Salome HOME
Porting to OCCT development version: Standard_PI -> M_PI
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Tools3D.cxx
index 6d97c6f61acd244594f2e7c536cbd26ae400e37c..f75e6df119bf2a1f14d8e09c91ded6108347018f 100755 (executable)
@@ -1,25 +1,27 @@
-// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// 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 
+// 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 
+//
+// 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 
+// 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
+//  File    : GEOMAlgo_Tools3D.cxx
+//  Created :
+//  Author  : Peter KURNEV
 
 #include <GEOMAlgo_Tools3D.ixx>
 
 #include <gp_Pnt2d.hxx>
 #include <gp_Pln.hxx>
 #include <gp_XYZ.hxx>
+#include <gp_Dir2d.hxx>
 
 #include <Geom_Curve.hxx>
 #include <Geom_Surface.hxx>
+
 #include <Geom2d_Curve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2d_Line.hxx>
+
+#include <Geom2dHatch_Intersector.hxx>
+#include <Geom2dHatch_Hatcher.hxx>
+#include <HatchGen_Domain.hxx>
+
 #include <GeomAPI_ProjectPointOnSurf.hxx>
 
 #include <TopAbs_ShapeEnum.hxx>
@@ -67,6 +78,7 @@
 #include <TopTools_MapOfShape.hxx>
 
 #include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepTools.hxx>
 
 #include <IntTools_Context.hxx>
 #include <IntTools_Tools.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 //
+#include <GeomAdaptor_Surface.hxx>
 
+
+//
 static
   Standard_Boolean FindFacePairs (const TopoDS_Edge& ,
-                                 const TopTools_ListOfShape& ,
-                                 NMTTools_ListOfCoupleOfShape& );
+                                  const TopTools_ListOfShape& ,
+                                  NMTTools_ListOfCoupleOfShape& );
 
 
 static
   Standard_Real AngleWithRef(const gp_Dir& ,
-                            const gp_Dir& ,
-                            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,
+                                    IntTools_Context& aCtx);
 
 //=======================================================================
 //function : IsInternalFace
-//purpose  : 
+//purpose  :
 //=======================================================================
-  Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
-                                                  const TopoDS_Solid& theSolid,
-                                                  const TopTools_IndexedDataMapOfShapeListOfShape& theMEF,
-                                                  const Standard_Real theTol,
-                                                  IntTools_Context& theContext)
+Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
+                                                  const TopoDS_Solid& theSolid,
+                                                  const TopTools_IndexedDataMapOfShapeListOfShape& theMEF,
+                                                  const Standard_Real theTol,
+                                                  IntTools_Context& theContext)
 {
   Standard_Boolean bRet;
   Standard_Integer aNbF;
@@ -121,7 +144,7 @@ static
     if (!theMEF.Contains(aE)) {
       continue;
     }
-    // 
+    //
     const TopTools_ListOfShape& aLF=theMEF.FindFromKey(aE);
     aNbF=aLF.Extent();
     if (!aNbF) {
@@ -130,7 +153,7 @@ static
     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);
+      bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aF1, aF1, theContext);
       return bRet;
     }
     else if (aNbF==2) {
@@ -138,16 +161,16 @@ static
       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);
-       return bRet;
+        // 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);
+      bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, aE, aLF, theContext);
       return bRet;
     }
   }//for(; aExp.More(); aExp.Next()) {
@@ -165,11 +188,12 @@ static
 }
 //=======================================================================
 //function : IsInternalFace
-//purpose  : 
+//purpose  :
 //=======================================================================
   Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
-                                                   const TopoDS_Edge& theEdge,
-                                                   const TopTools_ListOfShape& theLF)
+                                                    const TopoDS_Edge& theEdge,
+                                                    const TopTools_ListOfShape& theLF,
+                                                    IntTools_Context& theContext)
 {
   Standard_Boolean bRet;
   Standard_Boolean aNbF;
@@ -180,7 +204,7 @@ static
   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);
+    bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
     return bRet;
   }
   //
@@ -196,9 +220,9 @@ static
       //
       const TopoDS_Face& aF1=TopoDS::Face(aCSFF.Shape1());
       const TopoDS_Face& aF2=TopoDS::Face(aCSFF.Shape2());
