]> OCCT Git - occt-copy.git/commitdiff
0029523: Problem with BRepOffsetAPI_MakeEvolved
authornbv <nbv@opencascade.com>
Tue, 6 Mar 2018 10:31:18 +0000 (13:31 +0300)
committernbv <nbv@opencascade.com>
Tue, 29 May 2018 09:14:15 +0000 (12:14 +0300)
1. New class BRepFill_Voluved has been created in order to provide new OCCT-algorithm combining BRepFill_PipeShell and BOPAlgo_MakerVolume.

2. The interface of DRAW-command "evolved" has been corrected.

3. DRAW-command "evolvedsolid" has been deleted. Currently it can be replaced with DRAW-command "evolved" with specific options.

4. Some test cases have been corrected.

5. Testgrid "evolved" has been created.

48 files changed:
src/BRepFill/BRepFill_PipeShell.cxx
src/BRepFill/BRepFill_PipeShell.hxx
src/BRepFill/BRepFill_Sweep.cxx
src/BRepFill/BRepFill_Sweep.hxx
src/BRepFill/BRepFill_Voluved.cxx [new file with mode: 0644]
src/BRepFill/BRepFill_Voluved.hxx [new file with mode: 0644]
src/BRepFill/FILES
src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx
src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx
src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx
src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.hxx
src/BRepTest/BRepTest_SweepCommands.cxx
src/LocOpe/LocOpe_DPrism.cxx
src/NCollection/NCollection_List.hxx
src/math/math_NewtonMinimum.cxx
tests/bugs/modalg_4/pro19424
tests/bugs/modalg_6/bug26470_1
tests/bugs/modalg_6/bug26470_2
tests/evolved/begin [new file with mode: 0644]
tests/evolved/end [new file with mode: 0644]
tests/evolved/evolved/begin [new file with mode: 0644]
tests/evolved/evolved/bug26470_1 [new file with mode: 0644]
tests/evolved/evolved/bug26470_2 [new file with mode: 0644]
tests/evolved/evolved/pro19424 [new file with mode: 0644]
tests/evolved/grids.list [new file with mode: 0644]
tests/evolved/parse.rules [new file with mode: 0644]
tests/evolved/voluved/AGT001 [new file with mode: 0644]
tests/evolved/voluved/AGT002 [new file with mode: 0644]
tests/evolved/voluved/AGT003 [new file with mode: 0644]
tests/evolved/voluved/AGT004 [new file with mode: 0644]
tests/evolved/voluved/AGT005 [new file with mode: 0644]
tests/evolved/voluved/AGT006 [new file with mode: 0644]
tests/evolved/voluved/AGT007 [new file with mode: 0644]
tests/evolved/voluved/AGT008 [new file with mode: 0644]
tests/evolved/voluved/AGT009 [new file with mode: 0644]
tests/evolved/voluved/HMC001 [new file with mode: 0644]
tests/evolved/voluved/HMC002 [new file with mode: 0644]
tests/evolved/voluved/HMC003 [new file with mode: 0644]
tests/evolved/voluved/HMC004 [new file with mode: 0644]
tests/evolved/voluved/HMC005 [new file with mode: 0644]
tests/evolved/voluved/HMC006 [new file with mode: 0644]
tests/evolved/voluved/HMC007 [new file with mode: 0644]
tests/evolved/voluved/HMC008 [new file with mode: 0644]
tests/evolved/voluved/HMC009 [new file with mode: 0644]
tests/evolved/voluved/begin [new file with mode: 0644]
tests/evolved/voluved/bug26470_1 [new file with mode: 0644]
tests/evolved/voluved/bug26470_2 [new file with mode: 0644]
tests/evolved/voluved/pro19424 [new file with mode: 0644]

index 65ff2b28a02e563583219b78cfe8091b8c69f6cd..3d0eba45f8fbe2f2a297790ba5eb143e9f5cd41c 100644 (file)
@@ -692,7 +692,7 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
 //function : Build
 //purpose  : Construct the Shell and the history
 //=======================================================================
- Standard_Boolean BRepFill_PipeShell::Build() 
+ Standard_Boolean BRepFill_PipeShell::Build()
 {
   Standard_Boolean Ok;
   Standard_Real FirstS, LastS;
@@ -746,8 +746,9 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
   MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular);
   MkSw.SetAngularControl(angmin, angmax);
   MkSw.SetForceApproxC1(myForceApproxC1);
-  MkSw.SetBounds(TopoDS::Wire(myFirst), 
-                TopoDS::Wire(myLast));
+  MkSw.SetBounds(TopoDS::Wire(myFirst),
+                 TopoDS::Wire(myLast));
+
   GeomAbs_Shape theContinuity = GeomAbs_C2;
   if (myTrihedron == GeomFill_IsDiscreteTrihedron)
     theContinuity = GeomAbs_C0;
index c99ab7e75824301d1bf82723f40b78aa77ac04f2..36d6c824a0fe2e4733e0198ee3b2eb204163d8c9 100644 (file)
@@ -168,6 +168,10 @@ public:
   Standard_EXPORT void Simulate (const Standard_Integer NumberOfSection, TopTools_ListOfShape& Sections);
   
   //! Builds the resulting shape (redefined from MakeShape).
+  //! If theIsToCheckValidity == FALSE then BRepFill_Sweep algorithm
+  //! is allowed to create invalid faces (having self-interferences).
+  //! It is considered for them that such faces will be processed and
+  //! fixed by the high-level algorithms
   Standard_EXPORT Standard_Boolean Build();
   
   //! Transform the sweeping Shell in Solid.
index c7e9550149f6fe5e5066a2574cdf6f612cfb8b8b..1d2f0214b3adfbbf1f7b257a0feabcb592908334 100644 (file)
@@ -914,7 +914,7 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF,
   // Control the direction of the rotation
   Standard_Boolean ToReverseResult = Standard_False;
   gp_Vec d1u;
