0029523: Problem with BRepOffsetAPI_MakeEvolved
authornbv <nbv@opencascade.com>
Wed, 11 Apr 2018 09:23:29 +0000 (12:23 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 7 May 2019 11:20:58 +0000 (14:20 +0300)
The capabilities of the class BRepOffsetAPI_MakeEvolved have been extended with involving alternate algorithm of resolving the loops in the piped shape. The new option theIsVolume is added for that in the constructor.

New class BRepFill_AdvancedEvolved has been created in order to provide new OCCT-algorithm combining BRepFill_PipeShell and BOPAlgo_MakerVolume.

A change in BOPAlgo_PaveFiller.cxx has been made in order to solve a specific problem of Boolean operation.

The interface of DRAW-command "evolved" has been updated to add the new option. DRAW-command "evolvedsolid" has been deleted. Now it is replaced with DRAW-command "evolved" with the option "-solid".

Testgrid "evolved" has been created.

50 files changed:
src/BOPAlgo/BOPAlgo_PaveFiller.cxx
src/BOPDS/BOPDS_DS.cxx
src/BOPDS/BOPDS_DS.hxx
src/BRepFill/BRepFill_AdvancedEvolved.cxx [new file with mode: 0644]
src/BRepFill/BRepFill_AdvancedEvolved.hxx [new file with mode: 0644]
src/BRepFill/BRepFill_PipeShell.cxx
src/BRepFill/BRepFill_Sweep.cxx
src/BRepFill/BRepFill_Sweep.hxx
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/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/HMC010 [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 f4eb89a..d03fac1 100644 (file)
@@ -294,6 +294,8 @@ void BOPAlgo_PaveFiller::PerformInternal()
   //
   UpdateBlocksWithSharedVertices();
   //
+  myDS->RefineFaceInfoIn();
+  //
   MakeSplitEdges();
   if (HasErrors()) {
     return; 
index a8b605f..b547175 100644 (file)
@@ -1385,6 +1385,44 @@ void BOPDS_DS::RefineFaceInfoOn()
     }
   }
 }
+
+//=======================================================================
+//function : RefineFaceInfoIn
+//purpose  : 
+//=======================================================================
+void BOPDS_DS::RefineFaceInfoIn()
+{
+  for (Standard_Integer i = 0; i < myNbSourceShapes; ++i)
+  {
+    const BOPDS_ShapeInfo& aSI = ShapeInfo(i);
+    if (aSI.ShapeType() != TopAbs_FACE)
+      continue;
+
+    if (!aSI.HasReference())
+      continue;
+
+    BOPDS_FaceInfo& aFI = ChangeFaceInfo(i);
+
+    const BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.PaveBlocksOn();
+    BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
+
+    if (aMPBIn.IsEmpty() || aMPBOn.IsEmpty())
+      continue;
+
+    BOPDS_IndexedMapOfPaveBlock aMPBInNew;
+
+    const Standard_Integer aNbPBIn = aMPBIn.Extent();
+    for (Standard_Integer j = 1; j <= aNbPBIn; ++j)
+    {
+      if (!aMPBOn.Contains(aMPBIn(j)))
+        aMPBInNew.Add(aMPBIn(j));
+    }
+
+    if (aMPBInNew.Extent() < aNbPBIn)
+      aMPBIn = aMPBInNew;
+  }
+}
+
 //=======================================================================
 //function : AloneVertices
 //purpose  : 
index 756a36a..d51d775 100644 (file)
@@ -303,6 +303,8 @@ Standard_EXPORT virtual ~BOPDS_DS();
   //! ++
   Standard_EXPORT void RefineFaceInfoOn();
   
+  //! Removes any pave block from list of having IN state if it has also the state ON.
+  Standard_EXPORT void RefineFaceInfoIn();
 
   //! Returns information about ON/IN sub-shapes of the given faces.
   //! @param theMVOnIn  the indices of ON/IN vertices from both faces