-      bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2);
+      bRet=GEOMAlgo_Tools3D::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
       if (bRet) {
-       return bRet;
+        return bRet;
       }
     }
   }
@@ -206,15 +230,17 @@ static
 }
 //=======================================================================
 //function : IsInternalFace
-//purpose  : 
+//purpose  :
 //=======================================================================
   Standard_Boolean GEOMAlgo_Tools3D::IsInternalFace(const TopoDS_Face& theFace,
-                                                  const TopoDS_Edge& theEdge,
-                                                  const TopoDS_Face& theFace1,
-                                                  const TopoDS_Face& theFace2)
+                                                    const TopoDS_Edge& theEdge,
+                                                    const TopoDS_Face& theFace1,
+                                                    const TopoDS_Face& theFace2,
+                                                    IntTools_Context& theContext)
 {
   Standard_Boolean bRet;
-  Standard_Real aT1, aT2, aT, aDt2D, aDt2Dx;//aD1, aD2,
+  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;
@@ -229,7 +255,7 @@ static
   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) {
@@ -249,73 +275,44 @@ static
   // 3
   bRet=Standard_False;
   //
-  //modified by NIZNHY-PKV Mon Nov 13 12:12:53 2006f
+  GetApproxNormalToFaceOnEdge (aE1, theFace1, aT, aPF1, aDNF1, theContext);
+  GetApproxNormalToFaceOnEdge (aE2, theFace2, aT, aPF2, aDNF2, theContext);
   //
-  BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aE1, theFace1, aT, aPF1, aDNF1);
-  BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aE2, theFace2, aT, aPF2, aDNF2);
+  aTwoPI = 2.*M_PI;
+  gp_Vec aVBF (aPx, aPF );
+  gp_Vec aVBF1(aPx, aPF1);
+  gp_Vec aVBF2(aPx, aPF2);
   //
-  {
-    Standard_Real aA12, aA1x, aTwoPI;
-    //
-    aTwoPI=2.*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=aDBF1.AngleWithRef(aDBF2, aDTF1);
-    aA12=AngleWithRef(aDBF1, aDBF2, aDTF1);
-    if (aA12<0.) {
-      aA12=aA12+aTwoPI;
-    }
-    //aA1x=aDBF1.AngleWithRef(aDBF , aDTF1);
-    aA1x=AngleWithRef(aDBF1, aDBF , aDTF1);
-    if (aA1x<0.) {
-      aA1x=aA1x+aTwoPI;
-    }
-    //
-    if (aA1x<aA12) {
-      bRet=!bRet; //TopAbs_IN;
-    }
+  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;
   }
   //
-  /*
-  {
-    Standard_Real aD1, aD2;
-    //
-    //BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aE1, theFace1, aT, aPF1, aDNF1);
-    gp_Pln aPlnF1(aPx, aDNF1);
-    //
-    aD1=BOPTools_Tools3D::SignDistance(aPF, aPlnF1);
-    if (aD1<=0.) {
-      //BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aE2, theFace2, aT, aPF2, aDNF2);
-      gp_Pln aPlnF2(aPx, aDNF2);
-      //
-      aD2=BOPTools_Tools3D::SignDistance(aPF, aPlnF2);
-      if (aD2<=0.) {
-       bRet=!bRet; //TopAbs_IN;
-      }
-    }
+  if (aA1x<aA12) {
+    bRet=!bRet; //TopAbs_IN;
   }
-  */
-  //modified by NIZNHY-PKV Mon Nov 13 12:12:55 2006t
   //
   return bRet;
-  
 }
 //=======================================================================
 //function : GetFaceOff