-  d1u = Surf->DN(0, (f1+l1)/2, 1, 0);
+  d1u = Surf->DN(0, aPrm[aMaxIdx], 1, 0);
   if (d1u.Angle(TangentOnPart1) > M_PI/2) { //Invert everything
     ToReverseResult = Standard_True;
     /*
@@ -1815,8 +1815,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
                               const Standard_Boolean WithKPart) : 
                               isDone(Standard_False),
                               KPart(WithKPart)
-
-
 {
  mySec = Section;
  myLoc = Location;
@@ -3353,7 +3351,8 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const
          // Filling
          B = Filling(It1.Value(), myFaces->Value(ii, I1),
                      It2.Value(), myFaces->Value(ii, I2),
-                     myVEdgesModified, myTol3d, Axe, T1, Bord1, Bord2, FF);
+                      myVEdgesModified, myTol3d, Axe, T1,
+                      Bord1, Bord2, FF);
          
          if (B) {
            myAuxShape.Append(FF);
index b3b003a3f9d8162ca926c6a59b0ee8f6a57d6b32..72b1897959710ca7ae4cff4d9ce61c58d1411ef4 100644 (file)
@@ -80,7 +80,7 @@ public:
   //! to be C0.
   Standard_EXPORT void SetForceApproxC1 (const Standard_Boolean ForceApproxC1);
   
-  //! Build the Sweeep  Surface
+  //! Build the Sweep  Surface
   //! Transition define Transition strategy
   //! Approx define Approximation Strategy
   //! - GeomFill_Section : The composed Function Location X Section
@@ -118,13 +118,6 @@ public:
 
 protected:
 
-
-
-
-
-private:
-
-  
   Standard_EXPORT Standard_Boolean CorrectApproxParameters();
   
   Standard_EXPORT Standard_Boolean BuildWire (const BRepFill_TransitionStyle Transition);
@@ -142,6 +135,13 @@ private:
   Standard_EXPORT void RebuildTopOrBottomEdge (const TopoDS_Edge& aNewEdge, TopoDS_Edge& anEdge, TopTools_MapOfShape& ReversedEdges) const;
 
 
+
+
+private:
+
+  
+
+
   Standard_Boolean isDone;
   Standard_Boolean KPart;
   Standard_Real myTol3d;
@@ -168,7 +168,6 @@ private:
   TopoDS_Wire FirstShape;
   TopoDS_Wire LastShape;
 
-
 };
 
 
diff --git a/src/BRepFill/BRepFill_Voluved.cxx b/src/BRepFill/BRepFill_Voluved.cxx
new file mode 100644 (file)
index 0000000..12efc6f
--- /dev/null
@@ -0,0 +1,1700 @@
+// Created on: 2018-03-14
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <BRepFill_Voluved.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepFill_PipeShell.hxx>
+#include <BRepFill_TransitionStyle.hxx>
+#include <TopExp.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <BOPAlgo_Tools.hxx>
+#include <BRepLib_FindSurface.hxx>
+#include <Geom_Plane.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BOPAlgo_MakerVolume.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BOPAlgo_PaveFiller.hxx>
+#include <math_MultipleVarFunctionWithHessian.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <Adaptor2d_HCurve2d.hxx>
+#include <Adaptor3d_HSurface.hxx>
+#include <math_NewtonMinimum.hxx>
+#include <BOPTools_AlgoTools.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <BRepTools.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
+#include <BOPAlgo_BuilderFace.hxx>
+#include <BOPAlgo_BuilderFace.hxx>
+#include <Geom2d_Line.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <math_GlobOptMin.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <Extrema_ExtPC.hxx>
+#include <BOPDS_DS.hxx>
+#include <BRepLib.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
+#include <BRepLib_MakeFace.hxx>
+#include <ShapeFix_Shape.hxx>
+#include <BRepClass_FaceClassifier.hxx>
+#include <BRepGProp_Face.hxx>
+
+static const Standard_Real aPipeLinearTolerance = 1.0e-4;
+static const Standard_Real aPipeAngularTolerance = 1.0e-2;
+
+static Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF,
+                                               const Standard_Real theFuzzyToler,
+                                               TopTools_ListOfShape& theListOfFaces,
+                                               TopTools_ListOfShape& theListOfSplits);
+
+//=======================================================================
+//function : GetSpineAndProfile
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::GetSpineAndProfile(const TopoDS_Wire& theSpine,
+                                          const TopoDS_Wire& theProfile)
+{
+  mySpine = theSpine;
+  myProfile = theProfile;
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMVEP;
+  TopExp::MapShapesAndAncestors(theProfile, TopAbs_VERTEX, TopAbs_EDGE, aMVEP);
+
+  gp_Vec aN2;
+  gp_Pnt aLoc;
+
+  for (Standard_Integer i = 1; i <= aMVEP.Size(); i++)
+  {
+    const TopoDS_Vertex &aVC = TopoDS::Vertex(aMVEP.FindKey(i));
+
+    const TopTools_ListOfShape &aLE = aMVEP.FindFromIndex(i);
+
+    if (aLE.Extent() < 2)
+      continue;
+
+    const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First());
+    const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last());
+    
+    const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2);
+
+    const Standard_Real aPar1 = BRep_Tool::Parameter(aVC, anE1);
+    const Standard_Real aPar2 = BRep_Tool::Parameter(aVC, anE2);
+
+    gp_Pnt aP;
+    gp_Vec aT1, aT2;
+
+    anAC1.D1(aPar1, aP, aT1);
+    anAC1.D1(aPar2, aP, aT2);
+
+    aN2 = aT1.Crossed(aT2);
+
+    if (aN2.SquareMagnitude() > Precision::SquareConfusion())
+    {
+      aLoc = BRep_Tool::Pnt(aVC);
+      break;
+    }
+  }
+
+  BRepExtrema_DistShapeShape anExtr;
+  anExtr.LoadS1(theSpine);
+
+  if (aN2.SquareMagnitude() > Precision::SquareConfusion())
+  {
+    const gp_Pln aPln(aLoc, aN2);
+    BRepLib_MakeFace aMF(aPln, theProfile);
+    if (!aMF.IsDone())
+      return;
+
+    anExtr.LoadS2(aMF.Face());
+  }
+  else
+  {
+    anExtr.LoadS2(theProfile);
+  }
+
+  if (!anExtr.Perform())
+    return;
+
+  const Standard_Integer aNbSol = anExtr.NbSolution();
+  if (aNbSol < 1)
+    return;
+
+  Standard_Real aDistMin = RealLast();
+  Standard_Integer anIdxMin = 0;
+
+  for (Standard_Integer aSolId = 1; aSolId <= aNbSol; aSolId++)
+  {
+    const Standard_Real aD = anExtr.Value();
+    if (aD > aDistMin)
+      continue;
+
+    aDistMin = aD;
+    anIdxMin = aSolId;
+  }
+  
+  BRepExtrema_SupportType anExtrType2 = anExtr.SupportTypeShape2(anIdxMin);
+
+  if (aDistMin < Precision::Confusion())
+  {
+    anExtrType2 = BRepExtrema_IsInFace;
+  }
+
+  switch (anExtrType2)
+  {
+    case BRepExtrema_IsInFace:
+      if (anExtr.SupportTypeShape1(anIdxMin) == BRepExtrema_IsVertex)
+      {
+        const TopoDS_Vertex aV = TopoDS::Vertex(anExtr.SupportOnShape1(anIdxMin));
+        TopTools_IndexedDataMapOfShapeListOfShape aMVES;
+        TopExp::MapShapesAndAncestors(theSpine, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
+
+        const TopTools_ListOfShape &aLE = aMVES.FindFromKey(aV);
+
+        const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First());
+        const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last());
+
+        const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2);
+
+        const Standard_Real aPar1 = BRep_Tool::Parameter(aV, anE1);
+        const Standard_Real aPar2 = BRep_Tool::Parameter(aV, anE2);
+
+        gp_Pnt aP;
+        gp_Vec aT1, aT2;
+
+        anAC1.D1(aPar1, aP, aT1);
+        anAC1.D1(aPar2, aP, aT2);
+
+        // Find minimal sine
+        const Standard_Real aSqT1 = Max(aT1.SquareMagnitude(), 1.0 / Precision::Infinite());
+        const Standard_Real aSqT2 = Max(aT2.SquareMagnitude(), 1.0 / Precision::Infinite());
+
+        const Standard_Real aSqSin1 = aT1.CrossSquareMagnitude(aN2) / aSqT1;
+        const Standard_Real aSqSin2 = aT2.CrossSquareMagnitude(aN2) / aSqT2;
+
+        if (aSqSin1 < aSqSin2)
+        {
+          if (aT1.Dot(aN2) > 0.0)
+          {
+            myProfile.Reverse();
+          }
+        }
+        else
+        {
+          if (aT2.Dot(aN2) > 0.0)
+          {
+            myProfile.Reverse();
+          }
+        }
+      }
+      else // if (... == BRepExtrema_IsOnEdge)
+      {
+        const TopoDS_Edge anE = TopoDS::Edge(anExtr.SupportOnShape1(anIdxMin));
+        const BRepAdaptor_Curve anAC(anE);
+        Standard_Real aPar;
+        anExtr.ParOnEdgeS1(anIdxMin, aPar);
+
+        gp_Pnt aP;
+        gp_Vec aT1;
+        anAC.D1(aPar, aP, aT1);
+
+        if (aT1.Dot(aN2) > 0.0)
+        {
+          myProfile.Reverse();
+        }
+      }
+      break;
+
+    case BRepExtrema_IsOnEdge:
+    case BRepExtrema_IsVertex:
+    {
+      const BRepLib_MakeFace aMkFSpine(theSpine, Standard_True);
+      if (!aMkFSpine.IsDone())
+        return;
+
+      const TopoDS_Face &aFSpine = aMkFSpine.Face();
+      const Handle(Geom_Plane) aPlnSpine = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aFSpine));
+      const gp_Vec aN1(aPlnSpine->Axis().Direction());
+      gp_Vec aTanV;
+
+      if (anExtr.SupportTypeShape2(anIdxMin) == BRepExtrema_IsVertex)
+      {
+        const TopoDS_Vertex aV = TopoDS::Vertex(anExtr.SupportOnShape2(anIdxMin));
+        TopTools_IndexedDataMapOfShapeListOfShape aMVES;
+        TopExp::MapShapesAndAncestors(theProfile, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
+
+        const TopTools_ListOfShape &aLE = aMVES.FindFromKey(aV);
+
+        const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First());
+        const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last());
+
+        const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2);
+
+        const Standard_Real aPar1 = BRep_Tool::Parameter(aV, anE1);
+        const Standard_Real aPar2 = BRep_Tool::Parameter(aV, anE2);
+
+        gp_Pnt aP;
+        gp_Vec aT1, aT2;
+
+        anAC1.D1(aPar1, aP, aT1);
+        anAC1.D1(aPar2, aP, aT2);
+
+        // Find maximal cosine
+        Standard_Real aSqT1 = aT1.SquareMagnitude();
+        Standard_Real aSqT2 = aT2.SquareMagnitude();
+
+        if (aSqT1 < Precision::SquareConfusion())
+          aSqT1 = RealLast();
+
+        if (aSqT2 < Precision::SquareConfusion())
+          aSqT2 = RealLast();
+
+        const Standard_Real aDP1 = aT1.Dot(aN1);
+        const Standard_Real aDP2 = aT2.Dot(aN1);
+
+        if (aDP1*aDP1*aSqT2 > aDP2*aDP2*aSqT1)
+        {
+          //aDP1*aDP1/aSqT1 > aDP2*aDP2/aSqT2
+          aTanV = aT1;
+        }
+        else
+        {
+          aTanV = aT2;
+        }
+      }
+      else // if(anExtr.SupportTypeShape2(anIdxMin) == BRepExtrema_IsOnEdge)
+      {
+        const TopoDS_Edge anE = TopoDS::Edge(anExtr.SupportOnShape2(anIdxMin));
+        const BRepAdaptor_Curve anAC(anE);
+        Standard_Real aPar;
+        anExtr.ParOnEdgeS2(anIdxMin, aPar);
+
+        gp_Pnt aP;
+        anAC.D1(aPar, aP, aTanV);
+      }
+
+      //The point in the profile, which is the nearest to the spine
+      const gp_Pnt &aPnear = anExtr.PointOnShape2(anIdxMin);
+
+      BRepClass_FaceClassifier aFClass(aFSpine, aPnear, Precision::Confusion());
+      if (aFClass.State() != TopAbs_OUT)
+      {
+        if (aN1.Dot(aTanV) < 0.0)
+        {
+          myProfile = TopoDS::Wire(theProfile.Reversed());
+        }
+      }
+      else
+      {
+        if (aN1.Dot(aTanV) > 0.0)
+        {
+          myProfile = TopoDS::Wire(theProfile.Reversed());
+        }
+      }
+    }
+    break;
+    default:
+      break;
+  }
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::Perform(const TopoDS_Wire& theSpine, 
+                               const TopoDS_Wire& theProfile,
+                               const Standard_Real theTolerance,
+                               const Standard_Boolean theSolidReq)
+{
+  myErrorStatus = BRepFill_Voluved_Empty;
+
+  if (myFuzzyValue < Precision::Confusion())
+  {
+    myFuzzyValue = theTolerance;
+  }
+
+  GetSpineAndProfile(theSpine, theProfile);
+
+  myPipeShell.Nullify();
+  myTopBottom.Nullify();
+  myResult.Nullify();
+
+  PerformSweep();
+  GetLids();
+
+  if ((myErrorStatus != BRepFill_Voluved_NotSolid) && !theSolidReq)
+  {
+    myResult = myPipeShell;
+  }
+
+  BuildSolid();
+}
+
+//=======================================================================
+//function : PerformSweep
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::PerformSweep()
+{
+  if (myErrorStatus != BRepFill_Voluved_Empty)
+    return;
+
+  myErrorStatus = BRepFill_Voluved_SweepError;
+
+  Handle(BRepFill_PipeShell) aPipe = new BRepFill_PipeShell(mySpine);
+  aPipe->SetTolerance(aPipeLinearTolerance, aPipeLinearTolerance, aPipeAngularTolerance);
+  aPipe->SetTransition(BRepFill_TransitionStyle::BRepFill_Round);
+  aPipe->Add(myProfile, Standard_False, Standard_False);
+
+  if (aPipe->Build())
+  {
+    myErrorStatus = BRepFill_Voluved_NoLids;
+    myPipeShell = aPipe->Shape();
+  }
+}
+
+//=======================================================================
+//function : GetLids
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::GetLids()
+{
+  if (myPipeShell.IsNull())
+    return;
+
+  if (BRep_Tool::IsClosed(myProfile))
+  {
+    // No need in lids creation
+    myErrorStatus = BRepFill_Voluved_NotSolid;
+    return;
+  }
+
+  myErrorStatus = BRepFill_Voluved_NoLids;
+
+  BRepLib_FindSurface aFS(mySpine, -1.0, Standard_True);
+  const Handle(Geom_Plane) aSurf = Handle(Geom_Plane)::DownCast(aFS.Surface());
+
+  if (aSurf.IsNull())
+  {
+    myErrorStatus = BRepFill_Voluved_NotPlanarSpine;
+    return;
+  }
+
+  //Square of the default angular tolerance in
+  //BOPAlgo_Tools::EdgesToWires(...) and BOPAlgo_Tools::WiresToFaces(...) methods
+  const Standard_Real aSqAnguarTol = 1.0e-16;
+  const gp_Dir &aNormal = aSurf->Axis().Direction();
+
+  // Obtain free-edges from myPipeShell. All edges must be planar
+  // and parallel to the plane of mySpine
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMap;
+
+  TopExp::MapShapesAndAncestors(myPipeShell, TopAbs_EDGE, TopAbs_FACE, aMap);
+
+  TopTools_ListOfShape aLE;
+
+  gp_Pnt aP;
+  gp_Vec aTan;
+
+  for (Standard_Integer i = 1; i <= aMap.Size(); i++)
+  {
+    TopTools_ListOfShape& aListF = aMap(i);
+
+    if (aListF.Extent() != 1)
+      continue;
+
+    const TopoDS_Edge &anE = TopoDS::Edge(aMap.FindKey(i));
+
+    BRepAdaptor_Curve anAC(anE);
+    if (!anAC.Is3DCurve())
+    {
+      // We are not interested in degenerated edges.
+      continue;
+    }
+    
+    anAC.D1(0.5*(anAC.FirstParameter() + anAC.LastParameter()), aP, aTan);
+
+    const Standard_Real aSqModulus = aTan.SquareMagnitude();
+    if (aSqModulus < Precision::Confusion())
+      continue;
+
+    const Standard_Real aDP = aTan.XYZ().Dot(aNormal.XYZ());
+    if (aDP*aDP>aSqModulus*aSqAnguarTol)
+    {
+      //Only planar edges are considered
+      continue;
+    }
+    
+    aLE.Append(anE);
+  }
+
+  if (aLE.IsEmpty())
+  {
+    myErrorStatus = BRepFill_Voluved_NotPlanarSpine;
+    return;
+  }
+
+  // Split interfered edges
+  BOPAlgo_PaveFiller aPF;
+  aPF.SetArguments(aLE);
+  aPF.SetRunParallel(Standard_True);
+
+  aPF.Perform();
+  if (aPF.HasErrors())
+  {
+    myErrorStatus = BRepFill_Voluved_NotPlanarSpine;
+    return;
+  }
+
+  BOPAlgo_Builder aBuilder;
+  TopTools_ListIteratorOfListOfShape aItLE(aLE);
+  for (; aItLE.More(); aItLE.Next())
+  {
+    const TopoDS_Shape& aS = aItLE.Value();
+    aBuilder.AddArgument(aS);
+  }
+
+  aBuilder.SetRunParallel(Standard_True);
+  aBuilder.PerformWithFiller(aPF);
+  if (aBuilder.HasErrors())
+  {
+    myErrorStatus = BRepFill_Voluved_NotPlanarSpine;
+    return;
+  }
+
+  const TopoDS_Shape& aFreeEdges = aBuilder.Shape();
+
+  // Collect all free edges to wires and create planar 
+  // top and bottom lids from these wires.
+  BRep_Builder aBB;
+  TopoDS_Compound aCompW;
+  aBB.MakeCompound(aCompW);
+  aBB.MakeCompound(myTopBottom);
+  BOPAlgo_Tools::EdgesToWires(aFreeEdges, aCompW, Standard_True);
+  BOPAlgo_Tools::WiresToFaces(aCompW, myTopBottom);
+
+  myErrorStatus = BRepFill_Voluved_NotSolid;
+}
+
+//=======================================================================
+//function : ProcessVertex
+//purpose  : 
+//=======================================================================
+#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
+#include <BRep_TEdge.hxx>
+void ProcessVertex(const TopoDS_Vertex& aV,
+                   const TopTools_ListOfShape& aLE,
+                   const TopTools_ListOfShape& aLF)
+{
+  Standard_Real aTol, aD2, aTolMax2, aTolE, aParam;
+  gp_Pnt aPC3D;
+  gp_Pnt2d aPC2D;
+  TopAbs_Orientation anOrV;
+
+  TopTools_ListIteratorOfListOfShape anIt;
+  TopExp_Explorer aVExp;
+
+  BRep_ListIteratorOfListOfCurveRepresentation itcr;
+  //
+  aTolMax2 = -1.e6;
+  //
+  Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aV.TShape());
+  const gp_Pnt& aPV3D = TV->Pnt();
+  aTol = BRep_Tool::Tolerance(aV);
+  //
+  anIt.Initialize(aLE);
+  for (; anIt.More(); anIt.Next())
+  {
+    const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
+    //
+    Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
+    const TopLoc_Location& Eloc = aE.Location();
+    //
+    aVExp.Init(aE, TopAbs_VERTEX);
+    for (; aVExp.More(); aVExp.Next())
+    {
+      const TopoDS_Vertex& aVx = TopoDS::Vertex(aVExp.Current());
+      //
+      if (!aVx.IsSame(aV))
+      {
+        continue;
+      }
+      //
+      anOrV = aVx.Orientation();
+      if (!(anOrV == TopAbs_FORWARD || anOrV == TopAbs_REVERSED))
+      {
+        continue;
+      }
+      //
+      const BRep_ListOfCurveRepresentation& aLCR = TE->Curves();
+      itcr.Initialize(aLCR);
+      for (; itcr.More(); itcr.Next())
+      {
+        const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
+        const TopLoc_Location& loc = cr->Location();
+        TopLoc_Location L = (Eloc * loc).Predivided(aV.Location());
+        //
+        // 3D-Curve
+        if (cr->IsCurve3D())
+        {
+          const Handle(Geom_Curve)& aC3D = cr->Curve3D();
+          //
+          if (aC3D.IsNull())
+          {
+            continue;
+          }
+          // 3D-point treatment
+          aParam = BRep_Tool::Parameter(aVx, aE);
+          aPC3D = aC3D->Value(aParam);
+          aPC3D.Transform(L.Transformation());
+          aD2 = aPV3D.SquareDistance(aPC3D);
+          if (aD2 > aTolMax2)
+          {
+            aTolMax2 = aD2;
+          }
+          //
+        }//if (cr->IsCurve3D())
+        //
+        // 2D-Curve
+        else if (cr->IsCurveOnSurface())
+        {
+          const Handle(Geom2d_Curve)& aC2D = cr->PCurve();
+          if (aC2D.IsNull())
+          {
+            continue;
+          }
+          // Surface
+          const Handle(Geom_Surface)& aS = cr->Surface();
+          //
+          // 2D-point treatment
+          aParam = BRep_Tool::Parameter(aVx, aE, aS, L);
+          aPC2D = aC2D->Value(aParam);
+          aS->D0(aPC2D.X(), aPC2D.Y(), aPC3D);
+          aPC3D.Transform(L.Transformation());
+          aD2 = aPV3D.SquareDistance(aPC3D);
+          if (aD2 > aTolMax2)
+          {
+            aTolMax2 = aD2;
+          }
+        } //if (cr->IsCurveOnSurface())
+
+      }//for (; itcr.More(); itcr.Next())
+    }//for (; aVExp.More(); aVExp.Next()) 
+  }//for (; anIt.More(); anIt.Next()) 
+  //#########################################################
+  //
+  // Reducing
+  if (aTolMax2<0.)
+  {
+    return;
+  }
+  //
+  aTolMax2 = sqrt(aTolMax2);
+  if (aTolMax2>aTol)
+  {
+    return;
+  }
+  //
+  anIt.Initialize(aLE);
+  for (; anIt.More(); anIt.Next())
+  {
+    const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
+
+    aTolE = BRep_Tool::Tolerance(aE);
+    if (aTolMax2 < aTolE)
+    {
+      aTolMax2 = aTolE;
+    }
+  }
+  //
+  anIt.Initialize(aLF);
+  for (; anIt.More(); anIt.Next())
+  {
+    const TopoDS_Face& aF = TopoDS::Face(anIt.Value());
+
+    aTolE = BRep_Tool::Tolerance(aF);
+    if (aTolMax2 < aTolE)
+    {
+      aTolMax2 = aTolE;
+    }
+  }
+  //
+  if (aTolMax2>aTol)
+  {
+    return;
+  }
+  //
+  // Update Tolerance
+  TV->Tolerance(aTolMax2);
+}
+
+//=======================================================================
+//function : ReduceVertexTolerance
+//purpose  : 
+//=======================================================================
+void ReduceVertexTolerance(const TopoDS_Shape& aS)
+{
+  Standard_Integer i, aNbV;
+  TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap;
+
+  TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
+  TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap);
+
+  aNbV = aVEMap.Extent();
+  for (i = 1; i <= aNbV; i++)
+  {
+    const TopoDS_Vertex& aV = TopoDS::Vertex(aVEMap.FindKey(i));
+    const TopTools_ListOfShape& aLE = aVEMap(i);
+    const TopTools_ListOfShape& aLF = aVFMap.FindFromKey(aV);
+
+    ProcessVertex(aV, aLE, aLF);
+  }
+}
+
+
+//=======================================================================
+//function : BuildSolid
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::BuildSolid()
+{
+  if (myErrorStatus != BRepFill_Voluved_NotSolid)
+    return;
+
+  myErrorStatus = BRepFill_Voluved_NotVolume;
+
+  TopTools_MapOfShape aMapF;
+  TopTools_ListOfShape aLF, aLSplits;
+  TopExp_Explorer anExpF;
+
+  Handle(ShapeFix_Shape) aSFix = new ShapeFix_Shape;
+  aSFix->Init(myPipeShell);
+  aSFix->Perform();
+  myPipeShell = aSFix->Shape();
+
+  for (anExpF.Init(myPipeShell, TopAbs_FACE);
+       anExpF.More(); anExpF.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anExpF.Current());
+    if (!aMapF.Add(aF))
+      continue;
+
+    TopoDS_Face aFC = aF;
+    aSFix->Init(aFC);
+    aSFix->Perform();
+    aFC = TopoDS::Face(aSFix->Shape());
+    ReduceVertexTolerance(aFC);
+
+    CheckSingularityAndAdd(aFC, myFuzzyValue, aLF, aLSplits);
+  }
+  
+  {
+    TopTools_ListIteratorOfListOfShape anItrS(aLSplits);
+    for (; anItrS.More(); anItrS.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItrS.Value());
+      aLF.Append(aF);
+    }
+
+    // Split interfered faces
+    BOPAlgo_PaveFiller aPF;
+    aPF.SetArguments(aLF);
+    aPF.SetRunParallel(Standard_True);
+    aPF.SetFuzzyValue(myFuzzyValue);
+
+    aPF.Perform();
+    if (!aPF.HasErrors())
+    {
+      BOPAlgo_Builder aBuilder;
+      TopTools_ListIteratorOfListOfShape aItLE(aLF);
+      for (; aItLE.More(); aItLE.Next())
+      {
+        const TopoDS_Shape& aS = aItLE.Value();
+        aBuilder.AddArgument(aS);
+      }
+
+      aBuilder.SetRunParallel(Standard_True);
+      aBuilder.PerformWithFiller(aPF);
+      myPipeShell = aBuilder.Shape();
+    }
+  }
+
+  aLF.Clear();
+  aMapF.Clear();
+  for (anExpF.Init(myPipeShell, TopAbs_FACE);
+       anExpF.More(); anExpF.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anExpF.Current());
+    if (!aMapF.Add(aF))
+      continue;
+
+    aLF.Append(aF);
+  }
+  
+  if (!myTopBottom.IsNull())
+  {
+    TopoDS_Iterator anItLids(myTopBottom);
+    for (; anItLids.More(); anItLids.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItLids.Value());
+      aLF.Append(aF);
+    }
+  }
+  
+  BOPAlgo_MakerVolume aMV;
+  aMV.SetArguments(aLF);
+  aMV.SetFuzzyValue(myFuzzyValue);
+  aMV.SetIntersect(Standard_True);
+  aMV.SetRunParallel(Standard_True);
+  aMV.SetAvoidInternalShapes(Standard_True);
+  aMV.Perform();
+
+  if (aMV.HasErrors())
+  {
+    return;
+  }
+  
+  myResult = aMV.Shape();
+  RemoveExcessSolids(aLSplits, myResult, aLF, aMV);
+
+  myErrorStatus = BRepFill_Voluved_OK;
+}
+
+//=======================================================================
+//function : ExtractOuterSolid
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::ExtractOuterSolid(TopoDS_Shape& theShape,
+                                         TopTools_ListOfShape& theArgsList)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape aMapS;
+  TopExp::MapShapesAndAncestors(theShape, TopAbs_FACE, TopAbs_SOLID, aMapS);
+
+  Standard_Boolean hasBeenDeleted = Standard_False;
+
+  for (Standard_Integer i = 1; i <= aMapS.Extent(); i++)
+  {
+    const TopTools_ListOfShape &aL = aMapS(i);
+    if (aL.Extent() > 1)
+    {
+      // Face is shared between several solids. ==> 
+      // It cannot participate in the outer contour and should be removed.
+
+      const TopoDS_Face &aF = TopoDS::Face(aMapS.FindKey(i));
+      theArgsList.Remove(aF);
+      hasBeenDeleted = Standard_True;
+    }
+  }
+
+  if (!hasBeenDeleted)
+    return;
+
+  BOPAlgo_MakerVolume aMV;
+  aMV.SetArguments(theArgsList);
+  aMV.SetIntersect(Standard_True);
+  aMV.SetRunParallel(Standard_True);
+  aMV.SetAvoidInternalShapes(Standard_True);
+  aMV.Perform();
+
+  if (aMV.HasErrors())
+  {
+    return;
+  }
+
+  theShape = aMV.Shape();
+}
+
+//=======================================================================
+//function : RemoveExcessSolids
+//purpose  : 
+//=======================================================================
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+void BRepFill_Voluved::RemoveExcessSolids(const TopTools_ListOfShape& /*theLSplits*/,
+                                          TopoDS_Shape& theShape,
+                                          TopTools_ListOfShape& /*theArgsList*/,
+                                          BOPAlgo_MakerVolume& /*theMV*/)
+{
+  if (myErrorStatus != BRepFill_Voluved_NotVolume)
+    return;
+  
+#if 1
+  TopExp_Explorer anExpSo(theShape, TopAbs_SOLID);
+  Standard_Real aMaxVol = RealFirst();
+  myResult = anExpSo.Current();
+  for(;anExpSo.More(); anExpSo.Next())
+  {
+    const TopoDS_Solid &aSol = TopoDS::Solid(anExpSo.Current());
+    GProp_GProps aGprop;
+    BRepGProp::VolumeProperties(aSol, aGprop, 1.0e-4);
+    const Standard_Real aV = aGprop.Mass();
+
+    if(aV > aMaxVol)
+    {
+      aMaxVol = aV;
+      myResult = aSol;
+    }
+  }
+#else
+
+  TopExp_Explorer anExpSo;
+  for (Standard_Integer i = 0; i < 2; i++)
+  {
+    anExpSo.Init(theShape, TopAbs_SOLID);
+    if (!anExpSo.More())
+    {
+      myResult = theShape;
+      return;
+    }
+
+    anExpSo.Next();
+    if (!anExpSo.More())
+    {
+      // Only one solid has been generated
+      myResult = TopoDS::Solid(anExpSo.Current());
+      return;
+    }
+
+    if (i != 0)
+      break;
+
+    ExtractOuterSolid(theShape, theArgsList);
+  }
+
+  // Remove Split faces from the list of arguments
+  TopTools_ListIteratorOfListOfShape anItl(theLSplits);
+  for (; anItl.More(); anItl.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anItl.Value());
+    theArgsList.Remove(aF);
+  }
+
+  // Create a list of invalid faces. The face is invalid if
+  // BOPAlgo_MakerVolume changes its orientation while creating solids.
+  // Faces from theLSplits are not checked.
+  TopTools_ListOfShape aListInvFaces;
+  for (anItl.Init(theArgsList); anItl.More(); anItl.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anItl.Value());
+    for (TopTools_ListIteratorOfListOfShape anItM(theMV.Modified(aF));
+         anItM.More(); anItM.Next())
+    {
+      const TopoDS_Face &aFM = TopoDS::Face(anItM.Value());
+
+      if (aFM.Orientation() != aF.Orientation())
+        aListInvFaces.Append(aFM);
+    }
+  }
+
+  TopTools_ListOfShape aSolidList;
+  for (anExpSo.Init(theShape, TopAbs_SOLID); anExpSo.More(); anExpSo.Next())
+  {
+    const TopoDS_Solid &aSo = TopoDS::Solid(anExpSo.Current());
+    TopTools_IndexedMapOfShape aMapF;
+    TopExp::MapShapes(aSo, TopAbs_FACE, aMapF);
+    Standard_Boolean isToDelete = Standard_False;
+
+    for (anItl.Init(aListInvFaces); anItl.More(); anItl.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItl.Value());
+      if (aMapF.Contains(aF))
+      {
+        isToDelete = Standard_True;
+        break;
+      }
+    }
+
+    if (isToDelete)
+    {
+      continue;
+    }
+    
+    for (anItl.Init(theArgsList); anItl.More(); anItl.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItl.Value());
+      const Standard_Integer anIdx = aMapF.FindIndex(aF);
+      if (anIdx == 0)
+        continue;
+
+      const TopoDS_Face &aF1 = TopoDS::Face(aMapF.FindKey(anIdx));
+
+      // aF and aF1 are same shapes. Check if they are equal.
+
+      if (!aF.IsEqual(aF1))
+      {
+        isToDelete = Standard_True;
+        break;
+      }
+    }
+
+    if (isToDelete)
+    {
+      continue;
+    }
+
+    aSolidList.Append(aSo);
+  }
+
+  if (aSolidList.Extent() < 1)
+  {
+    myResult = theShape;
+    return;
+  }
+
+  if (aSolidList.Extent() == 1)
+  {
+    myResult = aSolidList.First();
+    return;
+  }
+
+  BRep_Builder aBB;
+  TopoDS_Compound aCmpSol;
+  aBB.MakeCompound(aCmpSol);
+
+  for (anItl.Init(aSolidList); anItl.More(); anItl.Next())
+  {
+    const TopoDS_Solid &aSo = TopoDS::Solid(anItl.Value());
+    aBB.Add(aCmpSol, aSo);
+  }
+
+  myResult = aCmpSol;
+#endif
+}
+
+//=======================================================================
+//class : NormalFunc
+//purpose  : 
+//=======================================================================
+class NormalFunc : public math_MultipleVarFunctionWithHessian
+{
+public:
+  NormalFunc(const Adaptor3d_CurveOnSurface& theCOS) :myCOnS(theCOS)
+  {
+  }
+
+  virtual Standard_Integer NbVariables() const Standard_OVERRIDE
+  {
+    return 1;
+  }
+
+
+  virtual Standard_Boolean Value(const math_Vector& X, Standard_Real& F) Standard_OVERRIDE;
+  virtual Standard_Boolean Gradient(const math_Vector& X, math_Vector& G) Standard_OVERRIDE;
+  virtual Standard_Boolean Values(const math_Vector& theX,
+                                  Standard_Real& theF,
+                                  math_Vector& theG) Standard_OVERRIDE
+  {
+    if (!Value(theX, theF))
+    return Standard_False;
+
+    if (!Gradient(theX, theG))
+      return Standard_False;
+
+    return Standard_True;
+  };
+
+  virtual Standard_Boolean Values(const math_Vector& theX,
+                                  Standard_Real& theF,
+                                  math_Vector& theG,
+                                  math_Matrix& theH) Standard_OVERRIDE
+  {
+    if (!Values(theX, theF, theG))
+    return Standard_False;
+
+    theH(1, 1) = theG(1);
+    return Standard_True;
+  };
+
+  Standard_Real FirstParameter() const
+  {
+    return myCOnS.FirstParameter();
+  }
+
+  Standard_Real LastParameter() const
+  {
+    return myCOnS.LastParameter();
+  }
+
+  gp_Pnt GetPoint(const Standard_Real theX)
+  {
+    const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve();
+    const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface();
+    const gp_Pnt2d aP2d(aC->Value(theX));
+    return aS->Value(aP2d.X(), aP2d.Y());
+  }
+
+protected:
+
+  NormalFunc& operator=(NormalFunc&);
+
+private:
+  const Adaptor3d_CurveOnSurface& myCOnS;
+};
+
+//=======================================================================
+//function : Value
+//purpose  : +aD1v_x^2*aD1u_y^2 + aD1v_x^2*aD1u_z^2 +
+//           +aD1v_y^2*aD1u_z^2 + aD1u_x^2*aD1v_y^2 + 
+//           +aD1u_x^2*aD1v_z^2 + aD1u_y^2*aD1v_z^2 -
+//           -  2*(+aD1u_x*aD1v_x*aD1u_y*aD1v_y + 
+//                 +aD1u_x*aD1v_x*aD1u_z*aD1v_z +
+//                 +aD1u_y*aD1v_y*aD1u_z*aD1v_z)
+//=======================================================================
+Standard_Boolean NormalFunc::Value(const math_Vector& theX, Standard_Real& theF)
+{
+  const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve();
+  const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface();
+
+  const gp_Pnt2d aP2d(aC->Value(theX(1)));
+  gp_Pnt aP3d;
+  gp_Vec aD1u, aD1v;
+  aS->D1(aP2d.X(), aP2d.Y(), aP3d, aD1u, aD1v);
+
+  theF = aD1u.Crossed(aD1v).SquareMagnitude();
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Gradient
+//purpose  :
+//2 * ((aD1v_x*aD1u_y)*(aD1u_y*(aD2uv_x*aDc_x + aD2v_x*aDc_y) + aD1v_x*(aD2u_y*aDc_x + aD2uv_y*aDc_y)) +
+//     (aD1v_x*aD1u_z)*(aD1u_z*(aD2uv_x*aDc_x + aD2v_x*aDc_y) + aD1v_x*(aD2u_z*aDc_x + aD2uv_z*aDc_y)) +
+//     (aD1v_y*aD1u_z)*(aD1u_z*(aD2uv_y*aDc_x + aD2v_y*aDc_y) + aD1v_y*(aD2u_z*aDc_x + aD2uv_z*aDc_y)) +
+//     (aD1u_x*aD1v_y)*(aD1u_x*(aD2uv_y*aDc_x + aD2v_y*aDc_y) + aD1v_y*(aD2u_x*aDc_x + aD2uv_x*aDc_y)) +
+//     (aD1u_x*aD1v_z)*(aD1u_x*(aD2uv_z*aDc_x + aD2v_z*aDc_y) + aD1v_z*(aD2u_x*aDc_x + aD2uv_x*aDc_y)) +
+//     (aD1u_y*aD1v_z)*(aD1u_y*(aD2uv_z*aDc_x + aD2v_z*aDc_y) + aD1v_z*(aD2u_y*aDc_x + aD2uv_y*aDc_y)) -
+//
+//     (aD2u_x*aDc_x + aD2uv_x*aDc_y)*aD1v_x*aD1u_y*aD1v_y -
+//     aD1u_x*(aD2uv_x*aDc_x + aD2v_x*aDc_y)*aD1u_y*aD1v_y -
+//     aD1u_x*aD1v_x*(aD2u_y*aDc_x + aD2uv_y*aDc_y)*aD1v_y -
+//     aD1u_x*aD1v_x*aD1u_y*(aD2uv_y*aDc_x + aD2v_y*aDc_y) -
+//
+//     (aD2u_x*aDc_x + aD2uv_x*aDc_y)*aD1v_x*aD1u_z*aD1v_z -
+//     aD1u_x*(aD2uv_x*aDc_x + aD2v_x*aDc_y)*aD1u_z*aD1v_z -
+//     aD1u_x*aD1v_x*(aD2u_z*aDc_x + aD2uv_z*aDc_y)*aD1v_z -
+//     aD1u_x*aD1v_x*aD1u_z*(aD2uv_z*aDc_x + aD2v_z*aDc_y) -
+//
+//     (aD2u_y*aDc_x + aD2uv_y*aDc_y)*aD1v_y*aD1u_z*aD1v_z -
+//     aD1u_y*(aD2uv_y*aDc_x + aD2v_y*aDc_y)*aD1u_z*aD1v_z -
+//     aD1u_y*aD1v_y*(aD2u_z*aDc_x + aD2uv_z*aDc_y)*aD1v_z -
+//     aD1u_y*aD1v_y*aD1u_z*(aD2uv_z*aDc_x + aD2v_z*aDc_y))
+//=======================================================================
+Standard_Boolean NormalFunc::Gradient(const math_Vector& theX, math_Vector& theG)
+{
+  const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve();
+  const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface();
+
+  gp_Pnt2d aP2d;
+  gp_Vec2d aDc;
+  aC->D1(theX(1), aP2d, aDc);
+
+  gp_Pnt aP3d;
+  gp_Vec aD1u, aD1v, aD2u, aD2v, aD2uv;
+  aS->D2(aP2d.X(), aP2d.Y(), aP3d, aD1u, aD1v, aD2u, aD2v, aD2uv);
+
+  theG(1) = (aD1v.X()*aD1u.Y())*(aD1u.Y()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y()) +
+            aD1v.X()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())) + 
+            (aD1v.X()*aD1u.Z())*(aD1u.Z()*(aD2uv.X()*aDc.X() + 
+            aD2v.X()*aDc.Y()) + aD1v.X()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())) +
+            (aD1v.Y()*aD1u.Z())*(aD1u.Z()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) + 
+            aD1v.Y()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())) + (aD1u.X()*aD1v.Y())*
+            (aD1u.X()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) + aD1v.Y()*(aD2u.X()*
+            aDc.X() + aD2uv.X()*aDc.Y())) + (aD1u.X()*aD1v.Z())*(aD1u.X()*(aD2uv.Z()*
+            aDc.X() + aD2v.Z()*aDc.Y()) + aD1v.Z()*(aD2u.X()*aDc.X() + 
+            aD2uv.X()*aDc.Y())) + (aD1u.Y()*aD1v.Z())*(aD1u.Y()*(aD2uv.Z()*aDc.X() + 
+            aD2v.Z()*aDc.Y()) + aD1v.Z()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())) -
+            (aD2u.X()*aDc.X() + aD2uv.X()*aDc.Y())*aD1v.X()*aD1u.Y()*aD1v.Y() - 
+            aD1u.X()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y())*aD1u.Y()*aD1v.Y() -
+            aD1u.X()*aD1v.X()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())*aD1v.Y() - 
+            aD1u.X()*aD1v.X()*aD1u.Y()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) - 
+            (aD2u.X()*aDc.X() + aD2uv.X()*aDc.Y())*aD1v.X()*aD1u.Z()*aD1v.Z() - 
+            aD1u.X()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y())*aD1u.Z()*aD1v.Z() - 
+            aD1u.X()*aD1v.X()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())*aD1v.Z() - 
+            aD1u.X()*aD1v.X()*aD1u.Z()*(aD2uv.Z()*aDc.X() + aD2v.Z()*aDc.Y()) - 
+            (aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())*aD1v.Y()*aD1u.Z()*aD1v.Z() - 
+            aD1u.Y()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y())*aD1u.Z()*aD1v.Z() - 
+            aD1u.Y()*aD1v.Y()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())*aD1v.Z() -
+            aD1u.Y()*aD1v.Y()*aD1u.Z()*(aD2uv.Z()*aDc.X() + aD2v.Z()*aDc.Y());
+
+  return Standard_True;
+}
+
+//=======================================================================
+//structure : EInfoTosplit
+//purpose  : 
+//=======================================================================
+struct EInfoTosplit
+{
+  TopoDS_Edge myEdge;
+  TopoDS_Vertex myVertexToSplit;
+  Standard_Real myParam;
+  Standard_Real myTolerance;
+};
+
+//=======================================================================
+//function : RebuildFaces
+//purpose  : Creates a wires from theEdges and puts it to the new face
+//            which is empty-copied from theSourceFace.
+//=======================================================================
+static void RebuildFaces(const TopTools_ListOfShape& theLE,
+                         const TopoDS_Face& theSourceFace,
+                         TopTools_ListOfShape& theList)
+{
+  //build new faces
+  BOPAlgo_BuilderFace aBF;
+
+  TopoDS_Face aF = TopoDS::Face(theSourceFace.Oriented(TopAbs_FORWARD));
+
+  aBF.SetFace(aF);
+  aBF.SetShapes(theLE);
+
+  aBF.Perform();
+
+  const TopTools_ListOfShape& aLFR = aBF.Areas();
+
+  if (aLFR.IsEmpty())
+  {
+    theList.Append(theSourceFace);
+    return;
+  }
+
+  TopTools_ListIteratorOfListOfShape aItFR(aLFR);
+  for (; aItFR.More(); aItFR.Next())
+  {
+    const TopoDS_Shape& aFR = TopoDS::Face(aItFR.Value());
+    theList.Append(aFR);
+  }
+}
+
+//=======================================================================
+//function : MakeEdgeDegenerated
+//purpose  : Returns TRUE if degenerated edge has been created.
+//           Every degenerated edge (to split) must be added in theLEdges twice
+//           with different orientations. Moreover, Degenerated edges cannot be shared.
+//           Therefore, make copy of them before adding.
+//=======================================================================
+static Standard_Boolean MakeEdgeDegenerated(const TopoDS_Vertex& theV,
+                                            const TopoDS_Face& theFace,
+                                            const gp_Pnt2d& thePf,
+                                            const gp_Pnt2d& thePl,
+                                            TopTools_ListOfShape& theLEdges)
+{
+  BRepAdaptor_Surface anAS(theFace, Standard_False);
+
+  const Standard_Real aTol = 2.0*BRep_Tool::Tolerance(theV);
+  const Standard_Real aTolU = anAS.UResolution(aTol),
+                      aTolV = anAS.VResolution(aTol);
+
+  if ((Abs(thePf.X() - thePl.X()) < aTolU) && (Abs(thePf.Y() - thePl.Y()) < aTolV))
+    return Standard_False;
+
+  const TopoDS_Vertex aVf = TopoDS::Vertex(theV.Oriented(TopAbs_FORWARD)),
+                      aVl = TopoDS::Vertex(theV.Oriented(TopAbs_REVERSED));
+  
+  const gp_XY aV = thePl.XY() - thePf.XY();
+  const Handle(Geom2d_Line) aL1 = new Geom2d_Line(thePf, gp_Dir2d(aV));
+  const Handle(Geom2d_Line) aL2 = new Geom2d_Line(thePl, gp_Dir2d(aV.Reversed()));
+
+  BRep_Builder aBB;
+  TopoDS_Edge anEdegen1, anEdegen2;
+  aBB.MakeEdge(anEdegen1);
+  aBB.MakeEdge(anEdegen2);
+
+  aBB.UpdateEdge(anEdegen1, aL1, theFace, Precision::Confusion());
+  aBB.UpdateEdge(anEdegen2, aL2, theFace, Precision::Confusion());
+
+  anEdegen1.Orientation(TopAbs_FORWARD);
+  anEdegen2.Orientation(TopAbs_FORWARD);
+
+  aBB.Add(anEdegen1, aVf);
+  aBB.Add(anEdegen1, aVl);
+  aBB.Add(anEdegen2, aVf);
+  aBB.Add(anEdegen2, aVl);
+
+  aBB.Degenerated(anEdegen1, Standard_True);
+  aBB.Degenerated(anEdegen2, Standard_True);
+
+  const Standard_Real aLPar = aV.Modulus();
+  aBB.Range(anEdegen1, 0.0, aLPar);
+  aBB.Range(anEdegen2, 0.0, aLPar);
+
+  theLEdges.Append(anEdegen1);
+  theLEdges.Append(anEdegen2);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : InsertEDegenerated
+//purpose  : 
+//=======================================================================
+static void InsertEDegenerated(const TopoDS_Face& theFace,
+                               TopTools_ListOfShape& theLEdges)
+{
+  BRep_Builder aBB;
+  TopoDS_Wire aWir;
+  aBB.MakeWire(aWir);
+
+  TopTools_ListIteratorOfListOfShape anItr(theLEdges);
+  for (; anItr.More(); anItr.Next())
+  {
+    const TopoDS_Edge &anE = TopoDS::Edge(anItr.Value());
+    aBB.Add(aWir, anE);
+  }
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
+  TopExp::MapShapesAndUniqueAncestors(aWir, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
+
+  BRepTools_WireExplorer anExp(aWir, theFace);
+
+  TopoDS_Edge anE1 = anExp.Current(), aFirstEdge, aLastEdge;
+
+  if (anE1.IsNull())
+  {
+    // It is possible if aWir contains
+    // only INTERNAL/EXTERNAL edges.
+
+    return;
+  }
+
+  aFirstEdge = anE1;
+  anExp.Next();
+
+# if 0
+  if (!anExp.More())
+  {
+    // The wire contains only single edge.
+    // But this edge can be closed itself (e.g. circle).
+
+    TopoDS_Vertex aVf, aVl;
+    TopExp::Vertices(anE1, aVf, aVl);
+    if (!aVf.IsNull() && aVf.IsSame(aVl))
+    {
+      Standard_Real aF, aL;
+      const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(anE1, theFace, aF, aL);
+      aF = BRep_Tool::Parameter(aVf, anE1);
+      aL = BRep_Tool::Parameter(aVl, anE1);
+      const gp_Pnt2d aPf(aC->Value(aF)), aPl(aC->Value(aL));
+
+      MakeEdgeDegenerated(aVf, theFace, aPf, aPl, theLEdges);
+    }
+
+    return;
+  }
+#endif
+
+  // Map containing all vertices of degenerated edges
+  TopTools_MapOfShape aMapVofDE;
+
+  {
+    TopExp_Explorer anExpDE(aWir, TopAbs_EDGE);
+    for (; anExpDE.More(); anExpDE.Next())
+    {
+      const TopoDS_Edge &anE = TopoDS::Edge(anExpDE.Current());
+      if (!BRep_Tool::Degenerated(anE))
+        continue;
+
+      TopoDS_Vertex aV1, aV2;
+      TopExp::Vertices(anE, aV1, aV2);
+
+      // aV1 and aV2 are SAME vertices
+
+      aMapVofDE.Add(aV1);
+    }
+  }
+
+  for (; anExp.More(); anExp.Next())
+  {
+    const TopoDS_Edge& anE2 = anExp.Current();
+    aLastEdge = anE2;
+#if 0
+    if (anE1.IsSame(anE2))
+    {
+      //Exclude a gap between two seam-edges (e.g. cylinder without roofs).
+      anE1 = anE2;
+      continue;
+    }
+#endif
+
+    const TopoDS_Vertex &aVertCurr = anExp.CurrentVertex();
+
+    if (aMapVofDE.Contains(aVertCurr))
+    {
+      // Necessary degenerated edge has already been created.
+      anE1 = anE2;
+      continue;
+    }
+
+    Standard_Real aF, aL;
+    const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(anE1, theFace, aF, aL),
+                               aC2 = BRep_Tool::CurveOnSurface(anE2, theFace, aF, aL);
+    aF = BRep_Tool::Parameter(aVertCurr, anE1);
+    aL = BRep_Tool::Parameter(aVertCurr, anE2);
+    const gp_Pnt2d aPf(aC1->Value(aF)), aPl(aC2->Value(aL));
+
+    if (MakeEdgeDegenerated(aVertCurr, theFace, aPf, aPl, theLEdges))
+    {
+      aMapVofDE.Add(aVertCurr);
+      anE1 = anE2;
+      continue;
+    }
+
+    const TopTools_ListOfShape *anEList = aMapVE.Seek(aVertCurr);
+    if ((anEList != 0) && (anEList->Extent() <= 2))
+    {
+      anE1 = anE2;
+      continue;
+    }
+
+    // Case like cone with apex. In 2D space all is OK
+    // (therefore BRepTools_WireExplorer processes this case
+    // correctly). But in 3D-space, we have several edges with
+    // the same vertex. Cone apex must be plugged by degenerated edge.
+
+    Standard_Boolean hasDegenerated = Standard_False;
+    TopTools_ListIteratorOfListOfShape anItr(*anEList);
+    for (; anItr.More(); anItr.Next())
+    {
+      const TopoDS_Edge &anEdge = TopoDS::Edge(anItr.Value());
+      if (BRep_Tool::Degenerated(anEdge))
+      {
+        hasDegenerated = Standard_True;
+        break;
+      }
+    }
+
+    if (hasDegenerated)
+    {
+      anE1 = anE2;
+      continue;
+    }
+
+    // Look for the pair for anE1 and anE2 edges
+    for (Standard_Integer i = 0; i < 2; i++)
+    {
+      const gp_Pnt2d &aPoint = i ? aPl : aPf;
+      anItr.Initialize(*anEList);
+      for (; anItr.More(); anItr.Next())
+      {
+        const TopoDS_Edge &anEdge = TopoDS::Edge(anItr.Value());
+
+        if (anEdge.IsSame(anE1) || anEdge.IsSame(anE2))
+          continue;
+
+        const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(anEdge, theFace, aF, aL);
+        aF = BRep_Tool::Parameter(aVertCurr, anEdge);
+        const gp_Pnt2d aP(aC->Value(aF));
+
+        if (MakeEdgeDegenerated(aVertCurr, theFace, aPoint, aP, theLEdges))
+        {
+          aMapVofDE.Add(aVertCurr);
+          i = 2;
+          break;
+        }
+      }
+    }
+    
+    anE1 = anE2;
+  }
+
+  if (aFirstEdge.IsNull() || aLastEdge.IsNull())
+    return;
+
+#if 0
+  if (aFirstEdge.IsSame(aLastEdge))
+  {
+    //Exclude a gap between two seam-edges (e.g. cylinder without bottom-base).
+
+    return;
+  }
+#endif
+
+  //TopExp::CommonVertex(...) does not work
+  //if edges have more than one pair of common vertex
+  //(e.g. two halves of circle). Here, we process this case.
+  TopoDS_Vertex aV[4];
+  TopExp::Vertices(aFirstEdge, aV[0], aV[1]);
+  if (!aV[0].IsNull() && aV[0].IsSame(aV[1]))
+  {
+    // Possible reason is the NOT-CLOSED edge
+    // has only single vertex and is covered by it.
+    return;
+  }
+
+  TopExp::Vertices(aLastEdge, aV[2], aV[3]);
+  if (!aV[2].IsNull() && aV[2].IsSame(aV[3]))
+  {
+    // Possible reason is the NOT-CLOSED edge
+    // has only single vertex and is covered by it.
+    return;
+  }
+
+  for (Standard_Integer anIDFE = 0; anIDFE < 2; anIDFE++)
+  {
+    for (Standard_Integer anIDLE = 2; anIDLE < 4; anIDLE++)
+    {
+      if (!aV[anIDFE].IsSame(aV[anIDLE]))
+        continue;
+
+      const NCollection_List<TopoDS_Shape> *anEList = aMapVE.Seek(aV[anIDFE]);
+      if ((anEList != 0) && (anEList->Extent() > 2))
+      {
+        // Causes:
+        //  1. Non-manifold topology.
+        //  2. Case such as:
+        //
+        //        *************************
+        //        *                       *
+        //  seam  *                       *  seam
+        //        *  edge1         edge2  *
+        //        * ********    ********* *
+        //       V1        V2   V3       V4
+        //
+        //
+        //  V1 - vertex between edge1 and seam
+        //  V4 - vertex between edge2 and seam
+        //
+        //  Indeed, V1 and V4 are same but they
+        //  must not be joined.
+
+        continue;
+      }
+
+      Standard_Real aF, aL;
+      const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(aFirstEdge, theFace, aF, aL),
+                                 aC2 = BRep_Tool::CurveOnSurface(aLastEdge, theFace, aF, aL);
+      aF = BRep_Tool::Parameter(aV[anIDFE], aFirstEdge);
+      aL = BRep_Tool::Parameter(aV[anIDLE], aLastEdge);
+      const gp_Pnt2d aPf(aC1->Value(aF)), aPl(aC2->Value(aL));
+
+      MakeEdgeDegenerated(aV[anIDFE], theFace, aPf, aPl, theLEdges);
+    }
+  }
+}
+
+//=======================================================================
+//function : CheckSingularityAndAdd
+//purpose  : Returns TRUE if theF has been split
+//=======================================================================
+Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF,
+                                        const Standard_Real theFuzzyToler,
+                                        TopTools_ListOfShape& theListOfFaces,
+                                        TopTools_ListOfShape& theListOfSplits)
+{
+  const BRepAdaptor_Surface anAS(theF, Standard_False);
+  GeomAbs_SurfaceType aSType = anAS.GetType();
+
+  if (aSType == GeomAbs_OffsetSurface)
+  {
+    aSType = anAS.BasisSurface()->GetType();
+  }
+
+  if (aSType == GeomAbs_Plane)
+  {
+    TopTools_MapOfShape aME;
+    TopTools_ListOfShape aLE;
+    TopExp_Explorer anExp(theF, TopAbs_EDGE);
+    for (; anExp.More(); anExp.Next())
+    {
+      const TopoDS_Edge &anE = TopoDS::Edge(anExp.Current());
+
+      if (aME.Add(anE))
+        aLE.Append(anE);
+    }
+
+    // Split interfered edges
+    BOPAlgo_PaveFiller aPF;
+    aPF.SetArguments(aLE);
+    aPF.SetRunParallel(Standard_True);
+
+    aPF.Perform();
+    if (aPF.HasErrors())
+    {
+      theListOfFaces.Append(theF);
+      return Standard_False;
+    }
+
+    const BOPDS_DS &aDS = aPF.DS();
+    if (aDS.NbShapes() == aDS.NbSourceShapes())
+    {
+      //Interfered edges have not been detected
+      theListOfFaces.Append(theF);
+      return Standard_False;
+    }
+
+    BOPAlgo_Builder aBuilder;
+    TopTools_ListIteratorOfListOfShape aItLE(aLE);
+    for (; aItLE.More(); aItLE.Next())
+    {
+      const TopoDS_Shape& aS = aItLE.Value();
+      aBuilder.AddArgument(aS);
+    }
+
+    aBuilder.SetRunParallel(Standard_True);
+    aBuilder.PerformWithFiller(aPF);
+    if (aBuilder.HasErrors())
+    {
+      theListOfFaces.Append(theF);
+      return Standard_False;
+    }
+
+    const TopoDS_Shape& anEdges = aBuilder.Shape();
+
+    BRep_Builder aBB;
+    TopoDS_Compound aCompW, aCompF;
+    aBB.MakeCompound(aCompW);
+    aBB.MakeCompound(aCompF);
+    BOPAlgo_Tools::EdgesToWires(anEdges, aCompW, Standard_True);
+    BOPAlgo_Tools::WiresToFaces(aCompW, aCompF);
+
+    aME.Clear();
+    anExp.Init(aCompF, TopAbs_FACE);
+    for (; anExp.More(); anExp.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anExp.Current());
+      theListOfSplits.Append(aF);
+    }
+
+    return Standard_True;
+  }
+
+  if ((aSType != GeomAbs_Cone) && 
+      (aSType != GeomAbs_Sphere) && 
+      (aSType != GeomAbs_BezierSurface) &&
+      (aSType != GeomAbs_BSplineSurface) &&
+      (aSType != GeomAbs_SurfaceOfRevolution))
+  {
+    theListOfFaces.Append(theF);
+    return Standard_False;
+  }
+
+  BRep_Builder aBB;
+
+  TopoDS_Compound aCWires;
+  aBB.MakeCompound(aCWires);
+
+  Standard_Boolean isSplit = Standard_False;
+  TopTools_ListOfShape aListEdges;
+
+  const TopoDS_Face aF = TopoDS::Face(theF.Oriented(TopAbs_FORWARD));
+
+  for (TopoDS_Iterator anExpW(aF); anExpW.More(); anExpW.Next())
+  {
+    const TopoDS_Wire &aWir = TopoDS::Wire(anExpW.Value());
+
+    TopTools_ListOfShape aLGF;
+    TopExp_Explorer anEExp(aWir, TopAbs_EDGE);
+    for (; anEExp.More(); anEExp.Next())
+    {
+      const TopoDS_Edge &anE = TopoDS::Edge(anEExp.Current());
+      aLGF.Append(anE);
+    }
+
+    BOPAlgo_PaveFiller aPF;
+    aPF.SetArguments(aLGF);
+    aPF.SetFuzzyValue(theFuzzyToler);
+    aPF.Perform();
+
+    if (aPF.HasErrors())
+    {
+      continue;
+    }
+
+    const BOPDS_DS &aDS = aPF.DS();
+    if (aDS.NbShapes() == aDS.NbSourceShapes())
+    {
+      //No new shapes have been created  
+      continue;
+    }
+
+    BOPAlgo_Builder aBAB(NCollection_BaseAllocator::CommonBaseAllocator());
+    TopTools_ListIteratorOfListOfShape aBItr(aLGF);
+    for (; aBItr.More(); aBItr.Next())
+    {
+      const TopoDS_Shape &aSh = aBItr.Value();
+      aBAB.AddArgument(aSh);
+    }
+
+    aBAB.SetRunParallel(Standard_True);
+    aBAB.SetNonDestructive(Standard_True);
+    aBAB.PerformWithFiller(aPF);
+    if (aBAB.HasErrors())
+    {
+      continue;
+    }
+
+    TopTools_ListOfShape aLE;
+#if 0
+    // This fragment requires fixing the issue #29656
+    TopTools_MapOfShape aMM;
+    TopExp_Explorer anExpEB(aBAB.Shape(), TopAbs_EDGE);
+    for (; anExpEB.More(); anExpEB.Next())
+    {
+      const TopoDS_Edge anEE = TopoDS::Edge(anExpEB.Current());
+      if (!aMM.Add(anEE))
+        continue;
+
+      aLE.Append(anEE);
+    }
+#else
+    for (aBItr.Init(aLGF); aBItr.More(); aBItr.Next())
+    {
+      const TopoDS_Edge &aSh = TopoDS::Edge(aBItr.Value());
+      const TopTools_ListOfShape &aLM = aBAB.Modified(aSh);
+      if (aLM.IsEmpty() || BRep_Tool::Degenerated(aSh))
+      {
+        aLE.Append(aSh);
+        continue;
+      }
+
+      TopTools_ListIteratorOfListOfShape anItLM(aLM);
+      for (; anItLM.More(); anItLM.Next())
+      {
+        const TopoDS_Edge &anEM = TopoDS::Edge(anItLM.Value());
+        aLE.Append(anEM);
+      }
+    }
+#endif
+
+    isSplit = Standard_True;
+    InsertEDegenerated(aF, aLE);
+    aListEdges.Append(aLE);
+  }
+
+  if (!isSplit)
+  {
+    theListOfFaces.Append(theF);
+    return Standard_False;
+  }
+
+  RebuildFaces(aListEdges, theF, theListOfSplits);
+
+  TopTools_ListIteratorOfListOfShape anItrS(theListOfSplits);
+  for (; anItrS.More(); anItrS.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anItrS.Value());
+    theListOfFaces.Append(aF.Oriented(theF.Orientation()));
+  }
+
+  return Standard_True;
+}
diff --git a/src/BRepFill/BRepFill_Voluved.hxx b/src/BRepFill/BRepFill_Voluved.hxx
new file mode 100644 (file)
index 0000000..5675cc9
--- /dev/null
@@ -0,0 +1,106 @@
+// Created on: 2018-03-14
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepFill_Voluved_HeaderFile
+#define _BRepFill_Voluved_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+class BOPAlgo_MakerVolume;
+
+//! Constructs an evolved volume from a spine (wire or face)
+//! and  a profile ( wire).
+class BRepFill_Voluved 
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  Standard_EXPORT BRepFill_Voluved() :myErrorStatus(BRepFill_Voluved_Empty),
+                                      myFuzzyValue(0.0)
+  {
+  }
+  
+  Standard_EXPORT void Perform(const TopoDS_Wire& theSpine, const TopoDS_Wire& theProfile, const Standard_Real theTolerance, const Standard_Boolean theSolidReq = Standard_True);
+  
+  Standard_Boolean IsDone(unsigned int* theErrorCode = 0) const
+  {
+    if (theErrorCode)
+      *theErrorCode = myErrorStatus;
+
+    return (myErrorStatus == BRepFill_Voluved_OK);
+  }
+
+  //! returns the resulting shape.
+  const TopoDS_Shape& Shape() const
+  {
+    return myResult;
+  }
+  
+protected:
+
+  Standard_EXPORT void PerformSweep();
+
+  Standard_EXPORT void GetLids();
+
+  Standard_EXPORT void BuildSolid();
+
+  Standard_EXPORT void RemoveExcessSolids(const TopTools_ListOfShape& theLSplits,
+                                          TopoDS_Shape& theShape,
+                                          TopTools_ListOfShape& theArgsList,
+                                          BOPAlgo_MakerVolume& theMV);
+
+  Standard_EXPORT void ExtractOuterSolid(TopoDS_Shape& theShape,
+                                         TopTools_ListOfShape& theArgsList);
+
+  Standard_EXPORT void GetSpineAndProfile(const TopoDS_Wire& theSpine,
+                                          const TopoDS_Wire& theProfile);
+
+private:
+
+  enum
+  {
+    BRepFill_Voluved_Empty = 0,
+    BRepFill_Voluved_NotPlanarSpine,
+    BRepFill_Voluved_SweepError,
+    BRepFill_Voluved_NoLids,
+    BRepFill_Voluved_NotSolid,
+    BRepFill_Voluved_NotVolume,
+    BRepFill_Voluved_OK = UINT_MAX
+  } myErrorStatus;
+
+  TopoDS_Wire mySpine;
+  TopoDS_Wire myProfile;
+  TopoDS_Shape myPipeShell;
+  TopoDS_Compound myTopBottom; // Lids can be split on several faces
+  TopoDS_Shape myResult;
+  Standard_Real myFuzzyValue;
+
+
+};
+
+
+
+
+
+
+
+#endif // _BRepFill_Voluved_HeaderFile
index ebba998dd6a5d2ff96ff91ed859b055f260f57ee..e0a9ded7a098a94c42b2823afa25b6c5539a2510 100644 (file)
@@ -83,3 +83,5 @@ BRepFill_TrimShellCorner.hxx
 BRepFill_TrimSurfaceTool.cxx
 BRepFill_TrimSurfaceTool.hxx
 BRepFill_TypeOfContact.hxx
