// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File : GEOMAlgo_Tools3D.cxx // Created : // Author : Peter KURNEV #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 #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 #include #include // #include // static Standard_Boolean FindFacePairs (const TopoDS_Edge& , const TopTools_ListOfShape& , NMTTools_ListOfCoupleOfShape& ); static Standard_Real AngleWithRef(const gp_Dir& , const gp_Dir& , const gp_Dir& ); static void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, Standard_Real aT, gp_Pnt& aPF, gp_Dir& aDNF, const Handle(IntTools_Context)& aCtx); //======================================================================= //function : IsInternalFace //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, const Standard_Real theTol, const Handle(IntTools_Context)& theContext) { Standard_Boolean bRet; Standard_Integer aNbF; TopoDS_Edge aEL; TopExp_Explorer aExp; TopTools_ListIteratorOfListOfShape aItF; // bRet=Standard_False; // // 1 Try to find an edge from theFace in theMEF aExp.Init(theFace, TopAbs_EDGE); for(; aExp.More(); aExp.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current()); if (!theMEF.Contains(aE)) { continue; } // const TopTools_ListOfShape& aLF=theMEF.FindFromKey(aE); aNbF=aLF.Extent(); if (!aNbF) { return bRet; // it can not be so } else if (aNbF==1) { // aE is internal edge on aLF.First() const TopoDS_Face& aF1=TopoDS::Face(aLF.First()); bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF1, theContext); return bRet; } else if (aNbF==2) { const TopoDS_Face& aF1=TopoDS::Face(aLF.First()); const TopoDS_Face& aF2=TopoDS::Face(aLF.Last()); // if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) { // treat as it was for 1 face bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF2, theContext); return bRet; } } if (aNbF%2) { return bRet; // it can not be so } else { // aNbF=2,4,6,8,... bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aLF, theContext); return bRet; } }//for(; aExp.More(); aExp.Next()) { // //======================================== // 2. Classify face using classifier // TopAbs_State aState; TopTools_IndexedMapOfShape aBounds; // aState=GEOMAlgo_Tools3D::ComputeState(theFace, theSolid, theTol, aBounds, theContext); bRet=(aState==TopAbs_IN); // return bRet; } //======================================================================= //function : IsInternalFace //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, const TopTools_ListOfShape& theLF, const Handle(IntTools_Context)& theContext) { Standard_Boolean bRet; Standard_Boolean aNbF; // bRet=Standard_False; // aNbF=theLF.Extent(); if (aNbF==2) { const TopoDS_Face& aF1=TopoDS::Face(theLF.First()); const TopoDS_Face& aF2=TopoDS::Face(theLF.Last()); bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext); return bRet; } // else { NMTTools_ListOfCoupleOfShape aLCFF; NMTTools_ListIteratorOfListOfCoupleOfShape aIt; // FindFacePairs(theEdge, theLF, aLCFF); // aIt.Initialize(aLCFF); for (; aIt.More(); aIt.Next()) { const NMTTools_CoupleOfShape& aCSFF=aIt.Value(); // const TopoDS_Face& aF1=TopoDS::Face(aCSFF.Shape1()); const TopoDS_Face& aF2=TopoDS::Face(aCSFF.Shape2()); bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext); if (bRet) { return bRet; } } } return bRet; } //======================================================================= //function : IsInternalFace //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, const TopoDS_Face& theFace1, const TopoDS_Face& theFace2, const Handle(IntTools_Context)& theContext) { Standard_Boolean bRet; Standard_Real aT1, aT2, aT, aDt2D, aDt2Dx; Standard_Real aA12, aA1x, aTwoPI; gp_Pnt aPx, aPF, aPF1, aPF2; gp_Pnt2d aP2D, aPF2D; gp_Dir aDNF1, aDNF2; TopoDS_Edge aE1, aE2; Handle(Geom_Curve)aC3D; // aC3D =BRep_Tool::Curve(theEdge, aT1, aT2); aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); aC3D->D0(aT, aPx); // // 1. PF aDt2D=BOPTools_Tools3D::MinStepIn2d(); aDt2Dx=10.*aDt2D; BOPTools_Tools3D::PointNearEdge (theEdge, theFace, aT, aDt2Dx, aPF2D, aPF); // // 2. E1, E2 GEOMAlgo_Tools3D::GetEdgeOnFace(theEdge, theFace1, aE1); if (aE1.Orientation()==TopAbs_INTERNAL) { aE2=aE1; aE1.Orientation(TopAbs_FORWARD); aE2.Orientation(TopAbs_REVERSED); } else if (theFace1==theFace2) { aE2=aE1; aE1.Orientation(TopAbs_FORWARD); aE2.Orientation(TopAbs_REVERSED); } else { GEOMAlgo_Tools3D::GetEdgeOnFace(theEdge, theFace2, aE2); } // // 3 bRet=Standard_False; // GetApproxNormalToFaceOnEdge (aE1, theFace1, aT, aPF1, aDNF1, theContext); GetApproxNormalToFaceOnEdge (aE2, theFace2, aT, aPF2, aDNF2, theContext); // aTwoPI = 2.*M_PI; gp_Vec aVBF (aPx, aPF ); gp_Vec aVBF1(aPx, aPF1); gp_Vec aVBF2(aPx, aPF2); // gp_Dir aDTF1; gp_Dir aDBF (aVBF); gp_Dir aDBF1(aVBF1); gp_Dir aDBF2(aVBF2); // aDTF1=aDNF1^aDBF1; aA12=AngleWithRef(aDBF1, aDBF2, aDTF1); if (aA12<0.) { aA12=aA12+aTwoPI; } aA1x=AngleWithRef(aDBF1, aDBF , aDTF1); if (aA1x<0.) { aA1x=aA1x+aTwoPI; } // if (aA1xD0(aT, aP3D); } // aState=GEOMAlgo_Tools3D::ComputeState(aP3D, theRef, theTol, theCtx); // return aState; } //======================================================================= // function: ComputeState // purpose: //======================================================================= TopAbs_State GEOMAlgo_Tools3D::ComputeState(const gp_Pnt& theP, const TopoDS_Solid& theRef, const Standard_Real theTol, const Handle(IntTools_Context)& theCtx) { TopAbs_State aState; // BRepClass3d_SolidClassifier& aSC=theCtx->SolidClassifier(theRef); aSC.Perform(theP, theTol); // aState=aSC.State(); // return aState; } //======================================================================= // function: IsSplitToReverse // purpose: //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Shape& theSp, const TopoDS_Shape& theSr, const Handle(IntTools_Context)& theCtx) { Standard_Boolean bRet; TopAbs_ShapeEnum aType; // bRet=Standard_False; // aType=theSp.ShapeType(); switch (aType) { case TopAbs_EDGE: { const TopoDS_Edge& aESp=TopoDS::Edge(theSp); const TopoDS_Edge& aESr=TopoDS::Edge(theSr); bRet=GEOMAlgo_Tools3D::IsSplitToReverse(aESp, aESr, theCtx); } break; // case TopAbs_FACE: { const TopoDS_Face& aFSp=TopoDS::Face(theSp); const TopoDS_Face& aFSr=TopoDS::Face(theSr); bRet=GEOMAlgo_Tools3D::IsSplitToReverse(aFSp, aFSr, theCtx); } break; // default: break; } return bRet; } //======================================================================= //function :IsSplitToReverse //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Face& theFSp, const TopoDS_Face& theFSr, const Handle(IntTools_Context)& theContext) { Standard_Boolean bRet, bFound, bInFace; Standard_Real aT1, aT2, aT, aU, aV, aScPr; gp_Pnt aPFSp, aPFSr; gp_Dir aDNFSp; gp_Vec aD1U, aD1V; Handle(Geom_Surface) aSr, aSp; TopAbs_Orientation aOrSr, aOrSp; TopExp_Explorer anExp; TopoDS_Edge aESp; // bRet=Standard_False; // aSr=BRep_Tool::Surface(theFSr); aSp=BRep_Tool::Surface(theFSp); if (aSr==aSp) { aOrSr=theFSr.Orientation(); aOrSp=theFSp.Orientation(); bRet=(aOrSr!=aOrSp); return bRet; } // bFound=Standard_False; anExp.Init(theFSp, TopAbs_EDGE); for (; anExp.More(); anExp.Next()) { aESp=TopoDS::Edge(anExp.Current()); if (!BRep_Tool::Degenerated(aESp)) { if (!BRep_Tool::IsClosed(aESp, theFSp)) { bFound=!bFound; break; } } } // //modified by NIZNHY-PKV Tue Nov 22 10:50:30 2011f if (!bFound) { Standard_Boolean bFlag; Standard_Integer iErr; gp_Pnt2d aP2DFSp; // iErr=GEOMAlgo_Tools3D::PntInFace(theFSp, aPFSp, aP2DFSp); if (iErr) { return bRet; } // aP2DFSp.Coord(aU, aV); bFlag=BOPTools_Tools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp); if (!bFlag) { return bRet; } } else { BRep_Tool::Range(aESp, aT1, aT2); aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp); } // /* if (!bFound) { return bRet; } BRep_Tool::Range(aESp, aT1, aT2); aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp); */ //modified by NIZNHY-PKV Tue Nov 22 10:50:37 2011t // // Parts of theContext.ComputeVS(..) GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr); aProjector.Perform(aPFSp); if (!aProjector.IsDone()) { return bRet; } // aProjector.LowerDistanceParameters(aU, aV); gp_Pnt2d aP2D(aU, aV); bInFace=theContext->IsPointInFace (theFSr, aP2D); if (!bInFace) { return bRet; } // aSr->D1(aU, aV, aPFSr, aD1U, aD1V); gp_Dir aDD1U(aD1U); gp_Dir aDD1V(aD1V); gp_Dir aDNFSr=aDD1U^aDD1V; if (theFSr.Orientation()==TopAbs_REVERSED){ aDNFSr.Reverse(); } // aScPr=aDNFSp*aDNFSr; bRet=(aScPr<0.); // return bRet; } //======================================================================= //function :IsSplitToReverse //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Edge& theSplit, const TopoDS_Edge& theEdge, const Handle(IntTools_Context)& theContext) { Standard_Boolean bRet, aFlag, bIsDegenerated; Standard_Real aTE, aTS, aScPr, aTa, aTb, aT1, aT2; TopAbs_Orientation aOrSr, aOrSp; Handle(Geom_Curve) aCEdge, aCSplit; gp_Vec aVE, aVS; gp_Pnt aP; // bRet=Standard_False; // bIsDegenerated=(BRep_Tool::Degenerated(theSplit) || BRep_Tool::Degenerated(theEdge)); if (bIsDegenerated) { return bRet; } // aCEdge =BRep_Tool::Curve(theEdge , aT1, aT2); aCSplit=BRep_Tool::Curve(theSplit, aTa, aTb); // if (aCEdge==aCSplit) { aOrSr=theEdge.Orientation(); aOrSp=theSplit.Orientation(); bRet=(aOrSr!=aOrSp); return bRet; } // aTS=BOPTools_Tools2D::IntermediatePoint(aTa, aTb); aCSplit->D0(aTS, aP); aFlag=BOPTools_Tools2D::EdgeTangent(theSplit, aTS, aVS); gp_Dir aDTS(aVS); // aFlag=theContext->ProjectPointOnEdge(aP, theEdge, aTE); aFlag=BOPTools_Tools2D::EdgeTangent(theEdge, aTE, aVE); gp_Dir aDTE(aVE); // aScPr=aDTS*aDTE; bRet=(aScPr<0.); // return bRet; } //======================================================================= // function: Sense // purpose: //======================================================================= Standard_Integer GEOMAlgo_Tools3D::Sense (const TopoDS_Face& theF1, const TopoDS_Face& theF2) { Standard_Integer iSense=0; gp_Dir aDNF1, aDNF2; TopoDS_Edge aE1, aE2; TopExp_Explorer anExp; // anExp.Init(theF1, TopAbs_EDGE); for (; anExp.More(); anExp.Next()) { aE1=TopoDS::Edge(anExp.Current()); if (!BRep_Tool::Degenerated(aE1)) { if (!BRep_Tool::IsClosed(aE1, theF1)) { break; } } } // anExp.Init(theF2, TopAbs_EDGE); for (; anExp.More(); anExp.Next()) { aE2=TopoDS::Edge(anExp.Current()); if (!BRep_Tool::Degenerated(aE2)) { if (!BRep_Tool::IsClosed(aE2, theF2)) { if (aE2.IsSame(aE1)) { iSense=1; break; } } } } // if (!iSense) { return iSense; } // BOPTools_Tools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1); BOPTools_Tools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2); // iSense=BOPTools_Tools3D::SenseFlag(aDNF1, aDNF2); // return iSense; } //======================================================================= // function: CopyFace // purpose: //======================================================================= void GEOMAlgo_Tools3D::CopyFace (const TopoDS_Face& theF1, TopoDS_Face& theF2) { Standard_Real aTol; TopLoc_Location aLoc; TopAbs_Orientation aOr; TopoDS_Iterator aIt; BRep_Builder aBB; // Handle(Geom_Surface) aSurface=BRep_Tool::Surface(theF1, aLoc); aTol=BRep_Tool::Tolerance(theF1); aOr=theF1.Orientation(); // aBB.MakeFace (theF2, aSurface, aLoc, aTol); theF2.Orientation(aOr); // aIt.Initialize(theF1); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aW=aIt.Value(); aBB.Add(theF2, aW); } } //======================================================================= // function: MakeContainer // purpose: //======================================================================= void GEOMAlgo_Tools3D::MakeContainer(const TopAbs_ShapeEnum theType, TopoDS_Shape& theC) { BRep_Builder aBB; // switch(theType) { case TopAbs_COMPOUND:{ TopoDS_Compound aC; aBB.MakeCompound(aC); theC=aC; } break; // case TopAbs_COMPSOLID:{ TopoDS_CompSolid aCS; aBB.MakeCompSolid(aCS); theC=aCS; } break; // case TopAbs_SOLID:{ TopoDS_Solid aSolid; aBB.MakeSolid(aSolid); theC=aSolid; } break; // // case TopAbs_SHELL:{ TopoDS_Shell aShell; aBB.MakeShell(aShell); theC=aShell; } break; // case TopAbs_WIRE: { TopoDS_Wire aWire; aBB.MakeWire(aWire); theC=aWire; } break; // default: break; } } //======================================================================= // function: MakeConnexityBlock. // purpose: //======================================================================= void GEOMAlgo_Tools3D::MakeConnexityBlock (const TopTools_ListOfShape& theLFIn, const TopTools_IndexedMapOfShape& theMEAvoid, TopTools_ListOfShape& theLCB) { Standard_Integer aNbF, aNbAdd1; TopExp_Explorer aExp; TopTools_IndexedDataMapOfShapeListOfShape aMEF; TopTools_MapIteratorOfMapOfShape aItM, aItM1; TopTools_MapOfShape aMCB, aMAdd, aMAdd1; TopTools_ListIteratorOfListOfShape aIt; // // 1. aMEF aNbF=theLFIn.Extent(); aIt.Initialize(theLFIn); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); } // // 2. aMCB const TopoDS_Shape& aF1=theLFIn.First(); aMAdd.Add(aF1); // while(1) { aMAdd1.Clear(); aItM.Initialize(aMAdd); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aF=aItM.Key(); // //aMAdd1.Clear(); aExp.Init(aF, TopAbs_EDGE); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aE=aExp.Current(); if (theMEAvoid.Contains(aE)){ continue; } // const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE); aIt.Initialize(aLF); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aFx=aIt.Value(); if (aFx.IsSame(aF)) { continue; } if (aMCB.Contains(aFx)) { continue; } aMAdd1.Add(aFx); } }//for (; aExp.More(); aExp.Next()){ aMCB.Add(aF); }// for (; aItM.More(); aItM.Next()) { // aNbAdd1=aMAdd1.Extent(); if (!aNbAdd1) { break; } // aMAdd.Clear(); aItM1.Initialize(aMAdd1); for (; aItM1.More(); aItM1.Next()) { const TopoDS_Shape& aFAdd=aItM1.Key(); aMAdd.Add(aFAdd); } // }//while(1) { // aNbF=aMCB.Extent(); aItM.Initialize(aMCB); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aF=aItM.Key(); theLCB.Append(aF); } } //======================================================================= //function : FindFacePairs //purpose : //======================================================================= Standard_Boolean FindFacePairs (const TopoDS_Edge& theE, const TopTools_ListOfShape& thLF, NMTTools_ListOfCoupleOfShape& theLCFF) { Standard_Boolean bFound; Standard_Integer i, aNbCEF; TopAbs_Orientation aOr, aOrC; TopTools_MapOfShape aMFP; TopoDS_Face aF1, aF2; TopoDS_Edge aEL, aE1; TopTools_ListIteratorOfListOfShape aItLF; NMTTools_CoupleOfShape aCEF, aCFF; NMTTools_ListOfCoupleOfShape aLCEF, aLCEFx; NMTTools_ListIteratorOfListOfCoupleOfShape aIt; // bFound=Standard_True; // // Preface aLCEF aItLF.Initialize(thLF); for (; aItLF.More(); aItLF.Next()) { const TopoDS_Face& aFL=TopoDS::Face(aItLF.Value()); // bFound=GEOMAlgo_Tools3D::GetEdgeOnFace(theE, aFL, aEL); if (!bFound) { return bFound; // it can not be so } // aCEF.SetShape1(aEL); aCEF.SetShape2(aFL); aLCEF.Append(aCEF); } // aNbCEF=aLCEF.Extent(); while(aNbCEF) { // // aLCEFx aLCEFx.Clear(); aIt.Initialize(aLCEF); for (i=0; aIt.More(); aIt.Next(), ++i) { const NMTTools_CoupleOfShape& aCSx=aIt.Value(); const TopoDS_Shape& aEx=aCSx.Shape1(); const TopoDS_Shape& aFx=aCSx.Shape2(); // aOr=aEx.Orientation(); // if (!i) { aOrC=TopAbs::Reverse(aOr); aE1=TopoDS::Edge(aEx); aF1=TopoDS::Face(aFx); aMFP.Add(aFx); continue; } // if (aOr==aOrC) { aLCEFx.Append(aCSx); aMFP.Add(aFx); } } // // F2 GEOMAlgo_Tools3D::GetFaceOff(aE1, aF1, aLCEFx, aF2); // aCFF.SetShape1(aF1); aCFF.SetShape2(aF2); theLCFF.Append(aCFF); // aMFP.Add(aF1); aMFP.Add(aF2); // // refine aLCEF aLCEFx.Clear(); aLCEFx=aLCEF; aLCEF.Clear(); aIt.Initialize(aLCEFx); for (; aIt.More(); aIt.Next()) { const NMTTools_CoupleOfShape& aCSx=aIt.Value(); const TopoDS_Shape& aFx=aCSx.Shape2(); if (!aMFP.Contains(aFx)) { aLCEF.Append(aCSx); } } // aNbCEF=aLCEF.Extent(); }//while(aNbCEF) { // return bFound; } // //======================================================================= //function : AngleWithRef //purpose : //======================================================================= Standard_Real AngleWithRef(const gp_Dir& theD1, const gp_Dir& theD2, const gp_Dir& theDRef) { Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr; gp_XYZ aXYZ; // aHalfPI=0.5*M_PI; // const gp_XYZ& aXYZ1=theD1.XYZ(); const gp_XYZ& aXYZ2=theD2.XYZ(); aXYZ=aXYZ1.Crossed(aXYZ2); aSinus=aXYZ.Modulus(); aCosinus=theD1*theD2; // aBeta=0.; if (aSinus>=0.) { aBeta=aHalfPI*(1.-aCosinus); } else { aBeta=2.*M_PI-aHalfPI*(3.+aCosinus); } // aScPr=aXYZ.Dot(theDRef.XYZ()); if (aScPr<0.) { aBeta=-aBeta; } return aBeta; } //======================================================================= //function : GetApproxNormalToFaceOnEdge //purpose : //======================================================================= void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aEx, const TopoDS_Face& aFx, Standard_Real aT, gp_Pnt& aPF, gp_Dir& aDNF, const Handle(IntTools_Context)& aCtx) { Standard_Boolean bReverse; Standard_Real aT1, aT2, dT, aU, aV; gp_Dir aDTT, aDNFT, aDBT; gp_Pnt aPFT, aPFx; Handle(Geom_Curve) aC3D; Handle(Geom_Surface) aS; GeomAdaptor_Surface aGAS; GeomAbs_SurfaceType aTS; TopoDS_Face aF; TopoDS_Edge aE; // bReverse=Standard_False; aF=aFx; aE=aEx; if (aF.Orientation()==TopAbs_REVERSED){ bReverse=!bReverse; aE.Reverse(); // aF.Orientation(TopAbs_FORWARD); } // // Point at aT aC3D =BRep_Tool::Curve(aE, aT1, aT2); aC3D->D0(aT, aPFT); // // Normal at aT BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNFT); // Tangent at aT BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDTT); // // Binormal at aT aDBT=aDNFT^aDTT; // dT=BOPTools_Tools3D::MinStepIn2d();//~1.e-5; dT=10.*dT; //---------------------------------------------- { aS=BRep_Tool::Surface(aF); aGAS.Load(aS); aTS=aGAS.GetType(); if (aTS==GeomAbs_BSplineSurface || aTS==GeomAbs_BezierSurface || aTS==GeomAbs_Plane){ Standard_Real aTolEx, aTolFx, aTol, dUR, dVR, dR; // aTolEx=BRep_Tool::Tolerance(aEx); aTolFx=BRep_Tool::Tolerance(aFx); aTol=2.*aTolEx+aTolFx; dUR=aGAS.UResolution(aTol); dVR=aGAS.VResolution(aTol); dR=(dUR>dVR)? dUR : dVR; if (dR>dT) { dT=dR; } } else if (GeomAbs_Torus || aTS==GeomAbs_Cylinder){ Standard_Real aTolEx, aTolFx, aTol; // aTolEx=BRep_Tool::Tolerance(aEx); aTolFx=BRep_Tool::Tolerance(aFx); aTol=2.*aTolEx+aTolFx; if (aTol>dT) { dT=aTol; } } } //---------------------------------------------- // aPFx.SetXYZ(aPFT.XYZ()+dT*aDBT.XYZ()); // aPF=aPFx; aDNF=aDNFT; if (bReverse) { aDNF.Reverse(); } // GeomAPI_ProjectPointOnSurf& aProjector=aCtx->ProjPS(aF); // aProjector.Perform(aPFx); if(aProjector.IsDone()) { aProjector.LowerDistanceParameters (aU, aV); aS->D0(aU, aV, aPF); BOPTools_Tools3D::GetNormalToSurface (aS, aU, aV, aDNF); if (bReverse){ aDNF.Reverse(); } } } //modified by NIZNHY-PKV Tue Nov 22 10:36:59 2011f //======================================================================= //function : PntInFace //purpose : //======================================================================= Standard_Integer GEOMAlgo_Tools3D::PntInFace(const TopoDS_Face& aF, gp_Pnt& theP, gp_Pnt2d& theP2D) { Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint; Standard_Integer iErr, aIx, aNbDomains, i; Standard_Real aUMin, aUMax, aVMin, aVMax; Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT; Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D; gp_Dir2d aD2D (0., 1.); gp_Pnt2d aP2D; gp_Pnt aPx; Handle(Geom2d_Curve) aC2D; Handle(Geom2d_TrimmedCurve) aCT2D; Handle(Geom2d_Line) aL2D; Handle(Geom_Surface) aS; TopAbs_Orientation aOrE; TopoDS_Face aFF; TopExp_Explorer aExp; // aTolHatch2D=1.e-8; aTolHatch3D=1.e-8; aTotArcIntr=1.e-10; aTolTangfIntr=1.e-10; // Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr); Geom2dHatch_Hatcher aHatcher(aIntr, aTolHatch2D, aTolHatch3D, Standard_True, Standard_False); // iErr=0; aEpsT=1.e-12; // aFF=aF; aFF.Orientation (TopAbs_FORWARD); // aS=BRep_Tool::Surface(aFF); BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax); // // 1 aExp.Init (aFF, TopAbs_EDGE); for (; aExp.More() ; aExp.Next()) { const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current()); aOrE=aE.Orientation(); // aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2); if (aC2D.IsNull() ) { iErr=1; return iErr; } if (fabs(aU1-aU2) < aEpsT) { iErr=2; return iErr; } // aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2); aHatcher.AddElement(aCT2D, aOrE); }// for (; aExp.More() ; aExp.Next()) { // // 2 aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax); aP2D.SetCoord(aUx, 0.); aL2D=new Geom2d_Line (aP2D, aD2D); Geom2dAdaptor_Curve aHCur(aL2D); // aIx=aHatcher.AddHatching(aHCur) ; // // 3. aHatcher.Trim(); bIsDone=aHatcher.TrimDone(aIx); if (!bIsDone) { iErr=3; return iErr; } // aHatcher.ComputeDomains(aIx); bIsDone=aHatcher.IsDone(aIx); if (!bIsDone) { iErr=4; return iErr; } // // 4. aNbDomains=aHatcher.NbDomains(aIx); for (i=1; i<=aNbDomains; ++i) { const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ; bHasFirstPoint=aDomain.HasFirstPoint(); if (!bHasFirstPoint) { iErr=5; return iErr; } // aV1=aDomain.FirstPoint().Parameter(); // bHasSecondPoint=aDomain.HasSecondPoint(); if (!bHasSecondPoint) { iErr=6; return iErr; } // aV2=aDomain.SecondPoint().Parameter(); // aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); // break; } // aS->D0(aUx, aVx, aPx); // theP2D.SetCoord(aUx, aVx); theP=aPx; // return iErr; } //modified by NIZNHY-PKV Tue Nov 22 10:37:01 2011t