From: jgv Date: Fri, 17 Feb 2017 15:23:18 +0000 (+0300) Subject: 0027998: Self-intersection is not detected X-Git-Tag: V7_2_0_beta~242 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=f48cb55d3359f4b33a851686169f853dbfa3affd 0027998: Self-intersection is not detected New method CheckFaceSelfIntersection has been added to BOPAlgo_CheckerSI: now self-intersection of each face is found as well as pairs of intersecting faces; -method IntPatch_Intersection::Perform(S1,D1,TolArc,TolTang) is modified for more effective search of self-interasections in case of Surface Of Extrusion; -method IntCurve_IntPolyPolyGen::Perform(C1,D1,TolConf,Tol,NbIter) is modified to detect segments of intersections. Small correction. Test cases are corrected. Correction of compiler error Fix of regressions Names of shapes correction --- diff --git a/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx b/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx index 6138f91bda..ed181df9b2 100644 --- a/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx +++ b/src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx @@ -384,12 +384,14 @@ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences() if(ii == 0) { aResult.SetShape1(myShape1); aResult.AddFaultyShape1(aS1); - aResult.AddFaultyShape1(aS2); + if (!aS1.IsSame(aS2)) + aResult.AddFaultyShape1(aS2); } else { aResult.SetShape2(myShape2); aResult.AddFaultyShape2(aS1); - aResult.AddFaultyShape2(aS2); + if (!aS1.IsSame(aS2)) + aResult.AddFaultyShape2(aS2); } aResult.SetCheckStatus(BOPAlgo_SelfIntersect); myResult.Append(aResult); diff --git a/src/BOPAlgo/BOPAlgo_CheckerSI.cxx b/src/BOPAlgo/BOPAlgo_CheckerSI.cxx index 323b5af6f0..06d6360a04 100644 --- a/src/BOPAlgo/BOPAlgo_CheckerSI.cxx +++ b/src/BOPAlgo/BOPAlgo_CheckerSI.cxx @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -34,9 +35,83 @@ #include #include #include +#include +#include #include #include #include +#include +#include + +//======================================================================= +//class : BOPAlgo_FaceSelfIntersect +//purpose : +//======================================================================= +class BOPAlgo_FaceSelfIntersect : + public IntTools_FaceFace, + public BOPAlgo_Algo { + + public: + DEFINE_STANDARD_ALLOC + + BOPAlgo_FaceSelfIntersect() : + IntTools_FaceFace(), + BOPAlgo_Algo(), + myIF(-1), myTolF(1.e-7) { + } + // + virtual ~BOPAlgo_FaceSelfIntersect() { + } + // + void SetIndex(const Standard_Integer nF) { + myIF = nF; + } + // + Standard_Integer IndexOfFace() const { + return myIF; + } + // + void SetFace(const TopoDS_Face& aF) { + myF = aF; + } + // + const TopoDS_Face& Face()const { + return myF; + } + // + void SetTolF(const Standard_Real aTolF) { + myTolF = aTolF; + } + // + Standard_Real TolF() const{ + return myTolF; + } + // + virtual void Perform() { + BOPAlgo_Algo::UserBreak(); + IntTools_FaceFace::Perform(myF, myF); + } + // + protected: + Standard_Integer myIF; + Standard_Real myTolF; + TopoDS_Face myF; +}; +//end of definition of class BOPAlgo_FaceSelfIntersect + +//======================================================================= + +typedef BOPCol_NCVector + BOPAlgo_VectorOfFaceSelfIntersect; +// +typedef BOPCol_Functor + BOPAlgo_FaceSelfIntersectFunctor; +// +typedef BOPCol_Cnt + BOPAlgo_FaceSelfIntersectCnt; + //======================================================================= //function : @@ -116,6 +191,8 @@ void BOPAlgo_CheckerSI::Perform() // Perform intersection of sub shapes BOPAlgo_PaveFiller::Perform(); // + CheckFaceSelfIntersection(); + // Perform intersection with solids if (!myErrorStatus) PerformVZ(); @@ -150,8 +227,7 @@ void BOPAlgo_CheckerSI::PostTreat() // BOPDS_MapOfPair& aMPK= *((BOPDS_MapOfPair*)&myDS->Interferences()); - aMPK.Clear(); - // + // 0 BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV(); aNb=aVVs.Extent(); @@ -238,23 +314,27 @@ void BOPAlgo_CheckerSI::PostTreat() continue; } // - iFound=0; - if (bTangentFaces) { - const TopoDS_Face& aF1=*((TopoDS_Face*)&myDS->Shape(n1)); - const TopoDS_Face& aF2=*((TopoDS_Face*)&myDS->Shape(n2)); - bFlag=BOPTools_AlgoTools::AreFacesSameDomain - (aF1, aF2, myContext, myFuzzyValue); - if (bFlag) { - ++iFound; - } - } - else { - for (j=0; j!=aNbC; ++j) { - const BOPDS_Curve& aNC=aVC(j); - const BOPDS_ListOfPaveBlock& aLPBC=aNC.PaveBlocks(); - if (aLPBC.Extent()) { + iFound = (n1 == n2) ? 1 : 0; + //case of self-intersection inside one face + if (!iFound) + { + if (bTangentFaces) { + const TopoDS_Face& aF1=*((TopoDS_Face*)&myDS->Shape(n1)); + const TopoDS_Face& aF2=*((TopoDS_Face*)&myDS->Shape(n2)); + bFlag=BOPTools_AlgoTools::AreFacesSameDomain + (aF1, aF2, myContext, myFuzzyValue); + if (bFlag) { ++iFound; - break; + } + } + else { + for (j=0; j!=aNbC; ++j) { + const BOPDS_Curve& aNC=aVC(j); + const BOPDS_ListOfPaveBlock& aLPBC=aNC.PaveBlocks(); + if (aLPBC.Extent()) { + ++iFound; + break; + } } } } @@ -315,3 +395,87 @@ void BOPAlgo_CheckerSI::PostTreat() aMPK.Add(aPK); } } + +//======================================================================= +//function : CheckFaceSelfIntersection +//purpose : +//======================================================================= +void BOPAlgo_CheckerSI::CheckFaceSelfIntersection() +{ + if (myLevelOfCheck < 5) + return; + + BOPDS_Pair aPK; + + BOPDS_MapOfPair& aMPK= + *((BOPDS_MapOfPair*)&myDS->Interferences()); + aMPK.Clear(); + + BOPAlgo_VectorOfFaceSelfIntersect aVFace; + + Standard_Integer aNbS=myDS->NbSourceShapes(); + + // + for (Standard_Integer i = 0; i < aNbS; i++) + { + const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i); + if (aSI.ShapeType() != TopAbs_FACE) + continue; + // + const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape())); + BRepAdaptor_Surface BAsurf(aF, Standard_False); + GeomAbs_SurfaceType aSurfType = BAsurf.GetType(); + if (aSurfType == GeomAbs_Plane || + aSurfType == GeomAbs_Cylinder || + aSurfType == GeomAbs_Cone || + aSurfType == GeomAbs_Sphere) + continue; + + if (aSurfType == GeomAbs_Torus) + { + gp_Torus aTorus = BAsurf.Torus(); + Standard_Real aMajorRadius = aTorus.MajorRadius(); + Standard_Real aMinorRadius = aTorus.MinorRadius(); + if (aMajorRadius > aMinorRadius + Precision::Confusion()) + continue; + } + + Standard_Real aTolF = BRep_Tool::Tolerance(aF); + + BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace.Append1(); + // + aFaceSelfIntersect.SetIndex(i); + aFaceSelfIntersect.SetFace(aF); + aFaceSelfIntersect.SetTolF(aTolF); + // + aFaceSelfIntersect.SetProgressIndicator(myProgressIndicator); + } + + Standard_Integer aNbFace = aVFace.Extent(); + //====================================================== + BOPAlgo_FaceSelfIntersectCnt::Perform(myRunParallel, aVFace); + //====================================================== + // + for (Standard_Integer k = 0; k < aNbFace; k++) + { + BOPAlgo_FaceSelfIntersect& aFaceSelfIntersect = aVFace(k); + // + Standard_Integer nF = aFaceSelfIntersect.IndexOfFace(); + + Standard_Boolean bIsDone = aFaceSelfIntersect.IsDone(); + if (bIsDone) + { + const IntTools_SequenceOfCurves& aCvsX = aFaceSelfIntersect.Lines(); + const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceSelfIntersect.Points(); + // + Standard_Integer aNbCurves = aCvsX.Length(); + Standard_Integer aNbPoints = aPntsX.Length(); + // + if (aNbCurves || aNbPoints) + { + aPK.SetIndices(nF, nF); + aMPK.Add(aPK); + } + } + } +} diff --git a/src/BOPAlgo/BOPAlgo_CheckerSI.hxx b/src/BOPAlgo/BOPAlgo_CheckerSI.hxx index 69cdf70786..f764f591e5 100644 --- a/src/BOPAlgo/BOPAlgo_CheckerSI.hxx +++ b/src/BOPAlgo/BOPAlgo_CheckerSI.hxx @@ -68,6 +68,8 @@ protected: //! Treats the intersection results Standard_EXPORT void PostTreat(); + Standard_EXPORT void CheckFaceSelfIntersection(); + //! Methods for intersection with solids //! Vertex/Solid intersection diff --git a/src/BOPTools/BOPTools_AlgoTools2D.cxx b/src/BOPTools/BOPTools_AlgoTools2D.cxx index 657c397f70..9697b92f56 100644 --- a/src/BOPTools/BOPTools_AlgoTools2D.cxx +++ b/src/BOPTools/BOPTools_AlgoTools2D.cxx @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -638,24 +639,24 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace } // ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR); - BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D); + ProjLib::MakePCurveOfType(aProj1, aC2D); aTolR = aProj1.GetTolerance(); } else { ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1 - BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D); + ProjLib::MakePCurveOfType(aProjCurv, aC2D); aTolR=aProjCurv.GetTolerance(); } // if (aC2D.IsNull()) { ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2 - BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D); + ProjLib::MakePCurveOfType(aProjCurvAgain, aC2D); aTolR = aProjCurvAgain.GetTolerance(); // if (aC2D.IsNull()) { Standard_Real aTR=0.0001; ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3 - BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D); + ProjLib::MakePCurveOfType(aProj3, aC2D); aTolR = aProj3.GetTolerance(); } } @@ -685,42 +686,6 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace } } -//======================================================================= -//function : MakePCurveOfType -//purpose : -//======================================================================= -void BOPTools_AlgoTools2D::MakePCurveOfType - (const ProjLib_ProjectedCurve& PC, - Handle(Geom2d_Curve)& C2D) -{ - - switch (PC.GetType()) { - - case GeomAbs_Line : - C2D = new Geom2d_Line(PC.Line()); - break; - case GeomAbs_Circle : - C2D = new Geom2d_Circle(PC.Circle()); - break; - case GeomAbs_Ellipse : - C2D = new Geom2d_Ellipse(PC.Ellipse()); - break; - case GeomAbs_Parabola : - C2D = new Geom2d_Parabola(PC.Parabola()); - break; - case GeomAbs_Hyperbola : - C2D = new Geom2d_Hyperbola(PC.Hyperbola()); - break; - case GeomAbs_BSplineCurve : - C2D = PC.BSpline(); - break; - case GeomAbs_BezierCurve : - case GeomAbs_OtherCurve : - default : - throw Standard_NotImplemented("BOPTools_AlgoTools2D::MakePCurveOfType"); - break; - } -} //======================================================================= //function : CheckEdgeLength //purpose : @@ -932,4 +897,4 @@ void BOPTools_AlgoTools2D::IsEdgeIsoline( const TopoDS_Edge& theE, isTheUIso = (aDPv <= aTol); isTheVIso = (aDPu <= aTol); -} \ No newline at end of file +} diff --git a/src/BOPTools/BOPTools_AlgoTools2D.hxx b/src/BOPTools/BOPTools_AlgoTools2D.hxx index 6407253570..f6f68b5edc 100644 --- a/src/BOPTools/BOPTools_AlgoTools2D.hxx +++ b/src/BOPTools/BOPTools_AlgoTools2D.hxx @@ -191,11 +191,6 @@ public: Standard_Real& aToler, const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - - //! Make empty P-Curve of relevant to type - Standard_EXPORT static void MakePCurveOfType (const ProjLib_ProjectedCurve& PC, Handle(Geom2d_Curve)& aC); - - //! Attach P-Curve from the edge on surface //! to the edge //! Returns 0 in case of success diff --git a/src/Geom2dAPI/Geom2dAPI_InterCurveCurve.cxx b/src/Geom2dAPI/Geom2dAPI_InterCurveCurve.cxx index e3555996ae..537a1ebb0a 100644 --- a/src/Geom2dAPI/Geom2dAPI_InterCurveCurve.cxx +++ b/src/Geom2dAPI/Geom2dAPI_InterCurveCurve.cxx @@ -180,13 +180,22 @@ void Geom2dAPI_InterCurveCurve::Segment Standard_OutOfRange_Raise_if(theIndex < 1 || theIndex > NbSegments(), "Geom2dAPI_InterCurveCurve::Segment"); - Standard_NullObject_Raise_if(myCurve1.IsNull() || myCurve2.IsNull(), + Standard_NullObject_Raise_if(myCurve1.IsNull(), "Geom2dAPI_InterCurveCurve::Segment"); - Standard_Real aU1 = myCurve1->FirstParameter(), - aU2 = myCurve1->LastParameter(), - aV1 = myCurve2->FirstParameter(), - aV2 = myCurve2->LastParameter(); + Standard_Real aU1, aU2, aV1, aV2; + aU1 = myCurve1->FirstParameter(); + aU2 = myCurve1->LastParameter(); + if (myCurve2.IsNull()) + { + aV1 = aU1; + aV2 = aU2; + } + else + { + aV1 = myCurve2->FirstParameter(); + aV2 = myCurve2->LastParameter(); + } const IntRes2d_IntersectionSegment& aSeg = myIntersector.Segment(theIndex); const Standard_Boolean isOpposite = aSeg.IsOpposite(); @@ -214,5 +223,8 @@ void Geom2dAPI_InterCurveCurve::Segment } theCurve1 = new Geom2d_TrimmedCurve(myCurve1, aU1, aU2); - theCurve2 = new Geom2d_TrimmedCurve(myCurve2, aV1, aV2); + if (myCurve2.IsNull()) + theCurve2 = new Geom2d_TrimmedCurve(myCurve1, aV1, aV2); + else + theCurve2 = new Geom2d_TrimmedCurve(myCurve2, aV1, aV2); } diff --git a/src/IntCurve/IntCurve_IntPolyPolyGen.gxx b/src/IntCurve/IntCurve_IntPolyPolyGen.gxx index aa868050c4..ae3c4bfb99 100644 --- a/src/IntCurve/IntCurve_IntPolyPolyGen.gxx +++ b/src/IntCurve/IntCurve_IntPolyPolyGen.gxx @@ -486,6 +486,181 @@ void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1 delete [] PtrSegIndex1; delete [] PtrSegIndex2; } + + //---------------------------------------------------------------------- + //-- Processing of TangentZone + //---------------------------------------------------------------------- + Standard_Integer Nbtz = InterPP.NbTangentZones(); + for(Standard_Integer tz=1; tz <= Nbtz; tz++) { + Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints(); + //==================================================================== + //== Find the first and the last point in the tangency zone. + //==================================================================== + Standard_Real ParamSupOnCurve2,ParamInfOnCurve2; + Standard_Real ParamSupOnCurve1,ParamInfOnCurve1; +// Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2; + Standard_Integer SegIndex1onP1,SegIndex1onP2; + Intf_PIType Type; + Standard_Real ParamOnLine; + Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup; + ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast(); + ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast(); + for(Standard_Integer qq=1;qq<=NbPnts;qq++) { + const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq); + //==================================================================== + //== The zones of tangency are discretized + //== Test of stop : Check if + //== (Deflection < Tolerance) + //== Or (Sample < EpsX) (normally the first condition is + //== more strict) + //==================================================================== +// Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup; + Standard_Real _PolyUInf,_PolyVInf; + + SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine); + if(SegIndex1onP1 > Poly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; } + if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; } + _PolyUInf = Poly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine); + + SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine); + if(SegIndex1onP2 > Poly1.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; } + if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; } + _PolyVInf = Poly1.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine); + + //---------------------------------------------------------------------- + + if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf; + if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf; + + if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf; + if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf; + } + + PolyUInf= ParamInfOnCurve1; + PolyUSup= ParamSupOnCurve1; + PolyVInf= ParamInfOnCurve2; + PolyVSup= ParamSupOnCurve2; + + TheCurveTool::D0(C1,PolyUInf,P1); + TheCurveTool::D0(C1,PolyVInf,P2); + Standard_Real distmemesens = P1.SquareDistance(P2); + TheCurveTool::D0(C1,PolyVSup,P2); + Standard_Real distdiffsens = P1.SquareDistance(P2); + if(distmemesens > distdiffsens) { + Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty; + } + + //----------------------------------------------------------------- + //-- Calculate Positions of Points on the curve and + //-- Transitions on each limit of the segment + + IntRes2d_Position Pos1 = IntRes2d_Middle; + IntRes2d_Position Pos2 = IntRes2d_Middle; + IntRes2d_Transition Trans1,Trans2; + + TheCurveTool::D1(C1,PolyUInf,P1,Tan1); + TheCurveTool::D1(C1,PolyVInf,P2,Tan2); + + if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) { + Pos1 = IntRes2d_Head; + } + else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { + Pos1 = IntRes2d_End; + } + if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) { + Pos2 = IntRes2d_Head; + } + else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { + Pos2 = IntRes2d_End; + } + + if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { + PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); + } + else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { + PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); + } + else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { + PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); + } + else { + PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); + } + + + + if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) + == Standard_False) + { + TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1); + TheCurveTool::D2(C1,PolyVInf,P2,Tan2,Norm2); + IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1, + Pos2,Tan2,Norm2,Trans2,TolConf); + } + IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf + ,Trans1,Trans2,Standard_False); + //---------------------------------------------------------------------- + + if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1)) || + (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C1))) + { + //bad segment + } + else + { + TheCurveTool::D1(C1,PolyUSup,P1,Tan1); + TheCurveTool::D1(C1,PolyVSup,P2,Tan2); + Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle; + + if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) { + Pos1 = IntRes2d_Head; + } + else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { + Pos1 = IntRes2d_End; + } + if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) { + Pos2 = IntRes2d_Head; + } + else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { + Pos2 = IntRes2d_End; + } + + + if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { + PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); + } + else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { + PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); + } + else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { + PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); + } + else { + PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); + } + + if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) + ==Standard_False) { + TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1); + TheCurveTool::D2(C1,PolyVSup,P2,Tan2,Norm2); + IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1, + Pos2,Tan2,Norm2,Trans2,TolConf); + } + IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup + ,Trans1,Trans2,Standard_False); + + Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True; + if(ParamInfOnCurve1 > ParamSupOnCurve1) { + IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False); + Append(Seg); + } + else { + IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False); + Append(Seg); + } + } + } //end of processing of TangentZone + done = Standard_True; } diff --git a/src/IntPatch/IntPatch_Intersection.cxx b/src/IntPatch/IntPatch_Intersection.cxx index 0a441abe5b..6213b3541a 100644 --- a/src/IntPatch/IntPatch_Intersection.cxx +++ b/src/IntPatch/IntPatch_Intersection.cxx @@ -26,6 +26,15 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include + //====================================================================== // function: SequenceOfLine //====================================================================== @@ -129,12 +138,35 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1, switch (S1->GetType()) { - case GeomAbs_Plane: - case GeomAbs_Cylinder: - case GeomAbs_Sphere: - case GeomAbs_Cone: - case GeomAbs_Torus: break; - default: + case GeomAbs_Plane: + case GeomAbs_Cylinder: + case GeomAbs_Sphere: + case GeomAbs_Cone: + case GeomAbs_Torus: + break; + case GeomAbs_SurfaceOfExtrusion: + { + gp_Dir aDirection = S1->Direction(); + gp_Ax3 anAxis(gp::Origin(), aDirection); + Handle(Adaptor3d_HCurve) aBasisCurve = S1->BasisCurve(); + ProjLib_ProjectOnPlane Projector(anAxis); + Projector.Load(aBasisCurve, Precision::Confusion()); + Handle(GeomAdaptor_HCurve) aProjCurve = Projector.GetResult(); + Handle(Geom_Plane) aPlane = new Geom_Plane(anAxis); + Handle(GeomAdaptor_HSurface) aGAHsurf = new GeomAdaptor_HSurface(aPlane); + ProjLib_ProjectedCurve aProjectedCurve(aGAHsurf, aProjCurve); + Handle(Geom2d_Curve) aPCurve; + ProjLib::MakePCurveOfType(aProjectedCurve, aPCurve); + Geom2dAdaptor_Curve AC(aPCurve, + aProjectedCurve.FirstParameter(), + aProjectedCurve.LastParameter()); + Geom2dInt_GInter Intersector(AC, + Precision::Confusion(), + Precision::Confusion()); + if (Intersector.IsDone() && Intersector.IsEmpty()) + break; + } + default: { IntPatch_PrmPrmIntersection interpp; interpp.Perform(S1,D1,TolTang,TolArc,myFleche,myUVMaxStep); diff --git a/src/IntTools/IntTools_FaceFace.cxx b/src/IntTools/IntTools_FaceFace.cxx index ccd519642e..e802a09299 100644 --- a/src/IntTools/IntTools_FaceFace.cxx +++ b/src/IntTools/IntTools_FaceFace.cxx @@ -627,8 +627,11 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1, #endif const Standard_Boolean isGeomInt = isTreatAnalityc(aBAS1, aBAS2, myTol); - myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang, - myListOfPnts, RestrictLine, isGeomInt); + if (aF1.IsSame(aF2)) + myIntersector.Perform(myHS1, dom1, TolArc, TolTang); + else + myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang, + myListOfPnts, RestrictLine, isGeomInt); myIsDone = myIntersector.IsDone(); diff --git a/src/ProjLib/ProjLib.cxx b/src/ProjLib/ProjLib.cxx index e536aacd8b..c9f380bcc8 100644 --- a/src/ProjLib/ProjLib.cxx +++ b/src/ProjLib/ProjLib.cxx @@ -39,6 +39,15 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include //======================================================================= //function : Project @@ -234,3 +243,41 @@ gp_Lin2d ProjLib::Project(const gp_Torus& To, const gp_Circ& Ci) ProjLib_Torus Proj( To, Ci); return Proj.Line(); } + +//======================================================================= +//function : MakePCurveOfType +//purpose : +//======================================================================= +void ProjLib::MakePCurveOfType + (const ProjLib_ProjectedCurve& PC, + Handle(Geom2d_Curve)& C2D) +{ + + switch (PC.GetType()) { + + case GeomAbs_Line : + C2D = new Geom2d_Line(PC.Line()); + break; + case GeomAbs_Circle : + C2D = new Geom2d_Circle(PC.Circle()); + break; + case GeomAbs_Ellipse : + C2D = new Geom2d_Ellipse(PC.Ellipse()); + break; + case GeomAbs_Parabola : + C2D = new Geom2d_Parabola(PC.Parabola()); + break; + case GeomAbs_Hyperbola : + C2D = new Geom2d_Hyperbola(PC.Hyperbola()); + break; + case GeomAbs_BSplineCurve : + C2D = PC.BSpline(); + break; + case GeomAbs_BezierCurve : + case GeomAbs_OtherCurve : + default : + Standard_NotImplemented::Raise + ("ProjLib::MakePCurveOfType"); + break; + } +} diff --git a/src/ProjLib/ProjLib.hxx b/src/ProjLib/ProjLib.hxx index a06c3dfde4..b5fa7ac097 100644 --- a/src/ProjLib/ProjLib.hxx +++ b/src/ProjLib/ProjLib.hxx @@ -20,6 +20,7 @@ #include #include #include +#include class gp_Pnt2d; class gp_Pln; @@ -128,6 +129,9 @@ public: Standard_EXPORT static gp_Lin2d Project (const gp_Torus& To, const gp_Circ& Ci); + //! Make empty P-Curve of relevant to type + Standard_EXPORT static void MakePCurveOfType (const ProjLib_ProjectedCurve& PC, + Handle(Geom2d_Curve)& aC); diff --git a/src/ProjLib/ProjLib_ProjectOnPlane.cxx b/src/ProjLib/ProjLib_ProjectOnPlane.cxx index b8b9a036f4..c31d8f6a5a 100644 --- a/src/ProjLib/ProjLib_ProjectOnPlane.cxx +++ b/src/ProjLib/ProjLib_ProjectOnPlane.cxx @@ -898,6 +898,16 @@ const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const return myCurve; } +//======================================================================= +//function : GetResult +//purpose : +//======================================================================= + +const Handle(GeomAdaptor_HCurve)& ProjLib_ProjectOnPlane::GetResult() const +{ + return myResult; +} + //======================================================================= //function : FirstParameter diff --git a/src/ProjLib/ProjLib_ProjectOnPlane.hxx b/src/ProjLib/ProjLib_ProjectOnPlane.hxx index 9b0a6d0dc5..e3d50ce496 100644 --- a/src/ProjLib/ProjLib_ProjectOnPlane.hxx +++ b/src/ProjLib/ProjLib_ProjectOnPlane.hxx @@ -92,6 +92,8 @@ public: Standard_EXPORT const Handle(Adaptor3d_HCurve)& GetCurve() const; + Standard_EXPORT const Handle(GeomAdaptor_HCurve)& GetResult() const; + Standard_EXPORT Standard_Real FirstParameter() const Standard_OVERRIDE; Standard_EXPORT Standard_Real LastParameter() const Standard_OVERRIDE; diff --git a/tests/bugs/modalg_6/bug27341_312 b/tests/bugs/modalg_6/bug27341_312 index 326496810a..85bcb3d93e 100644 --- a/tests/bugs/modalg_6/bug27341_312 +++ b/tests/bugs/modalg_6/bug27341_312 @@ -23,6 +23,6 @@ build3d result fit checkprops result -l 534.882 -checknbshapes result -vertex 310 -edge 155 +checknbshapes result -vertex 318 -edge 159 checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug27998_1 b/tests/bugs/modalg_6/bug27998_1 new file mode 100644 index 0000000000..c3de713581 --- /dev/null +++ b/tests/bugs/modalg_6/bug27998_1 @@ -0,0 +1,17 @@ +puts "============" +puts "OCC27998" +puts "============" +puts "" +###################################################### +# Self-intersection is not detected +###################################################### + +restore [locate_data_file bug27998_solid_8.brep] a + +set info1 [bopcheck a 9] + +if { [regexp "F/F: x6 x6" $info1] != 1 } { + puts "Error : bopcheck a works wrong" +} else { + puts "OK: bopcheck a works properly" +} \ No newline at end of file diff --git a/tests/bugs/modalg_6/bug27998_2 b/tests/bugs/modalg_6/bug27998_2 new file mode 100644 index 0000000000..0ee66cddde --- /dev/null +++ b/tests/bugs/modalg_6/bug27998_2 @@ -0,0 +1,17 @@ +puts "============" +puts "OCC27998" +puts "============" +puts "" +###################################################### +# Self-intersection is not detected +###################################################### + +restore [locate_data_file bug27998_shape_self-int.brep] a + +set info1 [bopcheck a 9] + +if { ([regexp "F/F: x18 x18" $info1] != 1) && ([regexp "F/F: x44 x44" $info1] != 1) } { + puts "Error : bopcheck a works wrong" +} else { + puts "OK: bopcheck a works properly" +} \ No newline at end of file diff --git a/tests/bugs/modalg_6/bug27998_3 b/tests/bugs/modalg_6/bug27998_3 new file mode 100644 index 0000000000..a73e8d60be --- /dev/null +++ b/tests/bugs/modalg_6/bug27998_3 @@ -0,0 +1,23 @@ +puts "============" +puts "OCC27998" +puts "============" +puts "" +###################################################### +# Self-intersection is not detected +###################################################### + +restore [locate_data_file bug20807_coil.brep] cc +explode cc e +mkcurve cc cc_1 +trim tc cc 0 6 +mkedge ee tc +prism a ee 0 0 50 +donly a + +set info1 [bopcheck a 9] + +if { [regexp "F/F: x0 x0" $info1] != 1 } { + puts "Error : bopcheck a works wrong" +} else { + puts "OK: bopcheck a works properly" +} \ No newline at end of file