+BRepFill_Voluved.cxx
+BRepFill_Voluved.hxx
\ No newline at end of file
index 10310e689d31882af937f9f92856b6d6133829d4..88f20c46da630728bb3397e23778cd7822b606f0 100644 (file)
@@ -22,6 +22,8 @@
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS.hxx>
 
 //=======================================================================
 //function : BRepOffsetAPI_MakeEvolved
@@ -43,19 +45,29 @@ BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Wire&     Spin
                                         const Standard_Boolean AxeProf,
                                         const Standard_Boolean Solid,
                                         const Standard_Boolean ProfOnSpine,
-                                        const Standard_Real    Tol)
+                                         const Standard_Boolean theIsVolume,
+                                         const Standard_Real    Tol)
 {
-  gp_Ax3 Axis(gp_Pnt(0.,0.,0.),
-             gp_Dir(0.,0.,1.),
-             gp_Dir(1.,0.,0.));
-
-  if ( !AxeProf) {
-    Standard_Boolean POS;
-    BRepFill::Axe(Spine,Profil,Axis,POS,Tol);
-    if (ProfOnSpine && !POS) return;
+  if (theIsVolume)
+  {
+    myVolume.Perform(Spine, Profil, Tol);
+  }
+  else
+  {
+    gp_Ax3 Axis(gp_Pnt(0., 0., 0.),
+                gp_Dir(0., 0., 1.),
+                gp_Dir(1., 0., 0.));
+
+    if (!AxeProf)
+    {
+      Standard_Boolean POS;
+      BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion()));
+      if (ProfOnSpine && !POS) return;
+    }
+
+    myEvolved.Perform(Spine, Profil, Axis, Join, Solid);
   }
 
