From 788cbaf4c4c90b6c1da67f55765abd3d1aa64e8f Mon Sep 17 00:00:00 2001 From: nbv Date: Thu, 19 Sep 2013 16:46:17 +0400 Subject: [PATCH] 0024005: Intersecting a slightly off angle plane with a cylinder takes 7+ seconds Checking of possibility of bad result. Adding test case for issue CR24005 Correction of test case for issue CR24005 --- src/ChFi3d/ChFi3d_Builder_0.cxx | 12 +- src/Draft/Draft_Modification_1.cxx | 15 +- src/IntAna/IntAna_QuadQuadGeo.cxx | 8 +- src/IntPatch/IntPatch_GLine.cxx | 536 +++++---- .../IntPatch_ImpImpIntersection_2.gxx | 2 +- src/IntPatch/IntPatch_Intersection.cdl | 291 ++--- src/IntPatch/IntPatch_Intersection.cxx | 1058 ++++++++--------- src/IntTools/IntTools_FaceFace.cdl | 14 +- src/IntTools/IntTools_FaceFace.cxx | 403 ++++--- src/QABugs/QABugs_19.cxx | 92 +- tests/bugs/modalg_5/bug24005 | 35 + 11 files changed, 1406 insertions(+), 1060 deletions(-) create mode 100755 tests/bugs/modalg_5/bug24005 diff --git a/src/ChFi3d/ChFi3d_Builder_0.cxx b/src/ChFi3d/ChFi3d_Builder_0.cxx index 211cbc843c..d303c66bea 100755 --- a/src/ChFi3d/ChFi3d_Builder_0.cxx +++ b/src/ChFi3d/ChFi3d_Builder_0.cxx @@ -3068,7 +3068,17 @@ Standard_Boolean ChFi3d_ComputeCurves(Handle(Adaptor3d_HSurface)& S1, cyl = S1->Cylinder(); } IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d); - if (ImpKK.IsDone()) { + Standard_Boolean isIntDone = ImpKK.IsDone(); + + if(ImpKK.TypeInter() == IntAna_Ellipse) + { + const gp_Elips anEl = ImpKK.Ellipse(1); + const Standard_Real aMajorR = anEl.MajorRadius(); + const Standard_Real aMinorR = anEl.MinorRadius(); + isIntDone = (aMajorR < 100000.0 * aMinorR); + } + + if (isIntDone) { Standard_Boolean c1line = 0; switch (ImpKK.TypeInter()) { case IntAna_Line: diff --git a/src/Draft/Draft_Modification_1.cxx b/src/Draft/Draft_Modification_1.cxx index a7800c5417..d33a7306aa 100755 --- a/src/Draft/Draft_Modification_1.cxx +++ b/src/Draft/Draft_Modification_1.cxx @@ -1627,10 +1627,21 @@ Handle(Geom_Surface) Draft_Modification::NewSurface #endif return NewS; } - if (Abs(Angle) > Precision::Angular()) { + if (Abs(Angle) > Precision::Angular()) + { IntAna_QuadQuadGeo i2s; i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion()); - if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) { + Standard_Boolean isIntDone = i2s.IsDone(); + + if(i2s.TypeInter() == IntAna_Ellipse) + { + const gp_Elips anEl = i2s.Ellipse(1); + const Standard_Real aMajorR = anEl.MajorRadius(); + const Standard_Real aMinorR = anEl.MinorRadius(); + isIntDone = (aMajorR < 100000.0 * aMinorR); + } + + if (!isIntDone || i2s.TypeInter() != IntAna_Circle) { #ifdef DEB cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl; #endif diff --git a/src/IntAna/IntAna_QuadQuadGeo.cxx b/src/IntAna/IntAna_QuadQuadGeo.cxx index e803a1ccb9..5a9e4b3678 100755 --- a/src/IntAna/IntAna_QuadQuadGeo.cxx +++ b/src/IntAna/IntAna_QuadQuadGeo.cxx @@ -534,13 +534,7 @@ gp_Ax2 DirToAx2(const gp_Pnt& P,const gp_Dir& D) param1bis = radius; } } - if(typeres == IntAna_Ellipse) { - if( param1>100000.0*param1bis - || param1bis>100000.0*param1) { - done = Standard_False; - return; - } - } + done = Standard_True; } //======================================================================= diff --git a/src/IntPatch/IntPatch_GLine.cxx b/src/IntPatch/IntPatch_GLine.cxx index a88bbedb3e..ef84e89165 100755 --- a/src/IntPatch/IntPatch_GLine.cxx +++ b/src/IntPatch/IntPatch_GLine.cxx @@ -550,185 +550,289 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/) SortAgain = Standard_False; SortIsOK = Standard_True; - for(i=2; i<=nbvtx && SortIsOK; i++) { + for(i=2; i<=nbvtx && SortIsOK; i++) + { IntPatch_Point& VTX = svtx.ChangeValue(i); - for(j=1; j<=nbvtx && SortIsOK; j++) { - if(i!=j) { - IntPatch_Point& VTXM1 = svtx.ChangeValue(j); - Standard_Boolean kill = Standard_False; - Standard_Boolean killm1 = Standard_False; - if(Abs(VTXM1.ParameterOnLine()-VTX.ParameterOnLine())i) indl--; else if(indl==i) indl=j; } - if(fipt) { if(indf>i) indf--; else if(indf==i) indf=j; } - svtx.Remove(i); - nbvtx--; - } - else if(killm1) { - SortIsOK = Standard_False; - if(lapt) { if(indl>j) indl--; else if(indl==j) indl=i-1;} - if(fipt) { if(indf>j) indf--; else if(indf==j) indf=i-1;} - svtx.Remove(j); - nbvtx--; - } -// else - else if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) { // eap - //-- deux points de meme parametre qui ne peuvent etre confondus - //-- On change les parametres d un des points si les points UV sont - //-- differents. Ceci distingue le cas des aretes de couture. - // ========================================================== - //-- 2 points with the same parameters - //-- Change parametres of one point if points UV are - //-- different. This is the case of seam edge - Standard_Real ponline = VTX.ParameterOnLine(); - // eap, =>> - Standard_Real newParam = ponline; - const Standard_Real PiPi = M_PI+M_PI; - Standard_Boolean is2PI = ( Abs(ponline-PiPi) <= PrecisionPConfusion ); + for(j=1; j<=nbvtx && SortIsOK; j++) + { + if(i!=j) + { + IntPatch_Point& VTXM1 = svtx.ChangeValue(j); + Standard_Boolean kill = Standard_False; + Standard_Boolean killm1 = Standard_False; + if(Abs(VTXM1.ParameterOnLine()-VTX.ParameterOnLine()) 2 && // do this check if seam edge only gives vertices - !is2PI) // but always change 2PI -> 0 - continue; - - if (is2PI) - newParam = 0; - else if (Abs(ponline) <= PrecisionPConfusion) - newParam = PiPi; - else - newParam -= PiPi; -// if( (Abs(ponline)<=PrecisionPConfusion) -// ||(Abs(ponline-M_PI-M_PI) <=PrecisionPConfusion)) - // eap, <<= - Standard_Real u1a,v1a,u2a,v2a,u1b,v1b,u2b,v2b; - VTXM1.Parameters(u1a,v1a,u2a,v2a); - VTX.Parameters(u1b,v1b,u2b,v2b); - Standard_Integer flag = 0; - - if( (Abs(u1a-u1b)<=PrecisionPConfusion) ) flag|=1; - if( (Abs(v1a-v1b)<=PrecisionPConfusion) ) flag|=2; - if( (Abs(u2a-u2b)<=PrecisionPConfusion) ) flag|=4; - if( (Abs(v2a-v2b)<=PrecisionPConfusion) ) flag|=8; - Standard_Boolean TestOn1 = Standard_False; - Standard_Boolean TestOn2 = Standard_False; - switch(flag) { - case 3: //-- meme point U1 V1 - case 7: //-- meme point U1 V1 meme U2 - case 12: //-- meme U2 V2 - case 13: //-- meme point U1 meme U2 V2 - case 10: //-- meme point V1 meme V2 Test si U1a=U1b Mod 2PI et Test si U2a=U2b Mod 2PI - break; - case 11: //-- meme point U1 V1 meme V2 Test si U2a=U2b Mod 2PI - { TestOn2 = Standard_True; break; } - case 14: //-- meme point V1 meme U2 V2 Test si U1a=U1b Mod 2PI - { TestOn1 = Standard_True; break; } - default: break; - }; - // eap - //if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) {} - if(TestOn1) { - //// modified by jgv, 2.11.01 for BUC61033 //// - Standard_Real U1A = (u1a < u1b)? u1a : u1b; - Standard_Real U1B = (u1a < u1b)? u1b : u1a; - if (u1min == RealLast()) - { - u1min = U1A; - u1max = U1B; - } - else - { - if (Abs(U1A-u1min) > PrecisionPConfusion) - ToBreak = Standard_True; - if (Abs(U1B-u1max) > PrecisionPConfusion) - ToBreak = Standard_True; - } + if(!(kill || killm1)) + { + if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()) //-- OnS2 OnS2 + { + if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) //-- OnS2 == OnS2 + { + if(VTXM1.IsOnDomS1()) //-- OnS2 == OnS2 OnS1 + { + if(VTX.IsOnDomS1()==Standard_False) //-- OnS2 == OnS2 OnS1 PasOnS1 + { + kill=Standard_True; + } + else + { + if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) //-- OnS2 == OnS2 OnS1 == OnS1 + { + if(VTXM1.IsVertexOnS1()) + { + kill=Standard_True; //-- OnS2 == OnS2 OnS1 == OnS1 Vtx PasVtx + } + else + { + killm1=Standard_True; //-- OnS2 == OnS2 OnS1 == OnS1 PasVtx Vtx + } + } + } + } + else + { //-- OnS2 == OnS2 PasOnS1 + if(VTX.IsOnDomS1()) //-- OnS2 == OnS2 PasOnS1 OnS1 + { + killm1=Standard_True; + } + } + } + } + else //-- Pas OnS2 et OnS2 + { + if(VTXM1.IsOnDomS1()==Standard_False && VTX.IsOnDomS1()==Standard_False) + { + if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()==Standard_False) + { + kill=Standard_True; + } + else if(VTX.IsOnDomS2() && VTXM1.IsOnDomS2()==Standard_False) + { + killm1=Standard_True; + } + } + } + } + + //-- On a j < i + if(kill) + { + SortIsOK = Standard_False; + if(lapt) + { + if(indl>i) + indl--; + else if(indl==i) + indl=j; + } + + if(fipt) + { + if(indf>i) + indf--; + else if(indf==i) + indf=j; + } + + svtx.Remove(i); + nbvtx--; + } + else if(killm1) + { + SortIsOK = Standard_False; + if(lapt) + { + if(indl>j) + indl--; + else if(indl==j) + indl=i-1; + } + + if(fipt) + { + if(indf>j) + indf--; + else if(indf==j) + indf=i-1; + } + + svtx.Remove(j); + nbvtx--; + }// else + else if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) // eap + { + //-- deux points de meme parametre qui ne peuvent etre confondus + //-- On change les parametres d un des points si les points UV sont + //-- differents. Ceci distingue le cas des aretes de couture. + // ========================================================== + //-- 2 points with the same parameters + //-- Change parametres of one point if points UV are + //-- different. This is the case of seam edge + + Standard_Real ponline = VTX.ParameterOnLine(); + // eap, =>> + Standard_Real newParam = ponline; + const Standard_Real PiPi = M_PI+M_PI; + Standard_Boolean is2PI = ( Abs(ponline-PiPi) <= PrecisionPConfusion ); + + if (nbvtx > 2 && // do this check if seam edge only gives vertices + !is2PI) // but always change 2PI -> 0 + continue; + + if (is2PI) + newParam = 0; + else if (Abs(ponline) <= PrecisionPConfusion) + newParam = PiPi; + else + newParam -= PiPi; + + // if( (Abs(ponline)<=PrecisionPConfusion) + // ||(Abs(ponline-M_PI-M_PI) <=PrecisionPConfusion)) + // eap, <<= + + Standard_Real u1a,v1a,u2a,v2a,u1b,v1b,u2b,v2b; + VTXM1.Parameters(u1a,v1a,u2a,v2a); + VTX.Parameters(u1b,v1b,u2b,v2b); + Standard_Integer flag = 0; + + if( (Abs(u1a-u1b)<=PrecisionPConfusion) ) + flag|=1; + + if( (Abs(v1a-v1b)<=PrecisionPConfusion) ) + flag|=2; + if( (Abs(u2a-u2b)<=PrecisionPConfusion) ) + flag|=4; + + if( (Abs(v2a-v2b)<=PrecisionPConfusion) ) + flag|=8; + + Standard_Boolean TestOn1 = Standard_False; + Standard_Boolean TestOn2 = Standard_False; + + switch(flag) + { + case 3: //-- meme point U1 V1 + case 7: //-- meme point U1 V1 meme U2 + case 12: //-- meme U2 V2 + case 13: //-- meme point U1 meme U2 V2 + case 10: //-- meme point V1 meme V2 Test si U1a=U1b Mod 2PI et Test si U2a=U2b Mod 2PI + break; + case 11: //-- meme point U1 V1 meme V2 Test si U2a=U2b Mod 2PI + { + TestOn2 = Standard_True; + break; + } + + case 14: //-- meme point V1 meme U2 V2 Test si U1a=U1b Mod 2PI + { + TestOn1 = Standard_True; + break; + } + default: + break; + }; + + // eap + //if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) {} + if(TestOn1) + { + //// modified by jgv, 2.11.01 for BUC61033 //// + Standard_Real U1A = (u1a < u1b)? u1a : u1b; + Standard_Real U1B = (u1a < u1b)? u1b : u1a; + + if (u1min == RealLast()) + { + u1min = U1A; + u1max = U1B; + } + else + { + if (Abs(U1A-u1min) > PrecisionPConfusion) + ToBreak = Standard_True; + if (Abs(U1B-u1max) > PrecisionPConfusion) + ToBreak = Standard_True; + } /////////////////////////////////////////////// // eap, =>> // if (Abs(ponline) <= PrecisionPConfusion) { // const Standard_Real PiPi = M_PI+M_PI; - if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine - /*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/) { - SortAgain = Standard_True; - SortIsOK = Standard_False; - if (newParam > ponline) - if(u1a < u1b) { VTX.SetParameter(newParam); } - else { VTXM1.SetParameter(newParam); } - else - if(u1a > u1b) { VTX.SetParameter(newParam); } - else { VTXM1.SetParameter(newParam); } - } + if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine + /*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/) + { + SortAgain = Standard_True; + SortIsOK = Standard_False; + if (newParam > ponline) + { + if(u1a < u1b) + { + VTX.SetParameter(newParam); + } + else + { + VTXM1.SetParameter(newParam); + } + } + else + { + if(u1a > u1b) + { + VTX.SetParameter(newParam); + } + else + { + VTXM1.SetParameter(newParam); + } + } + } // } // else { // if(0.0 >= ParamMinOnLine && 0.0<=ParamMaxOnLine) { @@ -739,38 +843,59 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/) // } // } // eap, <<= - } - if(TestOn2) { - //// modified by jgv, 2.11.01 for BUC61033 //// - Standard_Real U2A = (u2a < u2b)? u2a : u2b; - Standard_Real U2B = (u2a < u2b)? u2b : u2a; - if (u2min == RealLast()) - { - u2min = U2A; - u2max = U2B; - } - else - { - if (Abs(U2A-u2min) > PrecisionPConfusion) - ToBreak = Standard_True; - if (Abs(U2B-u2max) > PrecisionPConfusion) - ToBreak = Standard_True; - } + } + + if(TestOn2) + { + //// modified by jgv, 2.11.01 for BUC61033 //// + Standard_Real U2A = (u2a < u2b)? u2a : u2b; + Standard_Real U2B = (u2a < u2b)? u2b : u2a; + if (u2min == RealLast()) + { + u2min = U2A; + u2max = U2B; + } + else + { + if (Abs(U2A-u2min) > PrecisionPConfusion) + ToBreak = Standard_True; + + if (Abs(U2B-u2max) > PrecisionPConfusion) + ToBreak = Standard_True; + + } /////////////////////////////////////////////// // eap, =>> // if (Abs(ponline) <= PrecisionPConfusion) { // const Standard_Real PiPi = M_PI+M_PI; - if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine - /*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/) { - SortAgain = Standard_True; - SortIsOK = Standard_False; - if (newParam > ponline) - if(u2a < u2b) { VTX.SetParameter(newParam); } - else { VTXM1.SetParameter(newParam); } - else - if(u2a > u2b) { VTX.SetParameter(newParam); } - else { VTXM1.SetParameter(newParam); } - } + if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine + /*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/) + { + SortAgain = Standard_True; + SortIsOK = Standard_False; + if (newParam > ponline) + { + if(u2a < u2b) + { + VTX.SetParameter(newParam); + } + else + { + VTXM1.SetParameter(newParam); + } + } + else + { + if(u2a > u2b) + { + VTX.SetParameter(newParam); + } + else + { + VTXM1.SetParameter(newParam); + } + } + } // } // else { // if(0.0 >= ParamMinOnLine && 0.0<=ParamMaxOnLine) { @@ -783,10 +908,10 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/) // } // } // eap, <<= - } - } - } - } + } + } + } + } } //-- if(i!=j) } } @@ -809,6 +934,7 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/) } } while(!SortIsOK); + indl=nbvtx; indf=1; } diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx index 3984ca50d7..ca48848978 100755 --- a/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx @@ -76,7 +76,7 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1, IntSurf_Quadric quad1; IntSurf_Quadric quad2; IntPatch_ArcFunction AFunc; - Standard_Real Tolang = 1.e-8; + const Standard_Real Tolang = 1.e-8; GeomAbs_SurfaceType typs1 = S1->GetType(); GeomAbs_SurfaceType typs2 = S2->GetType(); // diff --git a/src/IntPatch/IntPatch_Intersection.cdl b/src/IntPatch/IntPatch_Intersection.cdl index f03835e9c3..2afc0b0058 100755 --- a/src/IntPatch/IntPatch_Intersection.cdl +++ b/src/IntPatch/IntPatch_Intersection.cdl @@ -22,20 +22,20 @@ class Intersection from IntPatch - ---Purpose: This class provides a generic algorithm to intersect + ---Purpose: This class provides a generic algorithm to intersect -- 2 surfaces. uses - HVertex from Adaptor3d, - HCurve2d from Adaptor2d, - HSurface from Adaptor3d, - Point from IntPatch, + HVertex from Adaptor3d, + HCurve2d from Adaptor2d, + HSurface from Adaptor3d, + Point from IntPatch, SequenceOfPoint from IntPatch, - TopolTool from Adaptor3d, - SequenceOfLine from IntPatch, - Line from IntPatch, - --amv - ListOfPntOn2S from IntSurf + TopolTool from Adaptor3d, + SequenceOfLine from IntPatch, + Line from IntPatch, + SurfaceType from GeomAbs, + ListOfPntOn2S from IntSurf raises NotDone from StdFail, OutOfRange from Standard, @@ -52,147 +52,160 @@ is S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; TolArc,TolTang: Real from Standard) - returns Intersection from IntPatch - - raises ConstructionError from Standard; + returns Intersection from IntPatch + raises ConstructionError from Standard; Create (S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; TolArc,TolTang: Real from Standard) - returns Intersection from IntPatch - - raises ConstructionError from Standard; + returns Intersection from IntPatch + raises ConstructionError from Standard; SetTolerances(me : in out; TolArc : Real from Standard; - TolTang : Real from Standard; - UVMaxStep: Real from Standard; - Fleche : Real from Standard) + TolTang : Real from Standard; + UVMaxStep: Real from Standard; + Fleche : Real from Standard) - ---Purpose: Set the tolerances used by the algorithms: - -- --- Implicit - Parametric - -- --- Parametric - Parametric - -- --- Implicit - Implicit - -- - -- TolArc is used to compute the intersections - -- between the restrictions of a surface and a - -- walking line. - -- - -- TolTang is used to compute the points on a walking - -- line, and in geometric algorithms. - -- - -- Fleche is a parameter used in the walking - -- algorithms to provide small curvatures on a line. - -- - -- UVMaxStep is a parameter used in the walking - -- algorithms to compute the distance between to - -- points in their respective parametrtic spaces. - -- - is static; + ---Purpose: Set the tolerances used by the algorithms: + -- --- Implicit - Parametric + -- --- Parametric - Parametric + -- --- Implicit - Implicit + -- + -- TolArc is used to compute the intersections + -- between the restrictions of a surface and a + -- walking line. + -- + -- TolTang is used to compute the points on a walking + -- line, and in geometric algorithms. + -- + -- Fleche is a parameter used in the walking + -- algorithms to provide small curvatures on a line. + -- + -- UVMaxStep is a parameter used in the walking + -- algorithms to compute the distance between to + -- points in their respective parametrtic spaces. + -- + + is static; - Perform (me: in out; - S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; - S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; - TolArc,TolTang: Real from Standard) - - raises ConstructionError from Standard - - is static; - - --amv Perform (me: in out; S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; TolArc,TolTang: Real from Standard; - LOfPnts: in out ListOfPntOn2S from IntSurf; - RestrictLine: Boolean from Standard = Standard_True) + isGeomInt : Boolean from Standard = Standard_True) - raises ConstructionError from Standard + raises ConstructionError from Standard + is static; + + --amv + Perform ( me: in out; + S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; + S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; + TolArc,TolTang: Real from Standard; + LOfPnts: in out ListOfPntOn2S from IntSurf; + RestrictLine: Boolean from Standard = Standard_True; + isGeomInt : Boolean from Standard = Standard_True) + + ---Purpose: If isGeomInt == Standard_False, then method + -- Param-Param intersection will be used. + + raises ConstructionError from Standard + is static; - is static; - - Perform (me: in out; - S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; - S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; - U1,V1,U2,V2 : Real from Standard; - TolArc,TolTang: Real from Standard) - - raises ConstructionError from Standard - - is static; + Perform ( me: in out; + S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; + S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; + U1,V1,U2,V2 : Real from Standard; + TolArc,TolTang: Real from Standard) + + raises ConstructionError from Standard + is static; Perform (me: in out; S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; TolArc,TolTang: Real from Standard) + + raises ConstructionError from Standard + is static; + + ParamParamPerfom( me: in out; + S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; + S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; + TolArc,TolTang: Real from Standard; + LOfPnts: in out ListOfPntOn2S from IntSurf; + RestrictLine: Boolean from Standard; + typs1, typs2: SurfaceType from GeomAbs) - raises ConstructionError from Standard - - is static; - + is private; + + GeomGeomPerfom( me: in out; + S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; + S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; + TolArc,TolTang: Real from Standard; + LOfPnts: in out ListOfPntOn2S from IntSurf; + RestrictLine: Boolean from Standard; + typs1, typs2: SurfaceType from GeomAbs) + is private; + + GeomParamPerfom(me: in out; + S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; + S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d; + isNotAnalitical: Boolean from Standard; + typs1, typs2: SurfaceType from GeomAbs) + + is private; + IsDone(me) ---Purpose: Returns True if the calculus was succesfull. returns Boolean from Standard - ---C++: inline - + ---C++: inline + is static; IsEmpty(me) - - ---Purpose: Returns true if the is no intersection. - - returns Boolean from Standard - ---C++: inline - - raises NotDone from StdFail - - is static; + ---Purpose: Returns true if the is no intersection. + ---C++: inline + returns Boolean from Standard + raises NotDone from StdFail + is static; TangentFaces(me) - - ---Purpose: Returns True if the two patches are considered as - -- entierly tangent, i-e every restriction arc of one - -- patch is inside the geometric base of the other patch. - - returns Boolean from Standard - ---C++: inline - - raises NotDone from StdFail - - is static; - - + ---Purpose: Returns True if the two patches are considered as + -- entierly tangent, i-e every restriction arc of one + -- patch is inside the geometric base of the other patch. + ---C++: inline + + returns Boolean from Standard + raises NotDone from StdFail + is static; + OppositeFaces(me) - - ---Purpose: Returns True when the TangentFaces returns True and the - -- normal vectors evaluated at a point on the first and the - -- second surface are opposite. - -- The exception DomainError is raised if TangentFaces - -- returns False. + ---Purpose: Returns True when the TangentFaces returns True and the + -- normal vectors evaluated at a point on the first and the + -- second surface are opposite. + -- The exception DomainError is raised if TangentFaces + -- returns False. + ---C++: inline returns Boolean from Standard - ---C++: inline - - raises NotDone from StdFail, - DomainError from Standard - - is static; + raises NotDone from StdFail, + DomainError from Standard + is static; NbPnts(me) - - ---Purpose: Returns the number of "single" points. + ---Purpose: Returns the number of "single" points. + ---C++: inline returns Integer from Standard - ---C++: inline - raises NotDone from StdFail - is static; @@ -200,52 +213,46 @@ is ---Purpose: Returns the point of range Index. -- An exception is raised if Index<=0 or Index>NbPnt. + ---C++: return const& + ---C++: inline returns Point from IntPatch - ---C++: return const& - ---C++: inline - - raises NotDone from StdFail, - OutOfRange from Standard + raises NotDone from StdFail, + OutOfRange from Standard is static; NbLines(me) - - ---Purpose: Returns the number of intersection lines. - - returns Integer from Standard - ---C++: inline - - raises NotDone from StdFail - - is static; - - + ---Purpose: Returns the number of intersection lines. + ---C++: inline + + returns Integer from Standard + raises NotDone from StdFail + is static; + Line(me; Index: Integer from Standard) - - ---Purpose: Returns the line of range Index. + ---Purpose: Returns the line of range Index. -- An exception is raised if Index<=0 or Index>NbLine. + ---C++: return const& + ---C++: inline returns Line from IntPatch - ---C++: return const& - ---C++: inline - - raises NotDone from StdFail, - OutOfRange from Standard + raises NotDone from StdFail, + OutOfRange from Standard + + is static; + + SequenceOfLine(me) + ---C++: return const& + + returns SequenceOfLine from IntPatch + raises NotDone from StdFail + is static; - is static; - - SequenceOfLine(me) - returns SequenceOfLine from IntPatch - ---C++: return const& - raises NotDone from StdFail - is static; - - Dump(me; Mode: Integer from Standard; - S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; - S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d) + Dump(me; Mode : Integer from Standard; + S1 : HSurface from Adaptor3d; D1: TopolTool from Adaptor3d; + S2 : HSurface from Adaptor3d; D2: TopolTool from Adaptor3d) ---Purpose: Dump of each result line. --- Mode for more accurate dumps. -- diff --git a/src/IntPatch/IntPatch_Intersection.cxx b/src/IntPatch/IntPatch_Intersection.cxx index 369d9af020..842d53c54b 100755 --- a/src/IntPatch/IntPatch_Intersection.cxx +++ b/src/IntPatch/IntPatch_Intersection.cxx @@ -32,7 +32,7 @@ #include #define DEBUG 0 -static Standard_Integer NBPOINTSSURALINE = 200; +static const Standard_Integer aNbPointsInALine = 200; //====================================================================== // function: SequenceOfLine @@ -708,18 +708,21 @@ static void FUN_TrimBothSurf(const Handle(Adaptor3d_HSurface)& S1, //function : Perform //purpose : //======================================================================= -void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, - const Handle(Adaptor3d_TopolTool)& D1, - const Handle(Adaptor3d_HSurface)& S2, - const Handle(Adaptor3d_TopolTool)& D2, +void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1, + const Handle(Adaptor3d_TopolTool)& theD1, + const Handle(Adaptor3d_HSurface)& theS2, + const Handle(Adaptor3d_TopolTool)& theD2, const Standard_Real TolArc, - const Standard_Real TolTang) -{ + const Standard_Real TolTang, + const Standard_Boolean isGeomInt) +{ myTolArc = TolArc; myTolTang = TolTang; - if(myFleche == 0.0) myFleche = 0.01; - if(myUVMaxStep == 0.0) myUVMaxStep = 0.01; - + if(myFleche <= Precision::PConfusion()) + myFleche = 0.01; + if(myUVMaxStep <= Precision::PConfusion()) + myUVMaxStep = 0.01; + done = Standard_False; spnt.Clear(); slin.Clear(); @@ -727,92 +730,108 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, tgte = Standard_False; oppo = Standard_False; - Standard_Integer i; - - GeomAbs_SurfaceType typs1 = S1->GetType(); - GeomAbs_SurfaceType typs2 = S2->GetType(); + GeomAbs_SurfaceType typs1 = theS1->GetType(); + GeomAbs_SurfaceType typs2 = theS2->GetType(); Standard_Boolean TreatAsBiParametric = Standard_False; - if(typs1 == GeomAbs_Cone) { - Standard_Real a1 = S1->Cone().SemiAngle(); - if(a1<0.0) a1=-a1; - if(a1<2.e-2 || a1>1.55) { - if(typs2==GeomAbs_Plane) { - if(a1<2e-2) { - const gp_Dir axec = S1->Cone().Axis().Direction(); - const gp_Dir axep = S2->Plane().Axis().Direction(); - Standard_Real ps=axec.Dot(axep); - if(ps<0.0) { - ps=-ps; - } - if(ps<0.015) { - TreatAsBiParametric = Standard_True; - } - } + if(typs1 == GeomAbs_Cone) + { + const gp_Cone Con1 = theS1->Cone(); + const Standard_Real a1 = Abs(Con1.SemiAngle()); + if((a1 < 0.02) || (a1 > 1.55)) + { + if(typs2==GeomAbs_Plane) + { + if(a1 < 0.02) + { + const gp_Pln Plan2 = theS2->Plane(); + const gp_Dir axec = Con1.Axis().Direction(); + const gp_Dir axep = Plan2.Axis().Direction(); + const Standard_Real ps = Abs(axec.Dot(axep)); + if(ps < 0.015) + { + TreatAsBiParametric = Standard_True; + } + } } - else TreatAsBiParametric = Standard_True; + else + TreatAsBiParametric = Standard_True; } } - if(typs2 == GeomAbs_Cone) { - gp_Cone Con2 = S2->Cone(); - Standard_Real a2 = Con2.SemiAngle(); - if(a2<0.0) a2=-a2; - if(a2<2.e-2 || a2>1.55) { - if(typs1==GeomAbs_Plane) { - if(a2<2e-2) { - const gp_Dir axec = S2->Cone().Axis().Direction(); - const gp_Dir axep = S1->Plane().Axis().Direction(); - Standard_Real ps=axec.Dot(axep); - if(ps<0.0) { - ps=-ps; - } - if(ps<0.015){ - TreatAsBiParametric = Standard_True; - } - } + + if(typs2 == GeomAbs_Cone) + { + const gp_Cone Con2 = theS2->Cone(); + const Standard_Real a2 = Abs(Con2.SemiAngle()); + if((a2 < 0.02) || (a2 > 1.55)) + { + if(typs1 == GeomAbs_Plane) + { + if(a2 < 0.02) + { + const gp_Pln Plan1 = theS1->Plane(); + const gp_Dir axec = Con2.Axis().Direction(); + const gp_Dir axep = Plan1.Axis().Direction(); + const Standard_Real ps = Abs(axec.Dot(axep)); + if(ps<0.015) + { + TreatAsBiParametric = Standard_True; + } + } } - else TreatAsBiParametric = Standard_True; + else + TreatAsBiParametric = Standard_True; } + //// modified by jgv, 15.12.02 for OCC565 //// - if (typs1 == GeomAbs_Cone) { - gp_Cone Con1 = S1->Cone(); - Standard_Real a1 = Con1.SemiAngle(); - if (a1 < 0.0) a1 = -a1; - if (a1 < 2.e-2 && a2 < 2.e-2) {//quasi-cylinders: if same domain, treat as canonic - gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); - if (A1.IsParallel(A2,Precision::Angular())) { - gp_Lin L1(A1); - if (L1.Distance( A2.Location() ) <= Precision::Confusion()){ - TreatAsBiParametric = Standard_False; - } - } + if (typs1 == GeomAbs_Cone) + { + const gp_Cone Con1 = theS1->Cone(); + const Standard_Real a1 = Abs(Con1.SemiAngle()); + if (a1 < 0.02 && a2 < 0.02) //quasi-cylinders: if same domain, treat as canonic + { + const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); + if (A1.IsParallel(A2,Precision::Angular())) + { + const gp_Lin L1(A1); + if (L1.Distance(A2.Location()) <= Precision::Confusion()) + { + TreatAsBiParametric = Standard_False; + } + } } - else if (a1 > 1.55 && a2 > 1.55) { //quasi-planes: if same domain, treat as canonic - gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); - if (A1.IsParallel(A2,Precision::Angular())) { - gp_Pnt Apex1 = Con1.Apex(), Apex2 = Con2.Apex(); - gp_Pln Plan1( Apex1, A1.Direction() ); - if (Plan1.Distance( Apex2 ) <= Precision::Confusion()){ - TreatAsBiParametric = Standard_False; - } - } + else if (a1 > 1.55 && a2 > 1.55) //quasi-planes: if same domain, treat as canonic + { + const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); + if (A1.IsParallel(A2,Precision::Angular())) + { + const gp_Pnt Apex1 = Con1.Apex(), Apex2 = Con2.Apex(); + const gp_Pln Plan1( Apex1, A1.Direction() ); + if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) + { + TreatAsBiParametric = Standard_False; + } + } } - else if ((a1 > 1.55 && a2 < 1.55) || (a2 > 1.55 && a1 < 1.55) ) { - gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); - if (A1.IsCoaxial(A2,Precision::Angular(),Precision::Confusion())) { - TreatAsBiParametric = Standard_False; - } + else if ((a1 > 1.55) || (a2 > 1.55)) + { + const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); + if (A1.IsCoaxial(A2,Precision::Angular(),Precision::Confusion())) + { + TreatAsBiParametric = Standard_False; + } } }// if (typs1 == GeomAbs_Cone) { }// if(typs2 == GeomAbs_Cone) { - // - if(D1->DomainIsInfinite() || D2->DomainIsInfinite()) { + + if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) { TreatAsBiParametric= Standard_False; } // Modified by skv - Mon Sep 26 14:58:30 2005 Begin // if(TreatAsBiParametric) { typs1 = typs2 = GeomAbs_BezierSurface; } - if(TreatAsBiParametric) { + if(TreatAsBiParametric) + { if (typs1 == GeomAbs_Cone && typs2 == GeomAbs_Plane) typs1 = GeomAbs_BezierSurface; // Using Imp-Prm Intersector else if (typs1 == GeomAbs_Plane && typs2 == GeomAbs_Cone) @@ -835,6 +854,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, case GeomAbs_Cone: ts1 = 1; break; default: break; } + Standard_Integer ts2 = 0; switch (typs2) { @@ -844,6 +864,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, case GeomAbs_Cone: ts2 = 1; break; default: break; } + // Possible intersection types: 1. ts1 == ts2 == 1 // 2. ts1 != ts2 // 3. ts1 == ts2 == 0 @@ -851,189 +872,33 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, // Geom - Geom if(ts1 == ts2 && ts1 == 1) { - IntPatch_ImpImpIntersection interii(S1,D1,S2,D2,myTolArc,myTolTang); - if (interii.IsDone()) - { - done = Standard_True; - empt = interii.IsEmpty(); - if (!empt) - { - tgte = interii.TangentFaces(); - if (tgte) oppo = interii.OppositeFaces(); - for (i = 1; i <= interii.NbLines(); i++) - { - const Handle_IntPatch_Line& line = interii.Line(i); - if (line->ArcType() == IntPatch_Analytic) - { - const GeomAbs_SurfaceType typs1 = S1->GetType(); - const GeomAbs_SurfaceType typs2 = S2->GetType(); - IntSurf_Quadric Quad1,Quad2; - switch(typs1) - { - case GeomAbs_Plane: Quad1.SetValue(S1->Plane()); break; - case GeomAbs_Cylinder: Quad1.SetValue(S1->Cylinder()); break; - case GeomAbs_Sphere: Quad1.SetValue(S1->Sphere()); break; - case GeomAbs_Cone: Quad1.SetValue(S1->Cone()); break; - default: break; - } - switch(typs2) - { - case GeomAbs_Plane: Quad2.SetValue(S2->Plane()); break; - case GeomAbs_Cylinder: Quad2.SetValue(S2->Cylinder()); break; - case GeomAbs_Sphere: Quad2.SetValue(S2->Sphere()); break; - case GeomAbs_Cone: Quad2.SetValue(S2->Cone()); break; - default: break; - } - IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,NBPOINTSSURALINE); - Handle(IntPatch_Line) wlin=AToW.MakeWLine((*((Handle_IntPatch_ALine *)(&line)))); - slin.Append(wlin); - } - else slin.Append(interii.Line(i)); - } - for (i = 1; i <= interii.NbPnts(); i++) spnt.Append(interii.Point(i)); - } - } - else goto prm; + const Standard_Boolean RestrictLine = Standard_True; + IntSurf_ListOfPntOn2S ListOfPnts; + ListOfPnts.Clear(); + if(isGeomInt) + { + GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); + } + else + { + ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); + } } + // Geom - Param if(ts1 != ts2) { - //cout << "IP" << endl; - IntPatch_ImpPrmIntersection interip; - if (myIsStartPnt) { - if (ts1 == 0) interip.SetStartPoint(myU1Start,myV1Start); - else interip.SetStartPoint(myU2Start,myV2Start); - } - if(D1->DomainIsInfinite() && D2->DomainIsInfinite()) - { - Standard_Boolean IsPLInt = Standard_False; - TColgp_SequenceOfPnt sop; - gp_Vec v; - FUN_PL_Intersection(S1,typs1,S2,typs2,IsPLInt,sop,v); - if(IsPLInt) - { - if(sop.Length() > 0) - { - for(Standard_Integer ip = 1; ip <= sop.Length(); ip++) - { - gp_Lin lin(sop.Value(ip),gp_Dir(v)); - Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False); - slin.Append(*(Handle_IntPatch_Line *)&gl); - } - done = Standard_True; - } - else done = Standard_False; - return; - } - else - { - Handle(Adaptor3d_HSurface) nS1 = S1; - Handle(Adaptor3d_HSurface) nS2 = S2; - FUN_TrimBothSurf(S1,typs1,S2,typs2,1.e+5,nS1,nS2); - interip.Perform(nS1,D1,nS2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep); - } - } - else interip.Perform(S1,D1,S2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep); -// IntPatch_ImpPrmIntersection interip(S1,D1,S2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep); - if (interip.IsDone()) - { - done = Standard_True; - empt = interip.IsEmpty(); - if (!empt) - { - for(i = 1; i <= interip.NbLines(); i++) - { - if(interip.Line(i)->ArcType() != IntPatch_Walking) slin.Append(interip.Line(i)); - } - for(i = 1; i <= interip.NbLines(); i++) - { - if(interip.Line(i)->ArcType() == IntPatch_Walking) slin.Append(interip.Line(i)); - } - for (i = 1; i <= interip.NbPnts(); i++) spnt.Append(interip.Point(i)); - } - } + GeomParamPerfom(theS1, theD1, theS2, theD2, ts1 == 0, typs1, typs2); } + // Param - Param if(ts1 == ts2 && ts1 == 0) { - //cout << "PP" << endl; -prm:; // this algorithm was modified last by OFV [29-Oct-2001] -> [2-Nov-2001] - IntPatch_PrmPrmIntersection interpp; - if(!D1->DomainIsInfinite() && !D2->DomainIsInfinite()) - { - interpp.Perform(S1,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep); - goto met; - } - else if( (!D1->DomainIsInfinite() && D2->DomainIsInfinite()) || (D1->DomainIsInfinite() && !D2->DomainIsInfinite()) ) - { - gp_Pnt pMaxXYZ, pMinXYZ; - if(D1->DomainIsInfinite()) - { - FUN_GetMinMaxXYZPnt( S2, pMinXYZ, pMaxXYZ ); - const Standard_Real MU = Max(Abs(S2->FirstUParameter()),Abs(S2->LastUParameter())); - const Standard_Real MV = Max(Abs(S2->FirstVParameter()),Abs(S2->LastVParameter())); - const Standard_Real AP = Max(MU, MV); - Handle(Adaptor3d_HSurface) SS; - FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, S1, AP, SS); - interpp.Perform(SS,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep); - } - else - { - FUN_GetMinMaxXYZPnt( S1, pMinXYZ, pMaxXYZ ); - const Standard_Real MU = Max(Abs(S1->FirstUParameter()),Abs(S1->LastUParameter())); - const Standard_Real MV = Max(Abs(S1->FirstVParameter()),Abs(S1->LastVParameter())); - const Standard_Real AP = Max(MU, MV); - Handle(Adaptor3d_HSurface) SS; - FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, S2, AP, SS); - interpp.Perform(S1,D1,SS,D2,TolArc,TolTang,myFleche,myUVMaxStep); - } - goto met; - }//(!D1->DomainIsInfinite() && D2->DomainIsInfinite()) || (D1->DomainIsInfinite() && !D2->DomainIsInfinite()) - else - { - if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface){ done = Standard_False; return; } - Standard_Boolean IsPLInt = Standard_False; - TColgp_SequenceOfPnt sop; - gp_Vec v; - FUN_PL_Intersection(S1,typs1,S2,typs2,IsPLInt,sop,v); - if(IsPLInt) - { - if(sop.Length() > 0) - { - for(Standard_Integer ip = 1; ip <= sop.Length(); ip++) - { - gp_Lin lin(sop.Value(ip),gp_Dir(v)); - Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False); - slin.Append(*(Handle_IntPatch_Line *)&gl); - } - done = Standard_True; - } - else done = Standard_False; - return; - } // 'COLLINEAR LINES' - else - { - Handle(Adaptor3d_HSurface) nS1 = S1; - Handle(Adaptor3d_HSurface) nS2 = S2; - FUN_TrimBothSurf(S1,typs1,S2,typs2,1.e+8,nS1,nS2); - interpp.Perform(nS1,D1,nS2,D2,TolArc,TolTang,myFleche,myUVMaxStep); - goto met; - }// 'NON - COLLINEAR LINES' - }// both domains are infinite -met:if (interpp.IsDone()) - { - done = Standard_True; - tgte = Standard_False; - empt = interpp.IsEmpty(); - for(i=1; i <= interpp.NbLines(); i++) - { - if(interpp.Line(i)->ArcType() != IntPatch_Walking) slin.Append(interpp.Line(i)); - } - for(i=1; i <= interpp.NbLines(); i++) - { - if(interpp.Line(i)->ArcType() == IntPatch_Walking) slin.Append(interpp.Line(i)); - } - } + const Standard_Boolean RestrictLine = Standard_True; + IntSurf_ListOfPntOn2S ListOfPnts; + ListOfPnts.Clear(); + + ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); } } @@ -1041,19 +906,22 @@ met:if (interpp.IsDone()) //function : Perform //purpose : //======================================================================= -void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, - const Handle(Adaptor3d_TopolTool)& D1, - const Handle(Adaptor3d_HSurface)& S2, - const Handle(Adaptor3d_TopolTool)& D2, +void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1, + const Handle(Adaptor3d_TopolTool)& theD1, + const Handle(Adaptor3d_HSurface)& theS2, + const Handle(Adaptor3d_TopolTool)& theD2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& ListOfPnts, - const Standard_Boolean RestrictLine) + const Standard_Boolean RestrictLine, + const Standard_Boolean isGeomInt) { myTolArc = TolArc; myTolTang = TolTang; - if(myFleche == 0.0) myFleche = 0.01; - if(myUVMaxStep == 0.0) myUVMaxStep = 0.01; + if(myFleche <= Precision::PConfusion()) + myFleche = 0.01; + if(myUVMaxStep <= Precision::PConfusion()) + myUVMaxStep = 0.01; done = Standard_False; spnt.Clear(); @@ -1062,101 +930,109 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, tgte = Standard_False; oppo = Standard_False; - Standard_Integer i; - - GeomAbs_SurfaceType typs1 = S1->GetType(); - GeomAbs_SurfaceType typs2 = S2->GetType(); + GeomAbs_SurfaceType typs1 = theS1->GetType(); + GeomAbs_SurfaceType typs2 = theS2->GetType(); Standard_Boolean TreatAsBiParametric = Standard_False; - if(typs1 == GeomAbs_Cone) { - Standard_Real a1 = S1->Cone().SemiAngle(); - if(a1<0.0) a1=-a1; - if(a1<2e-2 || a1>1.55) { - if(typs2==GeomAbs_Plane) { - if(a1<2e-2) { - gp_Dir axec = S1->Cone().Axis().Direction(); - gp_Dir axep = S2->Plane().Axis().Direction(); - Standard_Real ps=axec.Dot(axep); - if(ps<0.0) { - ps=-ps; - } - if(ps<0.015) { - TreatAsBiParametric = Standard_True; - } - } - } - else { - TreatAsBiParametric = Standard_True; - } - } - } - if(typs2 == GeomAbs_Cone) { - Standard_Real a2 = S2->Cone().SemiAngle(); - if(a2<0.0) a2=-a2; - if(a2<2.e-2 || a2>1.55) { - if(typs1==GeomAbs_Plane) { - if(a2<2e-2) { - const gp_Dir axec = S2->Cone().Axis().Direction(); - const gp_Dir axep = S1->Plane().Axis().Direction(); - Standard_Real ps=axec.Dot(axep); - if(ps<0.0){ - ps=-ps; - } - if(ps<0.015){ - TreatAsBiParametric = Standard_True; - } - } - } - else { - TreatAsBiParametric = Standard_True; - } - } - } - //// modified by jgv, 15.12.02 for OCC565 //// - if (typs1 == GeomAbs_Cone && typs2 == GeomAbs_Cone) + if(typs1 == GeomAbs_Cone) { - gp_Cone Con1 = S1->Cone(); - gp_Cone Con2 = S2->Cone(); - Standard_Real a1 = Con1.SemiAngle(); - if (a1 < 0.0) a1 = -a1; - Standard_Real a2 = Con2.SemiAngle(); - if (a2 < 0.0) a2 = -a2; - if (a1 < 2e-2 && a2 < 2e-2) //quasi-cylinders: if same domain, treat as canonic - { - gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); - if (A1.IsParallel(A2,Precision::Angular())) - { - gp_Lin L1(A1); - if (L1.Distance( A2.Location() ) <= Precision::Confusion()) - TreatAsBiParametric = Standard_False; - } - } - else if (a1 > 1.55 && a2 > 1.55) //quasi-planes: if same domain, treat as canonic - { - gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); - if (A1.IsParallel(A2,Precision::Angular())) - { - gp_Pnt Apex1 = Con1.Apex(), Apex2 = Con2.Apex(); - gp_Pln Plan1( Apex1, A1.Direction() ); - if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) - TreatAsBiParametric = Standard_False; - } - } - else if ((a1 > 1.55 && a2 < 1.55) || (a2 > 1.55 && a1 < 1.55) ) { - gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); - if (A1.IsCoaxial(A2,Precision::Angular(),Precision::Confusion())) { - TreatAsBiParametric = Standard_False; + const gp_Cone Con1 = theS1->Cone(); + const Standard_Real a1 = Abs(Con1.SemiAngle()); + if((a1 < 0.02) || (a1 > 1.55)) + { + if(typs2==GeomAbs_Plane) + { + if(a1 < 0.02) + { + const gp_Pln Plan2 = theS2->Plane(); + const gp_Dir axec = Con1.Axis().Direction(); + const gp_Dir axep = Plan2.Axis().Direction(); + const Standard_Real ps = Abs(axec.Dot(axep)); + if(ps < 0.015) + { + TreatAsBiParametric = Standard_True; + } + } } + else + TreatAsBiParametric = Standard_True; } } - ////////////////////////////////////////////// - if(D1->DomainIsInfinite() || D2->DomainIsInfinite()) { + if(typs2 == GeomAbs_Cone) + { + const gp_Cone Con2 = theS2->Cone(); + const Standard_Real a2 = Abs(Con2.SemiAngle()); + if((a2 < 0.02) || (a2 > 1.55)) + { + if(typs1 == GeomAbs_Plane) + { + if(a2 < 0.02) + { + const gp_Pln Plan1 = theS1->Plane(); + const gp_Dir axec = Con2.Axis().Direction(); + const gp_Dir axep = Plan1.Axis().Direction(); + const Standard_Real ps = Abs(axec.Dot(axep)); + if(ps<0.015) + { + TreatAsBiParametric = Standard_True; + } + } + } + else + TreatAsBiParametric = Standard_True; + } + + //// modified by jgv, 15.12.02 for OCC565 //// + if (typs1 == GeomAbs_Cone) + { + const gp_Cone Con1 = theS1->Cone(); + const Standard_Real a1 = Abs(Con1.SemiAngle()); + if (a1 < 0.02 && a2 < 0.02) //quasi-cylinders: if same domain, treat as canonic + { + const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); + if (A1.IsParallel(A2,Precision::Angular())) + { + const gp_Lin L1(A1); + if (L1.Distance(A2.Location()) <= Precision::Confusion()) + { + TreatAsBiParametric = Standard_False; + } + } + } + else if (a1 > 1.55 && a2 > 1.55) //quasi-planes: if same domain, treat as canonic + { + const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); + if (A1.IsParallel(A2,Precision::Angular())) + { + const gp_Pnt Apex1 = Con1.Apex(), Apex2 = Con2.Apex(); + const gp_Pln Plan1( Apex1, A1.Direction() ); + if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) + { + TreatAsBiParametric = Standard_False; + } + } + } + else if ((a1 > 1.55) || (a2 > 1.55)) + { + const gp_Ax1 A1 = Con1.Axis(), A2 = Con2.Axis(); + if (A1.IsCoaxial(A2,Precision::Angular(),Precision::Confusion())) + { + TreatAsBiParametric = Standard_False; + } + } + }// if (typs1 == GeomAbs_Cone) { + }// if(typs2 == GeomAbs_Cone) { + + if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) { TreatAsBiParametric= Standard_False; } - if(TreatAsBiParametric) { - typs1 = GeomAbs_BezierSurface; - typs2 = GeomAbs_BezierSurface; + + if(TreatAsBiParametric) + { + // Using Prm-Prm Intersector + typs1 = GeomAbs_BezierSurface; + typs2 = GeomAbs_BezierSurface; } // Surface type definition @@ -1169,6 +1045,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, case GeomAbs_Cone: ts1 = 1; break; default: break; } + Standard_Integer ts2 = 0; switch (typs2) { @@ -1178,206 +1055,319 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, case GeomAbs_Cone: ts2 = 1; break; default: break; } + // Possible intersection types: 1. ts1 == ts2 == 1 // 2. ts1 != ts2 // 3. ts1 == ts2 == 0 - // Geom - Geom - if(ts1 == ts2 && ts1 == 1) + if(!isGeomInt) { - IntPatch_ImpImpIntersection interii(S1,D1,S2,D2,myTolArc,myTolTang); - if (interii.IsDone()) - { - done = Standard_True; - empt = interii.IsEmpty(); - if (!empt) - { - tgte = interii.TangentFaces(); - if (tgte) oppo = interii.OppositeFaces(); - for (i = 1; i <= interii.NbLines(); i++) - { - const Handle_IntPatch_Line& line = interii.Line(i); - if (line->ArcType() == IntPatch_Analytic) - { - const GeomAbs_SurfaceType typs1 = S1->GetType(); - const GeomAbs_SurfaceType typs2 = S2->GetType(); - IntSurf_Quadric Quad1,Quad2; - switch(typs1) - { - case GeomAbs_Plane: Quad1.SetValue(S1->Plane()); break; - case GeomAbs_Cylinder: Quad1.SetValue(S1->Cylinder()); break; - case GeomAbs_Sphere: Quad1.SetValue(S1->Sphere()); break; - case GeomAbs_Cone: Quad1.SetValue(S1->Cone()); break; - default: break; - } - switch(typs2) - { - case GeomAbs_Plane: Quad2.SetValue(S2->Plane()); break; - case GeomAbs_Cylinder: Quad2.SetValue(S2->Cylinder()); break; - case GeomAbs_Sphere: Quad2.SetValue(S2->Sphere()); break; - case GeomAbs_Cone: Quad2.SetValue(S2->Cone()); break; - default: break; - } - IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,NBPOINTSSURALINE); - Handle(IntPatch_Line) wlin=AToW.MakeWLine((*((Handle_IntPatch_ALine *)(&line)))); - slin.Append(wlin); - } - else slin.Append(interii.Line(i)); - } - for (i = 1; i <= interii.NbPnts(); i++) spnt.Append(interii.Point(i)); - } - } - else goto prm; + ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); } - // Geom - Param - if(ts1 != ts2) + else if(ts1 != ts2) { - //cout << "IP" << endl; - IntPatch_ImpPrmIntersection interip; - if (myIsStartPnt) { - if (ts1 == 0) interip.SetStartPoint(myU1Start,myV1Start); - else interip.SetStartPoint(myU2Start,myV2Start); - } - if(D1->DomainIsInfinite() && D2->DomainIsInfinite()) - { - Standard_Boolean IsPLInt = Standard_False; - TColgp_SequenceOfPnt sop; - gp_Vec v; - FUN_PL_Intersection(S1,typs1,S2,typs2,IsPLInt,sop,v); - if(IsPLInt) - { - if(sop.Length() > 0) - { - for(Standard_Integer ip = 1; ip <= sop.Length(); ip++) - { - gp_Lin lin(sop.Value(ip),gp_Dir(v)); - Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False); - slin.Append(*(Handle_IntPatch_Line *)&gl); - } - done = Standard_True; - } - else done = Standard_False; - return; - } - else - { - Handle(Adaptor3d_HSurface) nS1 = S1; - Handle(Adaptor3d_HSurface) nS2 = S2; - FUN_TrimBothSurf(S1,typs1,S2,typs2,1.e+5,nS1,nS2); - interip.Perform(nS1,D1,nS2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep); - } - } - else interip.Perform(S1,D1,S2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep); -// IntPatch_ImpPrmIntersection interip(S1,D1,S2,D2,myTolArc,myTolTang,myFleche,myUVMaxStep); - if (interip.IsDone()) - { - done = Standard_True; - empt = interip.IsEmpty(); - if (!empt) - { - for(i = 1; i <= interip.NbLines(); i++) - { - if(interip.Line(i)->ArcType() != IntPatch_Walking) slin.Append(interip.Line(i)); - } - for(i = 1; i <= interip.NbLines(); i++) - { - if(interip.Line(i)->ArcType() == IntPatch_Walking) slin.Append(interip.Line(i)); - } - for (i = 1; i <= interip.NbPnts(); i++) spnt.Append(interip.Point(i)); - } - } + GeomParamPerfom(theS1, theD1, theS2, theD2, ts1 == 0, typs1, typs2); } - // Param - Param - if(ts1 == ts2 && ts1 == 0) + else if (ts1 == 0) { - //cout << "PP" << endl; -prm:; // this algorithm was modified last by OFV [29-Oct-2001] -> [2-Nov-2001] - IntPatch_PrmPrmIntersection interpp; - if(!D1->DomainIsInfinite() && !D2->DomainIsInfinite()) - { - // modified by NIZHNY-AMV Tue Oct 18 12:37:02 2005.BEGIN - Standard_Boolean ClearFlag = Standard_True; - if(!ListOfPnts.IsEmpty()){ - interpp.Perform(S1,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep, ListOfPnts, RestrictLine); - ClearFlag = Standard_False; - } - // modified by NIZHNY-AMV Tue Oct 18 12:37:02 2005.END - interpp.Perform(S1,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep,ClearFlag); - goto met; - } - else if( (!D1->DomainIsInfinite() && D2->DomainIsInfinite()) || (D1->DomainIsInfinite() && !D2->DomainIsInfinite()) ) - { - gp_Pnt pMaxXYZ, pMinXYZ; - if(D1->DomainIsInfinite()) - { - FUN_GetMinMaxXYZPnt( S2, pMinXYZ, pMaxXYZ ); - const Standard_Real MU = Max(Abs(S2->FirstUParameter()),Abs(S2->LastUParameter())); - const Standard_Real MV = Max(Abs(S2->FirstVParameter()),Abs(S2->LastVParameter())); - const Standard_Real AP = Max(MU, MV); - Handle(Adaptor3d_HSurface) SS; - FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, S1, AP, SS); - interpp.Perform(SS,D1,S2,D2,TolArc,TolTang,myFleche,myUVMaxStep); - } - else - { - FUN_GetMinMaxXYZPnt( S1, pMinXYZ, pMaxXYZ ); - const Standard_Real MU = Max(Abs(S1->FirstUParameter()),Abs(S1->LastUParameter())); - const Standard_Real MV = Max(Abs(S1->FirstVParameter()),Abs(S1->LastVParameter())); - const Standard_Real AP = Max(MU, MV); - Handle(Adaptor3d_HSurface) SS; - FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, S2, AP, SS); - interpp.Perform(S1,D1,SS,D2,TolArc,TolTang,myFleche,myUVMaxStep); - } - goto met; - }//(!D1->DomainIsInfinite() && D2->DomainIsInfinite()) || (D1->DomainIsInfinite() && !D2->DomainIsInfinite()) - else - { - if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface){ done = Standard_False; return; } - Standard_Boolean IsPLInt = Standard_False; - TColgp_SequenceOfPnt sop; - gp_Vec v; - FUN_PL_Intersection(S1,typs1,S2,typs2,IsPLInt,sop,v); - if(IsPLInt) - { - if(sop.Length() > 0) - { - for(Standard_Integer ip = 1; ip <= sop.Length(); ip++) - { - gp_Lin lin(sop.Value(ip),gp_Dir(v)); - Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False); - slin.Append(*(Handle_IntPatch_Line *)&gl); - } - done = Standard_True; - } - else done = Standard_False; - return; - } // 'COLLINEAR LINES' - else - { - Handle(Adaptor3d_HSurface) nS1 = S1; - Handle(Adaptor3d_HSurface) nS2 = S2; - FUN_TrimBothSurf(S1,typs1,S2,typs2,1.e+8,nS1,nS2); - interpp.Perform(nS1,D1,nS2,D2,TolArc,TolTang,myFleche,myUVMaxStep); - goto met; - }// 'NON - COLLINEAR LINES' - }// both domains are infinite -met: if (interpp.IsDone()) - { - done = Standard_True; - tgte = Standard_False; - empt = interpp.IsEmpty(); - for(i=1; i <= interpp.NbLines(); i++) - { - if(interpp.Line(i)->ArcType() != IntPatch_Walking) slin.Append(interpp.Line(i)); - } - for (i=1; i <= interpp.NbLines(); i++) - { - if(interpp.Line(i)->ArcType() == IntPatch_Walking) slin.Append(interpp.Line(i)); - } - } + ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); + } + else if(ts1 == 1) + { + GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); } } +//======================================================================= +//function : ParamParamPerfom +//purpose : +//======================================================================= +void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)& theS1, + const Handle(Adaptor3d_TopolTool)& theD1, + const Handle(Adaptor3d_HSurface)& theS2, + const Handle(Adaptor3d_TopolTool)& theD2, + const Standard_Real TolArc, + const Standard_Real TolTang, + IntSurf_ListOfPntOn2S& ListOfPnts, + const Standard_Boolean RestrictLine, + const GeomAbs_SurfaceType typs1, + const GeomAbs_SurfaceType typs2) +{ + IntPatch_PrmPrmIntersection interpp; + if(!theD1->DomainIsInfinite() && !theD2->DomainIsInfinite()) + { + Standard_Boolean ClearFlag = Standard_True; + if(!ListOfPnts.IsEmpty()) + { + interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep, ListOfPnts, RestrictLine); + ClearFlag = Standard_False; + } + interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep,ClearFlag); //double call!!!!!!! + } + else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())) + { + gp_Pnt pMaxXYZ, pMinXYZ; + if(theD1->DomainIsInfinite()) + { + FUN_GetMinMaxXYZPnt( theS2, pMinXYZ, pMaxXYZ ); + const Standard_Real MU = Max(Abs(theS2->FirstUParameter()),Abs(theS2->LastUParameter())); + const Standard_Real MV = Max(Abs(theS2->FirstVParameter()),Abs(theS2->LastVParameter())); + const Standard_Real AP = Max(MU, MV); + Handle(Adaptor3d_HSurface) SS; + FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS); + interpp.Perform(SS,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep); + } + else + { + FUN_GetMinMaxXYZPnt( theS1, pMinXYZ, pMaxXYZ ); + const Standard_Real MU = Max(Abs(theS1->FirstUParameter()),Abs(theS1->LastUParameter())); + const Standard_Real MV = Max(Abs(theS1->FirstVParameter()),Abs(theS1->LastVParameter())); + const Standard_Real AP = Max(MU, MV); + Handle(Adaptor3d_HSurface) SS; + FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS); + interpp.Perform(theS1, theD1, SS, theD2,TolArc,TolTang,myFleche,myUVMaxStep); + } + }//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()) + else + { + if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface) + { + done = Standard_False; + return; + } + + Standard_Boolean IsPLInt = Standard_False; + TColgp_SequenceOfPnt sop; + gp_Vec v; + FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v); + + if(IsPLInt) + { + if(sop.Length() > 0) + { + for(Standard_Integer ip = 1; ip <= sop.Length(); ip++) + { + gp_Lin lin(sop.Value(ip),gp_Dir(v)); + Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False); + slin.Append(*(Handle_IntPatch_Line *)&gl); + } + + done = Standard_True; + } + else + done = Standard_False; + + return; + }// 'COLLINEAR LINES' + else + { + Handle(Adaptor3d_HSurface) nS1 = theS1; + Handle(Adaptor3d_HSurface) nS2 = theS2; + FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2); + interpp.Perform(nS1,theD1,nS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep); + }// 'NON - COLLINEAR LINES' + }// both domains are infinite + + if (interpp.IsDone()) + { + done = Standard_True; + tgte = Standard_False; + empt = interpp.IsEmpty(); + + for(Standard_Integer i = 1; i <= interpp.NbLines(); i++) + { + if(interpp.Line(i)->ArcType() != IntPatch_Walking) + slin.Append(interpp.Line(i)); + } + + for (Standard_Integer i = 1; i <= interpp.NbLines(); i++) + { + if(interpp.Line(i)->ArcType() == IntPatch_Walking) + slin.Append(interpp.Line(i)); + } + } +} + +//======================================================================= +////function : GeomGeomPerfom +//purpose : +//======================================================================= +void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& theS1, + const Handle(Adaptor3d_TopolTool)& theD1, + const Handle(Adaptor3d_HSurface)& theS2, + const Handle(Adaptor3d_TopolTool)& theD2, + const Standard_Real TolArc, + const Standard_Real TolTang, + IntSurf_ListOfPntOn2S& ListOfPnts, + const Standard_Boolean RestrictLine, + const GeomAbs_SurfaceType typs1, + const GeomAbs_SurfaceType typs2) +{ + IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,myTolArc,myTolTang); + const Standard_Boolean anIS = interii.IsDone(); + if (anIS) + { + done = anIS; + empt = interii.IsEmpty(); + if (!empt) + { + tgte = interii.TangentFaces(); + if (tgte) + oppo = interii.OppositeFaces(); + + for (Standard_Integer i = 1; i <= interii.NbLines(); i++) + { + const Handle_IntPatch_Line& line = interii.Line(i); + if (line->ArcType() == IntPatch_Analytic) + { + const GeomAbs_SurfaceType typs1 = theS1->GetType(); + const GeomAbs_SurfaceType typs2 = theS2->GetType(); + IntSurf_Quadric Quad1,Quad2; + + switch(typs1) + { + case GeomAbs_Plane: + Quad1.SetValue(theS1->Plane()); + break; + + case GeomAbs_Cylinder: + Quad1.SetValue(theS1->Cylinder()); + break; + + case GeomAbs_Sphere: + Quad1.SetValue(theS1->Sphere()); + break; + + case GeomAbs_Cone: + Quad1.SetValue(theS1->Cone()); + break; + + default: + break; + } + + switch(typs2) + { + case GeomAbs_Plane: + Quad2.SetValue(theS2->Plane()); + break; + case GeomAbs_Cylinder: + Quad2.SetValue(theS2->Cylinder()); + break; + + case GeomAbs_Sphere: + Quad2.SetValue(theS2->Sphere()); + break; + + case GeomAbs_Cone: + Quad2.SetValue(theS2->Cone()); + break; + + default: + break; + } + + IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,aNbPointsInALine); + Handle(IntPatch_Line) wlin=AToW.MakeWLine((*((Handle_IntPatch_ALine *)(&line)))); + slin.Append(wlin); + } + else + slin.Append(interii.Line(i)); + } + + for (Standard_Integer i = 1; i <= interii.NbPnts(); i++) + { + spnt.Append(interii.Point(i)); + } + } + } + else + ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2); +} + +//======================================================================= +////function : GeomParamPerfom +//purpose : +//======================================================================= +void IntPatch_Intersection::GeomParamPerfom(const Handle(Adaptor3d_HSurface)& theS1, + const Handle(Adaptor3d_TopolTool)& theD1, + const Handle(Adaptor3d_HSurface)& theS2, + const Handle(Adaptor3d_TopolTool)& theD2, + const Standard_Boolean isNotAnalitical, + const GeomAbs_SurfaceType typs1, + const GeomAbs_SurfaceType typs2) +{ + IntPatch_ImpPrmIntersection interip; + if (myIsStartPnt) + { + if (isNotAnalitical/*ts1 == 0*/) + interip.SetStartPoint(myU1Start,myV1Start); + else + interip.SetStartPoint(myU2Start,myV2Start); + } + + if(theD1->DomainIsInfinite() && theD2->DomainIsInfinite()) + { + Standard_Boolean IsPLInt = Standard_False; + TColgp_SequenceOfPnt sop; + gp_Vec v; + FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v); + + if(IsPLInt) + { + if(sop.Length() > 0) + { + for(Standard_Integer ip = 1; ip <= sop.Length(); ip++) + { + gp_Lin lin(sop.Value(ip),gp_Dir(v)); + Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False); + slin.Append(*(Handle_IntPatch_Line *)&gl); + } + + done = Standard_True; + } + else + done = Standard_False; + + return; + } + else + { + Handle(Adaptor3d_HSurface) nS1 = theS1; + Handle(Adaptor3d_HSurface) nS2 = theS2; + FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+5,nS1,nS2); + interip.Perform(nS1,theD1,nS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep); + } + } + else + interip.Perform(theS1,theD1,theS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep); + + if (interip.IsDone()) + { + done = Standard_True; + empt = interip.IsEmpty(); + + if (!empt) + { + for(Standard_Integer i = 1; i <= interip.NbLines(); i++) + { + if(interip.Line(i)->ArcType() != IntPatch_Walking) + slin.Append(interip.Line(i)); + } + + for(Standard_Integer i = 1; i <= interip.NbLines(); i++) + { + if(interip.Line(i)->ArcType() == IntPatch_Walking) + slin.Append(interip.Line(i)); + } + + for (Standard_Integer i = 1; i <= interip.NbPnts(); i++) + spnt.Append(interip.Point(i)); + } + } +} + + void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, diff --git a/src/IntTools/IntTools_FaceFace.cdl b/src/IntTools/IntTools_FaceFace.cdl index fc8678ea10..2f87172637 100755 --- a/src/IntTools/IntTools_FaceFace.cdl +++ b/src/IntTools/IntTools_FaceFace.cdl @@ -25,13 +25,13 @@ class FaceFace from IntTools uses - TopolTool from Adaptor3d, - HSurface from GeomAdaptor, - ListOfPntOn2S from IntSurf , - Intersection from IntPatch, - Face from TopoDS, - SequenceOfCurves from IntTools, - LineConstructor from IntTools, + TopolTool from Adaptor3d, + HSurface from GeomAdaptor, + ListOfPntOn2S from IntSurf , + Intersection from IntPatch, + Face from TopoDS, + SequenceOfCurves from IntTools, + LineConstructor from IntTools, SequenceOfPntOn2Faces from IntTools, Context from BOPInt diff --git a/src/IntTools/IntTools_FaceFace.cxx b/src/IntTools/IntTools_FaceFace.cxx index 30a6804107..7815d6a27e 100755 --- a/src/IntTools/IntTools_FaceFace.cxx +++ b/src/IntTools/IntTools_FaceFace.cxx @@ -283,11 +283,8 @@ static static void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1, - const Handle(GeomAdaptor_HSurface)& aHS2, - Standard_Real& aTolArc, - Standard_Real& aTolTang, - Standard_Real& aUVMaxStep, - Standard_Real& aDeflection); + const Handle(GeomAdaptor_HSurface)& aHS2, + Standard_Real& aTolTang); static Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1, @@ -413,7 +410,7 @@ const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const { StdFail_NotDone_Raise_if (!myIsDone, - "IntTools_FaceFace::Lines() => !myIntersector.IsDone()"); + "IntTools_FaceFace::Lines() => myIntersector NOT DONE"); return mySeqOfCurve; } //======================================================================= @@ -446,127 +443,209 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts) { myListOfPnts = aListOfPnts; } + + +static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1, + const TopoDS_Face& theF2) +{ + const Standard_Real Tolang = 1.e-8; + const Standard_Real aTolF1=BRep_Tool::Tolerance(theF1); + const Standard_Real aTolF2=BRep_Tool::Tolerance(theF2); + const Standard_Real aTolSum = aTolF1 + aTolF2; + Standard_Real aHigh = 0.0; + + const BRepAdaptor_Surface aBAS1(theF1), aBAS2(theF2); + const GeomAbs_SurfaceType aType1=aBAS1.GetType(); + const GeomAbs_SurfaceType aType2=aBAS2.GetType(); + + gp_Pln aS1; + gp_Cylinder aS2; + if(aType1 == GeomAbs_Plane) + { + aS1=aBAS1.Plane(); + } + else if(aType2 == GeomAbs_Plane) + { + aS1=aBAS2.Plane(); + } + else + { + return Standard_True; + } + + if(aType1 == GeomAbs_Cylinder) + { + aS2=aBAS1.Cylinder(); + const Standard_Real VMin = aBAS1.FirstVParameter(); + const Standard_Real VMax = aBAS1.LastVParameter(); + + if( Precision::IsNegativeInfinite(VMin) || + Precision::IsPositiveInfinite(VMax)) + return Standard_True; + else + aHigh = VMax - VMin; + } + else if(aType2 == GeomAbs_Cylinder) + { + aS2=aBAS2.Cylinder(); + + const Standard_Real VMin = aBAS2.FirstVParameter(); + const Standard_Real VMax = aBAS2.LastVParameter(); + + if( Precision::IsNegativeInfinite(VMin) || + Precision::IsPositiveInfinite(VMax)) + return Standard_True; + else + aHigh = VMax - VMin; + } + else + { + return Standard_True; + } + + IntAna_QuadQuadGeo inter; + inter.Perform(aS1,aS2,Tolang,aTolSum, aHigh); + if(inter.TypeInter() == IntAna_Ellipse) + { + const gp_Elips anEl = inter.Ellipse(1); + const Standard_Real aMajorR = anEl.MajorRadius(); + const Standard_Real aMinorR = anEl.MinorRadius(); + + return (aMajorR < 100000.0 * aMinorR); + } + else + { + return inter.IsDone(); + } +} + + + //======================================================================= //function : Perform //purpose : intersect surfaces of the faces //======================================================================= void IntTools_FaceFace::Perform(const TopoDS_Face& aF1, - const TopoDS_Face& aF2) + const TopoDS_Face& aF2) { - Standard_Boolean hasCone, RestrictLine, bTwoPlanes, bReverse; - Standard_Integer aNbLin, aNbPnts, i, NbLinPP; - Standard_Real TolArc, TolTang, Deflection, UVMaxStep; - Standard_Real umin, umax, vmin, vmax; - Standard_Real aTolF1, aTolF2; - GeomAbs_SurfaceType aType1, aType2; - Handle(Geom_Surface) S1, S2; - Handle(IntTools_TopolTool) dom1, dom2; - BRepAdaptor_Surface aBAS1, aBAS2; - // + Standard_Boolean RestrictLine = Standard_False, hasCone = Standard_False; + if (myContext.IsNull()) { myContext=new BOPInt_Context; } - // + mySeqOfCurve.Clear(); myTolReached2d=0.; myTolReached3d=0.; myIsDone = Standard_False; myNbrestr=0;//? - hasCone = Standard_False; - bTwoPlanes = Standard_False; - // + myFace1=aF1; myFace2=aF2; - // - aBAS1.Initialize(myFace1, Standard_False); - aBAS2.Initialize(myFace2, Standard_False); - aType1=aBAS1.GetType(); - aType2=aBAS2.GetType(); - // - bReverse=SortTypes(aType1, aType2); - if (bReverse) { + + const BRepAdaptor_Surface aBAS1(myFace1, Standard_False); + const BRepAdaptor_Surface aBAS2(myFace2, Standard_False); + GeomAbs_SurfaceType aType1=aBAS1.GetType(); + GeomAbs_SurfaceType aType2=aBAS2.GetType(); + + const Standard_Boolean bReverse=SortTypes(aType1, aType2); + if (bReverse) + { myFace1=aF2; myFace2=aF1; aType1=aBAS2.GetType(); aType2=aBAS1.GetType(); - // - if (myListOfPnts.Extent()) { + + if (myListOfPnts.Extent()) + { Standard_Real aU1,aV1,aU2,aV2; IntSurf_ListIteratorOfListOfPntOn2S aItP2S; // aItP2S.Initialize(myListOfPnts); - for (; aItP2S.More(); aItP2S.Next()){ - IntSurf_PntOn2S& aP2S=aItP2S.Value(); - aP2S.Parameters(aU1,aV1,aU2,aV2); - aP2S.SetValue(aU2,aV2,aU1,aV1); + for (; aItP2S.More(); aItP2S.Next()) + { + IntSurf_PntOn2S& aP2S=aItP2S.Value(); + aP2S.Parameters(aU1,aV1,aU2,aV2); + aP2S.SetValue(aU2,aV2,aU1,aV1); } } } - // - S1=BRep_Tool::Surface(myFace1); - S2=BRep_Tool::Surface(myFace2); - // - aTolF1=BRep_Tool::Tolerance(myFace1); - aTolF2=BRep_Tool::Tolerance(myFace2); - // - TolArc= aTolF1 + aTolF2; - TolTang = TolArc; - // - NbLinPP = 0; - if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){ - bTwoPlanes = Standard_True; + + const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1); + const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2); + + const Standard_Real aTolF1=BRep_Tool::Tolerance(myFace1); + const Standard_Real aTolF2=BRep_Tool::Tolerance(myFace2); + + Standard_Real TolArc = aTolF1 + aTolF2; + Standard_Real TolTang = TolArc; + + const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder || + aType1 == GeomAbs_Cone || + aType1 == GeomAbs_Torus); + + const Standard_Boolean isFace2Quad = (aType2 == GeomAbs_Cylinder || + aType2 == GeomAbs_Cone || + aType2 == GeomAbs_Torus); + + if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) + { + Standard_Real umin, umax, vmin, vmax; BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax); myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax); // BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax); myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax); Standard_Real TolAng = 1.e-8; - PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2, - mySeqOfCurve, myTangentFaces); + + PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2, + mySeqOfCurve, myTangentFaces); myIsDone = Standard_True; - if(!myTangentFaces) { - // - NbLinPP = mySeqOfCurve.Length(); - if(NbLinPP) { - Standard_Real aTolFMax; - // - myTolReached3d = 1.e-7; - // - aTolFMax=Max(aTolF1, aTolF2); - // - if (aTolFMax>myTolReached3d) { - myTolReached3d=aTolFMax; - } - myTolReached2d = myTolReached3d; - // - if (bReverse) { - Handle(Geom2d_Curve) aC2D1, aC2D2; - // - aNbLin=mySeqOfCurve.Length(); - for (i=1; i<=aNbLin; ++i) { - IntTools_Curve& aIC=mySeqOfCurve(i); - aC2D1=aIC.FirstCurve2d(); - aC2D2=aIC.SecondCurve2d(); - // - aIC.SetFirstCurve2d(aC2D2); - aIC.SetSecondCurve2d(aC2D1); - } - } + if(!myTangentFaces) + { + const Standard_Integer NbLinPP = mySeqOfCurve.Length(); + if(NbLinPP) + { + Standard_Real aTolFMax; + myTolReached3d = 1.e-7; + aTolFMax=Max(aTolF1, aTolF2); + if (aTolFMax>myTolReached3d) + { + myTolReached3d=aTolFMax; + } + + myTolReached2d = myTolReached3d; + + if (bReverse) + { + Handle(Geom2d_Curve) aC2D1, aC2D2; + const Standard_Integer aNbLin = mySeqOfCurve.Length(); + for (Standard_Integer i = 1; i <= aNbLin; ++i) + { + IntTools_Curve& aIC=mySeqOfCurve(i); + aC2D1=aIC.FirstCurve2d(); + aC2D2=aIC.SecondCurve2d(); + aIC.SetFirstCurve2d(aC2D2); + aIC.SetSecondCurve2d(aC2D1); + } + } } } + return; }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){ - // - if (aType1==GeomAbs_Plane && - (aType2==GeomAbs_Cylinder || - aType2==GeomAbs_Cone || - aType2==GeomAbs_Torus)) { + + if ((aType1==GeomAbs_Plane) && isFace2Quad) + { Standard_Real dU, dV; + // F1 + Standard_Real umin, umax, vmin, vmax; BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax); + dU=0.1*(umax-umin); dV=0.1*(vmax-vmin); umin=umin-dU; @@ -584,13 +663,12 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts) hasCone = Standard_True; } } - // - else if ((aType1==GeomAbs_Cylinder|| - aType1==GeomAbs_Cone || - aType1==GeomAbs_Torus) && - aType2==GeomAbs_Plane) { + else if ((aType2==GeomAbs_Plane) && isFace1Quad) + { Standard_Real dU, dV; + //F1 + Standard_Real umin, umax, vmin, vmax; BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax); CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax); myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax); @@ -609,80 +687,84 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts) hasCone = Standard_True; } } - - // - else { + else + { + Standard_Real umin, umax, vmin, vmax; BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax); - // CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax); - // myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax); - // BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax); - // CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax); - // myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax); } - // - dom1 = new IntTools_TopolTool(myHS1); - dom2 = new IntTools_TopolTool(myHS2); - // + + const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1); + const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2); + myLConstruct.Load(dom1, dom2, myHS1, myHS2); - // - Deflection = (hasCone) ? 0.085 : 0.1; - UVMaxStep = 0.001; - // - Tolerances(myHS1, myHS2, TolArc, TolTang, UVMaxStep, Deflection); - // - myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection); - // - RestrictLine = Standard_False; - // + + + Tolerances(myHS1, myHS2, TolTang); + + { + const Standard_Real UVMaxStep = 0.001; + const Standard_Real Deflection = (hasCone) ? 0.085 : 0.1; + myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection); + } + if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) || (myHS1->IsVClosed() && !myHS1->IsVPeriodic()) || (myHS2->IsUClosed() && !myHS2->IsUPeriodic()) || - (myHS2->IsVClosed() && !myHS2->IsVPeriodic())) { + (myHS2->IsVClosed() && !myHS2->IsVPeriodic())) + { RestrictLine = Standard_True; } // - if(((aType1 != GeomAbs_BSplineSurface) && - (aType1 != GeomAbs_BezierSurface) && - (aType1 != GeomAbs_OtherSurface)) && - ((aType2 != GeomAbs_BSplineSurface) && - (aType2 != GeomAbs_BezierSurface) && - (aType2 != GeomAbs_OtherSurface))) { + if((aType1 != GeomAbs_BSplineSurface) && + (aType1 != GeomAbs_BezierSurface) && + (aType1 != GeomAbs_OtherSurface) && + (aType2 != GeomAbs_BSplineSurface) && + (aType2 != GeomAbs_BezierSurface) && + (aType2 != GeomAbs_OtherSurface)) + { RestrictLine = Standard_True; - // + if ((aType1 == GeomAbs_Torus) || - (aType2 == GeomAbs_Torus) ) { + (aType2 == GeomAbs_Torus)) + { myListOfPnts.Clear(); } } + // - if(!RestrictLine) { + if(!RestrictLine) + { TopExp_Explorer aExp; - // - for(i = 0; (!RestrictLine) && (i < 2); i++) { + for(Standard_Integer i = 0; (!RestrictLine) && (i < 2); i++) + { const TopoDS_Face& aF=(!i) ? myFace1 : myFace2; aExp.Init(aF, TopAbs_EDGE); - for(; aExp.More(); aExp.Next()) { - const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current()); - // - if(BRep_Tool::Degenerated(aE)) { - RestrictLine = Standard_True; - break; - } + for(; aExp.More(); aExp.Next()) + { + const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current()); + + if(BRep_Tool::Degenerated(aE)) + { + RestrictLine = Standard_True; + break; + } } } } - // - myIntersector.Perform(myHS1, dom1, myHS2, dom2, - TolArc, TolTang, - myListOfPnts, RestrictLine); - // + + const Standard_Boolean isGeomInt = isTreatAnalityc(aF1, aF2); + myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang, + myListOfPnts, RestrictLine, isGeomInt); + myIsDone = myIntersector.IsDone(); - if (myIsDone) { + + if (myIsDone) + { myTangentFaces=myIntersector.TangentFaces(); if (myTangentFaces) { return; @@ -692,8 +774,8 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts) myListOfPnts.Clear(); // to use LineConstructor } // - aNbLin = myIntersector.NbLines(); - for (i=1; i<=aNbLin; ++i) { + const Standard_Integer aNbLin = myIntersector.NbLines(); + for (Standard_Integer i=1; i <= aNbLin; ++i) { MakeCurve(i, dom1, dom2); } // @@ -702,43 +784,47 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts) if (bReverse) { Handle(Geom2d_Curve) aC2D1, aC2D2; // - aNbLin=mySeqOfCurve.Length(); - for (i=1; i<=aNbLin; ++i) { - IntTools_Curve& aIC=mySeqOfCurve(i); - aC2D1=aIC.FirstCurve2d(); - aC2D2=aIC.SecondCurve2d(); - // - aIC.SetFirstCurve2d(aC2D2); - aIC.SetSecondCurve2d(aC2D1); + const Standard_Integer aNbLin=mySeqOfCurve.Length(); + for (Standard_Integer i=1; i<=aNbLin; ++i) + { + IntTools_Curve& aIC=mySeqOfCurve(i); + aC2D1=aIC.FirstCurve2d(); + aC2D2=aIC.SecondCurve2d(); + aIC.SetFirstCurve2d(aC2D2); + aIC.SetSecondCurve2d(aC2D1); } } - // + // Points Standard_Real U1,V1,U2,V2; IntTools_PntOnFace aPntOnF1, aPntOnF2; IntTools_PntOn2Faces aPntOn2Faces; // - aNbPnts=myIntersector.NbPnts(); - for (i=1; i<=aNbPnts; ++i) { + const Standard_Integer aNbPnts = myIntersector.NbPnts(); + for (Standard_Integer i=1; i <= aNbPnts; ++i) + { const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S(); const gp_Pnt& aPnt=aISPnt.Value(); aISPnt.Parameters(U1,V1,U2,V2); aPntOnF1.Init(myFace1, aPnt, U1, V1); aPntOnF2.Init(myFace2, aPnt, U2, V2); // - if (!bReverse) { - aPntOn2Faces.SetP1(aPntOnF1); - aPntOn2Faces.SetP2(aPntOnF2); + if (!bReverse) + { + aPntOn2Faces.SetP1(aPntOnF1); + aPntOn2Faces.SetP2(aPntOnF2); } - else { - aPntOn2Faces.SetP2(aPntOnF1); - aPntOn2Faces.SetP1(aPntOnF2); + else + { + aPntOn2Faces.SetP2(aPntOnF1); + aPntOn2Faces.SetP1(aPntOnF2); } + myPnts.Append(aPntOn2Faces); } - // } } + //======================================================================= //function :ComputeTolReached3d //purpose : @@ -4656,11 +4742,8 @@ void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1, //purpose : //======================================================================= void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1, - const Handle(GeomAdaptor_HSurface)& aHS2, - Standard_Real& ,//aTolArc, - Standard_Real& aTolTang, - Standard_Real& ,//aUVMaxStep, - Standard_Real& )//aDeflection) + const Handle(GeomAdaptor_HSurface)& aHS2, + Standard_Real& aTolTang) { GeomAbs_SurfaceType aTS1, aTS2; // diff --git a/src/QABugs/QABugs_19.cxx b/src/QABugs/QABugs_19.cxx index 13f8787b79..2744491ca8 100755 --- a/src/QABugs/QABugs_19.cxx +++ b/src/QABugs/QABugs_19.cxx @@ -1144,6 +1144,96 @@ static Standard_Integer OCC11758 (Draw_Interpretor& di, Standard_Integer n, cons return 0; } +#include +#include +#include +#include + +static Standard_Integer OCC24005 (Draw_Interpretor& theDI, Standard_Integer theNArg, const char** theArgv) +{ + if(theNArg < 2) + { + theDI << "Wrong a number of arguments!\n"; + return 1; + } + + Handle_Geom_Plane plane(new Geom_Plane( + gp_Ax3( gp_Pnt(-72.948737453424499, 754.30437716359393, 259.52151854671678), + gp_Dir(6.2471473085930200e-007, -0.99999999999980493, 0.00000000000000000), + gp_Dir(0.99999999999980493, 6.2471473085930200e-007, 0.00000000000000000)))); + Handle(Geom_CylindricalSurface) cylinder( + new Geom_CylindricalSurface( + gp_Ax3(gp_Pnt(-6.4812490053250649, 753.39408794522092, 279.16400974257465), + gp_Dir(1.0000000000000000, 0.0, 0.00000000000000000), + gp_Dir(0.0, 1.0000000000000000, 0.00000000000000000)), + 19.712534607908712)); + + DrawTrSurf::Set("pln", plane); + theDI << "pln\n"; + DrawTrSurf::Set("cyl", cylinder); + theDI << "cyl\n"; + + BRep_Builder builder; + TopoDS_Face face1, face2; + builder.MakeFace(face1, plane, Precision::Confusion()); + builder.MakeFace(face2, cylinder, Precision::Confusion()); + IntTools_FaceFace anInters; + anInters.SetParameters(false, true, true, Precision::Confusion()); + anInters.Perform(face1, face2); + + if (!anInters.IsDone()) + { + theDI<<"No intersections found!"<<"\n"; + + return 1; + } + + //Handle(Geom_Curve) aResult; + //gp_Pnt aPoint; + + const IntTools_SequenceOfCurves& aCvsX=anInters.Lines(); + const IntTools_SequenceOfPntOn2Faces& aPntsX=anInters.Points(); + + char buf[1024]; + Standard_Integer aNbCurves, aNbPoints; + + aNbCurves=aCvsX.Length(); + aNbPoints=aPntsX.Length(); + + if (aNbCurves >= 2) + { + for (Standard_Integer i=1; i<=aNbCurves; ++i) + { + Sprintf(buf, "%s_%d",theArgv[1],i); + theDI << buf << " "; + + const IntTools_Curve& aIC = aCvsX(i); + const Handle(Geom_Curve)& aC3D= aIC.Curve(); + DrawTrSurf::Set(buf,aC3D); + } + } + else if (aNbCurves == 1) + { + const IntTools_Curve& aIC = aCvsX(1); + const Handle(Geom_Curve)& aC3D= aIC.Curve(); + Sprintf(buf, "%s",theArgv[1]); + theDI << buf << " "; + DrawTrSurf::Set(buf,aC3D); + } + + for (Standard_Integer i = 1; i<=aNbPoints; ++i) + { + const IntTools_PntOn2Faces& aPi=aPntsX(i); + const gp_Pnt& aP=aPi.P1().Pnt(); + + Sprintf(buf,"%s_p_%d",theArgv[1],i); + theDI << buf << " "; + DrawTrSurf::Set(buf, aP); + } + + return 0; +} + void QABugs::Commands_19(Draw_Interpretor& theCommands) { const char *group = "QABugs"; @@ -1163,6 +1253,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) { theCommands.Add("OCC23945", "OCC23945 surfname U V X Y Z [DUX DUY DUZ DVX DVY DVZ [D2UX D2UY D2UZ D2VX D2VY D2VZ D2UVX D2UVY D2UVZ]]", __FILE__, OCC23945,group); theCommands.Add ("OCC24019", "OCC24019 aShape", __FILE__, OCC24019, group); theCommands.Add ("OCC11758", "OCC11758", __FILE__, OCC11758, group); - + theCommands.Add ("OCC24005", "OCC24005 result", __FILE__, OCC24005, group); return; } diff --git a/tests/bugs/modalg_5/bug24005 b/tests/bugs/modalg_5/bug24005 new file mode 100755 index 0000000000..43d6dcc020 --- /dev/null +++ b/tests/bugs/modalg_5/bug24005 @@ -0,0 +1,35 @@ +puts "============" +puts "OCC24005" +puts "============" +puts "" +############################### +## Intersecting a slightly off angle plane with a cylinder takes 7+ seconds +############################### + +pload QAcommands + +dchrono h reset +dchrono h start + +OCC24005 result + +dchrono h stop +set q [dchrono h show] + +regexp {CPU user time: ([-0-9.+eE]+) seconds} $q full z +puts "$z" + +set max_time 0.1 +if { $z > ${max_time} } { + puts "Elapsed time is more than ${max_time} seconds - Faulty" +} else { + puts "Elapsed time is less than ${max_time} seconds - OK" +} + +if { [regexp {Ellipse} [dump result]] == 1 } { + puts "result is OK" +} else { + puts "result is Faulty" +} + +set 2dviewer 1