0024157: Parallelization of Assembly part of BO
authorpkv <pkv@opencascade.com>
Fri, 13 Sep 2013 03:05:16 +0000 (07:05 +0400)
committerbugmaster <bugmaster@opencascade.com>
Fri, 27 Sep 2013 05:54:29 +0000 (09:54 +0400)
The Build (Assembly) Part of BO consists of several sub-parts:
1. Building Vertices
2. Building Edges
3. Building Faces
4. Building Solids
5. Building Container Shapes (Wires, Shells, Compsolids, Compounds)

Among the parts above
3.Building Faces
and
4.Building Solids
are the most time-consuming and thus should be parallelized first.

The parallelization process can be divided on three phases:
1. Parallelization Building Faces
2. Parallelization Building Solids
3. Parallelization the rest parts

The phase 1 : Parallelization Building Faces consists of three parts:
1.1. Building Split Faces
1.2. Building Same Domain Faces
1.3. Building Faces with Internal Shapes
The branch deals with the phase 1. chapter 1.1. Building Split Faces

12 files changed:
src/BOPAlgo/BOPAlgo_BuilderFace.cdl
src/BOPAlgo/BOPAlgo_BuilderFace.cxx
src/BOPAlgo/BOPAlgo_Builder_2.cxx
src/BOPAlgo/BOPAlgo_Builder_2Cnt.hxx [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx
src/BOPAlgo/FILES
src/BOPCol/BOPCol.cdl
src/BOPCol/BOPCol_NCVector.hxx [new file with mode: 0644]
src/BOPCol/BOPCol_TBB.hxx [new file with mode: 0644]
src/BOPCol/FILES
src/BOPTools/BOPTools_AlgoTools2D.cdl
src/BOPTools/BOPTools_AlgoTools2D.cxx

index ac99e8d..42e640a 100644 (file)
@@ -26,7 +26,8 @@ class BuilderFace from BOPAlgo
         
        ---Purpose: The algorithm to build faces from set of edges  
 
-uses   
+uses    
+    Orientation from TopAbs,
     Face from TopoDS,
     BaseAllocator from BOPCol 
 --raises
@@ -76,9 +77,13 @@ is
      
     CheckData(me:out) 
        is redefined protected;   
-
+     
+    Orientation(me) 
+       returns Orientation from TopAbs; 
 fields  
     myFace : Face from TopoDS is protected;     
-     
+    myOrientation: Orientation from TopAbs is protected;             
 end BuilderFace; 
 
index 5ad003e..2b3e343 100644 (file)
@@ -83,6 +83,7 @@ static
 :
   BOPAlgo_BuilderArea()
 {
+  myOrientation=TopAbs_EXTERNAL;
 }
 //=======================================================================
 //function : 
@@ -91,7 +92,8 @@ static
   BOPAlgo_BuilderFace::BOPAlgo_BuilderFace(const Handle(NCollection_BaseAllocator)& theAllocator)
 :
   BOPAlgo_BuilderArea(theAllocator)
-{
+{ 
+  myOrientation=TopAbs_EXTERNAL;
 }
 //=======================================================================
 //function : ~
@@ -106,7 +108,17 @@ static
 //=======================================================================
   void BOPAlgo_BuilderFace::SetFace(const TopoDS_Face& theFace)
 {
+  myOrientation=theFace.Orientation();
   myFace=theFace;
+  myFace.Orientation(TopAbs_FORWARD);
+}
+//=======================================================================
+//function : Orientation
+//purpose  : 
+//=======================================================================
+TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
+{
+  return myOrientation;
 }
 //=======================================================================
 //function : Face
index 54f2a9a..528f54b 100644 (file)
 
 #include <BOPTools.hxx>
 #include <BOPTools_AlgoTools.hxx>
+#include <BOPTools_AlgoTools2D.hxx>
 #include <BOPTools_AlgoTools3D.hxx>
 #include <BOPAlgo_BuilderFace.hxx>
 #include <BOPTools_CoupleOfShape.hxx>
 #include <BOPTools_ListOfCoupleOfShape.hxx>
 #include <BOPTools_MapOfSet.hxx>
 #include <BOPTools_DataMapOfShapeSet.hxx>
+#include <BOPAlgo_Builder_2Cnt.hxx>
 
 static
   Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
@@ -74,11 +76,12 @@ static
                      BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
                      Handle(NCollection_IncAllocator)& aAllocator);
 
+
 //=======================================================================
 //function : FillImagesFaces
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_Builder::FillImagesFaces()
+void BOPAlgo_Builder::FillImagesFaces()
 {
   myErrorStatus=0;
   //
@@ -90,10 +93,12 @@ static
 //function : BuildSplitFaces
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_Builder::BuildSplitFaces()
+void BOPAlgo_Builder::BuildSplitFaces()
 {
   Standard_Boolean bHasFaceInfo, bIsClosed, bIsDegenerated, bToReverse;
   Standard_Integer i, j, aNbS, aNbPBIn, aNbPBOn, aNbPBSc, aNbAV, nSp;
+  Standard_Boolean bRunParallel;
+  Standard_Size aNbBF, k;
   TopoDS_Face aFF, aFSD;
   TopoDS_Edge aSp, aEE;
   TopAbs_Orientation anOriF, anOriE;
@@ -101,9 +106,10 @@ static
   BOPCol_ListIteratorOfListOfShape aIt;
   BOPCol_ListOfInteger aLIAV;
   BOPCol_MapOfShape aMFence;
-  Handle(NCollection_IncAllocator) aAllocator;
+  Handle(NCollection_BaseAllocator) aAllocator;
   BOPCol_ListOfShape aLFIm(myAllocator);
   BOPCol_MapIteratorOfMapOfShape aItMS;
+  BOPAlgo_VectorOfBuilderFace aVBF;
   //
   myErrorStatus=0;
   //
@@ -114,6 +120,7 @@ static
   BOPCol_MapOfShape aMDE(100, aAllocator);
   //
   aNbS=myDS->NbSourceShapes();
+  //
   for (i=0; i<aNbS; ++i) {
     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
     if (aSI.ShapeType()!=TopAbs_FACE) {
@@ -127,9 +134,6 @@ static
       continue;
     }
     //
-    // aLFIm will contain images of aF
-    aLFIm.Clear();
-    //
     const BOPDS_FaceInfo& aFI=myDS->FaceInfo(i);
     //
     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
@@ -247,17 +251,29 @@ static
       aLE.Append(aSp);
     }
     //
-    // 3 Build split faces
-    BOPAlgo_BuilderFace aBF(aAllocator);
-    //
-    aBF.SetFace(aFF);
-    //aBF.SetContext(myContext);
-    //
-    // <-DEB ft
+    BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane (aLE, aFF);
     //
+    // 3 Build split faces
+    BOPAlgo_BuilderFace& aBF=aVBF.Append1();
+    aBF.SetFace(aF);
     aBF.SetShapes(aLE);
     //
-    aBF.Perform();
+  }// for (i=0; i<aNbS; ++i) {
+  //
+  aNbBF=aVBF.Extent();
+  //
+  //===================================================
+  bRunParallel=Standard_True;
+  BOPAlgo_BuilderFaceCnt::Perform(bRunParallel, aVBF);
+  //===================================================
+  //
+  for (k=0; k<aNbBF; ++k) {
+    aLFIm.Clear();
+    //
+    BOPAlgo_BuilderFace& aBF=aVBF(k);
+    TopoDS_Face aF=aBF.Face();
+    anOriF=aBF.Orientation();
+    aF.Orientation(anOriF);
     //
     const BOPCol_ListOfShape& aLFR=aBF.Areas();
     aIt.Initialize(aLFR);
@@ -271,7 +287,7 @@ static
     }
     //
     mySplits.Bind(aF, aLFIm); 
-  }// for (i=0; i<aNbS; ++i) {
+  }// for (k=0; k<aNbBF; ++k) {
   //
   aAllocator.Nullify();
   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope t