-  myEvolved.Perform(Spine,Profil,Axis,Join,Solid);
   Build();
   Done();
 }
@@ -72,20 +84,31 @@ BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Face&     Spin
                                         const Standard_Boolean AxeProf,
                                         const Standard_Boolean Solid,
                                         const Standard_Boolean ProfOnSpine,
-                                        const Standard_Real    Tol)
+                                         const Standard_Boolean theIsVolume,
+                                         const Standard_Real    Tol)
 {
-  gp_Ax3 Axis(gp_Pnt(0.,0.,0.),
-             gp_Dir(0.,0.,1.),
-             gp_Dir(1.,0.,0.));
-
-  if ( !AxeProf) {
-    Standard_Boolean POS;
-    BRepFill::Axe(Spine,Profil,Axis,POS,Tol);
-    if (ProfOnSpine && !POS) return;
+  if (theIsVolume)
+  {
+    myVolume.Perform(TopoDS::Wire(TopoDS_Iterator(Spine).Value()), Profil, Tol);
+  }
+  else
+  {
+    gp_Ax3 Axis(gp_Pnt(0., 0., 0.),
+                gp_Dir(0., 0., 1.),
+                gp_Dir(1., 0., 0.));
+
+    if (!AxeProf)
+    {
+      Standard_Boolean POS;
+      BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion()));
+      if (ProfOnSpine && !POS) return;
+    }
+
+    myEvolved.Perform(Spine, Profil, Axis, Join, Solid);
   }
 