-//purpose  : 
+//purpose  :
 //=======================================================================
   void GEOMAlgo_Tools3D::GetFaceOff(const TopoDS_Edge& theE1,
-                                  const TopoDS_Face& theF1,
-                                  const NMTTools_ListOfCoupleOfShape& theLCSOff,
-                                  TopoDS_Face& theFOff)
+                                   const TopoDS_Face& theF1,
+                                   const NMTTools_ListOfCoupleOfShape& theLCSOff,
+                                   TopoDS_Face& theFOff)
 {
   Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
   gp_Pnt aPn1, aPn2;
@@ -324,7 +321,7 @@ static
   NMTTools_ListIteratorOfListOfCoupleOfShape aIt;
   //
   aAngleMin=100.;
-  aTwoPI=PI+PI;
+  aTwoPI = M_PI+M_PI;
   BRep_Tool::Range(theE1, aT1, aT2);
   aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
   // Ref
@@ -341,7 +338,7 @@ static
     const TopoDS_Face& aF2=TopoDS::Face(aCS.Shape2());
     //
     if (aF2==theF1) {
-      aAngle=PI;
+      aAngle=M_PI;
     }
     else if (aF2.IsSame(theF1)) {
       aAngle=aTwoPI;
@@ -350,15 +347,12 @@ static
       BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aE2, aF2, aT, aPn2, aDN2);
       aDN2.Reverse();
       // Angle
-      //
-      //aAngle=aDN1.AngleWithRef(aDN2, aDTtgt);
       aAngle=AngleWithRef(aDN1, aDN2, aDTtgt);
-      //
       if(aAngle<0.) {
-       aAngle=aTwoPI+aAngle;
+        aAngle=aTwoPI+aAngle;
       }
     }
-
+    //
     if (aAngle<aAngleMin){
       aAngleMin=aAngle;
       theFOff=aF2;
@@ -367,11 +361,11 @@ static
 }
 //=======================================================================
 //function : GetEdgeOnFace
-//purpose  : 
+//purpose  :
 //=======================================================================
   Standard_Boolean GEOMAlgo_Tools3D::GetEdgeOnFace(const TopoDS_Edge& theE1,
-                                                 const TopoDS_Face& theF2,
-                                                 TopoDS_Edge& theE2)
+                                                  const TopoDS_Face& theF2,
+                                                  TopoDS_Edge& theE2)
 {
   Standard_Boolean bFound;
   TopoDS_Iterator aItF, aItW;
@@ -385,9 +379,9 @@ static
     for (; aItW.More(); aItW.Next()) {
       const TopoDS_Shape& aE=aItW.Value();
       if (aE.IsSame(theE1)) {
-       theE2=TopoDS::Edge(aE);
-       bFound=!bFound;
-       return bFound;
+        theE2=TopoDS::Edge(aE);
+        bFound=!bFound;
+        return bFound;
       }
     }
   }
@@ -395,12 +389,12 @@ static
 }
 //=======================================================================
 //function : GetEdgeOff
-//purpose  : 
+//purpose  :
 //=======================================================================
-  Standard_Boolean GEOMAlgo_Tools3D::GetEdgeOff(const TopoDS_Edge& theE1,
-                                              const TopoDS_Face& theF2,
-                                              TopoDS_Edge& theE2)
-     
+Standard_Boolean GEOMAlgo_Tools3D::GetEdgeOff (const TopoDS_Edge& theE1,
+                                               const TopoDS_Face& theF2,
+                                               TopoDS_Edge& theE2)
+
 {
   Standard_Boolean bFound;
   TopAbs_Orientation aOr1, aOr1C, aOr2;
@@ -416,9 +410,9 @@ static
     if (aEF2.IsSame(theE1)) {
       aOr2=aEF2.Orientation();
       if (aOr2==aOr1C) {
-       theE2=aEF2;
-       bFound=!bFound;
-       return bFound;
+        theE2=aEF2;
+        bFound=!bFound;
+        return bFound;
       }
     }
   }
@@ -426,19 +420,19 @@ static
 }
 //=======================================================================
 // function:  ComputeState
-// purpose: 
+// purpose:
 //=======================================================================
   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Face& theF,
-                                            const TopoDS_Solid& theRef,
-                                            const Standard_Real theTol,
-                                            const TopTools_IndexedMapOfShape& theBounds,
-                                            IntTools_Context& theCtx)
+                                             const TopoDS_Solid& theRef,
+                                             const Standard_Real theTol,
+                                             const TopTools_IndexedMapOfShape& theBounds,
+                                             IntTools_Context& theCtx)
 {
   TopAbs_State aState;
-  TopExp_Explorer aExp; 
+  TopExp_Explorer aExp;
   TopoDS_Edge aE1;
   gp_Pnt2d aP2D;
-  gp_Pnt aP3D; 
+  gp_Pnt aP3D;
   //
   aState=TopAbs_UNKNOWN;
   //
@@ -468,12 +462,12 @@ static
 }
 //=======================================================================
 // function:  ComputeStateByOnePoint