diff --git a/src/BRepFill/BRepFill_AdvancedEvolved.cxx b/src/BRepFill/BRepFill_AdvancedEvolved.cxx
new file mode 100644 (file)
index 0000000..d28adfe
--- /dev/null
@@ -0,0 +1,2034 @@
+// 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_AdvancedEvolved.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>
+#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
+#include <BRep_TEdge.hxx>
+#include <ShapeUpgrade_UnifySameDomain.hxx>
+
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+#include <BinTools.hxx>
+#endif
+
+
+static const Standard_Real aPipeLinearTolerance = 1.0e-4;
+static const Standard_Real aPipeAngularTolerance = 1.0e-2;
+
+static Standard_Boolean ContainsInList(const TopTools_ListOfShape& theL,
+                                       const TopoDS_Shape& theObject);
+
+static void FindInternals(const TopoDS_Shape& theS,
+                          TopTools_ListOfShape& theLInt);
+
+static void RemoveInternalWires(const TopoDS_Shape& theShape);
+
+static void ProcessVertex(const TopoDS_Vertex& aV,
+                          const TopTools_ListOfShape& aLE,
+                          const TopTools_ListOfShape& aLF);
+
+static void ReduceVertexTolerance(const TopoDS_Shape& aS);
+
+//=======================================================================
+//function : PerformBoolean
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepFill_AdvancedEvolved::PerformBoolean(const TopTools_ListOfShape& theArgsList,
+                                                          TopoDS_Shape& theResult) const
+{
+  BOPAlgo_PaveFiller aPF;
+
+  aPF.SetArguments(theArgsList);
+  aPF.SetRunParallel(myIsParallel);
+  aPF.SetFuzzyValue(myFuzzyValue);
+
+  aPF.Perform();
+  if (aPF.HasErrors())
+  {
+    return Standard_False;
+  }
+
+  BOPAlgo_Builder aBuilder;
+  aBuilder.SetArguments(theArgsList);
+
+  aBuilder.SetRunParallel(myIsParallel);
+  aBuilder.PerformWithFiller(aPF);
+  if (aBuilder.HasErrors())
+  {
+    return Standard_False;
+  }
+
+  theResult = aBuilder.Shape();
+  return Standard_True;
+}
+
+//=======================================================================
+//function : GetSpineAndProfile
+//purpose  : 
+//=======================================================================
+void BRepFill_AdvancedEvolved::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.Reverse();
+        }
+      }
+      else
+      {
+        if (aN1.Dot(aTanV) > 0.0)
+        {
+          myProfile.Reverse();
+        }
+      }
+    }
+    break;
+    default:
+      break;
+  }
+}
+
+//=======================================================================
+//function : IsLid
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepFill_AdvancedEvolved::IsLid(const TopoDS_Face& theF,
+                                                 const TopTools_IndexedMapOfShape& theMapOfLids) const
+{
+  if (theMapOfLids.IsEmpty())
+    return Standard_False;
+
+  const Handle(Geom_Plane) aPlnF = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(theF));
+
+  if (aPlnF.IsNull())
+    return Standard_False;
+
+  TopTools_IndexedMapOfShape::Iterator anItr(theMapOfLids);
+  for (; anItr.More(); anItr.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anItr.Value());
+    const Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aF));
+
+    if (aPlane == aPlnF)
+      return Standard_True;
+  }
+
+  return Standard_False;
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+void BRepFill_AdvancedEvolved::Perform(const TopoDS_Wire& theSpine, 
+                                       const TopoDS_Wire& theProfile,
+                                       const Standard_Real theTolerance,
+                                       const Standard_Boolean theSolidReq)
+{
+  myErrorStatus = BRepFill_AdvancedEvolved_Empty;
+
+  if (myFuzzyValue < Precision::Confusion())
+  {
+    myFuzzyValue = theTolerance;
+  }
+
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+  char aBuff[10000];
+  Sprintf(aBuff, "%s%s", myDebugShapesPath, "spine.nbv");
+  BinTools::Write(theSpine, aBuff);
+  Sprintf(aBuff, "%s%s", myDebugShapesPath, "profile.nbv");
+  BinTools::Write(theProfile, aBuff);
+
+  std::streamsize aPrecVal = std::cout.precision();
+
+  std::cout.precision(15);
+
+  std::cout << "++++ Dump of Spine" << std::endl;
+  BRepTools::Dump(theSpine, std::cout);
+  std::cout << "---- Dump of Spine" << std::endl;
+
+  std::cout << "++++ Dump of Profile" << std::endl;
+  BRepTools::Dump(theProfile, std::cout);
+  std::cout << "---- Dump of Profile" << std::endl;
+
+  std::cout.precision(aPrecVal);
+#endif
+
+  GetSpineAndProfile(theSpine, theProfile);
+
+  myPipeShell.Nullify();
+  myTopBottom.Nullify();
+  myResult.Nullify();
+
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+  std::cout << "Start Evolved. Toler = " << myFuzzyValue << std::endl;
+#endif
+
+  PerformSweep();
+
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+  std::cout << "PerformSweep complete. Status = " << myErrorStatus << std::endl;
+#endif
+
+  GetLids();
+
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+  std::cout << "GetLids complete. Status = " << myErrorStatus << std::endl;
+#endif
+
+  if (myErrorStatus != BRepFill_AdvancedEvolved_NotSolid)
+  {
+    return;
+  }
+
+  myResult = myPipeShell;
+
+  BuildSolid();
+
+  if ((myErrorStatus != BRepFill_AdvancedEvolved_OK) || theSolidReq)
+  {
+    return;
+  }
+
+  TopoDS_Shell aShell;
+  TopTools_IndexedMapOfShape aMFLids;
+  TopExp::MapShapes(myTopBottom, TopAbs_FACE, aMFLids);
+
+  TopExp_Explorer anExp(myResult, TopAbs_FACE);
+  for (; anExp.More(); anExp.Next())
+  {
+    BRep_Builder aBB;
+    if (aShell.IsNull())
+      aBB.MakeShell(aShell);
+
+    const TopoDS_Face &aF = TopoDS::Face(anExp.Current());
+    if (IsLid(aF, aMFLids))
+      continue;
+
+    aBB.Add(aShell, aF);
+  }
+
+  if (!aShell.IsNull())
+    myResult = aShell;
+}
+
+//=======================================================================
+//function : PerformSweep
+//purpose  : 
+//=======================================================================
+void BRepFill_AdvancedEvolved::PerformSweep()
+{
+  if (myErrorStatus != BRepFill_AdvancedEvolved_Empty)
+    return;
+
+  myErrorStatus = BRepFill_AdvancedEvolved_SweepError;
+
+  Handle(BRepFill_PipeShell) aPipe = new BRepFill_PipeShell(mySpine);
+  aPipe->SetTolerance(aPipeLinearTolerance, aPipeLinearTolerance, aPipeAngularTolerance);
+  aPipe->SetTransition(BRepFill_Round);
+  aPipe->Add(myProfile, Standard_False, Standard_False);
+
+  if (aPipe->Build())
+  {
+    myErrorStatus = BRepFill_AdvancedEvolved_NoLids;
+    myPipeShell = aPipe->Shape();
+  }
+}
+
+//=======================================================================
+//function : GetLids
+//purpose  : 
+//=======================================================================
+void BRepFill_AdvancedEvolved::GetLids()
+{
+  if (myPipeShell.IsNull())
+    return;
+
+  if (BRep_Tool::IsClosed(myProfile))
+  {
+    // No need in lids creation
+    myErrorStatus = BRepFill_AdvancedEvolved_NotSolid;
+    return;
+  }
+
+  myErrorStatus = BRepFill_AdvancedEvolved_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_AdvancedEvolved_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->Position().Direction();
+
+  // Obtain free-edges from myPipeShell. All edges must be planar
+  // and parallel to the plane of mySpine
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
+
+  TopExp::MapShapesAndAncestors(myPipeShell, TopAbs_EDGE, TopAbs_FACE, aMapEF);
+
+  TopTools_ListOfShape aLE;
+
+  gp_Pnt aPtmp;
+  gp_Vec aTan;
+
+  for (Standard_Integer i = 1; i <= aMapEF.Size(); i++)
+  {
+    TopTools_ListOfShape& aListF = aMapEF(i);
+
+    if (aListF.Extent() != 1)
+      continue;
+
+    const TopoDS_Edge &anE = TopoDS::Edge(aMapEF.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()), aPtmp, 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_AdvancedEvolved_NotPlanarSpine;
+    return;
+  }
+
+  // Split interfered edges
+  TopoDS_Shape aFreeEdges;
+  if (!PerformBoolean(aLE, aFreeEdges))
+  {
+    myErrorStatus = BRepFill_AdvancedEvolved_NotPlanarSpine;
+    return;
+  }
+
+  // Collect all free edges to wires and create planar 
+  // top and bottom lids from these wires.
+  BRep_Builder aBB;
+  TopoDS_Compound aCompW, aCompF;
+  aBB.MakeCompound(aCompW);
+  aBB.MakeCompound(aCompF);
+  aBB.MakeCompound(myTopBottom);
+  BOPAlgo_Tools::EdgesToWires(aFreeEdges, aCompW, Standard_True);
+  BOPAlgo_Tools::WiresToFaces(aCompW, aCompF);
+
+  {
+    // Check orientation
+
+    TopTools_IndexedMapOfShape aMapV;
+    TopExp::MapShapes(myPipeShell, TopAbs_VERTEX, aMapV);
+    TopExp_Explorer anExp(aCompF, TopAbs_FACE);
+    for (; anExp.More(); anExp.Next())
+    {
+      const TopoDS_Face aF = TopoDS::Face(anExp.Current());
+      const Handle(Geom_Plane) aPln = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aF));
+      const gp_XYZ &aNorm = aPln->Position().Direction().XYZ();
+      const gp_XYZ &aLocP = aPln->Position().Location().XYZ();
+
+      Standard_Boolean isFound = Standard_False;
+
+      for (Standard_Integer i = 1; i <= aMapV.Size(); i++)
+      {
+        const TopoDS_Vertex aV = TopoDS::Vertex(aMapV.FindKey(i));
+        const gp_XYZ aP = BRep_Tool::Pnt(aV).XYZ();
+
+        const gp_XYZ aDelta = aP - aLocP;
+        const Standard_Real aSqD = aDelta.SquareModulus();
+
+        if (aSqD < Precision::SquareConfusion())
+          continue;
+
+        const Standard_Real aDP = aDelta.Dot(aNorm);
+
+        if (aDP*aDP < aSqD*Precision::SquareConfusion())
+        {
+          // aP is in the plane
+          continue;
+        }
+
+        if (aDP > 0.0)
+        {
+          aBB.Add(myTopBottom, aF.Reversed());
+        }
+        else
+        {
+          aBB.Add(myTopBottom, aF);
+        }
+
+        isFound = Standard_True;
+        break;
+      }
+
+      if (!isFound)
+      {
+        aBB.Add(myTopBottom, aF);
+      }
+    }
+  }
+
+  myErrorStatus = BRepFill_AdvancedEvolved_NotSolid;
+}
+
+//=======================================================================
+//function : BuildSolid
+//purpose  : 
+//=======================================================================
+void BRepFill_AdvancedEvolved::BuildSolid()
+{
+  if (myErrorStatus != BRepFill_AdvancedEvolved_NotSolid)
+    return;
+
+  myErrorStatus = BRepFill_AdvancedEvolved_NotVolume;
+
+  TopTools_MapOfShape aMapF;
+  TopTools_ListOfShape aLF, aLSplits;
+  TopExp_Explorer anExpF;
+
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+  char aBuff[10000];
+  Sprintf(aBuff, "%s%s", myDebugShapesPath, "shape2.nbv");
+  BinTools::Write(myPipeShell, aBuff);
+#endif
+
+  for (anExpF.Init(myPipeShell, TopAbs_FACE);
+       anExpF.More(); anExpF.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anExpF.Current());
+    if (!aMapF.Add(aF))
+      continue;
+
+    ReduceVertexTolerance(aF);
+    CheckSingularityAndAdd(aF, myFuzzyValue, aLF, aLSplits);
+  }
+  
+  {
+    TopTools_ListIteratorOfListOfShape anItrS(aLSplits);
+    for (; anItrS.More(); anItrS.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItrS.Value());
+      aLF.Append(aF);
+    }
+
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+    BRep_Builder aBB;
+    TopoDS_Compound aDebComp;
+    aBB.MakeCompound(aDebComp);
+    TopTools_ListIteratorOfListOfShape anItrDeb(aLF);
+    for (; anItrDeb.More(); anItrDeb.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItrDeb.Value());
+      aBB.Add(aDebComp, aF);
+    }
+
+    Sprintf(aBuff, "%s%s", myDebugShapesPath, "shape3.nbv");
+    BinTools::Write(aDebComp, aBuff);
+#endif
+
+    // Split interfered faces
+    PerformBoolean(aLF, myPipeShell);
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+    Sprintf(aBuff, "%s%s", myDebugShapesPath, "shape4.nbv");
+    BinTools::Write(myPipeShell, aBuff);
+#endif
+  }
+
+  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);
+    }
+  }
+  
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+  BRep_Builder aBB;
+  TopoDS_Compound aDebComp;
+  aBB.MakeCompound(aDebComp);
+  TopTools_ListIteratorOfListOfShape anItrDeb(aLF);
+  for (; anItrDeb.More(); anItrDeb.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anItrDeb.Value());
+    aBB.Add(aDebComp, aF);
+  }
+
+  Sprintf(aBuff, "%s%s", myDebugShapesPath, "shape5.nbv");
+  BinTools::Write(aDebComp, aBuff);
+#endif
+
+  BOPAlgo_MakerVolume aMV;
+  aMV.SetArguments(aLF);
+  aMV.SetFuzzyValue(myFuzzyValue);
+  aMV.SetIntersect(Standard_True);
+  aMV.SetRunParallel(myIsParallel);
+  aMV.SetAvoidInternalShapes(Standard_True);
+  aMV.Perform();
+
+  if (aMV.HasErrors())
+  {
+    return;
+  }
+  
+  myResult = aMV.Shape();
+
+#ifdef BRepFill_AdvancedEvolved_DEBUG
+  std::cout << "BuildSolid After VM." << std::endl;
+#endif
+
+  RemoveExcessSolids(aLSplits, myResult, aLF, aMV);
+
+  UnifyShape();
+  RemoveInternalWires(myResult);
+
+  myErrorStatus = BRepFill_AdvancedEvolved_OK;
+}
+
+//=======================================================================
+//function : UnifyShape
+//purpose  : 
+//=======================================================================
+void BRepFill_AdvancedEvolved::UnifyShape()
+{
+  ShapeUpgrade_UnifySameDomain aUnifier;
+
+  aUnifier.Initialize(myResult, Standard_True, Standard_True, Standard_False);
+  aUnifier.SetSafeInputMode(Standard_True);
+  aUnifier.AllowInternalEdges(Standard_False);
+  aUnifier.SetLinearTolerance(aPipeLinearTolerance);
+  aUnifier.SetAngularTolerance(aPipeAngularTolerance);
+  aUnifier.Build();
+
+  myResult = aUnifier.Shape();
+
+}
+
+//=======================================================================
+//function : ExtractOuterSolid
+//purpose  : 
+//=======================================================================
+void BRepFill_AdvancedEvolved::ExtractOuterSolid(TopoDS_Shape& theShape,
+                                                 TopTools_ListOfShape& theArgsList)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape aMapS;
+  TopExp::MapShapesAndAncestors(theShape, TopAbs_FACE, TopAbs_SOLID, aMapS);
+
+  //theArgsList.Clear();
+  TopTools_ListOfShape aNewList;
+  const Standard_Integer aNbF = aMapS.Extent();
+  for (Standard_Integer i = 1; i <= aNbF; ++i)
+  {
+    if (aMapS(i).Extent() == 1)
+      aNewList.Append(aMapS.FindKey(i));
+  }
+
+  if (aNewList.IsEmpty())
+    return;
+
+  {
+    TopTools_ListIteratorOfListOfShape anItrF;
+
+    Standard_Boolean isRemoved = Standard_True;
+    while (isRemoved)
+    {
+      isRemoved = Standard_False;
+      for (anItrF.Init(theArgsList); anItrF.More(); anItrF.Next())
+      {
+        const TopoDS_Face& aF = TopoDS::Face(anItrF.Value());
+        if (!ContainsInList(aNewList, aF))
+        {
+          theArgsList.Remove(aF);
+          isRemoved = Standard_True;
+          break;
+        }
+      }
+    }
+  }
+
+  BOPAlgo_MakerVolume aMV;
+  aMV.SetArguments(aNewList);
+  aMV.SetIntersect(Standard_True);
+  aMV.SetRunParallel(myIsParallel);
+  aMV.SetAvoidInternalShapes(Standard_True);
+  aMV.Perform();
+
+  if (aMV.HasErrors())
+  {
+    return;
+  }
+
+  theShape = aMV.Shape();
+}
+
+//=======================================================================
+//function : RemoveExcessSolids
+//purpose  : 
+//=======================================================================
+void BRepFill_AdvancedEvolved::RemoveExcessSolids(const TopTools_ListOfShape& theLSplits,
+                                                  const TopoDS_Shape& theShape,
+                                                  TopTools_ListOfShape& theArgsList,
+                                                  BOPAlgo_MakerVolume& theMV)
+{
+  if (myErrorStatus != BRepFill_AdvancedEvolved_NotVolume)
+    return;
+  
+  TopoDS_Shape aResShape = theShape;
+
+  TopExp_Explorer anExpSo;
+  for (Standard_Integer i = 0; i < 2; i++)
+  {
+    anExpSo.Init(aResShape, TopAbs_SOLID);
+    if (!anExpSo.More())
+    {
+      // No any solids
+      myResult = aResShape;
+      return;
+    }
+
+    anExpSo.Next();
+    if (!anExpSo.More())
+    {
+      // Only one solid has been generated
+      myResult = TopoDS::Solid(anExpSo.Current());
+      return;
+    }
+
+    if (i != 0)
+      break;
+
+    ExtractOuterSolid(aResShape, theArgsList);
+  }
+
+  TopTools_ListOfShape aSolidList;
+
+  //Look for all solids containing lids
+  {
+    anExpSo.Init(aResShape, TopAbs_SOLID);
+    for (; anExpSo.More(); anExpSo.Next())
+    {
+      const TopoDS_Solid &aSol = TopoDS::Solid(anExpSo.Current());
+      TopTools_IndexedMapOfShape aMapF;
+      TopExp::MapShapes(aSol, aMapF);
+
+      Standard_Boolean areThereLids = Standard_False;
+      TopExp_Explorer anExpLids(myTopBottom, TopAbs_FACE);
+      for (; anExpLids.More(); anExpLids.Next())
+      {
+        areThereLids = Standard_True;
+        const TopoDS_Face &aFLid = TopoDS::Face(anExpLids.Current());
+        const Standard_Integer aFIdx = aMapF.FindIndex(aFLid);
+        if (aFIdx < 1)
+          continue;
+
+        const TopoDS_Face &aFSol = TopoDS::Face(aMapF.FindKey(aFIdx));
+
+        if (aFSol.IsEqual(aFLid))
+        {
+          aSolidList.Append(aSol);
+        }
+
+        break;
+      }
+
+      if (!areThereLids)
+        break;
+    }
+
+    if (aSolidList.Extent() < 1)
+    {
+      myResult = aResShape;
+      return;
+    }
+
+    if (aSolidList.Extent() == 1)
+    {
+      myResult = aSolidList.First();
+      return;
+    }
+
+    if (aSolidList.Extent() > 0)
+    {
+      BRep_Builder aBB;
+      TopoDS_CompSolid aCompSol;
+      aBB.MakeCompSolid(aCompSol);
+      TopTools_ListIteratorOfListOfShape anItl(aSolidList);
+      for (; anItl.More(); anItl.Next())
+      {
+        const TopoDS_Solid &aSol = TopoDS::Solid(anItl.Value());
+        aBB.Add(aCompSol, aSol);
+      }
+
+      aResShape = aCompSol;
+      aSolidList.Clear();
+    }
+  }
+
+  {
+    // 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);
+      }
+    }
+
+    for (anExpSo.Init(aResShape, 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 = aResShape;
+    return;
+  }
+
+  if (aSolidList.Extent() == 1)
+  {
+    myResult = aSolidList.First();
+    return;
+  }
+
+  BRep_Builder aBB;
+  TopoDS_CompSolid aCmpSol;
+  aBB.MakeCompSolid(aCmpSol);
+
+  for (TopTools_ListIteratorOfListOfShape anItl(aSolidList); anItl.More(); anItl.Next())
+  {
+    const TopoDS_Solid &aSo = TopoDS::Solid(anItl.Value());
+    aBB.Add(aCmpSol, aSo);
+  }
+
+  myResult = aCmpSol;
+}
+
+#if 0
+//=======================================================================
+//class : NormalFunc
+//purpose  : This function computes square modulus of the normal to the
+//            surface in every point of the curve myCOnS. It allows detecting
+//            whether the curve goes through the singular point(s).
+//            It will be useful in case(s) when the result after PipeShell
+//            algorithm contains only one face with single seam-edge. E.g.:
+//                Draw[]> ellipse cc 0 0 0 0 0 1 30 10
+//                Draw[]> mkedge ee cc
+//                Draw[]> wire ww ee
+//                Draw[]> polyline tw 0 25 -5 0 -20 10
+//                Draw[]> mksweep ww
+//                Draw[]> addsweep tw
+//                Draw[]> buildsweep r1 -R
+//
+//           It results in creation of shell with self-interfered face.
+//            However, "checkshape" does not detect any invalidities.
+//
+//           The algorithm "Evolved" must be improved to process such cases.
+//            Currently they are not processed and this function is useless.
+//=======================================================================
+class NormalFunc : public math_MultipleVarFunctionWithGradient
+{
+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;
+}
+
+#endif
+//=======================================================================
+//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;
+    anItr.Init(*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.Init(*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 BRepFill_AdvancedEvolved::CheckSingularityAndAdd(const TopoDS_Face& theF,
+                                                                  const Standard_Real theFuzzyToler,
+                                                                  TopTools_ListOfShape& theListOfFaces,
+                                                                  TopTools_ListOfShape& theListOfSplits) const
+{
+  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(myIsParallel);
+
+    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;
+    aBuilder.SetArguments(aLE);
+    aBuilder.SetRunParallel(myIsParallel);
+    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 aFace = TopoDS::Face(theF.Oriented(TopAbs_FORWARD));
+
+  for (TopoDS_Iterator anExpW(aFace); 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 aBuilder;
+    aBuilder.SetArguments(aLGF);
+    aBuilder.SetRunParallel(myIsParallel);
+    aBuilder.SetNonDestructive(Standard_True);
+    aBuilder.PerformWithFiller(aPF);
+    if (aBuilder.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
+    TopTools_ListIteratorOfListOfShape aBItr(aLGF);
+    for (; aBItr.More(); aBItr.Next())
+    {
+      const TopoDS_Edge &aSh = TopoDS::Edge(aBItr.Value());
+      const TopTools_ListOfShape &aLM = aBuilder.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(aFace, 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;
+}
+
+//=======================================================================
+//function : ContainsInList
+//purpose  : 
+//=======================================================================
+Standard_Boolean ContainsInList(const TopTools_ListOfShape& theL,
+                                const TopoDS_Shape& theObject)
+{
+  TopTools_ListIteratorOfListOfShape anIt(theL);
+  for (; anIt.More(); anIt.Next())
+  {
+    if (anIt.Value().IsSame(theObject))
+    {
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+// function: FindInternals
+// purpose: Looks for internal shapes inside the face or solid
+//=======================================================================
+void FindInternals(const TopoDS_Shape& theS,
+                   TopTools_ListOfShape& theLInt)
+{
+  TopoDS_Iterator itS(theS);
+  for (; itS.More(); itS.Next())
+  {
+    const TopoDS_Shape& aSS = itS.Value();
+    if (aSS.Orientation() == TopAbs_INTERNAL)
+      theLInt.Append(aSS);
+    else
+    {
+      TopoDS_Iterator itSS(aSS);
+      for (; itSS.More(); itSS.Next())
+      {
+        if (itSS.Value().Orientation() == TopAbs_INTERNAL)
+        {
+          theLInt.Append(aSS);
+          break;
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+// function: RemoveInternalWires
+// purpose: Removes internal wires from the faces
+//=======================================================================
+void RemoveInternalWires(const TopoDS_Shape& theShape)
+{
+  TopExp_Explorer anExpF(theShape, TopAbs_FACE);
+  for (; anExpF.More(); anExpF.Next())
+  {
+    TopoDS_Face& aF = *(TopoDS_Face*) &anExpF.Current();
+    TopTools_ListOfShape aLWToRemove;
+    FindInternals(aF, aLWToRemove);
+    if (aLWToRemove.Extent())
+    {
+      aF.Free(Standard_True);
+      TopTools_ListIteratorOfListOfShape itR(aLWToRemove);
+      for (; itR.More(); itR.Next())
+      {
+        BRep_Builder().Remove(aF, itR.Value());
+      }
+      aF.Free(Standard_False);
+    }
+  }
+}
+
+//=======================================================================
+//function : ProcessVertex
+//purpose  : 
+//=======================================================================
+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);
+  }
+}
diff --git a/src/BRepFill/BRepFill_AdvancedEvolved.hxx b/src/BRepFill/BRepFill_AdvancedEvolved.hxx
new file mode 100644 (file)
index 0000000..3df98e8
--- /dev/null
@@ -0,0 +1,141 @@
+// 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_AdvancedEvolved_HeaderFile
+#define _BRepFill_AdvancedEvolved_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>
+#include <Standard_CString.hxx>
+
+class BOPAlgo_MakerVolume;
+class TopoDS_Face;
+
+//! Constructs an evolved volume from a spine (wire or face)
+//! and  a profile ( wire).
+class BRepFill_AdvancedEvolved
+{
+public:
+
+  DEFINE_STANDARD_ALLOC;
+
+  //! Constructor
+  Standard_EXPORT BRepFill_AdvancedEvolved() :myErrorStatus(BRepFill_AdvancedEvolved_Empty),
+                                              myFuzzyValue(0.0),
+                                              myIsParallel(Standard_True),
+                                              myDebugShapesPath("C:\\Temp")
+  {
+  }
+  
+  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_AdvancedEvolved_OK);
+  }
+
+  //! returns the resulting shape.
+  const TopoDS_Shape& Shape() const
+  {
+    return myResult;
+  }
+  
+  //! Sets directory where the debug shapes will be saved
+  void SetTemporaryDirectory(const Standard_CString& thePath)
+  {
+    myDebugShapesPath = thePath;
+  }
+
+  //! Sets/Unsets computation in parallel mode
+  void SetParallelMode(const Standard_Boolean theVal)
+  {
+    myIsParallel = theVal;
+  }
+
+protected:
+
+  Standard_EXPORT void PerformSweep();
+
+  Standard_EXPORT void GetLids();
+
+  Standard_EXPORT void BuildSolid();
+
+  Standard_EXPORT void RemoveExcessSolids(const TopTools_ListOfShape& theLSplits,
+                                          const 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);
+
+  Standard_EXPORT void UnifyShape();
+
+  Standard_EXPORT Standard_Boolean PerformBoolean(const TopTools_ListOfShape& theArgsList,
+                                                  TopoDS_Shape& theResult) const;
+
+  Standard_EXPORT Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF,
+                                                          const Standard_Real theFuzzyToler,
+                                                          TopTools_ListOfShape& theListOfFaces,
+                                                          TopTools_ListOfShape& theListOfSplits) const;
+
+  Standard_EXPORT Standard_Boolean IsLid(const TopoDS_Face& theF,
+                                         const TopTools_IndexedMapOfShape& theMapOfLids) const;
+
+private:
+
+  enum
+  {
+    BRepFill_AdvancedEvolved_Empty = 0,
+    BRepFill_AdvancedEvolved_NotPlanarSpine,
+    BRepFill_AdvancedEvolved_SweepError,
+    BRepFill_AdvancedEvolved_NoLids,
+    BRepFill_AdvancedEvolved_NotSolid,
+    BRepFill_AdvancedEvolved_NotVolume,
+    BRepFill_AdvancedEvolved_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;
+  Standard_Boolean myIsParallel;
+  Standard_CString myDebugShapesPath;
+
+};
+
+
+
+
+
+
+
+#endif // _BRepFill_AdvancedEvolved_HeaderFile
index 44c31e9..6fd49ec 100644 (file)
@@ -690,7 +690,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;
@@ -744,8 +744,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 d5e9439..7b110d0 100644 (file)
@@ -19,6 +19,7 @@
 #include <Approx_CurveOnSurface.hxx>
 #include <Approx_SameParameter.hxx>
 #include <Bnd_Box.hxx>
+#include <BOPTools_AlgoTools.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_CurveRepresentation.hxx>
 #include <BRep_GCurve.hxx>
@@ -702,7 +703,7 @@ static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d,
                             const Standard_Real l,
                             const Standard_Real Tol3d)
 {
-  gp_Pnt P1, P2, P;
+  gp_Pnt P;
   Standard_Real Tol1, Tol2, Tol, d;
 // Class BRep_Tool without fields and without Constructor :
 //  BRep_Tool BT;
@@ -710,11 +711,11 @@ static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d,
   TopoDS_Edge E;
 
 //  P1  = BT.Pnt(VF);
-  P1  = BRep_Tool::Pnt(VF);
+  const gp_Pnt P1  = BRep_Tool::Pnt(VF);
 //  Tol1 = BT.Tolerance(VF);
   Tol1 = BRep_Tool::Tolerance(VF);
 //  P2  = BT.Pnt(VL);
-  P2  = BRep_Tool::Pnt(VL);
+  const gp_Pnt P2  = BRep_Tool::Pnt(VL);
 //  Tol2 = BT.Tolerance(VF);
   Tol2 = BRep_Tool::Tolerance(VL);
   Tol = Max(Tol1, Tol2);
@@ -750,8 +751,6 @@ static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d,
   if (d > Tol1)
       B.UpdateVertex(VF, d);
 
-//  P1 = BT.Pnt(VL);
-  P1 = BRep_Tool::Pnt(VL);
   C3d->D0(l, P);
   d = P2.Distance(P);
   if (d > Tol2)
@@ -777,6 +776,19 @@ static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d,
   TopLoc_Location Loc;
   B.UpdateEdge(E, C2d, S, Loc, Tol3d);
 
+  const Handle(IntTools_Context) aNullCtx;
+  if (BOPTools_AlgoTools::IsMicroEdge(E, aNullCtx))
+  {
+    TopoDS_Vertex aV = VF;
+    B.UpdateVertex(aV, P1.Distance(P2));
+    B.MakeEdge(E);
+    B.UpdateEdge(E, C2d, S, TopLoc_Location(), Tol);
+    B.Add(E, TopoDS::Vertex(aV.Oriented(TopAbs_FORWARD)));
+    B.Add(E, TopoDS::Vertex(aV.Oriented(TopAbs_REVERSED)));
+    B.Range(E, f, l);
+    B.Degenerated(E, Standard_True);
+  }
+
   return E;
 }
 
@@ -914,7 +926,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 +1827,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
                               const Standard_Boolean WithKPart) : 
                               isDone(Standard_False),
                               KPart(WithKPart)
-
-
 {
  mySec = Section;
  myLoc = Location;
@@ -3380,7 +3390,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 b3b003a..72b1897 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;
 
-
 };
 
 
index ebba998..9289a69 100644 (file)
@@ -2,6 +2,8 @@ BRepFill.cxx
 BRepFill.hxx
 BRepFill_ACRLaw.cxx
 BRepFill_ACRLaw.hxx
+BRepFill_AdvancedEvolved.cxx
+BRepFill_AdvancedEvolved.hxx
 BRepFill_ApproxSeewing.cxx
 BRepFill_ApproxSeewing.hxx
 BRepFill_CompatibleWires.cxx
index 10310e6..1b7612b 100644 (file)
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS.hxx>
+#include <Standard_NotImplemented.hxx>
+
+static const TopTools_ListOfShape anEmptyList;
 
 //=======================================================================
-//function : BRepOffsetAPI_MakeEvolved
+//function : Constructor
 //purpose  : 
 //=======================================================================
 BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved()
 {
 }
 
-
 //=======================================================================
-//function : BRepOffsetAPI_MakeEvolved
+//function : Constructor
 //purpose  : 
 //=======================================================================
-
-BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Wire&     Spine,
-                                        const TopoDS_Wire&     Profil, 
-                                        const GeomAbs_JoinType Join,
-                                        const Standard_Boolean AxeProf,
-                                        const Standard_Boolean Solid,
-                                        const Standard_Boolean ProfOnSpine,
-                                        const Standard_Real    Tol)
+BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Shape&    Spine,
+                                                     const TopoDS_Wire&     Profil,
+                                                     const GeomAbs_JoinType Join,
+                                                     const Standard_Boolean AxeProf,
+                                                     const Standard_Boolean Solid,
+                                                     const Standard_Boolean ProfOnSpine,
+                                                     const Standard_Real    Tol,
+                                                     const Standard_Boolean theIsVolume,
+                                                     const Standard_Boolean theRunInParallel)
+  : myIsVolume (theIsVolume)
 {
-  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 (Spine.ShapeType() != TopAbs_WIRE && Spine.ShapeType() != TopAbs_FACE)
+  {
+    Standard_TypeMismatch::Raise ("BRepOffsetAPI_MakeEvolved: face or wire is expected as a spine");
   }
-
-  myEvolved.Perform(Spine,Profil,Axis,Join,Solid);
-  Build();
-  Done();
-}
-
-
-//=======================================================================
-//function : BRepOffsetAPI_MakeEvolved
-//purpose  : 
-//=======================================================================
-
-BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Face&     Spine,
-                                        const TopoDS_Wire&     Profil,
-                                        const GeomAbs_JoinType Join,
-                                        const Standard_Boolean AxeProf,
-                                        const Standard_Boolean Solid,
-                                        const Standard_Boolean ProfOnSpine,
-                                        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.SetParallelMode(theRunInParallel);
+    TopoDS_Wire aSpine;
+    if (Spine.ShapeType() == TopAbs_WIRE)
+    {
+      aSpine = TopoDS::Wire(Spine);
+    }
+    else
+    {
+      aSpine = TopoDS::Wire(TopoDS_Iterator(Spine).Value());
+    }
+    myVolume.Perform(aSpine, Profil, Tol, Solid);
+    if (!myVolume.IsDone())
+    {
+      return;
+    }
+  }
+  else
+  {
+    gp_Ax3 Axis(gp::Origin(), gp::DZ(), gp::DX());
+
+    if (!AxeProf)
+    {
+      Standard_Boolean POS;
+      BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion()));
+      if (ProfOnSpine && !POS) return;
+    }
+    if (Spine.ShapeType() == TopAbs_WIRE)
+    {
+      myEvolved.Perform(TopoDS::Wire(Spine), Profil, Axis, Join, Solid);
+    }
+    else
+    {
+      myEvolved.Perform(TopoDS::Face(Spine), Profil, Axis, Join, Solid);
+    }
   }
 
-  myEvolved.Perform(Spine,Profil,Axis,Join,Solid);
   Build();
 }
 
-
 //=======================================================================
 //function : BRepFill_Evolved&
 //purpose  : 
 //=======================================================================
 
-const BRepFill_Evolved& BRepOffsetAPI_MakeEvolved::Evolved() const 
+const BRepFill_Evolved& BRepOffsetAPI_MakeEvolved::Evolved() const
 {
+  if (myIsVolume)
+  {
+    Standard_TypeMismatch::Raise ("BRepOffsetAPI_MakeEvolved: myEvolved is accessed while in volume mode");
+  }
   return myEvolved;
 }
 
-
 //=======================================================================
-//function :
+//function : Build
 //purpose  : 
 //=======================================================================
-
 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();
 }
 