@@ -280,7 +296,7 @@ static
 //function : FillSameDomainFaces
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_Builder::FillSameDomainFaces()
+void BOPAlgo_Builder::FillSameDomainFaces()
 {
   Standard_Boolean bFlag;
   Standard_Integer i, aNbFFs, aNbCurves, aNbPoints, nF1, nF2, aNbS;
@@ -450,7 +466,7 @@ static
 // function: FillImagesFaces1
 // purpose: 
 //=======================================================================
-  void BOPAlgo_Builder::FillImagesFaces1()
+void BOPAlgo_Builder::FillImagesFaces1()
 {
   Standard_Integer i, aNbS, iSense;
   TopoDS_Face aFSD;
@@ -508,8 +524,8 @@ static
 // function: FillInternalVertices
 // purpose: 
 //=======================================================================
-  void BOPAlgo_Builder::FillInternalVertices(BOPCol_ListOfShape& aLFIm,
-                                             BOPCol_ListOfInteger& aLIAV)
+void BOPAlgo_Builder::FillInternalVertices(BOPCol_ListOfShape& aLFIm,
+                                          BOPCol_ListOfInteger& aLIAV)
 {
   Standard_Integer nV, iFlag;
   Standard_Real aU1, aU2;
@@ -681,7 +697,6 @@ Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
   }
   return bRet;
 }
-
 /*
 //DEBf
     {
diff --git a/src/BOPAlgo/BOPAlgo_Builder_2Cnt.hxx b/src/BOPAlgo/BOPAlgo_Builder_2Cnt.hxx
new file mode 100644 (file)
index 0000000..626cef3
--- /dev/null
@@ -0,0 +1,133 @@
+// Created by: Peter KURNEV
+// Copyright (c) 1999-2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef BOPAlgo_Builder_2Cnt_HeaderFile
+#define BOPAlgo_Builder_2Cnt_HeaderFile
+
+/*
+#ifdef HAVE_TBB
+#undef HAVE_TBB
+#endif
+*/
+#include <BOPCol_NCVector.hxx>
+#include <BOPAlgo_BuilderFace.hxx>
+
+#ifdef HAVE_TBB
+#include <BOPCol_TBB.hxx>
+
+#define flexible_range blocked_range
+#define flexible_for   parallel_for
+#else 
+#define flexible_range serial_range
+#define flexible_for   serial_for
+#endif
+
+//=======================================================================
+//class : serial_range
+//purpose  : 
+//=======================================================================
+template <class Type> class serial_range {
+ public:
+  serial_range(const Type& aBegin,
+              const Type& aEnd)
+    : myBegin(aBegin), myEnd(aEnd) {
+  }
+  //
+  ~serial_range() {
+  }
+  //
+  const Type& begin() const{
+    return myBegin;
+  }
+  //
+  const Type& end() const{
+    return myEnd;
+  };
+  //
+ protected:
+  Type myBegin;
+  Type myEnd;
+};
+//=======================================================================
+//function : serial_for
+//purpose  : 
+//=======================================================================
+template<typename Range, typename Body>
+static void serial_for( const Range& range, const Body& body ) {
+  body.operator()(range);
+};
+//
+//=======================================================================
+//class    : BOPAlgo_VectorOfBuilderFace
+//purpose  : 
+//=======================================================================
+typedef BOPCol_NCVector<BOPAlgo_BuilderFace> BOPAlgo_VectorOfBuilderFace;
+//
+//=======================================================================
+//class    : BOPAlgo_BuilderFaceFunctor
+//purpose  : 
+//=======================================================================
+class BOPAlgo_BuilderFaceFunctor {
+ protected:
+  BOPAlgo_VectorOfBuilderFace* myPVBF;
+  //
+ public:
+  //
+  BOPAlgo_BuilderFaceFunctor(BOPAlgo_VectorOfBuilderFace& aVBF) 
+    : myPVBF(&aVBF) {
+  }
+  //
+  void operator()( const flexible_range<Standard_Size>& aBR ) const{
+    Standard_Size i, iBeg, iEnd;
+    //
+    BOPAlgo_VectorOfBuilderFace& aVBF=*myPVBF;
+    //
+    iBeg=aBR.begin();
+    iEnd=aBR.end();
+    for(i=iBeg; i!=iEnd; ++i) {
+      BOPAlgo_BuilderFace& aBF=aVBF(i);
+      //
+      aBF.Perform();
+    }
+  }
+};
+//=======================================================================
+//class    : BOPAlgo_BuilderFaceCnt
+//purpose  : 
+//=======================================================================
+class BOPAlgo_BuilderFaceCnt {
+ public:
+  //-------------------------------
+  // Perform
+  Standard_EXPORT static void Perform(const Standard_Boolean bRunParallel,
+                                     BOPAlgo_VectorOfBuilderFace& aVBF) {
+    //
+    BOPAlgo_BuilderFaceFunctor aBFF(aVBF);
+    Standard_Size aNbBF=aVBF.Extent();
+    //
+    if (bRunParallel) {
+      flexible_for(flexible_range<Standard_Size>(0,aNbBF), aBFF);
+    }
+    else {
+      aBFF.operator()(flexible_range<Standard_Size>(0,aNbBF));
+    }
+  }
+  //
+};
+
+#endif
index 71b7af0..fb9132c 100644 (file)
@@ -48,6 +48,7 @@
 #include <BOPCol_SequenceOfReal.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
+#include <BOPTools_AlgoTools2D.hxx>
 //
 
 static
@@ -111,9 +112,7 @@ static
   Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
                              const GeomAdaptor_Surface& aGAS);
 
