From fa0291ff83b13bd6505a2d3714e7da73fa60c3e7 Mon Sep 17 00:00:00 2001 From: pkv Date: Fri, 21 Dec 2012 16:35:19 +0400 Subject: [PATCH] 0023576: Intersection algorithm produces trimmed circle with illegal parametric range. --- .../IntPatch_ImpImpIntersection_4.gxx | 100 +-- src/IntTools/IntTools_LineConstructor.cdl | 15 +- src/IntTools/IntTools_LineConstructor.cxx | 616 +++++++++--------- tests/bugs/moddata/bug23576 | 33 + tests/feat/featprism/N1 | 3 + 5 files changed, 423 insertions(+), 344 deletions(-) create mode 100755 tests/bugs/moddata/bug23576 mode change 100644 => 100755 tests/feat/featprism/N1 diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx index 41ca85f5a3..f12cf1e8e9 100755 --- a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx @@ -21,7 +21,7 @@ #include #include - +// static Standard_Boolean ExploreCurve(const gp_Cylinder& aCy, const gp_Cone& aCo, @@ -324,11 +324,12 @@ Standard_Boolean IntCyCy(const IntSurf_Quadric& Quad1, { gp_Vec Tgt; gp_Pnt ptref; - IntPatch_Point pmult1; - IntPatch_Point pmult2; + IntPatch_Point pmult1, pmult2; + elipsol = inter.Ellipse(1); - gp_Pnt pttang1(ElCLib::Value(M_PI*0.5,elipsol)); - gp_Pnt pttang2(ElCLib::Value(1.5*M_PI,elipsol)); + + gp_Pnt pttang1(ElCLib::Value(0.5*M_PI, elipsol)); + gp_Pnt pttang2(ElCLib::Value(1.5*M_PI, elipsol)); Multpoint = Standard_True; pmult1.SetValue(pttang1,Tol,Standard_True); @@ -344,8 +345,7 @@ Standard_Boolean IntCyCy(const IntSurf_Quadric& Quad1, Quad1.Parameters(pttang2,oU1,oV1); Quad2.Parameters(pttang2,oU2,oV2); pmult2.SetParameters(oU1,oV1,oU2,oV2); - - + // on traite la premiere ellipse //-- Calcul de la Transition de la ligne @@ -365,39 +365,53 @@ Standard_Boolean IntCyCy(const IntSurf_Quadric& Quad1, //-- Transition calculee au point 0 -> Trans2 , Trans1 //-- car ici, on devarit calculer en PI Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1); - pmult1.SetParameter(M_PI/2.); + // + { + Standard_Real aU1, aV1, aU2, aV2; + IntPatch_Point aIP; + gp_Pnt aP (ElCLib::Value(0., elipsol)); + // + aIP.SetValue(aP,Tol,Standard_False); + aIP.SetMultiple(Standard_False); + // + Quad1.Parameters(aP, aU1, aV1); + Quad2.Parameters(aP, aU2, aV2); + aIP.SetParameters(aU1, aV1, aU2, aV2); + // + aIP.SetParameter(0.); + glig->AddVertex(aIP); + glig->SetFirstPoint(1); + // + aIP.SetParameter(2.*M_PI); + glig->AddVertex(aIP); + glig->SetLastPoint(2); + } + // + pmult1.SetParameter(0.5*M_PI); glig->AddVertex(pmult1); - glig->SetFirstPoint(1); + // pmult2.SetParameter(1.5*M_PI); glig->AddVertex(pmult2); - glig->SetLastPoint(2); + + // slin.Append(glig); //-- Transitions calculee au point 0 OK - glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2); - pmult2.SetParameter(-M_PI/2.); - glig->AddVertex(pmult2); - glig->SetFirstPoint(1); - glig->AddVertex(pmult1); - glig->SetLastPoint(2); - slin.Append(glig); - - + // // on traite la deuxieme ellipse - elipsol = inter.Ellipse(2); Standard_Real param1 = ElCLib::Parameter(elipsol,pttang1); Standard_Real param2 = ElCLib::Parameter(elipsol,pttang2); Standard_Real parampourtransition; if (param1 < param2) { - pmult1.SetParameter(M_PI*0.5); + pmult1.SetParameter(0.5*M_PI); pmult2.SetParameter(1.5*M_PI); parampourtransition = M_PI; } else { - pmult1.SetParameter(-M_PI*0.5); - pmult2.SetParameter(M_PI*0.5); + pmult1.SetParameter(1.5*M_PI); + pmult2.SetParameter(0.5*M_PI); parampourtransition = 0.0; } @@ -417,25 +431,31 @@ Standard_Boolean IntCyCy(const IntSurf_Quadric& Quad1, } //-- La transition a ete calculee sur un point de cette ligne glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2); - glig->AddVertex(pmult1); - glig->SetFirstPoint(1); - glig->AddVertex(pmult2); - glig->SetLastPoint(2); - slin.Append(glig); - - if (param1 < param2) { - pmult2.SetParameter(-M_PI*0.5); + // + { + Standard_Real aU1, aV1, aU2, aV2; + IntPatch_Point aIP; + gp_Pnt aP (ElCLib::Value(0., elipsol)); + // + aIP.SetValue(aP,Tol,Standard_False); + aIP.SetMultiple(Standard_False); + // + Quad1.Parameters(aP, aU1, aV1); + Quad2.Parameters(aP, aU2, aV2); + aIP.SetParameters(aU1, aV1, aU2, aV2); + // + aIP.SetParameter(0.); + glig->AddVertex(aIP); + glig->SetFirstPoint(1); + // + aIP.SetParameter(2.*M_PI); + glig->AddVertex(aIP); + glig->SetLastPoint(2); } - else { - pmult1.SetParameter(1.5*M_PI); - } - - //-- Sur l'autre ligne, on invertse la transition - glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1); - glig->AddVertex(pmult2); - glig->SetFirstPoint(1); + // glig->AddVertex(pmult1); - glig->SetLastPoint(2); + glig->AddVertex(pmult2); + // slin.Append(glig); } break; diff --git a/src/IntTools/IntTools_LineConstructor.cdl b/src/IntTools/IntTools_LineConstructor.cdl index 1f1efb53c0..8e87cf4aca 100755 --- a/src/IntTools/IntTools_LineConstructor.cdl +++ b/src/IntTools/IntTools_LineConstructor.cdl @@ -83,16 +83,21 @@ is --- for given index of split --- - PeriodicLine(me; L: Line from IntPatch) - is static private; - + ---PeriodicLine(me; L: Line from IntPatch) + --- is protected; + + TreatCircle(me:out; + aLine : Line from IntPatch; + aTol: Real from Standard) + is protected; + fields done : Boolean from Standard; seqp : SequenceOfReal from TColStd; myDom1: TopolTool from Adaptor3d; myDom2: TopolTool from Adaptor3d; - myHS1 : HSurface from GeomAdaptor; - myHS2 : HSurface from GeomAdaptor; + myHS1 : HSurface from GeomAdaptor; + myHS2 : HSurface from GeomAdaptor; end LineConstructor; diff --git a/src/IntTools/IntTools_LineConstructor.cxx b/src/IntTools/IntTools_LineConstructor.cxx index 1ea96287c9..b88f0634d5 100755 --- a/src/IntTools/IntTools_LineConstructor.cxx +++ b/src/IntTools/IntTools_LineConstructor.cxx @@ -225,43 +225,20 @@ void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L) return; }// else if(typl == IntPatch_Walking) { // + //----------------------------------------------------------- else if (typl != IntPatch_Restriction) { - Standard_Boolean intrvtested; - Standard_Real u1,v1,u2,v2; - // seqp.Clear(); // Handle(IntPatch_GLine)& GLine = *((Handle(IntPatch_GLine) *)&L); - // reject micro circles, ellipses - switch (typl) { - case IntPatch_Circle: { - Standard_Real aR; - gp_Circ aCirc; - // - aCirc=GLine->Circle(); - aR=aCirc.Radius(); - if (aREllipse(); - aR=aEllipse.MajorRadius(); - if (aRLine()); - 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; - default: - break; - } - */ - //modified by NIZNHY-PKV Fri Nov 11 12:25:40 2011t // Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2); Recadre(myHS1,myHS2,u1,v1,u2,v2); @@ -310,42 +264,6 @@ void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L) } } // - 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()); - } - 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) { // Keep a priori. A point 2d on each // surface is required to make the decision. Will be done in the caller @@ -353,124 +271,9 @@ void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L) seqp.Append(GeomInt_LineTool::LastParameter(L)); } // - // Treatment Circles/Ellipses that are the results of intersection - // between Plane / (Cylinder, Sphere). - // In these cases the intersection curves can contain - // a lot of 'vertices' on the curve that leads to a lot of parts - // of the curve. Some adjacent parts can be united to the one part. - // - Standard_Integer aNbParts; - // - aNbParts = seqp.Length()/2; - if (aNbParts > 1 && (typl == IntPatch_Circle || typl == IntPatch_Ellipse)) { - Standard_Boolean bCond, bPCS, bPCS1, bPCS2, bCC; - GeomAbs_SurfaceType aST1, aST2; - // - aST1 = myHS1->Surface().GetType(); - aST2 = myHS2->Surface().GetType(); - // - bPCS1=((aST1==GeomAbs_Plane) && (aST2==GeomAbs_Cylinder || aST2==GeomAbs_Sphere)); - bPCS2=((aST2==GeomAbs_Plane) && (aST1==GeomAbs_Cylinder || aST1==GeomAbs_Sphere)); - bPCS=(bPCS1 || bPCS2); - bCC=(aST1==GeomAbs_Cylinder && aST2==GeomAbs_Cylinder); - // - // ZZ - //modified by NIZNHY-PKV Fri Nov 11 10:13:58 2011f - Standard_Integer j, i1, i2; - Standard_Real aT, aU, aV; - Handle(GeomAdaptor_HSurface) aHS; - // - bCond=Standard_False; - // - if (bCC) { - bCond=Standard_True; - } - else if (bPCS) { - if ((aST1==GeomAbs_Sphere) || (aST2==GeomAbs_Sphere)) { - if (aST1==GeomAbs_Sphere) { - aHS=myHS1; - } - else if (aST2==GeomAbs_Sphere){ - aHS=myHS2; - } - // - Standard_Integer aNbP; - Standard_Real aHalfPI, aPPC; - // - bCond=Standard_True; - // - aNbP=seqp.Length(); - aPPC=Precision::PConfusion(); - aHalfPI=0.5*M_PI; - i1=0; - i2=0; - // - for (i=1; i<=aNbP; ++i) { - gp_Pnt aP; - // - aT=seqp(i); - GLinePoint(typl, GLine, aT, aP); - Parameters(aHS, aP, aU, aV); - if (aV<0.) { - if (fabs(aV+aHalfPI) < aPPC) { - ++i2; - } - } - else { - if (fabs(aV-aHalfPI) < aPPC) { - ++i1; - } - } - } - if (i1==2 || i2==2) { - bCond=Standard_False; - } - } - }// else if (bPCS1 || bPCS2) { - //modified by NIZNHY-PKV Fri Nov 11 10:14:00 2011t - // - if (bCond){ - Standard_Integer i2, j2; - Standard_Real aFi, aLi, aFj, aLj, aF, aL; - TColStd_SequenceOfReal aSeq; - // - aFi=seqp(1); - aSeq.Append(aFi); - for (i=1; iArcType(); - if (typl != IntPatch_Circle && typl != IntPatch_Ellipse) - return; - - const Standard_Real Tol = Precision::PConfusion(); - Handle(IntPatch_GLine) glin = Handle(IntPatch_GLine)::DownCast(L); - Standard_Integer i,j,nbvtx = glin->NbVertex(); - for (i=1; i<=nbvtx; i++) - { - IntPatch_Point thevtx = glin->Vertex(i); - const Standard_Real prm = thevtx.ParameterOnLine(); - Standard_Boolean changevtx = Standard_False; - if (thevtx.IsOnDomS1() || thevtx.IsOnDomS2()) - { - for (j=1; j<=nbvtx; j++) - { - if (j!=i) - { - const IntPatch_Point& thevtxbis = glin->Vertex(j); - const Standard_Real prmbis = thevtxbis.ParameterOnLine(); - if (Abs(prm-prmbis) <= Tol) - { - Standard_Real u,v; - gp_Pnt2d p2d; - if (thevtx.IsOnDomS1() && thevtxbis.IsOnDomS1() && - thevtxbis.TransitionLineArc1().TransitionType()==IntSurf_In) - { - p2d = thevtx.ArcOnS1()->Value(thevtx.ParameterOnArc1()); - u = p2d.X(); v = p2d.Y(); - p2d = thevtxbis.ArcOnS1()->Value(thevtxbis.ParameterOnArc1()); - if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol) - { - changevtx = Standard_True; - break; - } - } - if (thevtx.IsOnDomS2() && thevtxbis.IsOnDomS2() && - thevtxbis.TransitionLineArc2().TransitionType()==IntSurf_In) - { - p2d = thevtx.ArcOnS2()->Value(thevtx.ParameterOnArc2()); - u = p2d.X(); v = p2d.Y(); - p2d = thevtxbis.ArcOnS2()->Value(thevtxbis.ParameterOnArc2()); - if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol) - { - changevtx = Standard_True; - break; - } - } - } - } - } - } - if (changevtx) { - thevtx.SetParameter(prm + 2.*M_PI); - glin->Replace(i,thevtx); - } - } -} -//modified by NIZNHY-PKV Fri Nov 11 10:30:34 2011f //======================================================================= //function : Recadre //purpose : @@ -855,33 +591,9 @@ void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1, Standard_Real& U2, Standard_Real& V2) { - //modified by NIZNHY-PKV Fri Nov 11 10:07:55 2011f Parameters(myHS1, Ptref, U1, V1); Parameters(myHS2, Ptref, U2, V2); - /* - IntSurf_Quadric quad1,quad2; - switch (myHS1->Surface().GetType()) - { - case GeomAbs_Plane: quad1.SetValue(myHS1->Surface().Plane()); break; - case GeomAbs_Cylinder: quad1.SetValue(myHS1->Surface().Cylinder()); break; - case GeomAbs_Cone: quad1.SetValue(myHS1->Surface().Cone()); break; - case GeomAbs_Sphere: quad1.SetValue(myHS1->Surface().Sphere()); break; - default: Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters"); - } - switch (myHS2->Surface().GetType()) - { - case GeomAbs_Plane: quad2.SetValue(myHS2->Surface().Plane()); break; - case GeomAbs_Cylinder: quad2.SetValue(myHS2->Surface().Cylinder()); break; - case GeomAbs_Cone: quad2.SetValue(myHS2->Surface().Cone()); break; - case GeomAbs_Sphere: quad2.SetValue(myHS2->Surface().Sphere()); break; - default: Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters"); - } - quad1.Parameters(Ptref,U1,V1); - quad2.Parameters(Ptref,U2,V2); - */ - //modified by NIZNHY-PKV Fri Nov 11 10:08:38 2011t } -//modified by NIZNHY-PKV Fri Nov 11 10:06:02 2011f //======================================================================= //function : Parameter //purpose : @@ -941,4 +653,310 @@ void GLinePoint(const IntPatch_IType typl, Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters"); } } -//modified by NIZNHY-PKV Fri Nov 11 10:06:04 2011t + +//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +// +//======================================================================= +//class : IntTools_RealWithFlag +//purpose : +//======================================================================= +class IntTools_RealWithFlag { + public: + IntTools_RealWithFlag() : + myValue(-99.), myFlag(1) + { + }; + // + ~IntTools_RealWithFlag() { + }; + // + void SetValue(const Standard_Real aT) { + myValue=aT; + }; + // + Standard_Real Value() const { + return myValue; + } + // + void SetFlag(const Standard_Integer aFlag) { + myFlag=aFlag; + }; + // + Standard_Integer Flag() const { + return myFlag; + } + // + Standard_Boolean operator < (const IntTools_RealWithFlag& aOther) { + return myValueArcType(); + Handle(IntPatch_GLine)& aGLine=*((Handle(IntPatch_GLine) *)&aLine); + // + bRejected=RejectMicroCircle(aGLine, aType, aTol); + if (bRejected) { + return; + } + //---------------------------------------- + Standard_Integer aNbVtx, aNbVtxWas, i; + Standard_Real aTolPC, aT, aT1, aT2, aTmid, aTwoPI, aTolPC1; + Standard_Real aU1, aV1, aU2, aV2; + TopAbs_State aIn1, aIn2; + GeomAbs_SurfaceType aTS1, aTS2; + gp_Pnt aPmid; + gp_Pnt2d aP2D; + IntTools_RealWithFlag *pVtx; + //-------------------------------------1 + aTwoPI=M_PI+M_PI; + aTolPC=Precision::PConfusion(); + aNbVtxWas=GeomInt_LineTool::NbVertex(aLine); + aNbVtx=aNbVtxWas+2; + //-------------------------------------2 + aTS1=myHS1->GetType(); + aTS2=myHS2->GetType(); + // + // About the value aTolPC1=1000.*aTolPC, + // see IntPatch_GLine.cxx, line:398 + // for more details; + aTolPC1=1000.*aTolPC; + //------------------------------------- + // + pVtx=new IntTools_RealWithFlag [aNbVtx]; + // + pVtx[0].SetValue(0.); + pVtx[1].SetValue(2.*M_PI); + // + for(i=1; i<=aNbVtxWas; ++i) { + aT=GeomInt_LineTool::Vertex(aLine, i).ParameterOnLine(); + aT=AdjustOnPeriod(aT, aTwoPI); + pVtx[i+1].SetValue(aT); + } + // + SortShell(aNbVtx, pVtx); + // + RejectNearBeacons(aNbVtx, pVtx, aTolPC1, aTS1, aTS2); + // + RejectDuplicates(aNbVtx, pVtx, aTolPC); + // + for(i=0; iClassify(aP2D, aTol); + if(aIn1 != TopAbs_OUT) { + aP2D.SetCoord(aU2, aV2); + aIn2=myDom2->Classify(aP2D, aTol); + if(aIn2 != TopAbs_OUT) { + seqp.Append(aT1); + seqp.Append(aT2); + } + } + } + // + delete [] pVtx; +} +//======================================================================= +//function : RejectNearBeacons +//purpose : Reject the thickenings near the beacon points (if exist) +// The gifts, made by sweep algo. +// chl/930/B5 B8 C2 C5 E2 E5 E8 F2 G8 H2 H5 H8 +//======================================================================= +void RejectNearBeacons(Standard_Integer& aNbVtx, + IntTools_RealWithFlag *pVtx, + Standard_Real aTolPC1, + const GeomAbs_SurfaceType aTS1, + const GeomAbs_SurfaceType aTS2) +{ + Standard_Integer i, j, iBcn; + Standard_Real aT, aBcn[2]; + // + if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) { + aBcn[0]=0.5*M_PI; + aBcn[1]=1.5*M_PI; + // + for (j=0; j<2; ++j) { + iBcn=-1; + for(i=0; i=0. && aT<=aPeriod)) { + k=(Standard_Integer)(aT/aPeriod); + aT=aT-k*aPeriod; + } + // + return aT; +} +//======================================================================= +//function : RejectMicroCrcles +//purpose : +//======================================================================= +Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine, + const IntPatch_IType aType, + const Standard_Real aTol3D) +{ + Standard_Boolean bRet; + Standard_Real aR; + // + bRet=Standard_False; + // + if (aType==IntPatch_Circle) { + aR=aGLine->Circle().Radius(); + bRet=(aREllipse().MajorRadius(); + bRet=(aR -1) goto m30; + }//if (a[l] < a[j]){ + }//for (i=0; i ${2_PI}} { + puts "Error: Bad value of parametric range rc2" +} else { + puts "Good value of parametric range rc2" +} diff --git a/tests/feat/featprism/N1 b/tests/feat/featprism/N1 old mode 100644 new mode 100755 index c367ad9842..a70397b28a --- a/tests/feat/featprism/N1 +++ b/tests/feat/featprism/N1 @@ -1,6 +1,9 @@ # Original bug : id160074 # Date : 23 Nov 98 +puts "*" +puts "TODO OCC23658 All:Error : The square of result shape is" + restore [locate_data_file CFE900_id160gdu.rle] base restore [locate_data_file id160074_face1.brep] cont