-
 //=======================================================================
 //function : Top
 //purpose  : 
 //=======================================================================
-
 const TopoDS_Shape&  BRepOffsetAPI_MakeEvolved::Top() const 
 {
   return myEvolved.Top();
@@ -126,7 +141,6 @@ const TopoDS_Shape&  BRepOffsetAPI_MakeEvolved::Top() const
 //function : Bottom
 //purpose  : 
 //=======================================================================
-
 const TopoDS_Shape&  BRepOffsetAPI_MakeEvolved::Bottom() const 
 {
   return myEvolved.Bottom();
@@ -136,11 +150,12 @@ const TopoDS_Shape&  BRepOffsetAPI_MakeEvolved::Bottom() const
 //function : GeneratedShapes
 //purpose  : 
 //=======================================================================
-
-const TopTools_ListOfShape&  BRepOffsetAPI_MakeEvolved::GeneratedShapes ( 
-   const TopoDS_Shape& SpineShape,
-   const TopoDS_Shape& ProfShape )
-const 
+const TopTools_ListOfShape&
+        BRepOffsetAPI_MakeEvolved::GeneratedShapes(const TopoDS_Shape& SpineShape,
+                                                   const TopoDS_Shape& ProfShape) const 
 {
+  if (!myEvolved.IsDone())
+    return anEmptyList;
+
   return myEvolved.GeneratedShapes(SpineShape,ProfShape);
 }
index fc778e3..ea2e106 100644 (file)
@@ -22,6 +22,7 @@
 #include <Standard_Handle.hxx>
 
 #include <BRepFill_Evolved.hxx>
+#include <BRepFill_AdvancedEvolved.hxx>
 #include <BRepBuilderAPI_MakeShape.hxx>
 #include <GeomAbs_JoinType.hxx>
 #include <Standard_Boolean.hxx>
@@ -43,20 +44,42 @@ class TopoDS_Shape;
 //! - implementing the construction algorithm, and
 //! - consulting the result.
 //! Computes an Evolved by
-//! 1 - sweeping a profil along a spine.
+//! 1 - sweeping a profile along a spine.
 //! 2 - removing the self-intersections.
 //!
+//! The Profile is expected to be planar and can be a line
+//! (which lies in infinite number of planes).
+//!
 //! The profile is defined in a Referential R. The position of
 //! the profile at the current point of the  spine is given by
 //! confusing R  and the local  referential given by (  D0, D1
-//! and the normal of the Spine)
+//! and the normal of the Spine).
 //!
-//! If the Boolean <AxeProf> is  true, R is  O,X,Y,Z
-//! else R is defined as the local refential at the nearest
-//! point of the profil to the spine.
+//! The coordinate system is determined by theIsAxeProf argument:
+//! - if theIsAxeProf is true, R is the global coordinate system,
+//! - if theIsAxeProf is false, R is computed so that:
+//!     * its origin is given by the point on the spine which is
+//!         closest to the profile,
+//!     * its "X Axis" is given by the tangent to the spine at this point, and
+//!     * its "Z Axis" is the normal to the plane which contains the spine.
 //!
-//! if <Solid> is TRUE the Shape result  is completed to be a
+//! theJoinType defines the type of pipe generated by the salient
+//! vertices of the spine. The default type is GeomAbs_Arc
+//! where the vertices generate revolved pipes about the
+//! axis passing along the vertex and the normal to the
+//! plane of the spine. At present, this is the only
+//! construction type implemented.
+//! 
+//! if <theIsSolid> is TRUE the Shape result is completed to be a
 //! solid or a compound of solids.
+//! 
+//! If theIsProfOnSpine == TRUE then the profile must connect with the spine.
+//!
+//! If theIsVolume option is switched on then self-intersections
+//! in the result of Pipe-algorithm will be removed by 
+//! BOPAlgo_MakerVolume algorithm. At that the arguments
+//! "theJoinType", "theIsAxeProf", "theIsProfOnSpine" are not used.
+
 class BRepOffsetAPI_MakeEvolved  : public BRepBuilderAPI_MakeShape
 {
 public:
@@ -66,29 +89,19 @@ 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);
-  
-  //! These constructors construct an evolved shape by sweeping the profile
-  //! Profile along the spine Spine.
-  //! The profile is defined in a coordinate system R.
-  //! The coordinate system is determined by AxeProf:
-  //! - if AxeProf is true, R is the global coordinate system,
-  //! - if AxeProf is false, R is computed so that:
-  //! - its origin is given by the point on the spine which is
-  //! closest to the profile,
-  //! - its "X Axis" is given by the tangent to the spine at this point, and
-  //! - its "Z Axis" is the normal to the plane which contains the spine.
-  //! The position of the profile at the current point of the
-  //! spine is given by making R coincident with the local
-  //! coordinate system given by the current point, the
-  //! tangent vector and the normal to the spine.
-  //! Join defines the type of pipe generated by the salient
-  //! vertices of the spine. The default type is GeomAbs_Arc
-  //! where the vertices generate revolved pipes about the
-  //! 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);
+  //! Constructs an evolved shape by sweeping the profile
+  //! (theProfile) along the spine (theSpine).
+  //! theSpine can be shape only of type wire or face.
+  //! See description to this class for detailed information.
+  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Shape& theSpine,
+                                            const TopoDS_Wire& theProfile,
+                                            const GeomAbs_JoinType theJoinType = GeomAbs_Arc,
+                                            const Standard_Boolean theIsAxeProf = Standard_True,
+                                            const Standard_Boolean theIsSolid = Standard_False,
+                                            const Standard_Boolean theIsProfOnSpine = Standard_False,
+                                            const Standard_Real theTol = 0.0000001,
+                                            const Standard_Boolean theIsVolume = Standard_False,
+                                            const Standard_Boolean theRunInParallel = Standard_False);
   
   Standard_EXPORT const BRepFill_Evolved& Evolved() const;
   
@@ -118,9 +131,9 @@ protected:
 private:
 
 
-
   BRepFill_Evolved myEvolved;
-
+  BRepFill_AdvancedEvolved myVolume;
+  Standard_Boolean myIsVolume;
 
 };
 
