// File: TopOpeBRep_EdgesIntersector.cxx // Created: Fri Oct 7 14:16:31 1994 // Author: Jean Yves LEBEY // #ifdef DRAW #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DEB Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceNYI(); Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceKRO(); Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceEDSF(); Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceDSF(); Standard_EXPORT Standard_Boolean TopOpeBRep_GettracePROEDG(); Standard_EXPORT Standard_Boolean TopOpeBRep_GetcontextTOL0(); Standard_EXPORT Standard_Boolean TopOpeBRep_GetcontextNOFEI(); Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceFITOL(); Standard_EXPORT Standard_Boolean TopOpeBRep_GettraceEEFF(); Standard_EXPORT void debeeff(); #include Standard_EXPORT TOPKRO KRO_DSFILLER_INTEE("intersection edge/edge"); #endif // la surface de reference peut etre celle de la 1ere ou la 2eme face // de l'appel de SetFaces. Ces deux faces sont "SameDomain". // Leurs normales geometriques sont SurfacesSameOriented() // Leurs normales topologiques sont FacesSameOriented() // cas type 1 : // face1 FORWARD, normale geometrique Ng1 en +Z // face2 REVERSED, normale geometrique Ng2 en -Z // ==> SurfaceSameOriented = 0, FacesSameOriented = 1 //======================================================================= //function : TopOpeBRep_EdgesIntersector //purpose : //======================================================================= TopOpeBRep_EdgesIntersector::TopOpeBRep_EdgesIntersector() { mySurface1 = new BRepAdaptor_HSurface(); mySurface2 = new BRepAdaptor_HSurface(); mySurfacesSameOriented = Standard_False; myFacesSameOriented = Standard_False; myTol1 = 0.; // Precision::PConfusion(); myTol2 = 0.; // Precision::PIntersection(); myDimension = 2; myTolForced = Standard_False; myf1surf1F_sameoriented = Standard_True; myf2surf1F_sameoriented = Standard_True; myNbSegments = 0; myHasSegment = Standard_False; SetSameDomain(Standard_False); myNbPoints = 0; myTrueNbPoints = 0; myPointIndex = 0; myip2d = mynp2d = 0; myselectkeep = Standard_True; } void TopOpeBRep_EdgesIntersector::Delete() {} //======================================================================= //function : SetFaces //purpose : //======================================================================= void TopOpeBRep_EdgesIntersector::SetFaces(const TopoDS_Shape& F1,const TopoDS_Shape& F2) { Bnd_Box B1,B2; SetFaces(F1,F2,B1,B2); } //======================================================================= //function : SetFaces //purpose : //======================================================================= void TopOpeBRep_EdgesIntersector::SetFaces(const TopoDS_Shape& F1,const TopoDS_Shape& F2,const Bnd_Box& B1,const Bnd_Box& B2) { Standard_Boolean computerestriction = Standard_False; Standard_Boolean so11 = Standard_True; Standard_Boolean so21 = Standard_True; myf1surf1F_sameoriented = so11; myf2surf1F_sameoriented = so21; mySurfacesSameOriented = Standard_True; myFacesSameOriented = Standard_True; myFace1 = TopoDS::Face(F1); BRepAdaptor_Surface& S1 = mySurface1->ChangeSurface(); S1.Initialize(myFace1,computerestriction); mySurfaceType1 = S1.GetType(); myFace2 = TopoDS::Face(F2); BRepAdaptor_Surface& S2 = mySurface2->ChangeSurface(); S2.Initialize(myFace2,computerestriction); mySurfaceType2 = S2.GetType(); TopoDS_Face face1forward = myFace1; face1forward.Orientation(TopAbs_FORWARD); so11 = TopOpeBRepTool_ShapeTool::FacesSameOriented(face1forward,myFace1); myf1surf1F_sameoriented = so11; so21 = TopOpeBRepTool_ShapeTool::FacesSameOriented(face1forward,myFace2); myf2surf1F_sameoriented = so21; mySurfacesSameOriented = TopOpeBRepTool_ShapeTool::SurfacesSameOriented(S1,S2); myFacesSameOriented = TopOpeBRepTool_ShapeTool::FacesSameOriented(myFace1,myFace2); if ( !myTolForced ) { FTOL_FaceTolerances2d(B1,B2,myFace1,myFace2,S1,S2,myTol1,myTol2); myTol1 = (myTol1 > 1.e-4)? 1.e-4: myTol1; myTol2 = (myTol2 > 1.e-4)? 1.e-4: myTol2; } #ifdef DEB Standard_Integer DEBi = 0; if ( DEBi ) { cout<<"TopOpeBRep_EdgesIntersector::SetFaces : "; cout<<"f1 "; TopAbs::Print(myFace1.Orientation(),cout); cout<< " / f1F : "; if (so11) cout<<"sameoriented"; else cout<<"difforiented"; cout< static Standard_Boolean TransitionEqualAndExtremity( const IntRes2d_Transition& T1 ,const IntRes2d_Transition& T2) { if( T1.PositionOnCurve() == IntRes2d_Head || T1.PositionOnCurve() == IntRes2d_End) { if(T1.PositionOnCurve() == T2.PositionOnCurve()) { if(T1.TransitionType() == T2.TransitionType()) { if(T1.TransitionType() == IntRes2d_Touch) { if(T1.IsTangent()==T2.IsTangent()) { if(T1.Situation() == T2.Situation()) { if(T1.IsOpposite() == T2.IsOpposite()) { return(Standard_True); } } } } else { return(Standard_True); } } } } return(Standard_False); } // Modified by Sergey KHROMOV - Fri Jan 11 14:49:48 2002 Begin static Standard_Boolean IsTangentSegment(const IntRes2d_IntersectionPoint &P1, const IntRes2d_IntersectionPoint &P2, const Geom2dAdaptor_Curve &aC1, const Geom2dAdaptor_Curve &aC2, const Standard_Real aTolConf) { const gp_Pnt2d &aP2d1 = P1.Value(); const gp_Pnt2d &aP2d2 = P2.Value(); const IntRes2d_Transition &aTrans1 = P1.TransitionOfFirst(); const IntRes2d_Transition &aTrans2 = P2.TransitionOfFirst(); if (aTrans1.TransitionType() == IntRes2d_Touch || aTrans2.TransitionType() == IntRes2d_Touch) { Standard_Real aSqrDistPP = aP2d1.SquareDistance(aP2d2); if (aSqrDistPP <= aTolConf) { Standard_Real aParDist1 = Abs(P1.ParamOnFirst() - P2.ParamOnFirst()); Standard_Real aParDist2 = Abs(P1.ParamOnSecond() - P2.ParamOnSecond()); Standard_Real aResol1 = aC1.Resolution(aTolConf); Standard_Real aResol2 = aC2.Resolution(aTolConf); if (aParDist1*aParDist1 <= aResol1 && aParDist2*aParDist2 <= aResol2) return Standard_True; } } return Standard_False; } // Modified by Sergey KHROMOV - Fri Jan 11 14:49:49 2002 End //------------------------------------------------------------------------ Standard_Boolean EdgesIntersector_checkT1D(const TopoDS_Edge& E1,const TopoDS_Edge& E2,const TopoDS_Vertex& vG, TopOpeBRepDS_Transition& newT) //------------------------------------------------------------------------ // E1 sdm E2, interfers with E2 at vertex vG // vG is vertex of E2, but not vertex of E1 // purpose : get newT / attached to E1, I1d=(newT(E2),G,E2) { #define FIRST (1) #define LAST (2) #define CLOSING (3) newT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN); Standard_Integer ovine = FUN_tool_orientVinE(vG,E2); if (ovine == 0) { return Standard_False; } else if (ovine == CLOSING) { newT.Set(TopAbs_INTERNAL); return Standard_True; } Standard_Boolean first = (ovine == FIRST); Standard_Boolean last = (ovine == LAST); TopOpeBRepDS_Config C = TopOpeBRepDS_SAMEORIENTED; Standard_Boolean sso = TopOpeBRepTool_ShapeTool::ShapesSameOriented(E1,E2); if (!sso) C = TopOpeBRepDS_DIFFORIENTED; Standard_Boolean SO = (C == TopOpeBRepDS_SAMEORIENTED); Standard_Boolean DO = (C == TopOpeBRepDS_DIFFORIENTED); TopAbs_Orientation o1 = E1.Orientation(); if (o1 == TopAbs_REVERSED) {SO = !SO; DO = !DO;} // relative to E1 FORWARD Standard_Boolean reversed = (SO && first) || (DO && last); Standard_Boolean forward = (SO && last) || (DO && first); if (reversed) newT.Set(TopAbs_REVERSED); if (forward) newT.Set(TopAbs_FORWARD); return (reversed || forward); } // EdgesIntersector_checkT1D //modified by NIZNHY-PKV Fri Nov 5 12:27:07 1999 from #include //modified by NIZNHY-PKV Fri Nov 5 12:27:10 1999 to //======================================================================= //function : Perform //purpose : //======================================================================= void TopOpeBRep_EdgesIntersector::Perform(const TopoDS_Shape& E1,const TopoDS_Shape& E2,const Standard_Boolean ReduceSegment) { mysp2d.Clear(); myip2d = 1; mynp2d = 0; myEdge1 = TopoDS::Edge(E1); myEdge2 = TopoDS::Edge(E2); Standard_Real first,last,tole,tolpc; gp_Pnt2d pfirst,plast; Handle(Geom2d_Curve) PC1; //modified by NIZNHY-PKV Thu Nov 4 16:08:05 1999 f BRepAdaptor_Surface aSurface1(myFace1), aSurface2(myFace2); GeomAbs_SurfaceType aSurfaceType1=aSurface1.GetType(), aSurfaceType2=aSurface2.GetType(); if (aSurfaceType1==GeomAbs_Sphere && aSurfaceType2==GeomAbs_Sphere) { PC1 = FC2D_MakeCurveOnSurface (myEdge1,myFace1,first,last,tolpc, Standard_True); } else { PC1 = FC2D_CurveOnSurface(myEdge1,myFace1,first,last,tolpc); } //modified by NIZNHY-PKV Thu Nov 4 15:44:13 1999 to if (PC1.IsNull()) Standard_Failure::Raise("EdgesIntersector::Perform : no 2d curve"); myCurve1.Load(PC1); BRep_Tool::UVPoints(myEdge1,myFace1,pfirst,plast); tole = BRep_Tool::Tolerance(myEdge1); myDomain1.SetValues(pfirst,first,tole,plast,last,tole); #ifdef DEB Standard_Boolean trc = Standard_False; if (trc) { cout<<"ed1 on fa1 : {pfirst=("<Transformed(loc.Transformation())); Standard_Real tolreached2d; //modified by NIZNHY-PKV Fri Nov 5 12:29:13 1999 from if (aSurfaceType1==GeomAbs_Sphere && aSurfaceType2==GeomAbs_Sphere) { PC2on1 = FC2D_MakeCurveOnSurface (myEdge2, myFace1, first, last, tolpc, Standard_True); } else { PC2on1 = TopOpeBRepTool_CurveTool::MakePCurveOnFace(myFace1,NC,tolreached2d); } //modified by NIZNHY-PKV Thu Nov 4 14:52:25 1999 t } if (!PC2on1.IsNull()) { myCurve2.Load(PC2on1); tole = BRep_Tool::Tolerance(myEdge2); PC2on1->D0(first,pfirst); PC2on1->D0(last,plast); myDomain2.SetValues(pfirst,first,tole,plast,last,tole); #ifdef DEB if ( TopOpeBRep_GettracePROEDG() ) { cout<<"------------ projection de curve"< // faulty INTERNAL transition at G=v9 : // xpu281098 : cto019D2, e3 sdm e9, faulty EXTERNAL transition Standard_Boolean esd = SameDomain(); for (InitPoint();MorePoint();NextPoint()) { TopOpeBRep_Point2d& P2D = mysp2d(myip2d); Standard_Boolean isvertex1 = P2D.IsVertex(1); Standard_Boolean isvertex2 = P2D.IsVertex(2); Standard_Boolean isvertex = isvertex1 || isvertex2; if (isvertex && esd) { TopOpeBRepDS_Transition& T1 = P2D.ChangeTransition(1); TopOpeBRepDS_Transition& T2 = P2D.ChangeTransition(2); Standard_Boolean newT1=Standard_False, newT2=Standard_False; Standard_Boolean isvertex12 = isvertex1 && isvertex2; Standard_Boolean isvertex22 = isvertex2 && !isvertex12; Standard_Boolean isvertex11 = isvertex1 && !isvertex12; Standard_Boolean T1INT = (T1.Orientation(TopAbs_IN) == TopAbs_INTERNAL); if (T1INT && isvertex2 && !isvertex1) { const TopoDS_Vertex& V2 = P2D.Vertex(2); TopOpeBRepDS_Transition newT; Standard_Boolean computed = ::EdgesIntersector_checkT1D(myEdge1,myEdge2,V2,newT); if (!computed) newT1 = Standard_False; else T1.Set(newT.Orientation(TopAbs_IN)); } Standard_Boolean T2INT = (T2.Orientation(TopAbs_IN) == TopAbs_INTERNAL); Standard_Boolean T2EXT = (T2.Orientation(TopAbs_IN) == TopAbs_EXTERNAL); Standard_Boolean INTEXT2 = T2INT || T2EXT; if (INTEXT2 && isvertex1 && !isvertex2) { const TopoDS_Vertex& V1 = P2D.Vertex(1); TopOpeBRepDS_Transition newT; Standard_Boolean computed = ::EdgesIntersector_checkT1D(myEdge2,myEdge1,V1,newT); if (!computed) newT2 = Standard_False; else T2.Set(newT.Orientation(TopAbs_IN)); } // xpu121098 : cto900I7 (e12on,vG14) TopoDS_Vertex vcl2; Standard_Boolean clE2 = TopOpeBRepTool_TOOL::ClosedE(myEdge2,vcl2); Standard_Boolean nT1 = ( !T1INT && clE2 && isvertex22 && vcl2.IsSame(P2D.Vertex(2)) ); if (nT1) T1.Set(TopAbs_INTERNAL); TopoDS_Vertex vcl1; Standard_Boolean clE1 = TopOpeBRepTool_TOOL::ClosedE(myEdge1,vcl1); Standard_Boolean nT2 = ( !T2INT && clE1 && isvertex11 && vcl1.IsSame(P2D.Vertex(1)) ); if (nT2) T2.Set(TopAbs_INTERNAL); #ifdef DEB if (trc&&(newT1||nT1)) {cout<<"-> ** newT on e(1) = ";T1.Dump(cout);cout< ** newT on e(2) = ";T2.Dump(cout);cout<ChangeSurface(); else if ( Index == 2 ) return mySurface2->ChangeSurface(); else Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Surface"); return mySurface1->ChangeSurface(); } //======================================================================= //function : SurfacesSameOriented //purpose : //======================================================================= Standard_Boolean TopOpeBRep_EdgesIntersector::SurfacesSameOriented () const { return mySurfacesSameOriented; } //======================================================================= //function : FacesSameOriented //purpose : //======================================================================= Standard_Boolean TopOpeBRep_EdgesIntersector::FacesSameOriented () const { return myFacesSameOriented; } //======================================================================= //function : InitPoint //purpose : //======================================================================= void TopOpeBRep_EdgesIntersector::InitPoint(const Standard_Boolean selectkeep) { myselectkeep = selectkeep; myip2d = 1; mynp2d = mysp2d.Length(); Find(); } //======================================================================= //function : MorePoint //purpose : //======================================================================= Standard_Boolean TopOpeBRep_EdgesIntersector::MorePoint() const { Standard_Boolean b = (myip2d <= mynp2d); return b; } //======================================================================= //function : NextPoint //purpose : //======================================================================= void TopOpeBRep_EdgesIntersector::NextPoint() { myip2d++; Find(); } //======================================================================= //function : Find //purpose : //======================================================================= void TopOpeBRep_EdgesIntersector::Find() { while (myip2d <= mynp2d) { if (myselectkeep) { Standard_Boolean kf = mysp2d(myip2d).Keep(); if (kf) break; else myip2d++; } else { break; } } } //======================================================================= //function : Points //purpose : //======================================================================= const TopOpeBRep_SequenceOfPoint2d& TopOpeBRep_EdgesIntersector::Points() const { return mysp2d; } //======================================================================= //function : Point //purpose : //======================================================================= const TopOpeBRep_Point2d& TopOpeBRep_EdgesIntersector::Point() const { return mysp2d(myip2d); } //======================================================================= //function : Point //purpose : //======================================================================= const TopOpeBRep_Point2d& TopOpeBRep_EdgesIntersector::Point(const Standard_Integer I) const { if (I<1 || I>mysp2d.Length()) Standard_Failure::Raise("TopOpeBRep_EdgesIntersector::Point(I)"); return mysp2d(I); } //======================================================================= //function : ToleranceMax //purpose : //======================================================================= Standard_Real TopOpeBRep_EdgesIntersector::ToleranceMax() const { Standard_Real tol = Max(myTol1,myTol2); return tol; } //======================================================================= //function : Tolerances //purpose : //======================================================================= void TopOpeBRep_EdgesIntersector::Tolerances(Standard_Real& tol1, Standard_Real& tol2) const { tol1 = myTol1; tol2 = myTol2; } //======================================================================= //function : NbPoints //purpose : (debug) //======================================================================= Standard_Integer TopOpeBRep_EdgesIntersector::NbPoints() const { return myNbPoints; } //======================================================================= //function : NbSegments //purpose : (debug) //======================================================================= Standard_Integer TopOpeBRep_EdgesIntersector::NbSegments() const { return myNbSegments; } //======================================================================= //function : Dump //purpose : //======================================================================= #ifndef DEB void TopOpeBRep_EdgesIntersector::Dump(const TCollection_AsciiString& ,const Standard_Integer ,const Standard_Integer ) { #else void TopOpeBRep_EdgesIntersector::Dump(const TCollection_AsciiString& str,const Standard_Integer E1index,const Standard_Integer E2index) { InitPoint();if (!MorePoint()) return; cout<