-// purpose: 
+// purpose:
 //=======================================================================
   TopAbs_State GEOMAlgo_Tools3D::ComputeStateByOnePoint(const TopoDS_Shape& theS,
-                                                      const TopoDS_Solid& theRef,
-                                                      const Standard_Real theTol,
-                                                      IntTools_Context& theCtx)
+                                                       const TopoDS_Solid& theRef,
+                                                       const Standard_Real theTol,
+                                                       IntTools_Context& theCtx)
 {
   TopAbs_State aState;
   TopAbs_ShapeEnum aType;
@@ -492,15 +486,15 @@ static
 }
 //=======================================================================
 // function:  ComputeState
-// purpose: 
+// purpose:
 //=======================================================================
   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Vertex& theV,
-                                            const TopoDS_Solid& theRef,
-                                            const Standard_Real theTol,
-                                            IntTools_Context& theCtx)
+                                             const TopoDS_Solid& theRef,
+                                             const Standard_Real theTol,
+                                             IntTools_Context& theCtx)
 {
   TopAbs_State aState;
-  gp_Pnt aP3D; 
+  gp_Pnt aP3D;
   //
   aP3D=BRep_Tool::Pnt(theV);
   aState=GEOMAlgo_Tools3D::ComputeState(aP3D, theRef, theTol, theCtx);
@@ -508,17 +502,17 @@ static
 }
 //=======================================================================
 // function:  ComputeState
-// purpose: 
+// purpose:
 //=======================================================================
   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const TopoDS_Edge& theE,
-                                            const TopoDS_Solid& theRef,
-                                            const Standard_Real theTol,
-                                            IntTools_Context& theCtx)
+                                             const TopoDS_Solid& theRef,
+                                             const Standard_Real theTol,
+                                             IntTools_Context& theCtx)
 {
   Standard_Real aT1, aT2, aT = 0.;
   TopAbs_State aState;
   Handle(Geom_Curve) aC3D;
-  gp_Pnt aP3D; 
+  gp_Pnt aP3D;
   //
   aC3D = BRep_Tool::Curve(theE, aT1, aT2);
   //
@@ -558,12 +552,12 @@ static
 }
 //=======================================================================
 // function:  ComputeState
-// purpose: 
+// purpose:
 //=======================================================================
   TopAbs_State GEOMAlgo_Tools3D::ComputeState(const gp_Pnt& theP,
-                                            const TopoDS_Solid& theRef,
-                                            const Standard_Real theTol,
-                                            IntTools_Context& theCtx)
+                                             const TopoDS_Solid& theRef,
+                                             const Standard_Real theTol,
+                                             IntTools_Context& theCtx)
 {
   TopAbs_State aState;
   //
@@ -576,11 +570,11 @@ static
 }
 //=======================================================================
 // function: IsSplitToReverse
-// purpose: 
+// purpose:
 //=======================================================================
   Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Shape& theSp,
-                                                    const TopoDS_Shape& theSr,
-                                                    IntTools_Context& theCtx)
+                                                     const TopoDS_Shape& theSr,
+                                                     IntTools_Context& theCtx)
 {
   Standard_Boolean bRet;
   TopAbs_ShapeEnum aType;
@@ -610,11 +604,11 @@ static
 }
 //=======================================================================
 //function :IsSplitToReverse
-//purpose  : 
+//purpose  :
 //=======================================================================
   Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Face& theFSp,
-                                                    const TopoDS_Face& theFSr,
-                                                    IntTools_Context& theContext)
+                                                     const TopoDS_Face& theFSr,
+                                                     IntTools_Context& theContext)
 {
   Standard_Boolean bRet, bFound, bInFace;
   Standard_Real aT1, aT2, aT, aU, aV, aScPr;
@@ -643,20 +637,46 @@ static
     aESp=TopoDS::Edge(anExp.Current());
     if (!BRep_Tool::Degenerated(aESp)) {
       if (!BRep_Tool::IsClosed(aESp, theFSp)) {
-       bFound=!bFound;
-       break;
+        bFound=!bFound;
+        break;
       }
     }
   }
