Back to index

salome-geom  6.5.0
GEOMAlgo_Tools3D.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 //  File    : GEOMAlgo_Tools3D.cxx
00023 //  Created :
00024 //  Author  : Peter KURNEV
00025 
00026 #include <GEOMAlgo_Tools3D.hxx>
00027 
00028 #include <Precision.hxx>
00029 
00030 #include <gp_Vec.hxx>
00031 #include <gp_Pnt.hxx>
00032 #include <gp_Dir.hxx>
00033 #include <gp_Pnt2d.hxx>
00034 #include <gp_Pln.hxx>
00035 #include <gp_XYZ.hxx>
00036 #include <gp_Dir2d.hxx>
00037 
00038 #include <Geom_Curve.hxx>
00039 #include <Geom_Surface.hxx>
00040 
00041 #include <Geom2d_Curve.hxx>
00042 #include <Geom2d_TrimmedCurve.hxx>
00043 #include <Geom2d_Line.hxx>
00044 
00045 #include <Geom2dHatch_Intersector.hxx>
00046 #include <Geom2dHatch_Hatcher.hxx>
00047 #include <HatchGen_Domain.hxx>
00048 
00049 #include <GeomAPI_ProjectPointOnSurf.hxx>
00050 
00051 #include <TopAbs_ShapeEnum.hxx>
00052 #include <TopAbs_State.hxx>
00053 
00054 #include <TopLoc_Location.hxx>
00055 
00056 #include <TopoDS.hxx>
00057 #include <TopoDS_Edge.hxx>
00058 #include <TopoDS_CompSolid.hxx>
00059 #include <TopoDS_Wire.hxx>
00060 #include <TopoDS_Compound.hxx>
00061 #include <TopoDS_Face.hxx>
00062 #include <TopoDS_Vertex.hxx>
00063 #include <TopoDS_Solid.hxx>
00064 #include <TopoDS_Shell.hxx>
00065 #include <TopoDS_Iterator.hxx>
00066 
00067 #include <TopExp.hxx>
00068 #include <TopExp_Explorer.hxx>
00069 
00070 #include <BRep_Builder.hxx>
00071 #include <BRep_Tool.hxx>
00072 //
00073 #include <TopTools_ListOfShape.hxx>
00074 #include <TopTools_IndexedMapOfShape.hxx>
00075 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00076 #include <TopTools_IndexedMapOfShape.hxx>
00077 #include <TopTools_ListIteratorOfListOfShape.hxx>
00078 #include <TopTools_MapOfShape.hxx>
00079 
00080 #include <BRepClass3d_SolidClassifier.hxx>
00081 #include <BRepTools.hxx>
00082 
00083 #include <IntTools_Context.hxx>
00084 #include <IntTools_Tools.hxx>
00085 
00086 #include <BOPTools_Tools3D.hxx>
00087 #include <BOPTools_Tools2D.hxx>
00088 #include <BOPTools_Tools.hxx>
00089 
00090 #include <NMTTools_ListOfCoupleOfShape.hxx>
00091 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
00092 #include <NMTTools_CoupleOfShape.hxx>
00093 #include <TopTools_DataMapOfShapeListOfShape.hxx>
00094 #include <TopTools_DataMapOfShapeListOfShape.hxx>
00095 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
00096 #include <TopTools_MapOfShape.hxx>
00097 #include <TopTools_MapIteratorOfMapOfShape.hxx>
00098 //
00099 #include <GeomAdaptor_Surface.hxx>
00100 
00101 
00102 //
00103 static
00104   Standard_Boolean FindFacePairs (const TopoDS_Edge& ,
00105                                   const TopTools_ListOfShape& ,
00106                                   NMTTools_ListOfCoupleOfShape& );
00107 
00108 
00109 static
00110   Standard_Real AngleWithRef(const gp_Dir& ,
00111                              const gp_Dir& ,
00112                              const gp_Dir& );
00113 
00114 static
00115   void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE,
00116                                     const TopoDS_Face& aF,
00117                                     Standard_Real aT,
00118                                     gp_Pnt& aPF,
00119                                     gp_Dir& aDNF,
00120                                     const Handle(IntTools_Context)& aCtx);
00121 
00122 //=======================================================================
00123 //function : IsInternalFace
00124 //purpose  :
00125 //=======================================================================
00126 Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
00127                                                   const TopoDS_Solid& theSolid,
00128                                                   const TopTools_IndexedDataMapOfShapeListOfShape& theMEF,
00129                                                   const Standard_Real theTol,
00130                                                   const Handle(IntTools_Context)& theContext)
00131 {
00132   Standard_Boolean bRet;
00133   Standard_Integer aNbF;
00134   TopoDS_Edge aEL;
00135   TopExp_Explorer aExp;
00136   TopTools_ListIteratorOfListOfShape aItF;
00137   //
00138   bRet=Standard_False;
00139   //
00140   // 1 Try to find an edge from theFace in theMEF
00141   aExp.Init(theFace, TopAbs_EDGE);
00142   for(; aExp.More(); aExp.Next()) {
00143     const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
00144     if (!theMEF.Contains(aE)) {
00145       continue;
00146     }
00147     //
00148     const TopTools_ListOfShape& aLF=theMEF.FindFromKey(aE);
00149     aNbF=aLF.Extent();
00150     if (!aNbF) {
00151       return bRet; // it can not be so
00152     }
00153     else if (aNbF==1) {
00154       // aE is internal edge on aLF.First()
00155       const TopoDS_Face& aF1=TopoDS::Face(aLF.First());
00156       bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF1, theContext);
00157       return bRet;
00158     }
00159     else if (aNbF==2) {
00160       const TopoDS_Face& aF1=TopoDS::Face(aLF.First());
00161       const TopoDS_Face& aF2=TopoDS::Face(aLF.Last());
00162       //
00163       if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
00164         // treat as it was for 1 face
00165         bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF2, theContext);
00166         return bRet;
00167       }
00168     }
00169     if (aNbF%2) {
00170       return bRet; // it can not be so
00171     }
00172     else { // aNbF=2,4,6,8,...
00173       bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aLF, theContext);
00174       return bRet;
00175     }
00176   }//for(; aExp.More(); aExp.Next()) {
00177   //
00178   //========================================
00179   // 2. Classify face using classifier
00180   //
00181   TopAbs_State aState;
00182   TopTools_IndexedMapOfShape aBounds;
00183   //
00184   aState=GEOMAlgo_Tools3D::ComputeState(theFace, theSolid, theTol, aBounds, theContext);
00185   bRet=(aState==TopAbs_IN);
00186   //
00187   return bRet;
00188 }
00189 //=======================================================================
00190 //function : IsInternalFace
00191 //purpose  :
00192 //=======================================================================
00193   Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
00194                                                     const TopoDS_Edge& theEdge,
00195                                                     const TopTools_ListOfShape& theLF,
00196                                                     const Handle(IntTools_Context)& theContext)
00197 {
00198   Standard_Boolean bRet;
00199   Standard_Boolean aNbF;
00200   //
00201   bRet=Standard_False;
00202   //
00203   aNbF=theLF.Extent();
00204   if (aNbF==2) {
00205     const TopoDS_Face& aF1=TopoDS::Face(theLF.First());
00206     const TopoDS_Face& aF2=TopoDS::Face(theLF.Last());
00207     bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
00208     return bRet;
00209   }
00210   //
00211   else {
00212     NMTTools_ListOfCoupleOfShape aLCFF;
00213     NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
00214     //
00215     FindFacePairs(theEdge, theLF, aLCFF);
00216     //
00217     aIt.Initialize(aLCFF);
00218     for (; aIt.More(); aIt.Next()) {
00219       const NMTTools_CoupleOfShape& aCSFF=aIt.Value();
00220       //
00221       const TopoDS_Face& aF1=TopoDS::Face(aCSFF.Shape1());
00222       const TopoDS_Face& aF2=TopoDS::Face(aCSFF.Shape2());
00223       bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
00224       if (bRet) {
00225         return bRet;
00226       }
00227     }
00228   }
00229   return bRet;
00230 }
00231 //=======================================================================
00232 //function : IsInternalFace
00233 //purpose  :
00234 //=======================================================================
00235   Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
00236                                                     const TopoDS_Edge& theEdge,
00237                                                     const TopoDS_Face& theFace1,
00238                                                     const TopoDS_Face& theFace2,
00239                                                     const Handle(IntTools_Context)& theContext)
00240 {
00241   Standard_Boolean bRet;
00242   Standard_Real aT1, aT2, aT, aDt2D, aDt2Dx;
00243   Standard_Real aA12, aA1x, aTwoPI;
00244   gp_Pnt aPx, aPF, aPF1, aPF2;
00245   gp_Pnt2d aP2D, aPF2D;
00246   gp_Dir aDNF1, aDNF2;
00247   TopoDS_Edge aE1, aE2;
00248   Handle(Geom_Curve)aC3D;
00249   //
00250   aC3D =BRep_Tool::Curve(theEdge, aT1, aT2);
00251   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
00252   aC3D->D0(aT, aPx);
00253   //
00254   // 1. PF
00255   aDt2D=BOPTools_Tools3D::MinStepIn2d();
00256   aDt2Dx=10.*aDt2D;
00257   BOPTools_Tools3D::PointNearEdge (theEdge, theFace, aT, aDt2Dx, aPF2D, aPF);
00258   //
00259   // 2. E1, E2
00260   GEOMAlgo_Tools3D::GetEdgeOnFace(theEdge, theFace1, aE1);
00261   if (aE1.Orientation()==TopAbs_INTERNAL) {
00262     aE2=aE1;
00263     aE1.Orientation(TopAbs_FORWARD);
00264     aE2.Orientation(TopAbs_REVERSED);
00265   }
00266   else if (theFace1==theFace2) {
00267     aE2=aE1;
00268     aE1.Orientation(TopAbs_FORWARD);
00269     aE2.Orientation(TopAbs_REVERSED);
00270   }
00271   else {
00272     GEOMAlgo_Tools3D::GetEdgeOnFace(theEdge, theFace2, aE2);
00273   }
00274   //
00275   // 3
00276   bRet=Standard_False;
00277   //
00278   GetApproxNormalToFaceOnEdge (aE1, theFace1, aT, aPF1, aDNF1, theContext);
00279   GetApproxNormalToFaceOnEdge (aE2, theFace2, aT, aPF2, aDNF2, theContext);
00280   //
00281   aTwoPI = 2.*M_PI;
00282   gp_Vec aVBF (aPx, aPF );
00283   gp_Vec aVBF1(aPx, aPF1);
00284   gp_Vec aVBF2(aPx, aPF2);
00285   //
00286   gp_Dir aDTF1;
00287   gp_Dir aDBF (aVBF);
00288   gp_Dir aDBF1(aVBF1);
00289   gp_Dir aDBF2(aVBF2);
00290   //
00291   aDTF1=aDNF1^aDBF1;
00292   aA12=AngleWithRef(aDBF1, aDBF2, aDTF1);
00293   if (aA12<0.) {
00294     aA12=aA12+aTwoPI;
00295   }
00296 
00297   aA1x=AngleWithRef(aDBF1, aDBF , aDTF1);
00298   if (aA1x<0.) {
00299     aA1x=aA1x+aTwoPI;
00300   }
00301   //
00302   if (aA1x<aA12) {
00303     bRet=!bRet; //TopAbs_IN;
00304   }
00305   //
00306   return bRet;
00307 }
00308 //=======================================================================
00309 //function : GetFaceOff
00310 //purpose  :
00311 //=======================================================================
00312   void GEOMAlgo_Tools3D::GetFaceOff(const TopoDS_Edge& theE1,
00313                                    const TopoDS_Face& theF1,
00314                                    const NMTTools_ListOfCoupleOfShape& theLCSOff,
00315                                    TopoDS_Face& theFOff)
00316 {
00317   Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
00318   gp_Pnt aPn1, aPn2;
00319   gp_Vec aVTgt;
00320   gp_Dir aDN1, aDN2;
00321   NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
00322   //
00323   aAngleMin=100.;
00324   aTwoPI = M_PI+M_PI;
00325   BRep_Tool::Range(theE1, aT1, aT2);
00326   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
00327   // Ref
00328   BOPTools_Tools2D::EdgeTangent(theE1, aT, aVTgt);
00329   gp_Dir aDTtgt(aVTgt);
00330   aDTtgt.Reverse();
00331   // N1
00332   BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(theE1, theF1, aT, aPn1, aDN1);
00333   //
00334   aIt.Initialize(theLCSOff);
00335   for (; aIt.More(); aIt.Next()) {
00336     const NMTTools_CoupleOfShape& aCS=aIt.Value();
00337     const TopoDS_Edge& aE2=TopoDS::Edge(aCS.Shape1());
00338     const TopoDS_Face& aF2=TopoDS::Face(aCS.Shape2());
00339     //
00340     if (aF2==theF1) {
00341       aAngle=M_PI;
00342     }
00343     else if (aF2.IsSame(theF1)) {
00344       aAngle=aTwoPI;
00345     }
00346     else {
00347       BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aE2, aF2, aT, aPn2, aDN2);
00348       aDN2.Reverse();
00349       // Angle
00350       aAngle=AngleWithRef(aDN1, aDN2, aDTtgt);
00351       if(aAngle<0.) {
00352         aAngle=aTwoPI+aAngle;
00353       }
00354     }
00355     //
00356     if (aAngle<aAngleMin){
00357       aAngleMin=aAngle;
00358       theFOff=aF2;
00359     }
00360   }
00361 }
00362 //=======================================================================
00363 //function : GetEdgeOnFace
00364 //purpose  :
00365 //=======================================================================
00366   Standard_Boolean GEOMAlgo_Tools3D::GetEdgeOnFace(const TopoDS_Edge& theE1,
00367                                                   const TopoDS_Face& theF2,
00368                                                   TopoDS_Edge& theE2)
00369 {
00370   Standard_Boolean bFound;
00371   TopoDS_Iterator aItF, aItW;
00372   //
00373   bFound=Standard_False;
00374   //
00375   aItF.Initialize(theF2);
00376   for (; aItF.More(); aItF.Next()) {
00377     const TopoDS_Shape& aW=aItF.Value();
00378     aItW.Initialize(aW);
00379     for (; aItW.More(); aItW.Next()) {
00380       const TopoDS_Shape& aE=aItW.Value();
00381       if (aE.IsSame(theE1)) {
00382         theE2=TopoDS::Edge(aE);
00383         bFound=!bFound;
00384         return bFound;
00385       }
00386     }
00387   }
00388   return bFound;
00389 }
00390 //=======================================================================
00391 //function : GetEdgeOff
00392 //purpose  :
00393 //=======================================================================
00394 Standard_Boolean GEOMAlgo_Tools3D::GetEdgeOff (const TopoDS_Edge& theE1,
00395                                                const TopoDS_Face& theF2,
00396                                                TopoDS_Edge& theE2)
00397 
00398 {
00399   Standard_Boolean bFound;
00400   TopAbs_Orientation aOr1, aOr1C, aOr2;
00401   TopExp_Explorer anExp;
00402   //
00403   bFound=Standard_False;
00404   aOr1=theE1.Orientation();
00405   aOr1C=TopAbs::Reverse(aOr1);
00406   //
00407   anExp.Init(theF2, TopAbs_EDGE);
00408   for (; anExp.More(); anExp.Next()) {
00409     const TopoDS_Edge& aEF2=TopoDS::Edge(anExp.Current());
00410     if (aEF2.IsSame(theE1)) {
00411       aOr2=aEF2.Orientation();
00412       if (aOr2==aOr1C) {
00413         theE2=aEF2;
00414         bFound=!bFound;
00415         return bFound;
00416       }
00417     }
00418   }
00419   return bFound;
00420 }
00421 //=======================================================================
00422 // function:  ComputeState
00423 // purpose:
00424 //=======================================================================
00425   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Face& theF,
00426                                              const TopoDS_Solid& theRef,
00427                                              const Standard_Real theTol,
00428                                              const TopTools_IndexedMapOfShape& theBounds,
00429                                              const Handle(IntTools_Context)& theCtx)
00430 {
00431   TopAbs_State aState;
00432   TopExp_Explorer aExp;
00433   TopoDS_Edge aE1;
00434   gp_Pnt2d aP2D;
00435   gp_Pnt aP3D;
00436   //
00437   aState=TopAbs_UNKNOWN;
00438   //
00439   aExp.Init(theF, TopAbs_EDGE);
00440   for (; aExp.More(); aExp.Next()) {
00441     const TopoDS_Edge& aSE=TopoDS::Edge(aExp.Current());
00442     if (BRep_Tool::Degenerated(aSE)) {
00443       continue;
00444     }
00445     //
00446     if (!theBounds.Contains(aSE)) {
00447       const TopoDS_Edge& aE=TopoDS::Edge(aSE);
00448       aState= GEOMAlgo_Tools3D::ComputeState(aE, theRef, theTol, theCtx);
00449       return aState;
00450     }
00451     if (aE1.IsNull()) {
00452       aE1=TopoDS::Edge(aSE);
00453     }
00454   }
00455   // !!<- process edges that are all on theRef
00456   if (!aE1.IsNull()) {
00457     BOPTools_Tools3D::PointNearEdge(aE1, theF, aP2D, aP3D);
00458     aState=GEOMAlgo_Tools3D::ComputeState(aP3D, theRef, theTol, theCtx);
00459   }
00460   //
00461   return aState;
00462 }
00463 //=======================================================================
00464 // function:  ComputeStateByOnePoint
00465 // purpose:
00466 //=======================================================================
00467   TopAbs_State GEOMAlgo_Tools3D::ComputeStateByOnePoint(const TopoDS_Shape& theS,
00468                                                        const TopoDS_Solid& theRef,
00469                                                        const Standard_Real theTol,
00470                                                        const Handle(IntTools_Context)& theCtx)
00471 {
00472   TopAbs_State aState;
00473   TopAbs_ShapeEnum aType;
00474   //
00475   aState=TopAbs_UNKNOWN;
00476   aType=theS.ShapeType();
00477   if (aType==TopAbs_VERTEX) {
00478     const TopoDS_Vertex& aV=TopoDS::Vertex(theS);
00479     aState=GEOMAlgo_Tools3D::ComputeState(aV, theRef, theTol, theCtx);
00480   }
00481   else if (aType==TopAbs_EDGE) {
00482     const TopoDS_Edge& aE=TopoDS::Edge(theS);
00483     aState=GEOMAlgo_Tools3D::ComputeState(aE, theRef, theTol, theCtx);
00484   }
00485   return aState;
00486 }
00487 //=======================================================================
00488 // function:  ComputeState
00489 // purpose:
00490 //=======================================================================
00491   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Vertex& theV,
00492                                              const TopoDS_Solid& theRef,
00493                                              const Standard_Real theTol,
00494                                              const Handle(IntTools_Context)& theCtx)
00495 {
00496   TopAbs_State aState;
00497   gp_Pnt aP3D;
00498   //
00499   aP3D=BRep_Tool::Pnt(theV);
00500   aState=GEOMAlgo_Tools3D::ComputeState(aP3D, theRef, theTol, theCtx);
00501   return aState;
00502 }
00503 //=======================================================================
00504 // function:  ComputeState
00505 // purpose:
00506 //=======================================================================
00507   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Edge& theE,
00508                                              const TopoDS_Solid& theRef,
00509                                              const Standard_Real theTol,
00510                                              const Handle(IntTools_Context)& theCtx)
00511 {
00512   Standard_Real aT1, aT2, aT = 0.;
00513   TopAbs_State aState;
00514   Handle(Geom_Curve) aC3D;
00515   gp_Pnt aP3D;
00516   //
00517   aC3D = BRep_Tool::Curve(theE, aT1, aT2);
00518   //
00519   if(aC3D.IsNull()) {
00520     //it means that we are in degenerated edge
00521     const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
00522     if(aV.IsNull()){
00523       return TopAbs_UNKNOWN;
00524     }
00525     aP3D=BRep_Tool::Pnt(aV);
00526   }
00527   else {//usual case
00528     Standard_Boolean bF2Inf, bL2Inf;
00529     Standard_Real dT=10.;
00530     //
00531     bF2Inf = Precision::IsNegativeInfinite(aT1);
00532     bL2Inf = Precision::IsPositiveInfinite(aT2);
00533     //
00534     if (bF2Inf && !bL2Inf) {
00535       aT=aT2-dT;
00536     }
00537     else if (!bF2Inf && bL2Inf) {
00538       aT=aT1+dT;
00539     }
00540     else if (bF2Inf && bL2Inf) {
00541       aT=0.;
00542     }
00543     else {
00544       aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
00545     }
00546     aC3D->D0(aT, aP3D);
00547   }
00548   //
00549   aState=GEOMAlgo_Tools3D::ComputeState(aP3D, theRef, theTol, theCtx);
00550   //
00551   return aState;
00552 }
00553 //=======================================================================
00554 // function:  ComputeState
00555 // purpose:
00556 //=======================================================================
00557   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const gp_Pnt& theP,
00558                                              const TopoDS_Solid& theRef,
00559                                              const Standard_Real theTol,
00560                                              const Handle(IntTools_Context)& theCtx)
00561 {
00562   TopAbs_State aState;
00563   //
00564   BRepClass3d_SolidClassifier& aSC=theCtx->SolidClassifier(theRef);
00565   aSC.Perform(theP, theTol);
00566   //
00567   aState=aSC.State();
00568   //
00569   return aState;
00570 }
00571 //=======================================================================
00572 // function: IsSplitToReverse
00573 // purpose:
00574 //=======================================================================
00575   Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Shape& theSp,
00576                                                      const TopoDS_Shape& theSr,
00577                                                      const Handle(IntTools_Context)& theCtx)
00578 {
00579   Standard_Boolean bRet;
00580   TopAbs_ShapeEnum aType;
00581   //
00582   bRet=Standard_False;
00583   //
00584   aType=theSp.ShapeType();
00585   switch (aType) {
00586     case TopAbs_EDGE: {
00587       const TopoDS_Edge& aESp=TopoDS::Edge(theSp);
00588       const TopoDS_Edge& aESr=TopoDS::Edge(theSr);
00589       bRet=GEOMAlgo_Tools3D::IsSplitToReverse(aESp, aESr, theCtx);
00590     }
00591       break;
00592       //
00593     case TopAbs_FACE: {
00594       const TopoDS_Face& aFSp=TopoDS::Face(theSp);
00595       const TopoDS_Face& aFSr=TopoDS::Face(theSr);
00596       bRet=GEOMAlgo_Tools3D::IsSplitToReverse(aFSp, aFSr, theCtx);
00597     }
00598       break;
00599       //
00600     default:
00601       break;
00602   }
00603   return bRet;
00604 }
00605 //=======================================================================
00606 //function :IsSplitToReverse
00607 //purpose  :
00608 //=======================================================================
00609   Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Face& theFSp,
00610                                                      const TopoDS_Face& theFSr,
00611                                                      const Handle(IntTools_Context)& theContext)
00612 {
00613   Standard_Boolean bRet, bFound, bInFace;
00614   Standard_Real aT1, aT2, aT, aU, aV, aScPr;
00615   gp_Pnt aPFSp, aPFSr;
00616   gp_Dir aDNFSp;
00617   gp_Vec aD1U, aD1V;
00618   Handle(Geom_Surface) aSr, aSp;
00619   TopAbs_Orientation aOrSr, aOrSp;
00620   TopExp_Explorer anExp;
00621   TopoDS_Edge aESp;
00622   //
00623   bRet=Standard_False;
00624   //
00625   aSr=BRep_Tool::Surface(theFSr);
00626   aSp=BRep_Tool::Surface(theFSp);
00627   if (aSr==aSp) {
00628     aOrSr=theFSr.Orientation();
00629     aOrSp=theFSp.Orientation();
00630     bRet=(aOrSr!=aOrSp);
00631     return bRet;
00632   }
00633   //
00634   bFound=Standard_False;
00635   anExp.Init(theFSp, TopAbs_EDGE);
00636   for (; anExp.More(); anExp.Next()) {
00637     aESp=TopoDS::Edge(anExp.Current());
00638     if (!BRep_Tool::Degenerated(aESp)) {
00639       if (!BRep_Tool::IsClosed(aESp, theFSp)) {
00640         bFound=!bFound;
00641         break;
00642       }
00643     }
00644   }
00645   //
00646   //modified by NIZNHY-PKV Tue Nov 22 10:50:30 2011f
00647   if (!bFound) {
00648     Standard_Boolean bFlag;
00649     Standard_Integer iErr;
00650     gp_Pnt2d aP2DFSp;
00651     //
00652     iErr=GEOMAlgo_Tools3D::PntInFace(theFSp, aPFSp, aP2DFSp);
00653     if (iErr) {
00654       return bRet;
00655     }
00656     //
00657     aP2DFSp.Coord(aU, aV);
00658     bFlag=BOPTools_Tools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
00659     if (!bFlag) {
00660       return bRet;
00661     }
00662   }
00663   else {
00664     BRep_Tool::Range(aESp, aT1, aT2);
00665     aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
00666     BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp);
00667   }
00668   //
00669   /*
00670   if (!bFound) {
00671     return bRet;
00672   }
00673   BRep_Tool::Range(aESp, aT1, aT2);
00674   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
00675   BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp);
00676   */
00677   //modified by NIZNHY-PKV Tue Nov 22 10:50:37 2011t
00678   //
00679   // Parts of theContext.ComputeVS(..)
00680   GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
00681   aProjector.Perform(aPFSp);
00682   if (!aProjector.IsDone()) {
00683     return bRet;
00684   }
00685   //
00686   aProjector.LowerDistanceParameters(aU, aV);
00687   gp_Pnt2d aP2D(aU, aV);
00688   bInFace=theContext->IsPointInFace (theFSr, aP2D);
00689   if (!bInFace) {
00690     return bRet;
00691   }
00692   //
00693   aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
00694   gp_Dir aDD1U(aD1U);
00695   gp_Dir aDD1V(aD1V);
00696   gp_Dir aDNFSr=aDD1U^aDD1V;
00697   if (theFSr.Orientation()==TopAbs_REVERSED){
00698     aDNFSr.Reverse();
00699   }
00700   //
00701   aScPr=aDNFSp*aDNFSr;
00702   bRet=(aScPr<0.);
00703   //
00704   return bRet;
00705 }
00706 //=======================================================================
00707 //function :IsSplitToReverse
00708 //purpose  :
00709 //=======================================================================
00710   Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Edge& theSplit,
00711                                                      const TopoDS_Edge& theEdge,
00712                                                      const Handle(IntTools_Context)& theContext)
00713 {
00714   Standard_Boolean bRet, aFlag, bIsDegenerated;
00715   Standard_Real aTE, aTS, aScPr, aTa, aTb, aT1, aT2;
00716   TopAbs_Orientation aOrSr, aOrSp;
00717   Handle(Geom_Curve) aCEdge, aCSplit;
00718   gp_Vec aVE, aVS;
00719   gp_Pnt aP;
00720   //
00721   bRet=Standard_False;
00722   //
00723   bIsDegenerated=(BRep_Tool::Degenerated(theSplit) ||
00724                   BRep_Tool::Degenerated(theEdge));
00725   if (bIsDegenerated) {
00726     return bRet;
00727   }
00728   //
00729   aCEdge =BRep_Tool::Curve(theEdge , aT1, aT2);
00730   aCSplit=BRep_Tool::Curve(theSplit, aTa, aTb);
00731   //
00732   if (aCEdge==aCSplit) {
00733     aOrSr=theEdge.Orientation();
00734     aOrSp=theSplit.Orientation();
00735     bRet=(aOrSr!=aOrSp);
00736     return bRet;
00737   }
00738   //
00739   aTS=BOPTools_Tools2D::IntermediatePoint(aTa, aTb);
00740   aCSplit->D0(aTS, aP);
00741   aFlag=BOPTools_Tools2D::EdgeTangent(theSplit, aTS, aVS);
00742   gp_Dir aDTS(aVS);
00743   //
00744   aFlag=theContext->ProjectPointOnEdge(aP, theEdge, aTE);
00745   aFlag=BOPTools_Tools2D::EdgeTangent(theEdge, aTE, aVE);
00746   gp_Dir aDTE(aVE);
00747   //
00748   aScPr=aDTS*aDTE;
00749   bRet=(aScPr<0.);
00750   //
00751   return bRet;
00752 }
00753 
00754 //=======================================================================
00755 // function: Sense
00756 // purpose:
00757 //=======================================================================
00758   Standard_Integer GEOMAlgo_Tools3D::Sense (const TopoDS_Face& theF1,
00759                                            const TopoDS_Face& theF2)
00760 {
00761   Standard_Integer iSense=0;
00762   gp_Dir aDNF1, aDNF2;
00763   TopoDS_Edge aE1, aE2;
00764   TopExp_Explorer anExp;
00765   //
00766   anExp.Init(theF1, TopAbs_EDGE);
00767   for (; anExp.More(); anExp.Next()) {
00768     aE1=TopoDS::Edge(anExp.Current());
00769     if (!BRep_Tool::Degenerated(aE1)) {
00770       if (!BRep_Tool::IsClosed(aE1, theF1)) {
00771         break;
00772       }
00773     }
00774   }
00775   //
00776   anExp.Init(theF2, TopAbs_EDGE);
00777   for (; anExp.More(); anExp.Next()) {
00778     aE2=TopoDS::Edge(anExp.Current());
00779     if (!BRep_Tool::Degenerated(aE2)) {
00780       if (!BRep_Tool::IsClosed(aE2, theF2)) {
00781         if (aE2.IsSame(aE1)) {
00782           iSense=1;
00783           break;
00784         }
00785       }
00786     }
00787   }
00788   //
00789   if (!iSense) {
00790     return iSense;
00791   }
00792   //
00793   BOPTools_Tools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
00794   BOPTools_Tools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
00795   //
00796   iSense=BOPTools_Tools3D::SenseFlag(aDNF1, aDNF2);
00797   //
00798   return iSense;
00799 }
00800 //=======================================================================
00801 // function: CopyFace
00802 // purpose:
00803 //=======================================================================
00804   void GEOMAlgo_Tools3D::CopyFace (const TopoDS_Face& theF1,
00805                                   TopoDS_Face& theF2)
00806 {
00807   Standard_Real aTol;
00808   TopLoc_Location aLoc;
00809   TopAbs_Orientation aOr;
00810   TopoDS_Iterator aIt;
00811   BRep_Builder aBB;
00812   //
00813   Handle(Geom_Surface) aSurface=BRep_Tool::Surface(theF1, aLoc);
00814   aTol=BRep_Tool::Tolerance(theF1);
00815   aOr=theF1.Orientation();
00816   //
00817   aBB.MakeFace (theF2, aSurface, aLoc, aTol);
00818   theF2.Orientation(aOr);
00819   //
00820   aIt.Initialize(theF1);
00821   for (; aIt.More(); aIt.Next()) {
00822     const TopoDS_Shape& aW=aIt.Value();
00823     aBB.Add(theF2, aW);
00824   }
00825 }
00826 //=======================================================================
00827 // function: MakeContainer
00828 // purpose:
00829 //=======================================================================
00830   void GEOMAlgo_Tools3D::MakeContainer(const TopAbs_ShapeEnum theType,
00831                                       TopoDS_Shape& theC)
00832 {
00833   BRep_Builder aBB;
00834   //
00835   switch(theType) {
00836     case TopAbs_COMPOUND:{
00837       TopoDS_Compound aC;
00838       aBB.MakeCompound(aC);
00839       theC=aC;
00840     }
00841       break;
00842       //
00843     case TopAbs_COMPSOLID:{
00844       TopoDS_CompSolid aCS;
00845       aBB.MakeCompSolid(aCS);
00846       theC=aCS;
00847     }
00848       break;
00849       //
00850     case TopAbs_SOLID:{
00851       TopoDS_Solid aSolid;
00852       aBB.MakeSolid(aSolid);
00853       theC=aSolid;
00854     }
00855       break;
00856       //
00857       //
00858     case TopAbs_SHELL:{
00859       TopoDS_Shell aShell;
00860       aBB.MakeShell(aShell);
00861       theC=aShell;
00862     }
00863       break;
00864       //
00865     case TopAbs_WIRE: {
00866       TopoDS_Wire aWire;
00867       aBB.MakeWire(aWire);
00868       theC=aWire;
00869     }
00870       break;
00871       //
00872     default:
00873       break;
00874   }
00875 }
00876 //=======================================================================
00877 // function: MakeConnexityBlock.
00878 // purpose:
00879 //=======================================================================
00880   void GEOMAlgo_Tools3D::MakeConnexityBlock (const TopTools_ListOfShape& theLFIn,
00881                                              const TopTools_IndexedMapOfShape& theMEAvoid,
00882                                              TopTools_ListOfShape& theLCB)
00883 {
00884   Standard_Integer  aNbF, aNbAdd1;
00885   TopExp_Explorer aExp;
00886   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
00887   TopTools_MapIteratorOfMapOfShape aItM, aItM1;
00888   TopTools_MapOfShape aMCB, aMAdd, aMAdd1;
00889   TopTools_ListIteratorOfListOfShape aIt;
00890   //
00891   // 1. aMEF
00892   aNbF=theLFIn.Extent();
00893   aIt.Initialize(theLFIn);
00894   for (; aIt.More(); aIt.Next()) {
00895     const TopoDS_Shape& aF=aIt.Value();
00896     TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
00897   }
00898   //
00899   // 2. aMCB
00900   const TopoDS_Shape& aF1=theLFIn.First();
00901   aMAdd.Add(aF1);
00902   //
00903   while(1) {
00904     aMAdd1.Clear();
00905     aItM.Initialize(aMAdd);
00906     for (; aItM.More(); aItM.Next()) {
00907       const TopoDS_Shape& aF=aItM.Key();
00908       //
00909       //aMAdd1.Clear();
00910       aExp.Init(aF, TopAbs_EDGE);
00911       for (; aExp.More(); aExp.Next()) {
00912         const TopoDS_Shape& aE=aExp.Current();
00913         if (theMEAvoid.Contains(aE)){
00914           continue;
00915         }
00916         //
00917         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
00918         aIt.Initialize(aLF);
00919         for (; aIt.More(); aIt.Next()) {
00920           const TopoDS_Shape& aFx=aIt.Value();
00921           if (aFx.IsSame(aF)) {
00922             continue;
00923           }
00924           if (aMCB.Contains(aFx)) {
00925             continue;
00926           }
00927           aMAdd1.Add(aFx);
00928         }
00929       }//for (; aExp.More(); aExp.Next()){
00930       aMCB.Add(aF);
00931     }// for (; aItM.More(); aItM.Next()) {
00932     //
00933     aNbAdd1=aMAdd1.Extent();
00934     if (!aNbAdd1) {
00935       break;
00936     }
00937     //
00938     aMAdd.Clear();
00939     aItM1.Initialize(aMAdd1);
00940     for (; aItM1.More(); aItM1.Next()) {
00941       const TopoDS_Shape& aFAdd=aItM1.Key();
00942       aMAdd.Add(aFAdd);
00943     }
00944     //
00945   }//while(1) {
00946 
00947   //
00948   aNbF=aMCB.Extent();
00949   aItM.Initialize(aMCB);
00950   for (; aItM.More(); aItM.Next()) {
00951     const TopoDS_Shape& aF=aItM.Key();
00952     theLCB.Append(aF);
00953   }
00954 }
00955 //=======================================================================
00956 //function : FindFacePairs
00957 //purpose  :
00958 //=======================================================================
00959 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
00960                                 const TopTools_ListOfShape& thLF,
00961                                 NMTTools_ListOfCoupleOfShape& theLCFF)
00962 {
00963   Standard_Boolean bFound;
00964   Standard_Integer i, aNbCEF;
00965   TopAbs_Orientation aOr, aOrC;
00966   TopTools_MapOfShape aMFP;
00967   TopoDS_Face aF1, aF2;
00968   TopoDS_Edge aEL, aE1;
00969   TopTools_ListIteratorOfListOfShape aItLF;
00970   NMTTools_CoupleOfShape aCEF, aCFF;
00971   NMTTools_ListOfCoupleOfShape aLCEF, aLCEFx;
00972   NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
00973   //
00974   bFound=Standard_True;
00975   //
00976   // Preface aLCEF
00977   aItLF.Initialize(thLF);
00978   for (; aItLF.More(); aItLF.Next()) {
00979     const TopoDS_Face& aFL=TopoDS::Face(aItLF.Value());
00980     //
00981     bFound=GEOMAlgo_Tools3D::GetEdgeOnFace(theE, aFL, aEL);
00982     if (!bFound) {
00983       return bFound; // it can not be so
00984     }
00985     //
00986     aCEF.SetShape1(aEL);
00987     aCEF.SetShape2(aFL);
00988     aLCEF.Append(aCEF);
00989   }
00990   //
00991   aNbCEF=aLCEF.Extent();
00992   while(aNbCEF) {
00993     //
00994     // aLCEFx
00995     aLCEFx.Clear();
00996     aIt.Initialize(aLCEF);
00997     for (i=0; aIt.More(); aIt.Next(), ++i) {
00998       const NMTTools_CoupleOfShape& aCSx=aIt.Value();
00999       const TopoDS_Shape& aEx=aCSx.Shape1();
01000       const TopoDS_Shape& aFx=aCSx.Shape2();
01001       //
01002       aOr=aEx.Orientation();
01003       //
01004       if (!i) {
01005         aOrC=TopAbs::Reverse(aOr);
01006         aE1=TopoDS::Edge(aEx);
01007         aF1=TopoDS::Face(aFx);
01008         aMFP.Add(aFx);
01009         continue;
01010       }
01011       //
01012       if (aOr==aOrC) {
01013         aLCEFx.Append(aCSx);
01014         aMFP.Add(aFx);
01015       }
01016     }
01017     //
01018     // F2
01019     GEOMAlgo_Tools3D::GetFaceOff(aE1, aF1, aLCEFx, aF2);
01020     //
01021     aCFF.SetShape1(aF1);
01022     aCFF.SetShape2(aF2);
01023     theLCFF.Append(aCFF);
01024     //
01025     aMFP.Add(aF1);
01026     aMFP.Add(aF2);
01027     //
01028     // refine aLCEF
01029     aLCEFx.Clear();
01030     aLCEFx=aLCEF;
01031     aLCEF.Clear();
01032     aIt.Initialize(aLCEFx);
01033     for (; aIt.More(); aIt.Next()) {
01034       const NMTTools_CoupleOfShape& aCSx=aIt.Value();
01035       const TopoDS_Shape& aFx=aCSx.Shape2();
01036       if (!aMFP.Contains(aFx)) {
01037         aLCEF.Append(aCSx);
01038       }
01039     }
01040     //
01041     aNbCEF=aLCEF.Extent();
01042   }//while(aNbCEF) {
01043   //
01044   return bFound;
01045 }
01046 //
01047 //=======================================================================
01048 //function : AngleWithRef
01049 //purpose  :
01050 //=======================================================================
01051 Standard_Real AngleWithRef(const gp_Dir& theD1,
01052                            const gp_Dir& theD2,
01053                            const gp_Dir& theDRef)
01054 {
01055   Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
01056   gp_XYZ aXYZ;
01057   //
01058   aHalfPI=0.5*M_PI;
01059   //
01060   const gp_XYZ& aXYZ1=theD1.XYZ();
01061   const gp_XYZ& aXYZ2=theD2.XYZ();
01062   aXYZ=aXYZ1.Crossed(aXYZ2);
01063   aSinus=aXYZ.Modulus();
01064   aCosinus=theD1*theD2;
01065   //
01066   aBeta=0.;
01067   if (aSinus>=0.) {
01068     aBeta=aHalfPI*(1.-aCosinus);
01069   }
01070   else {
01071     aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
01072   }
01073   //
01074   aScPr=aXYZ.Dot(theDRef.XYZ());
01075   if (aScPr<0.) {
01076     aBeta=-aBeta;
01077   }
01078   return aBeta;
01079 }
01080 //=======================================================================
01081 //function : GetApproxNormalToFaceOnEdge
01082 //purpose  :
01083 //=======================================================================
01084 void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aEx,
01085                                   const TopoDS_Face& aFx,
01086                                   Standard_Real aT,
01087                                   gp_Pnt& aPF,
01088                                   gp_Dir& aDNF,
01089                                   const Handle(IntTools_Context)& aCtx)
01090 {
01091   Standard_Boolean bReverse;
01092   Standard_Real aT1, aT2, dT, aU, aV;
01093   gp_Dir aDTT, aDNFT, aDBT;
01094   gp_Pnt aPFT, aPFx;
01095   Handle(Geom_Curve) aC3D;
01096   Handle(Geom_Surface) aS;
01097   GeomAdaptor_Surface aGAS;
01098   GeomAbs_SurfaceType aTS;
01099   TopoDS_Face aF;
01100   TopoDS_Edge aE;
01101   //
01102   bReverse=Standard_False;
01103   aF=aFx;
01104   aE=aEx;
01105   if (aF.Orientation()==TopAbs_REVERSED){
01106     bReverse=!bReverse;
01107     aE.Reverse();
01108     //
01109     aF.Orientation(TopAbs_FORWARD);
01110   }
01111   //
01112   // Point at aT
01113   aC3D =BRep_Tool::Curve(aE, aT1, aT2);
01114   aC3D->D0(aT, aPFT);
01115   //
01116   // Normal at aT
01117   BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNFT);
01118 
01119   // Tangent at aT
01120   BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDTT);
01121   //
01122   // Binormal at aT
01123   aDBT=aDNFT^aDTT;
01124   //
01125   dT=BOPTools_Tools3D::MinStepIn2d();//~1.e-5;
01126   dT=10.*dT;
01127   //----------------------------------------------
01128   {
01129     aS=BRep_Tool::Surface(aF);
01130     aGAS.Load(aS);
01131     aTS=aGAS.GetType();
01132     if (aTS==GeomAbs_BSplineSurface ||
01133         aTS==GeomAbs_BezierSurface ||
01134         aTS==GeomAbs_Plane){
01135       Standard_Real aTolEx, aTolFx, aTol, dUR, dVR, dR;
01136       //
01137       aTolEx=BRep_Tool::Tolerance(aEx);
01138       aTolFx=BRep_Tool::Tolerance(aFx);
01139       aTol=2.*aTolEx+aTolFx;
01140       dUR=aGAS.UResolution(aTol);
01141       dVR=aGAS.VResolution(aTol);
01142       dR=(dUR>dVR)? dUR : dVR;
01143       if (dR>dT) {
01144         dT=dR;
01145       }
01146     }
01147     else if (GeomAbs_Torus ||
01148              aTS==GeomAbs_Cylinder){
01149       Standard_Real aTolEx, aTolFx, aTol;
01150       //
01151       aTolEx=BRep_Tool::Tolerance(aEx);
01152       aTolFx=BRep_Tool::Tolerance(aFx);
01153       aTol=2.*aTolEx+aTolFx;
01154       if (aTol>dT) {
01155         dT=aTol;
01156       }
01157     }
01158   }
01159   //----------------------------------------------
01160   //
01161   aPFx.SetXYZ(aPFT.XYZ()+dT*aDBT.XYZ());
01162   //
01163   aPF=aPFx;
01164   aDNF=aDNFT;
01165   if (bReverse) {
01166     aDNF.Reverse();
01167   }
01168   //
01169   GeomAPI_ProjectPointOnSurf& aProjector=aCtx->ProjPS(aF);
01170   //
01171   aProjector.Perform(aPFx);
01172   if(aProjector.IsDone()) {
01173     aProjector.LowerDistanceParameters (aU, aV);
01174     aS->D0(aU, aV, aPF);
01175     BOPTools_Tools3D::GetNormalToSurface (aS, aU, aV, aDNF);
01176     if (bReverse){
01177       aDNF.Reverse();
01178     }
01179   }
01180 }
01181 
01182 //modified by NIZNHY-PKV Tue Nov 22 10:36:59 2011f
01183 //=======================================================================
01184 //function : PntInFace
01185 //purpose  :
01186 //=======================================================================
01187 Standard_Integer GEOMAlgo_Tools3D::PntInFace(const TopoDS_Face& aF,
01188                                         gp_Pnt& theP,
01189                                         gp_Pnt2d& theP2D)
01190 {
01191   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
01192   Standard_Integer iErr, aIx, aNbDomains, i;
01193   Standard_Real aUMin, aUMax, aVMin, aVMax;
01194   Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
01195   Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
01196   gp_Dir2d aD2D (0., 1.);
01197   gp_Pnt2d aP2D;
01198   gp_Pnt aPx;
01199   Handle(Geom2d_Curve) aC2D;
01200   Handle(Geom2d_TrimmedCurve) aCT2D;
01201   Handle(Geom2d_Line) aL2D;
01202   Handle(Geom_Surface) aS;
01203   TopAbs_Orientation aOrE;
01204   TopoDS_Face aFF;
01205   TopExp_Explorer aExp;
01206   //
01207   aTolHatch2D=1.e-8;
01208   aTolHatch3D=1.e-8;
01209   aTotArcIntr=1.e-10;
01210   aTolTangfIntr=1.e-10;
01211   //
01212   Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr);
01213   Geom2dHatch_Hatcher aHatcher(aIntr,
01214                             aTolHatch2D, aTolHatch3D,
01215                             Standard_True, Standard_False);
01216   //
01217   iErr=0;
01218   aEpsT=1.e-12;
01219   //
01220   aFF=aF;
01221   aFF.Orientation (TopAbs_FORWARD);
01222   //
01223   aS=BRep_Tool::Surface(aFF);
01224   BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
01225   //
01226   // 1
01227   aExp.Init (aFF, TopAbs_EDGE);
01228   for (; aExp.More() ; aExp.Next()) {
01229     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
01230     aOrE=aE.Orientation();
01231     //
01232     aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
01233     if (aC2D.IsNull() ) {
01234       iErr=1;
01235       return iErr;
01236     }
01237     if (fabs(aU1-aU2) < aEpsT) {
01238       iErr=2;
01239       return iErr;
01240     }
01241     //
01242     aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
01243     aHatcher.AddElement(aCT2D, aOrE);
01244   }// for (; aExp.More() ; aExp.Next()) {
01245   //
01246   // 2
01247   aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
01248   aP2D.SetCoord(aUx, 0.);
01249   aL2D=new Geom2d_Line (aP2D, aD2D);
01250   Geom2dAdaptor_Curve aHCur(aL2D);
01251   //
01252   aIx=aHatcher.AddHatching(aHCur) ;
01253   //
01254   // 3.
01255   aHatcher.Trim();
01256   bIsDone=aHatcher.TrimDone(aIx);
01257   if (!bIsDone) {
01258     iErr=3;
01259     return iErr;
01260   }
01261   //
01262   aHatcher.ComputeDomains(aIx);
01263   bIsDone=aHatcher.IsDone(aIx);
01264   if (!bIsDone) {
01265     iErr=4;
01266     return iErr;
01267   }
01268   //
01269   // 4.
01270   aNbDomains=aHatcher.NbDomains(aIx);
01271   for (i=1; i<=aNbDomains; ++i) {
01272     const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
01273     bHasFirstPoint=aDomain.HasFirstPoint();
01274     if (!bHasFirstPoint) {
01275       iErr=5;
01276       return iErr;
01277     }
01278     //
01279     aV1=aDomain.FirstPoint().Parameter();
01280     //
01281     bHasSecondPoint=aDomain.HasSecondPoint();
01282     if (!bHasSecondPoint) {
01283       iErr=6;
01284       return iErr;
01285     }
01286     //
01287     aV2=aDomain.SecondPoint().Parameter();
01288     //
01289     aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
01290     //
01291     break;
01292   }
01293   //
01294   aS->D0(aUx, aVx, aPx);
01295   //
01296   theP2D.SetCoord(aUx, aVx);
01297   theP=aPx;
01298   //
01299   return iErr;
01300 }
01301 //modified by NIZNHY-PKV Tue Nov 22 10:37:01 2011t