// File: BRepClass3d_SClassifier.cxx // Created: Mon Jul 15 17:26:21 1996 // Author: Laurent BUCHARD // // Modified by skv - Thu Sep 4 11:22:05 2003 OCC578 #include #include #include #include #include #include #include // modified by NIZHNY-MKK Mon Jun 21 15:13:40 2004 #include #include #include #include static void FaceNormal (const TopoDS_Face& aF, const Standard_Real U, const Standard_Real V, gp_Dir& aDN); static Standard_Real GetAddToParam(const gp_Lin& L,const Standard_Real P,const Bnd_Box& B); //======================================================================= //function : BRepClass3d_SClassifier //purpose : //======================================================================= BRepClass3d_SClassifier::BRepClass3d_SClassifier() { } //======================================================================= //function : BRepClass3d_SClassifier //purpose : //======================================================================= BRepClass3d_SClassifier::BRepClass3d_SClassifier(BRepClass3d_SolidExplorer& S, const gp_Pnt& P, const Standard_Real Tol) { if(S.Reject(P)) { myState=3; //-- in ds le cas solide sans face } else { Perform(S,P,Tol); } } //======================================================================= //function : PerformInfinitePoint //purpose : //======================================================================= void BRepClass3d_SClassifier::PerformInfinitePoint(BRepClass3d_SolidExplorer& aSE, const Standard_Real /*Tol*/) { //-- Idee : On prend un point A dans la face1 et un point B dans la face B //-- ( si on a une seule face , on prend 2 points dans la meme face.) //-- //-- On intersecte la droite AB avec le solide et on s interesse a la transition du //-- premier point. Si le solide a une seule face et que la droite AB ne le coupe pas //-- on ne peut pas decider. if(aSE.Reject(gp_Pnt(0,0,0))) { myState=3; //-- in ds le cas solide sans face return; } // //------------------------------------------------------------ // 1 Standard_Boolean bFound, bFlag; Standard_Integer nump; Standard_Real aParam, aU1, aV1, aU2, aV2; gp_Pnt A,B; gp_Dir aDN1, aDN2; TopoDS_Face aF, aF1, aF2; // nump = 0; aParam = 0.5; myFace.Nullify(); myState=2; for(aSE.InitShell(); aSE.MoreShell() && nump<2; aSE.NextShell()) { for(aSE.InitFace(); aSE.MoreFace() && nump<2; ) { TopoDS_Shape aLocalShape = aSE.CurrentFace(); aF = TopoDS::Face(aLocalShape); aSE.NextFace(); if(!nump) { nump++; bFound=aSE.FindAPointInTheFace(aF, A, aU1, aV1, aParam); if (!bFound) { return; } aF1=aF; if(!aSE.MoreFace()) { nump++; bFound=aSE.FindAPointInTheFace(aF, B, aU2, aV2, aParam); if (!bFound) { return; } aF2=aF; } }// if(nump==0) { else if(nump==1) { bFound=aSE.FindAPointInTheFace(aF, B, aU2, aV2, aParam); if(!bFound) { return; } aF2=aF; nump++; } }// for(aSE.InitFace(); aSE.MoreFace() && nump<2; ) { }// for(aSE.InitShell(); aSE.MoreShell() && nump<2; aSE.NextShell()) { // //------------------------------------------------------------ // 2 Standard_Integer cpasbon; Standard_Real parmin, aD2, aSP; IntCurveSurface_TransitionOnCurve aTC; TopAbs_State aState; // parmin = RealLast(); // bFlag=Standard_False; if (aF1!=aF2) { FaceNormal(aF1, aU1, aV1, aDN1); FaceNormal(aF2, aU2, aV2, aDN2); aSP=1.-aDN1*aDN2; if (aSP < 1.e-5) { bFlag=!bFlag; } } // aD2=A.SquareDistance(B); if(aD2<0.000001 || bFlag) { B.SetCoord(A.X()+1,A.Y()+1,A.Z()+1); } // cpasbon = 0; gp_Vec AB(A,B); // do { switch (cpasbon) { case 1 : AB.SetX(-AB.X());break; case 2 : AB.SetY(-AB.Y());break; case 3 : AB.SetZ(-AB.Z());break; case 4 : AB.SetY(-AB.Y());break; case 5 : AB.SetX(-AB.X());break; } gp_Lin L(A,gp_Dir(AB)); //-- cout<<"\npoint A "< anIndFace) { anIndFace = aCurInd; } else { myState = 1; return; } // Modified by skv - Thu Sep 4 11:22:10 2003 OCC578 End if (iFlag==1) { // IsOnFace // iFlag==1 i.e face is Infinite myState=2; return; } //SolidExplorer.Segment(P,L,Par); // //process results from uncorrected shells // //if(Par > 1.e+100 && L.Direction().IsParallel(gp_Dir(0.,0.,1.),1.e-8)) { if (iFlag==2) { myState = 4; return; } //-- BRepClass3d_Intersector3d Intersector3d; // Modified by skv - Thu Sep 4 13:48:27 2003 OCC578 Begin // Check if the point is ON surface but OUT of the face. // Just skip this face because it is bad for classification. if (iFlag == 3) continue; isFaultyLine = Standard_False; // Standard_Real parmin = RealLast(); // for(SolidExplorer.InitShell(); // SolidExplorer.MoreShell(); // SolidExplorer.NextShell()) { parmin = RealLast(); for(SolidExplorer.InitShell(); SolidExplorer.MoreShell() && !isFaultyLine; SolidExplorer.NextShell()) { // Modified by skv - Thu Sep 4 13:48:27 2003 OCC578 End if(SolidExplorer.RejectShell(L) == Standard_False) { // Modified by skv - Thu Sep 4 13:48:27 2003 OCC578 Begin // for(SolidExplorer.InitFace(); // SolidExplorer.MoreFace(); // SolidExplorer.NextFace()) { for(SolidExplorer.InitFace(); SolidExplorer.MoreFace() && !isFaultyLine; SolidExplorer.NextFace()) { // Modified by skv - Thu Sep 4 13:48:27 2003 OCC578 End if(SolidExplorer.RejectFace(L) == Standard_False) { //-- Intersector3d.Perform(L,Par,Tol,SolidExplorer.CurrentFace()); TopoDS_Shape aLocalShape = SolidExplorer.CurrentFace(); TopoDS_Face f = TopoDS::Face(aLocalShape); // TopoDS_Face f = TopoDS::Face(SolidExplorer.CurrentFace()); IntCurvesFace_Intersector& Intersector3d = SolidExplorer.Intersector(f); // MSV Oct 25, 2001: prolong segment, since there are cases when // the intersector does not find intersection points with the original // segment due to rough triangulation of a parametrized surface Standard_Real addW = Max(10*Tol, 0.01*Par); Standard_Real AddW = addW; Bnd_Box aBoxF = Intersector3d.Bounding(); // MSV 23.09.2004: the box must be finite in order to // correctly prolong the segment to its bounds if (!aBoxF.IsVoid() && !aBoxF.IsWhole()) { Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; aBoxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); Standard_Real boxaddW = GetAddToParam(L,Par,aBoxF); addW = Max(addW,boxaddW); } Standard_Real minW = -AddW;//-addW; Standard_Real maxW = Min(Par*10,Par+addW);//Par+addW; //cout << "range [" << minW << "," << maxW << "]" << endl << endl; Intersector3d.Perform(L,minW,maxW); //Intersector3d.Perform(L,-Tol,Par+10.0*Tol); if(Intersector3d.IsDone()) { Standard_Integer i; for (i=1; i <= Intersector3d.NbPnt(); i++) { if(Abs(Intersector3d.WParameter(i)) < Abs(parmin)) { parmin = Intersector3d.WParameter(i); // Modified by skv - Thu Sep 4 12:46:32 2003 OCC578 Begin TopAbs_State aState = Intersector3d.State(i); // Modified by skv - Thu Sep 4 12:46:33 2003 OCC578 End if(Abs(parmin)<=Tol) { myState = 2; myFace = f; } // Modified by skv - Thu Sep 4 12:46:32 2003 OCC578 Begin // Treatment of case TopAbs_ON separately. else if(aState==TopAbs_IN) { // Modified by skv - Thu Sep 4 12:46:32 2003 OCC578 End //-- The intersection point between the line and a face F // -- of the solid is in the face F IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i); if (tran == IntCurveSurface_Tangent) { #ifdef DEB cout<<"*Probleme ds BRepClass3d_SClassifier.cxx"< Par) Par = par; } else return 1.e+20; } } } return Par - P; } //======================================================================= //function : FaceNormal //purpose : //======================================================================= void FaceNormal (const TopoDS_Face& aF, const Standard_Real U, const Standard_Real V, gp_Dir& aDN) { gp_Pnt aPnt ; gp_Vec aD1U, aD1V, aN; Handle(Geom_Surface) aS; aS=BRep_Tool::Surface(aF); aS->D1 (U, V, aPnt, aD1U, aD1V); aN=aD1U.Crossed(aD1V); aN.Normalize(); aDN.SetXYZ(aN.XYZ()); if (aF.Orientation() == TopAbs_REVERSED){ aDN.Reverse(); } return; }