+  //
+  //modified by NIZNHY-PKV Tue Nov 22 10:50:30 2011f
   if (!bFound) {
-    return bRet;
+    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(..) 
+  // Parts of theContext.ComputeVS(..)
   GeomAPI_ProjectPointOnSurf& aProjector=theContext.ProjPS(theFSr);
   aProjector.Perform(aPFSp);
   if (!aProjector.IsDone()) {
@@ -671,9 +691,9 @@ static
   }
   //
   aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
-  gp_Dir aDD1U(aD1U); 
+  gp_Dir aDD1U(aD1U);
   gp_Dir aDD1V(aD1V);
-  gp_Dir aDNFSr=aDD1U^aDD1V; 
+  gp_Dir aDNFSr=aDD1U^aDD1V;
   if (theFSr.Orientation()==TopAbs_REVERSED){
     aDNFSr.Reverse();
   }
@@ -685,11 +705,11 @@ static
 }
 //=======================================================================
 //function :IsSplitToReverse
-//purpose  : 
+//purpose  :
 //=======================================================================
   Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Edge& theSplit,
-                                                    const TopoDS_Edge& theEdge,
-                                                    IntTools_Context& theContext)
+                                                     const TopoDS_Edge& theEdge,
+                                                     IntTools_Context& theContext)
 {
   Standard_Boolean bRet, aFlag, bIsDegenerated;
   Standard_Real aTE, aTS, aScPr, aTa, aTb, aT1, aT2;
@@ -700,8 +720,8 @@ static
   //
   bRet=Standard_False;
   //
-  bIsDegenerated=(BRep_Tool::Degenerated(theSplit) || 
-                 BRep_Tool::Degenerated(theEdge));
+  bIsDegenerated=(BRep_Tool::Degenerated(theSplit) ||
+                  BRep_Tool::Degenerated(theEdge));
   if (bIsDegenerated) {
     return bRet;
   }
@@ -733,10 +753,10 @@ static
 
 //=======================================================================
 // function: Sense
-// purpose: 
+// purpose:
 //=======================================================================
   Standard_Integer GEOMAlgo_Tools3D::Sense (const TopoDS_Face& theF1,
-                                          const TopoDS_Face& theF2)
+                                           const TopoDS_Face& theF2)
 {
   Standard_Integer iSense=0;
   gp_Dir aDNF1, aDNF2;
@@ -748,7 +768,7 @@ static
     aE1=TopoDS::Edge(anExp.Current());
     if (!BRep_Tool::Degenerated(aE1)) {
       if (!BRep_Tool::IsClosed(aE1, theF1)) {
-       break;
+        break;
       }
     }
   }
@@ -758,10 +778,10 @@ static
     aE2=TopoDS::Edge(anExp.Current());
     if (!BRep_Tool::Degenerated(aE2)) {
       if (!BRep_Tool::IsClosed(aE2, theF2)) {
-       if (aE2.IsSame(aE1)) {
-         iSense=1;
-         break;
-       }
+        if (aE2.IsSame(aE1)) {
+          iSense=1;
+          break;
+        }
       }
     }
   }
@@ -779,10 +799,10 @@ static
 }
 //=======================================================================
 // function: CopyFace
-// purpose: 
+// purpose:
 //=======================================================================
   void GEOMAlgo_Tools3D::CopyFace (const TopoDS_Face& theF1,
-                                 TopoDS_Face& theF2)
+                                  TopoDS_Face& theF2)
 {
   Standard_Real aTol;
   TopLoc_Location aLoc;
@@ -805,10 +825,10 @@ static
 }
 //=======================================================================
 // function: MakeContainer
-// purpose: 
+// purpose:
 //=======================================================================
   void GEOMAlgo_Tools3D::MakeContainer(const TopAbs_ShapeEnum theType,
-                                     TopoDS_Shape& theC)
+                                      TopoDS_Shape& theC)
 {
   BRep_Builder aBB;
   //
@@ -831,7 +851,7 @@ static
       TopoDS_Solid aSolid;
       aBB.MakeSolid(aSolid);
       theC=aSolid;
-    }  
+    }
       break;
       //
       //
@@ -839,7 +859,7 @@ static
       TopoDS_Shell aShell;
       aBB.MakeShell(aShell);
       theC=aShell;