index c24c817..ef0343c 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 305160d..1daf865 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.
@@ -285,7 +285,6 @@ private:
 
   Handle(BRepFill_PipeShell) myPipe;
 
-
 };
 
 
index 3ed5f73..b292f75 100644 (file)
@@ -263,49 +263,99 @@ static Standard_Integer geompipe(Draw_Interpretor&,
 Standard_Integer evolved(Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
   if (n == 1) {
-    //cout << " 1) evolved result base profil : "<< endl;
-    //cout << "        The relative position of the profil on the base" << endl;
-    //cout << "        is given in the referencial axis. " << endl;
-    //cout << " 2) evolved result base profil o : "<< endl;
-    //cout << "        This position is automatically computed." << endl;
-    di << " 1) evolved result base profil : \n";
-    di << "        The relative position of the profil on the base\n";
-    di << "        is given in the referencial axis. \n";
-    di << " 2) evolved result base profil o : \n";
-    di << "        This position is automatically computed.\n";
+    di << " evolved result -s spine -p profile [-solid] [-v] [-a] [-t toler] [-parallel] : \n";
+    di << "   Make evolved profile on spine.\n";
+    di << "   -solid means make closed solid.\n";
+    di << "   -v means use alternative algorithm (volume mode).\n";
+    di << "   -a means referencial CS is automatically computed, otherwise global CS is used. \n";
+    di << "   -t sets the tolerance.\n";
+    di << "   -parallel turns on parallel execution.\n";
     return 0;
   }
 
   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;
+  Standard_Boolean isParallel = Standard_True;
+
+  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;
+    }
 
+    if (!strcmp(a[i], "-stm"))
+    {
+      isParallel = Standard_False;
+      continue;
+    }
 
+    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);
+        }
+      }
+      break;
 
