mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0028599: Replacement of old Boolean operations with new ones in BRepProj_Projection algorithm
The usage of *BRepAlgo_Section* has been replaced with the usage of *BRepAlgoAPI_Section* in *BRepProj_Projection* algorithm. The TODO statements have been removed from the failing test case in the "prj" grid as they are working correctly now. The following changes have been made to improve the performance *BRepAlgoAPI_Section*: 1. Revision of the *IntPolyh_Intersection* class to avoid repeated calculation of the deflection of the same triangulation. 2. Small revision of the Edge/Face intersection algorithm to perform Extrema computation on the whole intersection range of the edge instead of discrete ranges. 3. Implementation of the extrema computation for the Circle and Sphere. 4. Correct computation of the parameter of the point on the Circle.
This commit is contained in:
18
tests/lowalgos/extcs/bug29426_1
Normal file
18
tests/lowalgos/extcs/bug29426_1
Normal file
@@ -0,0 +1,18 @@
|
||||
puts "========"
|
||||
puts "OCC29426"
|
||||
puts "========"
|
||||
puts ""
|
||||
########################################
|
||||
# Extrema algorithm fails to find minimal distance between Circle and Sphere
|
||||
########################################
|
||||
|
||||
|
||||
circle c 3.59679185933224e-016 11.6635040382361 -3.23970209548358 -3.67401855705945e-017 -0.943656647634893 0.330926172090505 -2.2723161366922e-016 0.330926172090505 0.943656647634893 1.30000000000039
|
||||
sphere s 0 2.425 0 0 1 0 1 -0 0 9.876
|
||||
|
||||
set log [extrema c s]
|
||||
|
||||
if {![regexp "Point" $log]} {
|
||||
set ext_dist [lindex [length ext_1] end]
|
||||
checkreal "Circle/Sphere min distance" $ext_dist 0. 1.e-10 1.e-10
|
||||
}
|
17
tests/lowalgos/extcs/bug29426_2
Normal file
17
tests/lowalgos/extcs/bug29426_2
Normal file
@@ -0,0 +1,17 @@
|
||||
puts "========"
|
||||
puts "OCC29426"
|
||||
puts "========"
|
||||
puts ""
|
||||
########################################
|
||||
# Extrema algorithm fails to find minimal distance between Circle and Sphere
|
||||
########################################
|
||||
|
||||
circle c 3.53600008984273e-016 11.5073628633636 -3.18494573739955 -3.67401855705945e-017 -0.943656647634893 0.330926172090505 -2.2723161366922e-016 0.330926172090505 0.943656647634893 1.30000000000039
|
||||
sphere s 0 2.425 0 0 1 0 1 -0 0 9.712
|
||||
|
||||
set log [extrema c s]
|
||||
|
||||
if {![regexp "Point" $log]} {
|
||||
set ext_dist [lindex [length ext_1] end]
|
||||
checkreal "Circle/Sphere min distance" $ext_dist 0. 1.e-10 1.e-10
|
||||
}
|
127
tests/lowalgos/extcs/circ_sph_inter
Normal file
127
tests/lowalgos/extcs/circ_sph_inter
Normal file
@@ -0,0 +1,127 @@
|
||||
puts "======================="
|
||||
puts "Test for Circle/Sphere extrema algorithm"
|
||||
puts "Intersection case (two intersection points should be found"
|
||||
puts "======================="
|
||||
puts ""
|
||||
|
||||
# Make sphere
|
||||
set x0 0.
|
||||
set y0 0.
|
||||
set z0 0.
|
||||
set sph_radius 10.
|
||||
sphere s $x0 $y0 $z0 $sph_radius
|
||||
|
||||
# All circles will be to connect the two points - one inside the sphere, another - outside.
|
||||
# Such circle will definitely intersect the initial sphere in two points.
|
||||
# The points to make the circle will taken two spheres - with smaller and bigger radius.
|
||||
|
||||
# Set the number of iterations (number of pairs of spheres)
|
||||
set nbpairs 2
|
||||
|
||||
# Set ratio to increase/decrease the radius if additional spheres
|
||||
set ratio_radius 2.
|
||||
|
||||
# Number of sampling points on the spheres
|
||||
set nbsamples 5
|
||||
|
||||
# Number of circles rotations
|
||||
set nbsteps 5
|
||||
set angle [expr 180. / $nbsteps]
|
||||
|
||||
# Iteration step
|
||||
set iStep 1
|
||||
|
||||
for {set i 1} {$i <= $nbpairs} {incr i} {
|
||||
# Define the radius for spheres
|
||||
set s_in_radius [expr $sph_radius / ($i * $ratio_radius)]
|
||||
set s_out_radius [expr $sph_radius * ($i * $ratio_radius)]
|
||||
|
||||
# Make the spheres
|
||||
sphere s_in $x0 $y0 $z0 $s_in_radius
|
||||
sphere s_out $x0 $y0 $z0 $s_out_radius
|
||||
|
||||
# Make the sampling of the spheres
|
||||
|
||||
# spheres are the same, so there is no difference from which one to take the parameters
|
||||
bounds s_in umin umax vmin vmax
|
||||
set du [dval (umax-umin)/$nbsteps]
|
||||
set dv [dval (vmax-vmin)/$nbsteps]
|
||||
|
||||
for {set u1 1} {$u1 <= $nbsamples} {incr u1} {
|
||||
for {set v1 1} {$v1 <= $nbsamples} {incr v1} {
|
||||
|
||||
# point on inner sphere
|
||||
svalue s_in [dval umin+$u1*$du] [dval vmin+$v1*$dv] x1 y1 z1
|
||||
|
||||
for {set u2 1} {$u2 <= $nbsamples} {incr u2} {
|
||||
for {set v2 1} {$v2 <= $nbsamples} {incr v2} {
|
||||
|
||||
# point on outer sphere
|
||||
svalue s_out [dval umin+$u2*$du] [dval vmin+$v2*$dv] x2 y2 z2
|
||||
|
||||
# rotation direction
|
||||
set dx [dval x2-x1]
|
||||
set dy [dval y2-y1]
|
||||
set dz [dval z2-z1]
|
||||
|
||||
# center of the circle
|
||||
set xc [dval (x1+x2)/2.]
|
||||
set yc [dval (y1+y2)/2.]
|
||||
set zc [dval (z1+z2)/2.]
|
||||
|
||||
# compute radius for circle
|
||||
set cir_radius [expr sqrt($dx*$dx + $dy*$dy + $dz*$dz) / 2.]
|
||||
|
||||
# make plane to get its XAxis
|
||||
plane p $xc $yc $zc $dx $dy $dz
|
||||
|
||||
regexp {XAxis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump p] full dxx dxy dxz
|
||||
|
||||
circle c $xc $yc $zc $dxx $dxy $dxz $cir_radius
|
||||
|
||||
# make rotation
|
||||
copy c c_rotated
|
||||
for {set j 1} {$j <= $nbsteps} {incr j} {
|
||||
rotate c_rotated $xc $yc $zc $dx $dy $dz $angle
|
||||
|
||||
set log [extrema c_rotated s]
|
||||
|
||||
# save each circle if necessary
|
||||
# copy c_rotated c_$iStep
|
||||
|
||||
set isfound1 0
|
||||
set isfound2 0
|
||||
|
||||
if {[regexp "ext_1" $log]} {
|
||||
set ext_dist [lindex [length ext_1] end]
|
||||
checkreal "Step $iStep, min distance 1" $ext_dist 0 1.e-7 1.e-7
|
||||
set isfound1 1
|
||||
}
|
||||
|
||||
if {[regexp "ext_2" $log]} {
|
||||
set ext_dist [lindex [length ext_2] end]
|
||||
checkreal "Step $iStep, min distance 2" $ext_dist 0 1.e-7 1.e-7
|
||||
set isfound2 1
|
||||
}
|
||||
|
||||
if {[regexp "Extrema 1 is point" $log]} {
|
||||
puts "Check of Step $iStep, min distance 1 OK"
|
||||
set isfound1 1
|
||||
}
|
||||
|
||||
if {[regexp "Extrema 2 is point" $log]} {
|
||||
puts "Check of Step $iStep, min distance 2 OK"
|
||||
set isfound2 1
|
||||
}
|
||||
|
||||
if {$isfound1 == 0 || $isfound2 == 0} {
|
||||
puts "Error: Extrema has not detected the intersection case on step $iStep"
|
||||
}
|
||||
|
||||
incr iStep
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
160
tests/lowalgos/extcs/circ_sph_nointer
Normal file
160
tests/lowalgos/extcs/circ_sph_nointer
Normal file
@@ -0,0 +1,160 @@
|
||||
puts "======================="
|
||||
puts "Test for Circle/Sphere extrema algorithm"
|
||||
puts "No intersection cases - one minimum solution should be found"
|
||||
puts "======================="
|
||||
puts ""
|
||||
|
||||
# Make sphere
|
||||
set x0 0.
|
||||
set y0 0.
|
||||
set z0 0.
|
||||
set sph_radius 10.
|
||||
sphere s $x0 $y0 $z0 $sph_radius
|
||||
|
||||
# The circles will be made on the distance from the surface
|
||||
# as intersection of pairs of inner and outer spheres with the plane
|
||||
|
||||
# Set the number of iterations
|
||||
set nbstep 5
|
||||
# Rotation angle
|
||||
set angle [expr 180. / $nbstep]
|
||||
|
||||
# Set the number of Inner/Outer spheres in one direction
|
||||
set nbpairs 1
|
||||
# Set the delta for the radius of inner circle
|
||||
set delta_radius [expr $sph_radius * 0.9 / (2 * $nbpairs)]
|
||||
|
||||
# Step for sampling of the circle
|
||||
set dt [expr [dval 2*pi] / $nbstep]
|
||||
|
||||
# Iteration step
|
||||
set iStep 1
|
||||
|
||||
for {set i 1} {$i <= $nbpairs} {incr i} {
|
||||
# Define the inner circle
|
||||
set circ_radius [expr $i * $delta_radius]
|
||||
circle c $x0 $y0 $z0 0 0 1 $circ_radius
|
||||
|
||||
set diff [expr $sph_radius - $circ_radius]
|
||||
|
||||
# Distance between inner sphere on circle and initial sphere
|
||||
set real_dist [expr $sph_radius - 2*$circ_radius]
|
||||
|
||||
# Circle will be rotated around the line
|
||||
line rotation_line $x0 $y0 $z0 1 0 0
|
||||
|
||||
# Line rotation
|
||||
for {set j 1} {$j <= $nbstep} {incr j} {
|
||||
rotate rotation_line $x0 $y0 $z0 0 0 1 $angle
|
||||
|
||||
# Get direction for circle's rotation
|
||||
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump rotation_line] full dx dy dz
|
||||
|
||||
# Circle rotation
|
||||
copy c c_rotated
|
||||
for {set k 1} {$k <= $nbstep} {incr k} {
|
||||
rotate c_rotated 0 0 0 $dx $dy $dz $angle
|
||||
|
||||
# Sampling of the circle
|
||||
for {set n 1} {$n <= $nbstep} {incr n} {
|
||||
cvalue c_rotated $n*$dt x1 y1 z1
|
||||
|
||||
set x1 [dval x1]
|
||||
set y1 [dval y1]
|
||||
set z1 [dval z1]
|
||||
|
||||
# Normalize the vector
|
||||
set dtx [expr ($x1 - $x0) / $circ_radius]
|
||||
set dty [expr ($y1 - $y0) / $circ_radius]
|
||||
set dtz [expr ($z1 - $z0) / $circ_radius]
|
||||
|
||||
# Create inner and outer spheres
|
||||
set iC 1
|
||||
|
||||
repeat 2 {
|
||||
sphere s_to_int $x1 $y1 $z1 $circ_radius
|
||||
|
||||
# Define the point closest to the initial sphere
|
||||
set x_sol [expr $x1 + $iC * $circ_radius * $dtx]
|
||||
set y_sol [expr $y1 + $iC * $circ_radius * $dty]
|
||||
set z_sol [expr $z1 + $iC * $circ_radius * $dtz]
|
||||
|
||||
|
||||
# Intersect the sphere with the plane originated in closes point
|
||||
|
||||
# Make the sampling of the sphere to define section plane's direction
|
||||
|
||||
bounds s_to_int umin umax vmin vmax
|
||||
|
||||
set du [dval (umax-umin)/$nbstep]
|
||||
set dv [dval (vmax-vmin)/$nbstep]
|
||||
|
||||
for {set u 1} {$u <= $nbstep} {incr u} {
|
||||
for {set v 1} {$v <= $nbstep} {incr v} {
|
||||
|
||||
# Get point on surface
|
||||
svalue s_to_int [dval umin+$u*$du] [dval vmin+$v*$dv] xs ys zs
|
||||
|
||||
# Check that it is not the same point
|
||||
set sqdist [dval (xs-$x_sol)*(xs-$x_sol)+(ys-$y_sol)*(ys-$y_sol)+(zs-$z_sol)*(zs-$z_sol)]
|
||||
if {$sqdist < 1.e-16} {
|
||||
# Skip the sampling point
|
||||
continue;
|
||||
}
|
||||
|
||||
# Create the intersection plane
|
||||
plane p_int $x_sol $y_sol $z_sol [dval xs-$x_sol] [dval ys-$y_sol] [dval zs-$z_sol]
|
||||
# Intersect the sphere by plane to obtain the circle
|
||||
foreach c_int [intersect c_inter s_to_int p_int] {
|
||||
|
||||
# Check if the circle contains the point
|
||||
if {![regexp "Point on curve" [proj $c_int $x_sol $y_sol $z_sol]]} {
|
||||
if {[lindex [length ext_1] end] >= 1.e-7} {
|
||||
# run extrema - one of the ends of the curve should be the solution
|
||||
set log [extrema $c_int s 1]
|
||||
if {[regexp "prm_1_1" $log]} {
|
||||
# get parameters of the curve
|
||||
bounds $c_int fp lp
|
||||
if {[dval prm_1_1-fp] > 1.e-7 && [dval lp-prm_1_1] > 1.e-7} {
|
||||
puts "Error: Extrema has failed to find the minimal distance on step $iStep"
|
||||
}
|
||||
} else {
|
||||
puts "Error: Extrema has failed to find the minimal distance on step $iStep"
|
||||
}
|
||||
|
||||
# save each circle if necessary
|
||||
# copy $c_int c_$iStep
|
||||
|
||||
incr iStep
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
# Make extrema computation
|
||||
set log [extrema $c_int s]
|
||||
|
||||
# save each circle if necessary
|
||||
# copy $c_int c_$iStep
|
||||
|
||||
if {![regexp "ext_1" $log]} {
|
||||
puts "Error: Extrema has failed to find the minimal distance on step $iStep"
|
||||
} else {
|
||||
set ext_dist [lindex [length ext_1] end]
|
||||
checkreal "Step $iStep, min distance " $ext_dist $real_dist 1.e-7 1.e-7
|
||||
}
|
||||
incr iStep
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# prepare for the outer sphere
|
||||
set x1 [expr $x1 + 2 * $diff * $dtx]
|
||||
set y1 [expr $y1 + 2 * $diff * $dty]
|
||||
set z1 [expr $z1 + 2 * $diff * $dtz]
|
||||
|
||||
set iC -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
82
tests/lowalgos/extcs/circ_sph_parallel
Normal file
82
tests/lowalgos/extcs/circ_sph_parallel
Normal file
@@ -0,0 +1,82 @@
|
||||
puts "======================="
|
||||
puts "Test for Circle/Sphere extrema algorithm"
|
||||
puts "Parallel case (center of sphere is on the circle's axis)"
|
||||
puts "======================="
|
||||
puts ""
|
||||
|
||||
# Make sphere
|
||||
set x0 0.
|
||||
set y0 0.
|
||||
set z0 0.
|
||||
set sph_radius 10.
|
||||
sphere s $x0 $y0 $z0 $sph_radius
|
||||
|
||||
# Initially the circle will be made at the same place as sphere with different radius
|
||||
# and will be rotated and shifted many times.
|
||||
# The distance between circle and sphere is a Abs(sqrt(centers_dist^2 + circ_radius^2) - sph_radius)
|
||||
|
||||
# Number of different radius of initial circle
|
||||
set nb_radius 7
|
||||
# Number of circle's rotations
|
||||
set nbstep 8
|
||||
set angle [expr 180. / $nbstep]
|
||||
|
||||
# Define the shift
|
||||
set shift_start -3
|
||||
set shift_end 3
|
||||
set shift 4
|
||||
|
||||
# Iteration step
|
||||
set iStep 1
|
||||
|
||||
for {set i 1} {$i < $nb_radius} {incr i} {
|
||||
set circ_radius [expr $i*2.]
|
||||
circle c $x0 $y0 $z0 0 0 1 $circ_radius
|
||||
|
||||
# Circle will be rotated around the line
|
||||
line rotation_line $x0 $y0 $z0 1 0 0
|
||||
# Line rotation
|
||||
for {set j 1} {$j <= $nbstep} {incr j} {
|
||||
rotate rotation_line $x0 $y0 $z0 0 0 1 $angle
|
||||
|
||||
# Get direction for circle's rotation
|
||||
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump rotation_line] full dx dy dz
|
||||
|
||||
# Circle rotation
|
||||
copy c c_rotated
|
||||
for {set k 1} {$k <= $nbstep} {incr k} {
|
||||
rotate c_rotated $x0 $y0 $z0 $dx $dy $dz $angle
|
||||
|
||||
# Add shift of the circle along its own axis
|
||||
|
||||
# Get shift direction
|
||||
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump c_rotated] full dcx dcy dcz
|
||||
|
||||
set dcx [expr $shift*$dcx]
|
||||
set dcy [expr $shift*$dcy]
|
||||
set dcz [expr $shift*$dcz]
|
||||
|
||||
# Make the shift
|
||||
for {set t $shift_start} {$t <= $shift_end} {incr t} {
|
||||
copy c_rotated c_shifted
|
||||
translate c_shifted $t*$dcx $t*$dcy $t*$dcz
|
||||
|
||||
set log [extrema c_shifted s]
|
||||
|
||||
# save each circle if necessary
|
||||
# copy c_shifted c_$iStep
|
||||
|
||||
if {![regexp "Infinite number of extremas" $log]} {
|
||||
puts "Error: Extrema has not detected the parallel case on step $iStep"
|
||||
} else {
|
||||
regexp {Center :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump c_shifted] full x y z
|
||||
set centers_dist [expr sqrt($x*$x + $y*$y + $z*$z)]
|
||||
set real_dist [expr abs(sqrt($centers_dist*$centers_dist + $circ_radius*$circ_radius) - $sph_radius)]
|
||||
set ext_dist [lindex $log end]
|
||||
checkreal "Step $iStep, min distance " $ext_dist $real_dist 1.e-7 1.e-7
|
||||
}
|
||||
incr iStep
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
93
tests/lowalgos/extcs/circ_sph_touch
Normal file
93
tests/lowalgos/extcs/circ_sph_touch
Normal file
@@ -0,0 +1,93 @@
|
||||
puts "======================="
|
||||
puts "Test for Circle/Sphere extrema algorithm"
|
||||
puts "Touch case (circle is just touching the sphere)"
|
||||
puts "======================="
|
||||
puts ""
|
||||
|
||||
# Make sphere
|
||||
set x0 0.
|
||||
set y0 0.
|
||||
set z0 0.
|
||||
set sph_radius 10.
|
||||
sphere s $x0 $y0 $z0 $sph_radius
|
||||
|
||||
# Initially the circle will be made at the same place as sphere with different radius
|
||||
# and will shifted many times to touch the sphere.
|
||||
# The distance should always be close to zero.
|
||||
|
||||
# Number of different radius of initial circle
|
||||
set nb_radius 7
|
||||
# Number of circle's rotations
|
||||
set nbstep 8
|
||||
set angle [expr 180. / $nbstep]
|
||||
|
||||
# Iteration step
|
||||
set iStep 1
|
||||
|
||||
for {set i 1} {$i < $nb_radius} {incr i} {
|
||||
set circ_radius [expr $i*2.]
|
||||
if {$circ_radius == $sph_radius} {
|
||||
set circ_radius [expr $circ_radius + 0.1]
|
||||
}
|
||||
circle c $x0 $y0 $z0 0 0 1 $circ_radius
|
||||
|
||||
# Circle will be rotated around the line
|
||||
line rotation_line $x0 $y0 $z0 1 0 0
|
||||
# Line rotation
|
||||
for {set j 1} {$j <= $nbstep} {incr j} {
|
||||
rotate rotation_line $x0 $y0 $z0 0 0 1 $angle
|
||||
|
||||
# Get direction for circle's rotation
|
||||
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump rotation_line] full dx dy dz
|
||||
|
||||
# Circle rotation
|
||||
copy c c_rotated
|
||||
for {set k 1} {$k <= $nbstep} {incr k} {
|
||||
rotate c_rotated $x0 $y0 $z0 $dx $dy $dz $angle
|
||||
|
||||
# Get translation axis for the circle
|
||||
regexp {XAxis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump c_rotated] full dxx dxy dxz
|
||||
|
||||
# Get rotation plane for translation line
|
||||
regexp {YAxis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump c_rotated] full dyx dyy dyz
|
||||
|
||||
line translation_line $x0 $y0 $z0 $dxx $dxy $dxz
|
||||
|
||||
for {set n 1} {$n <= $nbstep} {incr n} {
|
||||
rotate translation_line $x0 $y0 $z0 $dyx $dyy $dyz $angle
|
||||
|
||||
# Get direction for circle's translation
|
||||
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump translation_line] full dtx dty dtz
|
||||
|
||||
# Circle's translation
|
||||
copy c_rotated c_shifted
|
||||
translate c_shifted $sph_radius*$dtx $sph_radius*$dty $sph_radius*$dtz
|
||||
|
||||
# Shift circle to touch sphere
|
||||
set shift -1
|
||||
repeat 2 {
|
||||
copy c_shifted c_touch
|
||||
translate c_touch $shift*$circ_radius*$dxx $shift*$circ_radius*$dxy $shift*$circ_radius*$dxz
|
||||
|
||||
set log [extrema c_touch s]
|
||||
|
||||
# save each circle if necessary
|
||||
# copy c_touch c_$iStep
|
||||
|
||||
if {![regexp "ext_1" $log]} {
|
||||
if {![regexp "Extrema 1 is point" $log]} {
|
||||
puts "Error: Extrema has not detected the touching case on step $iStep"
|
||||
} else {
|
||||
puts "Check of Step $iStep, min distance OK"
|
||||
}
|
||||
} else {
|
||||
set ext_dist [lindex [length ext_1] end]
|
||||
checkreal "Step $iStep, min distance " $ext_dist 0 1.e-7 1.e-7
|
||||
}
|
||||
incr iStep
|
||||
set shift 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,2 +1,3 @@
|
||||
001 2dinter
|
||||
002 bnd
|
||||
003 extcs
|
||||
|
Reference in New Issue
Block a user