-static
-  void BuildPCurveForPlane (const BOPCol_ListOfShape myEdges,
-                            const TopoDS_Face& myFace);
+
 
 static
   Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
@@ -154,7 +153,8 @@ static
   const BOPCol_ListOfShape& myEdges=aCB.Shapes();
   //
   // 1.Filling mySmartMap
-  BuildPCurveForPlane(myEdges, myFace);
+  BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane(myEdges, myFace);
+  //
   aIt.Initialize(myEdges);
   for(; aIt.More(); aIt.Next()) {
     const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
@@ -817,42 +817,7 @@ Standard_Real Angle (const gp_Dir2d& aDir2D)
   //
   return aTol2D;
 }
-//=======================================================================
-// function: BuildPCurvesForPlane
-// purpose: 
-//=======================================================================
-  void BuildPCurveForPlane (const BOPCol_ListOfShape myEdges,
-                            const TopoDS_Face& myFace)
-{
-  TopLoc_Location aLoc;
-  Handle(Geom2d_Curve) aC2D;
-  Handle(Geom_Plane) aGP;
-  Handle(Geom_RectangularTrimmedSurface) aGRTS;
-  //
-  const Handle(Geom_Surface)& aS = BRep_Tool::Surface(myFace, aLoc);
-  aGRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
-  if(!aGRTS.IsNull()){
-    aGP=Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
-    }    
-  else {
-    aGP=Handle(Geom_Plane)::DownCast(aS);
-  }
-  //
-  if (aGP.IsNull()) {
-    return;
-  }
-  //
-  Standard_Real aTolE;
-  BOPCol_ListIteratorOfListOfShape aIt;
-  BRep_Builder aBB;
-  //
-  aIt.Initialize(myEdges);
-  for(; aIt.More(); aIt.Next()) {
-    const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
-    BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aTolE);
-    aBB.UpdateEdge(aE, aC2D, myFace, aTolE);
-  }
-}
+
 //=======================================================================
 //function : UTolerance2D
 //purpose  : 