-  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;
+      case 'p':
+      {
+        Prof = TopoDS::Wire(DBRep::Get(a[++i], TopAbs_WIRE, Standard_False));
+      }
+      break;
 
-  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;
+      case 'v':
+      {
+        isVolume = Standard_True;
+      }
+      break;
+
+      case 'a':
+      {
+        hasToComputeAxes = Standard_True;
+      }
+      break;
 
-  if (IsAFace) {
-    TopoDS_Shape Volevo
-      = BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base), Prof, GeomAbs_Arc, n == 4, Solid);
-    DBRep::Set(a[1], Volevo);
+      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 << "spine (face or wire) and profile (wire) are expected\n";
+    return 1;
   }
 
+  TopoDS_Shape Volevo = BRepOffsetAPI_MakeEvolved(Base, Prof, GeomAbs_Arc, !hasToComputeAxes,
+                                                  Solid, Standard_False, 
+                                                  aTolerance, isVolume, isParallel);
+
+  DBRep::Set(a[1],Volevo);
+
   return 0;
 }
 
@@ -945,10 +995,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 58f0de3..418d65e 100644 (file)
@@ -144,7 +144,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 dd326dc..76c2b8c 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 d36810d..77fab06 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 72b5716..8abebaf 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 c2cdf9b..404fca3 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..7da1432
--- /dev/null
@@ -0,0 +1,13 @@
+# To prevent loops limit to 10 minutes
+cpulimit 600
+
+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..f2d62f5
--- /dev/null
@@ -0,0 +1,20 @@
+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 result -s a -p b -a
+checkshape result
+
+checkprops result -s 558.33
+
+smallview
+don result a b
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/evolved/evolved/bug26470_2 b/tests/evolved/evolved/bug26470_2
new file mode 100644 (file)
index 0000000..102fd86
--- /dev/null
@@ -0,0 +1,20 @@
+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 result -s a -p b -a
+checkshape result
+
+checkprops result -s 572.14
+
+smallview
+don result a b
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
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..adfad86
--- /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 1573.58 -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..cf30b9c
--- /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 162.361 -v 95.3333
+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.5000000368888203e-007
+
+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..2431799
--- /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 361.087 -v 312.848
+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 3.0e-007 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..8714d8f
--- /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 142.657 -v 39.1789
+checkshape result
+
+checknbshapes result -solid 2 -shell 2
+
+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/HMC001 b/tests/evolved/voluved/HMC001
new file mode 100644 (file)
index 0000000..dfbaca3
--- /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.00010921129251073595
+
+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..60846bd
--- /dev/null
@@ -0,0 +1,30 @@
+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"
+}
+
+# Attention. Tolerance > 1 is quite big. However,
+# the dimensions of the shape "result" are about 1.0e+5.
+# So, this tolerance seems to be OK.
+
+checkmaxtol result -ref 1.000010000005457
+
+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..dbd8905
--- /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 2.8631382131562824e-006
+
+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..aa0f698
--- /dev/null
@@ -0,0 +1,229 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+cpulimit 100
+
+puts "TODO OCC30438 ALL: Error : The area of result shape is"
+puts "TODO OCC30438 ALL: Error : The volume of result shape is"
+puts "TODO OCC30438 ALL: Error :  is WRONG because number of SHELL"
+puts "TODO OCC30438 ALL: Error :  is WRONG because number of SOLID"
+puts "TODO OCC30438 ALL: Error: bopargcheck has found some faulties in result"
+
+
+restore [locate_data_file bug29523_cut_extrudewire07.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire07.brep] tw
+
+# Indeed the source shapes are invalid for evolved algorithm
+# (they contain gaps and discontinuous wire). Therefore, we
+# make them valid with following script.
+
+# Clear variables
+foreach a [directory cur_*] {unset $a}
+foreach a [directory ee*] {unset $a}
+
+# Obtain edges from the wire sw and copy their geometry (3D-curve cur_*) to the new edges ee*
+set NbEdges [llength [ explode sw e ]]
+for {set i 1} { $i <= $NbEdges} {incr i} { mkcurve cur_$i sw_$i } 
+for {set i 1} { $i <= $NbEdges} {incr i} { mkedge ee$i cur_$i } 
+
+# Extend every 3D-curve to cover the gap
+trim cur_1 cur_1 4.71239090823492 5.53811019613953
+trim cur_2 cur_2 -0.134931759799294 7999.99999936156
+trim cur_3 cur_3 1.57079573067402 2.39667036644493
+trim cur_4 cur_4 2.3157179964798 3.14159386656777
+trim cur_6 cur_6 3.14159205618886 3.96746669323983
+trim cur_7 cur_7 3.8865143232747 4.71239019354553
+trim cur_9 cur_9 4.71238838316655 5.53826302003487
+trim cur_10 cur_10 1.49677804444134e-010 357.366033033755
+trim cur_11 cur_11 5.467579522113 6.28318530589953
+trim cur_12 cur_12 -4.48015052825212e-005 496000.040846485
+trim cur_13 cur_13 5.83654858656781e-007 0.826061103391988
+
+
+foreach a {{1 2} {3 4} {6 7} {9 10} {10 11} {12 13} {1 13}} {
+  set i [lindex $a 0]
+  set j [lindex $a 1]
+
+  explode sw_$i v
+  explode sw_$j v
+
+  mkedge ee$i cur_$i
+  mkedge ee$j cur_$j
+  emptycopy ee$i ee$i
+  emptycopy ee$j ee$j
+
+  if {[regexp "REVERSED" [whatis sw_$i]]} {
+    orientation ee$i R
+  } else {
+    orientation ee$i F  
+  }
+  
+  if {[regexp "REVERSED" [whatis sw_$j]]} {
+    orientation ee$j R
+  } else {
+    orientation ee$j F  
+  }
+
+  add sw_${i}_1 ee$i
+  add sw_${i}_2 ee$i
+  add sw_${j}_1 ee$j
+  add sw_${j}_2 ee$j 
+}
+
+# Create new wire without any gaps
+
+bclearobjects 
+bcleartools
+eval baddobjects [directory ee*]
+bfillds
+bbuild rr
+edgestowire ww rr
+
+settolerance ww 1.0e-7
+
+mkplane pl ww
+explode pl w
+copy pl_1 sw
+
+# Eliminate not smoothness joint between two circles.
+# For that, every pair of circles will be joined by their common tangent.
+# So, smoothness joint will be provided automatically.
+
+# Clear variables
+foreach a [directory cur_*] {unset $a}
+foreach a [directory ee*] {unset $a}
+foreach a [directory sw_*] {unset $a}
+
+# Obtain edges from the wire sw and copy their geometry (3D-curve cur_*) to the new edges ee*
+set NbEdges [llength [ explode sw e ]]
+for {set i 1} { $i <= $NbEdges} {incr i} { mkcurve cur_$i sw_$i } 
+for {set i 1} { $i <= $NbEdges} {incr i} { mkedge ee$i cur_$i } 
+
+# Empty compound
+compound ce
+
+#Process circles sw_1 and sw_2
+
+# Trim every circle to the tangent point
+trim cur_1 cur_1 4.71239090823492 5.49761669005051
+trim cur_2 cur_2 5.83654858656781e-007 0.785568617129074
+
+# Fill the created gap by line
+line ccf1l2 -24754.1762623319 0 34741.3413352011 2003.1995336714681 0 2003.8825557731907
+trim ccf1l2 ccf1l2 0 2833.43495937946
+
+# Recreate necessary edges
+mkedge ee1 cur_1
+mkedge ee2 cur_2
+mkedge el12 ccf1l2
+
+# Add new (linear edge to compound)
+add el12 ce
+
+# Process circles sw_4 and sw_6.
+# Note that these circles are joined by the line sw_5.
+# This line is too small. Therefore it should be eliminated.
+
+unset ee5
+
+# Trim every circle to the tangent point
+trim cur_4 cur_4 5.49750649442623 6.28318530589953
+trim cur_6 cur_6 4.71238838316655 5.49750649442623
+
+# Fill the created gap by line
+line ccf4l6 522755.595179584 0 36741.7037941423 2000.8085436843103 0 -2001.9319102431036
+trim ccf4l6 ccf4l6 0 2830.365029767315
+
+# Recreate necessary edges
+mkedge ee4 cur_4
+mkedge ee6 cur_6
+mkedge el46 ccf4l6
+
+# Add new (linear edge to compound)
+add el46 ce
+
+# Process circles sw_8 and sw_9."
+# It is made analogically to the step 11.1.
+
+# Trim every circle to the tangent point
+trim cur_8 cur_8 3.92695569467718 4.71239019354553
+trim cur_9 cur_9 3.14159205618886 3.92695569467718
+
+# Fill the created gap by line
+line ccf8l9 522745.848826566 0 -24750.3286992239 2002.755997602304 0 2002.754818110996
+trim ccf8l9 ccf8l9 0 2832.3238599070564
+
+# Recreate necessary edges
+mkedge ee8 cur_8
+mkedge ee9 cur_9
+mkedge el89 ccf8l9
+
+# Add new (linear edge to compound)
+add el89 ce
+
+# Process circles sw_11 and sw_12
+# It is made analogically to the step 11.1.
+
+# Trim every circle to the tangent point
+trim cur_11 cur_11 2.3561593678824 3.14159386656777
+trim cur_12 cur_12 1.57079573067402 2.3561593678824
+
+# Fill the created gap by line
+line ccf11l12 -24750.328699221 0 -22745.8488265693 2002.7548181108614 0 -2002.7559976021548
+trim ccf11l12 ccf11l12 0 2832.323859906856
+
+# Recreate necessary edges
+mkedge ee11 cur_11
+mkedge ee12 cur_12
+mkedge el1112 ccf11l12
+
+# Add new (linear edge to compound)
+add el1112 ce
+
+# Build wire from compound of edges"
+foreach a [directory ee*] {add $a ce}
+
+bclearobjects 
+bcleartools
+eval baddcompound ce
+bfillds
+bbuild rr
+edgestowire ww rr
+
+# Check planarity
+mkplane pl ww
+explode pl w
+copy pl_1 sw
+
+
+tscale sw 0 0 0 1.0e-3
+tscale tw 0 0 0 1.0e-3
+removeloc sw sw
+removeloc tw tw
+
+evolved result -s sw -p tw -solid -a -v
+
+tscale result 0 0 0 1000
+
+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 result"
+}
+
+# Attention. Tolerance > 1 is quite big. However,
+# the dimensions of the shape "result" are about 1.0e+5.
+# So, this tolerance seems to be OK.
+
+checkmaxtol result -ref 18.634531507134731
+
+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..98a5ea4
--- /dev/null
@@ -0,0 +1,236 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+restore [locate_data_file bug29523_cut_extrudewire08.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire08.brep] tw
+
+# Indeed the source shapes are invalid for evolved algorithm
+# (they contain gaps and discontinuous wire). Therefore, we
+# make them valid with following script.
+
+# Clear variables
+foreach a [directory cur_*] {unset $a}
+foreach a [directory ee*] {unset $a}
+
+# Obtain edges from the wire sw and copy their geometry (3D-curve cur_*) to the new edges ee*
+set NbEdges [llength [ explode sw e ]]
+for {set i 1} { $i <= $NbEdges} {incr i} { mkcurve cur_$i sw_$i } 
+for {set i 1} { $i <= $NbEdges} {incr i} { mkedge ee$i cur_$i } 
+
+trim cur_1 cur_1 6.57409148379884e-010 25541.868037099
+trim cur_2 cur_2 0.488694408745945 1.07405488703373
+trim cur_3 cur_3 0.985620666922634 1.57079843167744
+trim cur_5 cur_5 1.57079573067402 2.39667036644493
+trim cur_6 cur_6 2.3157179964798 3.14159386656777
+trim cur_8 cur_8 3.14159205618886 3.96746669323982
+trim cur_9 cur_9 3.88651432327475 4.7123901935455
+trim cur_11 cur_11 4.71238838316667 5.53826302003462
+trim cur_12 cur_12 -7.31217388895948e-010 357.366033033913
+trim cur_13 cur_13 5.46757952211301 6.28318530589953
+trim cur_14 cur_14 -4.48015052825212e-005 473931.684018372
+trim cur_15 cur_15 1.20053942593701e-006 0.486331243523059
+
+foreach a {{1 2} {2 3} {5 6} {8 9} {11 12} {12 13} {14 15} {1 15}} {
+  set i [lindex $a 0]
+  set j [lindex $a 1]
+
+  explode sw_$i v
+  explode sw_$j v
+
+  mkedge ee$i cur_$i
+  mkedge ee$j cur_$j
+  emptycopy ee$i ee$i
+  emptycopy ee$j ee$j
+
+  if {[regexp "REVERSED" [whatis sw_$i]]} {
+    orientation ee$i R
+  } else {
+    orientation ee$i F  
+  }
+  
+  if {[regexp "REVERSED" [whatis sw_$j]]} {
+    orientation ee$j R
+  } else {
+    orientation ee$j F  
+  }
+
+  add sw_${i}_1 ee$i
+  add sw_${i}_2 ee$i
+  add sw_${j}_1 ee$j
+  add sw_${j}_2 ee$j 
+}
+
+# Step 11. Create new wire without any gaps
+
+bclearobjects 
+bcleartools
+eval baddobjects [directory ee*]
+bfillds
+bbuild rr
+edgestowire ww rr
+
+settolerance ww 1.0e-7
+
+mkplane pl ww
+explode pl w
+copy pl_1 sw
+
+# Step 12. Eliminate not smoothness joint between two circles.
+# For that, every pair of circles will be joined by their common tangent.
+# So, smoothness joint will be provided automatically.
+
+# Clear variables
+foreach a [directory cur_*] {unset $a}
+foreach a [directory ee*] {unset $a}
+foreach a [directory sw_*] {unset $a}
+
+# Obtain edges from the wire sw and copy their geometry (3D-curve cur_*) to the new edges ee*
+set NbEdges [llength [ explode sw e ]]
+for {set i 1} { $i <= $NbEdges} {incr i} { mkcurve cur_$i sw_$i } 
+for {set i 1} { $i <= $NbEdges} {incr i} { mkedge ee$i cur_$i } 
+
+# Empty compound
+compound ce
+
+# Step 12.1. Process circles sw_3 and sw_5.
+# Note that these circles are joined by the line sw_4.
+# This line is too small. Therefore it should be eliminated.
+
+unset ee4
+
+# Trim every circle to the tangent point
+trim cur_3 cur_3 5.49750649442626 6.28318530589953
+trim cur_5 cur_5 4.71238838316667 5.49750649442626
+
+# Fill the created gap by line
+line ccf3l5 522755.595179583 0 84741.703794143 2000.808543679188 0 -2001.9319102384907
+trim ccf3l5 ccf3l5 0 2830.365029760431
+
+# Recreate necessary edges
+mkedge ee3 cur_3
+mkedge ee5 cur_5
+
+mkedge el35 ccf3l5
+
+# Add new (linear) edge to compound
+add el35 ce
+
+# Step 12.2. Process circles sw_7 and sw_8 
+
+# Trim every circle to the tangent point
+trim cur_7 cur_7 3.92695569468046 4.7123901935455
+trim cur_8 cur_8 3.14159205618886 3.92695569468046
+
+# Fill the created gap by line
+line ccf7l8 524748.604824248 0 -22747.573881033 -2002.755997600907 0 -2002.7548181097663
+trim ccf7l8 ccf7l8 0 2832.3238599051992
+
+# Recreate necessary edges
+mkedge ee7 cur_7
+mkedge ee8 cur_8
+
+mkedge el78 ccf7l8
+
+# Add new (linear) edge to compound
+add el78 ce
+
+# Step 11.3. Process circles sw_10 and sw_11.
+# It is made analogically to the step 12.2.
+
+# Trim every circle to the tangent point
+trim cur_10 cur_10 2.3561593678821 3.14159386656777
+trim cur_11 cur_11 1.57079573067402 2.3561593678821
+
+# Fill the created gap by line
+line ccf10l11 -24750.3286992284 0 -22745.8488265618 2002.7548181109923 0 -2002.7559976022822
+trim ccf10l11 ccf10l11 0 2832.3238599070387
+
+# Recreate necessary edges
+mkedge ee10 cur_10
+mkedge ee11 cur_11
+mkedge el1011 ccf10l11
+
+# Add new (linear edge to compound)
+add el1011 ce
+
+# Step 12.4. Process circles sw_13 and sw_14.
+# It is made analogically to the step 12.2.
+
+# Trim every circle to the tangent point
+trim cur_13 cur_13 1.02983856973504 1.57079843167744
+trim cur_14 cur_14 0.488694408745945 1.02983856973504
+
+# Fill the created gap by line
+line ccf13l14 -28409.9420261742 0 66073.105965381 -1593.2045777171916 0 -2652.1042208640938
+trim ccf13l14 ccf13l14 0 3093.8580485833795
+
+# Recreate necessary edges
+mkedge ee13 cur_13
+mkedge ee14 cur_14
+mkedge el1314 ccf13l14
+
+# Add new (linear edge to compound)
+add el1314 ce
+
+# Step 13. Join two lines (sw_15 and sw_2 with "smooth circle")
+trim cur_2 cur_2 -4.48015052825212e-005 473931.43880149431
+trim cur_15 cur_15 81.530450931155428 25541.868037099
+
+circle cur_1 2.406856119850569e+004, 0.000000000000000e+000, 6.000556224103060e+004 0 1 0 34994.3148920752
+trim cur_1 cur_1 -0.4886661927028566 0
+
+mkedge ee1 cur_1
+mkedge ee2 cur_2
+mkedge ee15 cur_15
+
+
+# Step 14. Build wire from compound of edges
+foreach a [directory ee*] {add $a ce}
+
+bclearobjects 
+bcleartools
+eval baddcompound ce
+bfillds
+bbuild rr
+edgestowire ww rr
+
+# Step 15. Check planarity
+mkplane pl ww
+explode pl w
+copy pl_1 sw
+
+#Step 15. Process of profile
+
+settolerance tw 1.0e-7
+mkplane pl tw
+explode pl w
+copy pl_1 tw
+
+tscale sw 0 0 0 1.0e-3
+tscale tw 0 0 0 1.0e-3
+removeloc sw sw
+removeloc tw tw
+
+evolved result -s sw -p tw -solid -a -v
+
+tscale result 0 0 0 1000
+
+
+checkprops result -s 2.13384e+011 -v 7.22142e+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 3.5169018900217868
+
+smallview
+don result sw tw
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
diff --git a/tests/evolved/voluved/HMC010 b/tests/evolved/voluved/HMC010
new file mode 100644 (file)
index 0000000..017e106
--- /dev/null
@@ -0,0 +1,28 @@
+puts "=========="
+puts "OCC29523"
+puts "=========="
+
+cpulimit 60
+
+restore [locate_data_file bug29523_cut_extrudewire09.brep] sw 
+restore [locate_data_file bug29523_cut_toolwire09.brep] tw
+
+evolved result -s sw -p tw -solid -a -v
+
+checkprops result -s 21088.8 -v 75993.1
+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.031968491076118669
+
+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..b1fcc37
--- /dev/null
@@ -0,0 +1,20 @@
+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 result -s a -p b -a -v
+checkshape result
+
+checkprops result -s 558.33
+
+smallview
+don result a b
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/evolved/voluved/bug26470_2 b/tests/evolved/voluved/bug26470_2
new file mode 100644 (file)
index 0000000..26120f6
--- /dev/null
@@ -0,0 +1,20 @@
+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 result -s a -p b -a -v
+checkshape result
+
+checkprops result -s 572.14
+
+smallview
+don result a b
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
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
+