-  myEvolved.Perform(Spine,Profil,Axis,Join,Solid);
   Build();
+  Done();
 }
 
 
@@ -107,8 +130,16 @@ const BRepFill_Evolved& BRepOffsetAPI_MakeEvolved::Evolved() const
 
 void BRepOffsetAPI_MakeEvolved::Build()
 {
-  myShape = myEvolved.Shape();
-  if (myEvolved.IsDone())  Done();
+  if (myEvolved.IsDone())
+  {
+    myShape = myEvolved.Shape();
+  }
+  else if (myVolume.IsDone())
+  {
+    myShape = myVolume.Shape();
+  }
+  
+  Done();
 }
 
 
index fc778e36a0b8f448698928817006dc79942c08d6..1a16adb5d946d6c597c235e6ea7d39869996463c 100644 (file)
@@ -22,6 +22,7 @@
 #include <Standard_Handle.hxx>
 
 #include <BRepFill_Evolved.hxx>
+#include <BRepFill_Voluved.hxx>
 #include <BRepBuilderAPI_MakeShape.hxx>
 #include <GeomAbs_JoinType.hxx>
 #include <Standard_Boolean.hxx>
@@ -66,7 +67,7 @@ public:
   
   Standard_EXPORT BRepOffsetAPI_MakeEvolved();
   
