1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0024472: Wrong section curves

1. Checking, if intersection curve is collapsed, is added. (file GeomInt_LineConstructor.cxx)
2. Earlier, intersection line was considered as valid if only mid-point of every interval of this line is into two intersected surfaces (with given tolerance). That's no good because after inserting of new points, old points, which is considered as valid only because they are into beginning or into end of interval (therefore, they was not checked), moved to mid of interval and became invalid. Therefore, checking for first and last points was added. (file GeomInt_LineConstructor.cxx)
3. Intersection line became valid (see bug description) after adding of new additional points into it (file IntPatch_PrmPrmIntersection.cxx). Methods for finding and adding of new points were added. (file IntWalk_PWalking_1.gxx)
Some test cases were changed.
Test cases for issue CR24472
This commit is contained in:
nbv 2014-02-06 11:12:09 +04:00 committed by abv
parent 6aa799c976
commit d48f15113e
10 changed files with 3453 additions and 2587 deletions

View File

@ -104,7 +104,8 @@ void GeomInt_IntSS::Perform(const Handle(Geom_Surface)& S1,
// ============================================================
if (myIntersector.IsDone()) {
const Standard_Integer nblin = myIntersector.NbLines();
for (Standard_Integer i=1; i<= nblin; i++) {
for (Standard_Integer i=1; i<= nblin; i++)
{
MakeCurve(i,dom1,dom2,Tol,Approx,ApproxS1,ApproxS2);
}
}

View File

@ -186,10 +186,22 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
{
firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
if(firstp!=lastp)
{
const Standard_Real pmid = (firstp+lastp)*0.5;
const gp_Pnt Pmid = ALine->Value(pmid);
const Standard_Real pmid = (firstp+lastp)*0.5;
const gp_Pnt Pmid = ALine->Value(pmid);
//Checking, if it is an "micro-curve" (can it be collapsed in one point?).
//If "yes" then first-, last- and midpoints are same point.
gp_Pnt aP1 = ALine->Value(RealToInt(firstp)),
aP2 = ALine->Value(RealToInt(lastp));
Standard_Real aSQDist = aP1.SquareDistance(aP2);
aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid));
aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid));
Standard_Boolean isMicro = aSQDist*100.0 < Tol;
if((Abs(firstp-lastp)>Precision::PConfusion()) && !isMicro)
{
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
@ -206,29 +218,86 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
return;
}
else if(typl == IntPatch_Walking)
{
{
Standard_Real u1,v1,u2,v2;
Handle(IntPatch_WLine)& WLine = *((Handle(IntPatch_WLine) *)&L);
seqp.Clear();
i = 1;
{
firstp = GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
const IntSurf_PntOn2S& Pf = WLine->Point(RealToInt(firstp));
Pf.Parameters(u1,v1,u2,v2);
//Inscribe parameters into main period for periodic surfaces
Recadre(myHS1,myHS2,u1,v1,u2,v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
if((in1 == TopAbs_OUT) || (in2 == TopAbs_OUT))
{
i = 2;
}
}
nbvtx = GeomInt_LineTool::NbVertex(L);
for(i=1;i<nbvtx;i++)
{
for(;i<nbvtx;i++)
{
firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
if(firstp!=lastp)
{
const Standard_Integer pmid = (Standard_Integer )( (firstp+lastp)/2);
const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
const Standard_Integer pmid = RealToInt((firstp+lastp)*0.5);
const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
//Checking, if it is an "micro-curve" (can it be collapsed in one point?).
//If "yes" then first-, last- and midpoints are same point.
gp_Pnt aP1 = WLine->Point(RealToInt(firstp)).Value(),
aP2 = WLine->Point(RealToInt(lastp)).Value();
Standard_Real aSQDist = aP1.SquareDistance(aP2);
aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid.Value()));
aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid.Value()));
Standard_Boolean isMicro = aSQDist*100.0 < Tol;
if((Abs(firstp-lastp)>Precision::PConfusion()) && !isMicro)
{
Pmid.Parameters(u1,v1,u2,v2);
//Inscribe parameters into main period for periodic surfaces
Recadre(myHS1,myHS2,u1,v1,u2,v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1 != TopAbs_OUT) { //-- !=ON donne Pb
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
if(in2 != TopAbs_OUT) { //-- !=ON
seqp.Append(firstp);
seqp.Append(lastp);
}
const TopAbs_State in1m = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1m == TopAbs_OUT)
{
continue;
}
const TopAbs_State in2m = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
if(in2m == TopAbs_OUT)
{
continue;
}
const IntSurf_PntOn2S& Plast = WLine->Point(RealToInt(lastp));
Plast.Parameters(u1,v1,u2,v2);
//Inscribe parameters into main period for periodic surfaces
Recadre(myHS1,myHS2,u1,v1,u2,v2);
const TopAbs_State in1l = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1l == TopAbs_OUT)
{
continue;
}
const TopAbs_State in2l = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
if(in2l == TopAbs_OUT)
{
continue;
}
seqp.Append(firstp);
seqp.Append(lastp);
}
}
done = Standard_True;
@ -245,54 +314,51 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
{
firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
if(Abs(firstp-lastp)>Precision::PConfusion())
if((Abs(firstp-lastp)>Precision::PConfusion()))
{
intrvtested = Standard_True;
const Standard_Real pmid = (firstp+lastp)*0.5;
gp_Pnt Pmid;
gp_Pnt Pmid, aP1, aP2;
switch (typl)
{
case IntPatch_Lin: Pmid = ElCLib::Value(pmid,GLine->Line()); break;
case IntPatch_Circle: Pmid = ElCLib::Value(pmid,GLine->Circle()); break;
case IntPatch_Ellipse: Pmid = ElCLib::Value(pmid,GLine->Ellipse()); break;
case IntPatch_Hyperbola: Pmid = ElCLib::Value(pmid,GLine->Hyperbola()); break;
case IntPatch_Parabola: Pmid = ElCLib::Value(pmid,GLine->Parabola()); break;
case IntPatch_Lin:
Pmid = ElCLib::Value(pmid,GLine->Line());
aP1 = ElCLib::Value(firstp,GLine->Line());
aP2 = ElCLib::Value(lastp,GLine->Line());
break;
case IntPatch_Circle:
Pmid = ElCLib::Value(pmid,GLine->Circle());
aP1 = ElCLib::Value(firstp,GLine->Circle());
aP2 = ElCLib::Value(lastp,GLine->Circle());
break;
case IntPatch_Ellipse:
Pmid = ElCLib::Value(pmid,GLine->Ellipse());
aP1 = ElCLib::Value(firstp,GLine->Ellipse());
aP2 = ElCLib::Value(lastp,GLine->Ellipse());
break;
case IntPatch_Hyperbola:
Pmid = ElCLib::Value(pmid,GLine->Hyperbola());
aP1 = ElCLib::Value(firstp,GLine->Hyperbola());
aP2 = ElCLib::Value(lastp,GLine->Hyperbola());
break;
case IntPatch_Parabola:
Pmid = ElCLib::Value(pmid,GLine->Parabola());
aP1 = ElCLib::Value(firstp,GLine->Parabola());
aP2 = ElCLib::Value(lastp,GLine->Parabola());
break;
case IntPatch_Analytic:
case IntPatch_Walking:
case IntPatch_Restriction: break; // cases Analytic, Walking and Restriction are handled above
}
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1 != TopAbs_OUT) {
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
if(in2 != TopAbs_OUT) {
seqp.Append(firstp);
seqp.Append(lastp);
}
}
}
}
if(typl == IntPatch_Circle || typl == IntPatch_Ellipse)
{
firstp = GeomInt_LineTool::Vertex(L,nbvtx).ParameterOnLine();
lastp = M_PI + M_PI + GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
const Standard_Real cadrinf = GeomInt_LineTool::FirstParameter(L);
const Standard_Real cadrsup = GeomInt_LineTool::LastParameter(L);
Standard_Real acadr = (firstp+lastp)*0.5;
while(acadr < cadrinf) { acadr+=M_PI+M_PI; }
while(acadr > cadrsup) { acadr-=M_PI+M_PI; }
if(acadr>=cadrinf && acadr<=cadrsup)
{
if(Abs(firstp-lastp)>Precision::PConfusion())
{
intrvtested = Standard_True;
const Standard_Real pmid = (firstp+lastp)*0.5;
gp_Pnt Pmid;
if (typl == IntPatch_Circle)
Pmid = ElCLib::Value(pmid,GLine->Circle());
else
Pmid = ElCLib::Value(pmid,GLine->Ellipse());
Standard_Real aSQDist = aP1.SquareDistance(aP2);
aSQDist = Max(aSQDist, aP1.SquareDistance(Pmid));
aSQDist = Max(aSQDist, aP2.SquareDistance(Pmid));
if(aSQDist*100.0 > Tol)
{ //if it is not an "micro-curve" (can it be collapsed in one point?).
//If "yes" then first-, last- and midpoints are same point.
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
@ -305,7 +371,52 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
}
}
}
}
}
if(typl == IntPatch_Circle || typl == IntPatch_Ellipse)
{
const Standard_Real aT = M_PI + M_PI;
firstp = GeomInt_LineTool::Vertex(L,nbvtx).ParameterOnLine();
lastp = aT + GeomInt_LineTool::Vertex(L,1).ParameterOnLine();
const Standard_Real cadrinf = GeomInt_LineTool::FirstParameter(L);
const Standard_Real cadrsup = GeomInt_LineTool::LastParameter(L);
Standard_Real acadr = (firstp+lastp)*0.5;
while(acadr < cadrinf)
{
acadr+=aT;
}
while(acadr > cadrsup)
{
acadr-=aT;
}
if(acadr>=cadrinf && acadr<=cadrsup)
{
if(Abs(firstp-lastp) > Precision::PConfusion())
{
intrvtested = Standard_True;
const Standard_Real pmid = (firstp+lastp)*0.5;
gp_Pnt Pmid;
if (typl == IntPatch_Circle)
Pmid = ElCLib::Value(pmid,GLine->Circle());
else
Pmid = ElCLib::Value(pmid,GLine->Ellipse());
Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
Recadre(myHS1,myHS2,u1,v1,u2,v2);
const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
if(in1 != TopAbs_OUT)
{
const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
if(in2 != TopAbs_OUT)
{
seqp.Append(firstp);
seqp.Append(lastp);
}
}
}
}
}
if (!intrvtested) {
// on garde a priori. Il faudrait un point 2d sur chaque
// surface pour prendre la decision. Sera fait dans
@ -370,28 +481,36 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
{
// on cumule
GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
if (or1 != TopAbs_INTERNAL) {
if (valj.Orientation1() != TopAbs_INTERNAL) {
if (or1 != valj.Orientation1()) {
if (or1 != TopAbs_INTERNAL)
{
if (valj.Orientation1() != TopAbs_INTERNAL)
{
if (or1 != valj.Orientation1())
{
valj.SetOrientation1(TopAbs_INTERNAL);
}
}
else {
else
{
valj.SetOrientation1(or1);
}
}
if (or2 != TopAbs_INTERNAL) {
if (valj.Orientation2() != TopAbs_INTERNAL) {
if (or2 != valj.Orientation2()) {
if (or2 != TopAbs_INTERNAL)
{
if (valj.Orientation2() != TopAbs_INTERNAL)
{
if (or2 != valj.Orientation2())
{
valj.SetOrientation2(TopAbs_INTERNAL);
}
}
else {
else
{
valj.SetOrientation2(or2);
}
}
}
inserted = Standard_True;
break;
}
@ -403,7 +522,9 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
break;
}
}
if (!inserted) {
if (!inserted)
{
seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
}
}
@ -505,10 +626,12 @@ void GeomInt_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
lastp = seqpss(i).Parameter();
Standard_Real stofirst = Max(firstp, thefirst);
Standard_Real stolast = Min(lastp, thelast) ;
if (stolast > stofirst) {
if (stolast > stofirst)
{
seqp.Append(stofirst);
seqp.Append(stolast);
}
if (lastp > thelast)
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,8 @@ uses XY from gp,
PntOn2S from IntSurf,
LineOn2S from IntSurf,
Dir from gp,
Dir2d from gp
Dir2d from gp,
Pnt from gp
raises OutOfRange from Standard,
@ -248,14 +249,36 @@ is
is static;
AddAPoint ( me : in out ;
line : in out LineOn2S from IntSurf ;
POn2S : PntOn2S from IntSurf ) ;
---C++: inline
line : in out LineOn2S from IntSurf ;
POn2S : PntOn2S from IntSurf ) ;
---C++: inline
ExtendLineInCommonZone(me: in out; theChoixIso: ConstIsoparametric from IntImp;
theDirectionFlag: Boolean from Standard)
returns Boolean from Standard
is private;
theDirectionFlag: Boolean from Standard)
returns Boolean from Standard
is private;
DistanceMinimizeByGradient( me : in out;
theASurf1 , theASurf2 : ThePSurface ;
theU1, theV1, theU2, theV2: out Real from Standard;
theStep0U1V1: Real from Standard = 1.0e-6;
theStep0U2V2: Real from Standard = 1.0e-6)
returns Boolean from Standard
is private;
DistanceMinimizeByExtrema(me : in out;
theASurf1 : ThePSurface ;
theP0 : Pnt from gp;
theU0, theV0: out Real from Standard;
theStep0U: Real from Standard = 1.0;
theStep0V: Real from Standard = 1.0)
returns Boolean from Standard
is private;
SeekAdditionalPoints( me : in out;
theASurf1 , theASurf2 : ThePSurface;
theMinNbPoints : Integer from Standard)
returns Boolean from Standard;
fields

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
puts "TODO ?OCC23753 ALL: Process killed by CPU limit"
puts "TODO ?OCC23753 ALL: TEST INCOMPLETE"
puts "TODO ?OCC24472 ALL: Error : Result shape is WRONG because it must contains 70 edges instead of 71"
puts "TODO ?OCC24472 ALL: Error : Result shape is WRONG because it must contains 139 shapes instead of 140"
puts "============"
puts "OCC19793"
@ -9,8 +9,7 @@ puts ""
# Fuse problem of symetrical shapes. Appendix for NPAL19789
#######################################################################
cpulimit 1000
#cpulimit 4500
cpulimit 400
set BugNumber OCC19793
puts "Load first shape ..."

View File

@ -25,5 +25,5 @@ if { $ll_1 != $ll_2 } {
puts "PRO19653 OK : BREPALGO_BOOLEANOPERATION returns result"
}
set length 0
set length 228.265
set 2dviewer 0

45
tests/bugs/modalg_5/bug24299 Executable file
View File

@ -0,0 +1,45 @@
puts "========="
puts "CR24299"
puts "========="
puts ""
###############################
## Wrong section curve
###############################
restore [locate_data_file pro19653a.brep] b1
restore [locate_data_file pro19653b.brep] b2
explode b1 f
explode b2 f
mksurface s1 b1_1
mksurface s2 b2_1
intersect i s1 s2
dlog reset
dlog on
xdistcs i_2 s1 0 1 10
set Log1 [dlog get]
set List1 [split ${Log1} {TD= \t\n}]
set L1 [llength ${List1}]
set L2 10
set L3 5
set N [expr (${L1} - ${L2})/${L3} + 1]
set Tolerance 1.0e-5
set D_good 0.
for {set i 1} {${i} <= ${N}} {incr i} {
set j1 [expr ${L2} + (${i}-1)*${L3}]
set j2 [expr ${j1} + 2]
set T [lindex ${List1} ${j1}]
set D [lindex ${List1} ${j2}]
#puts "i=${i} j1=${j1} j2=${j2} T=${T} D=${D}"
if { [expr abs(${D} - ${D_good})] > ${Tolerance} } {
puts "Error: i=${i} T=${T} D=${D}"
}
}
smallview
fit
set only_screen_axo 1

112
tests/bugs/modalg_5/bug24472 Executable file
View File

@ -0,0 +1,112 @@
puts "========="
puts "CR24472"
puts "========="
puts ""
###############################
## Wrong section curves
###############################
proc checkList {List Tolerance D_good} {
set L1 [llength ${List}]
set L2 10
set L3 5
set N [expr (${L1} - ${L2})/${L3} + 1]
for {set i 1} {${i} <= ${N}} {incr i} {
set j1 [expr ${L2} + (${i}-1)*${L3}]
set j2 [expr ${j1} + 2]
set T [lindex ${List} ${j1}]
set D [lindex ${List} ${j2}]
#puts "i=${i} j1=${j1} j2=${j2} T=${T} D=${D}"
if { [expr abs(${D} - ${D_good})] > ${Tolerance} } {
puts "Error: i=${i} T=${T} D=${D}"
}
}
}
smallview
restore [locate_data_file bug24472_Pipe_1.brep] b1
explode b1 f
copy b1_2 f1
copy b1_3 f2
copy b1_6 f3
mksurface s1 f1
mksurface s2 f2
mksurface s3 f3
puts ""
puts "First test"
# 1.1 geometry
intersect i s1 s2
#donly i_22; fit
dlog reset
dlog on
xdistcs i_22 s1 0 1 10
set Log1 [dlog get]
set List1 [split ${Log1} {TD= \t\n}]
set Tolerance 1.0e-12
set D_good 0.
checkList ${List1} ${Tolerance} ${D_good}
puts ""
puts "Second test"
# 1.2 topology
bsection r f1 f2
bopcheck r
# r is self interfered
explode r e
mkcurve c r_1
#donly r_1; fit
dlog reset
dlog on
xdistcs c s1 0.0714822451660209 1 10
set Log2 [dlog get]
set List2 [split ${Log2} {TD= \t\n}]
set Tolerance 1.0e-12
set D_good 0.
checkList ${List2} ${Tolerance} ${D_good}
puts ""
puts "Third test"
# 2.1 geometry
intersect i s1 s3
#donly i_4; fit
dlog reset
dlog on
xdistcs i_4 s1 0 1 10
set Log3 [dlog get]
set List3 [split ${Log3} {TD= \t\n}]
set Tolerance 1.0e-6
set D_good 0.
checkList ${List3} ${Tolerance} ${D_good}
puts ""
puts "Fourth test"
# 2.2 topology
bsection r f1 f3
bopcheck r
#r is self interfered
explode r
mkcurve c r_1
#donly r_1; fit
dlog reset
dlog on
xdistcs c s1 0.0714822451660209 1 10
set Log4 [dlog get]
set List4 [split ${Log4} {TD= \t\n}]
set Tolerance 1.0e-12
set D_good 0.
checkList ${List4} ${Tolerance} ${D_good}

View File

@ -7,6 +7,8 @@ puts ""
## It is impossible to intersect two surfaces
##################################################
puts "TODO OCC24472 ALL: Error : Intersection was made WRONGLY"
restore [locate_data_file OCC13-1.draw] su1
############### checkshape su1 # is not a topological shape
restore [locate_data_file OCC13-2.draw] su2