index f2caa5c..01a0706 100644 (file)
@@ -13,3 +13,5 @@ BOPAlgo_Builder_4.cxx
 BOPAlgo_BOP_1.cxx
 BOPAlgo_WireSplitter_1.cxx
 BOPAlgo_ListOfCheckResult.hxx
+
+BOPAlgo_Builder_2Cnt.hxx
index 9937dac..c898bb8 100644 (file)
@@ -54,5 +54,6 @@ is
     imported DataMapOfIntegerListOfShape from BOPCol;
     imported IndexedDataMapOfIntegerListOfInteger from BOPCol;
     imported IndexedDataMapOfShapeInteger from BOPCol;  
+   
     
 end BOPCol;
diff --git a/src/BOPCol/BOPCol_NCVector.hxx b/src/BOPCol/BOPCol_NCVector.hxx
new file mode 100644 (file)
index 0000000..a23c8c4
--- /dev/null
@@ -0,0 +1,61 @@
+// Created by: Peter KURNEV
+// Copyright (c) 1999-2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+
+#ifndef BOPCol_NCVector_HeaderFile
+#define BOPCol_NCVector_HeaderFile
+
+#include <Standard.hxx>
+#include <NCollection_Vector.hxx>
+#include <NCollection_BaseAllocator.hxx>
+
+//=======================================================================
+//class    : BOPCol_NCVector
+//purpose  : 
+//=======================================================================
+template <class Type> class BOPCol_NCVector 
+  :
+  public NCollection_Vector<Type>
+{
+ public:
+  BOPCol_NCVector(const Standard_Integer theIncrement=256,
+                 const Handle_NCollection_BaseAllocator& theAlloc = NULL) 
+    : NCollection_Vector<Type>(theIncrement, theAlloc) {
+  };
+  //
+  BOPCol_NCVector(const BOPCol_NCVector& theOther) 
+    : NCollection_Vector<Type>(theOther) {
+  };
+  //
+  Type& Append1 ()
+  {
+    Type& anAppended = 
+      *(Type* )expandV (NCollection_BaseCollection<Type>::myAllocator, 
+                       NCollection_Vector<Type>::myLength);
+    return anAppended;
+  }
+  //
+  Standard_Integer Extent() const
+  {
+    return NCollection_Vector<Type>::myLength;
+  }
+ protected:
+  
+};
+
+#endif
diff --git a/src/BOPCol/BOPCol_TBB.hxx b/src/BOPCol/BOPCol_TBB.hxx
new file mode 100644 (file)
index 0000000..fbde3bc
--- /dev/null
@@ -0,0 +1,31 @@
+// Created by: Peter KURNEV
+// Copyright (c) 1999-2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _BOPDS_Col_HeaderFile
+#define _BOPDS_Col_HeaderFile
+
+#ifdef HAVE_TBB
+
+
+#include <tbb/tbb.h>
+using namespace tbb;
+
+
+#endif
+
+#endif
index 3543673..e1d8d8b 100644 (file)
@@ -28,4 +28,7 @@ BOPCol_DataMapOfIntegerListOfShape.hxx
 BOPCol_SequenceOfReal.hxx
 BOPCol_DataMapOfIntegerShape.hxx
 BOPCol_IndexedDataMapOfIntegerListOfInteger.hxx