-  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean AxeProf = Standard_True, const Standard_Boolean Solid = Standard_False, const Standard_Boolean ProfOnSpine = Standard_False, const Standard_Real Tol = 0.0000001);
+  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join/* = GeomAbs_Arc*/, const Standard_Boolean AxeProf/* = Standard_True*/, const Standard_Boolean Solid/* = Standard_False*/, const Standard_Boolean ProfOnSpine/* = Standard_False*/, const Standard_Boolean theIsVolume, const Standard_Real Tol/* = Precision::Confusion()*/);
   
   //! These constructors construct an evolved shape by sweeping the profile
   //! Profile along the spine Spine.
@@ -88,7 +89,7 @@ public:
   //! axis passing along the vertex and the normal to the
   //! plane of the spine. At present, this is the only
   //! construction type implemented.
-  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean AxeProf = Standard_True, const Standard_Boolean Solid = Standard_False, const Standard_Boolean ProfOnSpine = Standard_False, const Standard_Real Tol = 0.0000001);
+  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join/* = GeomAbs_Arc*/, const Standard_Boolean AxeProf/* = Standard_True*/, const Standard_Boolean Solid/* = Standard_False*/, const Standard_Boolean ProfOnSpine/* = Standard_False*/, const Standard_Boolean theIsVolume, const Standard_Real Tol/* = Precision::Confusion()*/);
   
   Standard_EXPORT const BRepFill_Evolved& Evolved() const;
   