-    }  
+    }
       break;
       //
     case TopAbs_WIRE: {
@@ -855,11 +875,11 @@ static
 }
 //=======================================================================
 // function: MakeConnexityBlock.
-// purpose: 
+// purpose:
 //=======================================================================
   void GEOMAlgo_Tools3D::MakeConnexityBlock (const TopTools_ListOfShape& theLFIn,
-                                            const TopTools_IndexedMapOfShape& theMEAvoid,
-                                            TopTools_ListOfShape& theLCB)
+                                             const TopTools_IndexedMapOfShape& theMEAvoid,
+                                             TopTools_ListOfShape& theLCB)
 {
   Standard_Integer  aNbF, aNbAdd1;
   TopExp_Explorer aExp;
@@ -872,7 +892,7 @@ static
   aNbF=theLFIn.Extent();
   aIt.Initialize(theLFIn);
   for (; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aF=aIt.Value();      
+    const TopoDS_Shape& aF=aIt.Value();
     TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
   }
   //
@@ -889,23 +909,23 @@ static
       //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);
-       }
+        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()) {
@@ -923,7 +943,7 @@ static
     }
     //
   }//while(1) {
-  
+
   //
   aNbF=aMCB.Extent();
   aItM.Initialize(aMCB);
@@ -932,14 +952,13 @@ static
     theLCB.Append(aF);
   }
 }
-
 //=======================================================================
 //function : FindFacePairs
-//purpose  : 
+//purpose  :
 //=======================================================================
 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
-                               const TopTools_ListOfShape& thLF,
-                               NMTTools_ListOfCoupleOfShape& theLCFF)
+                                const TopTools_ListOfShape& thLF,
+                                NMTTools_ListOfCoupleOfShape& theLCFF)
 {
   Standard_Boolean bFound;
   Standard_Integer i, aNbCEF;
@@ -956,7 +975,7 @@ Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
   //
   // Preface aLCEF
   aItLF.Initialize(thLF);
-  for (; aItLF.More(); aItLF.Next()) { 
+  for (; aItLF.More(); aItLF.Next()) {
     const TopoDS_Face& aFL=TopoDS::Face(aItLF.Value());
     //
     bFound=GEOMAlgo_Tools3D::GetEdgeOnFace(theE, aFL, aEL);
@@ -983,16 +1002,16 @@ Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
       aOr=aEx.Orientation();
       //
       if (!i) {
-       aOrC=TopAbs::Reverse(aOr);
-       aE1=TopoDS::Edge(aEx);
-       aF1=TopoDS::Face(aFx);
-       aMFP.Add(aFx);
-       continue;
+        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);
+        aLCEFx.Append(aCSx);
+        aMFP.Add(aFx);
       }
     }
     //
@@ -1015,7 +1034,7 @@ Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
       const NMTTools_CoupleOfShape& aCSx=aIt.Value();
       const TopoDS_Shape& aFx=aCSx.Shape2();
       if (!aMFP.Contains(aFx)) {
-       aLCEF.Append(aCSx);
+        aLCEF.Append(aCSx);
       }
     }
     //
@@ -1027,16 +1046,16 @@ Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
 //
 //=======================================================================
 //function : AngleWithRef
-//purpose  : 
+//purpose  :
 //=======================================================================
 Standard_Real AngleWithRef(const gp_Dir& theD1,
-                          const gp_Dir& theD2,
-                          const gp_Dir& theDRef)
+                           const gp_Dir& theD2,
+                           const gp_Dir& theDRef)
 {
   Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
   gp_XYZ aXYZ;
   //
-  aHalfPI=0.5*PI;
+  aHalfPI=0.5*M_PI;
   //
   const gp_XYZ& aXYZ1=theD1.XYZ();
   const gp_XYZ& aXYZ2=theD2.XYZ();
@@ -1049,7 +1068,7 @@ Standard_Real AngleWithRef(const gp_Dir& theD1,
     aBeta=aHalfPI*(1.-aCosinus);
   }
   else {
-    aBeta=2.*PI-aHalfPI*(3.+aCosinus);
+    aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
   }
   //
   aScPr=aXYZ.Dot(theDRef.XYZ());
@@ -1058,98 +1077,225 @@ Standard_Real AngleWithRef(const gp_Dir& theD1,
   }
   return aBeta;
 }