-BOPCol_IndexedDataMapOfShapeInteger.hxx
\ No newline at end of file
+BOPCol_IndexedDataMapOfShapeInteger.hxx
+
+BOPCol_TBB.hxx
+BOPCol_NCVector.hxx
index 7be6e33..94674bc 100644 (file)
@@ -32,8 +32,9 @@ uses
      
     Curve from Geom2d,
     Curve from Geom, 
-    ProjectedCurve from ProjLib
-
+    ProjectedCurve from ProjLib,
+    ListOfShape from BOPCol 
+    
 is   
 
     BuildPCurveForEdgeOnFace  (myclass; 
@@ -144,6 +145,10 @@ is
           ---
     BuildPCurveForEdgeOnPlane(myclass; 
               theE : Edge from TopoDS; 
+              theF : Face from TopoDS); 
+             
+    BuildPCurveForEdgesOnPlane(myclass; 
+              theLE : ListOfShape from BOPCol; 
               theF : Face from TopoDS);
  
     Make2D  (myclass;  
index 9bfda5d..e52bd3c 100755 (executable)
@@ -400,8 +400,8 @@ static
 //function : BuildPCurveForEdgeOnPlane
 //purpose  : 
 //=======================================================================
-  void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (const TopoDS_Edge& aE,
-                                                    const TopoDS_Face& aF)
+void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (const TopoDS_Edge& aE,
+                                                     const TopoDS_Face& aF)
 { 
   Standard_Real aTolE;
   TopLoc_Location aLoc;
@@ -428,14 +428,57 @@ static
   //
   return;
 }
+//=======================================================================
+// function: BuildPCurveForEdgesOnPlane
+// purpose: 
+//=======================================================================
+void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane 
+  (const BOPCol_ListOfShape& aEdges,
+   const TopoDS_Face& aFace)
+{
+  
+  TopLoc_Location aLoc;
+  Handle(Geom2d_Curve) aC2D;
+  Handle(Geom_Plane) aGP;
+  Handle(Geom_RectangularTrimmedSurface) aGRTS;
+  //
+  const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aFace, aLoc);
+  aGRTS=Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
+  if(!aGRTS.IsNull()){
+    aGP=Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
+    }    
+  else {
+    aGP=Handle(Geom_Plane)::DownCast(aS);
+  }
+  //
+  if (aGP.IsNull()) {
+    return;
+  }
+  //
+  Standard_Boolean bHasOld;
+  Standard_Real aTolE, aT1, aT2;
+  BOPCol_ListIteratorOfListOfShape aIt;
+  BRep_Builder aBB;
+  //
+  aIt.Initialize(aEdges);
+  for(; aIt.More(); aIt.Next()) {
+    const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
+    bHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface
+      (aE, aFace, aC2D, aT1, aT2, aTolE);
+    if (!bHasOld) {
+      BOPTools_AlgoTools2D::CurveOnSurface(aE, aFace, aC2D, aTolE);
+      aBB.UpdateEdge(aE, aC2D, aFace, aTolE);
+    }
+  }
+}
 
 //=======================================================================
 //function : Make2D
 //purpose  : 
 //=======================================================================
-  void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
-                                 const TopoDS_Face& aF,
-                                 Handle(Geom2d_Curve)& aC2D,
+void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
+                                  const TopoDS_Face& aF,
+                                  Handle(Geom2d_Curve)& aC2D,
                                  Standard_Real& aFirst,
                                  Standard_Real& aLast,
                                  Standard_Real& aToler)