@@ -118,9 +119,8 @@ protected:
 private:
 
 
-
   BRepFill_Evolved myEvolved;
-
+  BRepFill_Voluved myVolume;
 
 };
 
index c24c81743cd3dadbe157bdacf0f7f0fa4247e483..ef0343c4a07cf6ac1c19a2a2bfca07a674f3040e 100644 (file)
@@ -33,8 +33,6 @@
 //purpose  : 
 //=======================================================================
 BRepOffsetAPI_MakePipeShell::BRepOffsetAPI_MakePipeShell(const TopoDS_Wire& Spine)
-                      
-
 {
   myPipe = new (BRepFill_PipeShell) (Spine);
   SetTolerance();
@@ -255,7 +253,7 @@ void BRepOffsetAPI_MakePipeShell::SetMaxSegments(const Standard_Integer NewMaxSe
 //function :Build() 
 //purpose  : 
 //=======================================================================
- void BRepOffsetAPI_MakePipeShell::Build() 
+ void BRepOffsetAPI_MakePipeShell::Build()
 {
   Standard_Boolean Ok;
   Ok = myPipe->Build();
index 513acae20798f36b82d8496a584ff1799cff5d08..cf17ee207e7161cdf1ca5f45de8e5e81b68d88ac 100644 (file)
@@ -211,7 +211,7 @@ public:
   //! discontinuities are treated like round
   //! corner. The corner is treated as rotation
   //! of the profile around an axis which
-  //! passes through the point of the spine?s
+  //! passes through the point of the spine's
   //! fracture. This axis is based on cross
   //! product of directions tangent to the
   //! adjacent segments of the spine at their common point.
@@ -276,7 +276,6 @@ private:
 
   Handle(BRepFill_PipeShell) myPipe;
 
-
 };
 
 
index 8f3b51f120fb6dc753abd9e68669d58925ea4449..4d3c1f2c1988ace9f4a020fb098cbb5396f43a19 100644 (file)
@@ -237,34 +237,85 @@ Standard_Integer evolved(Draw_Interpretor& di, Standard_Integer n, const char**
 
   if ( n < 4 ) return 1;
   Standard_Boolean IsAFace = Standard_False;
-  Standard_Boolean Solid   = (!strcmp(a[0],"evolvedsolid"));
+  Standard_Boolean Solid   = Standard_False;  
+  Standard_Boolean isVolume = Standard_False;
+  Standard_Boolean hasToComputeAxes = Standard_False;
+  Standard_Real aTolerance = 0.0;
+  TopoDS_Shape Base;
+  TopoDS_Wire Prof;
+
+  for (Standard_Integer i = 2; i < n; i++)
+  {
+    if (a[i][0] != '-')
+    {
+      di << "Error: wrong option!\n";
+      return 1;
+    }
 
+    if (!Solid && !strcmp(a[i], "-solid"))
+    {
+      Solid = Standard_True;
+      continue;
+    }
 
-  TopoDS_Shape Base = DBRep::Get(a[2],TopAbs_WIRE,Standard_False);
-  if ( Base.IsNull()) {
-    Base = DBRep::Get(a[2],TopAbs_FACE,Standard_False);
-    IsAFace = Standard_True; 
-  }
-  if ( Base.IsNull()) return 1;
-
-  TopoDS_Shape InpuTShape(DBRep::Get(a[3],TopAbs_WIRE,Standard_False));
-  TopoDS_Wire Prof = TopoDS::Wire(InpuTShape);
-//  TopoDS_Wire Prof = 
-//    TopoDS::Wire(DBRep::Get(a[3],TopAbs_WIRE,Standard_False));
-  if ( Prof.IsNull()) return 1;
-
-  if (IsAFace) {
-    TopoDS_Shape Volevo 
-      = BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base),Prof,GeomAbs_Arc,n == 4,Solid);
-    DBRep::Set(a[1],Volevo);
+    switch (a[i][1])
+    {
+      case 's':
+      {
+        Base = DBRep::Get(a[++i], TopAbs_WIRE, Standard_False);
+        if (Base.IsNull())
+        {
+          Base = DBRep::Get(a[i], TopAbs_FACE, Standard_False);
+          IsAFace = Standard_True;
+        }
+      }
+      break;
+
+      case 'p':
+      {
+        Prof = TopoDS::Wire(DBRep::Get(a[++i], TopAbs_WIRE, Standard_False));
+      }
+      break;
+
+      case 'v':
+      {
+        isVolume = Standard_True;
+      }
+      break;
+
+      case 'a':
+      {
+        hasToComputeAxes = Standard_True;
+      }
+      break;
+
+      case 't':
+      {
+        aTolerance = Draw::Atof(a[++i]);
+      }
+      break;
+
+      default: 
+        di << "Error: Unknown option!\n";
+        break;
+    }
   }
-  else {
-    TopoDS_Shape Volevo 
-      = BRepOffsetAPI_MakeEvolved(TopoDS::Wire(Base),Prof,GeomAbs_Arc,n == 4,Solid);
-    DBRep::Set(a[1],Volevo);
+  if (Base.IsNull() || Prof.IsNull())
+  {
+    di << "Error: Null-shapes are not allowed\n";
+    return 1;
   }
 
+  TopoDS_Shape Volevo = IsAFace ? BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base),
+                                                            Prof, GeomAbs_Arc, !hasToComputeAxes,
+                                                            Solid, Standard_False, isVolume, aTolerance) :
+                                  BRepOffsetAPI_MakeEvolved(TopoDS::Wire(Base),
+                                                            Prof, GeomAbs_Arc, !hasToComputeAxes,
+                                                            Solid, Standard_False, isVolume, aTolerance);
+
+  DBRep::Set(a[1],Volevo);
+
   return 0;
 }
 
@@ -785,7 +836,11 @@ static Standard_Integer buildsweep(Draw_Interpretor& di,
     Sweep->SetTransitionMode(Transition);
   }
   // Reading solid ?
-  if ((n>cur) && (!strcmp(a[cur],"-S")) ) mksolid = Standard_True;
+  if ((n > cur) && (!strcmp(a[cur], "-S")))
+  {
+    mksolid = Standard_True;
+    ++cur;
+  }
 
   // Calcul le resultat
   Sweep->Build();
@@ -979,10 +1034,6 @@ void  BRepTest::SweepCommands(Draw_Interpretor& theCommands)
                  "evolved , no args to get help",
                  __FILE__,evolved,g);  
 
-  theCommands.Add("evolvedsolid",
-                 "evolved , no args to get help",
-                 __FILE__,evolved,g);  
-  
   theCommands.Add("pruled",
                  "pruled result Edge1/Wire1 Edge2/Wire2",
                  __FILE__,pruled,g);
index 8da855d76593b460ae0302925faa2e22a8d6b6bf..362a0269f96fdb8defd921b57285bfb0156ee377 100644 (file)
@@ -117,7 +117,7 @@ LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face&  Spine,
 
   myProfile  = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3);
 
-  myDPrism.Perform(mySpine,myProfile,gp::XOY()); 
+  myDPrism.Perform(mySpine,myProfile,gp::XOY(), GeomAbs_Arc, Standard_False); 
 
 
   if (myDPrism.IsDone()) {
@@ -370,7 +370,7 @@ LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face&   Spine,
   myProfile1 = BRepLib_MakeEdge(Vert4, Vert1);
   
   myProfile = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3);
-  myDPrism.Perform(mySpine,myProfile,gp::XOY()); 
+  myDPrism.Perform(mySpine,myProfile,gp::XOY(), GeomAbs_Arc, Standard_False); 
 
 
   if (myDPrism.IsDone()) {
index ded27c56d968e5df8a874f8eaf18f02f9e3f4735..0a16c0ad5b813568aeb507e906eb642f51f576dc 100644 (file)
@@ -142,7 +142,8 @@ public:
     PAppend(pNew, theIter);
   }
 