-//
-/*
-static
-  void Path(const TopoDS_Shape& ,
-         const TopoDS_Shape& ,
-         const TopTools_IndexedDataMapOfShapeListOfShape& ,
-         const TopTools_IndexedMapOfShape& ,
-         TopTools_IndexedMapOfShape& );
-
 //=======================================================================
-// function: MakeConnexityBlock.
-// purpose: 
+//function : GetApproxNormalToFaceOnEdge
+//purpose  :
 //=======================================================================
-  void GEOMAlgo_Tools3D::MakeConnexityBlock (const TopTools_ListOfShape& theLFIn,
-                                           const TopTools_IndexedMapOfShape& theMEAvoid,
-                                           TopTools_ListOfShape& theLCB)
+void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aEx,
+                                  const TopoDS_Face& aFx,
+                                  Standard_Real aT,
+                                  gp_Pnt& aPF,
+                                  gp_Dir& aDNF,
+                                  IntTools_Context& aCtx)
 {
-  Standard_Integer  j, aNbF;
-  TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
-  TopTools_IndexedMapOfShape aMFP, aCBMap;
-  TopTools_ListIteratorOfListOfShape aIt;
-  TopExp_Explorer aExp;
-  TopAbs_ShapeEnum aType;
-  //
-  aIt.Initialize(theLFIn);
-  for (; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aF=aIt.Value();      
-    aType=aF.ShapeType();
-    TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
+  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);
   }
   //
-  aCBMap.Clear();
-  const TopoDS_Shape& aF=theLFIn.First();
+  // Point at aT
+  aC3D =BRep_Tool::Curve(aE, aT1, aT2);
+  aC3D->D0(aT, aPFT);
   //
-  aCBMap.Add(aF);
+  // Normal at aT
+  BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNFT);
+
+  // Tangent at aT
+  BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDTT);
   //
-  aExp.Init(aF, TopAbs_EDGE);
-  for (; aExp.More(); aExp.Next()){
-    const TopoDS_Shape& aE=aExp.Current();
-    if (theMEAvoid.Contains(aE)){
-      continue;
+  // 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;
+      }
     }
-    //
-    const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
-    aIt.Initialize(aLF);
-    for (; aIt.More(); aIt.Next()) {
-      const TopoDS_Shape& aF1=aIt.Value();
-      if (!aF1.IsSame(aF)) {
-       Path (aE, aF1, aEFMap, theMEAvoid,  aCBMap);
+    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());
   //
-  aNbF=aCBMap.Extent();
-  for (j=1; j<=aNbF; ++j) {
-    const TopoDS_Shape& aFx=aCBMap(j);
-    theLCB.Append(aFx);
+  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: Path
-// purpose
+//function : PntInFace
+//purpose  
 //=======================================================================
-void Path(const TopoDS_Shape& theE1,
-         const TopoDS_Shape& theF1,
-         const TopTools_IndexedDataMapOfShapeListOfShape& theEFMap,
-         const TopTools_IndexedMapOfShape& theMEAvoid,
-         TopTools_IndexedMapOfShape& theCBMap)
+Standard_Integer GEOMAlgo_Tools3D::PntInFace(const TopoDS_Face& aF, 
+                                            gp_Pnt& theP,
+                                            gp_Pnt2d& theP2D)
 {
-  TopTools_ListIteratorOfListOfShape aIt;
+  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;
   //
-  if (theCBMap.Contains(theF1)){
-    return;
+  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;
   }
-  theCBMap.Add(theF1);
-  //
-  aExp.Init(theF1, TopAbs_EDGE);
-  for (; aExp.More(); aExp.Next()){
-    const TopoDS_Shape& aE=aExp.Current();
-    if (!aE.IsSame(theE1)){
-      if (theMEAvoid.Contains(aE)) {
-       continue;
-      }
-      //
-      const TopTools_ListOfShape& aLF=theEFMap.FindFromKey(aE);
-      aIt.Initialize(aLF);
-      for (; aIt.More(); aIt.Next()) {
-       const TopoDS_Shape& aF=aIt.Value();
-         Path (aE, aF, theEFMap, theMEAvoid, theCBMap);
-      }
+  //
+  // 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