-  //! Append another list at the end
+  //! Append another list at the end.
+  //! After this operation, theOther list will be cleared.
   void Append (NCollection_List& theOther)
   { 
     if (this == &theOther || theOther.Extent()<1)
index dd326dc1a9a50f0e4cac3614ee965f6d1b79390f..76c2b8cd1bcac4f5eaccdacae67f22baed740142 100644 (file)
@@ -165,15 +165,19 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
       Standard_Real aMult = RealLast();
       for(Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++)
       {
+        const Standard_Real anAbsStep = Abs(TheStep(anIdx));
+        if (anAbsStep < gp::Resolution())
+          continue;
+
         if (suivant->Value(anIdx) < myLeft(anIdx))
         {
-          Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / Abs(TheStep(anIdx));
+          Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / anAbsStep;
           aMult = Min (aValue, aMult);
         }
 
         if (suivant->Value(anIdx) > myRight(anIdx))
         {
-          Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / Abs(TheStep(anIdx));
+          Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / anAbsStep;
           aMult = Min (aValue, aMult);
         }
       }
index d36810d59b02a8086b7d386b7116d71732aaa0c1..77fab06a23faeb931f68508dbe6503b6ac437b21 100755 (executable)
@@ -8,7 +8,7 @@ checkshape b
 restore [locate_data_file pro19424b.brep] p
 checkshape p
 
-if [catch {evolved result b p o } catch_result] {
+if [catch {evolved result -s b -p p -a } catch_result] {
   puts "Faulty PRO19424 : function EVOLVED works wrongly"
 } else {
   puts "PRO19424 OK: function EVOLVED works properly"
index 72b5716ff2879156570a7e691190e42c0ad34a7d..8abebafea5c1d7ebfdc2dc313e09741eb2a66988 100644 (file)
@@ -8,4 +8,4 @@ puts ""
 
 restore [locate_data_file OCC26470-ClosedWire.brep] a
 restore [locate_data_file OCC26470-wprof1.brep] b
-evolved res a b o
+evolved res -s a -p b -a
index c2cdf9b7f3de782fca7ec71ed9be46085bc27a2f..404fca30640c47e8470bdde92ece6e110d6dd384 100644 (file)
@@ -8,5 +8,5 @@ puts ""
 
 restore [locate_data_file OCC26470-ClosedWire.brep] a
 restore [locate_data_file OCC26470-wprof2.brep] b
-evolved res a b o
+evolved res -s a -p b -a
 checkshape res
diff --git a/tests/evolved/begin b/tests/evolved/begin
new file mode 100644 (file)
index 0000000..0705f24
--- /dev/null
@@ -0,0 +1,13 @@
+# To prevent loops limit to 10 minutes
+cpulimit 60
+
+if { [array get Draw_Groups "TOPOLOGY Feature commands"] == "" } {
+       pload TOPTEST
+}
+
+if { [info exists imagedir] == 0 } {
+   set imagedir .
+}
+if { [info exists test_image ] == 0 } {
+   set test_image photo
+}
diff --git a/tests/evolved/end b/tests/evolved/end
new file mode 100644 (file)
index 0000000..57901e2
--- /dev/null
@@ -0,0 +1,2 @@
+# to end a test script
+puts "TEST COMPLETED"
diff --git a/tests/evolved/evolved/begin b/tests/evolved/evolved/begin
new file mode 100644 (file)
index 0000000..2d2ece6
--- /dev/null
@@ -0,0 +1 @@
+set subgroup evolved
diff --git a/tests/evolved/evolved/bug26470_1 b/tests/evolved/evolved/bug26470_1
new file mode 100644 (file)
index 0000000..8abebaf
--- /dev/null
@@ -0,0 +1,11 @@
+puts "========"
+puts "OCC26470"
+puts "========"
+puts ""
+##################################################
+# BRepFill_Evolved: exception and invalid result
+##################################################
+
+restore [locate_data_file OCC26470-ClosedWire.brep] a
+restore [locate_data_file OCC26470-wprof1.brep] b
+evolved res -s a -p b -a
diff --git a/tests/evolved/evolved/bug26470_2 b/tests/evolved/evolved/bug26470_2
new file mode 100644 (file)
index 0000000..404fca3
--- /dev/null
@@ -0,0 +1,12 @@
+puts "========"
+puts "OCC26470"
+puts "========"
+puts ""
+##################################################
+# BRepFill_Evolved: exception and invalid result
+##################################################
+
+restore [locate_data_file OCC26470-ClosedWire.brep] a
+restore [locate_data_file OCC26470-wprof2.brep] b
+evolved res -s a -p b -a
+checkshape res
diff --git a/tests/evolved/evolved/pro19424 b/tests/evolved/evolved/pro19424
new file mode 100644 (file)
index 0000000..77fab06
--- /dev/null
@@ -0,0 +1,20 @@
+
+puts "=========="
+puts "PRO19424"
+puts "=========="
+
+restore [locate_data_file pro19424a.brep] b 
+checkshape b
+restore [locate_data_file pro19424b.brep] p
+checkshape p
+
+if [catch {evolved result -s b -p p -a } catch_result] {
+  puts "Faulty PRO19424 : function EVOLVED works wrongly"
+} else {
+  puts "PRO19424 OK: function EVOLVED works properly"
+}
+
+checkprops result -s 246.506 
+checkshape result
+checkview -display result -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/grids.list b/tests/evolved/grids.list
new file mode 100644 (file)
index 0000000..7c8d397
--- /dev/null
@@ -0,0 +1,2 @@
+001 evolved
+002 voluved
diff --git a/tests/evolved/parse.rules b/tests/evolved/parse.rules
new file mode 100644 (file)
index 0000000..610d206
--- /dev/null
@@ -0,0 +1 @@
+FAILED /\bFaulty\b/ bad shape
diff --git a/tests/evolved/voluved/AGT001 b/tests/evolved/voluved/AGT001
new file mode 100644 (file)
index 0000000..7c546d5
--- /dev/null
@@ -0,0 +1,24 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+profile p F -1 10 TT -1 -1 C 1 90 TT 10 -1 W
+polyline t -1 -1 0 0 -1.5 5
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 268.774 -v 245.265
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 1.5e-7
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/AGT002 b/tests/evolved/voluved/AGT002
new file mode 100644 (file)
index 0000000..670be58
--- /dev/null
@@ -0,0 +1,24 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+polyline p 0 0 0 0 10 0 20 10 0 20 0 0 13 0 0 13 5 0 6 5 0 6 0 0 0 0 0
+polyline t -2 2 0 0 2 5 0 2 10 1 2 10 1 2 0 -2 2 0
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 1649.58 -v 1023.79
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 1.5e-7
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/AGT003 b/tests/evolved/voluved/AGT003
new file mode 100644 (file)
index 0000000..3b3c029
--- /dev/null
@@ -0,0 +1,24 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+polyline p 0 0 0 0 10 0 20 10 0 20 0 0 13 0 0 13 5 0 6 5 0 6 0 0 0 0 0
+polyline t -1 2 0 0 1 5 0 1 10 0.5 0.5 10 0.5 0.5 0
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 1803.56 -v 532.942
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 5.0e-6
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/AGT004 b/tests/evolved/voluved/AGT004
new file mode 100644 (file)
index 0000000..fbf058e
--- /dev/null
@@ -0,0 +1,25 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+profile p X 10 Y 2 X -10 W
+polyline t -1 1 0 1 1 10
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 287.517 -v 211.903
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+# See issue #0029657
+#if {[regexp "Faulties" [bopargcheck result]]} {
+#  puts "Error: bopargcheck has found some faulties in res2"
+#}
+
+checkmaxtol result -ref 1.5e-007
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/AGT005 b/tests/evolved/voluved/AGT005
new file mode 100644 (file)
index 0000000..9d44743
--- /dev/null
@@ -0,0 +1,24 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+profile p X 10 Y 2 X -10 W
+polyline t -1 1 0 1.2 1 10
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 266.546 -v 192.639
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 1.5e-7
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/AGT006 b/tests/evolved/voluved/AGT006
new file mode 100644 (file)
index 0000000..b296f85
--- /dev/null
@@ -0,0 +1,25 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+# Different results in command "evolved" with and without "-v"
+profile p X 10 Y 2 X -10 W
+profile t O 0 1 0 P 0 1 0 0 0 1 X 5 T -1 2 WW
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 137.58 -v 80.9221
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 0.00011504480776721356
+
+smallview
+don result p t
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/AGT007 b/tests/evolved/voluved/AGT007
new file mode 100644 (file)
index 0000000..df37ded
--- /dev/null
@@ -0,0 +1,28 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+# Result contains intersected faces
+profile p X 15 C 1 90 Y 5 X -7 Y -2 C -1 90 X -8 W
+profile t O 0 1 0 P 0 1 0 0 0 1 X 5 T -1 2 WW
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 308.284 -v 195.169
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 1.5e-7
+
+regexp {Tolerance MAX=([-0-9.+eE]+)} [tolerance result] full toler
+checkreal MAXTOL $toler 1.5e-7 0.0 0.1
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/AGT008 b/tests/evolved/voluved/AGT008
new file mode 100644 (file)
index 0000000..fb4f4ac
--- /dev/null
@@ -0,0 +1,25 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+# Different results with and without "-v"; internal/intersecting faces created
+profile p X 10 Y 2 X -10 W
+profile t O 0 1 0 P 0 1 0 0 0 1 X 2 RR -45 C 1 90 T -1 2 WW
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 129.967 -v 70.6801
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 3.25e-007
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/AGT009 b/tests/evolved/voluved/AGT009
new file mode 100644 (file)
index 0000000..455b917
--- /dev/null
@@ -0,0 +1,25 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+# Solids are correctly built but r_1 should be eliminated as junk
+profile p X 10 Y 2 X -10 W
+profile t O 0 1 0 P 0 1 0 0 0 1 RR 30 C -10 60 WW
+evolved result -s p -p t -a -solid -v
+
+checkprops result -s 308.284 -v 195.169
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 1.5e-7
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/evolved/voluved/HMC001 b/tests/evolved/voluved/HMC001
new file mode 100644 (file)
index 0000000..45b31cd
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+restore [locate_data_file bug29523_cut_extrudewire00.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire00.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 1.94263e+010 -v 6.2718e+013
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 0.00013577499521488808
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC002 b/tests/evolved/voluved/HMC002
new file mode 100644 (file)
index 0000000..2900702
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+restore [locate_data_file bug29523_cut_extrudewire01.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire01.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 2.18924e+011 -v 2.47705e+014
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 1.0e-7
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC003 b/tests/evolved/voluved/HMC003
new file mode 100644 (file)
index 0000000..08d0d09
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+restore [locate_data_file bug29523_cut_extrudewire02.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire02.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 2.18616e+011 -v 2.46411e+014
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 1.6e-5
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC004 b/tests/evolved/voluved/HMC004
new file mode 100644 (file)
index 0000000..194f839
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+restore [locate_data_file bug29523_cut_extrudewire03.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire03.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 3.02832e+010 -v 4.97434e+013
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 7.0e-7
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC005 b/tests/evolved/voluved/HMC005
new file mode 100644 (file)
index 0000000..654640e
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+restore [locate_data_file bug29523_cut_extrudewire04.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire04.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 1.94263e+010 -v 6.2718e+013
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 0.00013577500067185611
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC006 b/tests/evolved/voluved/HMC006
new file mode 100644 (file)
index 0000000..7b20055
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+restore [locate_data_file bug29523_cut_extrudewire05.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire05.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 2.84249e+010 -v 8.95554e+013
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 4.4607852024588505e-007
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC007 b/tests/evolved/voluved/HMC007
new file mode 100644 (file)
index 0000000..83158f3
--- /dev/null
@@ -0,0 +1,26 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+restore [locate_data_file bug29523_cut_extrudewire06.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire06.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 1.99565e+011 -v 6.75431e+014
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 4.7e-6
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC008 b/tests/evolved/voluved/HMC008
new file mode 100644 (file)
index 0000000..77cd8f8
--- /dev/null
@@ -0,0 +1,28 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+cpulimit 100
+
+restore [locate_data_file bug29523_cut_extrudewire07.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire07.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 1.99565e+011 -v 6.75431e+014
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 4.7e-6
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC009 b/tests/evolved/voluved/HMC009
new file mode 100644 (file)
index 0000000..c239295
--- /dev/null
@@ -0,0 +1,28 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+cpulimit 100
+
+restore [locate_data_file bug29523_cut_extrudewire08.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire08.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 1.99565e+011 -v 6.75431e+014
+checkshape result
+
+checknbshapes result -solid 1 -shell 1
+
+if {[regexp "Faulties" [bopargcheck result]]} {
+  puts "Error: bopargcheck has found some faulties in res2"
+}
+
+checkmaxtol result -ref 4.7e-6
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/begin b/tests/evolved/voluved/begin
new file mode 100644 (file)
index 0000000..1f09ffe
--- /dev/null
@@ -0,0 +1 @@
+set subgroup voluved
diff --git a/tests/evolved/voluved/bug26470_1 b/tests/evolved/voluved/bug26470_1
new file mode 100644 (file)
index 0000000..67b5f24
--- /dev/null
@@ -0,0 +1,11 @@
+puts "========"
+puts "OCC26470"
+puts "========"
+puts ""
+##################################################
+# BRepFill_Evolved: exception and invalid result
+##################################################
+
+restore [locate_data_file OCC26470-ClosedWire.brep] a
+restore [locate_data_file OCC26470-wprof1.brep] b
+evolved res -s a -p b -a -v
diff --git a/tests/evolved/voluved/bug26470_2 b/tests/evolved/voluved/bug26470_2
new file mode 100644 (file)
index 0000000..039e1e9
--- /dev/null
@@ -0,0 +1,12 @@
+puts "========"
+puts "OCC26470"
+puts "========"
+puts ""
+##################################################
+# BRepFill_Evolved: exception and invalid result
+##################################################
+
+restore [locate_data_file OCC26470-ClosedWire.brep] a
+restore [locate_data_file OCC26470-wprof2.brep] b
+evolved res -s a -p b -a -v
+checkshape res
diff --git a/tests/evolved/voluved/pro19424 b/tests/evolved/voluved/pro19424
new file mode 100644 (file)
index 0000000..c86eb48
--- /dev/null
@@ -0,0 +1,20 @@
+
+puts "=========="
+puts "PRO19424"
+puts "=========="
+
+restore [locate_data_file pro19424a.brep] b 
+checkshape b
+restore [locate_data_file pro19424b.brep] p
+checkshape p
+
+if [catch {evolved result -s b -p p -a -v } catch_result] {
+  puts "Faulty PRO19424 : function EVOLVED works wrongly"
+} else {
+  puts "PRO19424 OK: function EVOLVED works properly"
+}
+
+checkprops result -s 246.506 
+checkshape result
+checkview -display result -2d -path ${imagedir}/${test_image}.png
+