]> OCCT Git - occt-copy.git/commitdiff
Patches CR0_720_HMWC
authornbv <nbv@opencascade.com>
Wed, 5 Dec 2018 10:29:06 +0000 (13:29 +0300)
committernbv <nbv@opencascade.com>
Wed, 5 Dec 2018 12:09:30 +0000 (15:09 +0300)
66 files changed:
src/BOPAlgo/BOPAlgo.msg
src/BOPAlgo/BOPAlgo_Alerts.hxx
src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx
src/BOPAlgo/BOPAlgo_PaveFiller.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_11.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
src/BOPDS/BOPDS_DS.cxx
src/BOPDS/BOPDS_DS.hxx
src/BOPTest/BOPTest_CheckCommands.cxx
src/BOPTools/BOPTools_AlgoTools2D.cxx
src/BRepFill/BRepFill_Pipe.cxx
src/BRepFill/BRepFill_PipeShell.cxx
src/BRepFill/BRepFill_PipeShell.hxx
src/BRepFill/BRepFill_Section.cxx
src/BRepFill/BRepFill_Section.hxx
src/BRepFill/BRepFill_Section.lxx
src/BRepFill/BRepFill_Sweep.cxx
src/BRepFill/BRepFill_Sweep.hxx
src/BRepFill/BRepFill_TrimShellCorner.cxx
src/BRepFill/BRepFill_TrimShellCorner.hxx
src/BRepFill/BRepFill_Voluved.cxx [new file with mode: 0644]
src/BRepFill/BRepFill_Voluved.hxx [new file with mode: 0644]
src/BRepFill/FILES
src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx
src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx
src/BRepTest/BRepTest_SweepCommands.cxx
src/BRepTest/QABugs_20.cxx [new file with mode: 0644]
src/DrawResources/CheckCommands.tcl
src/Font/Font_BRepFont.cxx
src/Font/Font_FTFont.cxx
src/Font/Font_FTFont.hxx
src/Font/Font_FontMgr.cxx
src/Font/Font_SystemFont.cxx
src/Font/Font_SystemFont.hxx
src/Geom/Geom_ConicalSurface.cxx
src/Geom/Geom_ConicalSurface.hxx
src/GeomLib/GeomLib.cxx
src/GeomLib/GeomLib.hxx
src/Image/Image_VideoRecorder.cxx
src/IntWalk/IntWalk_PWalking.cxx
src/IntWalk/IntWalk_PWalking.hxx
src/LocOpe/LocOpe_DPrism.cxx
src/OpenGl/OpenGl_AVIWriter.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_AVIWriter.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_View_Redraw.cxx
src/Poly/Poly_IBuffer.cxx [new file with mode: 0644]
src/Poly/Poly_IBuffer.hxx [new file with mode: 0644]
src/Poly/Poly_IBuffer.lxx [new file with mode: 0644]
src/SelectMgr/SelectMgr_SelectionManager.cxx
src/Standard/Standard_GUID.cxx
src/StdSelect/StdSelect_Shape.cxx
src/TDF/TDF_Label.hxx
src/TDataXtd/TDataXtd_Presentation.cxx
src/TDataXtd/TDataXtd_Presentation.hxx
src/TPrsStd/TPrsStd_AISPresentation.cxx
src/TPrsStd/TPrsStd_AISPresentation.hxx
src/VrmlData/VrmlData_ShapeConvert.cxx
src/XmlMDF/XmlMDF.cxx
src/XmlMDataStd/XmlMDataStd_ExtStringArrayDriver.cxx
src/math/math_NewtonMinimum.cxx

index 67350fca885b8da67af2d250344852f7292e81aa..673a39ec422eb6ca65ce375a547e438dd4d875fe 100644 (file)
@@ -67,3 +67,12 @@ Warning: Removal of internal boundaries among Faces has failed
 
 .BOPAlgo_AlertRemovalOfIBForEdgesFailed
 Warning: Removal of internal boundaries among Edges has failed
+
+.BOPAlgo_AlertIntersectionOfPairOfShapesFailed
+Warning: Intersection of pair of shapes has failed
+
+.BOPAlgo_AlertBuildingPCurveFailed
+Warning: Building 2D curve of edge on face has failed
+
+.BOPAlgo_AlertAcquiredSelfIntersection
+Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered
index 02cec15f8fdff99caba10136c1a8423dc914aada..04ce9c7b4f51023661b807b64e0bc51fd1c89d13 100644 (file)
@@ -78,4 +78,14 @@ DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertShellSplitterFailed)
 //! Some edges are too small and have no valid range
 DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertTooSmallEdge)
 
+//! Intersection of pair of shapes has failed
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertIntersectionOfPairOfShapesFailed)
+
+//! Building 2D curve of edge on face has failed
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertBuildingPCurveFailed)
+
+//! Some sub-shapes of some of the argument become connected through
+//! other shapes and the argument became self-interfered
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertAcquiredSelfIntersection)
+
 #endif // _BOPAlgo_Alerts_HeaderFile
index c63a53875c5eed6a43de17fe623c51c541a8b49e..feec778809112d49ae33b2194f13500591714911 100644 (file)
@@ -69,4 +69,13 @@ static const char BOPAlgo_BOPAlgo_msg[] =
   "Warning: Removal of internal boundaries among Faces has failed\n"
   "\n"
   ".BOPAlgo_AlertRemovalOfIBForEdgesFailed\n"
-  "Warning: Removal of internal boundaries among Edges has failed\n";
+  "Warning: Removal of internal boundaries among Edges has failed\n"
+  "\n"
+  ".BOPAlgo_AlertIntersectionOfPairOfShapesFailed\n"
+  "Warning: Intersection of pair of shapes has failed\n"
+  "\n"
+  ".BOPAlgo_AlertBuildingPCurveFailed\n"
+  "Warning: Building 2D curve of edge on face has failed\n"
+  "\n"
+  ".BOPAlgo_AlertAcquiredSelfIntersection\n"
+  "Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered\n";
index 5867221f5e96d1c5267aacd2a237ca07cbf048a2..5c3b35cf926d93db8ffdba332b741a356eb8870a 100644 (file)
@@ -294,6 +294,8 @@ void BOPAlgo_PaveFiller::PerformInternal()
   //
   UpdateBlocksWithSharedVertices();
   //
+  myDS->RefineFaceInfoIn();
+  //
   MakeSplitEdges();
   if (HasErrors()) {
     return; 
index ab79f4ec98e9a4ccfddbf0a7cd919d1be745645d..bd4e512faec3dcb629e3cb1e6828e11e4348f58e 100644 (file)
@@ -87,13 +87,19 @@ class TopoDS_Face;
 //! - *Gluing options* - allows to speed up the calculation on the special
 //!                      cases, in which some sub-shapes are coincide.<br>
 //!
-//! The algorithm returns the following Warning statuses:<br>
-//! - *BOPAlgo_AlertSelfInterferingShape* - in case some of the argument shapes are self-interfering shapes;<br>
-//! - *BOPAlgo_AlertTooSmallEdge* - in case some edges of the input shapes have no valid range;<br>
+//! The algorithm returns the following Warning statuses:
+//! - *BOPAlgo_AlertSelfInterferingShape* - in case some of the argument shapes are self-interfering shapes;
+//! - *BOPAlgo_AlertTooSmallEdge* - in case some edges of the input shapes have no valid range;
 //! - *BOPAlgo_AlertNotSplittableEdge* - in case some edges of the input shapes has such a small
-//!                         valid range so it cannot be split;<br>
+//!                                      valid range so it cannot be split;
 //! - *BOPAlgo_AlertBadPositioning* - in case the positioning of the input shapes leads to creation
-//!                      of small edges.<br>
+//!                                   of small edges;
+//! - *BOPAlgo_AlertIntersectionOfPairOfShapesFailed* - in case intersection of some of the
+//!                                                     sub-shapes has failed;
+//! - *BOPAlgo_AlertAcquiredSelfIntersection* - in case some sub-shapes of the argument become connected
+//!                                             through other shapes;
+//! - *BOPAlgo_AlertBuildingPCurveFailed* - in case building 2D curve for some of the edges
+//!                                         on the faces has failed.
 //!
 //! The algorithm returns the following Error alerts:
 //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to
@@ -290,6 +296,7 @@ protected:
                                     BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges,
                                     BOPCol_DataMapOfIntegerInteger& theDMNewSD,
                                     const BOPCol_IndexedMapOfShape& theMicroEdges,
+                                    const BOPCol_IndexedMapOfShape& theVertsOnRejectedPB,
                                     const BOPCol_BaseAllocator& theAllocator);
   
   Standard_EXPORT void FindPaveBlocks (const Standard_Integer theV, const Standard_Integer theF, BOPDS_ListOfPaveBlock& theLPB);
@@ -474,6 +481,8 @@ protected:
   //! In case self-interference is found the warning is added.
   Standard_EXPORT void CheckSelfInterference();
 
+  //! Adds the warning about failed intersection of pair of sub-shapes
+  Standard_EXPORT void AddIntersectionFailedWarning(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2);
 
   BOPCol_ListOfShape myArguments;
   BOPDS_PDS myDS;
index c8341c5dd7bd1d279fa5fbb120412e89a82487ce..83faf2d1261d5454499ea796667258eb8051dd71 100644 (file)
@@ -112,7 +112,8 @@ void BOPAlgo_PaveFiller::CheckSelfInterference()
               }
               //
               if (aLE.Extent() > 1) {
-                // Add warning
+                // Add the acquired self-interference warning:
+                // The same common block contains several edges from one argument
                 TopoDS_Compound aWC;
                 aBB.MakeCompound(aWC);
                 //
@@ -122,7 +123,7 @@ void BOPAlgo_PaveFiller::CheckSelfInterference()
                   aBB.Add(aWC, aE1);
                 }
                 //
-                AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
+                AddWarning (new BOPAlgo_AlertAcquiredSelfIntersection (aWC));
               }
             }
           }
@@ -168,7 +169,8 @@ void BOPAlgo_PaveFiller::CheckSelfInterference()
     for (j = 1; j <= aNbC; ++j) {
       const BOPCol_IndexedMapOfShape& aMCS = aMCSI(j);
       if (aMCS.Extent() > 1) {
-        // Add self-interference warning
+        // Add acquired self-interference warning:
+        // Several faces from one argument contain the same vertex or edge
         TopoDS_Compound aWC;
         aBB.MakeCompound(aWC);
         //
@@ -177,7 +179,7 @@ void BOPAlgo_PaveFiller::CheckSelfInterference()
           const TopoDS_Shape& aSx = aMCS(iS);
           aBB.Add(aWC, aSx);
         }
-        AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
+        AddWarning (new BOPAlgo_AlertAcquiredSelfIntersection (aWC));
       }
     }
   }
index c4966683d94875f3c302647f50a1a6d599cc9c6d..9ac5e67ae7493a8934304254511d52fb61b15439 100644 (file)
@@ -17,6 +17,7 @@
 
 
 #include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPAlgo_Tools.hxx>
 #include <BOPCol_NCVector.hxx>
 #include <BOPCol_Parallel.hxx>
@@ -27,6 +28,7 @@
 #include <BOPDS_PaveBlock.hxx>
 #include <BOPDS_VectorOfInterfVE.hxx>
 #include <BOPTools_AlgoTools.hxx>
+#include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <gp_Pnt.hxx>
 #include <IntTools_Context.hxx>
@@ -110,7 +112,16 @@ class BOPAlgo_VertexEdge : public BOPAlgo_Algo {
   //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
-    myFlag=myContext->ComputeVE (myV, myE, myT, myTolVNew, myFuzzyValue);
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      myFlag=myContext->ComputeVE (myV, myE, myT, myTolVNew, myFuzzyValue);
+    }
+    catch (Standard_Failure)
+    {
+      AddError(new BOPAlgo_AlertIntersectionFailed);
+    }
   };
   //
  protected:
@@ -267,6 +278,11 @@ void BOPAlgo_PaveFiller::IntersectVE
   for (i = 0; i < aNbVE; ++i) {
     const BOPAlgo_VertexEdge& aVESolver = aVVE(i);
     if (aVESolver.Flag() != 0) {
+      if (aVESolver.HasErrors())
+      {
+        // Warn about failed intersection of sub-shapes
+        AddIntersectionFailedWarning(aVESolver.Vertex(), aVESolver.Edge());
+      }
       continue;
     }
     //
@@ -491,3 +507,19 @@ void BOPAlgo_PaveFiller::SplitPaveBlocks(const BOPCol_MapOfInteger& theMEdges,
     }
   }
 }
+
+//=======================================================================
+// function: AddIntersectionFailedWarning
+// purpose: 
+//=======================================================================
+void BOPAlgo_PaveFiller::AddIntersectionFailedWarning(const TopoDS_Shape& theS1,
+                                                      const TopoDS_Shape& theS2)
+{
+  // Create the warn shape
+  TopoDS_Compound aWC;
+  BRep_Builder().MakeCompound(aWC);
+  BRep_Builder().Add(aWC, theS1);
+  BRep_Builder().Add(aWC, theS2);
+  // Add the warning
+  AddWarning(new BOPAlgo_AlertIntersectionOfPairOfShapesFailed(aWC));
+}
\ No newline at end of file
index 3a8892e0beae6da45cf989f8bf5898cbbc71ca0c..5db97a8aff16879786f34c5a2f0421dd3afb367c 100644 (file)
@@ -93,7 +93,16 @@ class BOPAlgo_EdgeEdge :
   //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
-    IntTools_EdgeEdge::Perform();
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      IntTools_EdgeEdge::Perform();
+    }
+    catch (Standard_Failure)
+    {
+      AddError(new BOPAlgo_AlertIntersectionFailed);
+    }
   }
   //
  protected:
@@ -229,7 +238,11 @@ void BOPAlgo_PaveFiller::PerformEE()
     Bnd_Box aBB1, aBB2;
     //
     BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k);
-    if (!anEdgeEdge.IsDone()) {
+    if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors()) {
+      // Warn about failed intersection of sub-shapes
+      const TopoDS_Shape& aE1 = myDS->Shape(anEdgeEdge.PaveBlock1()->OriginalEdge());
+      const TopoDS_Shape& aE2 = myDS->Shape(anEdgeEdge.PaveBlock2()->OriginalEdge());
+      AddIntersectionFailedWarning(aE1, aE2);
       continue;
     }
     //
index 291edb2de862bcd14befeabe32c1fa90bd026fb3..900d363bbbee35b25d82ef74707c278153e46732 100644 (file)
@@ -17,6 +17,7 @@
 
 
 #include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPAlgo_SectionAttribute.hxx>
 #include <BOPCol_MapOfInteger.hxx>
 #include <BOPCol_NCVector.hxx>
@@ -107,7 +108,16 @@ class BOPAlgo_VertexFace : public BOPAlgo_Algo {
   //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
-    myFlag=myContext->ComputeVF(myV, myF, myT1, myT2, myTolVNew, myFuzzyValue);
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      myFlag=myContext->ComputeVF(myV, myF, myT1, myT2, myTolVNew, myFuzzyValue);
+    }
+    catch (Standard_Failure)
+    {
+      AddError(new BOPAlgo_AlertIntersectionFailed);
+    }
   }
   //
  protected:
@@ -212,7 +222,12 @@ void BOPAlgo_PaveFiller::PerformVF()
     const BOPAlgo_VertexFace& aVertexFace=aVVF(k);
     // 
     iFlag=aVertexFace.Flag();
-    if (iFlag) {
+    if (iFlag != 0) {
+      if (aVertexFace.HasErrors())
+      {
+        // Warn about failed intersection of sub-shapes
+        AddIntersectionFailedWarning(aVertexFace.Vertex(), aVertexFace.Face());
+      }
       continue;
     }
     //
index 84fc6d10d051aa9bf8e3ef376cea95851682623c..717e4789201074e96ceb27451f12dcc809876b73 100644 (file)
@@ -103,7 +103,16 @@ class BOPAlgo_EdgeFace :
   //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
-    IntTools_EdgeFace::Perform();
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      IntTools_EdgeFace::Perform();
+    }
+    catch (Standard_Failure)
+    {
+      AddError(new BOPAlgo_AlertIntersectionFailed);
+    }
   }
   //
  protected:
@@ -258,7 +267,9 @@ void BOPAlgo_PaveFiller::PerformEF()
   //
   for (k=0; k < aNbEdgeFace; ++k) {
     BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k);
-    if (!aEdgeFace.IsDone()) {
+    if (!aEdgeFace.IsDone() || aEdgeFace.HasErrors()) {
+      // Warn about failed intersection of sub-shapes
+      AddIntersectionFailedWarning(aEdgeFace.Edge(), aEdgeFace.Face());
       continue;
     }
     //
index bbc1b35c91637db6c2330a319094e55a7e95d821..dfbfe61954da6bc5bbb7c0154a3bddc1f189fa50 100644 (file)
@@ -144,7 +144,16 @@ class BOPAlgo_FaceFace :
   //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
-    IntTools_FaceFace::Perform(myF1, myF2);
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      IntTools_FaceFace::Perform(myF1, myF2);
+    }
+    catch (Standard_Failure)
+    {
+      AddError(new BOPAlgo_AlertIntersectionFailed);
+    }
   }
   //
  protected:
@@ -263,10 +272,12 @@ void BOPAlgo_PaveFiller::PerformFF()
   for (k = 0; k < aNbFaceFace; ++k) {
     BOPAlgo_FaceFace& aFaceFace = aVFaceFace(k);
     aFaceFace.Indices(nF1, nF2);
-    if (!aFaceFace.IsDone()) {
+    if (!aFaceFace.IsDone() || aFaceFace.HasErrors()) {
       BOPDS_InterfFF& aFF = aFFs.Append1();
       aFF.SetIndices(nF1, nF2);
       aFF.Init(0, 0);
+      // Warn about failed intersection of faces
+      AddIntersectionFailedWarning(aFaceFace.Face1(), aFaceFace.Face2());
       continue;
     }
     //
@@ -373,6 +384,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
   BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
   BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
+  BOPCol_IndexedMapOfShape aVertsOnRejectedPB;
   //
   for (i=0; i<aNbFF; ++i) {
     //
@@ -557,6 +569,19 @@ void BOPAlgo_PaveFiller::MakeBlocks()
             if (!bInBothFaces) {
               aMPBAdd.Add(aPBOut);
               PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
+              // Try fusing the vertices of the existing pave block
+              // with the vertices put on the real section curve (except
+              // for technological vertices, which will be removed)
+              Standard_Integer nVOut1, nVOut2;
+              aPBOut->Indices(nVOut1, nVOut2);
+              if (nV1 != nVOut1 && nV1 != nVOut2 && !aMVBounds.Contains(nV1))
+              {
+                aVertsOnRejectedPB.Add(aV1);
+              }
+              if (nV2 != nVOut1 && nV2 != nVOut2 && !aMVBounds.Contains(nV2))
+              {
+                aVertsOnRejectedPB.Add(aV2);
+              }
             }
           }
           continue;
@@ -639,7 +664,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   // 
   // post treatment
   MakeSDVerticesFF(aDMVLV, aDMNewSD);
-  PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
+  PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aVertsOnRejectedPB, aAllocator);
   if (HasErrors()) {
     return;
   }
@@ -697,6 +722,7 @@ void BOPAlgo_PaveFiller::PostTreatFF
      BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
      BOPCol_DataMapOfIntegerInteger& aDMNewSD,
      const BOPCol_IndexedMapOfShape& theMicroEdges,
+     const BOPCol_IndexedMapOfShape& theVertsOnRejectedPB,
      const Handle(NCollection_BaseAllocator)& theAllocator)
 {
   Standard_Integer aNbS = theMSCPB.Extent();
@@ -724,8 +750,9 @@ void BOPAlgo_PaveFiller::PostTreatFF
   BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
   //
   Standard_Integer aNbME = theMicroEdges.Extent();
+  Standard_Integer aNbVOnRPB = theVertsOnRejectedPB.Extent();
   // 0
-  if (aNbS==1 && (aNbME == 0)) {
+  if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0)) {
     const TopoDS_Shape& aS=theMSCPB.FindKey(1);
     const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
     //
@@ -824,6 +851,20 @@ void BOPAlgo_PaveFiller::PostTreatFF
       aBB.UpdateVertex(aVerts[1], aTolV2 + aDist);
     }
   }
+
+  // Add vertices put on the real section curves to unify them with the
+  // vertices of the edges, by which these sections curves have been rejected
+  for (Standard_Integer i = 1; i <= aNbVOnRPB; ++i)
+  {
+    TopoDS_Shape aVer = theVertsOnRejectedPB(i);
+    Standard_Integer iVer = myDS->Index(aVer);
+    const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
+    if (pSD)
+      aVer = myDS->Shape(*pSD);
+
+    if (anAddedSD.Add(aVer))
+      aLS.Append(aVer);
+  }
   //
   // 2 Fuse shapes
   aPF.SetProgressIndicator(myProgressIndicator);
index bf02175998c08f17e0c7d7fcd84c8896f5fe683e..1e91f5529ae7da1fc6d6f6b3b6b817bf554ec839 100644 (file)
@@ -16,6 +16,7 @@
 // commercial license or contractual agreement.
 
 #include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPAlgo_SectionAttribute.hxx>
 #include <BOPAlgo_Tools.hxx>
 #include <BOPCol_IndexedMapOfShape.hxx>
@@ -241,28 +242,37 @@ class BOPAlgo_MPC : public BOPAlgo_Algo  {
   }
   //
   virtual void Perform() {
-    Standard_Integer iErr;
-    //
-    iErr=1;
-    if (!myEz.IsNull()) {
-      TopoDS_Edge aSpz;
+    try
+    {
+      OCC_CATCH_SIGNALS
+
+      Standard_Integer iErr;
       //
-      BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1, 
-                                        myV2, myT2, aSpz);
+      iErr=1;
+      if (!myEz.IsNull()) {
+        TopoDS_Edge aSpz;
+        //
+        BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1, 
+                                          myV2, myT2, aSpz);
+        //
+        iErr=
+          BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz, 
+                                                     myE, 
+                                                     myF, 
+                                                     myContext);
+      }
       //
-      iErr=
-        BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz, 
-                                                   myE, 
-                                                   myF, 
-                                                   myContext);
-    }
-    //
-    if (iErr) { 
-      BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF, myContext);
+      if (iErr) { 
+        BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF, myContext);
+      }
+      // 
+      if (myFlag) {
+        UpdateVertices(myE, myF);
+      }
     }
-    // 
-    if (myFlag) {
-      UpdateVertices(myE, myF);
+    catch (Standard_Failure)
+    {
+      AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape()));
     }
   }
   //
@@ -676,6 +686,20 @@ void BOPAlgo_PaveFiller::MakePCurves()
   //======================================================
   BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
   //======================================================
+
+  // Add warnings of the failed projections
+  Standard_Integer aNb = aVMPC.Extent();
+  for (i = 0; i < aNb; ++i)
+  {
+    if (aVMPC(i).HasErrors())
+    {
+      TopoDS_Compound aWC;
+      BRep_Builder().MakeCompound(aWC);
+      BRep_Builder().Add(aWC, aVMPC(i).Edge());
+      BRep_Builder().Add(aWC, aVMPC(i).Face());
+      AddWarning(new BOPAlgo_AlertBuildingPCurveFailed(aWC));
+    }
+  }
 }
 //=======================================================================
 //function : UpdateVertices
index c89f7a31b95134fd9db3c39f7cb524bcaa931a18..58bbe6d79f16e9dacaa41b6240dca765cfd09506 100644 (file)
@@ -1418,6 +1418,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 6b19debd0e7dca122b0bb7e26bfc3e9a5d693dc1..276c15961a69e97aa7b058d63706e75538a8278e 100644 (file)
@@ -302,6 +302,9 @@ Standard_EXPORT virtual ~BOPDS_DS();
   //! ++
   Standard_EXPORT void RefineFaceInfoOn();
   
+  //! Removes faces with state ON from the 
+  //! list of IN-faces
+  Standard_EXPORT void RefineFaceInfoIn();
 
   //! Returns information about ON/IN subshapes of the given faces.
   //! @param theMVOnIn  the indices of ON/IN vertices from both faces
index 618e86cda44ad43fdd086283355b45c63e311cc4..77d5cd2a44c896757ebeb7686492db0034ec95ea 100644 (file)
@@ -235,6 +235,8 @@ Standard_Integer bopcheck (Draw_Interpretor& di,
   //
   aTimer.Stop();
   //
+  BOPTest::ReportAlerts(aChecker);
+  //
   iErr=aChecker.HasErrors();
   //
   const BOPDS_DS& aDS=*(aChecker.PDS());
index 9697b92f561c0d37a9d62568ee3731cef13d58ad..2696de0e4e682c534d3590a51d70f62a9b48e487 100644 (file)
@@ -46,6 +46,7 @@
 #include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomInt.hxx>
+#include <GeomLib.hxx>
 #include <GeomProjLib.hxx>
 #include <gp.hxx>
 #include <gp_Cylinder.hxx>
@@ -667,12 +668,25 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
   }
   //
   TolReached2d=aTolR;
-  //
+
+  // Adjust curve for periodic surface
   Handle(Geom2d_Curve) aC2DA;
   BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA);
-  //
-  aC2D=aC2DA;
-  //
+  aC2D = aC2DA;
+
+  // Make sure that the range of the 2D curve is sufficient for representation of the 3D curve.
+  Standard_Real aTCFirst = aC2D->FirstParameter();
+  Standard_Real aTCLast  = aC2D->LastParameter();
+  if ((aTCFirst - aT1) > Precision::PConfusion() ||
+      (aT2 - aTCLast ) > Precision::PConfusion())
+  {
+    if (aTCFirst < aT1) aTCFirst = aT1;
+    if (aTCLast  > aT2) aTCLast  = aT2;
+
+    GeomLib::SameRange(Precision::PConfusion(), aC2D,
+                       aTCFirst, aTCLast, aT1, aT2, aC2D);
+  }
+
   // compute the appropriate tolerance for the edge
   Handle(Geom_Surface) aS = pBAS->Surface().Surface();
   aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf()));
index c514052544b63297c70a13db22c420dbf74a958f..db46764d7abb0755b9ea2f392008b82500a5137a 100644 (file)
@@ -102,40 +102,6 @@ static Standard_Boolean UpdateMap(const TopoDS_Shape&                 theKey,
   return !found;
 }
 
-static void ReverseModifiedEdges(TopoDS_Shape& aShape,
-                                 TopTools_MapOfShape& Emap)
-{
-  TopExp_Explorer Explo(aShape, TopAbs_FACE);
-  BRep_Builder BB;
-  
-  for (; Explo.More(); Explo.Next())
-  {
-    TopoDS_Shape aFace = Explo.Current();
-    TopoDS_Iterator itf(aFace);
-    for (; itf.More(); itf.Next())
-    {
-      TopoDS_Shape aWire = itf.Value();
-      TopTools_ListOfShape Ledges;
-      TopoDS_Iterator itw(aWire);
-      for (; itw.More(); itw.Next())
-        Ledges.Append(itw.Value());
-
-      aWire.Free(Standard_True);
-      TopTools_ListIteratorOfListOfShape itl(Ledges);
-      for (; itl.More(); itl.Next())
-        BB.Remove(aWire, itl.Value());
-        
-      for (itl.Initialize(Ledges); itl.More(); itl.Next())
-      {
-        TopoDS_Shape anEdge = itl.Value();
-        if (Emap.Contains(anEdge))
-          anEdge.Reverse();
-        BB.Add(aWire, anEdge);
-      }
-    }
-  }
-}
-
 static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace,
                                            TopoDS_Edge& anEdge)
 {
@@ -739,9 +705,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
       result = MkSw.Shape();
       UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap);
       myErrorOnSurf = MkSw.ErrorOnSurface();
-      //Correct <myFirst> and <myLast>
-      ReverseModifiedEdges(myFirst, myReversedEdges);
-      ReverseModifiedEdges(myLast, myReversedEdges);
 
       // Labeling of elements
       if (mySections.IsNull()) {
index 519c6b5d0b19deb5002833ce741edf19d4379d2f..3d0eba45f8fbe2f2a297790ba5eb143e9f5cd41c 100644 (file)
@@ -583,28 +583,15 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
 //=======================================================================
  void BRepFill_PipeShell::DeleteProfile(const TopoDS_Shape&  Profile)
 {
-  Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX);
-
   Standard_Boolean Trouve=Standard_False;
   Standard_Integer ii;
   for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) {
-    Standard_Boolean found = Standard_False;
-    const TopoDS_Wire& aWire = mySeq.Value(ii).Wire();
-    if (isVertex)
-      {
-       TopExp_Explorer Explo(aWire, TopAbs_VERTEX);
-       for (; Explo.More(); Explo.Next())
-         if (Profile.IsSame(Explo.Current()))
-           found = Standard_True;
-      }
-    else if (Profile.IsSame(aWire))
-      found = Standard_True;
-    
-    if (found)
-      {
-       Trouve = Standard_True;
-       mySeq.Remove(ii);
-      }
+    const TopoDS_Shape& aSection = mySeq.Value(ii).OriginalShape();
+    if (Profile.IsSame(aSection))
+    {
+      Trouve = Standard_True;
+      mySeq.Remove(ii);
+    }
   }
 
   if (Trouve) mySection.Nullify();
@@ -705,7 +692,7 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
 //function : Build
 //purpose  : Construct the Shell and the history
 //=======================================================================
- Standard_Boolean BRepFill_PipeShell::Build() 
+ Standard_Boolean BRepFill_PipeShell::Build()
 {
   Standard_Boolean Ok;
   Standard_Real FirstS, LastS;
@@ -759,8 +746,9 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
   MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular);
   MkSw.SetAngularControl(angmin, angmax);
   MkSw.SetForceApproxC1(myForceApproxC1);
-  MkSw.SetBounds(TopoDS::Wire(myFirst), 
-                TopoDS::Wire(myLast));
+  MkSw.SetBounds(TopoDS::Wire(myFirst),
+                 TopoDS::Wire(myLast));
+
   GeomAbs_Shape theContinuity = GeomAbs_C2;
   if (myTrihedron == GeomFill_IsDiscreteTrihedron)
     theContinuity = GeomAbs_C0;
@@ -914,13 +902,9 @@ const TopoDS_Shape& BRepFill_PipeShell::LastShape() const
 //function : Generated
 //purpose  : 
 //=======================================================================
-//  void BRepFill_PipeShell::Generated(const TopoDS_Shape& ,
-//                                 TopTools_ListOfShape& ) 
 void BRepFill_PipeShell::Generated(const TopoDS_Shape&   theShape,
                                   TopTools_ListOfShape& theList) 
 {
-  //   throw Standard_NotImplemented("Generated:Pas Fait");
-  
   theList.Clear();
 
   if(myGenMap.IsBound(theShape)) {
@@ -1197,9 +1181,6 @@ void BRepFill_PipeShell::Place(const BRepFill_Section& Sec,
                                  Sec.WithCorrection());
   TopoDS_Wire TmpWire =  Sec.Wire();
   aTrsf = Place.Transformation();
-  //TopLoc_Location Loc2(Place.Transformation()), Loc1;
-  //Loc1 = TmpWire.Location();
-  //W.Location(Loc2.Multiplied(Loc1));
   //Transform the copy
   W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True));
   ////////////////////////////////////
@@ -1240,37 +1221,40 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
   TopoDS_Iterator itw;
   for (indw = 1; indw <= mySeq.Length(); indw++)
   {
-    const TopoDS_Wire& aSection = mySeq(indw).Wire();
+    const TopoDS_Shape& Section = mySeq(indw).OriginalShape();
+    TopoDS_Wire aSection;
     Standard_Boolean IsPunctual = mySeq(indw).IsPunctual();
     if (IsPunctual)
     {
       //for punctual sections (first or last)
       //we take all the wires generated along the path
-      TopExp_Explorer Explo(aSection, TopAbs_VERTEX);
-      const TopoDS_Shape& VerSection = Explo.Current();
+      
       TopTools_ListOfShape Elist;
       for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++)
         for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++)
           Elist.Append(anUEdges->Value(i,j));
-      myGenMap.Bind(VerSection, Elist);
+      myGenMap.Bind(Section, Elist);
       continue;
     }
+    else
+      aSection = TopoDS::Wire(Section);
     //Take the real index of section on the path
     Standard_Integer IndOfW = myIndOfSec(indw);
     const TopoDS_Wire& theWire = TopoDS::Wire(WSeq(IndOfW));
     BRepTools_WireExplorer wexp_sec(aSection);
     for (inde = 1; wexp_sec.More(); wexp_sec.Next())
     {
-      const TopoDS_Edge& anEdge = TopoDS::Edge(wexp_sec.Current());
+      const TopoDS_Edge& anOriginalEdge = TopoDS::Edge(wexp_sec.Current());
+      TopoDS_Edge anEdge = TopoDS::Edge(mySeq(indw).ModifiedShape(anOriginalEdge));
       if (BRep_Tool::Degenerated(anEdge))
         continue;
 
       TopoDS_Shell aShell;
       BB.MakeShell(aShell);
       TopoDS_Vertex aVertex [2];
-      TopExp::Vertices(anEdge, aVertex[0], aVertex[1]);
+      TopExp::Vertices(anOriginalEdge, aVertex[0], aVertex[1]);
       Standard_Integer SignOfAnEdge =
-        (anEdge.Orientation() == TopAbs_FORWARD)? 1 : -1;
+        (anOriginalEdge.Orientation() == TopAbs_FORWARD)? 1 : -1;
       
       //For each non-degenerated inde-th edge of <aSection>
       //we find inde-th edge in <theWire>
@@ -1422,7 +1406,7 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
       
       TopTools_ListOfShape ListShell;
       ListShell.Append(aShell);
-      myGenMap.Bind(anEdge, ListShell);
+      myGenMap.Bind(anOriginalEdge, ListShell);
       ////////////////////////
 
       inde++;
index c99ab7e75824301d1bf82723f40b78aa77ac04f2..36d6c824a0fe2e4733e0198ee3b2eb204163d8c9 100644 (file)
@@ -168,6 +168,10 @@ public:
   Standard_EXPORT void Simulate (const Standard_Integer NumberOfSection, TopTools_ListOfShape& Sections);
   
   //! Builds the resulting shape (redefined from MakeShape).
+  //! If theIsToCheckValidity == FALSE then BRepFill_Sweep algorithm
+  //! is allowed to create invalid faces (having self-interferences).
+  //! It is considered for them that such faces will be processed and
+  //! fixed by the high-level algorithms
   Standard_EXPORT Standard_Boolean Build();
   
   //! Transform the sweeping Shell in Solid.
index b65b5f85c1bed4d2983ce1a1aa2ffe4f93574e8f..09e5d6f8a72552ea915987be9b2eb75fa15f9212 100644 (file)
@@ -22,6 +22,9 @@
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
+#include <ShapeUpgrade_RemoveLocations.hxx>
 
 BRepFill_Section::BRepFill_Section() :islaw(0),
                                       ispunctual(0),
@@ -41,12 +44,19 @@ BRepFill_Section::BRepFill_Section(const TopoDS_Shape& Profile,
                                     contact(WithContact),
                                    correction(WithCorrection)
 {
-  if (Profile.ShapeType() == TopAbs_WIRE)
-    wire = TopoDS::Wire(Profile);
-  else if (Profile.ShapeType() == TopAbs_VERTEX)
+  myOriginalShape = Profile;
+  
+  ShapeUpgrade_RemoveLocations RemLoc;
+  RemLoc.SetRemoveLevel(TopAbs_COMPOUND);
+  RemLoc.Remove(Profile);
+  TopoDS_Shape aProfile = RemLoc.GetResult();
+  
+  if (aProfile.ShapeType() == TopAbs_WIRE)
+    wire = TopoDS::Wire(aProfile);
+  else if (aProfile.ShapeType() == TopAbs_VERTEX)
     {
       ispunctual = Standard_True;
-      TopoDS_Vertex aVertex = TopoDS::Vertex(Profile);
+      TopoDS_Vertex aVertex = TopoDS::Vertex(aProfile);
       BRep_Builder BB;
       
       TopoDS_Edge DegEdge;
@@ -67,3 +77,58 @@ void BRepFill_Section::Set(const Standard_Boolean IsLaw)
 {
   islaw = IsLaw;
 }
+
+TopoDS_Shape BRepFill_Section::ModifiedShape(const TopoDS_Shape& theShape) const
+{
+  TopoDS_Shape aModifiedShape;
+  
+  switch (theShape.ShapeType())
+  {
+  case TopAbs_WIRE:
+    if (theShape.IsSame(myOriginalShape))
+      aModifiedShape = wire;
+    break;
+  case TopAbs_EDGE:
+    {
+      TopoDS_Iterator itor(myOriginalShape);
+      TopoDS_Iterator itw(wire);
+      for (; itor.More(); itor.Next(),itw.Next())
+      {
+        const TopoDS_Shape& anOriginalEdge = itor.Value();
+        const TopoDS_Shape& anEdge         = itw.Value();
+        if (anOriginalEdge.IsSame(theShape))
+        {
+          aModifiedShape = anEdge;
+          break;
+        }
+      }
+    }
+    break;
+  case TopAbs_VERTEX:
+    if (theShape.IsSame(myOriginalShape))
+    {
+      TopExp_Explorer Explo(wire, TopAbs_VERTEX);
+      aModifiedShape = Explo.Current();
+    }
+    else
+    {
+      TopExp_Explorer ExpOrig(myOriginalShape, TopAbs_VERTEX);
+      TopExp_Explorer ExpWire(wire, TopAbs_VERTEX);
+      for (; ExpOrig.More(); ExpOrig.Next(),ExpWire.Next())
+      {
+        const TopoDS_Shape& anOriginalVertex = ExpOrig.Current();
+        const TopoDS_Shape& aVertex          = ExpWire.Current();
+        if (anOriginalVertex.IsSame(theShape))
+        {
+          aModifiedShape = aVertex;
+          break;
+        }
+      }
+    }
+    break;
+  default:
+    break;
+  }
+
+  return aModifiedShape;
+}
index ede9091f054b2ad1b81592055240d0b144e9d5b7..10acf1decc817a24a0313f41db4accf1415fb98d 100644 (file)
@@ -43,10 +43,14 @@ public:
   
   Standard_EXPORT void Set (const Standard_Boolean IsLaw);
   
+    const TopoDS_Shape& OriginalShape() const;
+  
     const TopoDS_Wire& Wire() const;
   
     const TopoDS_Vertex& Vertex() const;
   
+  Standard_EXPORT TopoDS_Shape ModifiedShape(const TopoDS_Shape& theShape) const;
+  
     Standard_Boolean IsLaw() const;
   
     Standard_Boolean IsPunctual() const;
@@ -68,6 +72,7 @@ private:
 
 
 
+  TopoDS_Shape myOriginalShape;
   TopoDS_Wire wire;
   TopoDS_Vertex vertex;
   Standard_Boolean islaw;
index 5b80bc996ef46d1a9196d3851884fb13696c5527..c96eaec01f482778770e065a9524481bc725c783 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+inline const TopoDS_Shape& BRepFill_Section::OriginalShape() const
+{
+  return myOriginalShape; 
+}
+
 inline const TopoDS_Wire& BRepFill_Section::Wire() const
 {
   return wire; 
index 9e35334bbb96d0e6fb40da8149ca8178bf8c4cfc..1d2f0214b3adfbbf1f7b257a0feabcb592908334 100644 (file)
@@ -366,6 +366,56 @@ static Standard_Boolean SameParameter(TopoDS_Edge&    E,
   return Standard_True;
 }
 
+static void CorrectSameParameter(TopoDS_Edge&       theEdge,
+                                 const TopoDS_Face& theFace1,
+                                 const TopoDS_Face& theFace2)
+{
+  if (BRep_Tool::Degenerated(theEdge))
+    return;
+  
+  Standard_Real fpar, lpar;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, fpar, lpar);
+
+  Standard_Boolean PCurveExists [2] = {Standard_False, Standard_False};
+  BRepAdaptor_Curve BAcurve [2];
+  
+  if (!theFace1.IsNull())
+  {
+    PCurveExists[0] = Standard_True;
+    BAcurve[0].Initialize(theEdge, theFace1);
+  }
+  if (!theFace1.IsNull() &&
+      theFace1.IsSame(theFace2))
+    theEdge.Reverse();
+  if (!theFace2.IsNull())
+  {
+    PCurveExists[1] = Standard_True;
+    BAcurve[1].Initialize(theEdge, theFace2);
+  }
+
+  Standard_Real MaxSqDist = 0.;
+  const Standard_Integer NCONTROL = 23;
+  Standard_Real delta = (lpar - fpar)/NCONTROL;
+
+  for (Standard_Integer i = 0; i <= NCONTROL; i++)
+  {
+    Standard_Real aParam = fpar + i*delta;
+    gp_Pnt aPnt = aCurve->Value(aParam);
+    for (Standard_Integer j = 0; j < 2; j++)
+      if (PCurveExists[j])
+      {
+        gp_Pnt aPntFromFace = BAcurve[j].Value(aParam);
+        Standard_Real aSqDist = aPnt.SquareDistance(aPntFromFace);
+        if (aSqDist > MaxSqDist)
+          MaxSqDist = aSqDist;
+      }
+  }
+
+  Standard_Real aTol = sqrt(MaxSqDist);
+  BRep_Builder BB;
+  BB.UpdateEdge(theEdge, aTol);
+}
+
 //=======================================================================
 //Objet : Orientate an edge of natural restriction 
 //      : General
@@ -666,7 +716,7 @@ static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d,
 //  P2  = BT.Pnt(VL);
   P2  = BRep_Tool::Pnt(VL);
 //  Tol2 = BT.Tolerance(VF);
-  Tol2 = BRep_Tool::Tolerance(VF);
+  Tol2 = BRep_Tool::Tolerance(VL);
   Tol = Max(Tol1, Tol2);
 
   if (VF.IsSame(VL) || 
@@ -809,24 +859,44 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF,
   Prof1 = BRep_Tool::Curve(E1, f1, l1);
 //  Prof2 = BT.Curve(E2, f2, l2);
   Prof2 = BRep_Tool::Curve(E2, f2, l2);
+
+  // Indeed, both Prof1 and Prof2 are the same curves but in different positions
+
   gp_Pnt P1, P2, P;
-  gp_Pnt2d p1, p2;
-  gp_Trsf Tf;
-  Tf.SetTransformation(Axe);
-
-// Choose the angle of opening
-  P1 = Prof1->Value((f1+l1)/2);
-  P2 = Prof2->Value((f2+l2)/2);
-  P1.Transform(Tf);
-  P2.Transform(Tf);
-  p1.SetCoord(P1.Z(), P1.X());
-  p2.SetCoord(P2.Z(), P2.X());
-  gp_Vec2d v1(gp::Origin2d(), p1);
-  gp_Vec2d v2(gp::Origin2d(), p2);
-  if (v1.Magnitude() <= gp::Resolution() ||
-      v2.Magnitude() <= gp::Resolution())
+
+  // Choose the angle of opening
+  gp_Trsf aTf;
+  aTf.SetTransformation(Axe);
+
+  // Choose the furthest point from the "center of revolution"
+  // to provide correct angle measurement.
+  const Standard_Real aPrm[] = {f1, 0.5*(f1 + l1), l1};
+  const gp_Pnt aP1[] = {Prof1->Value(aPrm[0]).Transformed(aTf),
+                        Prof1->Value(aPrm[1]).Transformed(aTf),
+                        Prof1->Value(aPrm[2]).Transformed(aTf)};
+
+  Standard_Integer aMaxIdx = -1;
+  Standard_Real aMaxDist = RealFirst();
+  for (Standard_Integer i = 0; i < 3; i++)
+  {
+    const Standard_Real aDist = aP1[i].X()*aP1[i].X() + aP1[i].Z()*aP1[i].Z();
+    if (aDist > aMaxDist)
+    {
+      aMaxDist = aDist;
+      aMaxIdx = i;
+    }
+  }
+
+  const gp_Pnt aP2 = Prof2->Value(aPrm[aMaxIdx]).Transformed(aTf);
+  const gp_Vec2d aV1(aP1[aMaxIdx].Z(), aP1[aMaxIdx].X());
+  const gp_Vec2d aV2(aP2.Z(), aP2.X());
+  if (aV1.SquareMagnitude() <= gp::Resolution() ||
+      aV2.SquareMagnitude() <= gp::Resolution())
+  {
     return Standard_False;
-  Angle = v1.Angle(v2);
+  }
+
+  Angle = aV1.Angle(aV2);
 
   gp_Ax1 axe(Axe.Location(), Axe.YDirection());
 
@@ -837,14 +907,14 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF,
 
   Handle(Geom_SurfaceOfRevolution) Rev = 
     new (Geom_SurfaceOfRevolution) (Prof1, axe);
-  
+
   Handle(Geom_Surface) Surf = 
     new (Geom_RectangularTrimmedSurface) (Rev, 0, Angle, f1, l1);
 
   // 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;
     /*
@@ -1135,19 +1205,40 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF,
     B.MakeEdge(Aux2);
 
   // Set the orientation
-  gp_Vec D1U, D1V, N1, N2;
-  C1->D0( (f1+l1)/2, P2d);
-  Surf->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
-  N1 = D1U^D1V;
-  
-//  C1 = BT.CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
-  C1 = BRep_Tool::CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
-  C1->D0( (f1+l1)/2, P2d);
-  Handle(BRepAdaptor_HSurface) AS = new BRepAdaptor_HSurface(TopoDS::Face(F1));
-  AS->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
-  N2 = D1U^D1V;
+
+  // Provide correct normals computation
+  // (the normal will be computed not in 
+  // singularity point definitely).
+  Angle = RealFirst();
+  for (Standard_Integer i = 0; i < 3; i++)
+  {
+    gp_Vec D1U, D1V, N1, N2;
+    C1->D0(aPrm[i], P2d);
+    Surf->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
+    N1 = D1U^D1V;
+
+    if (N1.SquareMagnitude() < Precision::SquareConfusion())
+      continue;
+
+    //  C1 = BT.CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
+    C1 = BRep_Tool::CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
+    C1->D0(aPrm[i], P2d);
+    Handle(BRepAdaptor_HSurface) AS = new BRepAdaptor_HSurface(TopoDS::Face(F1));
+    AS->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
+    N2 = D1U^D1V;
+
+    if (N2.SquareMagnitude() < Precision::SquareConfusion())
+      continue;
+
+    Angle = N1.Angle(N2);
+
+    break;
+  }
   
-  if ( (F1.Orientation() == TopAbs_REVERSED) ^ (N1.Angle(N2)>M_PI/2) )
+  if (Angle == RealFirst())
+    return Standard_False;
+
+  if ( (F1.Orientation() == TopAbs_REVERSED) ^ (Angle>M_PI/2))
     Result.Orientation(TopAbs_REVERSED);
   else  Result.Orientation(TopAbs_FORWARD);
 
@@ -1661,6 +1752,60 @@ static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S,
   return B;
 }
 
+static void ReverseEdgeInFirstOrLastWire(TopoDS_Shape&       theWire,
+                                         const TopoDS_Shape& theEdge)
+{
+  TopoDS_Shape EdgeToReverse;
+  TopoDS_Iterator itw(theWire);
+
+  for (; itw.More(); itw.Next())
+  {
+    const TopoDS_Shape& anEdge = itw.Value();
+    if (anEdge.IsSame(theEdge))
+    {
+      EdgeToReverse = anEdge;
+      break;
+    }
+  }
+
+  if (!EdgeToReverse.IsNull())
+  {
+    BRep_Builder BB;
+    theWire.Free(Standard_True);
+    BB.Remove(theWire, EdgeToReverse);
+    EdgeToReverse.Reverse();
+    BB.Add(theWire, EdgeToReverse);
+  }
+}
+
+static void ReverseModifiedEdges(TopoDS_Wire&               theWire,
+                                 const TopTools_MapOfShape& theEmap)
+{
+  if (theEmap.IsEmpty())
+    return;
+  
+  TopoDS_Iterator itw(theWire);
+  BRep_Builder BB;
+  
+  TopTools_ListOfShape Ledges;
+  for (; itw.More(); itw.Next())
+    Ledges.Append(itw.Value());
+  
+  theWire.Free(Standard_True);
+  TopTools_ListIteratorOfListOfShape itl(Ledges);
+  for (; itl.More(); itl.Next())
+    BB.Remove(theWire, itl.Value());
+        
+  for (itl.Initialize(Ledges); itl.More(); itl.Next())
+  {
+    TopoDS_Shape anEdge = itl.Value();
+    if (theEmap.Contains(anEdge))
+      anEdge.Reverse();
+    BB.Add(theWire, anEdge);
+  }
+}
+
+
 //=======================================================================
 //function : Constructeur
 //purpose  : 
@@ -1670,8 +1815,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
                               const Standard_Boolean WithKPart) : 
                               isDone(Standard_False),
                               KPart(WithKPart)
-
-
 {
  mySec = Section;
  myLoc = Location;
@@ -1947,11 +2090,12 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
   BRep_Builder B;
   Standard_Integer NbPath = ILast - IFirst;
   Standard_Integer NbLaw =  mySec->NbLaw();
-  Standard_Boolean uclose, vclose,  constSection, hasdegen = Standard_False;
+  Standard_Boolean uclose, vclose, global_vclose, constSection, hasdegen = Standard_False;
   constSection = mySec->IsConstant();
   uclose = mySec->IsUClosed();
   vclose = (mySec->IsVClosed() && myLoc->IsClosed()) && 
            (NbPath == myLoc->NbLaw()) && (myLoc->IsG1(0, myTol3d)>= 0);
+  global_vclose = (myLoc->IsClosed()) && (myLoc->IsG1(0, myTol3d)>= 0);
   Error = 0.;
 
   // (1) Construction of all surfaces
@@ -2064,6 +2208,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
   Standard_Boolean exuv, singu, singv;
   Handle(Geom_Surface) S;
 
+  //Correct <FirstShape> and <LastShape>: reverse modified edges
+  ReverseModifiedEdges(FirstShape, ReversedEdges);
+  ReverseModifiedEdges(LastShape,  ReversedEdges);
+
   // (2.0) return preexisting Edges and vertices
   TopoDS_Edge E;
   TColStd_Array1OfBoolean IsBuilt(1, NbLaw);
@@ -2293,7 +2441,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
 
  
   // ---------- Creation of Vertex and edge ------------
-  ReversedEdges.Clear();
   for (ipath=1, IPath=IFirst; ipath<=NbPath; 
        ipath++, IPath++) {
     for (isec=1; isec <=NbLaw; isec++) {
@@ -2496,7 +2643,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
                                    TopoDS::Edge(VEdge(isec, ipath)),
                                    ReversedEdges);
             if (ReversedEdges.Contains(VEdge(isec, ipath)))
+            {
+              ReverseEdgeInFirstOrLastWire(FirstShape, VEdge(isec, ipath));
               StartEdges(isec).Reverse();
+            }
           }
         }
        
@@ -2524,7 +2674,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
                                           myTol3d);
        else
         {
-          if (ipath != NbPath || vclose)
+          if (ipath != NbPath ||
+              vclose ||
+              (global_vclose && ILast == myLoc->NbLaw()+1))
+            
             UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), 
                        S, exuv, VLast);
           else //ipath == NbPath && !vclose => rebuild last edge
@@ -2536,6 +2689,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
             RebuildTopOrBottomEdge(aNewLastEdge,
                                    TopoDS::Edge(VEdge(isec, ipath+1)),
                                    ReversedEdges);
+            if (ReversedEdges.Contains(VEdge(isec, ipath+1)))
+              ReverseEdgeInFirstOrLastWire(LastShape, VEdge(isec, ipath+1));
           }
         }
       }
@@ -2877,6 +3032,30 @@ void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
       }
     }
 
+    //Ensure Same Parameter on U-edges
+    for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++)
+    {
+      if (mySec->IsUClosed() && ii == myUEdges->UpperRow())
+        continue;
+      for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++)
+      {
+       TopoDS_Edge anEdge = TopoDS::Edge(myUEdges->Value(ii, jj));
+        if (anEdge.IsNull())
+          continue;
+        TopoDS_Face Face1, Face2;
+        Standard_Integer i1 = ii-1, i2 = ii;
+        if (i1 == 0 && mySec->IsUClosed())
+          i1 = myFaces->UpperRow();
+        if (i2 > myFaces->UpperRow())
+          i2 = 0;
+        if (i1 != 0)
+          Face1 = TopoDS::Face(myFaces->Value(i1, jj));
+        if (i2 != 0)
+          Face2 = TopoDS::Face(myFaces->Value(i2, jj));
+        CorrectSameParameter(anEdge, Face1, Face2);
+      }
+    }
+
     for (ii = 1; ii <= NbLaw; ii++)
       for (jj = 1; jj <= NbPath; jj++)
       {
@@ -3083,7 +3262,7 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const
     }
   }
 
-  BRepFill_TrimShellCorner aTrim(aFaces, AxeOfBisPlane, aPlaneF);
+  BRepFill_TrimShellCorner aTrim(aFaces, Transition, AxeOfBisPlane);
   aTrim.AddBounds(Bounds);
   aTrim.AddUEdges(aUEdges);
   aTrim.Perform();
@@ -3172,7 +3351,8 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const
          // Filling
          B = Filling(It1.Value(), myFaces->Value(ii, I1),
                      It2.Value(), myFaces->Value(ii, I2),
-                     myVEdgesModified, myTol3d, Axe, T1, Bord1, Bord2, FF);
+                      myVEdgesModified, myTol3d, Axe, T1,
+                      Bord1, Bord2, FF);
          
          if (B) {
            myAuxShape.Append(FF);
index b3b003a3f9d8162ca926c6a59b0ee8f6a57d6b32..72b1897959710ca7ae4cff4d9ce61c58d1411ef4 100644 (file)
@@ -80,7 +80,7 @@ public:
   //! to be C0.
   Standard_EXPORT void SetForceApproxC1 (const Standard_Boolean ForceApproxC1);
   
-  //! Build the Sweeep  Surface
+  //! Build the Sweep  Surface
   //! Transition define Transition strategy
   //! Approx define Approximation Strategy
   //! - GeomFill_Section : The composed Function Location X Section
@@ -118,13 +118,6 @@ public:
 
 protected:
 
-
-
-
-
-private:
-
-  
   Standard_EXPORT Standard_Boolean CorrectApproxParameters();
   
   Standard_EXPORT Standard_Boolean BuildWire (const BRepFill_TransitionStyle Transition);
@@ -142,6 +135,13 @@ private:
   Standard_EXPORT void RebuildTopOrBottomEdge (const TopoDS_Edge& aNewEdge, TopoDS_Edge& anEdge, TopTools_MapOfShape& ReversedEdges) const;
 
 
+
+
+private:
+
+  
+
+
   Standard_Boolean isDone;
   Standard_Boolean KPart;
   Standard_Real myTol3d;
@@ -168,7 +168,6 @@ private:
   TopoDS_Wire FirstShape;
   TopoDS_Wire LastShape;
 
-
 };
 
 
index 9d3e925ca626cb27fc08e08e356426cd1e057710..0083bf8e232936d6766e8e46b8b74c046cb848b5 100644 (file)
@@ -25,6 +25,7 @@
 #include <BRepFill_TrimShellCorner.hxx>
 #include <BRepLib_MakeEdge.hxx>
 #include <BRepLib_MakeWire.hxx>
+#include <BRepLib_MakeVertex.hxx>
 #include <BRepTools_ReShape.hxx>
 #include <gce_MakeLin.hxx>
 #include <GCPnts_UniformAbscissa.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_SequenceOfShape.hxx>
+#include <BRepExtrema_ExtCC.hxx>
+
+static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
+                                                TopoDS_Compound&     theComp,
+                                                const gp_Ax1&        theAxis);
+
+static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex&  theVertex1,
+                                        const TopoDS_Vertex&  theVertex2,
+                                        const gp_Ax1&         theAxis,
+                                        TopoDS_Compound&      theComp,
+                                        TopTools_ListOfShape& theElist);
+
+static Standard_Boolean FindCommonVertex(const TopoDS_Edge&   theFirstEdge,
+                                         const TopoDS_Edge&   theLastEdge,
+                                         const TopoDS_Vertex& theFirstVertex,
+                                         const TopoDS_Vertex& theLastVertex,
+                                         TopoDS_Vertex&       theCommonVertex);
 
 static Standard_Boolean FindCommonVertex(const BOPDS_PDS&         theDS,
                                          const Standard_Integer   theEIndex1,
@@ -71,24 +89,6 @@ static Standard_Boolean FindCommonVertex(const BOPDS_PDS&         theDS,
                                          Standard_Real&           theParamOnE1,
                                          Standard_Real&           theParamOnE2);
 
-static Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theIndex,
-                                        const Handle(TopTools_HArray2OfShape)&     theUEdges, 
-                                        const Handle(TopTools_HArray2OfShape)&     theBounds, 
-                                        const BOPDS_PDS&                           theDS,
-                                        const Standard_Integer                     theFaceIndex1, 
-                                        const Standard_Integer                     theFaceIndex2, 
-                                        TopTools_DataMapOfShapeListOfShape&        theHistMap);
-
-static Standard_Boolean MakeFacesSec(const Standard_Integer                     theIndex,
-                                     const Handle(TopTools_HArray2OfShape)&     theUEdges, 
-                                     const Handle(TopTools_HArray2OfShape)&     theBounds, 
-                                     const BOPDS_PDS&                           theDS,
-                                     const Standard_Integer                     theFaceIndex1, 
-                                     const Standard_Integer                     theFaceIndex2, 
-                                     const Standard_Integer                     theSSInterfIndex,
-                                     const gp_Ax2&                              AxeOfBisPlane,
-                                     TopTools_DataMapOfShapeListOfShape&        theHistMap);
-
 static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)&     theUEdges, 
                                     const BOPDS_PDS&                           theDS,
                                     TopTools_DataMapOfShapeListOfShape&        theHistMap);
@@ -186,55 +186,27 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir
                                                         gp_Pln& thePlane,
                                                         Standard_Boolean& IsSingular);
 
-static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp,
-                                      const gp_Ax2& bis,
-                                      TopoDS_Shape& resWire,
-                                      gp_Pln& resPlane,
-                                      Standard_Boolean& IsSingular);
-
-// ===========================================================================================
-// function: Constructor
-// purpose:
-// ===========================================================================================
-BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
-                                                   const gp_Ax2&                          theAxeOfBisPlane,
-                                                   const TopoDS_Face&                     theSecPlane) :
-myAxeOfBisPlane(theAxeOfBisPlane),
-myDone(Standard_False),
-myHasSection(Standard_False)
-{
-  myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), 
-                                        theFaces->LowerCol(), theFaces->UpperCol());
-  myFaces->ChangeArray2() = theFaces->Array2();
-  mySecPln = theSecPlane;
-}
+static void UpdateSectionEdge(TopoDS_Edge&         theEdge,
+                              const TopoDS_Vertex& theConstVertex,
+                              TopoDS_Vertex&       theVertex,
+                              const Standard_Real  theParam);
 
+  
 // ===========================================================================================
 // function: Constructor
 // purpose:
 // ===========================================================================================
 BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
-                                                   const gp_Ax2&                          theAxeOfBisPlane,
-                                                   const TopoDS_Wire&                     theSpine,
-                                                   const TopoDS_Face&                     theSecPlane):
-myAxeOfBisPlane(theAxeOfBisPlane),
-myDone(Standard_False),
-myHasSection(Standard_False)
+                                                   const BRepFill_TransitionStyle         theTransition,
+                                                   const gp_Ax2&                          theAxeOfBisPlane) :
+  myTransition(theTransition),
+  myAxeOfBisPlane(theAxeOfBisPlane),
+  myDone(Standard_False),
+  myHasSection(Standard_False)
 {
   myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), 
                                         theFaces->LowerCol(), theFaces->UpperCol());
   myFaces->ChangeArray2() = theFaces->Array2();
-  mySpine = theSpine;
-  mySecPln = theSecPlane;
-}
-
-// ===========================================================================================
-// function: SetSpine
-// purpose:
-// ===========================================================================================
-void BRepFill_TrimShellCorner::SetSpine(const TopoDS_Wire& theSpine) 
-{
-  mySpine = theSpine;
 }
 
 // ===========================================================================================
@@ -351,14 +323,13 @@ void BRepFill_TrimShellCorner::Perform()
         }
 
         if(!bhassec) {
-          if(!MakeFacesNonSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, myHistMap)) {
+          if(!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2)) {
             myHistMap.Clear();
             return;
           }
         }
         else {
-          if(!MakeFacesSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, 
-                           i, myAxeOfBisPlane, myHistMap)) {
+          if(!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i)) {
             myHistMap.Clear();
             return;
           }
@@ -403,23 +374,21 @@ void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape&   theShape,
 }
 
 // ----------------------------------------------------------------------------------------------------
-// static function: MakeFacesNonSec
-// purpose:
+// function: MakeFacesNonSec
+// purpose:         Updates <myHistMap> by new faces in the case when old faces do not intersect
 // ----------------------------------------------------------------------------------------------------
-Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theIndex,
-                                 const Handle(TopTools_HArray2OfShape)&     theUEdges, 
-                                 const Handle(TopTools_HArray2OfShape)&     theBounds, 
-                                 const BOPDS_PDS&                           theDS,
-                                 const Standard_Integer                     theFaceIndex1, 
-                                 const Standard_Integer                     theFaceIndex2, 
-                                 TopTools_DataMapOfShapeListOfShape&        theHistMap)
+Standard_Boolean
+BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer                     theIndex,
+                                          const BOPDS_PDS&                           theDS,
+                                          const Standard_Integer                     theFaceIndex1, 
+                                          const Standard_Integer                     theFaceIndex2)
 {
   Standard_Boolean bHasNewEdge = Standard_False;
   TopoDS_Edge aNewEdge;
 
   BRep_Builder aBB;
-  const TopoDS_Shape& aE1 = theBounds->Value(theIndex, 1);
-  const TopoDS_Shape& aE2 = theBounds->Value(theIndex, 2);
+  const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1);
+  const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2);
 
   // search common vertex between bounds. begin
   TopoDS_Vertex aCommonVertex;
@@ -439,20 +408,20 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
   Standard_Integer ueit = 0, eindex = 0;
 
   for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
-    const TopoDS_Shape& aShape1 = theUEdges->Value(eindex, theUEdges->LowerCol());
-    const TopoDS_Shape& aShape2 = theUEdges->Value(eindex, theUEdges->UpperCol());
+    const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol());
+    const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol());
     TopoDS_Edge aUE1 = TopoDS::Edge(aShape1);
     TopoDS_Edge aUE2 = TopoDS::Edge(aShape2);
 
-    if(theHistMap.IsBound(aShape1)) {
-      const TopTools_ListOfShape& lst = theHistMap.Find(aShape1);
+    if (myHistMap.IsBound(aShape1)) {
+      const TopTools_ListOfShape& lst = myHistMap.Find(aShape1);
 
       if(!lst.IsEmpty())
         aUE1 = TopoDS::Edge(lst.First());
     }
 
-    if(theHistMap.IsBound(aShape2)) {
-      const TopTools_ListOfShape& lst = theHistMap.Find(aShape2);
+    if (myHistMap.IsBound(aShape2)) {
+      const TopTools_ListOfShape& lst = myHistMap.Find(aShape2);
 
       if(!lst.IsEmpty())
         aUE2 = TopoDS::Edge(lst.First());
@@ -499,11 +468,11 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
     aBB.MakeCompound(aComp);
 
     for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
-      const TopoDS_Shape& aShape = theUEdges->Value(eindex, theUEdges->LowerCol() + fit - 1);
+      const TopoDS_Shape& aShape = myUEdges->Value(eindex, myUEdges->LowerCol() + fit - 1);
       TopoDS_Shape aUE = aShape;
 
-      if(theHistMap.IsBound(aShape)) {
-        const TopTools_ListOfShape& lst = theHistMap.Find(aShape);
+      if(myHistMap.IsBound(aShape)) {
+        const TopTools_ListOfShape& lst = myHistMap.Find(aShape);
 
         if(!lst.IsEmpty())
           aUE = TopoDS::Edge(lst.First());
@@ -638,7 +607,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
     aNewFace.Orientation(aFaceOri);
     TopTools_ListOfShape atmpList;
     atmpList.Append(aNewFace);
-    theHistMap.Bind(aFace, atmpList);
+    myHistMap.Bind(aFace, atmpList);
 
     anExpE.Init(aFace, TopAbs_EDGE);
 
@@ -648,7 +617,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
       if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
         continue;
 
-      if(theHistMap.IsBound(anExpE.Current()))
+      if (myHistMap.IsBound(anExpE.Current()))
         continue;
       TopTools_ListOfShape aListOfNewEdge;
       TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
@@ -656,7 +625,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
       for(; anExpE2.More(); anExpE2.Next()) {
         aListOfNewEdge.Append(anExpE2.Current());
       }
-      theHistMap.Bind(anExpE.Current(), aListOfNewEdge);
+      myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
     }
   }
 
@@ -664,18 +633,15 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
 }
 
 // ----------------------------------------------------------------------------------------------------
-// static function: MakeFacesSec
-// purpose:
+// function: MakeFacesSec
+// purpose:  Updates <myHistMap> by new faces in the case when old faces intersect each other
 // ----------------------------------------------------------------------------------------------------
-Standard_Boolean MakeFacesSec(const Standard_Integer                     theIndex,
-                              const Handle(TopTools_HArray2OfShape)&     theUEdges, 
-                              const Handle(TopTools_HArray2OfShape)&     theBounds, 
-                              const BOPDS_PDS&                           theDS,
-                              const Standard_Integer                     theFaceIndex1, 
-                              const Standard_Integer                     theFaceIndex2, 
-                              const Standard_Integer                     theSSInterfIndex,
-                              const gp_Ax2&                              AxeOfBisPlane,
-                              TopTools_DataMapOfShapeListOfShape&        theHistMap)
+Standard_Boolean
+BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer                     theIndex,
+                                       const BOPDS_PDS&                           theDS,
+                                       const Standard_Integer                     theFaceIndex1, 
+                                       const Standard_Integer                     theFaceIndex2, 
+                                       const Standard_Integer                     theSSInterfIndex)
 {
   const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
   const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex);
@@ -687,10 +653,30 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
   if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges))
     return Standard_False;
 
+  //Extract vertices on the intersection of correspondent U-edges
+  const TopoDS_Shape& LeftE1  = myUEdges->Value(theIndex, 1);
+  const TopoDS_Shape& LeftE2  = myUEdges->Value(theIndex, 2);
+  const TopoDS_Shape& RightE1 = myUEdges->Value(theIndex+1, 1);
+  const TopoDS_Shape& RightE2 = myUEdges->Value(theIndex+1, 2);
+
+  Standard_Integer IndexOfLeftE1  = theDS->Index(LeftE1);
+  Standard_Integer IndexOfLeftE2  = theDS->Index(LeftE2);
+  Standard_Integer IndexOfRightE1 = theDS->Index(RightE1);
+  Standard_Integer IndexOfRightE2 = theDS->Index(RightE2);
+
+  TopoDS_Vertex FirstVertex, LastVertex;
+  Standard_Real ParamOnLeftE1, ParamOnLeftE2, ParamOnRightE1, ParamOnRightE2;
+  FindCommonVertex(theDS, IndexOfLeftE1, IndexOfLeftE2,
+                   FirstVertex, ParamOnLeftE1, ParamOnLeftE2);
+  FindCommonVertex(theDS, IndexOfRightE1, IndexOfRightE2,
+                   LastVertex, ParamOnRightE1, ParamOnRightE2);
+
   TopoDS_Shape SecWire;
   gp_Pln SecPlane;
   Standard_Boolean IsSingular;
-  Standard_Boolean WireFound = ChooseSection( aSecEdges, AxeOfBisPlane, SecWire, SecPlane, IsSingular );
+  Standard_Boolean WireFound = ChooseSection(aSecEdges,
+                                             FirstVertex, LastVertex,
+                                             SecWire, SecPlane, IsSingular );
 
   if(WireFound) {
     //aSecEdges = SecWire;
@@ -715,19 +701,19 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
     TopAbs_Orientation aFaceOri = aFace.Orientation();
     TopoDS_Face aFaceF = aFace;
     aFaceF.Orientation(TopAbs_FORWARD);
-    TopoDS_Edge aBoundEdge = TopoDS::Edge(theBounds->Value(theIndex, theBounds->LowerCol() +fit));
+    TopoDS_Edge aBoundEdge = TopoDS::Edge(myBounds->Value(theIndex, myBounds->LowerCol() +fit));
     Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge);
     TopoDS_Edge aUE1;
     TopoDS_Edge aUE2;
 
-    if(!GetUEdges(theIndex, fit, theUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
+    if(!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
       return Standard_False;
 
     TopoDS_Edge aUE1old = aUE1;
     TopoDS_Edge aUE2old = aUE2;
 
-    if(theHistMap.IsBound(aUE1)) {
-      const TopTools_ListOfShape& lst = theHistMap.Find(aUE1);
+    if (myHistMap.IsBound(aUE1)) {
+      const TopTools_ListOfShape& lst = myHistMap.Find(aUE1);
 
       if(!lst.IsEmpty()) {
         const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation());
@@ -738,8 +724,8 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
       }
     }
 
-    if(theHistMap.IsBound(aUE2)) {
-      const TopTools_ListOfShape& lst = theHistMap.Find(aUE2);
+    if (myHistMap.IsBound(aUE2)) {
+      const TopTools_ListOfShape& lst = myHistMap.Find(aUE2);
 
       if(!lst.IsEmpty()) {
         const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation());
@@ -757,12 +743,12 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
     Standard_Boolean isPave1OnUEdge = Standard_True;
 
     if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex, 
-                     theDS, theHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) {
+                     theDS, myHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) {
       TopTools_ListOfShape aSecondListOfEdges;
       Standard_Boolean bisSectionFound = Standard_False;
 
       if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge, 
-                        aBoundEdgeIndex, theDS, theHistMap, aSecondListOfEdges, bisSectionFound)) {
+                        aBoundEdgeIndex, theDS, myHistMap, aSecondListOfEdges, bisSectionFound)) {
         return Standard_False;
       }
 
@@ -792,7 +778,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
     aNewFace.Orientation(aFaceOri);
     TopTools_ListOfShape atmpList;
     atmpList.Append(aNewFace);
-    theHistMap.Bind(aFace, atmpList);
+    myHistMap.Bind(aFace, atmpList);
 
     TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
 
@@ -802,7 +788,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
       if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
         continue;
 
-      if(theHistMap.IsBound(anExpE.Current()))
+      if (myHistMap.IsBound(anExpE.Current()))
         continue;
       TopTools_ListOfShape aListOfNewEdge;
       TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
@@ -810,12 +796,240 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
       for(; anExpE2.More(); anExpE2.Next()) {
         aListOfNewEdge.Append(anExpE2.Current());
       }
-      theHistMap.Bind(anExpE.Current(), aListOfNewEdge);
+      myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
     }
   }
   return Standard_True;
 }
 
+//=======================================================================
+//function : ChooseSection
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepFill_TrimShellCorner::ChooseSection(const TopoDS_Shape& Comp,
+                                                         const TopoDS_Vertex& theFirstVertex,
+                                                         const TopoDS_Vertex& theLastVertex,
+                                                         TopoDS_Shape& resWire,
+                                                         gp_Pln& resPlane,
+                                                         Standard_Boolean& IsSingular)
+{
+  IsSingular = Standard_False;
+
+  Standard_Integer ind, i, j;
+  BRep_Builder BB;
+
+  if (myTransition == BRepFill_Right &&
+      !theFirstVertex.IsNull() &&
+      !theLastVertex.IsNull()) //the case where section wire goes from
+    //its known first vertex to its known last vertex
+  {
+    TopoDS_Wire NewWire;
+    BB.MakeWire(NewWire);
+    
+    TopoDS_Compound OldComp;
+    BB.MakeCompound( OldComp );
+    TopoDS_Iterator iter( Comp );
+    for (; iter.More(); iter.Next())
+      BB.Add( OldComp, iter.Value() );
+
+    TopoDS_Edge FirstEdge = FindEdgeCloseToBisectorPlane(theFirstVertex,
+                                                          OldComp,
+                                                          myAxeOfBisPlane.Axis());
+    iter.Initialize(OldComp);
+    if (!iter.More())
+    {
+      iter.Initialize(Comp);
+      BB.Add( OldComp, iter.Value() );
+    }
+    TopoDS_Edge LastEdge  = FindEdgeCloseToBisectorPlane(theLastVertex,
+                                                          OldComp,
+                                                          myAxeOfBisPlane.Axis());
+    
+    BB.Add(NewWire, FirstEdge);
+
+    if (!FirstEdge.IsSame(LastEdge))
+    {
+      TopoDS_Vertex aCommonVertex;
+      Standard_Boolean CommonVertexExists = FindCommonVertex(FirstEdge, LastEdge,
+                                                             theFirstVertex, theLastVertex,
+                                                             aCommonVertex);
+      if (CommonVertexExists)
+        BB.Add(NewWire, LastEdge);
+      else
+      {
+        TopoDS_Vertex Vertex1, Vertex2, V1, V2;
+        TopExp::Vertices(FirstEdge, V1, V2);
+        Vertex1 = (theFirstVertex.IsSame(V1))? V2 : V1;
+        TopExp::Vertices(LastEdge, V1, V2);
+        Vertex2 = (theLastVertex.IsSame(V1))? V2 : V1;
+        
+        TopTools_ListOfShape MiddleEdges;
+        if (FindMiddleEdges(Vertex1, Vertex2, myAxeOfBisPlane.Axis(), OldComp, MiddleEdges))
+        {
+          TopTools_ListIteratorOfListOfShape itl(MiddleEdges);
+          for (; itl.More(); itl.Next())
+            BB.Add(NewWire, itl.Value());
+          BB.Add(NewWire, LastEdge);
+        }
+        else
+        {
+          //trim <FirstEdge> and <LastEdge> in the points of extrema
+          //these points become new vertex with centre between them
+          BRepExtrema_ExtCC Extrema(FirstEdge, LastEdge);
+          if (Extrema.IsDone() && Extrema.NbExt() > 0)
+          {
+            Standard_Integer imin = 1;
+            for (i = 2; i <= Extrema.NbExt(); i++)
+              if (Extrema.SquareDistance(i) < Extrema.SquareDistance(imin))
+                imin = i;
+            
+            Standard_Real aMinDist = sqrt(Extrema.SquareDistance(imin));
+            Standard_Real ParamOnFirstEdge = Extrema.ParameterOnE1(imin);
+            Standard_Real ParamOnLastEdge  = Extrema.ParameterOnE2(imin);
+            gp_Pnt PointOnFirstEdge = Extrema.PointOnE1(imin);
+            gp_Pnt PointOnLastEdge  = Extrema.PointOnE2(imin);
+            gp_Pnt MidPnt((PointOnFirstEdge.XYZ() + PointOnLastEdge.XYZ())/2);
+            aCommonVertex = BRepLib_MakeVertex(MidPnt);
+            BB.UpdateVertex(aCommonVertex, 1.001*aMinDist/2);
+            
+            UpdateSectionEdge(FirstEdge, theFirstVertex, aCommonVertex, ParamOnFirstEdge);
+            UpdateSectionEdge(LastEdge,  theLastVertex,  aCommonVertex, ParamOnLastEdge);
+            
+            BB.Add(NewWire, LastEdge);
+          }
+        }
+      }
+    }
+
+    resWire = NewWire;
+    resPlane = gp_Pln(myAxeOfBisPlane);
+    return Standard_True;
+  }
+
+  //General case: try to find continuous section closest to bisector plane
+  TopoDS_Compound OldComp;
+  BRep_Builder B;
+  B.MakeCompound( OldComp );
+  TopoDS_Iterator iter( Comp );
+  for (; iter.More(); iter.Next())
+    B.Add( OldComp, iter.Value() );
+
+  Standard_Boolean anError = Standard_False;
+  //TopoDS_Wire NewWire [2];
+  TopTools_SequenceOfShape Wseq;
+  for (;;)
+  {
+    TopExp_Explorer explo( OldComp, TopAbs_EDGE );
+    if (!explo.More())
+      break;
+    TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
+    TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge );
+    B.Remove( OldComp, FirstEdge );
+    if (NewWire.Closed())
+    {
+      Wseq.Append(NewWire);
+      continue;
+    }
+    
+    for (;;)
+    {
+      TopoDS_Vertex Extremity [2];
+      TopExp::Vertices( NewWire, Extremity[0], Extremity[1] );
+      if (Extremity[0].IsNull() || Extremity[1].IsNull())
+      {
+        anError = Standard_True;
+        break;
+      }
+      TopTools_IndexedDataMapOfShapeListOfShape VEmap;
+      TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
+      TopTools_ListOfShape Vedges [2];
+      for (j = 0; j < 2; j++)
+        if (VEmap.Contains( Extremity[j] ))
+          Vedges[j] = VEmap.FindFromKey( Extremity[j] );
+      if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
+        //no more edges in OldComp to continue NewWire
+        break;
+      Standard_Boolean Modified = Standard_False;
+      for (j = 0; j < 2; j++)
+      {
+        if (Vedges[j].Extent() == 1)
+        {
+          const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() );
+          NewWire = BRepLib_MakeWire( NewWire, anEdge );
+          B.Remove( OldComp, anEdge );
+          Modified = Standard_True;
+        }
+      }
+      if (!Modified) //only multiple connections
+      {
+        ind = (Vedges[0].IsEmpty())? 1 : 0;
+        TopTools_SequenceOfShape Edges;
+        TopTools_ListIteratorOfListOfShape itl( Vedges[ind] );
+        for (; itl.More(); itl.Next())
+          Edges.Append( itl.Value() );
+        Standard_Integer theind=0;
+        Standard_Real MinDeviation = RealLast();
+        for (j = 1; j <= Edges.Length(); j++)
+        {
+          TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) );
+          gp_Pln aPlane;
+          Standard_Boolean issing;
+          Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing );
+          if (Deviation < MinDeviation)
+          {
+            MinDeviation = Deviation;
+            theind = j;
+          }
+        }
+        NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) );
+        B.Remove( OldComp, Edges(theind) );
+      }
+      if (NewWire.Closed())
+        break;
+    }
+    Wseq.Append(NewWire);
+    if (anError)
+      break;
+  }
+  
+  Standard_Real MinAngle = RealLast();
+  TopExp_Explorer Explo( OldComp, TopAbs_EDGE );
+  if (!anError && !Explo.More()) //wires are built successfully and compound <OldComp> is empty
+  {
+    if (Wseq.Length() == 1) //only one wire => it becomes result
+    {
+      resWire = Wseq.First();
+      ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular );
+      return Standard_True;
+    }
+    else //we must choose the wire which average plane is closest to bisector plane
+    {    //(check angle between axes)
+      for (i = 1; i <= Wseq.Length(); i++)
+      {
+        TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) );
+        gp_Pln aPln;
+        Standard_Boolean issing;
+        ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
+        if (issing)
+          continue;
+        
+        Standard_Real Angle = aPln.Axis().Angle( myAxeOfBisPlane.Axis() );
+        if (Angle > M_PI/2)
+          Angle = M_PI - Angle;
+        
+        if (Angle < MinAngle)
+        {
+          MinAngle = Angle;
+          resWire = aWire;
+          resPlane = aPln;
+        }
+      }
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
 
 // ------------------------------------------------------------------------------------------
 // static function: SplitUEdges
@@ -966,13 +1180,15 @@ Standard_Boolean FindCommonVertex(const BOPDS_PDS&         theDS,
         continue;
 
       IntTools_CommonPrt aCP = aEE.CommonPart();
-      if(aCP.Type() == TopAbs_VERTEX) {
+      if(aCP.Type() == TopAbs_VERTEX)
+      {
         theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew());
-        if (theEIndex1 == aEE.Index1()) {
+        
+        if (theEIndex1 == aEE.Index1())
           IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2);
-        } else {
+        else
           IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1);
-        }
+       
         //
         bvertexfound = Standard_True;
         break;
@@ -2004,147 +2220,182 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir
   return MaxDeviation;
 }
 
-//=======================================================================
-//function : ChooseSection
-//purpose  : 
-//=======================================================================
-static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp,
-                                      const gp_Ax2& bis,
-                                      TopoDS_Shape& resWire,
-                                      gp_Pln& resPlane,
-                                      Standard_Boolean& IsSingular)
+
+static void UpdateSectionEdge(TopoDS_Edge&         theEdge,
+                              const TopoDS_Vertex& theConstVertex,
+                              TopoDS_Vertex&       theVertex,
+                              const Standard_Real  theParam)
 {
-  IsSingular = Standard_False;
-  Standard_Real TolDeviation = 0.01; //, TolConf = 1.e-4, TolAng = 1.e-5;
+  TopoDS_Edge F_Edge = theEdge;
+  F_Edge.Orientation(TopAbs_FORWARD);
+  
+  TopAbs_Orientation OrOfVertex;
+  TopoDS_Vertex V1, V2, AnotherVertex;
+  TopExp::Vertices(F_Edge, V1, V2);
+  if (theConstVertex.IsSame(V1))
+  {
+    //OrOfConst = TopAbs_FORWARD;
+    OrOfVertex = TopAbs_REVERSED;
+    AnotherVertex = V2;
+  }
+  else
+  {
+    //OrOfConst = TopAbs_REVERSED;
+    OrOfVertex = TopAbs_FORWARD;
+    AnotherVertex = V1;
+  }
 
-//  Standard_Integer N = 100;
-  Standard_Integer ind, i, j;
+  BRep_Builder BB;
+  Standard_Real fpar, lpar;
+  BRep_Tool::Range(F_Edge, fpar, lpar);
+  if (OrOfVertex == TopAbs_FORWARD)
+    fpar = theParam;
+  else
+    lpar = theParam;
+  BB.Range(F_Edge, fpar, lpar);
+
+  F_Edge.Free(Standard_True);
+  BB.Remove(F_Edge, AnotherVertex);
+  theVertex.Orientation(OrOfVertex);
+  BB.Add(F_Edge, theVertex);
+}
 
-  //Simplest case
-  TopoDS_Compound OldComp;
-  BRep_Builder B;
-  B.MakeCompound( OldComp );
-  TopoDS_Iterator iter( Comp );
-  for (; iter.More(); iter.Next())
-    B.Add( OldComp, iter.Value() );
+//Finds the edge connected to <theVertex> in the compound <theComp>
+//that is closest to bisector plane angularly.
+//Removes found edge from <theComp>
+//<theAxis> is the axis of bisector plane
+static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
+                                                TopoDS_Compound&     theComp,
+                                                const gp_Ax1&        theAxis)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape VEmap;
+  TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
+  
+  TopoDS_Edge MinEdge;
+  if (!VEmap.Contains(theVertex))
+    return MinEdge;
+  
+  BRep_Builder BB;
+  
+  const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex);
+  if (Edges.Extent() == 1)
+    MinEdge = TopoDS::Edge(Edges.First());
+  else
+  {
+    TopTools_ListIteratorOfListOfShape itl(Edges);
+    Standard_Real MinAngle = RealLast();
+    for (; itl.More(); itl.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+      TopoDS_Wire aWire;
+      BB.MakeWire(aWire);
+      BB.Add(aWire, anEdge);
+      gp_Pln aPln;
+      Standard_Boolean issing;
+      ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
+      Standard_Real anAngle;
+      if (issing) //edge is a segment of line
+      {
+        //<anAngle> is angle between <anEdge> and its projection on bisector plane
+        BRepAdaptor_Curve BAcurve(anEdge);
+        gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
+        gp_Pnt LastPnt  = BAcurve.Value(BAcurve.LastParameter());
+        gp_Vec EdgeVec(FirstPnt, LastPnt);
+        gp_Ax1 EdgeAxis(FirstPnt, EdgeVec);
+        anAngle = EdgeAxis.Direction().Angle(theAxis.Direction());
+        if (anAngle > M_PI/2)
+          anAngle = M_PI - anAngle;
+        anAngle = M_PI/2 - anAngle;
+      }
+      else
+      {
+        anAngle = aPln.Axis().Angle( theAxis );
+        if (anAngle > M_PI/2)
+          anAngle = M_PI - anAngle;
+      }
+      
+      if (anAngle < MinAngle)
+      {
+        MinAngle = anAngle;
+        MinEdge  = anEdge;
+      }
+    }
+  } //else (more than one edge)
 
-  Standard_Boolean anError = Standard_False;
-  //TopoDS_Wire NewWire [2];
-  TopTools_SequenceOfShape Wseq;
+  BB.Remove(theComp, MinEdge);
+  return MinEdge;
+}
+
+static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex&  theVertex1,
+                                        const TopoDS_Vertex&  theVertex2,
+                                        const gp_Ax1&         theAxis,
+                                        TopoDS_Compound&      theComp,
+                                        TopTools_ListOfShape& theElist)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape VEmap;
+  TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
+  if (VEmap.IsEmpty())
+    return Standard_False;
+
+  if (!VEmap.Contains(theVertex1) ||
+      !VEmap.Contains(theVertex2))
+    return Standard_False;
+
+  TopoDS_Vertex CurVertex = theVertex1;
   for (;;)
-    {
-      TopExp_Explorer explo( OldComp, TopAbs_EDGE );
-      if (!explo.More())
-        break;
-      TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
-      TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge );
-      B.Remove( OldComp, FirstEdge );
-      if (NewWire.Closed())
-        {
-          Wseq.Append(NewWire);
-          continue;
-        }
+  {
+    TopoDS_Edge CurEdge;
+    
+    CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis);
+    if (CurEdge.IsNull())
+      return Standard_False;
+    
+    TopoDS_Vertex V1, V2;
+    TopExp::Vertices(CurEdge, V1, V2);
+    CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
 
-      for (;;)
-        {
-          TopoDS_Vertex Extremity [2];
-          TopExp::Vertices( NewWire, Extremity[0], Extremity[1] );
-          if (Extremity[0].IsNull() || Extremity[1].IsNull())
-            {
-              anError = Standard_True;
-              break;
-            }
-          TopTools_IndexedDataMapOfShapeListOfShape VEmap;
-          TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
-          TopTools_ListOfShape Vedges [2];
-          for (j = 0; j < 2; j++)
-            if (VEmap.Contains( Extremity[j] ))
-              Vedges[j] = VEmap.FindFromKey( Extremity[j] );
-          if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
-            //no more edges in OldComp to continue NewWire
-            break;
-          Standard_Boolean Modified = Standard_False;
-          for (j = 0; j < 2; j++)
-            {
-              if (Vedges[j].Extent() == 1)
-                {
-                  const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() );
-                  NewWire = BRepLib_MakeWire( NewWire, anEdge );
-                  B.Remove( OldComp, anEdge );
-                  Modified = Standard_True;
-                }
-            }
-          if (!Modified) //only multiple connections
-            {
-              ind = (Vedges[0].IsEmpty())? 1 : 0;
-              TopTools_SequenceOfShape Edges;
-              TopTools_ListIteratorOfListOfShape itl( Vedges[ind] );
-              for (; itl.More(); itl.Next())
-                Edges.Append( itl.Value() );
-              Standard_Integer theind=0;
-              Standard_Real MinDeviation = RealLast();
-              for (j = 1; j <= Edges.Length(); j++)
-                {
-                  TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) );
-                  gp_Pln aPlane;
-                  Standard_Boolean issing;
-                  Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing );
-                  if (Deviation < MinDeviation)
-                    {
-                      MinDeviation = Deviation;
-                      theind = j;
-                    }
-                }
-              NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) );
-              B.Remove( OldComp, Edges(theind) );
-            }
-          if (NewWire.Closed())
-            break;
-        }
-      Wseq.Append(NewWire);
-      if (anError)
-        break;
-    }
+    theElist.Append(CurEdge);
+    if (CurVertex.IsSame(theVertex2))
+      return Standard_True;
+  }
+}
 
-  Standard_Real Deviation=0.;
-  Standard_Real MinAngle = RealLast();
-  TopExp_Explorer Explo( OldComp, TopAbs_EDGE );
-  if (!anError && !Explo.More())
+static Standard_Boolean FindCommonVertex(const TopoDS_Edge&   theFirstEdge,
+                                         const TopoDS_Edge&   theLastEdge,
+                                         const TopoDS_Vertex& theFirstVertex,
+                                         const TopoDS_Vertex& theLastVertex,
+                                         TopoDS_Vertex&       theCommonVertex)
+{
+  if (!theFirstVertex.IsSame(theLastVertex))
+  {
+    Standard_Boolean CommonVertexExists = TopExp::CommonVertex(theFirstEdge,
+                                                               theLastEdge,
+                                                               theCommonVertex);
+    return CommonVertexExists;
+  }
+
+  TopoDS_Vertex V1, V2, V3, V4;
+  TopExp::Vertices(theFirstEdge, V1, V2);
+  TopExp::Vertices(theLastEdge, V3, V4);
+
+  if (V1.IsSame(theFirstVertex))
+  {
+    if (V2.IsSame(V3) ||
+        V2.IsSame(V4))
     {
-      if (Wseq.Length() == 1)
-        {
-          resWire = Wseq.First();
-          Deviation = ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular );
-          return Standard_True;
-        }
-      else
-        {
-          for (i = 1; i <= Wseq.Length(); i++)
-            {
-              TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) );
-              gp_Pln aPln;
-              Standard_Boolean issing;
-              Standard_Real aDeviation =
-                ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
-              if (issing)
-                continue;
-
-              Standard_Real Angle = aPln.Axis().Angle( bis.Axis() );
-              if (Angle > M_PI/2)
-                Angle = M_PI - Angle;
-              
-              if (Angle < MinAngle)
-                {
-                  MinAngle = Angle;
-                  resWire = aWire;
-                  resPlane = aPln;
-                  Deviation = aDeviation;
-                }
-            }
-          if (Deviation <= TolDeviation)
-            return Standard_True;
-        }
+      theCommonVertex = V2;
+      return Standard_True;
     }
+  }
+  else
+  {
+    if (V1.IsSame(V3) ||
+        V1.IsSame(V4))
+    {
+      theCommonVertex = V1;
+      return Standard_True;
+    }
+  }
+
   return Standard_False;
-  //end of simplest case
 }
index 2298d7c6b49c2a960f74ab403e95b3b1b84d5d99..a134916e8be9288b935a86a079922a2f62ac3ef9 100644 (file)
@@ -20,6 +20,7 @@
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
+#include <BRepFill_TransitionStyle.hxx>
 #include <gp_Ax2.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Wire.hxx>
 #include <Standard_Boolean.hxx>
 #include <TopTools_DataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <BOPDS_PDS.hxx>
 class gp_Ax2;
 class TopoDS_Face;
 class TopoDS_Wire;
 class TopoDS_Shape;
 
 
-
+//! Trims sets of faces in the corner to make proper parts of pipe
 class BRepFill_TrimShellCorner 
 {
 public:
@@ -42,12 +44,13 @@ public:
   DEFINE_STANDARD_ALLOC
 
   
-  Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Face& theSecPlane);
-  
-  Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Wire& theSpine, const TopoDS_Face& theSecPlane);
-  
-  Standard_EXPORT void SetSpine (const TopoDS_Wire& theSpine);
-  
+  //! Constructor: takes faces to intersect,
+  //! type of transition (it can be RightCorner or RoundCorner)
+  //! and axis of bisector plane
+  Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
+                                           const BRepFill_TransitionStyle         theTransition,
+                                           const gp_Ax2&                          theAxeOfBisPlane);
+
   Standard_EXPORT void AddBounds (const Handle(TopTools_HArray2OfShape)& Bounds);
   
   Standard_EXPORT void AddUEdges (const Handle(TopTools_HArray2OfShape)& theUEdges);
@@ -71,13 +74,29 @@ protected:
 
 private:
 
+  Standard_Boolean MakeFacesSec(const Standard_Integer                     theIndex,
+                                const BOPDS_PDS&                           theDS,
+                                const Standard_Integer                     theFaceIndex1, 
+                                const Standard_Integer                     theFaceIndex2, 
+                                const Standard_Integer                     theSSInterfIndex);
+  
+  Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theIndex,
+                                   const BOPDS_PDS&                           theDS,
+                                   const Standard_Integer                     theFaceIndex1, 
+                                   const Standard_Integer                     theFaceIndex2);
+  
+  Standard_Boolean ChooseSection(const TopoDS_Shape& Comp,
+                                 const TopoDS_Vertex& theFirstVertex,
+                                 const TopoDS_Vertex& theLastVertex,
+                                 TopoDS_Shape& resWire,
+                                 gp_Pln& resPlane,
+                                 Standard_Boolean& IsSingular);
 
 
+  BRepFill_TransitionStyle myTransition;
   gp_Ax2 myAxeOfBisPlane;
   TopoDS_Shape myShape1;
   TopoDS_Shape myShape2;
-  TopoDS_Wire mySpine;
-  TopoDS_Face mySecPln;
   Handle(TopTools_HArray2OfShape) myBounds;
   Handle(TopTools_HArray2OfShape) myUEdges;
   Handle(TopTools_HArray2OfShape) myFaces;
diff --git a/src/BRepFill/BRepFill_Voluved.cxx b/src/BRepFill/BRepFill_Voluved.cxx
new file mode 100644 (file)
index 0000000..9412050
--- /dev/null
@@ -0,0 +1,1794 @@
+// Created on: 2018-03-14
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <BRepFill_Voluved.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepFill_PipeShell.hxx>
+#include <BRepFill_TransitionStyle.hxx>
+#include <TopExp.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <BOPAlgo_Tools.hxx>
+#include <BRepLib_FindSurface.hxx>
+#include <Geom_Plane.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BOPAlgo_MakerVolume.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BOPAlgo_PaveFiller.hxx>
+#include <math_MultipleVarFunctionWithHessian.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <Adaptor2d_HCurve2d.hxx>
+#include <Adaptor3d_HSurface.hxx>
+#include <math_NewtonMinimum.hxx>
+#include <BOPTools_AlgoTools.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <BRepTools.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
+#include <BOPAlgo_BuilderFace.hxx>
+#include <BOPAlgo_BuilderFace.hxx>
+#include <Geom2d_Line.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <math_GlobOptMin.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <Extrema_ExtPC.hxx>
+#include <BOPDS_DS.hxx>
+#include <BRepLib.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
+#include <BRepLib_MakeFace.hxx>
+#include <ShapeFix_Shape.hxx>
+#include <BRepClass_FaceClassifier.hxx>
+#include <BRepGProp_Face.hxx>
+#include <BinTools.hxx>
+
+static const Standard_Real aPipeLinearTolerance = 1.0e-4;
+static const Standard_Real aPipeAngularTolerance = 1.0e-2;
+
+static const Standard_Boolean isParallelComputation = Standard_False;
+const char aDirPatch[] = "T:\\pp\\";
+
+static Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF,
+                                               const Standard_Real theFuzzyToler,
+                                               TopTools_ListOfShape& theListOfFaces,
+                                               TopTools_ListOfShape& theListOfSplits);
+
+//#define BREPFILL_VOLUVED_DEBUG
+
+//=======================================================================
+//function : GetSpineAndProfile
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::GetSpineAndProfile(const TopoDS_Wire& theSpine,
+                                          const TopoDS_Wire& theProfile)
+{
+  mySpine = theSpine;
+  myProfile = theProfile;
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMVEP;
+  TopExp::MapShapesAndAncestors(theProfile, TopAbs_VERTEX, TopAbs_EDGE, aMVEP);
+
+  gp_Vec aN2;
+  gp_Pnt aLoc;
+
+  for (Standard_Integer i = 1; i <= aMVEP.Size(); i++)
+  {
+    const TopoDS_Vertex &aVC = TopoDS::Vertex(aMVEP.FindKey(i));
+
+    const TopTools_ListOfShape &aLE = aMVEP.FindFromIndex(i);
+
+    if (aLE.Extent() < 2)
+      continue;
+
+    const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First());
+    const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last());
+    
+    const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2);
+
+    const Standard_Real aPar1 = BRep_Tool::Parameter(aVC, anE1);
+    const Standard_Real aPar2 = BRep_Tool::Parameter(aVC, anE2);
+
+    gp_Pnt aP;
+    gp_Vec aT1, aT2;
+
+    anAC1.D1(aPar1, aP, aT1);
+    anAC1.D1(aPar2, aP, aT2);
+
+    aN2 = aT1.Crossed(aT2);
+
+    if (aN2.SquareMagnitude() > Precision::SquareConfusion())
+    {
+      aLoc = BRep_Tool::Pnt(aVC);
+      break;
+    }
+  }
+
+  BRepExtrema_DistShapeShape anExtr;
+  anExtr.LoadS1(theSpine);
+
+  if (aN2.SquareMagnitude() > Precision::SquareConfusion())
+  {
+    const gp_Pln aPln(aLoc, aN2);
+    BRepLib_MakeFace aMF(aPln, theProfile);
+    if (!aMF.IsDone())
+      return;
+
+    anExtr.LoadS2(aMF.Face());
+  }
+  else
+  {
+    anExtr.LoadS2(theProfile);
+  }
+
+  if (!anExtr.Perform())
+    return;
+
+  const Standard_Integer aNbSol = anExtr.NbSolution();
+  if (aNbSol < 1)
+    return;
+
+  Standard_Real aDistMin = RealLast();
+  Standard_Integer anIdxMin = 0;
+
+  for (Standard_Integer aSolId = 1; aSolId <= aNbSol; aSolId++)
+  {
+    const Standard_Real aD = anExtr.Value();
+    if (aD > aDistMin)
+      continue;
+
+    aDistMin = aD;
+    anIdxMin = aSolId;
+  }
+  
+  BRepExtrema_SupportType anExtrType2 = anExtr.SupportTypeShape2(anIdxMin);
+
+  if (aDistMin < Precision::Confusion())
+  {
+    anExtrType2 = BRepExtrema_IsInFace;
+  }
+
+  switch (anExtrType2)
+  {
+    case BRepExtrema_IsInFace:
+      if (anExtr.SupportTypeShape1(anIdxMin) == BRepExtrema_IsVertex)
+      {
+        const TopoDS_Vertex aV = TopoDS::Vertex(anExtr.SupportOnShape1(anIdxMin));
+        TopTools_IndexedDataMapOfShapeListOfShape aMVES;
+        TopExp::MapShapesAndAncestors(theSpine, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
+
+        const TopTools_ListOfShape &aLE = aMVES.FindFromKey(aV);
+
+        const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First());
+        const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last());
+
+        const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2);
+
+        const Standard_Real aPar1 = BRep_Tool::Parameter(aV, anE1);
+        const Standard_Real aPar2 = BRep_Tool::Parameter(aV, anE2);
+
+        gp_Pnt aP;
+        gp_Vec aT1, aT2;
+
+        anAC1.D1(aPar1, aP, aT1);
+        anAC1.D1(aPar2, aP, aT2);
+
+        // Find minimal sine
+        const Standard_Real aSqT1 = Max(aT1.SquareMagnitude(), 1.0 / Precision::Infinite());
+        const Standard_Real aSqT2 = Max(aT2.SquareMagnitude(), 1.0 / Precision::Infinite());
+
+        const Standard_Real aSqSin1 = aT1.CrossSquareMagnitude(aN2) / aSqT1;
+        const Standard_Real aSqSin2 = aT2.CrossSquareMagnitude(aN2) / aSqT2;
+
+        if (aSqSin1 < aSqSin2)
+        {
+          if (aT1.Dot(aN2) > 0.0)
+          {
+            myProfile.Reverse();
+          }
+        }
+        else
+        {
+          if (aT2.Dot(aN2) > 0.0)
+          {
+            myProfile.Reverse();
+          }
+        }
+      }
+      else // if (... == BRepExtrema_IsOnEdge)
+      {
+        const TopoDS_Edge anE = TopoDS::Edge(anExtr.SupportOnShape1(anIdxMin));
+        const BRepAdaptor_Curve anAC(anE);
+        Standard_Real aPar;
+        anExtr.ParOnEdgeS1(anIdxMin, aPar);
+
+        gp_Pnt aP;
+        gp_Vec aT1;
+        anAC.D1(aPar, aP, aT1);
+
+        if (aT1.Dot(aN2) > 0.0)
+        {
+          myProfile.Reverse();
+        }
+      }
+      break;
+
+    case BRepExtrema_IsOnEdge:
+    case BRepExtrema_IsVertex:
+    {
+      const BRepLib_MakeFace aMkFSpine(theSpine, Standard_True);
+      if (!aMkFSpine.IsDone())
+        return;
+
+      const TopoDS_Face &aFSpine = aMkFSpine.Face();
+      const Handle(Geom_Plane) aPlnSpine = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aFSpine));
+      const gp_Vec aN1(aPlnSpine->Axis().Direction());
+      gp_Vec aTanV;
+
+      if (anExtr.SupportTypeShape2(anIdxMin) == BRepExtrema_IsVertex)
+      {
+        const TopoDS_Vertex aV = TopoDS::Vertex(anExtr.SupportOnShape2(anIdxMin));
+        TopTools_IndexedDataMapOfShapeListOfShape aMVES;
+        TopExp::MapShapesAndAncestors(theProfile, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
+
+        const TopTools_ListOfShape &aLE = aMVES.FindFromKey(aV);
+
+        const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First());
+        const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last());
+
+        const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2);
+
+        const Standard_Real aPar1 = BRep_Tool::Parameter(aV, anE1);
+        const Standard_Real aPar2 = BRep_Tool::Parameter(aV, anE2);
+
+        gp_Pnt aP;
+        gp_Vec aT1, aT2;
+
+        anAC1.D1(aPar1, aP, aT1);
+        anAC1.D1(aPar2, aP, aT2);
+
+        // Find maximal cosine
+        Standard_Real aSqT1 = aT1.SquareMagnitude();
+        Standard_Real aSqT2 = aT2.SquareMagnitude();
+
+        if (aSqT1 < Precision::SquareConfusion())
+          aSqT1 = RealLast();
+
+        if (aSqT2 < Precision::SquareConfusion())
+          aSqT2 = RealLast();
+
+        const Standard_Real aDP1 = aT1.Dot(aN1);
+        const Standard_Real aDP2 = aT2.Dot(aN1);
+
+        if (aDP1*aDP1*aSqT2 > aDP2*aDP2*aSqT1)
+        {
+          //aDP1*aDP1/aSqT1 > aDP2*aDP2/aSqT2
+          aTanV = aT1;
+        }
+        else
+        {
+          aTanV = aT2;
+        }
+      }
+      else // if(anExtr.SupportTypeShape2(anIdxMin) == BRepExtrema_IsOnEdge)
+      {
+        const TopoDS_Edge anE = TopoDS::Edge(anExtr.SupportOnShape2(anIdxMin));
+        const BRepAdaptor_Curve anAC(anE);
+        Standard_Real aPar;
+        anExtr.ParOnEdgeS2(anIdxMin, aPar);
+
+        gp_Pnt aP;
+        anAC.D1(aPar, aP, aTanV);
+      }
+
+      //The point in the profile, which is the nearest to the spine
+      const gp_Pnt &aPnear = anExtr.PointOnShape2(anIdxMin);
+
+      BRepClass_FaceClassifier aFClass(aFSpine, aPnear, Precision::Confusion());
+      if (aFClass.State() != TopAbs_OUT)
+      {
+        if (aN1.Dot(aTanV) < 0.0)
+        {
+          myProfile = TopoDS::Wire(theProfile.Reversed());
+        }
+      }
+      else
+      {
+        if (aN1.Dot(aTanV) > 0.0)
+        {
+          myProfile = TopoDS::Wire(theProfile.Reversed());
+        }
+      }
+    }
+    break;
+    default:
+      break;
+  }
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::Perform(const TopoDS_Wire& theSpine, 
+                               const TopoDS_Wire& theProfile,
+                               const Standard_Real theTolerance,
+                               const Standard_Boolean theSolidReq)
+{
+  myErrorStatus = BRepFill_Voluved_Empty;
+
+  if (myFuzzyValue < Precision::Confusion())
+  {
+    myFuzzyValue = theTolerance;
+  }
+
+#ifdef BREPFILL_VOLUVED_DEBUG
+  char aBuff[10000];
+  Sprintf(aBuff, "%s%s", aDirPatch, "spine.nbv");
+  BinTools::Write(theSpine, aBuff);
+  Sprintf(aBuff, "%s%s", aDirPatch, "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_VOLUVED_DEBUG
+  std::cout << "Start Evolved. Toler = " << myFuzzyValue << std::endl;
+#endif
+
+  PerformSweep();
+
+#ifdef BREPFILL_VOLUVED_DEBUG
+  std::cout << "PerformSweep complete. Status = " << myErrorStatus << std::endl;
+#endif
+  
+  GetLids();
+
+#ifdef BREPFILL_VOLUVED_DEBUG
+  std::cout << "GetLids complete. Status = " << myErrorStatus << std::endl;
+#endif
+
+  if ((myErrorStatus != BRepFill_Voluved_NotSolid) && !theSolidReq)
+  {
+    myResult = myPipeShell;
+  }
+
+  BuildSolid();
+}
+
+//=======================================================================
+//function : PerformSweep
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::PerformSweep()
+{
+  if (myErrorStatus != BRepFill_Voluved_Empty)
+    return;
+
+  myErrorStatus = BRepFill_Voluved_SweepError;
+
+  Handle(BRepFill_PipeShell) aPipe = new BRepFill_PipeShell(mySpine);
+  aPipe->SetTolerance(aPipeLinearTolerance, aPipeLinearTolerance, aPipeAngularTolerance);
+  aPipe->SetTransition(BRepFill_TransitionStyle::BRepFill_Round);
+  aPipe->Add(myProfile, Standard_False, Standard_False);
+
+  if (aPipe->Build())
+  {
+    myErrorStatus = BRepFill_Voluved_NoLids;
+    myPipeShell = aPipe->Shape();
+  }
+}
+
+//=======================================================================
+//function : GetLids
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::GetLids()
+{
+  if (myPipeShell.IsNull())
+    return;
+
+  if (BRep_Tool::IsClosed(myProfile))
+  {
+    // No need in lids creation
+    myErrorStatus = BRepFill_Voluved_NotSolid;
+    return;
+  }
+
+  myErrorStatus = BRepFill_Voluved_NoLids;
+
+  BRepLib_FindSurface aFS(mySpine, -1.0, Standard_True);
+  const Handle(Geom_Plane) aSurf = Handle(Geom_Plane)::DownCast(aFS.Surface());
+
+  if (aSurf.IsNull())
+  {
+    myErrorStatus = BRepFill_Voluved_NotPlanarSpine;
+    return;
+  }
+
+  //Square of the default angular tolerance in
+  //BOPAlgo_Tools::EdgesToWires(...) and BOPAlgo_Tools::WiresToFaces(...) methods
+  const Standard_Real aSqAnguarTol = 1.0e-16;
+  const gp_Dir &aNormal = aSurf->Axis().Direction();
+
+  // Obtain free-edges from myPipeShell. All edges must be planar
+  // and parallel to the plane of mySpine
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMap;
+
+  TopExp::MapShapesAndAncestors(myPipeShell, TopAbs_EDGE, TopAbs_FACE, aMap);
+
+  TopTools_ListOfShape aLE;
+
+  gp_Pnt aP;
+  gp_Vec aTan;
+
+  for (Standard_Integer i = 1; i <= aMap.Size(); i++)
+  {
+    TopTools_ListOfShape& aListF = aMap(i);
+
+    if (aListF.Extent() != 1)
+      continue;
+
+    const TopoDS_Edge &anE = TopoDS::Edge(aMap.FindKey(i));
+
+    BRepAdaptor_Curve anAC(anE);
+    if (!anAC.Is3DCurve())
+    {
+      // We are not interested in degenerated edges.
+      continue;
+    }
+    
+    anAC.D1(0.5*(anAC.FirstParameter() + anAC.LastParameter()), aP, aTan);
+
+    const Standard_Real aSqModulus = aTan.SquareMagnitude();
+    if (aSqModulus < Precision::Confusion())
+      continue;
+
+    const Standard_Real aDP = aTan.XYZ().Dot(aNormal.XYZ());
+    if (aDP*aDP>aSqModulus*aSqAnguarTol)
+    {
+      //Only planar edges are considered
+      continue;
+    }
+    
+    aLE.Append(anE);
+  }
+
+  if (aLE.IsEmpty())
+  {
+    myErrorStatus = BRepFill_Voluved_NotPlanarSpine;
+    return;
+  }
+
+  // Split interfered edges
+  BOPAlgo_PaveFiller aPF;
+  aPF.SetArguments(aLE);
+  aPF.SetRunParallel(myIsParallel);
+
+  aPF.Perform();
+  if (aPF.HasErrors())
+  {
+    myErrorStatus = BRepFill_Voluved_NotPlanarSpine;
+    return;
+  }
+
+  BOPAlgo_Builder aBuilder;
+  TopTools_ListIteratorOfListOfShape aItLE(aLE);
+  for (; aItLE.More(); aItLE.Next())
+  {
+    const TopoDS_Shape& aS = aItLE.Value();
+    aBuilder.AddArgument(aS);
+  }
+
+  aBuilder.SetRunParallel(myIsParallel);
+  aBuilder.PerformWithFiller(aPF);
+  if (aBuilder.HasErrors())
+  {
+    myErrorStatus = BRepFill_Voluved_NotPlanarSpine;
+    return;
+  }
+
+  const TopoDS_Shape& aFreeEdges = aBuilder.Shape();
+
+  // Collect all free edges to wires and create planar 
+  // top and bottom lids from these wires.
+  BRep_Builder aBB;
+  TopoDS_Compound aCompW;
+  aBB.MakeCompound(aCompW);
+  aBB.MakeCompound(myTopBottom);
+  BOPAlgo_Tools::EdgesToWires(aFreeEdges, aCompW, Standard_True);
+  BOPAlgo_Tools::WiresToFaces(aCompW, myTopBottom);
+
+  myErrorStatus = BRepFill_Voluved_NotSolid;
+}
+
+//=======================================================================
+//function : ProcessVertex
+//purpose  : 
+//=======================================================================
+#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
+#include <BRep_TEdge.hxx>
+void ProcessVertex(const TopoDS_Vertex& aV,
+                   const TopTools_ListOfShape& aLE,
+                   const TopTools_ListOfShape& aLF)
+{
+  Standard_Real aTol, aD2, aTolMax2, aTolE, aParam;
+  gp_Pnt aPC3D;
+  gp_Pnt2d aPC2D;
+  TopAbs_Orientation anOrV;
+
+  TopTools_ListIteratorOfListOfShape anIt;
+  TopExp_Explorer aVExp;
+
+  BRep_ListIteratorOfListOfCurveRepresentation itcr;
+  //
+  aTolMax2 = -1.e6;
+  //
+  Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aV.TShape());
+  const gp_Pnt& aPV3D = TV->Pnt();
+  aTol = BRep_Tool::Tolerance(aV);
+  //
+  anIt.Initialize(aLE);
+  for (; anIt.More(); anIt.Next())
+  {
+    const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
+    //
+    Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
+    const TopLoc_Location& Eloc = aE.Location();
+    //
+    aVExp.Init(aE, TopAbs_VERTEX);
+    for (; aVExp.More(); aVExp.Next())
+    {
+      const TopoDS_Vertex& aVx = TopoDS::Vertex(aVExp.Current());
+      //
+      if (!aVx.IsSame(aV))
+      {
+        continue;
+      }
+      //
+      anOrV = aVx.Orientation();
+      if (!(anOrV == TopAbs_FORWARD || anOrV == TopAbs_REVERSED))
+      {
+        continue;
+      }
+      //
+      const BRep_ListOfCurveRepresentation& aLCR = TE->Curves();
+      itcr.Initialize(aLCR);
+      for (; itcr.More(); itcr.Next())
+      {
+        const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
+        const TopLoc_Location& loc = cr->Location();
+        TopLoc_Location L = (Eloc * loc).Predivided(aV.Location());
+        //
+        // 3D-Curve
+        if (cr->IsCurve3D())
+        {
+          const Handle(Geom_Curve)& aC3D = cr->Curve3D();
+          //
+          if (aC3D.IsNull())
+          {
+            continue;
+          }
+          // 3D-point treatment
+          aParam = BRep_Tool::Parameter(aVx, aE);
+          aPC3D = aC3D->Value(aParam);
+          aPC3D.Transform(L.Transformation());
+          aD2 = aPV3D.SquareDistance(aPC3D);
+          if (aD2 > aTolMax2)
+          {
+            aTolMax2 = aD2;
+          }
+          //
+        }//if (cr->IsCurve3D())
+        //
+        // 2D-Curve
+        else if (cr->IsCurveOnSurface())
+        {
+          const Handle(Geom2d_Curve)& aC2D = cr->PCurve();
+          if (aC2D.IsNull())
+          {
+            continue;
+          }
+          // Surface
+          const Handle(Geom_Surface)& aS = cr->Surface();
+          //
+          // 2D-point treatment
+          aParam = BRep_Tool::Parameter(aVx, aE, aS, L);
+          aPC2D = aC2D->Value(aParam);
+          aS->D0(aPC2D.X(), aPC2D.Y(), aPC3D);
+          aPC3D.Transform(L.Transformation());
+          aD2 = aPV3D.SquareDistance(aPC3D);
+          if (aD2 > aTolMax2)
+          {
+            aTolMax2 = aD2;
+          }
+        } //if (cr->IsCurveOnSurface())
+
+      }//for (; itcr.More(); itcr.Next())
+    }//for (; aVExp.More(); aVExp.Next()) 
+  }//for (; anIt.More(); anIt.Next()) 
+  //#########################################################
+  //
+  // Reducing
+  if (aTolMax2<0.)
+  {
+    return;
+  }
+  //
+  aTolMax2 = sqrt(aTolMax2);
+  if (aTolMax2>aTol)
+  {
+    return;
+  }
+  //
+  anIt.Initialize(aLE);
+  for (; anIt.More(); anIt.Next())
+  {
+    const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
+
+    aTolE = BRep_Tool::Tolerance(aE);
+    if (aTolMax2 < aTolE)
+    {
+      aTolMax2 = aTolE;
+    }
+  }
+  //
+  anIt.Initialize(aLF);
+  for (; anIt.More(); anIt.Next())
+  {
+    const TopoDS_Face& aF = TopoDS::Face(anIt.Value());
+
+    aTolE = BRep_Tool::Tolerance(aF);
+    if (aTolMax2 < aTolE)
+    {
+      aTolMax2 = aTolE;
+    }
+  }
+  //
+  if (aTolMax2>aTol)
+  {
+    return;
+  }
+  //
+  // Update Tolerance
+  TV->Tolerance(aTolMax2);
+}
+
+//=======================================================================
+//function : ReduceVertexTolerance
+//purpose  : 
+//=======================================================================
+void ReduceVertexTolerance(const TopoDS_Shape& aS)
+{
+  Standard_Integer i, aNbV;
+  TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap;
+
+  TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
+  TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap);
+
+  aNbV = aVEMap.Extent();
+  for (i = 1; i <= aNbV; i++)
+  {
+    const TopoDS_Vertex& aV = TopoDS::Vertex(aVEMap.FindKey(i));
+    const TopTools_ListOfShape& aLE = aVEMap(i);
+    const TopTools_ListOfShape& aLF = aVFMap.FindFromKey(aV);
+
+    ProcessVertex(aV, aLE, aLF);
+  }
+}
+
+
+//=======================================================================
+//function : BuildSolid
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::BuildSolid()
+{
+  if (myErrorStatus != BRepFill_Voluved_NotSolid)
+    return;
+
+  myErrorStatus = BRepFill_Voluved_NotVolume;
+
+  TopTools_MapOfShape aMapF;
+  TopTools_ListOfShape aLF, aLSplits;
+  TopExp_Explorer anExpF;
+
+  Handle(ShapeFix_Shape) aSFix = new ShapeFix_Shape;
+  aSFix->Init(myPipeShell);
+
+#ifdef BREPFILL_VOLUVED_DEBUG
+  char aBuff[10000];
+  Sprintf(aBuff, "%s%s", aDirPatch, "shape1.nbv");
+  BinTools::Write(myPipeShell, aBuff);
+#endif
+
+
+  aSFix->Perform();
+  myPipeShell = aSFix->Shape();
+
+#ifdef BREPFILL_VOLUVED_DEBUG
+  Sprintf(aBuff, "%s%s", aDirPatch, "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;
+
+    TopoDS_Face aFC = aF;
+    aSFix->Init(aFC);
+    aSFix->Perform();
+    aFC = TopoDS::Face(aSFix->Shape());
+    ReduceVertexTolerance(aFC);
+
+    CheckSingularityAndAdd(aFC, myFuzzyValue, aLF, aLSplits);
+  }
+  
+  {
+    TopTools_ListIteratorOfListOfShape anItrS(aLSplits);
+    for (; anItrS.More(); anItrS.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItrS.Value());
+      aLF.Append(aF);
+    }
+
+#ifdef BREPFILL_VOLUVED_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", aDirPatch, "shape3.nbv");
+    BinTools::Write(aDebComp, aBuff);
+#endif
+
+    // Split interfered faces
+    BOPAlgo_PaveFiller aPF;
+    aPF.SetArguments(aLF);
+    aPF.SetRunParallel(myIsParallel);
+    aPF.SetFuzzyValue(myFuzzyValue);
+
+    aPF.Perform();
+    if (!aPF.HasErrors())
+    {
+      BOPAlgo_Builder aBuilder;
+      TopTools_ListIteratorOfListOfShape aItLE(aLF);
+      for (; aItLE.More(); aItLE.Next())
+      {
+        const TopoDS_Shape& aS = aItLE.Value();
+        aBuilder.AddArgument(aS);
+      }
+
+      aBuilder.SetRunParallel(myIsParallel);
+      aBuilder.PerformWithFiller(aPF);
+      myPipeShell = aBuilder.Shape();
+    }
+  }
+
+#ifdef BREPFILL_VOLUVED_DEBUG
+  Sprintf(aBuff, "%s%s", aDirPatch, "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_VOLUVED_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", aDirPatch, "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_VOLUVED_DEBUG
+  std::cout << "BuildSolid After VM." << std::endl;
+#endif
+
+  RemoveExcessSolids(aLSplits, myResult, aLF, aMV);
+
+  myErrorStatus = BRepFill_Voluved_OK;
+}
+
+//=======================================================================
+//function : ExtractOuterSolid
+//purpose  : 
+//=======================================================================
+void BRepFill_Voluved::ExtractOuterSolid(TopoDS_Shape& theShape,
+                                         TopTools_ListOfShape& theArgsList)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape aMapS;
+  TopExp::MapShapesAndAncestors(theShape, TopAbs_FACE, TopAbs_SOLID, aMapS);
+
+  Standard_Boolean hasBeenDeleted = Standard_False;
+
+  for (Standard_Integer i = 1; i <= aMapS.Extent(); i++)
+  {
+    const TopTools_ListOfShape &aL = aMapS(i);
+    if (aL.Extent() > 1)
+    {
+      // Face is shared between several solids. ==> 
+      // It cannot participate in the outer contour and should be removed.
+
+      const TopoDS_Face &aF = TopoDS::Face(aMapS.FindKey(i));
+      theArgsList.Remove(aF);
+      hasBeenDeleted = Standard_True;
+    }
+  }
+
+  if (!hasBeenDeleted)
+    return;
+
+  BOPAlgo_MakerVolume aMV;
+  aMV.SetArguments(theArgsList);
+  aMV.SetIntersect(Standard_True);
+  aMV.SetRunParallel(myIsParallel);
+  aMV.SetAvoidInternalShapes(Standard_True);
+  aMV.Perform();
+
+  if (aMV.HasErrors())
+  {
+    return;
+  }
+
+  theShape = aMV.Shape();
+}
+
+//=======================================================================
+//function : RemoveExcessSolids
+//purpose  : 
+//=======================================================================
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+void BRepFill_Voluved::RemoveExcessSolids(const TopTools_ListOfShape& /*theLSplits*/,
+                                          TopoDS_Shape& theShape,
+                                          TopTools_ListOfShape& /*theArgsList*/,
+                                          BOPAlgo_MakerVolume& /*theMV*/)
+{
+  if (myErrorStatus != BRepFill_Voluved_NotVolume)
+    return;
+  
+#if 1
+  TopExp_Explorer anExpSo(theShape, TopAbs_SOLID);
+  Standard_Real aMaxVol = RealFirst();
+  myResult = anExpSo.Current();
+  for(;anExpSo.More(); anExpSo.Next())
+  {
+    const TopoDS_Solid &aSol = TopoDS::Solid(anExpSo.Current());
+    GProp_GProps aGprop;
+    BRepGProp::VolumeProperties(aSol, aGprop, 1.0e-4);
+    const Standard_Real aV = aGprop.Mass();
+
+    if(aV > aMaxVol)
+    {
+      aMaxVol = aV;
+      myResult = aSol;
+    }
+  }
+#else
+
+  TopExp_Explorer anExpSo;
+  for (Standard_Integer i = 0; i < 2; i++)
+  {
+    anExpSo.Init(theShape, TopAbs_SOLID);
+    if (!anExpSo.More())
+    {
+      myResult = theShape;
+      return;
+    }
+
+    anExpSo.Next();
+    if (!anExpSo.More())
+    {
+      // Only one solid has been generated
+      myResult = TopoDS::Solid(anExpSo.Current());
+      return;
+    }
+
+    if (i != 0)
+      break;
+
+    ExtractOuterSolid(theShape, theArgsList);
+  }
+
+  // Remove Split faces from the list of arguments
+  TopTools_ListIteratorOfListOfShape anItl(theLSplits);
+  for (; anItl.More(); anItl.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anItl.Value());
+    theArgsList.Remove(aF);
+  }
+
+  // Create a list of invalid faces. The face is invalid if
+  // BOPAlgo_MakerVolume changes its orientation while creating solids.
+  // Faces from theLSplits are not checked.
+  TopTools_ListOfShape aListInvFaces;
+  for (anItl.Init(theArgsList); anItl.More(); anItl.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anItl.Value());
+    for (TopTools_ListIteratorOfListOfShape anItM(theMV.Modified(aF));
+         anItM.More(); anItM.Next())
+    {
+      const TopoDS_Face &aFM = TopoDS::Face(anItM.Value());
+
+      if (aFM.Orientation() != aF.Orientation())
+        aListInvFaces.Append(aFM);
+    }
+  }
+
+  TopTools_ListOfShape aSolidList;
+  for (anExpSo.Init(theShape, TopAbs_SOLID); anExpSo.More(); anExpSo.Next())
+  {
+    const TopoDS_Solid &aSo = TopoDS::Solid(anExpSo.Current());
+    TopTools_IndexedMapOfShape aMapF;
+    TopExp::MapShapes(aSo, TopAbs_FACE, aMapF);
+    Standard_Boolean isToDelete = Standard_False;
+
+    for (anItl.Init(aListInvFaces); anItl.More(); anItl.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItl.Value());
+      if (aMapF.Contains(aF))
+      {
+        isToDelete = Standard_True;
+        break;
+      }
+    }
+
+    if (isToDelete)
+    {
+      continue;
+    }
+    
+    for (anItl.Init(theArgsList); anItl.More(); anItl.Next())
+    {
+      const TopoDS_Face &aF = TopoDS::Face(anItl.Value());
+      const Standard_Integer anIdx = aMapF.FindIndex(aF);
+      if (anIdx == 0)
+        continue;
+
+      const TopoDS_Face &aF1 = TopoDS::Face(aMapF.FindKey(anIdx));
+
+      // aF and aF1 are same shapes. Check if they are equal.
+
+      if (!aF.IsEqual(aF1))
+      {
+        isToDelete = Standard_True;
+        break;
+      }
+    }
+
+    if (isToDelete)
+    {
+      continue;
+    }
+
+    aSolidList.Append(aSo);
+  }
+
+  if (aSolidList.Extent() < 1)
+  {
+    myResult = theShape;
+    return;
+  }
+
+  if (aSolidList.Extent() == 1)
+  {
+    myResult = aSolidList.First();
+    return;
+  }
+
+  BRep_Builder aBB;
+  TopoDS_Compound aCmpSol;
+  aBB.MakeCompound(aCmpSol);
+
+  for (anItl.Init(aSolidList); anItl.More(); anItl.Next())
+  {
+    const TopoDS_Solid &aSo = TopoDS::Solid(anItl.Value());
+    aBB.Add(aCmpSol, aSo);
+  }
+
+  myResult = aCmpSol;
+#endif
+}
+
+//=======================================================================
+//class : NormalFunc
+//purpose  : 
+//=======================================================================
+class NormalFunc : public math_MultipleVarFunctionWithHessian
+{
+public:
+  NormalFunc(const Adaptor3d_CurveOnSurface& theCOS) :myCOnS(theCOS)
+  {
+  }
+
+  virtual Standard_Integer NbVariables() const Standard_OVERRIDE
+  {
+    return 1;
+  }
+
+
+  virtual Standard_Boolean Value(const math_Vector& X, Standard_Real& F) Standard_OVERRIDE;
+  virtual Standard_Boolean Gradient(const math_Vector& X, math_Vector& G) Standard_OVERRIDE;
+  virtual Standard_Boolean Values(const math_Vector& theX,
+                                  Standard_Real& theF,
+                                  math_Vector& theG) Standard_OVERRIDE
+  {
+    if (!Value(theX, theF))
+    return Standard_False;
+
+    if (!Gradient(theX, theG))
+      return Standard_False;
+
+    return Standard_True;
+  };
+
+  virtual Standard_Boolean Values(const math_Vector& theX,
+                                  Standard_Real& theF,
+                                  math_Vector& theG,
+                                  math_Matrix& theH) Standard_OVERRIDE
+  {
+    if (!Values(theX, theF, theG))
+    return Standard_False;
+
+    theH(1, 1) = theG(1);
+    return Standard_True;
+  };
+
+  Standard_Real FirstParameter() const
+  {
+    return myCOnS.FirstParameter();
+  }
+
+  Standard_Real LastParameter() const
+  {
+    return myCOnS.LastParameter();
+  }
+
+  gp_Pnt GetPoint(const Standard_Real theX)
+  {
+    const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve();
+    const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface();
+    const gp_Pnt2d aP2d(aC->Value(theX));
+    return aS->Value(aP2d.X(), aP2d.Y());
+  }
+
+protected:
+
+  NormalFunc& operator=(NormalFunc&);
+
+private:
+  const Adaptor3d_CurveOnSurface& myCOnS;
+};
+
+//=======================================================================
+//function : Value
+//purpose  : +aD1v_x^2*aD1u_y^2 + aD1v_x^2*aD1u_z^2 +
+//           +aD1v_y^2*aD1u_z^2 + aD1u_x^2*aD1v_y^2 + 
+//           +aD1u_x^2*aD1v_z^2 + aD1u_y^2*aD1v_z^2 -
+//           -  2*(+aD1u_x*aD1v_x*aD1u_y*aD1v_y + 
+//                 +aD1u_x*aD1v_x*aD1u_z*aD1v_z +
+//                 +aD1u_y*aD1v_y*aD1u_z*aD1v_z)
+//=======================================================================
+Standard_Boolean NormalFunc::Value(const math_Vector& theX, Standard_Real& theF)
+{
+  const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve();
+  const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface();
+
+  const gp_Pnt2d aP2d(aC->Value(theX(1)));
+  gp_Pnt aP3d;
+  gp_Vec aD1u, aD1v;
+  aS->D1(aP2d.X(), aP2d.Y(), aP3d, aD1u, aD1v);
+
+  theF = aD1u.Crossed(aD1v).SquareMagnitude();
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Gradient
+//purpose  :
+//2 * ((aD1v_x*aD1u_y)*(aD1u_y*(aD2uv_x*aDc_x + aD2v_x*aDc_y) + aD1v_x*(aD2u_y*aDc_x + aD2uv_y*aDc_y)) +
+//     (aD1v_x*aD1u_z)*(aD1u_z*(aD2uv_x*aDc_x + aD2v_x*aDc_y) + aD1v_x*(aD2u_z*aDc_x + aD2uv_z*aDc_y)) +
+//     (aD1v_y*aD1u_z)*(aD1u_z*(aD2uv_y*aDc_x + aD2v_y*aDc_y) + aD1v_y*(aD2u_z*aDc_x + aD2uv_z*aDc_y)) +
+//     (aD1u_x*aD1v_y)*(aD1u_x*(aD2uv_y*aDc_x + aD2v_y*aDc_y) + aD1v_y*(aD2u_x*aDc_x + aD2uv_x*aDc_y)) +
+//     (aD1u_x*aD1v_z)*(aD1u_x*(aD2uv_z*aDc_x + aD2v_z*aDc_y) + aD1v_z*(aD2u_x*aDc_x + aD2uv_x*aDc_y)) +
+//     (aD1u_y*aD1v_z)*(aD1u_y*(aD2uv_z*aDc_x + aD2v_z*aDc_y) + aD1v_z*(aD2u_y*aDc_x + aD2uv_y*aDc_y)) -
+//
+//     (aD2u_x*aDc_x + aD2uv_x*aDc_y)*aD1v_x*aD1u_y*aD1v_y -
+//     aD1u_x*(aD2uv_x*aDc_x + aD2v_x*aDc_y)*aD1u_y*aD1v_y -
+//     aD1u_x*aD1v_x*(aD2u_y*aDc_x + aD2uv_y*aDc_y)*aD1v_y -
+//     aD1u_x*aD1v_x*aD1u_y*(aD2uv_y*aDc_x + aD2v_y*aDc_y) -
+//
+//     (aD2u_x*aDc_x + aD2uv_x*aDc_y)*aD1v_x*aD1u_z*aD1v_z -
+//     aD1u_x*(aD2uv_x*aDc_x + aD2v_x*aDc_y)*aD1u_z*aD1v_z -
+//     aD1u_x*aD1v_x*(aD2u_z*aDc_x + aD2uv_z*aDc_y)*aD1v_z -
+//     aD1u_x*aD1v_x*aD1u_z*(aD2uv_z*aDc_x + aD2v_z*aDc_y) -
+//
+//     (aD2u_y*aDc_x + aD2uv_y*aDc_y)*aD1v_y*aD1u_z*aD1v_z -
+//     aD1u_y*(aD2uv_y*aDc_x + aD2v_y*aDc_y)*aD1u_z*aD1v_z -
+//     aD1u_y*aD1v_y*(aD2u_z*aDc_x + aD2uv_z*aDc_y)*aD1v_z -
+//     aD1u_y*aD1v_y*aD1u_z*(aD2uv_z*aDc_x + aD2v_z*aDc_y))
+//=======================================================================
+Standard_Boolean NormalFunc::Gradient(const math_Vector& theX, math_Vector& theG)
+{
+  const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve();
+  const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface();
+
+  gp_Pnt2d aP2d;
+  gp_Vec2d aDc;
+  aC->D1(theX(1), aP2d, aDc);
+
+  gp_Pnt aP3d;
+  gp_Vec aD1u, aD1v, aD2u, aD2v, aD2uv;
+  aS->D2(aP2d.X(), aP2d.Y(), aP3d, aD1u, aD1v, aD2u, aD2v, aD2uv);
+
+  theG(1) = (aD1v.X()*aD1u.Y())*(aD1u.Y()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y()) +
+            aD1v.X()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())) + 
+            (aD1v.X()*aD1u.Z())*(aD1u.Z()*(aD2uv.X()*aDc.X() + 
+            aD2v.X()*aDc.Y()) + aD1v.X()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())) +
+            (aD1v.Y()*aD1u.Z())*(aD1u.Z()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) + 
+            aD1v.Y()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())) + (aD1u.X()*aD1v.Y())*
+            (aD1u.X()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) + aD1v.Y()*(aD2u.X()*
+            aDc.X() + aD2uv.X()*aDc.Y())) + (aD1u.X()*aD1v.Z())*(aD1u.X()*(aD2uv.Z()*
+            aDc.X() + aD2v.Z()*aDc.Y()) + aD1v.Z()*(aD2u.X()*aDc.X() + 
+            aD2uv.X()*aDc.Y())) + (aD1u.Y()*aD1v.Z())*(aD1u.Y()*(aD2uv.Z()*aDc.X() + 
+            aD2v.Z()*aDc.Y()) + aD1v.Z()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())) -
+            (aD2u.X()*aDc.X() + aD2uv.X()*aDc.Y())*aD1v.X()*aD1u.Y()*aD1v.Y() - 
+            aD1u.X()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y())*aD1u.Y()*aD1v.Y() -
+            aD1u.X()*aD1v.X()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())*aD1v.Y() - 
+            aD1u.X()*aD1v.X()*aD1u.Y()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) - 
+            (aD2u.X()*aDc.X() + aD2uv.X()*aDc.Y())*aD1v.X()*aD1u.Z()*aD1v.Z() - 
+            aD1u.X()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y())*aD1u.Z()*aD1v.Z() - 
+            aD1u.X()*aD1v.X()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())*aD1v.Z() - 
+            aD1u.X()*aD1v.X()*aD1u.Z()*(aD2uv.Z()*aDc.X() + aD2v.Z()*aDc.Y()) - 
+            (aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())*aD1v.Y()*aD1u.Z()*aD1v.Z() - 
+            aD1u.Y()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y())*aD1u.Z()*aD1v.Z() - 
+            aD1u.Y()*aD1v.Y()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())*aD1v.Z() -
+            aD1u.Y()*aD1v.Y()*aD1u.Z()*(aD2uv.Z()*aDc.X() + aD2v.Z()*aDc.Y());
+
+  return Standard_True;
+}
+
+//=======================================================================
+//structure : EInfoTosplit
+//purpose  : 
+//=======================================================================
+struct EInfoTosplit
+{
+  TopoDS_Edge myEdge;
+  TopoDS_Vertex myVertexToSplit;
+  Standard_Real myParam;
+  Standard_Real myTolerance;
+};
+
+//=======================================================================
+//function : RebuildFaces
+//purpose  : Creates a wires from theEdges and puts it to the new face
+//            which is empty-copied from theSourceFace.
+//=======================================================================
+static void RebuildFaces(const TopTools_ListOfShape& theLE,
+                         const TopoDS_Face& theSourceFace,
+                         TopTools_ListOfShape& theList)
+{
+  //build new faces
+  BOPAlgo_BuilderFace aBF;
+
+  TopoDS_Face aF = TopoDS::Face(theSourceFace.Oriented(TopAbs_FORWARD));
+
+  aBF.SetFace(aF);
+  aBF.SetShapes(theLE);
+
+  aBF.Perform();
+
+  const TopTools_ListOfShape& aLFR = aBF.Areas();
+
+  if (aLFR.IsEmpty())
+  {
+    theList.Append(theSourceFace);
+    return;
+  }
+
+  TopTools_ListIteratorOfListOfShape aItFR(aLFR);
+  for (; aItFR.More(); aItFR.Next())
+  {
+    const TopoDS_Shape& aFR = TopoDS::Face(aItFR.Value());
+    theList.Append(aFR);
+  }
+}
+
+//=======================================================================
+//function : MakeEdgeDegenerated
+//purpose  : Returns TRUE if degenerated edge has been created.
+//           Every degenerated edge (to split) must be added in theLEdges twice
+//           with different orientations. Moreover, Degenerated edges cannot be shared.
+//           Therefore, make copy of them before adding.
+//=======================================================================
+static Standard_Boolean MakeEdgeDegenerated(const TopoDS_Vertex& theV,
+                                            const TopoDS_Face& theFace,
+                                            const gp_Pnt2d& thePf,
+                                            const gp_Pnt2d& thePl,
+                                            TopTools_ListOfShape& theLEdges)
+{
+  BRepAdaptor_Surface anAS(theFace, Standard_False);
+
+  const Standard_Real aTol = 2.0*BRep_Tool::Tolerance(theV);
+  const Standard_Real aTolU = anAS.UResolution(aTol),
+                      aTolV = anAS.VResolution(aTol);
+
+  if ((Abs(thePf.X() - thePl.X()) < aTolU) && (Abs(thePf.Y() - thePl.Y()) < aTolV))
+    return Standard_False;
+
+  const TopoDS_Vertex aVf = TopoDS::Vertex(theV.Oriented(TopAbs_FORWARD)),
+                      aVl = TopoDS::Vertex(theV.Oriented(TopAbs_REVERSED));
+  
+  const gp_XY aV = thePl.XY() - thePf.XY();
+  const Handle(Geom2d_Line) aL1 = new Geom2d_Line(thePf, gp_Dir2d(aV));
+  const Handle(Geom2d_Line) aL2 = new Geom2d_Line(thePl, gp_Dir2d(aV.Reversed()));
+
+  BRep_Builder aBB;
+  TopoDS_Edge anEdegen1, anEdegen2;
+  aBB.MakeEdge(anEdegen1);
+  aBB.MakeEdge(anEdegen2);
+
+  aBB.UpdateEdge(anEdegen1, aL1, theFace, Precision::Confusion());
+  aBB.UpdateEdge(anEdegen2, aL2, theFace, Precision::Confusion());
+
+  anEdegen1.Orientation(TopAbs_FORWARD);
+  anEdegen2.Orientation(TopAbs_FORWARD);
+
+  aBB.Add(anEdegen1, aVf);
+  aBB.Add(anEdegen1, aVl);
+  aBB.Add(anEdegen2, aVf);
+  aBB.Add(anEdegen2, aVl);
+
+  aBB.Degenerated(anEdegen1, Standard_True);
+  aBB.Degenerated(anEdegen2, Standard_True);
+
+  const Standard_Real aLPar = aV.Modulus();
+  aBB.Range(anEdegen1, 0.0, aLPar);
+  aBB.Range(anEdegen2, 0.0, aLPar);
+
+  theLEdges.Append(anEdegen1);
+  theLEdges.Append(anEdegen2);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : InsertEDegenerated
+//purpose  : 
+//=======================================================================
+static void InsertEDegenerated(const TopoDS_Face& theFace,
+                               TopTools_ListOfShape& theLEdges)
+{
+  BRep_Builder aBB;
+  TopoDS_Wire aWir;
+  aBB.MakeWire(aWir);
+
+  TopTools_ListIteratorOfListOfShape anItr(theLEdges);
+  for (; anItr.More(); anItr.Next())
+  {
+    const TopoDS_Edge &anE = TopoDS::Edge(anItr.Value());
+    aBB.Add(aWir, anE);
+  }
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
+  TopExp::MapShapesAndUniqueAncestors(aWir, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
+
+  BRepTools_WireExplorer anExp(aWir, theFace);
+
+  TopoDS_Edge anE1 = anExp.Current(), aFirstEdge, aLastEdge;
+
+  if (anE1.IsNull())
+  {
+    // It is possible if aWir contains
+    // only INTERNAL/EXTERNAL edges.
+
+    return;
+  }
+
+  aFirstEdge = anE1;
+  anExp.Next();
+
+# if 0
+  if (!anExp.More())
+  {
+    // The wire contains only single edge.
+    // But this edge can be closed itself (e.g. circle).
+
+    TopoDS_Vertex aVf, aVl;
+    TopExp::Vertices(anE1, aVf, aVl);
+    if (!aVf.IsNull() && aVf.IsSame(aVl))
+    {
+      Standard_Real aF, aL;
+      const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(anE1, theFace, aF, aL);
+      aF = BRep_Tool::Parameter(aVf, anE1);
+      aL = BRep_Tool::Parameter(aVl, anE1);
+      const gp_Pnt2d aPf(aC->Value(aF)), aPl(aC->Value(aL));
+
+      MakeEdgeDegenerated(aVf, theFace, aPf, aPl, theLEdges);
+    }
+
+    return;
+  }
+#endif
+
+  // Map containing all vertices of degenerated edges
+  TopTools_MapOfShape aMapVofDE;
+
+  {
+    TopExp_Explorer anExpDE(aWir, TopAbs_EDGE);
+    for (; anExpDE.More(); anExpDE.Next())
+    {
+      const TopoDS_Edge &anE = TopoDS::Edge(anExpDE.Current());
+      if (!BRep_Tool::Degenerated(anE))
+        continue;
+
+      TopoDS_Vertex aV1, aV2;
+      TopExp::Vertices(anE, aV1, aV2);
+
+      // aV1 and aV2 are SAME vertices
+
+      aMapVofDE.Add(aV1);
+    }
+  }
+
+  for (; anExp.More(); anExp.Next())
+  {
+    const TopoDS_Edge& anE2 = anExp.Current();
+    aLastEdge = anE2;
+#if 0
+    if (anE1.IsSame(anE2))
+    {
+      //Exclude a gap between two seam-edges (e.g. cylinder without roofs).
+      anE1 = anE2;
+      continue;
+    }
+#endif
+
+    const TopoDS_Vertex &aVertCurr = anExp.CurrentVertex();
+
+    if (aMapVofDE.Contains(aVertCurr))
+    {
+      // Necessary degenerated edge has already been created.
+      anE1 = anE2;
+      continue;
+    }
+
+    Standard_Real aF, aL;
+    const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(anE1, theFace, aF, aL),
+                               aC2 = BRep_Tool::CurveOnSurface(anE2, theFace, aF, aL);
+    aF = BRep_Tool::Parameter(aVertCurr, anE1);
+    aL = BRep_Tool::Parameter(aVertCurr, anE2);
+    const gp_Pnt2d aPf(aC1->Value(aF)), aPl(aC2->Value(aL));
+
+    if (MakeEdgeDegenerated(aVertCurr, theFace, aPf, aPl, theLEdges))
+    {
+      aMapVofDE.Add(aVertCurr);
+      anE1 = anE2;
+      continue;
+    }
+
+    const TopTools_ListOfShape *anEList = aMapVE.Seek(aVertCurr);
+    if ((anEList != 0) && (anEList->Extent() <= 2))
+    {
+      anE1 = anE2;
+      continue;
+    }
+
+    // Case like cone with apex. In 2D space all is OK
+    // (therefore BRepTools_WireExplorer processes this case
+    // correctly). But in 3D-space, we have several edges with
+    // the same vertex. Cone apex must be plugged by degenerated edge.
+
+    Standard_Boolean hasDegenerated = Standard_False;
+    TopTools_ListIteratorOfListOfShape anItr(*anEList);
+    for (; anItr.More(); anItr.Next())
+    {
+      const TopoDS_Edge &anEdge = TopoDS::Edge(anItr.Value());
+      if (BRep_Tool::Degenerated(anEdge))
+      {
+        hasDegenerated = Standard_True;
+        break;
+      }
+    }
+
+    if (hasDegenerated)
+    {
+      anE1 = anE2;
+      continue;
+    }
+
+    // Look for the pair for anE1 and anE2 edges
+    for (Standard_Integer i = 0; i < 2; i++)
+    {
+      const gp_Pnt2d &aPoint = i ? aPl : aPf;
+      anItr.Initialize(*anEList);
+      for (; anItr.More(); anItr.Next())
+      {
+        const TopoDS_Edge &anEdge = TopoDS::Edge(anItr.Value());
+
+        if (anEdge.IsSame(anE1) || anEdge.IsSame(anE2))
+          continue;
+
+        const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(anEdge, theFace, aF, aL);
+        aF = BRep_Tool::Parameter(aVertCurr, anEdge);
+        const gp_Pnt2d aP(aC->Value(aF));
+
+        if (MakeEdgeDegenerated(aVertCurr, theFace, aPoint, aP, theLEdges))
+        {
+          aMapVofDE.Add(aVertCurr);
+          i = 2;
+          break;
+        }
+      }
+    }
+    
+    anE1 = anE2;
+  }
+
+  if (aFirstEdge.IsNull() || aLastEdge.IsNull())
+    return;
+
+#if 0
+  if (aFirstEdge.IsSame(aLastEdge))
+  {
+    //Exclude a gap between two seam-edges (e.g. cylinder without bottom-base).
+
+    return;
+  }
+#endif
+
+  //TopExp::CommonVertex(...) does not work
+  //if edges have more than one pair of common vertex
+  //(e.g. two halves of circle). Here, we process this case.
+  TopoDS_Vertex aV[4];
+  TopExp::Vertices(aFirstEdge, aV[0], aV[1]);
+  if (!aV[0].IsNull() && aV[0].IsSame(aV[1]))
+  {
+    // Possible reason is the NOT-CLOSED edge
+    // has only single vertex and is covered by it.
+    return;
+  }
+
+  TopExp::Vertices(aLastEdge, aV[2], aV[3]);
+  if (!aV[2].IsNull() && aV[2].IsSame(aV[3]))
+  {
+    // Possible reason is the NOT-CLOSED edge
+    // has only single vertex and is covered by it.
+    return;
+  }
+
+  for (Standard_Integer anIDFE = 0; anIDFE < 2; anIDFE++)
+  {
+    for (Standard_Integer anIDLE = 2; anIDLE < 4; anIDLE++)
+    {
+      if (!aV[anIDFE].IsSame(aV[anIDLE]))
+        continue;
+
+      const NCollection_List<TopoDS_Shape> *anEList = aMapVE.Seek(aV[anIDFE]);
+      if ((anEList != 0) && (anEList->Extent() > 2))
+      {
+        // Causes:
+        //  1. Non-manifold topology.
+        //  2. Case such as:
+        //
+        //        *************************
+        //        *                       *
+        //  seam  *                       *  seam
+        //        *  edge1         edge2  *
+        //        * ********    ********* *
+        //       V1        V2   V3       V4
+        //
+        //
+        //  V1 - vertex between edge1 and seam
+        //  V4 - vertex between edge2 and seam
+        //
+        //  Indeed, V1 and V4 are same but they
+        //  must not be joined.
+
+        continue;
+      }
+
+      Standard_Real aF, aL;
+      const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(aFirstEdge, theFace, aF, aL),
+                                 aC2 = BRep_Tool::CurveOnSurface(aLastEdge, theFace, aF, aL);
+      aF = BRep_Tool::Parameter(aV[anIDFE], aFirstEdge);
+      aL = BRep_Tool::Parameter(aV[anIDLE], aLastEdge);
+      const gp_Pnt2d aPf(aC1->Value(aF)), aPl(aC2->Value(aL));
+
+      MakeEdgeDegenerated(aV[anIDFE], theFace, aPf, aPl, theLEdges);
+    }
+  }
+}
+
+//=======================================================================
+//function : CheckSingularityAndAdd
+//purpose  : Returns TRUE if theF has been split
+//=======================================================================
+Standard_Boolean BRepFill_Voluved::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;
+    TopTools_ListIteratorOfListOfShape aItLE(aLE);
+    for (; aItLE.More(); aItLE.Next())
+    {
+      const TopoDS_Shape& aS = aItLE.Value();
+      aBuilder.AddArgument(aS);
+    }
+
+    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 aF = TopoDS::Face(theF.Oriented(TopAbs_FORWARD));
+
+  for (TopoDS_Iterator anExpW(aF); anExpW.More(); anExpW.Next())
+  {
+    const TopoDS_Wire &aWir = TopoDS::Wire(anExpW.Value());
+
+    TopTools_ListOfShape aLGF;
+    TopExp_Explorer anEExp(aWir, TopAbs_EDGE);
+    for (; anEExp.More(); anEExp.Next())
+    {
+      const TopoDS_Edge &anE = TopoDS::Edge(anEExp.Current());
+      aLGF.Append(anE);
+    }
+
+    BOPAlgo_PaveFiller aPF;
+    aPF.SetArguments(aLGF);
+    aPF.SetFuzzyValue(theFuzzyToler);
+    aPF.Perform();
+
+    if (aPF.HasErrors())
+    {
+      continue;
+    }
+
+    const BOPDS_DS &aDS = aPF.DS();
+    if (aDS.NbShapes() == aDS.NbSourceShapes())
+    {
+      //No new shapes have been created  
+      continue;
+    }
+
+    BOPAlgo_Builder aBAB(NCollection_BaseAllocator::CommonBaseAllocator());
+    TopTools_ListIteratorOfListOfShape aBItr(aLGF);
+    for (; aBItr.More(); aBItr.Next())
+    {
+      const TopoDS_Shape &aSh = aBItr.Value();
+      aBAB.AddArgument(aSh);
+    }
+
+    aBAB.SetRunParallel(myIsParallel);
+    aBAB.SetNonDestructive(Standard_True);
+    aBAB.PerformWithFiller(aPF);
+    if (aBAB.HasErrors())
+    {
+      continue;
+    }
+
+    TopTools_ListOfShape aLE;
+#if 0
+    // This fragment requires fixing the issue #29656
+    TopTools_MapOfShape aMM;
+    TopExp_Explorer anExpEB(aBAB.Shape(), TopAbs_EDGE);
+    for (; anExpEB.More(); anExpEB.Next())
+    {
+      const TopoDS_Edge anEE = TopoDS::Edge(anExpEB.Current());
+      if (!aMM.Add(anEE))
+        continue;
+
+      aLE.Append(anEE);
+    }
+#else
+    for (aBItr.Init(aLGF); aBItr.More(); aBItr.Next())
+    {
+      const TopoDS_Edge &aSh = TopoDS::Edge(aBItr.Value());
+      const TopTools_ListOfShape &aLM = aBAB.Modified(aSh);
+      if (aLM.IsEmpty() || BRep_Tool::Degenerated(aSh))
+      {
+        aLE.Append(aSh);
+        continue;
+      }
+
+      TopTools_ListIteratorOfListOfShape anItLM(aLM);
+      for (; anItLM.More(); anItLM.Next())
+      {
+        const TopoDS_Edge &anEM = TopoDS::Edge(anItLM.Value());
+        aLE.Append(anEM);
+      }
+    }
+#endif
+
+    isSplit = Standard_True;
+    InsertEDegenerated(aF, aLE);
+    aListEdges.Append(aLE);
+  }
+
+  if (!isSplit)
+  {
+    theListOfFaces.Append(theF);
+    return Standard_False;
+  }
+
+  RebuildFaces(aListEdges, theF, theListOfSplits);
+
+  TopTools_ListIteratorOfListOfShape anItrS(theListOfSplits);
+  for (; anItrS.More(); anItrS.Next())
+  {
+    const TopoDS_Face &aF = TopoDS::Face(anItrS.Value());
+    theListOfFaces.Append(aF.Oriented(theF.Orientation()));
+  }
+
+  return Standard_True;
+}
diff --git a/src/BRepFill/BRepFill_Voluved.hxx b/src/BRepFill/BRepFill_Voluved.hxx
new file mode 100644 (file)
index 0000000..39c1ca7
--- /dev/null
@@ -0,0 +1,120 @@
+// Created on: 2018-03-14
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 1999-2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepFill_Voluved_HeaderFile
+#define _BRepFill_Voluved_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+class BOPAlgo_MakerVolume;
+class TopoDS_Face;
+
+//! Constructs an evolved volume from a spine (wire or face)
+//! and  a profile ( wire).
+class BRepFill_Voluved 
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  Standard_EXPORT BRepFill_Voluved() :myErrorStatus(BRepFill_Voluved_Empty),
+                                      myFuzzyValue(0.0),
+                                      myIsParallel(Standard_True)
+  {
+  }
+  
+  Standard_EXPORT void Perform(const TopoDS_Wire& theSpine, const TopoDS_Wire& theProfile, const Standard_Real theTolerance, const Standard_Boolean theSolidReq = Standard_True);
+  
+  Standard_Boolean IsDone(unsigned int* theErrorCode = 0) const
+  {
+    if (theErrorCode)
+      *theErrorCode = myErrorStatus;
+
+    return (myErrorStatus == BRepFill_Voluved_OK);
+  }
+
+  //! returns the resulting shape.
+  const TopoDS_Shape& Shape() const
+  {
+    return myResult;
+  }
+  
+  //! Triggers computation mode between Parallel/Single-thread
+  void SetRunParallel(Standard_Boolean theValue)
+  {
+    myIsParallel = theValue;
+  }
+
+protected:
+
+  Standard_EXPORT void PerformSweep();
+
+  Standard_EXPORT void GetLids();
+
+  Standard_EXPORT void BuildSolid();
+
+  Standard_EXPORT void RemoveExcessSolids(const TopTools_ListOfShape& theLSplits,
+                                          TopoDS_Shape& theShape,
+                                          TopTools_ListOfShape& theArgsList,
+                                          BOPAlgo_MakerVolume& theMV);
+
+  Standard_EXPORT void ExtractOuterSolid(TopoDS_Shape& theShape,
+                                         TopTools_ListOfShape& theArgsList);
+
+  Standard_EXPORT void GetSpineAndProfile(const TopoDS_Wire& theSpine,
+                                          const TopoDS_Wire& theProfile);
+
+  Standard_EXPORT Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF,
+                                                          const Standard_Real theFuzzyToler,
+                                                          TopTools_ListOfShape& theListOfFaces,
+                                                          TopTools_ListOfShape& theListOfSplits) const;
+
+
+private:
+
+  enum
+  {
+    BRepFill_Voluved_Empty = 0,
+    BRepFill_Voluved_NotPlanarSpine,
+    BRepFill_Voluved_SweepError,
+    BRepFill_Voluved_NoLids,
+    BRepFill_Voluved_NotSolid,
+    BRepFill_Voluved_NotVolume,
+    BRepFill_Voluved_OK = UINT_MAX
+  } myErrorStatus;
+
+  TopoDS_Wire mySpine;
+  TopoDS_Wire myProfile;
+  TopoDS_Shape myPipeShell;
+  TopoDS_Compound myTopBottom; // Lids can be split on several faces
+  TopoDS_Shape myResult;
+  Standard_Real myFuzzyValue;
+  Standard_Boolean myIsParallel;
+
+};
+
+
+
+
+
+
+
+#endif // _BRepFill_Voluved_HeaderFile
index ebba998dd6a5d2ff96ff91ed859b055f260f57ee..e0a9ded7a098a94c42b2823afa25b6c5539a2510 100644 (file)
@@ -83,3 +83,5 @@ BRepFill_TrimShellCorner.hxx
 BRepFill_TrimSurfaceTool.cxx
 BRepFill_TrimSurfaceTool.hxx
 BRepFill_TypeOfContact.hxx
+BRepFill_Voluved.cxx
+BRepFill_Voluved.hxx
\ No newline at end of file
index 10310e689d31882af937f9f92856b6d6133829d4..50e4b0ca2c7bf91fc7f485c7c0659cde736ca56a 100644 (file)
@@ -22,6 +22,8 @@
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS.hxx>
 
 //=======================================================================
 //function : BRepOffsetAPI_MakeEvolved
@@ -43,19 +45,31 @@ BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Wire&     Spin
                                         const Standard_Boolean AxeProf,
                                         const Standard_Boolean Solid,
                                         const Standard_Boolean ProfOnSpine,
-                                        const Standard_Real    Tol)
+                                         const Standard_Boolean theIsVolume,
+                                         const Standard_Real    Tol,
+                                         const Standard_Boolean theRunInParallel)
 {
-  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.SetRunParallel(theRunInParallel);
+    myVolume.Perform(Spine, Profil, Tol);
+  }
+  else
+  {
+    gp_Ax3 Axis(gp_Pnt(0., 0., 0.),
+                gp_Dir(0., 0., 1.),
+                gp_Dir(1., 0., 0.));
+
+    if (!AxeProf)
+    {
+      Standard_Boolean POS;
+      BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion()));
+      if (ProfOnSpine && !POS) return;
+    }
+
+    myEvolved.Perform(Spine, Profil, Axis, Join, Solid);
   }
 
-  myEvolved.Perform(Spine,Profil,Axis,Join,Solid);
   Build();
   Done();
 }
@@ -72,20 +86,33 @@ BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Face&     Spin
                                         const Standard_Boolean AxeProf,
                                         const Standard_Boolean Solid,
                                         const Standard_Boolean ProfOnSpine,
-                                        const Standard_Real    Tol)
+                                         const Standard_Boolean theIsVolume,
+                                         const Standard_Real    Tol,
+                                         const Standard_Boolean theRunInParallel)
 {
-  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.SetRunParallel(theRunInParallel);
+    myVolume.Perform(TopoDS::Wire(TopoDS_Iterator(Spine).Value()), Profil, Tol);
+  }
+  else
+  {
+    gp_Ax3 Axis(gp_Pnt(0., 0., 0.),
+                gp_Dir(0., 0., 1.),
+                gp_Dir(1., 0., 0.));
+
+    if (!AxeProf)
+    {
+      Standard_Boolean POS;
+      BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion()));
+      if (ProfOnSpine && !POS) return;
+    }
+
+    myEvolved.Perform(Spine, Profil, Axis, Join, Solid);
   }
 
-  myEvolved.Perform(Spine,Profil,Axis,Join,Solid);
   Build();
+  Done();
 }
 
 
@@ -107,8 +134,16 @@ const BRepFill_Evolved& BRepOffsetAPI_MakeEvolved::Evolved() const
 
 void BRepOffsetAPI_MakeEvolved::Build()
 {
-  myShape = myEvolved.Shape();
-  if (myEvolved.IsDone())  Done();
+  if (myEvolved.IsDone())
+  {
+    myShape = myEvolved.Shape();
+  }
+  else if (myVolume.IsDone())
+  {
+    myShape = myVolume.Shape();
+  }
+  
+  Done();
 }
 
 
index fc778e36a0b8f448698928817006dc79942c08d6..3a5129bdf430ab70bb233d3a63c58a482da1e208 100644 (file)
@@ -22,6 +22,7 @@
 #include <Standard_Handle.hxx>
 
 #include <BRepFill_Evolved.hxx>
+#include <BRepFill_Voluved.hxx>
 #include <BRepBuilderAPI_MakeShape.hxx>
 #include <GeomAbs_JoinType.hxx>
 #include <Standard_Boolean.hxx>
@@ -66,7 +67,7 @@ public:
   
   Standard_EXPORT BRepOffsetAPI_MakeEvolved();
   
-  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean AxeProf = Standard_True, const Standard_Boolean Solid = Standard_False, const Standard_Boolean ProfOnSpine = Standard_False, const Standard_Real Tol = 0.0000001);
+  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join/* = GeomAbs_Arc*/, const Standard_Boolean AxeProf/* = Standard_True*/, const Standard_Boolean Solid/* = Standard_False*/, const Standard_Boolean ProfOnSpine/* = Standard_False*/, const Standard_Boolean theIsVolume, const Standard_Real Tol/* = Precision::Confusion()*/, const Standard_Boolean theRunInParallel);
   
   //! These constructors construct an evolved shape by sweeping the profile
   //! Profile along the spine Spine.
@@ -88,7 +89,7 @@ public:
   //! axis passing along the vertex and the normal to the
   //! plane of the spine. At present, this is the only
   //! construction type implemented.
-  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean AxeProf = Standard_True, const Standard_Boolean Solid = Standard_False, const Standard_Boolean ProfOnSpine = Standard_False, const Standard_Real Tol = 0.0000001);
+  Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join/* = GeomAbs_Arc*/, const Standard_Boolean AxeProf/* = Standard_True*/, const Standard_Boolean Solid/* = Standard_False*/, const Standard_Boolean ProfOnSpine/* = Standard_False*/, const Standard_Boolean theIsVolume, const Standard_Real Tol/* = Precision::Confusion()*/, const Standard_Boolean theRunInParallel);
   
   Standard_EXPORT const BRepFill_Evolved& Evolved() const;
   
@@ -118,9 +119,8 @@ protected:
 private:
 
 
-
   BRepFill_Evolved myEvolved;
-
+  BRepFill_Voluved myVolume;
 
 };
 
index 8f3b51f120fb6dc753abd9e68669d58925ea4449..64c8e27b8a06f2c17266f7fa31140b3c98892b19 100644 (file)
@@ -237,34 +237,94 @@ Standard_Integer evolved(Draw_Interpretor& di, Standard_Integer n, const char**
 
   if ( n < 4 ) return 1;
   Standard_Boolean IsAFace = Standard_False;
-  Standard_Boolean Solid   = (!strcmp(a[0],"evolvedsolid"));
+  Standard_Boolean Solid   = Standard_False;  
+  Standard_Boolean isVolume = Standard_False;
+  Standard_Boolean hasToComputeAxes = Standard_False;
+  Standard_Real aTolerance = 0.0;
+  TopoDS_Shape Base;
+  TopoDS_Wire Prof;
+  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 (!strcmp(a[i], "-solid"))
+    {
+      Solid = Standard_True;
+      continue;
+    }
 
-  TopoDS_Shape Base = DBRep::Get(a[2],TopAbs_WIRE,Standard_False);
-  if ( Base.IsNull()) {
-    Base = DBRep::Get(a[2],TopAbs_FACE,Standard_False);
-    IsAFace = Standard_True; 
-  }
-  if ( Base.IsNull()) return 1;
-
-  TopoDS_Shape InpuTShape(DBRep::Get(a[3],TopAbs_WIRE,Standard_False));
-  TopoDS_Wire Prof = TopoDS::Wire(InpuTShape);
-//  TopoDS_Wire Prof = 
-//    TopoDS::Wire(DBRep::Get(a[3],TopAbs_WIRE,Standard_False));
-  if ( Prof.IsNull()) return 1;
-
-  if (IsAFace) {
-    TopoDS_Shape Volevo 
-      = BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base),Prof,GeomAbs_Arc,n == 4,Solid);
-    DBRep::Set(a[1],Volevo);
+    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);
+          IsAFace = Standard_True;
+        }
+      }
+      break;
+
+      case 'p':
+      {
+        Prof = TopoDS::Wire(DBRep::Get(a[++i], TopAbs_WIRE, Standard_False));
+      }
+      break;
+
+      case 'v':
+      {
+        isVolume = Standard_True;
+      }
+      break;
+
+      case 'a':
+      {
+        hasToComputeAxes = Standard_True;
+      }
+      break;
+
+      case 't':
+      {
+        aTolerance = Draw::Atof(a[++i]);
+      }
+      break;
+
+      default: 
+        di << "Error: Unknown option!\n";
+        break;
+    }
   }
-  else {
-    TopoDS_Shape Volevo 
-      = BRepOffsetAPI_MakeEvolved(TopoDS::Wire(Base),Prof,GeomAbs_Arc,n == 4,Solid);
-    DBRep::Set(a[1],Volevo);
+  if (Base.IsNull() || Prof.IsNull())
+  {
+    di << "Error: Null-shapes are not allowed\n";
+    return 1;
   }
 
+  TopoDS_Shape Volevo = IsAFace ? BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base),
+                                                            Prof, GeomAbs_Arc, !hasToComputeAxes,
+                                                            Solid, Standard_False, isVolume,
+                                                            aTolerance, isParallel) :
+                                  BRepOffsetAPI_MakeEvolved(TopoDS::Wire(Base),
+                                                            Prof, GeomAbs_Arc, !hasToComputeAxes,
+                                                            Solid, Standard_False, isVolume,
+                                                            aTolerance, isParallel);
+
+  DBRep::Set(a[1],Volevo);
+
   return 0;
 }
 
@@ -785,7 +845,11 @@ static Standard_Integer buildsweep(Draw_Interpretor& di,
     Sweep->SetTransitionMode(Transition);
   }
   // Reading solid ?
-  if ((n>cur) && (!strcmp(a[cur],"-S")) ) mksolid = Standard_True;
+  if ((n > cur) && (!strcmp(a[cur], "-S")))
+  {
+    mksolid = Standard_True;
+    ++cur;
+  }
 
   // Calcul le resultat
   Sweep->Build();
@@ -979,10 +1043,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);
diff --git a/src/BRepTest/QABugs_20.cxx b/src/BRepTest/QABugs_20.cxx
new file mode 100644 (file)
index 0000000..1ff98e2
--- /dev/null
@@ -0,0 +1,2705 @@
+// Created on: 2015-10-26
+// Created by: Nikolai BUKHALOV
+// Copyright (c) 2002-2014 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 <QABugs.hxx>
+
+#include <gp_Ax2.hxx>
+#include <Extrema_GenLocateExtPS.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_SurfaceOfLinearExtrusion.hxx>
+#include <NCollection_List.hxx>
+#include <TColgp_Array2OfPnt.hxx>
+#include <TColStd_Array2OfReal.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_Array1OfInteger.hxx>
+#include <Geom_BezierCurve.hxx>
+#include <Geom_BSplineSurface.hxx>
+#include <GeomConvert.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_Line.hxx>
+#include <GeomFill_BSplineCurves.hxx>
+#include <Draw.hxx>
+#include <DrawTrSurf.hxx>
+#include <ShapeConstruct_ProjectCurveOnSurface.hxx>
+
+#include <TopExp.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <BRep_Tool.hxx>
+#include <TopoDS_Edge.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepTools.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <TopoDS.hxx>
+#include <DBRep.hxx>
+
+#include <BRepGProp.hxx>
+#include <DDocStd.hxx>
+#include <GProp_GProps.hxx>
+#include <TDocStd_Document.hxx>
+#include <XCAFDimTolObjects_DatumObject.hxx>
+#include <XCAFDimTolObjects_DimensionObject.hxx>
+#include <XCAFDimTolObjects_GeomToleranceObject.hxx>
+#include <XCAFDoc_Datum.hxx>
+#include <XCAFDoc_Dimension.hxx>
+#include <XCAFDoc_DimTolTool.hxx>
+#include <XCAFDoc_DocumentTool.hxx>
+#include <XCAFDoc_GeomTolerance.hxx>
+#include <XCAFDoc_ShapeTool.hxx>
+
+#include <HLRAppli_ReflectLines.hxx>
+#include <HLRBRep_PolyHLRToShape.hxx>
+#include <HLRBRep_PolyAlgo.hxx>
+
+#include <limits>
+
+#pragma comment(lib, "TKCAF.lib")
+#pragma comment(lib, "TKCDF.lib")
+#pragma comment(lib, "TKLCAF.lib")
+#pragma comment(lib, "TKXCAF.lib")
+#pragma comment(lib, "TKDCAF.lib")
+
+//=======================================================================
+//function : SurfaceGenOCC26675_1 
+//purpose  : Generates a surface for intersect (in corresponding
+//            test case). If we save these surfaces to the disk
+//            then bug will not be reproduced. Therefore, this generator
+//            is very important (despite its taking many lines of the code).
+//=======================================================================
+static Standard_Integer SurfaceGenOCC26675_1( Draw_Interpretor& theDI,
+                                              Standard_Integer  theNArg,
+                                              const char ** theArgVal)
+{
+
+  if(theNArg < 2)
+  {
+    theDI << "Use OCC26675_1 result\n";
+    return 1;
+  }
+
+  const gp_Pnt aCircCenter(-112.93397037070100000000, +177.52792379072199000000, +10.63374076104853900000);
+  const gp_Dir aCircN(+0.00000000000000000000, +1.00000000000000000000, +0.00000000000000000000);
+  const gp_Dir aCircX(+0.00000000000000000000, -0.00000000000000000000, +1.00000000000000000000);
+  const gp_Dir anExtrDir(-500.00000000000000000000, -866.02540378443609000000, +0.00000000000000000000);
+  const gp_Ax2 aCircAxes(aCircCenter, aCircN, aCircX);
+  const Handle(Geom_Curve) aCurv = new Geom_Circle(aCircAxes, +50.00000000000000000000);
+
+  const Handle(Geom_Surface) aS2 = new Geom_SurfaceOfLinearExtrusion(aCurv, anExtrDir);
+
+  TColgp_Array2OfPnt aPoles(1, 7, 1, 81);
+  TColStd_Array2OfReal aWeights(1, 7, 1, 81);
+  TColStd_Array1OfReal aUKnots(1, 2), aVKnots(1, 12);
+  TColStd_Array1OfInteger aUMult(1, 2), aVMult(1, 12);
+  const Standard_Integer aUDegree = 6, aVDegree = 8;
+
+  aUKnots(1) = +0.00000000000000000000;
+  aUKnots(2) = +1.00000000000000000000;
+  aVKnots(1) = +0.08911853946147080300;
+  aVKnots(2) = +0.11779167587451674000;
+  aVKnots(3) = +0.14583467562325506000;
+  aVKnots(4) = +0.20255081178503931000;
+  aVKnots(5) = +0.25926694794682359000;
+  aVKnots(6) = +0.31598308410860781000;
+  aVKnots(7) = +0.34262437462234741000;
+  aVKnots(8) = +0.37067364397889985000;
+  aVKnots(9) = +0.39731552779654306000;
+  aVKnots(10) = +0.42536420384919182000;
+  aVKnots(11) = +0.45200329235672548000;
+  aVKnots(12) = +0.47802918742799144000;
+
+  aUMult(1) = 7;
+  aUMult(2) = 7;
+  aVMult(1) = 9;
+  aVMult(2) = 7;
+  aVMult(3) = 7;
+  aVMult(4) = 7;
+  aVMult(5) = 7;
+  aVMult(6) = 7;
+  aVMult(7) = 7;
+  aVMult(8) = 7;
+  aVMult(9) = 7;
+  aVMult(10) = 8;
+  aVMult(11) = 8;
+  aVMult(12) = 9;
+
+  ////
+  {
+    aWeights.ChangeValue(1, 1) = +1.02986327036737910000;
+    aPoles.ChangeValue(1, 1) = gp_Pnt(+131.75315905495660000000, +2.88570510351864900000, -66.24709307590461500000);
+    aWeights.ChangeValue(1, 2) = +1.02989244478761060000;
+    aPoles.ChangeValue(1, 2) = gp_Pnt(+128.70876344053133000000, +2.88791208181246970000, -67.92914281439198000000);
+    aWeights.ChangeValue(1, 3) = +1.02991676091113950000;
+    aPoles.ChangeValue(1, 3) = gp_Pnt(+125.64133203841195000000, +2.88975018186799830000, -69.56968825975690200000);
+    aWeights.ChangeValue(1, 4) = +1.02993613450133650000;
+    aPoles.ChangeValue(1, 4) = gp_Pnt(+122.55164101294532000000, +2.89121448973680460000, -71.16831921321855200000);
+    aWeights.ChangeValue(1, 5) = +1.02995970896170810000;
+    aPoles.ChangeValue(1, 5) = gp_Pnt(+119.44028474076808000000, +2.89299532863950050000, -72.72471137484106400000);
+    aWeights.ChangeValue(1, 6) = +1.02998196300928410000;
+    aPoles.ChangeValue(1, 6) = gp_Pnt(+116.30796917345266000000, +2.89467567823625730000, -74.23853925439507900000);
+    aWeights.ChangeValue(1, 7) = +1.02999781361772440000;
+    aPoles.ChangeValue(1, 7) = gp_Pnt(+113.15537818476763000000, +2.89587201010380560000, -75.70949847615843000000);
+    aWeights.ChangeValue(1, 8) = +1.03001626830283270000;
+    aPoles.ChangeValue(1, 8) = gp_Pnt(+109.98323502828077000000, +2.89726468512897210000, -77.13723994508107800000);
+    aWeights.ChangeValue(1, 9) = +1.03004822145815230000;
+    aPoles.ChangeValue(1, 9) = gp_Pnt(+103.60126699909762000000, +2.89967510685080440000, -79.90571269046952800000);
+    aWeights.ChangeValue(1, 10) = +1.03006364818936770000;
+    aPoles.ChangeValue(1, 10) = gp_Pnt(+100.39144092265354000000, +2.90083845616186050000, -81.24644132200651800000);
+    aWeights.ChangeValue(1, 11) = +1.03007725635592000000;
+    aPoles.ChangeValue(1, 11) = gp_Pnt(+97.16342330855667300000, +2.90186436688425700000, -82.54338871675531700000);
+    aWeights.ChangeValue(1, 12) = +1.03009045031501500000;
+    aPoles.ChangeValue(1, 12) = gp_Pnt(+93.91790293022438600000, +2.90285879918974650000, -83.79626764915399000000);
+    aWeights.ChangeValue(1, 13) = +1.03010285398183930000;
+    aPoles.ChangeValue(1, 13) = gp_Pnt(+90.65560197798836800000, +2.90379346029782100000, -85.00479786905465600000);
+    aWeights.ChangeValue(1, 14) = +1.03011393120350900000;
+    aPoles.ChangeValue(1, 14) = gp_Pnt(+87.37722618415423900000, +2.90462796925060120000, -86.16871841453435400000);
+    aWeights.ChangeValue(1, 15) = +1.03012484065787050000;
+    aPoles.ChangeValue(1, 15) = gp_Pnt(+84.08346762829417300000, +2.90544970249433290000, -87.28777941880029800000);
+    aWeights.ChangeValue(1, 16) = +1.03015471267321200000;
+    aPoles.ChangeValue(1, 16) = gp_Pnt(+74.15848807058078800000, +2.90769927244280210000, -90.50962423575197100000);
+    aWeights.ChangeValue(1, 17) = +1.03017194800922400000;
+    aPoles.ChangeValue(1, 17) = gp_Pnt(+67.48342008926763900000, +2.90899668032978950000, -92.47701903504494700000);
+    aWeights.ChangeValue(1, 18) = +1.03018680682765670000;
+    aPoles.ChangeValue(1, 18) = gp_Pnt(+60.75515833606132100000, +2.91011480947056490000, -94.26204121664201800000);
+    aWeights.ChangeValue(1, 19) = +1.03019958109549670000;
+    aPoles.ChangeValue(1, 19) = gp_Pnt(+53.97928154760177200000, +2.91107580930771360000, -95.86305268935117900000);
+    aWeights.ChangeValue(1, 20) = +1.03021050389503350000;
+    aPoles.ChangeValue(1, 20) = gp_Pnt(+47.16164692132413400000, +2.91189735380426780000, -97.27865560180262600000);
+    aWeights.ChangeValue(1, 21) = +1.03021974942385830000;
+    aPoles.ChangeValue(1, 21) = gp_Pnt(+40.30838837608569500000, +2.91259264267907050000, -98.50769317562559000000);
+    aWeights.ChangeValue(1, 22) = +1.03022743299486370000;
+    aPoles.ChangeValue(1, 22) = gp_Pnt(+33.42591476110869300000, +2.91317040233699530000, -99.54925039136011800000);
+    aWeights.ChangeValue(1, 23) = +1.03023979631718900000;
+    aPoles.ChangeValue(1, 23) = gp_Pnt(+19.61576136171939000000, +2.91409991934468550000, -101.25602945077115000000);
+    aWeights.ChangeValue(1, 24) = +1.03024450452679140000;
+    aPoles.ChangeValue(1, 24) = gp_Pnt(+12.68754355991407800000, +2.91445385083459700000, -101.92122234436175000000);
+    aWeights.ChangeValue(1, 25) = +1.03024781840890120000;
+    aPoles.ChangeValue(1, 25) = gp_Pnt(+5.74236948737514120000, +2.91470294045230770000, -102.39751844510502000000);
+    aWeights.ChangeValue(1, 26) = +1.03024979501192000000;
+    aPoles.ChangeValue(1, 26) = gp_Pnt(-1.21367831605073050000, +2.91485150371151920000, -102.68442590550356000000);
+    aWeights.ChangeValue(1, 27) = +1.03025046568879790000;
+    aPoles.ChangeValue(1, 27) = gp_Pnt(-8.17455041611474620000, +2.91490191238154670000, -102.78167594353056000000);
+    aWeights.ChangeValue(1, 28) = +1.03024983609703540000;
+    aPoles.ChangeValue(1, 28) = gp_Pnt(-15.13423127055194300000, +2.91485459458572780000, -102.68922293042964000000);
+    aWeights.ChangeValue(1, 29) = +1.03024788619868260000;
+    aPoles.ChangeValue(1, 29) = gp_Pnt(-22.08674002008992700000, +2.91470803482494080000, -102.40724441194320000000);
+    aWeights.ChangeValue(1, 30) = +1.03024126030624540000;
+    aPoles.ChangeValue(1, 30) = gp_Pnt(-35.96556766132121700000, +2.91420996731856930000, -101.46503408514069000000);
+    aWeights.ChangeValue(1, 31) = +1.03023657011944230000;
+    aPoles.ChangeValue(1, 31) = gp_Pnt(-42.89191729472150200000, +2.91385737699769360000, -100.80479886745856000000);
+    aWeights.ChangeValue(1, 32) = +1.03023047292900880000;
+    aPoles.ChangeValue(1, 32) = gp_Pnt(-49.79923779841396900000, +2.91339898565004060000, -99.95583114848535900000);
+    aWeights.ChangeValue(1, 33) = +1.03022290017099550000;
+    aPoles.ChangeValue(1, 33) = gp_Pnt(-56.68161614207340900000, +2.91282960709223810000, -98.91875138839027700000);
+    aWeights.ChangeValue(1, 34) = +1.03021374148842180000;
+    aPoles.ChangeValue(1, 34) = gp_Pnt(-63.53316994906088400000, +2.91214088593828220000, -97.69440448679608800000);
+    aWeights.ChangeValue(1, 35) = +1.03020284473128080000;
+    aPoles.ChangeValue(1, 35) = gp_Pnt(-70.34804877511381000000, +2.91132129711663760000, -96.28385939245710300000);
+    aWeights.ChangeValue(1, 36) = +1.03019001595653580000;
+    aPoles.ChangeValue(1, 36) = gp_Pnt(-77.12043535415037400000, +2.91035614521427500000, -94.68840860671046800000);
+    aWeights.ChangeValue(1, 37) = +1.03016805964614980000;
+    aPoles.ChangeValue(1, 37) = gp_Pnt(-86.96652166958519100000, +2.90870378328618400000, -92.08365976972685000000);
+    aWeights.ChangeValue(1, 38) = +1.03016062145972500000;
+    aPoles.ChangeValue(1, 38) = gp_Pnt(-90.07809790629383400000, +2.90814392820824040000, -91.21821667329717800000);
+    aWeights.ChangeValue(1, 39) = +1.03015268516758060000;
+    aPoles.ChangeValue(1, 39) = gp_Pnt(-93.17869710255469300000, +2.90754650188789080000, -90.31338955501080100000);
+    aWeights.ChangeValue(1, 40) = +1.03014422393874510000;
+    aPoles.ChangeValue(1, 40) = gp_Pnt(-96.26774201507643600000, +2.90690946644790090000, -89.36934028436292000000);
+    aWeights.ChangeValue(1, 41) = +1.03013520381253840000;
+    aPoles.ChangeValue(1, 41) = gp_Pnt(-99.34465666946248100000, +2.90623024256504880000, -88.38624129906430900000);
+    aWeights.ChangeValue(1, 42) = +1.03012558369857450000;
+    aPoles.ChangeValue(1, 42) = gp_Pnt(-102.40886646020824000000, +2.90550570939860810000, -87.36427556081821400000);
+    aWeights.ChangeValue(1, 43) = +1.03011531537676040000;
+    aPoles.ChangeValue(1, 43) = gp_Pnt(-105.45979824903711000000, +2.90473220450791560000, -86.30363650725728100000);
+    aWeights.ChangeValue(1, 44) = +1.03009266486593140000;
+    aPoles.ChangeValue(1, 44) = gp_Pnt(-111.76765655411073000000, +2.90302557752729130000, -84.02084620865503000000);
+    aWeights.ChangeValue(1, 45) = +1.03007954250893910000;
+    aPoles.ChangeValue(1, 45) = gp_Pnt(-115.02237879255169000000, +2.90203661863772000000, -82.79254553120374300000);
+    aWeights.ChangeValue(1, 46) = +1.03006700046846360000;
+    aPoles.ChangeValue(1, 46) = gp_Pnt(-118.26033551796380000000, +2.90109123094133370000, -81.51987347500843800000);
+    aWeights.ChangeValue(1, 47) = +1.03005153385518430000;
+    aPoles.ChangeValue(1, 47) = gp_Pnt(-121.48081153033489000000, +2.89992503429592440000, -80.20310945547186100000);
+    aWeights.ChangeValue(1, 48) = +1.03003663316288070000;
+    aPoles.ChangeValue(1, 48) = gp_Pnt(-124.68310204708784000000, +2.89880123910694910000, -78.84252385592422700000);
+    aWeights.ChangeValue(1, 49) = +1.03002002524051230000;
+    aPoles.ChangeValue(1, 49) = gp_Pnt(-127.86649232671233000000, +2.89754829341323060000, -77.43842231968982000000);
+    aWeights.ChangeValue(1, 50) = +1.03000192732161230000;
+    aPoles.ChangeValue(1, 50) = gp_Pnt(-131.03028254956638000000, +2.89618247462029290000, -75.99111259804850200000);
+    aWeights.ChangeValue(1, 51) = +1.02996526567113600000;
+    aPoles.ChangeValue(1, 51) = gp_Pnt(-137.09281139094972000000, +2.89341459629042360000, -73.11712223836046600000);
+    aWeights.ChangeValue(1, 52) = +1.02994403451589630000;
+    aPoles.ChangeValue(1, 52) = gp_Pnt(-139.99435839258939000000, +2.89181101472158900000, -71.69634981883045600000);
+    aWeights.ChangeValue(1, 53) = +1.02992866105538440000;
+    aPoles.ChangeValue(1, 53) = gp_Pnt(-142.87784656482347000000, +2.89064973421052680000, -70.23882874204873900000);
+    aWeights.ChangeValue(1, 54) = +1.02989968743283590000;
+    aPoles.ChangeValue(1, 54) = gp_Pnt(-145.74271824362268000000, +2.88845983550875030000, -68.74489127449217600000);
+    aWeights.ChangeValue(1, 55) = +1.02988222474524970000;
+    aPoles.ChangeValue(1, 55) = gp_Pnt(-148.58838121276386000000, +2.88713941077432070000, -67.21475112846350400000);
+    aWeights.ChangeValue(1, 56) = +1.02985386954408620000;
+    aPoles.ChangeValue(1, 56) = gp_Pnt(-151.41432118416620000000, +2.88499463682574180000, -65.64875099202183200000);
+    aWeights.ChangeValue(1, 57) = +1.02982704006090460000;
+    aPoles.ChangeValue(1, 57) = gp_Pnt(-154.21993049579214000000, +2.88296397171855910000, -64.04717955157212800000);
+    aWeights.ChangeValue(1, 58) = +1.02976639514278400000;
+    aPoles.ChangeValue(1, 58) = gp_Pnt(-160.00375832753414000000, +2.87837140815595260000, -60.64735416015690100000);
+    aWeights.ChangeValue(1, 59) = +1.02972545417711370000;
+    aPoles.ChangeValue(1, 59) = gp_Pnt(-162.97914403387477000000, +2.87526824819569480000, -58.84445149944087200000);
+    aWeights.ChangeValue(1, 60) = +1.02970377642253300000;
+    aPoles.ChangeValue(1, 60) = gp_Pnt(-165.92810584856278000000, +2.87362619373759860000, -56.99783055334398100000);
+    aWeights.ChangeValue(1, 61) = +1.02963665582001740000;
+    aPoles.ChangeValue(1, 61) = gp_Pnt(-168.85438185317770000000, +2.86853152516479340000, -55.11698298198095400000);
+    aWeights.ChangeValue(1, 62) = +1.02961756328192160000;
+    aPoles.ChangeValue(1, 62) = gp_Pnt(-171.75125340157436000000, +2.86708271055963240000, -53.19057330425229700000);
+    aWeights.ChangeValue(1, 63) = +1.02954937293527580000;
+    aPoles.ChangeValue(1, 63) = gp_Pnt(-174.62251681022158000000, +2.86190007017706360000, -51.22700225930964300000);
+    aWeights.ChangeValue(1, 64) = +1.02950097342691520000;
+    aPoles.ChangeValue(1, 64) = gp_Pnt(-177.46620192435449000000, +2.85821732043423180000, -49.22415777229338100000);
+    aWeights.ChangeValue(1, 65) = +1.02943612532291810000;
+    aPoles.ChangeValue(1, 65) = gp_Pnt(-180.28206426096281000000, +2.85327724467687100000, -47.18300981722491400000);
+    aWeights.ChangeValue(1, 66) = +1.02937840445786000000;
+    aPoles.ChangeValue(1, 66) = gp_Pnt(-182.89713737694305000000, +2.84888100315162470000, -45.28741010449485300000);
+    aWeights.ChangeValue(1, 67) = +1.02929786839840220000;
+    aPoles.ChangeValue(1, 67) = gp_Pnt(-185.48808576506855000000, +2.84272935508061810000, -43.35897595091199000000);
+    aWeights.ChangeValue(1, 68) = +1.02927785532845030000;
+    aPoles.ChangeValue(1, 68) = gp_Pnt(-188.05509745668041000000, +2.84122612975151250000, -41.39706700987362400000);
+    aWeights.ChangeValue(1, 69) = +1.02909457173363930000;
+    aPoles.ChangeValue(1, 69) = gp_Pnt(-190.59634219852757000000, +2.82717082550985440000, -39.40453806610211300000);
+    aWeights.ChangeValue(1, 70) = +1.02915656102508410000;
+    aPoles.ChangeValue(1, 70) = gp_Pnt(-193.11296933822229000000, +2.83195841118334000000, -37.37763511391345600000);
+    aWeights.ChangeValue(1, 71) = +1.02891246603941110000;
+    aPoles.ChangeValue(1, 71) = gp_Pnt(-195.60305999702362000000, +2.81322479805689340000, -35.32107774203857500000);
+    aWeights.ChangeValue(1, 72) = +1.02884001996307940000;
+    aPoles.ChangeValue(1, 72) = gp_Pnt(-198.06589030811097000000, +2.80764438138268390000, -33.23208121127716900000);
+    aWeights.ChangeValue(1, 73) = +1.02870418206103250000;
+    aPoles.ChangeValue(1, 73) = gp_Pnt(-200.50111697620073000000, +2.79717360924099090000, -31.11182660391394400000);
+    aWeights.ChangeValue(1, 74) = +1.02860417892814660000;
+    aPoles.ChangeValue(1, 74) = gp_Pnt(-202.93720652839650000000, +2.78949733525485710000, -28.99085629216911300000);
+    aWeights.ChangeValue(1, 75) = +1.02826579045547110000;
+    aPoles.ChangeValue(1, 75) = gp_Pnt(-205.34394850673777000000, +2.76315604312090550000, -26.83940109433629200000);
+    aWeights.ChangeValue(1, 76) = +1.02871793966742330000;
+    aPoles.ChangeValue(1, 76) = gp_Pnt(-207.72575255584553000000, +2.79855565223875710000, -24.65500081264426800000);
+    aWeights.ChangeValue(1, 77) = +1.02728787827176630000;
+    aPoles.ChangeValue(1, 77) = gp_Pnt(-210.07706367406874000000, +2.68725363743552850000, -22.43634910730148800000);
+    aWeights.ChangeValue(1, 78) = +1.02767535385809120000;
+    aPoles.ChangeValue(1, 78) = gp_Pnt(-212.39605978578481000000, +2.71705476277515070000, -20.20562112100595800000);
+    aWeights.ChangeValue(1, 79) = +1.02745809923169020000;
+    aPoles.ChangeValue(1, 79) = gp_Pnt(-214.68098626410506000000, +2.69985190382785320000, -17.91605900374278100000);
+    aWeights.ChangeValue(1, 80) = +1.02725110106359850000;
+    aPoles.ChangeValue(1, 80) = gp_Pnt(-216.94385389331507000000, +2.68435107488514250000, -15.61289037092123000000);
+    aWeights.ChangeValue(1, 81) = +1.02619749797986360000;
+    aPoles.ChangeValue(1, 81) = gp_Pnt(-219.16685583874414000000, +2.59983520096898510000, -13.28583956380401400000);
+    aWeights.ChangeValue(2, 1) = +1.00955713824395700000;
+    aPoles.ChangeValue(2, 1) = gp_Pnt(+131.76756408216349000000, +2.10451717388867540000, -66.27316135719137000000);
+    aWeights.ChangeValue(2, 2) = +1.00956608612165600000;
+    aPoles.ChangeValue(2, 2) = gp_Pnt(+128.72252404033563000000, +2.10631182699007670000, -67.95492700832653600000);
+    aWeights.ChangeValue(2, 3) = +1.00957354292813030000;
+    aPoles.ChangeValue(2, 3) = gp_Pnt(+125.65455798821807000000, +2.10780700070896730000, -69.59522708152212500000);
+    aWeights.ChangeValue(2, 4) = +1.00957948395970430000;
+    aPoles.ChangeValue(2, 4) = gp_Pnt(+122.56436007131990000000, +2.10899819276768510000, -71.19369911011085600000);
+    aWeights.ChangeValue(2, 5) = +1.00958671248272140000;
+    aPoles.ChangeValue(2, 5) = gp_Pnt(+119.45249930698063000000, +2.11044722765431250000, -72.74983445837314400000);
+    aWeights.ChangeValue(2, 6) = +1.00959353559448470000;
+    aPoles.ChangeValue(2, 6) = gp_Pnt(+116.31971419268339000000, +2.11181476538007030000, -74.26341133748536500000);
+    aWeights.ChangeValue(2, 7) = +1.00959839503054960000;
+    aPoles.ChangeValue(2, 7) = gp_Pnt(+113.16673272248508000000, +2.11278857229853930000, -75.73421464457315700000);
+    aWeights.ChangeValue(2, 8) = +1.00960405269294800000;
+    aPoles.ChangeValue(2, 8) = gp_Pnt(+109.99417142410560000000, +2.11392227976110990000, -77.16175403351917300000);
+    aWeights.ChangeValue(2, 9) = +1.00961384794963970000;
+    aPoles.ChangeValue(2, 9) = gp_Pnt(+103.61137952541701000000, +2.11588481923337430000, -79.92991318438167500000);
+    aWeights.ChangeValue(2, 10) = +1.00961857675621050000;
+    aPoles.ChangeValue(2, 10) = gp_Pnt(+100.40113044627800000000, +2.11683214779396200000, -81.27049552555527600000);
+    aWeights.ChangeValue(2, 11) = +1.00962274789480260000;
+    aPoles.ChangeValue(2, 11) = gp_Pnt(+97.17272090352022900000, +2.11766766635255620000, -82.56731642507010300000);
+    aWeights.ChangeValue(2, 12) = +1.00962679188946770000;
+    aPoles.ChangeValue(2, 12) = gp_Pnt(+93.92682593436140300000, +2.11847763961438810000, -83.82006598438695700000);
+    aWeights.ChangeValue(2, 13) = +1.00963059350869510000;
+    aPoles.ChangeValue(2, 13) = gp_Pnt(+90.66416580726762200000, +2.11923900414192050000, -85.02847304317147300000);
+    aWeights.ChangeValue(2, 14) = +1.00963398843777610000;
+    aPoles.ChangeValue(2, 14) = gp_Pnt(+87.38545325411524800000, +2.11991885797243330000, -86.19228543784532800000);
+    aWeights.ChangeValue(2, 15) = +1.00963733185346640000;
+    aPoles.ChangeValue(2, 15) = gp_Pnt(+84.09136475788710600000, +2.12058835416503610000, -87.31123582184922300000);
+    aWeights.ChangeValue(2, 16) = +1.00964648640037450000;
+    aPoles.ChangeValue(2, 16) = gp_Pnt(+74.16530685267888100000, +2.12242134451684360000, -90.53282418399284400000);
+    aWeights.ChangeValue(2, 17) = +1.00965176794147850000;
+    aPoles.ChangeValue(2, 17) = gp_Pnt(+67.48955141808187400000, +2.12347869023601370000, -92.50007118315201600000);
+    aWeights.ChangeValue(2, 18) = +1.00965632094816660000;
+    aPoles.ChangeValue(2, 18) = gp_Pnt(+60.76066172731987800000, +2.12439006790716880000, -94.28495774595940300000);
+    aWeights.ChangeValue(2, 19) = +1.00966023501695720000;
+    aPoles.ChangeValue(2, 19) = gp_Pnt(+53.98420072674593900000, +2.12517346720689600000, -95.88584819516199800000);
+    aWeights.ChangeValue(2, 20) = +1.00966358166845400000;
+    aPoles.ChangeValue(2, 20) = gp_Pnt(+47.16601123883578600000, +2.12584324589548320000, -97.30134659055448800000);
+    aWeights.ChangeValue(2, 21) = +1.00966641434734730000;
+    aPoles.ChangeValue(2, 21) = gp_Pnt(+40.31221541713015500000, +2.12641013013135180000, -98.53029698991525700000);
+    aWeights.ChangeValue(2, 22) = +1.00966876842241260000;
+    aPoles.ChangeValue(2, 22) = gp_Pnt(+33.42921418500849000000, +2.12688121470786750000, -99.57178366381829400000);
+    aWeights.ChangeValue(2, 23) = +1.00967255617655650000;
+    aPoles.ChangeValue(2, 23) = gp_Pnt(+19.61796125907087400000, +2.12763915883061920000, -101.27845724558523000000);
+    aWeights.ChangeValue(2, 24) = +1.00967399859793750000;
+    aPoles.ChangeValue(2, 24) = gp_Pnt(+12.68919279606528900000, +2.12792777824197280000, -101.94361028295506000000);
+    aWeights.ChangeValue(2, 25) = +1.00967501382968900000;
+    aPoles.ChangeValue(2, 25) = gp_Pnt(+5.74348853231593990000, +2.12813091177048630000, -102.41987704106546000000);
+    aWeights.ChangeValue(2, 26) = +1.00967561936957820000;
+    aPoles.ChangeValue(2, 26) = gp_Pnt(-1.21307744928976070000, +2.12825206894226590000, -102.70676666240287000000);
+    aWeights.ChangeValue(2, 27) = +1.00967582483410380000;
+    aPoles.ChangeValue(2, 27) = gp_Pnt(-8.17446448579617170000, +2.12829317854427910000, -102.80401081431219000000);
+    aWeights.ChangeValue(2, 28) = +1.00967563195849760000;
+    aPoles.ChangeValue(2, 28) = gp_Pnt(-15.13466558037753100000, +2.12825458864942170000, -102.71156371647888000000);
+    aWeights.ChangeValue(2, 29) = +1.00967503459672270000;
+    aPoles.ChangeValue(2, 29) = gp_Pnt(-22.08770764998126900000, +2.12813506662251010000, -102.42960214757312000000);
+    aWeights.ChangeValue(2, 30) = +1.00967300468446490000;
+    aPoles.ChangeValue(2, 30) = gp_Pnt(-35.96760988752987500000, +2.12772890088942160000, -101.48744752427969000000);
+    aWeights.ChangeValue(2, 31) = +1.00967156777535580000;
+    aPoles.ChangeValue(2, 31) = gp_Pnt(-42.89448004815705000000, +2.12744138030294440000, -100.82725372327035000000);
+    aWeights.ChangeValue(2, 32) = +1.00966969979090780000;
+    aPoles.ChangeValue(2, 32) = gp_Pnt(-49.80232400744441900000, +2.12706759457740000000, -99.97834162579670200000);
+    aWeights.ChangeValue(2, 33) = +1.00966737970297200000;
+    aPoles.ChangeValue(2, 33) = gp_Pnt(-56.68523628384353000000, +2.12660332632729520000, -98.94133225857957800000);
+    aWeights.ChangeValue(2, 34) = +1.00966457365849260000;
+    aPoles.ChangeValue(2, 34) = gp_Pnt(-63.53734456971785200000, +2.12604178346724470000, -97.71706998895581400000);
+    aWeights.ChangeValue(2, 35) = +1.00966123497950600000;
+    aPoles.ChangeValue(2, 35) = gp_Pnt(-70.35281013187348300000, +2.12537359908900880000, -96.30662240267085400000);
+    aWeights.ChangeValue(2, 36) = +1.00965730416314050000;
+    aPoles.ChangeValue(2, 36) = gp_Pnt(-77.12582820180557500000, +2.12458683129447450000, -94.71128014840769500000);
+    aWeights.ChangeValue(2, 37) = +1.00965057624220010000;
+    aPoles.ChangeValue(2, 37) = gp_Pnt(-86.97287762202962800000, +2.12324005462031540000, -92.10671540000876700000);
+    aWeights.ChangeValue(2, 38) = +1.00964829695753690000;
+    aPoles.ChangeValue(2, 38) = gp_Pnt(-90.08473551349412400000, +2.12278376932639290000, -91.24134329153459100000);
+    aWeights.ChangeValue(2, 39) = +1.00964586498084840000;
+    aPoles.ChangeValue(2, 39) = gp_Pnt(-93.18562459494498300000, +2.12229689243319890000, -90.33659169532975900000);
+    aWeights.ChangeValue(2, 40) = +1.00964327207694590000;
+    aPoles.ChangeValue(2, 40) = gp_Pnt(-96.27496896689456200000, +2.12177776971417840000, -89.39262240039663300000);
+    aWeights.ChangeValue(2, 41) = +1.00964050782222770000;
+    aPoles.ChangeValue(2, 41) = gp_Pnt(-99.35219429474524600000, +2.12122430736176200000, -88.40960770124299000000);
+    aWeights.ChangeValue(2, 42) = +1.00963755960468140000;
+    aPoles.ChangeValue(2, 42) = gp_Pnt(-102.41672784011750000000, +2.12063397196916760000, -87.38773038403248000000);
+    aWeights.ChangeValue(2, 43) = +1.00963441262388320000;
+    aPoles.ChangeValue(2, 43) = gp_Pnt(-105.46799849165807000000, +2.12000379050942020000, -86.32718371153289600000);
+    aWeights.ChangeValue(2, 44) = +1.00962747055142050000;
+    aPoles.ChangeValue(2, 44) = gp_Pnt(-111.77654530973133000000, +2.11861352771318150000, -84.04460889409097000000);
+    aWeights.ChangeValue(2, 45) = +1.00962344856326270000;
+    aPoles.ChangeValue(2, 45) = gp_Pnt(-115.03162075269803000000, +2.11780798556167320000, -82.81644583890866300000);
+    aWeights.ChangeValue(2, 46) = +1.00961960432211730000;
+    aPoles.ChangeValue(2, 46) = gp_Pnt(-118.26993104545312000000, +2.11703799459344700000, -81.54389579486141300000);
+    aWeights.ChangeValue(2, 47) = +1.00961486342011010000;
+    aPoles.ChangeValue(2, 47) = gp_Pnt(-121.49080060905077000000, +2.11608829135299810000, -80.22729418526657200000);
+    aWeights.ChangeValue(2, 48) = +1.00961029578343630000;
+    aPoles.ChangeValue(2, 48) = gp_Pnt(-124.69348951442340000000, +2.11517321690879800000, -78.86685283462101400000);
+    aWeights.ChangeValue(2, 49) = +1.00960520454014850000;
+    aPoles.ChangeValue(2, 49) = gp_Pnt(-127.87731027004676000000, +2.11415312105035590000, -77.46291256687052900000);
+    aWeights.ChangeValue(2, 50) = +1.00959965618773250000;
+    aPoles.ChangeValue(2, 50) = gp_Pnt(-131.04156234039974000000, +2.11304129636208420000, -76.01577573259778800000);
+    aWeights.ChangeValue(2, 51) = +1.00958841592243690000;
+    aPoles.ChangeValue(2, 51) = gp_Pnt(-137.10496896782513000000, +2.11078854745601690000, -73.14215015354327000000);
+    aWeights.ChangeValue(2, 52) = +1.00958190609540830000;
+    aPoles.ChangeValue(2, 52) = gp_Pnt(-140.00695092509352000000, +2.10948365684345340000, -71.72161996530125800000);
+    aWeights.ChangeValue(2, 53) = +1.00957719225994170000;
+    aPoles.ChangeValue(2, 53) = gp_Pnt(-142.89082065884315000000, +2.10853873486620720000, -70.26423921243410600000);
+    aWeights.ChangeValue(2, 54) = +1.00956830737110970000;
+    aPoles.ChangeValue(2, 54) = gp_Pnt(-145.75622246387837000000, +2.10675729535240960000, -68.77065477701791000000);
+    aWeights.ChangeValue(2, 55) = +1.00956295195561060000;
+    aPoles.ChangeValue(2, 55) = gp_Pnt(-148.60233584192389000000, +2.10568335609513650000, -67.24065593702246700000);
+    aWeights.ChangeValue(2, 56) = +1.00955425555818930000;
+    aPoles.ChangeValue(2, 56) = gp_Pnt(-151.42883073983140000000, +2.10393921590561070000, -65.67497260857376800000);
+    aWeights.ChangeValue(2, 57) = +1.00954602613011150000;
+    aPoles.ChangeValue(2, 57) = gp_Pnt(-154.23502547473331000000, +2.10228833319884910000, -64.07366145615235100000);
+    aWeights.ChangeValue(2, 58) = +1.00952742278729300000;
+    aPoles.ChangeValue(2, 58) = gp_Pnt(-160.02004322449872000000, +2.09855561509982950000, -60.67448614970191300000);
+    aWeights.ChangeValue(2, 59) = +1.00951486183164940000;
+    aPoles.ChangeValue(2, 59) = gp_Pnt(-162.99613088380306000000, +2.09603444654779600000, -58.87207545484513800000);
+    aWeights.ChangeValue(2, 60) = +1.00950821186194630000;
+    aPoles.ChangeValue(2, 60) = gp_Pnt(-165.94554723216726000000, +2.09470002788322150000, -57.02566663092176900000);
+    aWeights.ChangeValue(2, 61) = +1.00948761363819010000;
+    aPoles.ChangeValue(2, 61) = gp_Pnt(-168.87287521283019000000, +2.09056345777511910000, -55.14566924440539700000);
+    aWeights.ChangeValue(2, 62) = +1.00948175483840210000;
+    aPoles.ChangeValue(2, 62) = gp_Pnt(-171.77025983587509000000, +2.08938700649796160000, -53.21936605947655600000);
+    aWeights.ChangeValue(2, 63) = +1.00946082358399410000;
+    aPoles.ChangeValue(2, 63) = gp_Pnt(-174.64262250370552000000, +2.08518149324171190000, -51.25662423685646700000);
+    aWeights.ChangeValue(2, 64) = +1.00944596410269540000;
+    aPoles.ChangeValue(2, 64) = gp_Pnt(-177.48726621628353000000, +2.08219461660139650000, -49.25423871740036900000);
+    aWeights.ChangeValue(2, 65) = +1.00942605045267530000;
+    aPoles.ChangeValue(2, 65) = gp_Pnt(-180.30433731845508000000, +2.07819005191471670000, -47.21374002625280800000);
+    aWeights.ChangeValue(2, 66) = +1.00940832657289500000;
+    aPoles.ChangeValue(2, 66) = gp_Pnt(-182.92026834009920000000, +2.07462614892136180000, -45.31887901738367200000);
+    aWeights.ChangeValue(2, 67) = +1.00938358350026620000;
+    aPoles.ChangeValue(2, 67) = gp_Pnt(-185.51252638985017000000, +2.06964535925843180000, -43.39137009339865600000);
+    aWeights.ChangeValue(2, 68) = +1.00937745534293180000;
+    aPoles.ChangeValue(2, 68) = gp_Pnt(-188.07970214515959000000, +2.06841969296490240000, -41.42984981640538000000);
+    aWeights.ChangeValue(2, 69) = +1.00932110415642830000;
+    aPoles.ChangeValue(2, 69) = gp_Pnt(-190.62397551723822000000, +2.05705915800362950000, -39.43932945784815300000);
+    aWeights.ChangeValue(2, 70) = +1.00934018958961060000;
+    aPoles.ChangeValue(2, 70) = gp_Pnt(-193.13969442040633000000, +2.06091733419064350000, -37.41169132931209200000);
+    aWeights.ChangeValue(2, 71) = +1.00926513417552190000;
+    aPoles.ChangeValue(2, 71) = gp_Pnt(-195.63329272671066000000, +2.04578165519120160000, -35.35822241980492500000);
+    aWeights.ChangeValue(2, 72) = +1.00924284324010150000;
+    aPoles.ChangeValue(2, 72) = gp_Pnt(-198.09761820165846000000, +2.04128022217386820000, -33.26975126412686700000);
+    aWeights.ChangeValue(2, 73) = +1.00920104311988150000;
+    aPoles.ChangeValue(2, 73) = gp_Pnt(-200.53514329838038000000, +2.03283693524956680000, -31.15087616958502200000);
+    aWeights.ChangeValue(2, 74) = +1.00917029694372660000;
+    aPoles.ChangeValue(2, 74) = gp_Pnt(-202.97255799662608000000, +2.02663657044316060000, -29.03126127135719200000);
+    aWeights.ChangeValue(2, 75) = +1.00906597799637380000;
+    aPoles.ChangeValue(2, 75) = gp_Pnt(-205.38430250588374000000, +2.00548607046822540000, -26.88375382824776200000);
+    aWeights.ChangeValue(2, 76) = +1.00920552993214340000;
+    aPoles.ChangeValue(2, 76) = gp_Pnt(-207.76049754988114000000, +2.03384304897263670000, -24.69318019977189100000);
+    aWeights.ChangeValue(2, 77) = +1.00876475817298510000;
+    aPoles.ChangeValue(2, 77) = gp_Pnt(-210.12674832523484000000, +1.94448851661030540000, -22.49703905023471500000);
+    aWeights.ChangeValue(2, 78) = +1.00888387250469380000;
+    aPoles.ChangeValue(2, 78) = gp_Pnt(-212.44800842772909000000, +1.96852329008748410000, -20.25405344977475500000);
+    aWeights.ChangeValue(2, 79) = +1.00881670070680670000;
+    aPoles.ChangeValue(2, 79) = gp_Pnt(-214.73260668420895000000, +1.95481624964232450000, -17.97008076073228700000);
+    aWeights.ChangeValue(2, 80) = +1.00875338528797620000;
+    aPoles.ChangeValue(2, 80) = gp_Pnt(-216.99878954601004000000, +1.94217039944868790000, -15.66960286452947800000);
+    aWeights.ChangeValue(2, 81) = +1.00842683370719490000;
+    aPoles.ChangeValue(2, 81) = gp_Pnt(-219.23765241170187000000, +1.87520469423183880000, -13.35291936652889800000);
+    aWeights.ChangeValue(3, 1) = +0.99802424639217791000;
+    aPoles.ChangeValue(3, 1) = gp_Pnt(+131.89876890515018000000, +1.35189067474276530000, -66.51059820355672500000);
+    aWeights.ChangeValue(3, 2) = +0.99802234515929278000;
+    aPoles.ChangeValue(3, 2) = gp_Pnt(+128.85071311608803000000, +1.35313353595059940000, -68.19368716153405800000);
+    aWeights.ChangeValue(3, 3) = +0.99802076064203826000;
+    aPoles.ChangeValue(3, 3) = gp_Pnt(+125.77977143028471000000, +1.35416922698475650000, -69.83529373030198400000);
+    aWeights.ChangeValue(3, 4) = +0.99801949820651126000;
+    aPoles.ChangeValue(3, 4) = gp_Pnt(+122.68659332837821000000, +1.35499438550965670000, -71.43508181423516100000);
+    aWeights.ChangeValue(3, 5) = +0.99801796211084914000;
+    aPoles.ChangeValue(3, 5) = gp_Pnt(+119.57173533591266000000, +1.35599832254451200000, -72.99244308799212900000);
+    aWeights.ChangeValue(3, 6) = +0.99801651211145281000;
+    aPoles.ChangeValue(3, 6) = gp_Pnt(+116.43595392098000000000, +1.35694592285710100000, -74.50721127326711700000);
+    aWeights.ChangeValue(3, 7) = +0.99801547938002733000;
+    aPoles.ChangeValue(3, 7) = gp_Pnt(+113.28000153804584000000, +1.35762078417993900000, -75.97921900496575600000);
+    aWeights.ChangeValue(3, 8) = +0.99801427699595313000;
+    aPoles.ChangeValue(3, 8) = gp_Pnt(+110.10443724854701000000, +1.35840649430771500000, -77.40790012997213400000);
+    aWeights.ChangeValue(3, 9) = +0.99801219521191387000;
+    aPoles.ChangeValue(3, 9) = gp_Pnt(+103.71561277285424000000, +1.35976677896647580000, -80.17831514578958300000);
+    aWeights.ChangeValue(3, 10) = +0.99801119017200446000;
+    aPoles.ChangeValue(3, 10) = gp_Pnt(+100.50232486897988000000, +1.36042346207845170000, -81.51999289835789900000);
+    aWeights.ChangeValue(3, 11) = +0.99801030363459775000;
+    aPoles.ChangeValue(3, 11) = gp_Pnt(+97.27087733082035500000, +1.36100269005924380000, -82.81788136334564900000);
+    aWeights.ChangeValue(3, 12) = +0.99800944410125381000;
+    aPoles.ChangeValue(3, 12) = gp_Pnt(+94.02193936655145000000, +1.36156425167614130000, -84.07165794609035500000);
+    aWeights.ChangeValue(3, 13) = +0.99800863606857426000;
+    aPoles.ChangeValue(3, 13) = gp_Pnt(+90.75622955795523700000, +1.36209214789795310000, -85.28105659074749700000);
+    aWeights.ChangeValue(3, 14) = +0.99800791446328430000;
+    aPoles.ChangeValue(3, 14) = gp_Pnt(+87.47446474935537700000, +1.36256356235759690000, -86.44582972368263500000);
+    aWeights.ChangeValue(3, 15) = +0.99800720379689600000;
+    aPoles.ChangeValue(3, 15) = gp_Pnt(+84.17731596959211500000, +1.36302781837419680000, -87.56569962027794000000);
+    aWeights.ChangeValue(3, 16) = +0.99800525790220496000;
+    aPoles.ChangeValue(3, 16) = gp_Pnt(+74.24198734063921300000, +1.36429897306986340000, -90.78996991844945800000);
+    aWeights.ChangeValue(3, 17) = +0.99800413521623321000;
+    aPoles.ChangeValue(3, 17) = gp_Pnt(+67.56001809965197000000, +1.36503231983535440000, -92.75885901427626800000);
+    aWeights.ChangeValue(3, 18) = +0.99800316736440942000;
+    aPoles.ChangeValue(3, 18) = gp_Pnt(+60.82490109578901600000, +1.36566449260567850000, -94.54523441794054900000);
+    aWeights.ChangeValue(3, 19) = +0.99800233531441818000;
+    aPoles.ChangeValue(3, 19) = gp_Pnt(+54.04219505707111900000, +1.36620793936844790000, -96.14746061467829500000);
+    aWeights.ChangeValue(3, 20) = +0.99800162387306934000;
+    aPoles.ChangeValue(3, 20) = gp_Pnt(+47.21773986109732800000, +1.36667259642912180000, -97.56414160157402200000);
+    aWeights.ChangeValue(3, 21) = +0.99800102168630012000;
+    aPoles.ChangeValue(3, 21) = gp_Pnt(+40.35765665228271400000, +1.36706588836418840000, -98.79412083143951400000);
+    aWeights.ChangeValue(3, 22) = +0.99800052123917371000;
+    aPoles.ChangeValue(3, 22) = gp_Pnt(+33.46834796257081700000, +1.36739272798589770000, -99.83648116661171900000);
+    aWeights.ChangeValue(3, 23) = +0.99799971600020576000;
+    aPoles.ChangeValue(3, 23) = gp_Pnt(+19.64441706716387900000, +1.36791861440644060000, -101.54459131896159000000);
+    aWeights.ChangeValue(3, 24) = +0.99799940935225717000;
+    aPoles.ChangeValue(3, 24) = gp_Pnt(+12.70928858254282900000, +1.36811887624638580000, -102.21030492597274000000);
+    aWeights.ChangeValue(3, 25) = +0.99799919351964705000;
+    aPoles.ChangeValue(3, 25) = gp_Pnt(+5.75722078489831280000, +1.36825982711689180000, -102.68697252648171000000);
+    aWeights.ChangeValue(3, 26) = +0.99799906478455291000;
+    aPoles.ChangeValue(3, 26) = gp_Pnt(-1.20571159764999210000, +1.36834389755229970000, -102.97410341218257000000);
+    aWeights.ChangeValue(3, 27) = +0.99799902110371730000;
+    aPoles.ChangeValue(3, 27) = gp_Pnt(-8.17346746041202720000, +1.36837242333404090000, -103.07142929357101000000);
+    aWeights.ChangeValue(3, 28) = +0.99799906210844536000;
+    aPoles.ChangeValue(3, 28) = gp_Pnt(-15.14003926915473600000, +1.36834564548690430000, -102.97890429403182000000);
+    aWeights.ChangeValue(3, 29) = +0.99799918910460783000;
+    aPoles.ChangeValue(3, 29) = gp_Pnt(-22.09945300681867100000, +1.36826271027814080000, -102.69670494840925000000);
+    aWeights.ChangeValue(3, 30) = +0.99799962065035785000;
+    aPoles.ChangeValue(3, 30) = gp_Pnt(-35.99208002634647800000, +1.36798088374117890000, -101.75375562004130000000);
+    aWeights.ChangeValue(3, 31) = +0.99799992612548816000;
+    aPoles.ChangeValue(3, 31) = gp_Pnt(-42.92529183965938000000, +1.36778138671521220000, -101.09300634269859000000);
+    aWeights.ChangeValue(3, 32) = +0.99800032324181509000;
+    aPoles.ChangeValue(3, 32) = gp_Pnt(-49.83946240643516700000, +1.36752203923507090000, -100.24338136864999000000);
+    aWeights.ChangeValue(3, 33) = +0.99800081646744487000;
+    aPoles.ChangeValue(3, 33) = gp_Pnt(-56.72868525600537000000, +1.36719992054037180000, -99.20550257416397200000);
+    aWeights.ChangeValue(3, 34) = +0.99800141299480705000;
+    aPoles.ChangeValue(3, 34) = gp_Pnt(-63.58708851299418500000, +1.36681032802942060000, -97.98021473616272200000);
+    aWeights.ChangeValue(3, 35) = +0.99800212274065336000;
+    aPoles.ChangeValue(3, 35) = gp_Pnt(-70.40883481115771800000, +1.36634677727753220000, -96.56858555851044900000);
+    aWeights.ChangeValue(3, 36) = +0.99800295834605834000;
+    aPoles.ChangeValue(3, 36) = gp_Pnt(-77.18812120943384500000, +1.36580100206191160000, -94.97190570545618000000);
+    aWeights.ChangeValue(3, 37) = +0.99800438851666018000;
+    aPoles.ChangeValue(3, 37) = gp_Pnt(-87.04430869357409500000, +1.36486684103840930000, -92.36516064771883800000);
+    aWeights.ChangeValue(3, 38) = +0.99800487302440710000;
+    aPoles.ChangeValue(3, 38) = gp_Pnt(-90.15904180478642600000, +1.36455036334574700000, -91.49906951050012100000);
+    aWeights.ChangeValue(3, 39) = +0.99800538998403165000;
+    aPoles.ChangeValue(3, 39) = gp_Pnt(-93.26280104894121300000, +1.36421268117563340000, -90.59356682763008500000);
+    aWeights.ChangeValue(3, 40) = +0.99800594114472085000;
+    aPoles.ChangeValue(3, 40) = gp_Pnt(-96.35501076566437500000, +1.36385265030680070000, -89.64881447076304300000);
+    aWeights.ChangeValue(3, 41) = +0.99800652872047668000;
+    aPoles.ChangeValue(3, 41) = gp_Pnt(-99.43509702281136200000, +1.36346882243976730000, -88.66498478868943800000);
+    aWeights.ChangeValue(3, 42) = +0.99800715539011531000;
+    aPoles.ChangeValue(3, 42) = gp_Pnt(-102.50248760972849000000, +1.36305944519955100000, -87.64226061031386900000);
+    aWeights.ChangeValue(3, 43) = +0.99800782429726853000;
+    aPoles.ChangeValue(3, 43) = gp_Pnt(-105.55661203062589000000, +1.36262246213878830000, -86.58083524789229600000);
+    aWeights.ChangeValue(3, 44) = +0.99800929984388531000;
+    aPoles.ChangeValue(3, 44) = gp_Pnt(-111.87105232543304000000, +1.36165848631400000000, -84.29637819122412200000);
+    aWeights.ChangeValue(3, 45) = +0.99801015470554688000;
+    aPoles.ChangeValue(3, 45) = gp_Pnt(-115.12916723990907000000, +1.36109998387148300000, -83.06721412498791300000);
+    aWeights.ChangeValue(3, 46) = +0.99801097177629106000;
+    aPoles.ChangeValue(3, 46) = gp_Pnt(-118.37050305702043000000, +1.36056615831231790000, -81.79361556056927900000);
+    aWeights.ChangeValue(3, 47) = +0.99801197939908182000;
+    aPoles.ChangeValue(3, 47) = gp_Pnt(-121.59440429164877000000, +1.35990780214188640000, -80.47594855348815200000);
+    aWeights.ChangeValue(3, 48) = +0.99801295017732938000;
+    aPoles.ChangeValue(3, 48) = gp_Pnt(-124.80011198391350000000, +1.35927349774917520000, -79.11439339164216700000);
+    aWeights.ChangeValue(3, 49) = +0.99801403220993246000;
+    aPoles.ChangeValue(3, 49) = gp_Pnt(-127.98695272451793000000, +1.35856646260703170000, -77.70931006235629500000);
+    aWeights.ChangeValue(3, 50) = +0.99801521135673477000;
+    aPoles.ChangeValue(3, 50) = gp_Pnt(-131.15422466608416000000, +1.35779592883408770000, -76.26099835790641600000);
+    aWeights.ChangeValue(3, 51) = +0.99801760008173268000;
+    aPoles.ChangeValue(3, 51) = gp_Pnt(-137.22341426940562000000, +1.35623488186342090000, -73.38505097675174200000);
+    aWeights.ChangeValue(3, 52) = +0.99801898347031770000;
+    aPoles.ChangeValue(3, 52) = gp_Pnt(-140.12817143218851000000, +1.35533077140178190000, -71.96340636458091900000);
+    aWeights.ChangeValue(3, 53) = +0.99801998518653323000;
+    aPoles.ChangeValue(3, 53) = gp_Pnt(-143.01477271081365000000, +1.35467609324036100000, -70.50482384325539400000);
+    aWeights.ChangeValue(3, 54) = +0.99802187318341851000;
+    aPoles.ChangeValue(3, 54) = gp_Pnt(-145.88296929650440000000, +1.35344206211285110000, -69.01011970904052400000);
+    aWeights.ChangeValue(3, 55) = +0.99802301113749214000;
+    aPoles.ChangeValue(3, 55) = gp_Pnt(-148.73181832948791000000, +1.35269822187277230000, -67.47885556090747600000);
+    aWeights.ChangeValue(3, 56) = +0.99802485896116799000;
+    aPoles.ChangeValue(3, 56) = gp_Pnt(-151.56108889838526000000, +1.35149030610332030000, -65.91196867904423600000);
+    aWeights.ChangeValue(3, 57) = +0.99802660746081140000;
+    aPoles.ChangeValue(3, 57) = gp_Pnt(-154.37005843077941000000, +1.35034719652907540000, -64.30939181125272300000);
+    aWeights.ChangeValue(3, 58) = +0.99803055992501810000;
+    aPoles.ChangeValue(3, 58) = gp_Pnt(-160.16078498432634000000, +1.34776300585323040000, -60.90758294114521500000);
+    aWeights.ChangeValue(3, 59) = +0.99803322842151521000;
+    aPoles.ChangeValue(3, 59) = gp_Pnt(-163.13986451909619000000, +1.34601805132734250000, -59.10384793755353900000);
+    aWeights.ChangeValue(3, 60) = +0.99803464125751229000;
+    aPoles.ChangeValue(3, 60) = gp_Pnt(-166.09208359425281000000, +1.34509430571165490000, -57.25595351707911400000);
+    aWeights.ChangeValue(3, 61) = +0.99803901668572381000;
+    aPoles.ChangeValue(3, 61) = gp_Pnt(-169.02259847263389000000, +1.34223252516315280000, -55.37471701865561600000);
+    aWeights.ChangeValue(3, 62) = +0.99804026123487555000;
+    aPoles.ChangeValue(3, 62) = gp_Pnt(-171.92274649713781000000, +1.34141857200850120000, -53.44681670722970100000);
+    aWeights.ChangeValue(3, 63) = +0.99804470691034153000;
+    aPoles.ChangeValue(3, 63) = gp_Pnt(-174.79824691248783000000, +1.33851025764084610000, -51.48277226031661500000);
+    aWeights.ChangeValue(3, 64) = +0.99804786265209489000;
+    aPoles.ChangeValue(3, 64) = gp_Pnt(-177.64589658566118000000, +1.33644541377468110000, -49.47887210970986900000);
+    aWeights.ChangeValue(3, 65) = +0.99805209132461004000;
+    aPoles.ChangeValue(3, 65) = gp_Pnt(-180.46609411219177000000, +1.33367801102763010000, -47.43691639460438100000);
+    aWeights.ChangeValue(3, 66) = +0.99805585511720041000;
+    aPoles.ChangeValue(3, 66) = gp_Pnt(-183.08478109176986000000, +1.33121501172845690000, -45.54077967192022000000);
+    aWeights.ChangeValue(3, 67) = +0.99806110806405779000;
+    aPoles.ChangeValue(3, 67) = gp_Pnt(-185.68001727848417000000, +1.32777577033982250000, -43.61205685047624300000);
+    aWeights.ChangeValue(3, 68) = +0.99806241123000117000;
+    aPoles.ChangeValue(3, 68) = gp_Pnt(-188.24953622256075000000, +1.32692526187276720000, -41.64902509374122300000);
+    aWeights.ChangeValue(3, 69) = +0.99807437025077705000;
+    aPoles.ChangeValue(3, 69) = gp_Pnt(-190.79766796840426000000, +1.31909012471800140000, -39.65777616520052400000);
+    aWeights.ChangeValue(3, 70) = +0.99807032269259688000;
+    aPoles.ChangeValue(3, 70) = gp_Pnt(-193.31511620328166000000, +1.32174544077043810000, -37.62798636408343400000);
+    aWeights.ChangeValue(3, 71) = +0.99808625039380772000;
+    aPoles.ChangeValue(3, 71) = gp_Pnt(-195.81278252670535000000, +1.31130937814640340000, -35.57429171163009600000);
+    aWeights.ChangeValue(3, 72) = +0.99809097922828749000;
+    aPoles.ChangeValue(3, 72) = gp_Pnt(-198.28008499427182000000, +1.30820906528388470000, -33.48422839734306700000);
+    aWeights.ChangeValue(3, 73) = +0.99809984631895698000;
+    aPoles.ChangeValue(3, 73) = gp_Pnt(-200.72099421295775000000, +1.30239515227575060000, -31.36416391357070300000);
+    aWeights.ChangeValue(3, 74) = +0.99810637147759285000;
+    aPoles.ChangeValue(3, 74) = gp_Pnt(-203.16127009409345000000, +1.29812048781277520000, -29.24337154392900800000);
+    aWeights.ChangeValue(3, 75) = +0.99812847998895315000;
+    aPoles.ChangeValue(3, 75) = gp_Pnt(-205.57777363915829000000, +1.28359951668439790000, -27.09591401257074100000);
+    aWeights.ChangeValue(3, 76) = +0.99809892249848597000;
+    aPoles.ChangeValue(3, 76) = gp_Pnt(-207.95321979211485000000, +1.30303533816127510000, -24.90029856221717000000);
+    aWeights.ChangeValue(3, 77) = +0.99819234539248169000;
+    aPoles.ChangeValue(3, 77) = gp_Pnt(-210.32920376311637000000, +1.24168994973372330000, -22.71372419603407900000);
+    aWeights.ChangeValue(3, 78) = +0.99816706733577565000;
+    aPoles.ChangeValue(3, 78) = gp_Pnt(-212.65404345030839000000, +1.25824740351837460000, -20.46200135460381000000);
+    aWeights.ChangeValue(3, 79) = +0.99818127776964660000;
+    aPoles.ChangeValue(3, 79) = gp_Pnt(-214.94032188963598000000, +1.24888524402456480000, -18.17894168737611000000);
+    aWeights.ChangeValue(3, 80) = +0.99819475509197664000;
+    aPoles.ChangeValue(3, 80) = gp_Pnt(-217.21049138159862000000, +1.24010538580557930000, -15.87773552075580100000);
+    aWeights.ChangeValue(3, 81) = +0.99826376750414003000;
+    aPoles.ChangeValue(3, 81) = gp_Pnt(-219.45963474898130000000, +1.19454909379966280000, -13.56324778739743800000);
+    aWeights.ChangeValue(4, 1) = +0.99424302042862245000;
+    aPoles.ChangeValue(4, 1) = gp_Pnt(+132.13618409480023000000, +0.70840889522526063000, -66.94024029007874800000);
+    aWeights.ChangeValue(4, 2) = +0.99423758610938695000;
+    aPoles.ChangeValue(4, 2) = gp_Pnt(+129.08297406972278000000, +0.70909252303575865000, -68.62615176496952100000);
+    aWeights.ChangeValue(4, 3) = +0.99423305718875432000;
+    aPoles.ChangeValue(4, 3) = gp_Pnt(+126.00685240811242000000, +0.70966228194967051000, -70.27050713058781600000);
+    aWeights.ChangeValue(4, 4) = +0.99422944886444642000;
+    aPoles.ChangeValue(4, 4) = gp_Pnt(+122.90845587213282000000, +0.71011623149435366000, -71.87297804945868100000);
+    aWeights.ChangeValue(4, 5) = +0.99422505844796127000;
+    aPoles.ChangeValue(4, 5) = gp_Pnt(+119.78834767262531000000, +0.71066859395963999000, -73.43294438704307900000);
+    aWeights.ChangeValue(4, 6) = +0.99422091417503022000;
+    aPoles.ChangeValue(4, 6) = gp_Pnt(+116.64728496160824000000, +0.71119000548737488000, -74.95024473036627900000);
+    aWeights.ChangeValue(4, 7) = +0.99421796254996875000;
+    aPoles.ChangeValue(4, 7) = gp_Pnt(+113.48602386120655000000, +0.71156137519735096000, -76.42471498016054500000);
+    aWeights.ChangeValue(4, 8) = +0.99421452605999638000;
+    aPoles.ChangeValue(4, 8) = gp_Pnt(+110.30511547520040000000, +0.71199375553590705000, -77.85578472764748900000);
+    aWeights.ChangeValue(4, 9) = +0.99420857626658776000;
+    aPoles.ChangeValue(4, 9) = gp_Pnt(+103.90553506044348000000, +0.71274238201017392000, -80.63083668700706100000);
+    aWeights.ChangeValue(4, 10) = +0.99420570386914531000;
+    aPoles.ChangeValue(4, 10) = gp_Pnt(+100.68683453164211000000, +0.71310380757531833000, -81.97476109354066400000);
+    aWeights.ChangeValue(4, 11) = +0.99420317017586146000;
+    aPoles.ChangeValue(4, 11) = gp_Pnt(+97.44994659335081600000, +0.71342262156961334000, -83.27482261755635300000);
+    aWeights.ChangeValue(4, 12) = +0.99420071368291341000;
+    aPoles.ChangeValue(4, 12) = gp_Pnt(+94.19554253170841200000, +0.71373172711717636000, -84.53069694549194000000);
+    aWeights.ChangeValue(4, 13) = +0.99419840439350793000;
+    aPoles.ChangeValue(4, 13) = gp_Pnt(+90.92433917217061900000, +0.71402231445757036000, -85.74211902365664200000);
+    aWeights.ChangeValue(4, 14) = +0.99419634212229768000;
+    aPoles.ChangeValue(4, 14) = gp_Pnt(+87.63705473050230000000, +0.71428182289044062000, -86.90884124933938900000);
+    aWeights.ChangeValue(4, 15) = +0.99419431112670464000;
+    aPoles.ChangeValue(4, 15) = gp_Pnt(+84.33436439436984200000, +0.71453739893908408000, -88.03058362353205300000);
+    aWeights.ChangeValue(4, 16) = +0.99418875003915341000;
+    aPoles.ChangeValue(4, 16) = gp_Pnt(+74.38231313217285400000, +0.71523720648163680000, -91.26025430410756200000);
+    aWeights.ChangeValue(4, 17) = +0.99418554160984429000;
+    aPoles.ChangeValue(4, 17) = gp_Pnt(+67.68910051798944500000, +0.71564096751482986000, -93.23244050128337800000);
+    aWeights.ChangeValue(4, 18) = +0.99418277570171931000;
+    aPoles.ChangeValue(4, 18) = gp_Pnt(+60.94265918181897500000, +0.71598904839509359000, -95.02180567308657500000);
+    aWeights.ChangeValue(4, 19) = +0.99418039790864621000;
+    aPoles.ChangeValue(4, 19) = gp_Pnt(+54.14855416044807900000, +0.71628829211206946000, -96.62671289123449000000);
+    aWeights.ChangeValue(4, 20) = +0.99417836479981814000;
+    aPoles.ChangeValue(4, 20) = gp_Pnt(+47.31263275511362600000, +0.71654416141740851000, -98.04576467050098600000);
+    aWeights.ChangeValue(4, 21) = +0.99417664391975691000;
+    aPoles.ChangeValue(4, 21) = gp_Pnt(+40.44102486854357200000, +0.71676073875086976000, -99.27780280738555500000);
+    aWeights.ChangeValue(4, 22) = +0.99417521378830997000;
+    aPoles.ChangeValue(4, 22) = gp_Pnt(+33.54014335198198900000, +0.71694072618465221000, -100.32190824729783000000);
+    aWeights.ChangeValue(4, 23) = +0.99417291266204433000;
+    aPoles.ChangeValue(4, 23) = gp_Pnt(+19.69298272358705000000, +0.71723033475882103000, -102.03287833894613000000);
+    aWeights.ChangeValue(4, 24) = +0.99417203636017570000;
+    aPoles.ChangeValue(4, 24) = gp_Pnt(+12.74619890889187300000, +0.71734062296661449000, -102.69970663658552000000);
+    aWeights.ChangeValue(4, 25) = +0.99417141958182476000;
+    aPoles.ChangeValue(4, 25) = gp_Pnt(+5.78245043030823250000, +0.71741824902277995000, -103.17717197796689000000);
+    aWeights.ChangeValue(4, 26) = +0.99417105170022846000;
+    aPoles.ChangeValue(4, 26) = gp_Pnt(-1.19217909208406270000, +0.71746454980293017000, -103.46478315098152000000);
+    aWeights.ChangeValue(4, 27) = +0.99417092687508068000;
+    aPoles.ChangeValue(4, 27) = gp_Pnt(-8.17163978203099180000, +0.71748026003105458000, -103.56227159755184000000);
+    aWeights.ChangeValue(4, 28) = +0.99417104405253187000;
+    aPoles.ChangeValue(4, 28) = gp_Pnt(-15.14991535484593800000, +0.71746551227361877000, -103.46959139663633000000);
+    aWeights.ChangeValue(4, 29) = +0.99417140696519068000;
+    aPoles.ChangeValue(4, 29) = gp_Pnt(-22.12102296425817400000, +0.71741983693815459000, -103.18691926012113000000);
+    aWeights.ChangeValue(4, 30) = +0.99417264018315676000;
+    aPoles.ChangeValue(4, 30) = gp_Pnt(-36.03699423807252300000, +0.71726462804712465000, -102.24239043165372000000);
+    aWeights.ChangeValue(4, 31) = +0.99417351313460955000;
+    aPoles.ChangeValue(4, 31) = gp_Pnt(-42.98185258768797500000, +0.71715476185170723000, -101.58053487832193000000);
+    aWeights.ChangeValue(4, 32) = +0.99417464796983568000;
+    aPoles.ChangeValue(4, 32) = gp_Pnt(-49.90763755490115700000, +0.71701193671091712000, -100.72948788576410000000);
+    aWeights.ChangeValue(4, 33) = +0.99417605745995530000;
+    aPoles.ChangeValue(4, 33) = gp_Pnt(-56.80843390632649900000, +0.71683454604177377000, -99.68987236817491700000);
+    aWeights.ChangeValue(4, 34) = +0.99417776216385467000;
+    aPoles.ChangeValue(4, 34) = gp_Pnt(-63.67836146608049600000, +0.71662000367742562000, -98.46253420440308400000);
+    aWeights.ChangeValue(4, 35) = +0.99417979042818705000;
+    aPoles.ChangeValue(4, 35) = gp_Pnt(-70.51157486810592400000, +0.71636474389607163000, -97.04854231351581000000);
+    aWeights.ChangeValue(4, 36) = +0.99418217838737100000;
+    aPoles.ChangeValue(4, 36) = gp_Pnt(-77.30226331485057800000, +0.71606422146024096000, -95.44918875092946600000);
+    aWeights.ChangeValue(4, 37) = +0.99418626551507883000;
+    aPoles.ChangeValue(4, 37) = gp_Pnt(-87.17503156127875700000, +0.71554987190288122000, -92.83807781738744300000);
+    aWeights.ChangeValue(4, 38) = +0.99418765014289556000;
+    aPoles.ChangeValue(4, 38) = gp_Pnt(-90.29499963358738100000, +0.71537562386381059000, -91.97053762881716900000);
+    aWeights.ChangeValue(4, 39) = +0.99418912751868260000;
+    aPoles.ChangeValue(4, 39) = gp_Pnt(-93.40397633478176000000, +0.71518970580821706000, -91.06351986664817800000);
+    aWeights.ChangeValue(4, 40) = +0.99419070264287346000;
+    aPoles.ChangeValue(4, 40) = gp_Pnt(-96.50138523104767800000, +0.71499148886670094000, -90.11718659777564300000);
+    aWeights.ChangeValue(4, 41) = +0.99419238184469383000;
+    aPoles.ChangeValue(4, 41) = gp_Pnt(-99.58665166110419900000, +0.71478017704711161000, -89.13171035602891800000);
+    aWeights.ChangeValue(4, 42) = +0.99419417278216393000;
+    aPoles.ChangeValue(4, 42) = gp_Pnt(-102.65920271683186000000, +0.71455480723882170000, -88.10727415073346000000);
+    aWeights.ChangeValue(4, 43) = +0.99419608444209617000;
+    aPoles.ChangeValue(4, 43) = gp_Pnt(-105.71846722422283000000, +0.71431424921765596000, -87.04407147601585800000);
+    aWeights.ChangeValue(4, 44) = +0.99420030141669824000;
+    aPoles.ChangeValue(4, 44) = gp_Pnt(-112.04353021881408000000, +0.71378360593609291000, -84.75579106017932000000);
+    aWeights.ChangeValue(4, 45) = +0.99420274455295243000;
+    aPoles.ChangeValue(4, 45) = gp_Pnt(-115.30712351688430000000, +0.71347617951477893000, -83.52457168950516600000);
+    aWeights.ChangeValue(4, 46) = +0.99420507969516914000;
+    aPoles.ChangeValue(4, 46) = gp_Pnt(-118.55391065270935000000, +0.71318234625457844000, -82.24884224143599500000);
+    aWeights.ChangeValue(4, 47) = +0.99420795946419460000;
+    aPoles.ChangeValue(4, 47) = gp_Pnt(-121.78323693095153000000, +0.71281998990170370000, -80.92897147787398600000);
+    aWeights.ChangeValue(4, 48) = +0.99421073394729520000;
+    aPoles.ChangeValue(4, 48) = gp_Pnt(-124.99434061394447000000, +0.71247088780699119000, -79.56513754354314500000);
+    aWeights.ChangeValue(4, 49) = +0.99421382643715051000;
+    aPoles.ChangeValue(4, 49) = gp_Pnt(-128.18654935306802000000, +0.71208178090166396000, -78.15770189412481300000);
+    aWeights.ChangeValue(4, 50) = +0.99421719652005114000;
+    aPoles.ChangeValue(4, 50) = gp_Pnt(-131.35915951555538000000, +0.71165775668839981000, -76.70696466864815500000);
+    aWeights.ChangeValue(4, 51) = +0.99422402375653052000;
+    aPoles.ChangeValue(4, 51) = gp_Pnt(-137.43857370930490000000, +0.71079877890710363000, -73.82620311743470200000);
+    aWeights.ChangeValue(4, 52) = +0.99422797768691740000;
+    aPoles.ChangeValue(4, 52) = gp_Pnt(-140.34822128390073000000, +0.71030132584778982000, -72.40218284379008700000);
+    aWeights.ChangeValue(4, 53) = +0.99423084075610579000;
+    aPoles.ChangeValue(4, 53) = gp_Pnt(-143.23968120103163000000, +0.70994112075449667000, -70.94115847846593700000);
+    aWeights.ChangeValue(4, 54) = +0.99423623706224973000;
+    aPoles.ChangeValue(4, 54) = gp_Pnt(-146.11271315064005000000, +0.70926223398833632000, -69.44395856663618400000);
+    aWeights.ChangeValue(4, 55) = +0.99423948964319253000;
+    aPoles.ChangeValue(4, 55) = gp_Pnt(-148.96636467875118000000, +0.70885305306993507000, -67.91012785943519200000);
+    aWeights.ChangeValue(4, 56) = +0.99424477127021760000;
+    aPoles.ChangeValue(4, 56) = gp_Pnt(-151.80041102174371000000, +0.70818863107582075000, -66.34061951491401000000);
+    aWeights.ChangeValue(4, 57) = +0.99424976912431906000;
+    aPoles.ChangeValue(4, 57) = gp_Pnt(-154.61412826195317000000, +0.70755993553172780000, -64.73535576374381200000);
+    aWeights.ChangeValue(4, 58) = +0.99426106692542415000;
+    aPoles.ChangeValue(4, 58) = gp_Pnt(-160.41462700323274000000, +0.70613881146866808000, -61.32785485541679500000);
+    aWeights.ChangeValue(4, 59) = +0.99426869485276259000;
+    aPoles.ChangeValue(4, 59) = gp_Pnt(-163.39874797129167000000, +0.70517937516238605000, -59.52109641918814000000);
+    aWeights.ChangeValue(4, 60) = +0.99427273335051769000;
+    aPoles.ChangeValue(4, 60) = gp_Pnt(-166.35588428707737000000, +0.70467140031138198000, -57.67014968010805400000);
+    aWeights.ChangeValue(4, 61) = +0.99428524121150996000;
+    aPoles.ChangeValue(4, 61) = gp_Pnt(-169.29147402675417000000, +0.70309833118760823000, -55.78569706052214600000);
+    aWeights.ChangeValue(4, 62) = +0.99428879891231192000;
+    aPoles.ChangeValue(4, 62) = gp_Pnt(-172.19641321622018000000, +0.70265088960130029000, -53.85463096447261900000);
+    aWeights.ChangeValue(4, 63) = +0.99430150819260854000;
+    aPoles.ChangeValue(4, 63) = gp_Pnt(-175.07684836851479000000, +0.70105264832187786000, -51.88726956537038900000);
+    aWeights.ChangeValue(4, 64) = +0.99431053021705873000;
+    aPoles.ChangeValue(4, 64) = gp_Pnt(-177.92932492963632000000, +0.69991818857623234000, -49.88000737868681300000);
+    aWeights.ChangeValue(4, 65) = +0.99432262020918794000;
+    aPoles.ChangeValue(4, 65) = gp_Pnt(-180.75433885652521000000, +0.69839807993520564000, -47.83460859504128800000);
+    aWeights.ChangeValue(4, 66) = +0.99433338093448842000;
+    aPoles.ChangeValue(4, 66) = gp_Pnt(-183.37745173242254000000, +0.69704510882650861000, -45.93530736698277700000);
+    aWeights.ChangeValue(4, 67) = +0.99434840096468768000;
+    aPoles.ChangeValue(4, 67) = gp_Pnt(-185.97711214268182000000, +0.69515696483250133000, -44.00334265992864100000);
+    aWeights.ChangeValue(4, 68) = +0.99435212441487342000;
+    aPoles.ChangeValue(4, 68) = gp_Pnt(-188.55092060214918000000, +0.69468843290184534000, -42.03706245316480100000);
+    aWeights.ChangeValue(4, 69) = +0.99438632495837886000;
+    aPoles.ChangeValue(4, 69) = gp_Pnt(-191.10351948864678000000, +0.69039032514405918000, -40.04240176159244400000);
+    aWeights.ChangeValue(4, 70) = +0.99437474610357146000;
+    aPoles.ChangeValue(4, 70) = gp_Pnt(-193.62512272227769000000, +0.69184483548244469000, -38.00925246210125900000);
+    aWeights.ChangeValue(4, 71) = +0.99442029730057158000;
+    aPoles.ChangeValue(4, 71) = gp_Pnt(-196.12715745709386000000, +0.68612074693666814000, -35.95207510226987300000);
+    aWeights.ChangeValue(4, 72) = +0.99443382321708784000;
+    aPoles.ChangeValue(4, 72) = gp_Pnt(-198.59871781224271000000, +0.68442148883790921000, -33.85842837168388500000);
+    aWeights.ChangeValue(4, 73) = +0.99445918644353237000;
+    aPoles.ChangeValue(4, 73) = gp_Pnt(-201.04387700918369000000, +0.68123533540985159000, -31.73471330438436400000);
+    aWeights.ChangeValue(4, 74) = +0.99447784672499884000;
+    aPoles.ChangeValue(4, 74) = gp_Pnt(-203.48830197003542000000, +0.67889067518118906000, -29.61036197082074800000);
+    aWeights.ChangeValue(4, 75) = +0.99454111417144087000;
+    aPoles.ChangeValue(4, 75) = gp_Pnt(-205.90905874701556000000, +0.67094847421818948000, -27.45911353863423800000);
+    aWeights.ChangeValue(4, 76) = +0.99445650432969468000;
+    aPoles.ChangeValue(4, 76) = gp_Pnt(-208.28851122415659000000, +0.68156618053615436000, -25.25989914496455000000);
+    aWeights.ChangeValue(4, 77) = +0.99472383917628937000;
+    aPoles.ChangeValue(4, 77) = gp_Pnt(-210.66819860636727000000, +0.64801004101885640000, -23.06997485052475800000);
+    aWeights.ChangeValue(4, 78) = +0.99465154011060308000;
+    aPoles.ChangeValue(4, 78) = gp_Pnt(-212.99829629837927000000, +0.65709020698928045000, -20.81293704958459000000);
+    aWeights.ChangeValue(4, 79) = +0.99469225299704522000;
+    aPoles.ChangeValue(4, 79) = gp_Pnt(-215.28778722004142000000, +0.65198647566642243000, -18.52648999480212300000);
+    aWeights.ChangeValue(4, 80) = +0.99473072608314816000;
+    aPoles.ChangeValue(4, 80) = gp_Pnt(-217.56233176434088000000, +0.64714607636795729000, -16.22125679272672700000);
+    aWeights.ChangeValue(4, 81) = +0.99492849872148770000;
+    aPoles.ChangeValue(4, 81) = gp_Pnt(-219.81591407133737000000, +0.62237708094437050000, -13.90082269618381800000);
+    aWeights.ChangeValue(5, 1) = +0.99802424639217535000;
+    aPoles.ChangeValue(5, 1) = gp_Pnt(+132.45622778603641000000, +0.24240580374773624000, -67.51941232824347600000);
+    aWeights.ChangeValue(5, 2) = +0.99802234515930366000;
+    aPoles.ChangeValue(5, 2) = gp_Pnt(+129.39621499227619000000, +0.24264599956164210000, -69.20932849809996400000);
+    aWeights.ChangeValue(5, 3) = +0.99802076064199163000;
+    aPoles.ChangeValue(5, 3) = gp_Pnt(+126.31320722587012000000, +0.24284620475411531000, -70.85757023346207000000);
+    aWeights.ChangeValue(5, 4) = +0.99801949820656444000;
+    aPoles.ChangeValue(5, 4) = gp_Pnt(+123.20785947444472000000, +0.24300571706284735000, -72.46379895615213200000);
+    aWeights.ChangeValue(5, 5) = +0.99801796211084626000;
+    aPoles.ChangeValue(5, 5) = gp_Pnt(+120.08075545981777000000, +0.24319982314295371000, -74.02745916652884300000);
+    aWeights.ChangeValue(5, 6) = +0.99801651211139986000;
+    aPoles.ChangeValue(5, 6) = gp_Pnt(+116.93263892914923000000, +0.24338306180645181000, -75.54835063375608700000);
+    aWeights.ChangeValue(5, 7) = +0.99801547938007906000;
+    aPoles.ChangeValue(5, 7) = gp_Pnt(+113.76425167349765000000, +0.24351357797625062000, -77.02627451676777100000);
+    aWeights.ChangeValue(5, 8) = +0.99801427699593348000;
+    aPoles.ChangeValue(5, 8) = gp_Pnt(+110.57618061475338000000, +0.24366553774363486000, -78.46071663606139200000);
+    aWeights.ChangeValue(5, 9) = +0.99801219521177365000;
+    aPoles.ChangeValue(5, 9) = gp_Pnt(+104.16217613984874000000, +0.24392865233284403000, -81.24228081548614000000);
+    aWeights.ChangeValue(5, 10) = +0.99801119017243534000;
+    aPoles.ChangeValue(5, 10) = gp_Pnt(+100.93622072836907000000, +0.24405568433254640000, -82.58935804874866400000);
+    aWeights.ChangeValue(5, 11) = +0.99801030363411136000;
+    aPoles.ChangeValue(5, 11) = gp_Pnt(+97.69202612265307600000, +0.24416774311013159000, -83.89246252379766100000);
+    aWeights.ChangeValue(5, 12) = +0.99800944410126124000;
+    aPoles.ChangeValue(5, 12) = gp_Pnt(+94.43027249107268500000, +0.24427639255629080000, -85.15127753548810600000);
+    aWeights.ChangeValue(5, 13) = +0.99800863606905588000;
+    aPoles.ChangeValue(5, 13) = gp_Pnt(+91.15167507122404800000, +0.24437853537532742000, -86.36553541507953500000);
+    aWeights.ChangeValue(5, 14) = +0.99800791446282866000;
+    aPoles.ChangeValue(5, 14) = gp_Pnt(+87.85695090009397700000, +0.24446975628264125000, -87.53498464352057300000);
+    aWeights.ChangeValue(5, 15) = +0.99800720379704511000;
+    aPoles.ChangeValue(5, 15) = gp_Pnt(+84.54678770958248900000, +0.24455959646371978000, -88.65934979276558200000);
+    aWeights.ChangeValue(5, 16) = +0.99800525790220262000;
+    aPoles.ChangeValue(5, 16) = gp_Pnt(+74.57222162875666500000, +0.24480559775636487000, -91.89655746079053200000);
+    aWeights.ChangeValue(5, 17) = +0.99800413521623044000;
+    aPoles.ChangeValue(5, 17) = gp_Pnt(+67.86385477996348900000, +0.24494753702776123000, -93.87334138726605200000);
+    aWeights.ChangeValue(5, 18) = +0.99800316736440708000;
+    aPoles.ChangeValue(5, 18) = gp_Pnt(+61.10212188651380700000, +0.24506990714535715000, -95.66687639706128700000);
+    aWeights.ChangeValue(5, 19) = +0.99800233531441618000;
+    aPoles.ChangeValue(5, 19) = gp_Pnt(+54.29260355218377000000, +0.24517511152453569000, -97.27552257290322800000);
+    aWeights.ChangeValue(5, 20) = +0.99800162387306812000;
+    aPoles.ChangeValue(5, 20) = gp_Pnt(+47.44116356008504500000, +0.24526506890417449000, -98.69787956398771200000);
+    aWeights.ChangeValue(5, 21) = +0.99800102168629923000;
+    aPoles.ChangeValue(5, 21) = gp_Pnt(+40.55394899036769400000, +0.24534121333759545000, -99.93278652962781900000);
+    aWeights.ChangeValue(5, 22) = +0.99800052123917249000;
+    aPoles.ChangeValue(5, 22) = gp_Pnt(+33.63739034141031700000, +0.24540449418574758000, -100.97932209286283000000);
+    aWeights.ChangeValue(5, 23) = +0.99799971600020576000;
+    aPoles.ChangeValue(5, 23) = gp_Pnt(+19.75877904385457000000, +0.24550631764576064000, -102.69427034587730000000);
+    aWeights.ChangeValue(5, 24) = +0.99799940935225595000;
+    aPoles.ChangeValue(5, 24) = gp_Pnt(+12.79621461719473900000, +0.24554509442498113000, -103.36264862290150000000);
+    aWeights.ChangeValue(5, 25) = +0.99799919351964361000;
+    aPoles.ChangeValue(5, 25) = gp_Pnt(+5.81664173483571470000, +0.24557238768930081000, -103.84122357926364000000);
+    aWeights.ChangeValue(5, 26) = +0.99799906478454914000;
+    aPoles.ChangeValue(5, 26) = gp_Pnt(-1.17384006705611750000, +0.24558866712534574000, -104.12950288114470000000);
+    aWeights.ChangeValue(5, 27) = +0.99799902110371452000;
+    aPoles.ChangeValue(5, 27) = gp_Pnt(-8.16916502467035950000, +0.24559419086566145000, -104.22721740658889000000);
+    aWeights.ChangeValue(5, 28) = +0.99799906210844525000;
+    aPoles.ChangeValue(5, 28) = gp_Pnt(-15.16330109337111900000, +0.24558900548798951000, -104.13432123956672000000);
+    aWeights.ChangeValue(5, 29) = +0.99799918910460916000;
+    aPoles.ChangeValue(5, 29) = gp_Pnt(-22.15024989420349800000, +0.24557294601509544000, -103.85099166853988000000);
+    aWeights.ChangeValue(5, 30) = +0.99799962065035952000;
+    aPoles.ChangeValue(5, 30) = gp_Pnt(-36.09784025928350100000, +0.24551837507724711000, -102.90426687944763000000);
+    aWeights.ChangeValue(5, 31) = +0.99799992612548860000;
+    aPoles.ChangeValue(5, 31) = gp_Pnt(-43.05848024708384300000, +0.24547974681812620000, -102.24087223758063000000);
+    aWeights.ChangeValue(5, 32) = +0.99800032324181287000;
+    aPoles.ChangeValue(5, 32) = gp_Pnt(-50.00000136683811300000, +0.24542953068576923000, -101.38784584473753000000);
+    aWeights.ChangeValue(5, 33) = +0.99800081646744143000;
+    aPoles.ChangeValue(5, 33) = gp_Pnt(-56.91647304260395400000, +0.24536716218422927000, -100.34581179308852000000);
+    aWeights.ChangeValue(5, 34) = +0.99800141299480460000;
+    aPoles.ChangeValue(5, 34) = gp_Pnt(-63.80199929133657100000, +0.24529173277606747000, -99.11561770524215800000);
+    aWeights.ChangeValue(5, 35) = +0.99800212274065292000;
+    aPoles.ChangeValue(5, 35) = gp_Pnt(-70.65071863638867500000, +0.24520198988589620000, -97.69833476064030700000);
+    aWeights.ChangeValue(5, 36) = +0.99800295834605834000;
+    aPoles.ChangeValue(5, 36) = gp_Pnt(-77.45680402323041800000, +0.24509633690518939000, -96.09525772913629300000);
+    aWeights.ChangeValue(5, 37) = +0.99800438851665707000;
+    aPoles.ChangeValue(5, 37) = gp_Pnt(-87.35194268844766400000, +0.24491551610541196000, -93.47806376363495000000);
+    aWeights.ChangeValue(5, 38) = +0.99800487302440644000;
+    aPoles.ChangeValue(5, 38) = gp_Pnt(-90.47898339307414500000, +0.24485425955861742000, -92.60850028621504700000);
+    aWeights.ChangeValue(5, 39) = +0.99800538998403221000;
+    aPoles.ChangeValue(5, 39) = gp_Pnt(-93.59500505694055100000, +0.24478890139349116000, -91.69936647202810300000);
+    aWeights.ChangeValue(5, 40) = +0.99800594114472096000;
+    aPoles.ChangeValue(5, 40) = gp_Pnt(-96.69942959625443300000, +0.24471922075774133000, -90.75082469114758500000);
+    aWeights.ChangeValue(5, 41) = +0.99800652872047502000;
+    aPoles.ChangeValue(5, 41) = gp_Pnt(-99.79168063143930600000, +0.24464493811196314000, -89.76304779373697300000);
+    aWeights.ChangeValue(5, 42) = +0.99800715539011187000;
+    aPoles.ChangeValue(5, 42) = gp_Pnt(-102.87118348036965000000, +0.24456571523016235000, -88.73621911304020700000);
+    aWeights.ChangeValue(5, 43) = +0.99800782429726465000;
+    aPoles.ChangeValue(5, 43) = gp_Pnt(-105.93736515171811000000, +0.24448115520035879000, -87.67053246863201800000);
+    aWeights.ChangeValue(5, 44) = +0.99800929984371112000;
+    aPoles.ChangeValue(5, 44) = gp_Pnt(-112.27672847568951000000, +0.24429462970498794000, -85.37690123862388700000);
+    aWeights.ChangeValue(5, 45) = +0.99801015470633669000;
+    aPoles.ChangeValue(5, 45) = gp_Pnt(-115.54769755356581000000, +0.24418656943131900000, -84.14279592325505100000);
+    aWeights.ChangeValue(5, 46) = +0.99801097177455889000;
+    aPoles.ChangeValue(5, 46) = gp_Pnt(-118.80182311076892000000, +0.24408328894344730000, -82.86408351153079400000);
+    aWeights.ChangeValue(5, 47) = +0.99801197940129383000;
+    aPoles.ChangeValue(5, 47) = gp_Pnt(-122.03843417449148000000, +0.24395592759703674000, -81.54111184389478200000);
+    aWeights.ChangeValue(5, 48) = +0.99801295017559344000;
+    aPoles.ChangeValue(5, 48) = gp_Pnt(-125.25678060282321000000, +0.24383322797751039000, -80.17408187890907800000);
+    aWeights.ChangeValue(5, 49) = +0.99801403221073270000;
+    aPoles.ChangeValue(5, 49) = gp_Pnt(-128.45617956663568000000, +0.24369647262362162000, -78.76334161483092100000);
+    aWeights.ChangeValue(5, 50) = +0.99801521135655380000;
+    aPoles.ChangeValue(5, 50) = gp_Pnt(-131.63592529803751000000, +0.24354745092247693000, -77.30919404502431300000);
+    aWeights.ChangeValue(5, 51) = +0.99801760008187401000;
+    aPoles.ChangeValue(5, 51) = gp_Pnt(-137.72900951211963000000, +0.24324557860805471000, -74.42165429070698200000);
+    aWeights.ChangeValue(5, 52) = +0.99801898346970708000;
+    aPoles.ChangeValue(5, 52) = gp_Pnt(-140.64518873661288000000, +0.24307076523393223000, -72.99426192178911800000);
+    aWeights.ChangeValue(5, 53) = +0.99801998518786039000;
+    aPoles.ChangeValue(5, 53) = gp_Pnt(-143.54316005505726000000, +0.24294418386170585000, -71.52981926220020600000);
+    aWeights.ChangeValue(5, 54) = +0.99802187318168345000;
+    aPoles.ChangeValue(5, 54) = gp_Pnt(-146.42260629144496000000, +0.24270562978064991000, -70.02903356238938700000);
+    aWeights.ChangeValue(5, 55) = +0.99802301113888081000;
+    aPoles.ChangeValue(5, 55) = gp_Pnt(-149.28266198929455000000, +0.24256185427332766000, -68.49161271016626500000);
+    aWeights.ChangeValue(5, 56) = +0.99802485896051119000;
+    aPoles.ChangeValue(5, 56) = gp_Pnt(-152.12302992679020000000, +0.24232840183433180000, -66.91836178765569800000);
+    aWeights.ChangeValue(5, 57) = +0.99802660746095961000;
+    aPoles.ChangeValue(5, 57) = gp_Pnt(-154.94301695331424000000, +0.24210751871096883000, -65.30929034698890200000);
+    aWeights.ChangeValue(5, 58) = +0.99803055992501044000;
+    aPoles.ChangeValue(5, 58) = gp_Pnt(-160.75642720778953000000, +0.24160825342055195000, -61.89368007550259400000);
+    aWeights.ChangeValue(5, 59) = +0.99803322842160846000;
+    aPoles.ChangeValue(5, 59) = gp_Pnt(-163.74717060555361000000, +0.24127121961594802000, -60.08255013672670200000);
+    aWeights.ChangeValue(5, 60) = +0.99803464125717123000;
+    aPoles.ChangeValue(5, 60) = gp_Pnt(-166.71086689375946000000, +0.24109275824918924000, -58.22731479955884700000);
+    aWeights.ChangeValue(5, 61) = +0.99803901668628470000;
+    aPoles.ChangeValue(5, 61) = gp_Pnt(-169.65297207222594000000, +0.24054025241076704000, -56.33806928337021700000);
+    aWeights.ChangeValue(5, 62) = +0.99804026123435818000;
+    aPoles.ChangeValue(5, 62) = gp_Pnt(-172.56427255537395000000, +0.24038308942389072000, -54.40260496408483000000);
+    aWeights.ChangeValue(5, 63) = +0.99804470691060532000;
+    aPoles.ChangeValue(5, 63) = gp_Pnt(-175.45101016300779000000, +0.23982181928534163000, -52.43032166263763100000);
+    aWeights.ChangeValue(5, 64) = +0.99804786265202527000;
+    aPoles.ChangeValue(5, 64) = gp_Pnt(-178.30970270493245000000, +0.23942347201733374000, -50.41823769283568900000);
+    aWeights.ChangeValue(5, 65) = +0.99805209132460959000;
+    aPoles.ChangeValue(5, 65) = gp_Pnt(-181.14080917168710000000, +0.23888978094458979000, -48.36782293133622100000);
+    aWeights.ChangeValue(5, 66) = +0.99805585511722006000;
+    aPoles.ChangeValue(5, 66) = gp_Pnt(-183.76963089028271000000, +0.23841474156011525000, -46.46384963887197700000);
+    aWeights.ChangeValue(5, 67) = +0.99806110806389992000;
+    aPoles.ChangeValue(5, 67) = gp_Pnt(-186.37480135254410000000, +0.23775204017864099000, -44.52702607060874100000);
+    aWeights.ChangeValue(5, 68) = +0.99806241123039841000;
+    aPoles.ChangeValue(5, 68) = gp_Pnt(-188.95443339023049000000, +0.23758721013871806000, -42.55611011320790700000);
+    aWeights.ChangeValue(5, 69) = +0.99807437025022461000;
+    aPoles.ChangeValue(5, 69) = gp_Pnt(-191.51185439080101000000, +0.23607937004601673000, -40.55588840407725800000);
+    aWeights.ChangeValue(5, 70) = +0.99807032269304363000;
+    aPoles.ChangeValue(5, 70) = gp_Pnt(-194.03956238778505000000, +0.23658914396266717000, -38.51843887702921200000);
+    aWeights.ChangeValue(5, 71) = +0.99808625039358922000;
+    aPoles.ChangeValue(5, 71) = gp_Pnt(-196.54607703546344000000, +0.23458111537982981000, -36.45513422497234800000);
+    aWeights.ChangeValue(5, 72) = +0.99809097922833689000;
+    aPoles.ChangeValue(5, 72) = gp_Pnt(-199.02284030117690000000, +0.23398526561785285000, -34.35633603568415100000);
+    aWeights.ChangeValue(5, 73) = +0.99809984631895676000;
+    aPoles.ChangeValue(5, 73) = gp_Pnt(-201.47284391020807000000, +0.23286808083306546000, -32.22700780168109700000);
+    aWeights.ChangeValue(5, 74) = +0.99810637147739267000;
+    aPoles.ChangeValue(5, 74) = gp_Pnt(-203.92239692899503000000, +0.23204542949601353000, -30.09717639714928000000);
+    aWeights.ChangeValue(5, 75) = +0.99812847998973830000;
+    aPoles.ChangeValue(5, 75) = gp_Pnt(-206.34684289021220000000, +0.22926391512904498000, -27.93902362306789300000);
+    aWeights.ChangeValue(5, 76) = +0.99809892249694432000;
+    aPoles.ChangeValue(5, 76) = gp_Pnt(-208.73420674519565000000, +0.23297935369059405000, -25.73750919512989600000);
+    aWeights.ChangeValue(5, 77) = +0.99819234539430379000;
+    aPoles.ChangeValue(5, 77) = gp_Pnt(-211.11258262007470000000, +0.22122441504945897000, -23.53328220960779800000);
+    aWeights.ChangeValue(5, 78) = +0.99816706733442118000;
+    aPoles.ChangeValue(5, 78) = gp_Pnt(-213.44890831521380000000, +0.22441150695403267000, -21.27426418813643800000);
+    aWeights.ChangeValue(5, 79) = +0.99818127777024523000;
+    aPoles.ChangeValue(5, 79) = gp_Pnt(-215.74298068197336000000, +0.22262736656649654000, -18.98075706196405200000);
+    aWeights.ChangeValue(5, 80) = +0.99819475509184485000;
+    aPoles.ChangeValue(5, 80) = gp_Pnt(-218.02209738817496000000, +0.22092240555297402000, -16.66880151580776100000);
+    aWeights.ChangeValue(5, 81) = +0.99826376750413803000;
+    aPoles.ChangeValue(5, 81) = gp_Pnt(-220.27506837008727000000, +0.21227676902692139000, -14.33587171753685400000);
+    aWeights.ChangeValue(6, 1) = +1.00955713824395920000;
+    aPoles.ChangeValue(6, 1) = gp_Pnt(+132.82497533600920000000, -0.00000000000000355271, -68.18672206105269100000);
+    aWeights.ChangeValue(6, 2) = +1.00956608612165510000;
+    aPoles.ChangeValue(6, 2) = gp_Pnt(+129.75720107675980000000, -0.00000000000001501048, -69.88134023490506800000);
+    aWeights.ChangeValue(6, 3) = +1.00957354292813720000;
+    aPoles.ChangeValue(6, 3) = gp_Pnt(+126.66630562875893000000, +0.00000000000001468880, -71.53414324810810900000);
+    aWeights.ChangeValue(6, 4) = +1.00957948395969920000;
+    aPoles.ChangeValue(6, 4) = gp_Pnt(+123.55299204973852000000, -0.00000000000002420214, -73.14476521965842400000);
+    aWeights.ChangeValue(6, 5) = +1.00958671248272540000;
+    aPoles.ChangeValue(6, 5) = gp_Pnt(+120.41786571412476000000, +0.00000000000000774289, -74.71276629883676900000);
+    aWeights.ChangeValue(6, 6) = +1.00959353559449030000;
+    aPoles.ChangeValue(6, 6) = gp_Pnt(+117.26165038381876000000, +0.00000000000002827238, -76.23787924846354300000);
+    aWeights.ChangeValue(6, 7) = +1.00959839503053540000;
+    aPoles.ChangeValue(6, 7) = gp_Pnt(+114.08506189168672000000, -0.00000000000002567399, -77.71984701658058700000);
+    aWeights.ChangeValue(6, 8) = +1.00960405269295440000;
+    aPoles.ChangeValue(6, 8) = gp_Pnt(+110.88875430250306000000, +0.00000000000001531652, -79.15824703626482500000);
+    aWeights.ChangeValue(6, 9) = +1.00961384794965610000;
+    aPoles.ChangeValue(6, 9) = gp_Pnt(+104.45816547225203000000, +0.00000000000002372811, -81.94743615023858800000);
+    aWeights.ChangeValue(6, 10) = +1.00961857675613920000;
+    aPoles.ChangeValue(6, 10) = gp_Pnt(+101.22387341781818000000, -0.00000000000003253030, -83.29820264563102200000);
+    aWeights.ChangeValue(6, 11) = +1.00962274789490230000;
+    aPoles.ChangeValue(6, 11) = gp_Pnt(+97.97127406275538400000, +0.00000000000002165813, -84.60486564781918200000);
+    aWeights.ChangeValue(6, 12) = +1.00962679188945900000;
+    aPoles.ChangeValue(6, 12) = gp_Pnt(+94.70106106239124700000, +0.00000000000003307844, -85.86712155505158300000);
+    aWeights.ChangeValue(6, 13) = +1.00963059350859920000;
+    aPoles.ChangeValue(6, 13) = gp_Pnt(+91.41394873512904000000, -0.00000000000001002370, -87.08469757155246800000);
+    aWeights.ChangeValue(6, 14) = +1.00963398843787310000;
+    aPoles.ChangeValue(6, 14) = gp_Pnt(+88.11065082060795800000, -0.00000000000001620026, -88.25733602781997400000);
+    aWeights.ChangeValue(6, 15) = +1.00963733185343440000;
+    aPoles.ChangeValue(6, 15) = gp_Pnt(+84.79187377942922400000, +0.00000000000001387836, -89.38476986722990600000);
+    aWeights.ChangeValue(6, 16) = +1.00964648640037490000;
+    aPoles.ChangeValue(6, 16) = gp_Pnt(+74.79138897281484300000, +0.00000000000001147648, -92.63077806554609600000);
+    aWeights.ChangeValue(6, 17) = +1.00965176794147980000;
+    aPoles.ChangeValue(6, 17) = gp_Pnt(+68.06556894151637500000, +0.00000000000001348105, -94.61292925638954900000);
+    aWeights.ChangeValue(6, 18) = +1.00965632094816880000;
+    aPoles.ChangeValue(6, 18) = gp_Pnt(+61.28620656548358900000, +0.00000000000001132208, -96.41133393799678700000);
+    aWeights.ChangeValue(6, 19) = +1.00966023501695920000;
+    aPoles.ChangeValue(6, 19) = gp_Pnt(+54.45890525472331200000, +0.00000000000000779610, -98.02434736777235000000);
+    aWeights.ChangeValue(6, 20) = +1.00966358166845540000;
+    aPoles.ChangeValue(6, 20) = gp_Pnt(+47.58955228763309700000, +0.00000000000000496426, -99.45056478986435900000);
+    aWeights.ChangeValue(6, 21) = +1.00966641434734750000;
+    aPoles.ChangeValue(6, 21) = gp_Pnt(+40.68431826182812500000, +0.00000000000000415229, -100.68882169811890000000);
+    aWeights.ChangeValue(6, 22) = +1.00966876842241240000;
+    aPoles.ChangeValue(6, 22) = gp_Pnt(+33.74965652868991100000, +0.00000000000000595055, -101.73819405254569000000);
+    aWeights.ChangeValue(6, 23) = +1.00967255617655690000;
+    aPoles.ChangeValue(6, 23) = gp_Pnt(+19.83474481990451800000, +0.00000000000000626687, -103.45778313292877000000);
+    aWeights.ChangeValue(6, 24) = +1.00967399859793900000;
+    aPoles.ChangeValue(6, 24) = gp_Pnt(+12.85396744583563800000, +0.00000000000000961706, -104.12796934503771000000);
+    aWeights.ChangeValue(6, 25) = +1.00967501382969150000;
+    aPoles.ChangeValue(6, 25) = gp_Pnt(+5.85612456199985140000, +0.00000000000001451316, -104.60783896197547000000);
+    aWeights.ChangeValue(6, 26) = +1.00967561936958040000;
+    aPoles.ChangeValue(6, 26) = gp_Pnt(-1.15266320632332260000, +0.00000000000001739414, -104.89689790453474000000);
+    aWeights.ChangeValue(6, 27) = +1.00967582483410530000;
+    aPoles.ChangeValue(6, 27) = gp_Pnt(-8.16630892272242730000, +0.00000000000001688939, -104.99487618531697000000);
+    aWeights.ChangeValue(6, 28) = +1.00967563195849790000;
+    aPoles.ChangeValue(6, 28) = gp_Pnt(-15.17875958769639600000, +0.00000000000001381871, -104.90172793642448000000);
+    aWeights.ChangeValue(6, 29) = +1.00967503459672230000;
+    aPoles.ChangeValue(6, 29) = gp_Pnt(-22.18399638815323600000, +0.00000000000001119232, -104.61763141615558000000);
+    aWeights.ChangeValue(6, 30) = +1.00967300468446440000;
+    aPoles.ChangeValue(6, 30) = gp_Pnt(-36.16808769247344200000, +0.00000000000001926896, -103.66834538209933000000);
+    aWeights.ChangeValue(6, 31) = +1.00967156777535520000;
+    aPoles.ChangeValue(6, 31) = gp_Pnt(-43.14695215605046700000, +0.00000000000002086710, -103.00315490229345000000);
+    aWeights.ChangeValue(6, 32) = +1.00966969979090850000;
+    aPoles.ChangeValue(6, 32) = gp_Pnt(-50.10664482445217500000, +0.00000000000002115378, -102.14781821392242000000);
+    aWeights.ChangeValue(6, 33) = +1.00966737970297340000;
+    aPoles.ChangeValue(6, 33) = gp_Pnt(-57.04121502398449900000, +0.00000000000002158031, -101.10296070558179000000);
+    aWeights.ChangeValue(6, 34) = +1.00966457365849420000;
+    aPoles.ChangeValue(6, 34) = gp_Pnt(-63.94474533155499800000, +0.00000000000002290082, -99.86943240681669900000);
+    aWeights.ChangeValue(6, 35) = +1.00966123497950670000;
+    aPoles.ChangeValue(6, 35) = gp_Pnt(-70.81135197820185600000, +0.00000000000002517228, -98.44830786498150100000);
+    aWeights.ChangeValue(6, 36) = +1.00965730416314160000;
+    aPoles.ChangeValue(6, 36) = gp_Pnt(-77.63518524225725100000, +0.00000000000002775445, -96.84088598857995600000);
+    aWeights.ChangeValue(6, 37) = +1.00965057624219750000;
+    aPoles.ChangeValue(6, 37) = gp_Pnt(-87.55609990295042200000, +0.00000000000002423047, -94.21659328767886200000);
+    aWeights.ChangeValue(6, 38) = +1.00964829695753600000;
+    aPoles.ChangeValue(6, 38) = gp_Pnt(-90.69129861847109500000, +0.00000000000002587407, -93.34466557470412300000);
+    aWeights.ChangeValue(6, 39) = +1.00964586498085130000;
+    aPoles.ChangeValue(6, 39) = gp_Pnt(-93.81544408055053500000, +0.00000000000003006614, -92.43305897005754400000);
+    aWeights.ChangeValue(6, 40) = +1.00964327207695040000;
+    aPoles.ChangeValue(6, 40) = gp_Pnt(-96.92795589621758300000, +0.00000000000003388207, -91.48193626907418300000);
+    aWeights.ChangeValue(6, 41) = +1.00964050782223150000;
+    aPoles.ChangeValue(6, 41) = gp_Pnt(-100.02825520717420000000, +0.00000000000003564727, -90.49147079864104600000);
+    aWeights.ChangeValue(6, 42) = +1.00963755960468200000;
+    aPoles.ChangeValue(6, 42) = gp_Pnt(-103.11576472135789000000, +0.00000000000003493709, -89.46184640324143800000);
+    aWeights.ChangeValue(6, 43) = +1.00963441262388120000;
+    aPoles.ChangeValue(6, 43) = gp_Pnt(-106.18990874397944000000, +0.00000000000003257692, -88.39325742978746800000);
+    aWeights.ChangeValue(6, 44) = +1.00962747055172470000;
+    aPoles.ChangeValue(6, 44) = gp_Pnt(-112.54574015681582000000, +0.00000000000006160655, -86.09336936272072200000);
+    aWeights.ChangeValue(6, 45) = +1.00962344856191890000;
+    aPoles.ChangeValue(6, 45) = gp_Pnt(-115.82520602454126000000, -0.00000000000003931317, -84.85588414554271700000);
+    aWeights.ChangeValue(6, 46) = +1.00961960432502520000;
+    aPoles.ChangeValue(6, 46) = gp_Pnt(-119.08778487668772000000, +0.00000000000016494845, -83.57368219250022900000);
+    aWeights.ChangeValue(6, 47) = +1.00961486341637220000;
+    aPoles.ChangeValue(6, 47) = gp_Pnt(-122.33277704237545000000, -0.00000000000006102663, -82.24707666574315100000);
+    aWeights.ChangeValue(6, 48) = +1.00961029578642010000;
+    aPoles.ChangeValue(6, 48) = gp_Pnt(-125.55945424028559000000, +0.00000000000005443726, -80.87630621413205700000);
+    aWeights.ChangeValue(6, 49) = +1.00960520453872830000;
+    aPoles.ChangeValue(6, 49) = gp_Pnt(-128.76711471386264000000, +0.00000000000006731284, -79.46169679871513800000);
+    aWeights.ChangeValue(6, 50) = +1.00959965618806670000;
+    aPoles.ChangeValue(6, 50) = gp_Pnt(-131.95505034236234000000, +0.00000000000001744703, -78.00355594499717400000);
+    aWeights.ChangeValue(6, 51) = +1.00958841592259230000;
+    aPoles.ChangeValue(6, 51) = gp_Pnt(-138.06383173526737000000, +0.00000000000005091738, -75.10807262033468100000);
+    aWeights.ChangeValue(6, 52) = +1.00958190609477040000;
+    aPoles.ChangeValue(6, 52) = gp_Pnt(-140.98751167669514000000, +0.00000000000001249767, -73.67671445695528100000);
+    aWeights.ChangeValue(6, 53) = +1.00957719226123470000;
+    aPoles.ChangeValue(6, 53) = gp_Pnt(-143.89297197091258000000, +0.00000000000004304958, -72.20827197874005800000);
+    aWeights.ChangeValue(6, 54) = +1.00956830736954160000;
+    aPoles.ChangeValue(6, 54) = gp_Pnt(-146.77976177895343000000, +0.00000000000014315600, -70.70325097869228200000);
+    aWeights.ChangeValue(6, 55) = +1.00956295195680430000;
+    aPoles.ChangeValue(6, 55) = gp_Pnt(-149.64716302220674000000, -0.00000000000013374459, -69.16163316263994400000);
+    aWeights.ChangeValue(6, 56) = +1.00955425555763600000;
+    aPoles.ChangeValue(6, 56) = gp_Pnt(-152.49476001470052000000, +0.00000000000014982315, -67.58397318476696100000);
+    aWeights.ChangeValue(6, 57) = +1.00954602613024340000;
+    aPoles.ChangeValue(6, 57) = gp_Pnt(-155.32190503332637000000, -0.00000000000000021066, -65.97043121899140800000);
+    aWeights.ChangeValue(6, 58) = +1.00952742278739690000;
+    aPoles.ChangeValue(6, 58) = gp_Pnt(-161.15007234465017000000, -0.00000000000001992904, -62.54527347940126700000);
+    aWeights.ChangeValue(6, 59) = +1.00951486183122910000;
+    aPoles.ChangeValue(6, 59) = gp_Pnt(-164.14837014605524000000, +0.00000000000023572067, -60.72896647597298900000);
+    aWeights.ChangeValue(6, 60) = +1.00950821186278380000;
+    aPoles.ChangeValue(6, 60) = gp_Pnt(-167.11960531963629000000, -0.00000000000028988207, -58.86870049528032900000);
+    aWeights.ChangeValue(6, 61) = +1.00948761363721440000;
+    aPoles.ChangeValue(6, 61) = gp_Pnt(-170.06906478280905000000, +0.00000000000040689923, -56.97372124744497800000);
+    aWeights.ChangeValue(6, 62) = +1.00948175483910860000;
+    aPoles.ChangeValue(6, 62) = gp_Pnt(-172.98765254825670000000, -0.00000000000024250881, -55.03312548926784600000);
+    aWeights.ChangeValue(6, 63) = +1.00946082358368820000;
+    aPoles.ChangeValue(6, 63) = gp_Pnt(-175.88148729884773000000, +0.00000000000015443744, -53.05496328096450000000);
+    aWeights.ChangeValue(6, 64) = +1.00944596410276510000;
+    aPoles.ChangeValue(6, 64) = gp_Pnt(-178.74719668858941000000, +0.00000000000002184305, -51.03719587787818300000);
+    aWeights.ChangeValue(6, 65) = +1.00942605045267690000;
+    aPoles.ChangeValue(6, 65) = gp_Pnt(-181.58512029181043000000, +0.00000000000003863576, -48.98084041218928800000);
+    aWeights.ChangeValue(6, 66) = +1.00940832657292460000;
+    aPoles.ChangeValue(6, 66) = gp_Pnt(-184.22041885135505000000, +0.00000000000012642202, -47.07128183802177500000);
+    aWeights.ChangeValue(6, 67) = +1.00938358350016230000;
+    aPoles.ChangeValue(6, 67) = gp_Pnt(-186.83172267077580000000, -0.00000000000026075896, -45.12863792869809700000);
+    aWeights.ChangeValue(6, 68) = +1.00937745534316470000;
+    aPoles.ChangeValue(6, 68) = gp_Pnt(-189.41814135962036000000, +0.00000000000050815389, -43.15221363464823400000);
+    aWeights.ChangeValue(6, 69) = +1.00932110415609880000;
+    aPoles.ChangeValue(6, 69) = gp_Pnt(-191.98049421722968000000, -0.00000000000036869153, -41.14519558079494000000);
+    aWeights.ChangeValue(6, 70) = +1.00934018958992230000;
+    aPoles.ChangeValue(6, 70) = gp_Pnt(-194.51554398045388000000, +0.00000000000024701945, -39.10283303403318900000);
+    aWeights.ChangeValue(6, 71) = +1.00926513417534820000;
+    aPoles.ChangeValue(6, 71) = gp_Pnt(-197.02654362639632000000, +0.00000000000002378284, -37.03182458375535900000);
+    aWeights.ChangeValue(6, 72) = +1.00924284324015100000;
+    aPoles.ChangeValue(6, 72) = gp_Pnt(-199.50902604112426000000, +0.00000000000001468063, -34.92696457232537500000);
+    aWeights.ChangeValue(6, 73) = +1.00920104311988210000;
+    aPoles.ChangeValue(6, 73) = gp_Pnt(-201.96417476016930000000, +0.00000000000004485301, -32.79087292323346500000);
+    aWeights.ChangeValue(6, 74) = +1.00917029694376930000;
+    aPoles.ChangeValue(6, 74) = gp_Pnt(-204.41947086956830000000, +0.00000000000007013856, -30.65436716589900700000);
+    aWeights.ChangeValue(6, 75) = +1.00906597799622610000;
+    aPoles.ChangeValue(6, 75) = gp_Pnt(-206.84718146821811000000, -0.00000000000006381675, -28.48746943619916600000);
+    aWeights.ChangeValue(6, 76) = +1.00920552993238920000;
+    aPoles.ChangeValue(6, 76) = gp_Pnt(-209.24487385523256000000, +0.00000000000020688933, -26.28443183778934900000);
+    aWeights.ChangeValue(6, 77) = +1.00876475817276390000;
+    aPoles.ChangeValue(6, 77) = gp_Pnt(-211.61934752962611000000, -0.00000000000012087895, -24.05869960942788700000);
+    aWeights.ChangeValue(6, 78) = +1.00888387250480620000;
+    aPoles.ChangeValue(6, 78) = gp_Pnt(-213.96155431166437000000, +0.00000000000019025578, -21.80066237623914200000);
+    aWeights.ChangeValue(6, 79) = +1.00881670070678450000;
+    aPoles.ChangeValue(6, 79) = gp_Pnt(-216.26151615033589000000, -0.00000000000009572292, -19.49741392382435400000);
+    aWeights.ChangeValue(6, 80) = +1.00875338528797620000;
+    aPoles.ChangeValue(6, 80) = gp_Pnt(-218.54531424806936000000, +0.00000000000008182630, -17.17704407009146500000);
+    aWeights.ChangeValue(6, 81) = +1.00842683370719580000;
+    aPoles.ChangeValue(6, 81) = gp_Pnt(-220.79435406720884000000, +0.00000000000004973799, -14.82789528118522200000);
+    aWeights.ChangeValue(7, 1) = +1.02986327036737910000;
+    aPoles.ChangeValue(7, 1) = gp_Pnt(+133.20307692191452000000, -0.00000000000000177636, -68.87095947031473000000);
+    aWeights.ChangeValue(7, 2) = +1.02989244478762340000;
+    aPoles.ChangeValue(7, 2) = gp_Pnt(+130.12738123407763000000, -0.00000000000000516390, -70.57040146390383500000);
+    aWeights.ChangeValue(7, 3) = +1.02991676091110000000;
+    aPoles.ChangeValue(7, 3) = gp_Pnt(+127.02840986317391000000, +0.00000000000000554535, -72.22789464235242500000);
+    aWeights.ChangeValue(7, 4) = +1.02993613450137910000;
+    aPoles.ChangeValue(7, 4) = gp_Pnt(+123.90694758506712000000, -0.00000000000000702621, -73.84302715009133100000);
+    aWeights.ChangeValue(7, 5) = +1.02995970896171030000;
+    aPoles.ChangeValue(7, 5) = gp_Pnt(+120.76360256847768000000, -0.00000000000000047370, -75.41549467632542300000);
+    aWeights.ChangeValue(7, 6) = +1.02998196300924330000;
+    aPoles.ChangeValue(7, 6) = gp_Pnt(+117.59908279457284000000, +0.00000000000000772901, -76.94495426059752700000);
+    aWeights.ChangeValue(7, 7) = +1.02999781361776170000;
+    aPoles.ChangeValue(7, 7) = gp_Pnt(+114.41407453952652000000, -0.00000000000000327310, -78.43108601253017300000);
+    aWeights.ChangeValue(7, 8) = +1.03001626830282000000;
+    aPoles.ChangeValue(7, 8) = gp_Pnt(+111.20931631680004000000, +0.00000000000000421483, -79.87356087705671800000);
+    aWeights.ChangeValue(7, 9) = +1.03004822145821140000;
+    aPoles.ChangeValue(7, 9) = gp_Pnt(+104.76172782897289000000, +0.00000000000000259283, -82.67059011797552200000);
+    aWeights.ChangeValue(7, 10) = +1.03006364818919470000;
+    aPoles.ChangeValue(7, 10) = gp_Pnt(+101.51889932580750000000, +0.00000000000000793496, -84.02514647707548100000);
+    aWeights.ChangeValue(7, 11) = +1.03007725635610380000;
+    aPoles.ChangeValue(7, 11) = gp_Pnt(+98.25768758130365700000, +0.00000000000000127608, -85.33546669488836800000);
+    aWeights.ChangeValue(7, 12) = +1.03009045031501540000;
+    aPoles.ChangeValue(7, 12) = gp_Pnt(+94.97880175952953200000, +0.00000000000000289709, -86.60126064632369500000);
+    aWeights.ChangeValue(7, 13) = +1.03010285398165520000;
+    aPoles.ChangeValue(7, 13) = gp_Pnt(+91.68295682468645700000, +0.00000000000000548904, -87.82224920548925700000);
+    aWeights.ChangeValue(7, 14) = +1.03011393120368040000;
+    aPoles.ChangeValue(7, 14) = gp_Pnt(+88.37086140882031800000, -0.00000000000000004450, -88.99816853898946100000);
+    aWeights.ChangeValue(7, 15) = +1.03012484065781210000;
+    aPoles.ChangeValue(7, 15) = gp_Pnt(+85.04324466385365600000, +0.00000000000000407116, -90.12875955698966400000);
+    aWeights.ChangeValue(7, 16) = +1.03015471267321310000;
+    aPoles.ChangeValue(7, 16) = gp_Pnt(+75.01621211174902700000, +0.00000000000001208092, -93.38380423550353300000);
+    aWeights.ChangeValue(7, 17) = +1.03017194800922480000;
+    aPoles.ChangeValue(7, 17) = gp_Pnt(+68.27251352067813200000, +0.00000000000001147779, -95.37146758037383200000);
+    aWeights.ChangeValue(7, 18) = +1.03018680682765580000;
+    aPoles.ChangeValue(7, 18) = gp_Pnt(+61.47507566136914600000, +0.00000000000000851456, -97.17487791831784700000);
+    aWeights.ChangeValue(7, 19) = +1.03019958109549560000;
+    aPoles.ChangeValue(7, 19) = gp_Pnt(+54.62953031922813800000, +0.00000000000000645560, -98.79238303220959900000);
+    aWeights.ChangeValue(7, 20) = +1.03021050389503310000;
+    aPoles.ChangeValue(7, 20) = gp_Pnt(+47.74179355100338300000, +0.00000000000000683493, -100.22257163394704000000);
+    aWeights.ChangeValue(7, 21) = +1.03021974942385920000;
+    aPoles.ChangeValue(7, 21) = gp_Pnt(+40.81806392732334400000, +0.00000000000000945638, -101.46427420633951000000);
+    aWeights.ChangeValue(7, 22) = +1.03022743299486530000;
+    aPoles.ChangeValue(7, 22) = gp_Pnt(+33.86482072309787100000, +0.00000000000001239365, -102.51656369616552000000);
+    aWeights.ChangeValue(7, 23) = +1.03023979631718960000;
+    aPoles.ChangeValue(7, 23) = gp_Pnt(+19.91267581058432200000, +0.00000000000001269021, -104.24092170462040000000);
+    aWeights.ChangeValue(7, 24) = +1.03024450452679180000;
+    aPoles.ChangeValue(7, 24) = gp_Pnt(+12.91322103073442500000, +0.00000000000001310657, -104.91296575233191000000);
+    aWeights.ChangeValue(7, 25) = +1.03024781840890150000;
+    aPoles.ChangeValue(7, 25) = gp_Pnt(+5.89663552968925500000, +0.00000000000001362222, -105.39416639705574000000);
+    aWeights.ChangeValue(7, 26) = +1.03024979501191980000;
+    aPoles.ChangeValue(7, 26) = gp_Pnt(-1.13093554742009240000, +0.00000000000001442955, -105.68402704533355000000);
+    aWeights.ChangeValue(7, 27) = +1.03025046568879810000;
+    aPoles.ChangeValue(7, 27) = gp_Pnt(-8.16338049757019310000, +0.00000000000001553070, -105.78227646648484000000);
+    aWeights.ChangeValue(7, 28) = +1.03024983609703620000;
+    aPoles.ChangeValue(7, 28) = gp_Pnt(-15.19462185431612500000, +0.00000000000001673746, -105.68886888131540000000);
+    aWeights.ChangeValue(7, 29) = +1.03024788619868390000;
+    aPoles.ChangeValue(7, 29) = gp_Pnt(-22.21861718693262200000, +0.00000000000001767135, -105.40398398356824000000);
+    aWeights.ChangeValue(7, 30) = +1.03024126030624560000;
+    aPoles.ChangeValue(7, 30) = gp_Pnt(-36.24014829916134100000, +0.00000000000002019891, -104.45206611492652000000);
+    aWeights.ChangeValue(7, 31) = +1.03023657011944200000;
+    aPoles.ChangeValue(7, 31) = gp_Pnt(-43.23771519136024500000, +0.00000000000002161068, -103.78502949380328000000);
+    aWeights.ChangeValue(7, 32) = +1.03023047292900840000;
+    aPoles.ChangeValue(7, 32) = gp_Pnt(-50.21605719916001900000, +0.00000000000002249329, -102.92731708926736000000);
+    aWeights.ChangeValue(7, 33) = +1.03022290017099440000;
+    aPoles.ChangeValue(7, 33) = gp_Pnt(-57.16920057960702200000, +0.00000000000002320995, -101.87955571848956000000);
+    aWeights.ChangeValue(7, 34) = +1.03021374148842140000;
+    aPoles.ChangeValue(7, 34) = gp_Pnt(-64.09120253994868200000, +0.00000000000002399266, -100.64259867222304000000);
+    aWeights.ChangeValue(7, 35) = +1.03020284473128120000;
+    aPoles.ChangeValue(7, 35) = gp_Pnt(-70.97615252947152000000, +0.00000000000002494226, -99.21752532044712300000);
+    aWeights.ChangeValue(7, 36) = +1.03019001595653670000;
+    aPoles.ChangeValue(7, 36) = gp_Pnt(-77.81817349811507300000, +0.00000000000002602838, -97.60564061068184600000);
+    aWeights.ChangeValue(7, 37) = +1.03016805964614980000;
+    aPoles.ChangeValue(7, 37) = gp_Pnt(-87.76549855749630100000, +0.00000000000002703745, -94.97405836608523100000);
+    aWeights.ChangeValue(7, 38) = +1.03016062145972500000;
+    aPoles.ChangeValue(7, 38) = gp_Pnt(-90.90906843451735100000, +0.00000000000002735353, -94.09969925934423400000);
+    aWeights.ChangeValue(7, 39) = +1.03015268516758060000;
+    aPoles.ChangeValue(7, 39) = gp_Pnt(-94.04154842308000200000, +0.00000000000002795160, -93.18554984223239000000);
+    aWeights.ChangeValue(7, 40) = +1.03014422393874510000;
+    aPoles.ChangeValue(7, 40) = gp_Pnt(-97.16235536263198500000, +0.00000000000002873660, -92.23177350871787900000);
+    aWeights.ChangeValue(7, 41) = +1.03013520381253840000;
+    aPoles.ChangeValue(7, 41) = gp_Pnt(-100.27090735629974000000, +0.00000000000002960449, -91.23854430518403500000);
+    aWeights.ChangeValue(7, 42) = +1.03012558369857450000;
+    aPoles.ChangeValue(7, 42) = gp_Pnt(-103.36662387191370000000, +0.00000000000003044224, -90.20604688574815100000);
+    aWeights.ChangeValue(7, 43) = +1.03011531537676040000;
+    aPoles.ChangeValue(7, 43) = gp_Pnt(-106.44892584135401000000, +0.00000000000003112785, -89.13447646370049400000);
+    aWeights.ChangeValue(7, 44) = +1.03009266486582220000;
+    aPoles.ChangeValue(7, 44) = gp_Pnt(-112.82164316087234000000, +0.00000000000002877514, -86.82815610446842000000);
+    aWeights.ChangeValue(7, 45) = +1.03007954250937140000;
+    aPoles.ChangeValue(7, 45) = gp_Pnt(-116.10982863064515000000, +0.00000000000005217709, -85.58719260568324200000);
+    aWeights.ChangeValue(7, 46) = +1.03006700046765860000;
+    aPoles.ChangeValue(7, 46) = gp_Pnt(-119.38108228759732000000, -0.00000000000000364635, -84.30140001571530200000);
+    aWeights.ChangeValue(7, 47) = +1.03005153385603830000;
+    aPoles.ChangeValue(7, 47) = gp_Pnt(-122.63466837574235000000, +0.00000000000007773224, -82.97105629274108200000);
+    aWeights.ChangeValue(7, 48) = +1.03003663316235050000;
+    aPoles.ChangeValue(7, 48) = gp_Pnt(-125.86988610286646000000, +0.00000000000000501775, -81.59643931580511400000);
+    aWeights.ChangeValue(7, 49) = +1.03002002524069390000;
+    aPoles.ChangeValue(7, 49) = gp_Pnt(-129.08600965998806000000, +0.00000000000004872530, -80.17785297868806500000);
+    aWeights.ChangeValue(7, 50) = +1.03000192732158440000;
+    aPoles.ChangeValue(7, 50) = gp_Pnt(-132.28232849510800000000, +0.00000000000003627431, -78.71561001568775900000);
+    aWeights.ChangeValue(7, 51) = +1.02996526567106140000;
+    aPoles.ChangeValue(7, 51) = gp_Pnt(-138.40719443250111000000, +0.00000000000004030865, -75.81195871455292900000);
+    aWeights.ChangeValue(7, 52) = +1.02994403451619650000;
+    aPoles.ChangeValue(7, 52) = gp_Pnt(-141.33856968181306000000, +0.00000000000003444592, -74.37651555974527200000);
+    aWeights.ChangeValue(7, 53) = +1.02992866105480000000;
+    aPoles.ChangeValue(7, 53) = gp_Pnt(-144.25171811139330000000, +0.00000000000003429445, -72.90395453557894700000);
+    aWeights.ChangeValue(7, 54) = +1.02989968743351530000;
+    aPoles.ChangeValue(7, 54) = gp_Pnt(-147.14603336223070000000, +0.00000000000004355038, -71.39457006641885100000);
+    aWeights.ChangeValue(7, 55) = +1.02988222474475720000;
+    aPoles.ChangeValue(7, 55) = gp_Pnt(-150.02095857157173000000, +0.00000000000003217269, -69.84863841933133700000);
+    aWeights.ChangeValue(7, 56) = +1.02985386954430420000;
+    aPoles.ChangeValue(7, 56) = gp_Pnt(-152.87595706513403000000, +0.00000000000003648661, -68.26644064265008200000);
+    aWeights.ChangeValue(7, 57) = +1.02982704006085530000;
+    aPoles.ChangeValue(7, 57) = gp_Pnt(-155.71041601974636000000, +0.00000000000003591181, -66.64830754728993200000);
+    aWeights.ChangeValue(7, 58) = +1.02976639514271140000;
+    aPoles.ChangeValue(7, 58) = gp_Pnt(-161.55369960091491000000, +0.00000000000003646415, -63.21332070345936700000);
+    aWeights.ChangeValue(7, 59) = +1.02972545417744080000;
+    aPoles.ChangeValue(7, 59) = gp_Pnt(-164.55974256681068000000, +0.00000000000003294676, -61.39167299907511900000);
+    aWeights.ChangeValue(7, 60) = +1.02970377642180270000;
+    aPoles.ChangeValue(7, 60) = gp_Pnt(-167.53873683551103000000, +0.00000000000002190344, -59.52621075357659900000);
+    aWeights.ChangeValue(7, 61) = +1.02963665582099750000;
+    aPoles.ChangeValue(7, 61) = gp_Pnt(-170.49570646978711000000, +0.00000000000009010479, -57.62531748377598000000);
+    aWeights.ChangeValue(7, 62) = +1.02961756328110620000;
+    aPoles.ChangeValue(7, 62) = gp_Pnt(-173.42176702363508000000, -0.00000000000003499440, -55.67944052993496500000);
+    aWeights.ChangeValue(7, 63) = +1.02954937293567860000;
+    aPoles.ChangeValue(7, 63) = gp_Pnt(-176.32284460610933000000, +0.00000000000007636921, -53.69521656711459900000);
+    aWeights.ChangeValue(7, 64) = +1.02950097342681770000;
+    aPoles.ChangeValue(7, 64) = gp_Pnt(-179.19569709355173000000, +0.00000000000003273955, -51.67161593723249500000);
+    aWeights.ChangeValue(7, 65) = +1.02943612532291810000;
+    aPoles.ChangeValue(7, 65) = gp_Pnt(-182.04053139917158000000, +0.00000000000003996803, -49.60917258111981500000);
+    aWeights.ChangeValue(7, 66) = +1.02937840445762090000;
+    aPoles.ChangeValue(7, 66) = gp_Pnt(-184.68250151172640000000, +0.00000000000004112926, -47.69381589112448700000);
+    aWeights.ChangeValue(7, 67) = +1.02929786839945800000;
+    aPoles.ChangeValue(7, 67) = gp_Pnt(-187.30004443981446000000, +0.00000000000003629801, -45.74517623046489900000);
+    aWeights.ChangeValue(7, 68) = +1.02927785532615720000;
+    aPoles.ChangeValue(7, 68) = gp_Pnt(-189.89358418563035000000, +0.00000000000003708012, -43.76295173174737800000);
+    aWeights.ChangeValue(7, 69) = +1.02909457173661250000;
+    aPoles.ChangeValue(7, 69) = gp_Pnt(-192.46070903458983000000, +0.00000000000005500515, -41.74904085552218200000);
+    aWeights.ChangeValue(7, 70) = +1.02915656102268340000;
+    aPoles.ChangeValue(7, 70) = gp_Pnt(-195.00353322314638000000, +0.00000000000002645256, -39.70148425813464900000);
+    aWeights.ChangeValue(7, 71) = +1.02891246604057510000;
+    aPoles.ChangeValue(7, 71) = gp_Pnt(-197.51895024482548000000, +0.00000000000005006422, -37.62251287581096900000);
+    aWeights.ChangeValue(7, 72) = +1.02884001996279940000;
+    aPoles.ChangeValue(7, 72) = gp_Pnt(-200.00717902020989000000, +0.00000000000003866246, -35.51147139839754600000);
+    aWeights.ChangeValue(7, 73) = +1.02870418206103280000;
+    aPoles.ChangeValue(7, 73) = gp_Pnt(-202.46745722827831000000, +0.00000000000003996803, -33.36845405838467800000);
+    aWeights.ChangeValue(7, 74) = +1.02860417892808040000;
+    aPoles.ChangeValue(7, 74) = gp_Pnt(-204.92874075079348000000, +0.00000000000003952569, -31.22492832365916000000);
+    aWeights.ChangeValue(7, 75) = +1.02826579045574770000;
+    aPoles.ChangeValue(7, 75) = gp_Pnt(-207.35951843182116000000, +0.00000000000002864861, -29.04902036970887700000);
+    aWeights.ChangeValue(7, 76) = +1.02871793966685040000;
+    aPoles.ChangeValue(7, 76) = gp_Pnt(-209.76815931164757000000, +0.00000000000007786791, -26.84449461829588300000);
+    aWeights.ChangeValue(7, 77) = +1.02728787827248790000;
+    aPoles.ChangeValue(7, 77) = gp_Pnt(-212.13952611955784000000, -0.00000000000002645359, -24.59453985262025100000);
+    aWeights.ChangeValue(7, 78) = +1.02767535385751650000;
+    aPoles.ChangeValue(7, 78) = gp_Pnt(-214.48523983715771000000, +0.00000000000011316462, -22.34028621398329100000);
+    aWeights.ChangeValue(7, 79) = +1.02745809923196680000;
+    aPoles.ChangeValue(7, 79) = gp_Pnt(-216.79261871005519000000, -0.00000000000002978790, -20.02558452892611700000);
+    aWeights.ChangeValue(7, 80) = +1.02725110106353260000;
+    aPoles.ChangeValue(7, 80) = gp_Pnt(-219.08116944862113000000, +0.00000000000005732296, -17.69632354506026700000);
+    aWeights.ChangeValue(7, 81) = +1.02619749797986360000;
+    aPoles.ChangeValue(7, 81) = gp_Pnt(-221.32510969435936000000, +0.00000000000004618528, -15.33078661161192400000);
+  }
+  ////
+
+  const Handle(Geom_Surface) aS1 = new Geom_BSplineSurface(aPoles, aWeights, aUKnots, aVKnots, aUMult, aVMult, aUDegree, aVDegree);
+
+  char buff[1024];
+
+  Sprintf(buff, "%s_1", theArgVal[1]);
+  DrawTrSurf::Set(buff, aS1);
+  theDI << buff << " ";
+
+  Sprintf(buff, "%s_2", theArgVal[1]);
+  DrawTrSurf::Set(buff, aS2);
+  theDI << buff << "\n";
+
+  return 0;
+}
+
+namespace AllocTest
+{
+  // The test is based of occupying of all available virtual memory.
+  // Obviously it has no sense on 64-bit platforms.
+
+  enum AllocTestStatus
+  {
+    NotApplicable = 0x1,
+    OUMCatchOK    = 0x2,
+    OUMCatchFail  = 0x4
+  };
+
+  template<int> int test()
+  {
+    // non-32-bit implementation
+    return NotApplicable;
+  }
+  
+  template<> int test<4>()
+  {
+    // 32-bit implementation
+    NCollection_List<Standard_Address> aList;
+    const Standard_Integer aBlockSizes[] = {100000, 10000, 10};
+    int aStatus = 0;
+
+    // start populate memory with blocks of large size, then
+    // smaller ones and so on according to content of the array aBlockSizes
+    for (size_t i=0; i < sizeof(aBlockSizes)/sizeof(int); i++)
+    {
+      try
+      {
+        for (;;)
+          aList.Append(Standard::Allocate(aBlockSizes[i]));
+      }
+      catch (Standard_Failure)
+      {
+        aStatus |= OUMCatchOK;
+      }
+      catch (...)
+      {
+        aStatus |= OUMCatchFail;
+        break;
+      }
+    }
+    // release all allocated blocks
+    for (NCollection_List<Standard_Address>::Iterator it(aList); it.More(); it.Next())
+    {
+      Standard::Free(it.Value());
+    }
+    return aStatus;
+  }
+}
+
+//=======================================================================
+//function : OCC24836
+//purpose :
+//=======================================================================
+static Standard_Integer OCC24836 (Draw_Interpretor& theDI, Standard_Integer n, const char** a)
+{
+  if (n != 1)
+  {
+    theDI << "Usage : " << a[0] << "\n";
+    return 1;
+  }
+
+  int aStatus = AllocTest::test<sizeof(size_t)>();
+
+  if (aStatus & AllocTest::NotApplicable)
+    theDI << "This test case is not applicable for 64-bit and higher platforms\n";
+  if (aStatus & AllocTest::OUMCatchOK)
+    theDI << "out-of-memory has been caught: OK\n";
+  if (aStatus & AllocTest::OUMCatchFail)
+    theDI << "Error: out-of-memory is not always caught\n";
+  return 0;
+}
+
+
+//=======================================================================
+//function : OCC27021 
+//purpose  : Tests performance of obtaining geometry (points) via topological
+//           exploring or fetching the geometry.
+//=======================================================================
+
+// Fetch via topology
+static std::pair<gp_Pnt, gp_Pnt> getVerticesA(const TopoDS_Edge& theEdge)
+{
+  std::pair<gp_Pnt, gp_Pnt> result;
+
+  static TopoDS_Vertex aFirst, aLast;
+  TopExp::Vertices(theEdge, aFirst, aLast, Standard_True);
+
+  result.first = BRep_Tool::Pnt(aFirst);
+  result.second = BRep_Tool::Pnt(aLast);
+
+  return result;
+}
+
+//Geometrical way
+static std::pair<gp_Pnt, gp_Pnt> getVerticesB(const TopoDS_Edge& theEdge)
+{
+  Standard_Real first;
+  Standard_Real last;
+
+  Handle(Geom_Curve) curve = BRep_Tool::Curve(theEdge, first, last);
+
+  std::pair<gp_Pnt, gp_Pnt> result;
+
+  if (theEdge.Orientation() == TopAbs_REVERSED)
+  {
+    curve->D0(first, result.second);
+    curve->D0(last, result.first);
+  }
+  else
+  {
+    curve->D0(first, result.first);
+    curve->D0(last, result.second);
+  }
+  return result;
+}
+
+
+
+static Standard_Integer OCC27021(Draw_Interpretor& theDI,
+                                 Standard_Integer  theNArg,
+                                 const char ** theArgVal)
+{
+  if (theNArg != 2)
+  {
+    cout << "Use: " << theArgVal[0] << " shape" << endl;
+    return 1;
+  }
+
+  TopoDS_Shape shape (DBRep::Get(theArgVal[1]));
+
+  TopTools_IndexedMapOfShape shape_faces;
+  TopExp::MapShapes(shape, TopAbs_FACE, shape_faces);
+
+  // Pick a single face which shows the problem.
+  TopoDS_Face face = TopoDS::Face(shape_faces(10));
+  TopTools_IndexedMapOfShape face_edges;
+  TopExp::MapShapes(face, TopAbs_EDGE, face_edges);
+  TopoDS_Edge edge = TopoDS::Edge(face_edges(2));
+
+  Standard_Integer iterations = 100000000;
+
+  std::pair<gp_Pnt, gp_Pnt> vertices;
+  clock_t t = clock();
+
+  theDI << "\nRetrieving " << iterations << " vertices using approach A)...";
+  for (int i = 0; i < iterations; ++i)
+  {
+    vertices = getVerticesA(edge);
+  }
+  theDI << "done in " << (clock() - t) / (double)CLOCKS_PER_SEC << " seconds\n";
+  t = clock();
+
+  theDI << "\nRetrieving " << iterations << " vertices using approach B)...";
+  for (int i = 0; i < iterations; ++i)
+  {
+    vertices = getVerticesB(edge);
+  }
+  theDI << "done in " << (clock() - t) / (double)CLOCKS_PER_SEC << " seconds\n";
+
+  return 0;
+}
+
+//=======================================================================
+//function : OCC27235
+//purpose : check presentation in GDT document
+//=======================================================================
+static Standard_Integer OCC27235 (Draw_Interpretor& theDI, Standard_Integer n, const char** a)
+{
+  if (n < 2) {
+    theDI<<"Use: OCC27235 Doc";
+    return 1;
+  }
+
+  Handle(TDocStd_Document) Doc;
+  DDocStd::GetDocument(a[1], Doc);
+  if ( Doc.IsNull() ) { theDI << a[1] << " is not a document\n"; return 1; }
+  Handle(XCAFDoc_DimTolTool) aDimTolTool= XCAFDoc_DocumentTool::DimTolTool(Doc->Main());
+  Handle(XCAFDoc_ShapeTool) aShapeTool= XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
+  TopoDS_Compound aPresentations;
+  BRep_Builder B;
+  B.MakeCompound(aPresentations);
+
+  TDF_LabelSequence aLabels;
+  aShapeTool->GetShapes(aLabels);
+  for ( Standard_Integer i=1; i <= aLabels.Length(); i++ )
+  {
+    aShapeTool->GetSubShapes(aLabels.Value(i), aLabels);
+  }
+
+  TDF_LabelSequence aGDTs;
+  aDimTolTool->GetDimensionLabels(aGDTs);
+  for (Standard_Integer i = 1; i <= aGDTs.Length(); i++) {
+    Handle(XCAFDoc_Dimension) aDimAttr;
+    if (!aGDTs.Value(i).FindAttribute(XCAFDoc_Dimension::GetID(),aDimAttr)) 
+      continue;
+    Handle(XCAFDimTolObjects_DimensionObject) anObject = aDimAttr->GetObject();
+    if (anObject.IsNull())
+      continue;
+    TopoDS_Shape aShape = anObject->GetPresentation();
+    if (!aShape.IsNull())
+      B.Add(aPresentations, aShape);
+  }
+
+  aGDTs.Clear();
+  aDimTolTool->GetGeomToleranceLabels(aGDTs);
+  for (Standard_Integer i = 1; i <= aGDTs.Length(); i++) {
+    Handle(XCAFDoc_GeomTolerance) aGTAttr;
+    if (!aGDTs.Value(i).FindAttribute(XCAFDoc_GeomTolerance::GetID(),aGTAttr)) 
+      continue;
+    Handle(XCAFDimTolObjects_GeomToleranceObject) anObject = aGTAttr->GetObject();
+    if (anObject.IsNull())
+      continue;
+    TopoDS_Shape aShape = anObject->GetPresentation();
+    if (!aShape.IsNull())
+      B.Add(aPresentations, aShape);
+  }
+
+  for ( Standard_Integer i=1; i <= aLabels.Length(); i++ )
+  {
+    TDF_LabelSequence aDatL;
+    if(aDimTolTool->GetRefDatumLabel(aLabels.Value(i), aDatL))
+    {
+      for(Standard_Integer j = aDatL.Lower(); j <= aDatL.Upper(); j++)
+      {
+        Handle(XCAFDoc_Datum) aDat;
+        if(!aDatL.Value(j).FindAttribute(XCAFDoc_Datum::GetID(), aDat))
+          continue;
+        Handle(XCAFDimTolObjects_DatumObject) anObject = aDat->GetObject();
+        if (anObject.IsNull())
+          continue;
+        TopoDS_Shape aShape = anObject->GetPresentation();
+        if (!aShape.IsNull())
+          B.Add(aPresentations, aShape);
+      }
+    }
+  }
+
+  GProp_GProps aG;
+  BRepGProp::LinearProperties(aPresentations, aG);
+  gp_Pnt aPnt = aG.CentreOfMass();
+  theDI << "Centre of mass: " << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
+  theDI << "Mass: " << aG.Mass() << "\n";
+
+  return 0;
+}
+
+//=======================================================================
+//function : OCC24836
+//purpose :
+//=======================================================================
+static Standard_Integer OCC26930(Draw_Interpretor& theDI,
+                                 Standard_Integer  theNArg,
+                                 const char ** theArgVal)
+{
+  if (theNArg != 5)
+  {
+    cout << "Use: " << theArgVal[0] <<" surface curve start end" << endl;
+    return 1;
+  }
+
+
+
+
+
+  Handle(Geom_Surface) aSurface = DrawTrSurf::GetSurface(theArgVal[1]);
+  Handle(Geom_Curve) aCurve = DrawTrSurf::GetCurve(theArgVal[2]);
+  Standard_Real aStart = Draw::Atof(theArgVal[3]);
+  Standard_Real anEnd = Draw::Atof(theArgVal[4]);
+
+  //project
+  Handle (Geom2d_Curve) aPCurve;
+
+  ShapeConstruct_ProjectCurveOnSurface aProj;
+  aProj.Init(aSurface, Precision::Confusion());
+  {
+    try {
+        Handle (Geom_Curve) aTmpCurve = aCurve; //to use reference in Perform()
+        aProj.Perform (aTmpCurve, aStart, anEnd, aPCurve);
+    } catch (const Standard_Failure&) {
+    }
+  }
+
+  //check results
+  if (aPCurve.IsNull()) {
+    theDI << "Error: pcurve is null\n";
+  }
+  else {
+    if (aPCurve->IsKind(STANDARD_TYPE(Geom2d_Line))) {
+      theDI << "Pcurve is line: OK\n";
+    }
+    else {
+      theDI << "Error: PCurve is not line\n";
+    }
+  }
+
+  return 0;
+}
+
+//=======================================================================
+//function : OCC27341
+//purpose : check exact HLR algorighm's work
+//=======================================================================
+static Standard_Integer OCC27341 (Draw_Interpretor& , Standard_Integer n, const char** a)
+{
+  if (n != 4)
+  {
+    cout << "Use: OCC27341 res shape axo/top/bottom/front/back/left/right" << endl;
+    return 1;
+  }
+
+  TopoDS_Shape aShape =  DBRep::Get(a[2]);
+  if (aShape.IsNull())
+    return 1;
+
+  gp_Pnt anOrigin(0.,0.,0.);
+  gp_Dir aNormal(0.57735026918962573, -0.57735026918962573, 0.57735026918962573);
+  gp_Ax2 anAxes(anOrigin, aNormal);
+  gp_Dir aDX = anAxes.XDirection();
+  
+  HLRAppli_ReflectLines Reflector(aShape);
+
+  if (strcmp(a[3],"axo") == 0)
+  {
+    aNormal.SetCoord(0.57735026918962573, -0.57735026918962573, 0.57735026918962573);
+    aDX.SetCoord(-0.40824829046386307, 0.40824829046386307, 0.81649658092772615);
+  }
+  else if (strcmp(a[3],"top") == 0)
+  {
+    aNormal.SetCoord(0,0,1);
+    aDX.SetCoord(0,1,0);
+  }
+  else if (strcmp(a[3],"bottom") == 0)
+  {
+    aNormal.SetCoord(0,0,-1);
+    aDX.SetCoord(0,-1,0);
+  }
+  else if (strcmp(a[3],"front") == 0)
+  {
+    aNormal.SetCoord(0,-1,0);
+    aDX.SetCoord(0,0,1);
+  }
+  else if (strcmp(a[3],"back") == 0)
+  {
+    aNormal.SetCoord(0,1,0);
+    aDX.SetCoord(0,0,1);
+  }
+  else if (strcmp(a[3],"left") == 0)
+  {
+    aNormal.SetCoord(-1,0,0);
+    aDX.SetCoord(0,0,1);
+  }
+  else if (strcmp(a[3],"right") == 0)
+  {
+    aNormal.SetCoord(1,0,0);
+    aDX.SetCoord(0,0,1);
+  }
+    
+  Reflector.SetAxes(aNormal.X(), aNormal.Y(), aNormal.Z(),
+                    anOrigin.X(), anOrigin.Y(), anOrigin.Z(),
+                    aDX.X(), aDX.Y(), aDX.Z());
+
+  Reflector.Perform();
+
+  TopoDS_Compound Result;
+  BRep_Builder BB;
+  BB.MakeCompound(Result);
+  
+  TopoDS_Shape SharpEdges = Reflector.GetCompoundOf3dEdges(HLRBRep_Sharp, Standard_True, Standard_False);
+  if (!SharpEdges.IsNull())
+    BB.Add(Result, SharpEdges);
+  TopoDS_Shape OutLines = Reflector.GetCompoundOf3dEdges(HLRBRep_OutLine, Standard_True, Standard_False);
+  if (!OutLines.IsNull())
+    BB.Add(Result, OutLines);
+  TopoDS_Shape SmoothEdges = Reflector.GetCompoundOf3dEdges(HLRBRep_Rg1Line, Standard_True, Standard_False);
+  if (!SmoothEdges.IsNull())
+    BB.Add(Result, SmoothEdges);
+  
+  DBRep::Set(a[1], Result);
+
+  return 0;
+}
+
+//=======================================================================
+//function : OCC27466
+//purpose :
+//=======================================================================
+static Standard_Integer OCC27466(Draw_Interpretor& theDI,
+  Standard_Integer  theNArg,
+  const char ** theArgVal)
+{
+  if (theNArg != 4)
+  {
+    cout << "Use: " << theArgVal[0] << " face point start_pnt2d" << endl;
+    return 1;
+  }
+
+  TopoDS_Face aFace = TopoDS::Face(DBRep::Get(theArgVal[1], TopAbs_FACE, Standard_True));
+  if (aFace.IsNull())
+    return 1;
+  gp_Pnt aPnt;
+  if (!DrawTrSurf::GetPoint(theArgVal[2], aPnt))
+    return 1;
+  gp_Pnt2d aUV;
+  if (!DrawTrSurf::GetPoint2d(theArgVal[3], aUV))
+    return 1;
+  BRepAdaptor_Surface aSurf(aFace);
+
+  Standard_Real aTolU = Precision::PConfusion();
+  Standard_Real aTolV = Precision::PConfusion();
+
+  Extrema_GenLocateExtPS anExtrema(aSurf, aTolU, aTolV);
+  anExtrema.Perform(aPnt, aUV.X(), aUV.Y(), Standard_True);
+
+  if (!anExtrema.IsDone())
+  {
+    theDI << "Error: Extrema is not done";
+  }
+  else
+  {
+    Standard_Real aSqDist = anExtrema.SquareDistance();
+    gp_Pnt aResPnt = anExtrema.Point().Value();
+    Standard_Real u, v;
+    anExtrema.Point().Parameter(u, v);
+    gp_Pnt2d aResUV(u, v);
+    DrawTrSurf::Set((TCollection_AsciiString(theArgVal[2]) + "_res").ToCString(), aResPnt);
+    DrawTrSurf::Set((TCollection_AsciiString(theArgVal[3]) + "_res").ToCString(), aResUV);
+    theDI << theArgVal[2] << "_res and " << theArgVal[3] << "_res are created, dist=" << sqrt(aSqDist);
+  }
+  return 0;
+}
+
+#include <GCE2d_MakeParabola.hxx>
+#include <gp_Ax22d.hxx>
+#include <Geom2d_Parabola.hxx>
+#include <gp_Parab2d.hxx>
+
+namespace Parab2d_Bug26747
+{
+  //Directrix and X-axe direction
+  gp_Ax2d Axes;
+
+  //Focus
+  gp_Pnt2d FocusPoint;
+
+  //Focal length
+  Standard_Real FocalLength;
+
+  //Coordiantes of the vertex
+  Standard_Real VertX, VertY;
+
+  //Parameter
+  Standard_Real Parameter;
+
+  //Coefficients
+  Standard_Real Coeffs[6];
+}
+
+//========================================================================
+//function : OCC26747_CheckParabola
+//purpose  : Checks if created parabola is correct
+//========================================================================
+static void OCC26747_CheckParabola(Draw_Interpretor& theDI,
+                                   const char *theName,
+                                   const Standard_Boolean theSense = Standard_True)
+{
+  const Standard_Real aCompareTol = 1.0e-12;
+
+  //                      Directrix,                    Focus
+  GCE2d_MakeParabola aPrb(Parab2d_Bug26747::Axes, Parab2d_Bug26747::FocusPoint, theSense);
+
+  DrawTrSurf::Set(theName, aPrb.Value());
+
+  gp_Pnt2d aVert(aPrb.Value()->Parab2d().Location());
+
+  theDI << "Focal Length: " << aPrb.Value()->Parab2d().Focal() << "\n";
+  theDI << "Vertex (" << aVert.X() << ", " << aVert.Y() << ")\n";
+  theDI << "Parameter = " << aPrb.Value()->Parab2d().Parameter() << "\n";
+
+  Standard_Real aF[6] = {RealLast(), RealLast(), RealLast(),
+                         RealLast(), RealLast(), RealLast()};  
+  aPrb.Value()->Parab2d().Coefficients(aF[0], aF[1], aF[2], aF[3], aF[4], aF[5]);
+  theDI << "A = " << aF[0] << ", B = " << aF[1] << ", C = " << aF[2] <<
+           ", D = " << aF[3] << ", E = " << aF[4] << ", F = " << aF[5] << "\n";
+
+  if(Abs(aPrb.Value()->Parab2d().Focal() - 
+                        Parab2d_Bug26747::FocalLength) > aCompareTol)
+    theDI << "Error in focal length computation!\n";
+
+  if( (Abs(aVert.X() - Parab2d_Bug26747::VertX) > aCompareTol) ||
+      (Abs(aVert.Y() - Parab2d_Bug26747::VertY) > aCompareTol))
+    theDI << "Error in vertex computation!\n";
+
+  if(Abs(aPrb.Value()->Parab2d().Parameter() -
+                        Parab2d_Bug26747::Parameter) > aCompareTol)
+    theDI << "Error in parameter computation!\n";
+
+  for(int i = 0; i < 6; i++)
+  {
+    if(Abs(aF[i] - Parab2d_Bug26747::Coeffs[i]) > aCompareTol)
+    {
+      theDI << "Error in " << i << "-th coefficient computation!\n";
+    }
+  }
+}
+
+//========================================================================
+//function : OCC26747_1
+//purpose  : Creates a 2D-parabola for testing
+//========================================================================
+static Standard_Integer OCC26747_1(Draw_Interpretor& theDI, 
+                                   Standard_Integer  theNArg, 
+                                   const char **     theArgVal)
+{
+  if(theNArg < 2)
+  {
+    theDI << "Use: OCC26747_1 result\n";
+    return 1;
+  }
+
+  //Expected parabola:
+
+  //  ^ Y
+  //  |
+  //  |
+  //  |
+  //  |
+  //  |                 o
+  //  |    A   o   F
+  //  |     o     x
+  //  |        o
+  //  |                 o
+  //  |
+  //  ---------------------------> X
+
+  //  where
+  //  Y-axe is the directrix of the parabola,
+  //  A(0.5, 3.0) is a Vertex of the parabola,
+  //  F(1.0, 3.0) is the focus of the parabola,
+  //  Focal length is 0.5,
+  //  Parameter of the parabola is 1.
+  //  Equation: (y-3)^2=2*p*(x-0.5), i.e. (y-3)^2=2*(x-0.5)
+  //  A * X^2 + B * Y^2 + 2*C*X*Y + 2*D*X    + 2*E*Y    + F = 0.
+  //                  OR
+  //  0 * X^2 + 1 * Y^2 + 2*0*X*Y + 2*(-1)*X + 2*(-3)*Y + 10 = 0.
+
+  Parab2d_Bug26747::Axes = gp_Ax2d(gp_Pnt2d(0.0, 3.0), gp_Dir2d(0.0, 1.0));
+  Parab2d_Bug26747::FocusPoint.SetCoord(1.0, 3.0);
+
+  Parab2d_Bug26747::FocalLength = 0.5;
+
+  Parab2d_Bug26747::VertX = 0.5;
+  Parab2d_Bug26747::VertY = 3.0;
+
+  Parab2d_Bug26747::Parameter = 1.0;
+
+  Parab2d_Bug26747::Coeffs[0] = 0.0;
+  Parab2d_Bug26747::Coeffs[1] = 1.0;
+  Parab2d_Bug26747::Coeffs[2] = 0.0;
+  Parab2d_Bug26747::Coeffs[3] = -1.0;
+  Parab2d_Bug26747::Coeffs[4] = -3.0;
+  Parab2d_Bug26747::Coeffs[5] = 10.0;
+
+  OCC26747_CheckParabola(theDI, theArgVal[1]);
+
+  return 0;
+}
+
+//=======================================================================
+//function : OCC26747_2
+//purpose  : Creates a 2D-parabola for testing
+//=======================================================================
+static Standard_Integer OCC26747_2(Draw_Interpretor& theDI,
+                                   Standard_Integer  theNArg,
+                                   const char **     theArgVal)
+{
+  if(theNArg < 2)
+  {
+    theDI << "Use: OCC26747_2 result\n";
+    return 1;
+  }
+
+  //Expected parabola:
+
+  //                          ^ Y
+  //                          |
+  //        o                 |
+  //                 o        |
+  //            F x     o A   |
+  //                 o        |
+  //        o                 |
+  //                          |
+  //  <------------------------
+  //  X
+
+  //  where (in UCS - User Coordinate System, - which
+  //  is shown in the picture):
+  //    Y-axe is the directrix of the parabola,
+  //    A(0.5, 3.0) is a Vertex of the parabola,
+  //    F(1.0, 3.0) is the focus of the parabola.
+  //
+  //  In WCS (World Coordinate System) these points have coordinates:
+  //    A(-0.5, 3.0), F(-1.0, 3.0).
+  //
+  //  Focal length is 0.5,
+  //  Parameter of the parabola is 1.
+  //  Equation (in WCS): (y-3)^2=2*p*(-x-0.5), i.e. (y-3)^2=2*(-x-0.5)
+  //  A * X^2 + B * (Y^2) + 2*C*(X*Y) + 2*D*X + 2*E*Y    + F = 0.
+  //  0 * X^2 + 1 * (Y^2) + 2*0*(X*Y) + 2*1*X + 2*(-3)*Y + 10 = 0.
+
+
+  Parab2d_Bug26747::Axes = gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(0.0, 1.0));
+  Parab2d_Bug26747::FocusPoint.SetCoord(-1.0, 3.0);
+
+  Parab2d_Bug26747::FocalLength = 0.5;
+
+  Parab2d_Bug26747::VertX = -0.5;
+  Parab2d_Bug26747::VertY = 3.0;
+
+  Parab2d_Bug26747::Parameter = 1.0;
+
+  Parab2d_Bug26747::Coeffs[0] = 0.0;
+  Parab2d_Bug26747::Coeffs[1] = 1.0;
+  Parab2d_Bug26747::Coeffs[2] = 0.0;
+  Parab2d_Bug26747::Coeffs[3] = 1.0;
+  Parab2d_Bug26747::Coeffs[4] = -3.0;
+  Parab2d_Bug26747::Coeffs[5] = 10.0;
+
+  OCC26747_CheckParabola(theDI, theArgVal[1], Standard_False);
+
+  return 0;
+}
+
+//=======================================================================
+//function : OCC26747_3
+//purpose  : Creates a 2D-parabola for testing
+//=======================================================================
+static Standard_Integer OCC26747_3(Draw_Interpretor& theDI,
+                                   Standard_Integer  theNArg,
+                                   const char **     theArgVal)
+{
+  if(theNArg < 2)
+  {
+    theDI << "Use: OCC26747_2 result\n";
+    return 1;
+  }
+
+  //Expected parabola:
+
+  //                    ^ Y
+  //                    |
+  //        o           |
+  //                 o  |
+  //            F x     o A
+  //                 o  |
+  //        o           |
+  //                    |
+  //  <------------------
+  //  X
+
+  //  where (in UCS - User Coordinate System, - which
+  //  is shown in the picture):
+  //    Y-axe is the directrix of the parabola,
+  //    A(0.0, 3.0) is a Vertex of the parabola,
+  //    F(0.0, 3.0) is the focus of the parabola (the Focus
+  //                matches with the Apex).
+  //
+  //  In WCS (World Coordinate System) these points have coordinates:
+  //    A(0.0, 3.0), F(0.0, 3.0).
+  //
+  //  Focal length is 0.0,
+  //  Parameter of the parabola is 0.0.
+  //  Equation (in WCS): (y-3)^2=2*p*(-x-0.0), i.e. (y-3)^2=0 (looks like a line y=3)
+  //  A * X^2 + B * (Y^2) + 2*C*(X*Y) + 2*D*X + 2*E*Y    + F = 0.
+  //  0 * X^2 + 1 * (Y^2) + 2*0*(X*Y) + 2*0*X + 2*(-3)*Y + 9 = 0.
+
+  Parab2d_Bug26747::Axes = gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(0.0, 1.0));
+  Parab2d_Bug26747::FocusPoint.SetCoord(0.0, 3.0);
+
+  Parab2d_Bug26747::FocalLength = 0.0;
+
+  Parab2d_Bug26747::VertX = 0.0;
+  Parab2d_Bug26747::VertY = 3.0;
+
+  Parab2d_Bug26747::Parameter = 0.0;
+
+  Parab2d_Bug26747::Coeffs[0] = 0.0;
+  Parab2d_Bug26747::Coeffs[1] = 1.0;
+  Parab2d_Bug26747::Coeffs[2] = 0.0;
+  Parab2d_Bug26747::Coeffs[3] = 0.0;
+  Parab2d_Bug26747::Coeffs[4] = -3.0;
+  Parab2d_Bug26747::Coeffs[5] = 9.0;
+
+  OCC26747_CheckParabola(theDI, theArgVal[1], Standard_False);
+
+  return 0;
+}
+
+#include "Geom2d_BezierCurve.hxx"
+#include "Geom2dGcc_QualifiedCurve.hxx"
+#include "Geom2dAdaptor_Curve.hxx"
+#include "Geom2dAPI_ProjectPointOnCurve.hxx"
+#include "Geom2dGcc_Circ2d2TanOn.hxx"
+//=======================================================================
+//function : OCC27357
+//purpose :
+//=======================================================================
+static Standard_Integer OCC27357(Draw_Interpretor& theDI,
+                                 Standard_Integer,
+                                 const char **)
+{
+  TColgp_Array1OfPnt2d aPoles(1,3);
+  aPoles.SetValue(1, gp_Pnt2d(0.,0.));
+  aPoles.SetValue(2, gp_Pnt2d(0.,1.));
+  aPoles.SetValue(3, gp_Pnt2d(6.,0.));
+
+  Handle(Geom2d_BezierCurve) aCurve1 = new Geom2d_BezierCurve(aPoles);
+  aPoles.SetValue(2, gp_Pnt2d(0.,1.5));
+  Handle(Geom2d_BezierCurve) aCurve2 = new Geom2d_BezierCurve(aPoles);
+  NCollection_List<Standard_Integer> aDuumyList;
+  int nP = 100;
+  for(int i = 0 ; i < nP ; i++){
+    Standard_Real u = i / (nP-1.);
+    gp_Pnt2d aP1;
+    gp_Vec2d aTangent;
+    aCurve1->D1(u,aP1,aTangent);
+    gp_Vec2d aNormal(-aTangent.Y(),aTangent.X());
+    Handle(Geom2d_Line) normalLine=new Geom2d_Line(aP1, gp_Dir2d(aNormal));
+    Geom2dGcc_QualifiedCurve qualifiedC1(Geom2dAdaptor_Curve(aCurve1),GccEnt_unqualified);
+    Geom2dGcc_QualifiedCurve qualifiedC2(Geom2dAdaptor_Curve(aCurve2),GccEnt_unqualified);
+
+    try
+    {
+      Geom2dAPI_ProjectPointOnCurve projPc1(aP1, aCurve1);
+      double g1 = projPc1.LowerDistanceParameter();
+      Geom2dAPI_ProjectPointOnCurve projPc3(aP1, normalLine);
+      double g3 = projPc3.LowerDistanceParameter();
+      Geom2dGcc_Circ2d2TanOn aCircleBuilder(qualifiedC1,qualifiedC2,
+        Geom2dAdaptor_Curve(normalLine),1e-9,g1,g1,g3);
+      aDuumyList.Append(aCircleBuilder.NbSolutions());
+    }
+    catch(Standard_Failure)
+    {
+      theDI << "Exception was caught\n";
+    }
+  }
+  return 0;
+}
+#include <Standard_ErrorHandler.hxx>
+#include <TColGeom_SequenceOfCurve.hxx>
+#include <GeomFill_NSections.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <TopExp_Explorer.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+//=======================================================================
+//function : OCC26270
+//purpose :
+//=======================================================================
+static Standard_Integer OCC26270(Draw_Interpretor& theDI,
+                                 Standard_Integer theNArg,
+                                 const char **theArgVal)
+{
+  if (theNArg != 3)
+  {
+    theDI << "Usage :" << theArgVal[0] << " shape result\n";
+    return 0;
+  }
+  TopoDS_Shape aShape = DBRep::Get(theArgVal[1]);
+  TopExp_Explorer anExp(aShape, TopAbs_EDGE);
+  TColGeom_SequenceOfCurve aCurveSeq;
+  for (; anExp.More(); anExp.Next())
+  {
+    Standard_Real f, l;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(anExp.Current()), f, l);
+    if (!aCurve.IsNull())
+    {
+      aCurve = new Geom_TrimmedCurve(aCurve, f, l);
+      aCurveSeq.Append(aCurve);
+    }
+  }
+  if (aCurveSeq.Length() > 1)
+  {
+    try
+    {
+      OCC_CATCH_SIGNALS
+        GeomFill_NSections aBSurface(aCurveSeq);
+      Handle(Geom_BSplineSurface) aRes = aBSurface.BSplineSurface();
+      if (!aRes.IsNull())
+      {
+        BRepBuilderAPI_MakeFace b_face1(aRes, Precision::Confusion());
+        TopoDS_Face bsp_face1 = b_face1.Face();
+        DBRep::Set(theArgVal[2], bsp_face1);
+      }
+    }
+    catch (Standard_Failure)
+    {
+      theDI << "ERROR: Exception in GeomFill_NSections\n";
+    }
+  }
+  return 0;
+}
+
+#include "BRepBuilderAPI_MakeWire.hxx"
+#include "BRepBuilderAPI_MakeEdge.hxx"
+static Standard_Integer OCC27552(Draw_Interpretor&,
+                                   Standard_Integer,
+                                   const char **  )
+{
+  BRep_Builder BB;
+  TopoDS_Vertex V1, V2, V3;
+  TopoDS_Edge E1, E2;
+  BB.MakeVertex(V1, gp_Pnt(0,0,0), 0.1);
+  BB.MakeVertex(V2, gp_Pnt(5,0,0), 0.1);
+  BB.MakeVertex(V3, gp_Pnt(10,0,0), 0.1);
+  E1 = BRepBuilderAPI_MakeEdge(V1, V2).Edge();
+  E2 = BRepBuilderAPI_MakeEdge(V2, V3).Edge();
+  BRepBuilderAPI_MakeWire MW;
+  MW.Add(E1);
+  MW.Add(E2);
+  TopoDS_Vertex V4, V5, V6, V7;
+  TopoDS_Edge E3, E4;
+  BB.MakeVertex(V4, gp_Pnt(10,0+0.05,0), 0.07);
+  BB.MakeVertex(V5, gp_Pnt(10,0-0.05,0), 0.07);
+  BB.MakeVertex(V6, gp_Pnt(10,0+2,0), 0.07);
+  BB.MakeVertex(V7, gp_Pnt(10,0-2,0), 0.07);
+  E3 = BRepBuilderAPI_MakeEdge(V4, V6).Edge();
+  E4 = BRepBuilderAPI_MakeEdge(V5, V7).Edge();
+  TopTools_ListOfShape LLE;
+  LLE.Append(E3);
+  LLE.Append(E4);
+  MW.Add(LLE);
+  TopoDS_Shape W = MW.Wire();
+  DBRep::Set("outw", W);
+
+  return 0;
+}
+
+#include <NCollection_IncAllocator.hxx>
+static Standard_Integer OCC27875(Draw_Interpretor& theDI,
+                                 Standard_Integer theNArg,
+                                 const char ** theArgVal)
+{
+  if (theNArg < 2)
+  {
+    theDI << "Use: OCC27875 curve\n";
+  }
+
+  TColGeom_SequenceOfCurve aNC(new NCollection_IncAllocator());
+
+  const Handle(Geom_Curve) aC = Handle(Geom_Curve)::DownCast(DrawTrSurf::Get(theArgVal[1]));
+
+  aNC.Append(aC);
+
+  GeomFill_NSections aNS(aNC);
+
+  if (aNS.BSplineSurface().IsNull())
+  {
+    theDI << "GeomFill_NSections is not done.\n";
+  }
+
+  return 0;
+}
+
+
+#include <TDF_Tool.hxx>
+#include <XCAFDoc_View.hxx>
+#include <XCAFDoc_ViewTool.hxx>
+#include <XCAFView_Object.hxx>
+#include <XCAFView_ProjectionType.hxx>
+static Standard_Integer OCC28389(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+{
+  if (argc < 20) {
+    di << "Use: OCC28389 Doc label nb_shapes nb_GDT nb_planes name type pp_x pp_y pp_z vd_x vd_y vd_z ud_x ud_y ud_z zoom width height";
+    return 1;
+  }
+  Handle(TDocStd_Document) aDoc;
+  DDocStd::GetDocument(argv[1], aDoc);
+  if (aDoc.IsNull()) {
+    di << "Error: Wrong document";
+    return 1;
+  }
+  Handle(XCAFDoc_ViewTool) aViewTool = XCAFDoc_DocumentTool::ViewTool(aDoc->Main());
+
+  TDF_Label aLabel;
+  TDF_Tool::Label(aDoc->GetData(), argv[2], aLabel);
+  if (aLabel.IsNull()) {
+    di << "Error: Wrong label";
+    return 1;
+  }
+  Handle(XCAFDoc_View) aView;
+  if (!aLabel.FindAttribute(XCAFDoc_View::GetID(), aView)) {
+    di << "Error: Wrong label";
+    return 1;
+  }
+  Handle(XCAFView_Object) anObj = aView->GetObject();
+  if (anObj.IsNull()) {
+    di << "Error: Wrong label";
+    return 1;
+  }
+
+  Standard_Boolean isOK = Standard_True;
+  // check links
+  Standard_Integer nbShapes = Draw::Atoi(argv[3]);
+  Standard_Integer nbGDTs = Draw::Atoi(argv[4]);
+  Standard_Integer nbPlanes = Draw::Atoi(argv[5]);
+  TDF_LabelSequence aSequence;
+  aViewTool->GetRefShapeLabel(aLabel, aSequence);
+  if (aSequence.Length() != nbShapes)
+    isOK = Standard_False;
+  aSequence.Clear();
+  aViewTool->GetRefGDTLabel(aLabel, aSequence);
+  if (aSequence.Length() != nbGDTs)
+    isOK = Standard_False;
+  aSequence.Clear();
+  aViewTool->GetRefClippingPlaneLabel(aLabel, aSequence);
+  if (aSequence.Length() != nbPlanes)
+    isOK = Standard_False;
+  if (!isOK) {
+    di << "Error: Wrong references";
+    return 1;
+  }
+
+  if (anObj->Name()->IsDifferent(new TCollection_HAsciiString(argv[6]))) {
+    di << "Error: Wrong name";
+    return 1;
+  }
+
+  XCAFView_ProjectionType aType = XCAFView_ProjectionType_NoCamera;
+  if (argv[7][0] == 'p')
+    aType = XCAFView_ProjectionType_Parallel;
+  else if (argv[7][0] == 'c')
+    aType = XCAFView_ProjectionType_Central;
+
+  if (anObj->Type()!= aType) {
+    di << "Error: Wrong type";
+    return 1;
+  }
+
+  gp_Pnt aPP(Draw::Atof(argv[8]), Draw::Atof(argv[9]), Draw::Atof(argv[10]));
+  if (aPP.Distance(anObj->ProjectionPoint()) > Precision::Confusion()) {
+    di << "Error: Wrong projection point";
+    return 1;
+  }
+
+  gp_Dir aVD(Draw::Atof(argv[11]), Draw::Atof(argv[12]), Draw::Atof(argv[13]));
+  if (!aVD.IsEqual(anObj->ViewDirection(), Precision::Angular())) {
+    di << "Error: Wrong view direction";
+    return 1;
+  }
+
+  gp_Dir aUD(Draw::Atof(argv[14]), Draw::Atof(argv[15]), Draw::Atof(argv[16]));
+  if (!aUD.IsEqual(anObj->UpDirection(), Precision::Angular())) {
+    di << "Error: Wrong up direction";
+    return 1;
+  }
+
+  if (fabs(anObj->ZoomFactor() - Draw::Atof(argv[17])) > Precision::Confusion()) {
+    di << "Error: Wrong zoom factor";
+    return 1;
+  }
+
+  if (fabs(anObj->WindowHorizontalSize() - Draw::Atof(argv[18])) > Precision::Confusion())
+    isOK = Standard_False;
+  if (fabs(anObj->WindowVerticalSize() - Draw::Atof(argv[19])) > Precision::Confusion())
+    isOK = Standard_False;
+  if (!isOK) {
+    di << "Error: Wrong Window size";
+    return 1;
+  }
+
+  di << argv[2] << " OK";
+  return 0;
+}
+
+#include <TColgp_HArray1OfPnt2d.hxx>
+#include <TColgp_Array1OfVec2d.hxx>
+#include <TColStd_HArray1OfBoolean.hxx>
+#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2dAPI_Interpolate.hxx>
+#include <GeomAPI.hxx>
+#include <BRepBuilderAPI_MakeEdge2d.hxx>
+
+static Standard_Integer OCC28594(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+{
+  if (argc != 3)
+  {
+    di << "Usage :" << argv[0] << " curve_with_scale curve_without_scale\n";
+    return 0;
+  }
+  Handle(TColgp_HArray1OfPnt2d) points_2d = new TColgp_HArray1OfPnt2d(1, 6);
+  (*points_2d)(1) = gp_Pnt2d(-30.4, 8);
+  (*points_2d)(2) = gp_Pnt2d(-16.689912, 17.498217);
+  (*points_2d)(3) = gp_Pnt2d(-23.803064, 24.748543);
+  (*points_2d)(4) = gp_Pnt2d(-16.907466, 32.919615);
+  (*points_2d)(5) = gp_Pnt2d(-8.543829, 26.549421);
+  (*points_2d)(6) = gp_Pnt2d(0, 39.200000);
+
+  TColgp_Array1OfVec2d tangent_2d(1, 6);
+  (tangent_2d)(1) = gp_Vec2d(0.3, 0.4);
+  (tangent_2d)(2) = gp_Vec2d(0, 0);
+  (tangent_2d)(3) = gp_Vec2d(0, 0);
+  (tangent_2d)(4) = gp_Vec2d(0, 0);
+  (tangent_2d)(5) = gp_Vec2d(0, 0);
+  (tangent_2d)(6) = gp_Vec2d(1, 0);
+
+  Handle(TColStd_HArray1OfBoolean) tangent_flags = new TColStd_HArray1OfBoolean(1, 6);
+  (*tangent_flags)(1) = true;
+  (*tangent_flags)(2) = false;
+  (*tangent_flags)(3) = false;
+  (*tangent_flags)(4) = false;
+  (*tangent_flags)(5) = false;
+  (*tangent_flags)(6) = true;
+
+  Geom2dAPI_Interpolate interp_2d_with_scale(points_2d, Standard_False, Precision::Confusion());
+  interp_2d_with_scale.Load(tangent_2d, tangent_flags);
+  interp_2d_with_scale.Perform();
+  Handle(Geom2d_BSplineCurve) curve_2d_with_scale = interp_2d_with_scale.Curve();
+
+  Geom2dAPI_Interpolate interp_2d_without_scale(points_2d, Standard_False, Precision::Confusion());
+  interp_2d_without_scale.Load(tangent_2d, tangent_flags, Standard_False);
+  interp_2d_without_scale.Perform();
+  Handle(Geom2d_BSplineCurve) curve_2d_without_scale = interp_2d_without_scale.Curve();
+
+  DrawTrSurf::Set(argv[1], curve_2d_with_scale);
+  DrawTrSurf::Set(argv[2], curve_2d_without_scale);
+  return 0;
+}
+
+static Standard_Integer OCC28784(Draw_Interpretor&, Standard_Integer argc, const char** argv)
+{
+  if (argc < 3)
+    return 1;
+
+  TopoDS_Shape aShape =  DBRep::Get(argv[2]);
+  if (aShape.IsNull())
+    return 1;
+
+  gp_Ax2 aPlane (gp::Origin(), gp::DX(), -gp::DZ());
+  HLRAlgo_Projector aProjector(aPlane);
+
+  Handle(HLRBRep_PolyAlgo) aHLR = new HLRBRep_PolyAlgo(aShape);
+  aHLR->Projector(aProjector);
+  aHLR->Update();
+
+  HLRBRep_PolyHLRToShape aHLRtoShape;
+  aHLRtoShape.Update(aHLR);
+
+  TopoDS_Shape aHidden = aHLRtoShape.HCompound();
+  
+  DBRep::Set(argv[1], aHidden);
+
+  return 0;
+}
+
+static Standard_Integer OCC28829 (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // do something that causes FPE exception
+  std::cout << "sqrt(-1) = " << sqrt (-1.) << std::endl;
+  return 0;
+}
+
+#include <NCollection_Buffer.hxx>
+#include <DDocStd_DrawDocument.hxx>
+#include <OSD_OpenFile.hxx>
+#include <Standard_ArrayStreamBuffer.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDocStd_Application.hxx>
+
+#ifdef max
+  #undef max
+#endif
+
+static Standard_Integer OCC28887 (Draw_Interpretor&, Standard_Integer theNbArgs, const char** theArgVec)
+{
+  if (theNbArgs < 3)
+  {
+    std::cout << "Syntax error: wrong number of arguments!\n";
+    return 1;
+  }
+
+  const TCollection_AsciiString aFilePath (theArgVec[1]);
+  const TCollection_AsciiString aName     (theArgVec[2]);
+  Handle(NCollection_Buffer) aBuffer;
+  {
+    std::ifstream aFile;
+    OSD_OpenStream (aFile, aFilePath.ToCString(), std::ios::binary | std::ios::in);
+    if (!aFile.is_open())
+    {
+      std::cout << "Error: input file '" << aFilePath << "' cannot be read\n";
+      return 1;
+    }
+    aFile.seekg (0, std::ios_base::end);
+    const int64_t aFileLength = int64_t (aFile.tellg());
+    if (aFileLength > int64_t (std::numeric_limits<ptrdiff_t>::max())
+     || aFileLength < 1)
+    {
+      std::cout << "Error: input file '" << aFilePath << "' is too large\n";
+      return 1;
+    }
+    aFile.seekg (0, std::ios_base::beg);
+
+    aBuffer = new NCollection_Buffer (NCollection_BaseAllocator::CommonBaseAllocator());
+    if (!aBuffer->Allocate (size_t(aFileLength)))
+    {
+      std::cout << "Error: memory allocation (" << aFileLength << ") has failed\n";
+      return 1;
+    }
+
+    aFile.read ((char* )aBuffer->ChangeData(), aBuffer->Size());
+    if (!aFile.good())
+    {
+      std::cout << "Error: input file '" << aFilePath << "' reading failure\n";
+      return 1;
+    }
+  }
+
+  Standard_ArrayStreamBuffer aStreamBuffer ((const char* )aBuffer->ChangeData(), aBuffer->Size());
+  std::istream aStream (&aStreamBuffer);
+  // just play with seeking
+  aStream.seekg (0, std::ios_base::end);
+  aStream.seekg (0, std::ios_base::beg);
+  if (aFilePath.EndsWith (".brep")
+   || aFilePath.EndsWith (".rle"))
+  {
+    TopoDS_Shape aShape;
+    BRep_Builder aBuilder;
+    BRepTools::Read (aShape, aStream, aBuilder);
+    DBRep::Set (aName.ToCString(), aShape);
+  }
+  else
+  {
+    Handle(TDocStd_Document) aDoc;
+    Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
+    Standard_CString aNameVar = aName.ToCString();
+    if (DDocStd::GetDocument (aNameVar, aDoc, Standard_False))
+    {
+      std::cout << "Error: document with name " << aName << " already exists\n";
+      return 1;
+    }
+
+    if (anApp->Open (aStream, aDoc) != PCDM_RS_OK)
+    {
+      std::cout << "Error: cannot open XDE document\n";
+      return 1;
+    }
+
+    Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc);
+    TDataStd_Name::Set (aDoc->GetData()->Root(), aName.ToCString());
+    Draw::Set (aName.ToCString(), aDrawDoc);
+  }
+
+  return 0;
+}
+
+static Standard_Integer OCC28131 (Draw_Interpretor&, Standard_Integer theNbArgs, const char** theArgVec)
+{
+  if (theNbArgs != 2)
+  {
+    std::cerr << "Error: wrong number of arguments" << std::endl;
+    return 1;
+  }
+
+  double height = 8.5;
+  gp_Pnt JiZhunXian2_v0 = gp_Pnt(-17.6, 0.0, 0.0);
+  gp_Pnt JiZhunXian2_v1 = gp_Pnt(0, 32.8, 0.0);
+
+  // Outline
+  TColgp_Array1OfPnt outer_e_bzr_geom_v(1, 4);
+  {
+    outer_e_bzr_geom_v(1) = JiZhunXian2_v0;
+    outer_e_bzr_geom_v(4) = JiZhunXian2_v1;
+
+    Standard_Real ratio1 = 5.4 / 13.2;
+    outer_e_bzr_geom_v(2) = gp_Pnt(outer_e_bzr_geom_v(1).X(), ratio1*outer_e_bzr_geom_v(4).Y(), 0);
+    Standard_Real ratio2 = 6.0 / 6.8;
+    outer_e_bzr_geom_v(3) = gp_Pnt(ratio2*outer_e_bzr_geom_v(1).X(), outer_e_bzr_geom_v(4).Y(), 0);
+  }
+
+  Handle(Geom_BezierCurve) outer_e_bzr_geom = new Geom_BezierCurve(outer_e_bzr_geom_v);
+  Handle(Geom_BSplineCurve) outer_e_bsp_geom = GeomConvert::CurveToBSplineCurve(outer_e_bzr_geom);
+  TopoDS_Edge outer_e = BRepBuilderAPI_MakeEdge(outer_e_bsp_geom);
+
+  Handle(Geom_BSplineCurve) curve1;
+  {
+    Handle(TColgp_HArray1OfPnt2d) harray = new TColgp_HArray1OfPnt2d(1, 2); // sizing harray
+    harray->SetValue(1, gp_Pnt2d(-JiZhunXian2_v1.Y(), 0));
+    harray->SetValue(2, gp_Pnt2d(0, height + height / 2));
+
+    Geom2dAPI_Interpolate anInterpolation(harray, Standard_False, 1e-6);
+
+    gp_Vec2d vtangent1(0, 1);
+    gp_Vec2d vtangent2(1, 0);
+    anInterpolation.Load(vtangent1, vtangent2);
+    anInterpolation.Perform();
+
+    Handle(Geom2d_BSplineCurve) c = anInterpolation.Curve();
+
+    gp_Pln pln(gp_Ax3(gp_Pnt(), gp_Dir(1, 0, 0), gp_Dir(0, -1, 0)));
+
+    Handle(Geom_BSplineCurve) c3d = Handle(Geom_BSplineCurve)::DownCast(GeomAPI::To3d(c, pln));
+    curve1 = c3d;
+  }
+
+  Handle(Geom_BSplineCurve) curve2;
+  {
+    Handle(TColgp_HArray1OfPnt2d) harray = new TColgp_HArray1OfPnt2d(1, 3); // sizing harray
+    harray->SetValue(1, gp_Pnt2d(-JiZhunXian2_v0.X(), 0));
+    harray->SetValue(2, gp_Pnt2d(-JiZhunXian2_v0.X() - 2.6, height));
+    harray->SetValue(3, gp_Pnt2d(0, height + height / 2));
+
+    Geom2dAPI_Interpolate anInterpolation(harray, Standard_False, 1e-6);
+    anInterpolation.Perform();
+
+    Handle(Geom2d_BSplineCurve) c = anInterpolation.Curve();
+    gp_Pln pln(gp_Ax3(gp_Pnt(), gp_Dir(0, -1, 0), gp_Dir(-1, 0, 0)));
+    Handle(Geom_BSplineCurve) c3d = Handle(Geom_BSplineCurve)::DownCast(GeomAPI::To3d(c, pln));
+    curve2 = c3d;
+  }
+
+  //////////////////////////////////////
+  GeomFill_BSplineCurves fill2;
+  fill2.Init(outer_e_bsp_geom, curve1, curve2, GeomFill_CoonsStyle);
+
+  const Handle(Geom_BSplineSurface)& surf_geom = fill2.Surface();
+
+  TopoDS_Shape filled_face = BRepBuilderAPI_MakeFace(surf_geom, 0);
+
+  DBRep::Set (theArgVec[1], filled_face);
+
+/*
+  ///////////////////////////////////////////////////////////////////////
+  TopoDS_Solid first_solid;
+  {
+    BRepOffset_MakeOffset myOffsetShape(filled_face, -offset_thick, 1e-4,
+      BRepOffset_Skin, //Mode
+      Standard_False, //Intersection
+      Standard_False, //SelfInter
+      GeomAbs_Intersection, //Join
+      Standard_True, //Thickening
+      Standard_False //RemoveIntEdges
+      ); //RemoveInvalidFaces
+    first_solid = TopoDS::Solid(myOffsetShape.Shape());
+  }
+*/
+  return 0;
+}
+
+#include <BRepOffsetAPI_MakeEvolved.hxx>
+#include <ShapeFix_Wireframe.hxx>
+static Standard_Integer myCall(Draw_Interpretor&, Standard_Integer theNbArgs, const char** theArgVec)
+{
+  TopoDS_Wire extrudeWire = TopoDS::Wire(DBRep::Get(theArgVec[2]));
+  TopoDS_Wire toolWire = TopoDS::Wire(DBRep::Get(theArgVec[3]));
+
+  // ################################ Check and Fix Wire Gaps #########################################
+  if (1)
+  {
+    ShapeFix_Wireframe fix_tool(extrudeWire);
+    fix_tool.ModeDropSmallEdges() = Standard_True;
+    fix_tool.SetPrecision(Precision::Confusion()); //yes!
+    fix_tool.FixSmallEdges();
+    fix_tool.FixWireGaps();
+    extrudeWire = TopoDS::Wire(fix_tool.Shape());
+  }
+
+  // ################################ Extrude tool #########################################
+  BRepOffsetAPI_MakeEvolved mkEvolved = BRepOffsetAPI_MakeEvolved(extrudeWire, toolWire, GeomAbs_Arc, Standard_False, Standard_True, Standard_False, Standard_True, 0);
+
+  DBRep::Set(theArgVec[1], mkEvolved.Shape());
+
+  return 0;
+}
+
+//=======================================================================
+//function : FindGaps
+//purpose  : 
+//=======================================================================
+static Standard_Integer FindGaps(Draw_Interpretor& theDI, Standard_Integer theNArg, const char** theArgV)
+{
+  if (theNArg < 3)
+  {
+    theDI << "Use: " << theArgV[0] << " result wire\n";
+    return 1;
+  }
+
+  const TopoDS_Wire aWir = TopoDS::Wire(DBRep::Get(theArgV[2]));
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
+  TopExp::MapShapesAndAncestors(aWir, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
+
+  Standard_Real aMaxDist = RealFirst();
+
+  for (Standard_Integer i = 1; i <= aMapVE.Extent(); i++)
+  {
+    const TopoDS_Vertex &aV = TopoDS::Vertex(aMapVE.FindKey(i));
+
+    TopTools_ListOfShape aLE = aMapVE.FindFromIndex(i);
+
+    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 aPrm1 = BRep_Tool::Parameter(aV, anE1);
+    const Standard_Real aPrm2 = BRep_Tool::Parameter(aV, anE2);
+
+    gp_Pnt aP1, aP2;
+    anAC1.D0(aPrm1, aP1);
+    anAC2.D0(aPrm2, aP2);
+
+    char aBuff[100];
+    Sprintf(aBuff, "%sv%d", theArgV[1], i);
+    DBRep::Set(aBuff, aV);
+
+    const Standard_Real aDist = aP1.Distance(aP2);
+    aMaxDist = Max(aMaxDist, aDist);
+
+    theDI << aBuff << ": Dist = " << aDist << "\n";
+  }
+
+  theDI << "Max. gap is " << aMaxDist << "\n";
+
+  return 0;
+}
+
+//=======================================================================
+//function : VEProcess
+//purpose  : 
+//=======================================================================
+static Standard_Integer VEProcess(Draw_Interpretor& theDI, Standard_Integer theNArg, const char** theArgV)
+{
+  if (theNArg < 3)
+  {
+    theDI << "Use: " << theArgV[0] << " result wire\n";
+    return 1;
+  }
+
+  const TopoDS_Wire aWir = TopoDS::Wire(DBRep::Get(theArgV[2]));
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
+  TopExp::MapShapesAndAncestors(aWir, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
+
+  for (Standard_Integer i = 1; i <= aMapVE.Extent(); i++)
+  {
+    const TopoDS_Vertex &aV = TopoDS::Vertex(aMapVE.FindKey(i));
+
+    TopTools_ListOfShape aLE = aMapVE.FindFromIndex(i);
+
+    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 aPrm1 = BRep_Tool::Parameter(aV, anE1);
+    const Standard_Real aPrm2 = BRep_Tool::Parameter(aV, anE2);
+
+    gp_Pnt aP;
+    gp_Vec aT1, aT2;
+    anAC1.D1(aPrm1, aP, aT1);
+    anAC2.D1(aPrm2, aP, aT2);
+
+    Standard_Real anAngle = aT1.Angle(aT2);
+
+    if (anAngle > M_PI_2)
+      anAngle = M_PI - anAngle;
+
+    char aBuff[100];
+    Sprintf(aBuff, "%sv%d", theArgV[1], i);
+    DBRep::Set(aBuff, aV);
+
+    theDI << aBuff << " (" << BRep_Tool::Tolerance(aV) << "): A = " << anAngle << "\n";
+  }
+
+  return 0;
+}
+
+
+void QABugs::Commands_20(Draw_Interpretor& theCommands) {
+  const char *group = "QABugs";
+
+  theCommands.Add ("OCC26675_1", "OCC26675_1 result", __FILE__, SurfaceGenOCC26675_1, group);
+  theCommands.Add ("OCC24836", "OCC24836", __FILE__, OCC24836, group);
+  theCommands.Add("OCC27021", "OCC27021", __FILE__, OCC27021, group);
+  theCommands.Add("OCC27235", "OCC27235", __FILE__, OCC27235, group);
+  theCommands.Add("OCC26930", "OCC26930", __FILE__, OCC26930, group);
+  theCommands.Add("OCC27466", "OCC27466", __FILE__, OCC27466, group);
+  theCommands.Add("OCC27341",
+                  "OCC27341 res shape axo/top/bottom/front/back/left/right",
+                  __FILE__, OCC27341, group);
+  theCommands.Add ("OCC26747_1", "OCC26747_1 result", __FILE__, OCC26747_1, group);
+  theCommands.Add ("OCC26747_2", "OCC26747_2 result", __FILE__, OCC26747_2, group);
+  theCommands.Add ("OCC26747_3", "OCC26747_3 result", __FILE__, OCC26747_3, group);
+  theCommands.Add ("OCC27357", "OCC27357", __FILE__, OCC27357, group);
+  theCommands.Add("OCC26270", "OCC26270 shape result", __FILE__, OCC26270, group);
+  theCommands.Add ("OCC27552", "OCC27552", __FILE__, OCC27552, group); 
+  theCommands.Add("OCC27875", "OCC27875 curve", __FILE__, OCC27875, group);
+  theCommands.Add("OCC28389", "OCC28389", __FILE__, OCC28389, group);
+  theCommands.Add("OCC28594", "OCC28594", __FILE__, OCC28594, group);
+  theCommands.Add("OCC28784", "OCC28784 result shape", __FILE__, OCC28784, group);
+  theCommands.Add("OCC28829", "OCC28829: perform invalid FPE operation", __FILE__, OCC28829, group);
+  theCommands.Add("OCC28887",
+                  "OCC28887 filePath result"
+                  "\n\t\t: Check interface for reading BRep from memory.",
+                  __FILE__, OCC28887, group);
+  theCommands.Add("OCC28131", "OCC28131 name: creates face problematic for offset", __FILE__, OCC28131, group);
+
+  theCommands.Add("myCall", "myCall result spine profile", __FILE__, myCall, group);
+
+  theCommands.Add("findgaps", "findgaps result wire", __FILE__, FindGaps, group);
+  theCommands.Add("veproc", "veproc result wire", __FILE__, VEProcess, group);
+
+  return;
+}
index b9acbb100de88604307d0f598f349efda724f9c6..5a2b24f2a7bbd0ff182e8394c950d967699e88c5 100644 (file)
@@ -595,6 +595,14 @@ proc checkprops {shape args} {
                 if { $m == 0 } {
                     puts "Error : The command is not valid. The $prop is 0."
                 }
+                # Provide comparation with negative value
+                if { [expr $mass*$m ] < 0.0 } {
+                  # Value and expected value have different sign
+                  puts "Error : The $prop of result shape is $m"
+                } else {
+                  set mass [expr abs($mass)]
+                  set m [expr abs($m)]
+                }
                 if { $mass > 0 } {
                     puts "The expected $prop is $mass"
                 }
index ff3e47e62d2e175dd118ccacea6824008822b657..8f8dc94a7bdf3caee702abc8a79bed1f9766b004 100755 (executable)
@@ -66,9 +66,10 @@ namespace
 
   //! Auxiliary method to convert FT_Vector to gp_XY
   static gp_XY readFTVec (const FT_Vector& theVec,
-                          const Standard_Real theScaleUnits)
+                          const Standard_Real theScaleUnits,
+                          const Standard_Real theWidthScaling = 1.0)
   {
-    return gp_XY (theScaleUnits * Standard_Real(theVec.x) / 64.0, theScaleUnits * Standard_Real(theVec.y) / 64.0);
+    return gp_XY (theScaleUnits * Standard_Real(theVec.x) * theWidthScaling / 64.0, theScaleUnits * Standard_Real(theVec.y) / 64.0);
   }
 
 }
@@ -265,7 +266,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
 
   TopLoc_Location aLoc;
   TopoDS_Face aFaceDraft;
-  myBuilder.MakeFace (aFaceDraft, mySurface, myPrecision);
+  TopoDS_Compound aFaceCompDraft;
 
   // Get orientation is useless since it doesn't retrieve any in-font information and just computes orientation.
   // Because it fails in some cases - leave this to ShapeFix.
@@ -277,7 +278,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
     const short anEndIndex = anOutline.contours[aContour];
     const short aPntsNb    = (anEndIndex - aStartIndex) + 1;
     aStartIndex = anEndIndex + 1;
-    if (aPntsNb < 3)
+    if (aPntsNb < 3 && !myIsSingleLine)
     {
       // closed contour can not be constructed from < 3 points
       continue;
@@ -286,10 +287,11 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
     BRepBuilderAPI_MakeWire aWireMaker;
 
     gp_XY aPntPrev;
-    gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits);
-    gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits);
+    gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits, myWidthScaling);
+    gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits, myWidthScaling);
 
-    Standard_Integer aLinePnts = (FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On) ? 1 : 0;
+    bool isLineSeg = !myIsSingleLine
+                  && FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On;
     gp_XY aPntLine1 = aPntCurr;
 
     // see http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-6.html
@@ -298,15 +300,15 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
     {
       aPntPrev = aPntCurr;
       aPntCurr = aPntNext;
-      aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits);
+      aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits, myWidthScaling);
 
       // process tags
       if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_On)
       {
-        if (aLinePnts < 1)
+        if (!isLineSeg)
         {
           aPntLine1 = aPntCurr;
-          aLinePnts = 1;
+          isLineSeg = true;
           continue;
         }
 
@@ -315,7 +317,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
         if (aLen <= myPrecision)
         {
           aPntLine1 = aPntCurr;
-          aLinePnts = 1;
+          isLineSeg = true;
           continue;
         }
 
@@ -339,7 +341,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
       }
       else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Conic)
       {
-        aLinePnts = 0;
+        isLineSeg = false;
         gp_XY aPntPrev2 = aPntPrev;
         gp_XY aPntNext2 = aPntNext;
 
@@ -378,11 +380,11 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
       else if (FT_CURVE_TAG(aTags[aPntId])                 == FT_Curve_Tag_Cubic
             && FT_CURVE_TAG(aTags[(aPntId + 1) % aPntsNb]) == FT_Curve_Tag_Cubic)
       {
-        aLinePnts = 0;
+        isLineSeg = false;
         my4Poles.SetValue (1, aPntPrev);
         my4Poles.SetValue (2, aPntCurr);
         my4Poles.SetValue (3, aPntNext);
-        my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits)));
+        my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits, myWidthScaling)));
         Handle(Geom2d_BezierCurve) aBezier = new Geom2d_BezierCurve (my4Poles);
         if (myIsCompositeCurve)
         {
@@ -411,7 +413,8 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
 
       const gp_Pnt2d aFirstPnt = aDraft2d->StartPoint();
       const gp_Pnt2d aLastPnt  = aDraft2d->EndPoint();
-      if (!aFirstPnt.IsEqual (aLastPnt, myPrecision))
+      if (!myIsSingleLine
+       && !aFirstPnt.IsEqual (aLastPnt, myPrecision))
       {
         Handle(Geom2d_TrimmedCurve) aLine = GCE2d_MakeSegment (aLastPnt, aFirstPnt);
         myConcatMaker.Add (aLine, myPrecision);
@@ -438,7 +441,8 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
       TopExp::Vertices (aWireMaker.Wire(), aFirstV, aLastV);
       gp_Pnt aFirstPoint = BRep_Tool::Pnt (aFirstV);
       gp_Pnt aLastPoint  = BRep_Tool::Pnt (aLastV);
-      if (!aFirstPoint.IsEqual (aLastPoint, myPrecision))
+      if (!myIsSingleLine
+       && !aFirstPoint.IsEqual (aLastPoint, myPrecision))
       {
         aWireMaker.Add (BRepLib_MakeEdge (aFirstV, aLastV));
       }
@@ -450,31 +454,64 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
     }
 
     TopoDS_Wire aWireDraft = aWireMaker.Wire();
-    //if (anOrient == FT_ORIENTATION_FILL_LEFT)
-    //{
-    // According to the TrueType specification, clockwise contours must be filled
-    aWireDraft.Reverse();
-    //}
-    myBuilder.Add (aFaceDraft, aWireDraft);
+    if (!myIsSingleLine)
+    {
+      //if (anOrient == FT_ORIENTATION_FILL_LEFT)
+      //{
+      // According to the TrueType specification, clockwise contours must be filled
+      aWireDraft.Reverse();
+      //}
+      if (aFaceDraft.IsNull())
+      {
+        myBuilder.MakeFace (aFaceDraft, mySurface, myPrecision);
+      }
+      myBuilder.Add (aFaceDraft, aWireDraft);
+    }
+    else
+    {
+      if (aFaceCompDraft.IsNull())
+      {
+        myBuilder.MakeCompound (aFaceCompDraft);
+      }
+      myBuilder.Add (aFaceCompDraft, aWireDraft);
+    }
   }
 
-  myFixer.Init (aFaceDraft);
-  myFixer.Perform();
-  theShape = myFixer.Result();
-  if (!theShape.IsNull()
-  &&  theShape.ShapeType() != TopAbs_FACE)
+  if (!aFaceDraft.IsNull())
   {
-    // shape fix can not fix orientation within the single call
-    TopoDS_Compound aComp;
-    myBuilder.MakeCompound (aComp);
-    for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
+    myFixer.Init (aFaceDraft);
+    myFixer.Perform();
+    TopoDS_Shape aFixResult = myFixer.Result();
+    if (!aFixResult.IsNull()
+     &&  aFixResult.ShapeType() != TopAbs_FACE)
+    {
+      // shape fix can not fix orientation within the single call
+      if (aFaceCompDraft.IsNull())
+      {
+        myBuilder.MakeCompound (aFaceCompDraft);
+      }
+      for (TopExp_Explorer aFaceIter (aFixResult, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
+      {
+        TopoDS_Face aFace = TopoDS::Face (aFaceIter.Current());
+        myFixer.Init (aFace);
+        myFixer.Perform();
+        myBuilder.Add (aFaceCompDraft, myFixer.Result());
+      }
+      theShape = aFaceCompDraft;
+    }
+    else if (!aFaceCompDraft.IsNull())
     {
-      TopoDS_Face aFace = TopoDS::Face (aFaceIter.Current());
-      myFixer.Init (aFace);
-      myFixer.Perform();
-      myBuilder.Add (aComp, myFixer.Result());
+      myBuilder.Add (aFaceCompDraft, aFixResult);
+      theShape = aFaceCompDraft;
     }
-    theShape = aComp;
+    else
+    {
+      theShape = aFixResult;
+    }
+  }
+  else if (!aFaceCompDraft.IsNull())
+  {
+    theShape = aFaceCompDraft;
   }
 
   myCache.Bind (theChar, theShape);
index b51cac3f8c87111b4235437be37b073c9a2390a5..6a967728bd7058dd74ad00cc7128b22e2601878d 100755 (executable)
@@ -29,12 +29,14 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient)
 // purpose  :
 // =======================================================================
 Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
-: myFTLib      (theFTLib),
-  myFTFace     (NULL),
-  myPointSize  (0U),
-  myLoadFlags  (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
-  myKernAdvance(new FT_Vector()),
-  myUChar      (0U)
+: myFTLib       (theFTLib),
+  myFTFace      (NULL),
+  myPointSize   (0U),
+  myWidthScaling(1.0),
+  myLoadFlags   (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
+  myIsSingleLine(false),
+  myKernAdvance (new FT_Vector()),
+  myUChar       (0U)
 {
   if (myFTLib.IsNull())
   {
@@ -118,9 +120,12 @@ bool Font_FTFont::Init (const NCollection_String& theFontName,
 {
   Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
   const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString());
-  Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize);
-  return !aRequestedFont.IsNull()
-      && Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
+  if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize))
+  {
+    myIsSingleLine = aRequestedFont->IsSingleStrokeFont();
+    return Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
+  }
+  return false;
 }
 
 // =======================================================================
@@ -263,12 +268,19 @@ float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
     return 0.0f;
   }
 
-  if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
-   || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
+  FT_Pos aKerningX = 0;
+  if (theUCharNext != 0
+   && FT_HAS_KERNING (myFTFace) != 0)
   {
-    return fromFTPoints<float> (myFTFace->glyph->advance.x);
+    const FT_UInt aCharCurr = FT_Get_Char_Index (myFTFace, myUChar);
+    const FT_UInt aCharNext = FT_Get_Char_Index (myFTFace, theUCharNext);
+    if (aCharCurr != 0 && aCharNext != 0
+     && FT_Get_Kerning (myFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, myKernAdvance) == 0)
+    {
+      aKerningX = myKernAdvance->x;
+    }
   }
-  return fromFTPoints<float> (myKernAdvance->x + myFTFace->glyph->advance.x);
+  return myWidthScaling * fromFTPoints<float> (myFTFace->glyph->advance.x + aKerningX);
 }
 
 // =======================================================================
@@ -282,12 +294,19 @@ float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
     return 0.0f;
   }
 
-  if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
-   || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
+  FT_Pos aKerningY = 0;
+  if (theUCharNext != 0
+   && FT_HAS_KERNING (myFTFace) != 0)
   {
-    return fromFTPoints<float> (myFTFace->glyph->advance.y);
+    const FT_UInt aCharCurr = FT_Get_Char_Index (myFTFace, myUChar);
+    const FT_UInt aCharNext = FT_Get_Char_Index (myFTFace, theUCharNext);
+    if (aCharCurr != 0 && aCharNext != 0
+        && FT_Get_Kerning (myFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, myKernAdvance) == 0)
+    {
+      aKerningY = myKernAdvance->y;
+    }
   }
-  return fromFTPoints<float> (myKernAdvance->y + myFTFace->glyph->advance.y);
+  return fromFTPoints<float> (myFTFace->glyph->advance.y + aKerningY);
 }
 
 // =======================================================================
index 4d500fe0b0017b933ab2d50e3418e426c6bbfd29..8409aad6fa6a18c6804080f2feca0cb2fadcaeb7 100755 (executable)
@@ -73,6 +73,13 @@ public:
                              const unsigned int        thePointSize,
                              const unsigned int        theResolution);
 
+  //! Return TRUE if this is single-stroke (one-line) font, FALSE by default.
+  //! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software.
+  bool IsSingleStrokeFont() const { return myIsSingleLine; }
+
+  //! Set if this font should be rendered as single-stroke (one-line).
+  void SetSingleStrokeFont (bool theIsSingleLine) { myIsSingleLine = theIsSingleLine; }
+
   //! Release currently loaded font.
   Standard_EXPORT virtual void Release();
 
@@ -100,6 +107,13 @@ public:
     return myPointSize;
   }
 
+  //! Setup glyph scaling along X-axis.
+  //! By default glyphs are not scaled (scaling factor = 1.0)
+  void SetWidthScaling (const float theScaleFactor)
+  {
+    myWidthScaling = theScaleFactor;
+  }
+
   //! Compute advance to the next character with kerning applied when applicable.
   //! Assuming text rendered horizontally.
   Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUCharNext);
@@ -154,15 +168,17 @@ protected:
 
 protected:
 
-  Handle(Font_FTLibrary) myFTLib;       //!< handle to the FT library object
-  FT_Face                myFTFace;      //!< FT face object
-  NCollection_String     myFontPath;    //!< font path
-  unsigned int           myPointSize;   //!< point size set by FT_Set_Char_Size
-  int32_t                myLoadFlags;   //!< default load flags
-
-  Image_PixMap           myGlyphImg;    //!< cached glyph plane
-  FT_Vector*             myKernAdvance; //!< buffer variable
-  Standard_Utf32Char     myUChar;       //!< currently loaded unicode character
+  Handle(Font_FTLibrary) myFTLib;        //!< handle to the FT library object
+  FT_Face                myFTFace;       //!< FT face object
+  NCollection_String     myFontPath;     //!< font path
+  unsigned int           myPointSize;    //!< point size set by FT_Set_Char_Size
+  float                  myWidthScaling; //!< scale glyphs along X-axis
+  int32_t                myLoadFlags;    //!< default load flags
+  bool                   myIsSingleLine; //!< single stroke font flag, FALSE by default
+
+  Image_PixMap           myGlyphImg;     //!< cached glyph plane
+  FT_Vector*             myKernAdvance;  //!< buffer variable
+  Standard_Utf32Char     myUChar;        //!< currently loaded unicode character
 
 public:
 
index 65f24d94c6327f756ebbf3f1633aadc71933a802..d49a6764a8bd25d5f824dd9ad646063227f5f29c 100644 (file)
@@ -49,7 +49,8 @@ static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
   { "Symbol"                   , "Symbol"         , Font_FA_Regular  },
   { "ZapfDingbats"             , "WingDings"      , Font_FA_Regular  },
   { "Rock"                     , "Arial"          , Font_FA_Regular  },
-  { "Iris"                     , "Lucida Console" , Font_FA_Regular  }
+  { "Iris"                     , "Lucida Console" , Font_FA_Regular  },
+  { "NSimSun"                  , "SimSun"         , Font_FA_Regular  }
 
 #elif defined(__ANDROID__)
 
@@ -218,6 +219,8 @@ static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib
     Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aFontFace->family_name);
     Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (theFontPath);
     aResult = new Font_SystemFont (aFontName, anAspect, aFontPath);
+    // automatically identify some known single-line fonts
+    aResult->SetSingleStrokeFont (aFontName->String().StartsWith ("OLF "));
   }
 
   FT_Done_Face (aFontFace);
index 29f1653bd3d9c77fd03b24e0e42bf73845bcb4e9..19c3c1636d991ef4fcd224dfea4ee2fecb8dd9dd 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-// Updated:
-
 #include <Font_SystemFont.hxx>
+
 #include <OSD_Path.hxx>
 #include <Standard_Type.hxx>
 #include <TCollection_HAsciiString.hxx>
 
-IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont,Standard_Transient)
-
-Font_SystemFont::Font_SystemFont():
-MyFontName(),
-MyFontAspect(Font_FA_Undefined),
-MyFaceSize(-1),
-MyVerification(Standard_False)
+IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
+
+// =======================================================================
+// function : Font_SystemFont
+// purpose  :
+// =======================================================================
+Font_SystemFont::Font_SystemFont()
+: myFontAspect (Font_FA_Undefined),
+  myFaceSize (-1),
+  myIsSingleLine (Standard_False),
+  myIsDefined (Standard_False)
 {
+  //
 }
 
-Font_SystemFont::Font_SystemFont( const Handle(TCollection_HAsciiString)& FontName,
-                                const Font_FontAspect FontAspect,
-                                const Handle(TCollection_HAsciiString)& FilePath ):
-MyFontName(FontName),
-MyFontAspect(FontAspect),
-MyFaceSize(-1),
-MyFilePath(FilePath),
-MyVerification(Standard_True)
+// =======================================================================
+// function : Font_SystemFont
+// purpose  :
+// =======================================================================
+Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theFontName,
+                                  const Font_FontAspect theFontAspect,
+                                  const Handle(TCollection_HAsciiString)& theFilePath)
+: myFontName (theFontName),
+  myFontAspect (theFontAspect),
+  myFaceSize (-1),
+  myFilePath (theFilePath),
+  myIsSingleLine (Standard_False),
+  myIsDefined (Standard_True)
 {
-
+  //
 }
 
+// =======================================================================
+// function : Font_SystemFont
+// purpose  :
+// =======================================================================
 Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD,
-                                  const Handle(TCollection_HAsciiString)& theFilePath) :
-MyFontAspect(Font_FA_Regular),
-MyFaceSize(-1),
-MyFilePath(theFilePath)
+                                  const Handle(TCollection_HAsciiString)& theFilePath)
+: myFontAspect (Font_FA_Regular),
+  myFaceSize (-1),
+  myFilePath (theFilePath),
+  myIsSingleLine (Standard_False),
+  myIsDefined (Standard_True)
 {
-  MyVerification = Standard_True;
-  if (theXLFD.IsNull())
+  if (theXLFD.IsNull()
+   || theXLFD->IsEmpty())
   {
-    MyVerification = Standard_False; // empty font description handler
+    myIsDefined = Standard_False;
+    return;
   }
-  if (theXLFD->IsEmpty())
+
+  myFontName = theXLFD->Token ("-", 2);
+  const TCollection_AsciiString& aXLFD = theXLFD->String();
+
+  // Getting font size for fixed size fonts
+  if (aXLFD.Search ("-0-0-0-0-") >= 0)
   {
-    MyVerification = Standard_False; // empty font description
+    myFaceSize = -1; // Scalable font
   }
-
-  if (MyVerification)
+  else
   {
-    MyFontName = theXLFD->Token ("-", 2);
-    TCollection_AsciiString aXLFD (theXLFD->ToCString());
-
-    // Getting font size for fixed size fonts
-    if (aXLFD.Search ("-0-0-0-0-") >= 0)
-      MyFaceSize = -1; // Scalable font
-    else
-      //TODO catch exeption
-      MyFaceSize = aXLFD.Token ("-", 7).IntegerValue();
-
-    // Detect font aspect
-    if (aXLFD.Token ("-", 3).IsEqual ("bold") &&
-       (aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o")))
-    {
-      MyFontAspect = Font_FA_BoldItalic;
-    }
-    else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
-    {
-      MyFontAspect = Font_FA_Bold;
-    }
-    else if (aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o"))
-    {
-      MyFontAspect = Font_FA_Italic;
-    }
+    myFaceSize = aXLFD.Token ("-", 7).IntegerValue();
   }
-}
-
-Standard_Boolean Font_SystemFont::IsValid() const{
-  if ( !MyVerification)
-    return Standard_False;
-
-  if ( MyFontAspect == Font_FA_Undefined )
-    return Standard_False;
 
-  if ( MyFontName->IsEmpty() || !MyFontName->IsAscii() )
-    return Standard_False;
-
-  OSD_Path path;
-  return path.IsValid( MyFilePath->String() );
-}
-
-Handle(TCollection_HAsciiString) Font_SystemFont::FontPath() const{
-  return MyFilePath;
-}
-
-Handle(TCollection_HAsciiString) Font_SystemFont::FontName() const{
-  return MyFontName;
-}
-
-Font_FontAspect Font_SystemFont::FontAspect() const{
-  return MyFontAspect;
-}
-
-Standard_Integer Font_SystemFont::FontHeight() const {
-  return MyFaceSize;
-}
-
-Standard_Boolean Font_SystemFont::IsEqual(const Handle(Font_SystemFont)& theOtherFont) const
-{
-  if (!MyFontName->IsSameString (theOtherFont->FontName(), Standard_False))
+  // Detect font aspect
+  if (aXLFD.Token ("-", 3).IsEqual ("bold")
+   && (aXLFD.Token ("-", 4).IsEqual ("i")
+    || aXLFD.Token ("-", 4).IsEqual ("o")))
   {
-    return Standard_False;
+    myFontAspect = Font_FA_BoldItalic;
   }
-
-  if (MyFontAspect != theOtherFont->FontAspect())
+  else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
   {
-    return Standard_False;
+    myFontAspect = Font_FA_Bold;
   }
-
-  if (MyFaceSize != theOtherFont->FontHeight())
+  else if (aXLFD.Token ("-", 4).IsEqual ("i")
+        || aXLFD.Token ("-", 4).IsEqual ("o"))
   {
-    return Standard_False;
+    myFontAspect = Font_FA_Italic;
   }
+}
 
-  return Standard_True;
+// =======================================================================
+// function : IsValid
+// purpose  :
+// =======================================================================
+Standard_Boolean Font_SystemFont::IsValid() const
+{
+  return myIsDefined
+     &&  myFontAspect != Font_FA_Undefined
+     && !myFontName->IsEmpty()
+     &&  OSD_Path::IsValid (myFilePath->String());
+}
+
+// =======================================================================
+// function : IsEqual
+// purpose  :
+// =======================================================================
+Standard_Boolean Font_SystemFont::IsEqual (const Handle(Font_SystemFont)& theOtherFont) const
+{
+  return myFontName->IsSameString (myFontName, Standard_False)
+      && myFontAspect == theOtherFont->myFontAspect
+      && myFaceSize   == theOtherFont->myFaceSize;
 }
index 062f916d510f0016c5f4ae6c91d3d5dea61496a5..7cb13e25de22e7a97191a5b55fa4dd8e523800b8 100644 (file)
 #include <Standard_Transient.hxx>
 class TCollection_HAsciiString;
 
-
-class Font_SystemFont;
-DEFINE_STANDARD_HANDLE(Font_SystemFont, Standard_Transient)
-
-//! Structure for store of Font System Information
+//! This class stores information about the font, which is merely a file path and cached metadata about the font.
 class Font_SystemFont : public Standard_Transient
 {
-
+  DEFINE_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
 public:
 
-  
-  //! Creates empty font object
+  //! Creates an empty font object.
   Standard_EXPORT Font_SystemFont();
+
+  //! Creates a new font object.
+  Standard_EXPORT Font_SystemFont (const Handle(TCollection_HAsciiString)& theFontName,
+                                   const Font_FontAspect theFontAspect,
+                                   const Handle(TCollection_HAsciiString)& theFilePath);
+
+  //! Creates a font object and initialize class fields with values taken from XLFD (X Logical Font Description)
+  Standard_EXPORT Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD,
+                                   const Handle(TCollection_HAsciiString)& theFilePath);
+
+  //! Returns font family name.
+  const Handle(TCollection_HAsciiString)& FontName() const { return myFontName; }
   
-  //! Creates Font object initialized with <FontName> as name
-  //! <FontAspect>.... TODO
-  Standard_EXPORT Font_SystemFont(const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Handle(TCollection_HAsciiString)& theFilePath);
-  
-  //! Creates Font object and initialize class fields with
-  //! values taken from XLFD (X Logical Font Description)
-  Standard_EXPORT Font_SystemFont(const Handle(TCollection_HAsciiString)& theXLFD, const Handle(TCollection_HAsciiString)& theFilePath);
-  
-  //! Returns font family name
-  Standard_EXPORT Handle(TCollection_HAsciiString) FontName() const;
-  
-  //! Returns font file path
-  //! Level: Public
-  Standard_EXPORT Handle(TCollection_HAsciiString) FontPath() const;
-  
-  //! Returns font aspect
-  //! Level: Public
-  Standard_EXPORT Font_FontAspect FontAspect() const;
+  //! Returns font file path.
+  const Handle(TCollection_HAsciiString)& FontPath() const { return myFilePath; }
   
-  //! Returns font height
-  //! If returned value is equal -1 it means that font is resizable
-  //! Level: Public
-  Standard_EXPORT Standard_Integer FontHeight() const;
+  //! Returns font aspect.
+  Font_FontAspect FontAspect() const { return myFontAspect; }
   
+  //! Returns font height.
+  //! If returned value is equal -1 it means that font is resizable.
+  Standard_Integer FontHeight() const { return myFaceSize; }
+
   Standard_EXPORT Standard_Boolean IsValid() const;
   
   //! Return true if the FontName, FontAspect and FontSize are the same.
-  //! Level: Public
   Standard_EXPORT Standard_Boolean IsEqual (const Handle(Font_SystemFont)& theOtherFont) const;
 
+  //! Return TRUE if this is single-stroke (one-line) font, FALSE by default.
+  //! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software.
+  Standard_Boolean IsSingleStrokeFont() const { return myIsSingleLine; }
 
-
-
-  DEFINE_STANDARD_RTTIEXT(Font_SystemFont,Standard_Transient)
-
-protected:
-
-
-
+  //! Set if this font should be rendered as single-stroke (one-line).
+  void SetSingleStrokeFont (Standard_Boolean theIsSingleLine) { myIsSingleLine = theIsSingleLine; }
 
 private:
 
-
-  Handle(TCollection_HAsciiString) MyFontName;
-  Font_FontAspect MyFontAspect;
-  Standard_Integer MyFaceSize;
-  Handle(TCollection_HAsciiString) MyFilePath;
-  Standard_Boolean MyVerification;
-
+  Handle(TCollection_HAsciiString) myFontName;
+  Font_FontAspect                  myFontAspect;
+  Standard_Integer                 myFaceSize;
+  Handle(TCollection_HAsciiString) myFilePath;
+  Standard_Boolean                 myIsSingleLine; //!< single stroke font flag, FALSE by default
+  Standard_Boolean                 myIsDefined;
 
 };
 
-
-
-
-
-
+DEFINE_STANDARD_HANDLE(Font_SystemFont, Standard_Transient)
 
 #endif // _Font_SystemFont_HeaderFile
index 5dd0e7029b393ebd8c683ec526cb9baa66367735..948258483e2752bd0a09037b4d3a7da87eaf7b4f 100644 (file)
@@ -229,13 +229,21 @@ void Geom_ConicalSurface::SetSemiAngle (const Standard_Real Ang) {
 //function : Apex
 //purpose  : 
 //=======================================================================
-
 Pnt Geom_ConicalSurface::Apex () const 
+{
+  return Apex(0L);
+}
+
+Pnt Geom_ConicalSurface::Apex(Standard_Real* const theVParametr) const
 {
 
    XYZ Coord = Position().Direction().XYZ();
    Coord.Multiply (-radius / Tan (semiAngle));
    Coord.Add      (Position().Location().XYZ());
+
+   if (theVParametr)
+     *theVParametr = -radius / Sin(semiAngle);
+
    return Pnt     (Coord);
 }
 
index 40ac5b531ad6b98db7c0e8fd75e57a2e824bddd1..da7c0513fa2f17abd203e40acc8f6efd03e7624a 100644 (file)
@@ -179,7 +179,10 @@ public:
   //! side of the axis of revolution of this cone if the
   //! half-angle at the apex is positive, and on the positive
   //! side of the "main Axis" if the half-angle is negative.
+  //! If theVParametr != 0 (points on the real variable) then it will store
+  //! the V-parameter of the apex.
   Standard_EXPORT gp_Pnt Apex() const;
+  Standard_EXPORT gp_Pnt Apex(Standard_Real* const theVParametr) const;
   
 
   //! The conical surface is infinite in the V direction so
index 5d7b6a2489260795ca4257e4d71fb9e070c17f4b..b45f7575d81a3f8f0827bb2b405c5184f6742468 100644 (file)
@@ -53,6 +53,7 @@
 #include <CSLib.hxx>
 #include <CSLib_NormalStatus.hxx>
 #include <ElCLib.hxx>
+#include <Extrema_ECC.hxx>
 #include <Geom2d_BezierCurve.hxx>
 #include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_Circle.hxx>
 #include <Geom_BSplineCurve.hxx>
 #include <Geom_BSplineSurface.hxx>
 #include <Geom_Circle.hxx>
+#include <Geom_ConicalSurface.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Ellipse.hxx>
 #include <Geom_Hyperbola.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_OffsetCurve.hxx>
+#include <Geom_OffsetSurface.hxx>
 #include <Geom_Parabola.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom_TrimmedCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
 #include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomConvert.hxx>
@@ -962,14 +966,7 @@ void GeomLib::SameRange(const Standard_Real         Tolerance,
   else 
   { // On segmente le resultat
     Handle(Geom2d_TrimmedCurve) TC;
-    Handle(Geom2d_Curve) aCCheck = CurvePtr;
-
-    if(aCCheck->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
-    {
-      aCCheck = Handle(Geom2d_TrimmedCurve)::DownCast(aCCheck)->BasisCurve();
-    }
-
-    if(aCCheck->IsPeriodic())
+    if (CurvePtr->IsPeriodic())
     {
       TC = new Geom2d_TrimmedCurve( CurvePtr, FirstOnCurve, LastOnCurve );
     }
@@ -2737,12 +2734,148 @@ Standard_Boolean GeomLib::IsBzVClosed (const Handle(Geom_BezierSurface)& S,
   return CompareWeightPoles(aPF, 0, aPL, 0, Tol2);
 }
 
+//=======================================================================
+//function : AllowExtendUParameter
+//purpose  : 
+//=======================================================================
+Standard_Boolean GeomLib::IsUTrimAllowed(const GeomAdaptor_Surface& theS,
+                                         const Standard_Real theNewUFirst,
+                                         const Standard_Real theNewULast)
+{
+  const Handle(Geom_Surface) &aSurf = theS.Surface();
+
+  Standard_Real anIsoParameter = theS.FirstVParameter();
+  if (Precision::IsInfinite(anIsoParameter))
+    anIsoParameter = theS.LastVParameter();
+
+  if (Precision::IsInfinite(anIsoParameter))
+    anIsoParameter = 0.0;
+  
+  Handle(Geom_Curve) aC = aSurf->VIso(anIsoParameter);
+
+  if (aC->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+  {
+    // In order to obtain the default curve's work range
+    aC = Handle(Geom_TrimmedCurve)::DownCast(aC)->BasisCurve();
+  }
+
+  return (IsTrimAllowed(aC, theNewUFirst, theNewULast));
+}
+
+//=======================================================================
+//function : AllowExtendVParameter
+//purpose  : 
+//=======================================================================
+Standard_Boolean GeomLib::IsVTrimAllowed(const GeomAdaptor_Surface& theS,
+                                         const Standard_Real theNewVFirst,
+                                         const Standard_Real theNewVLast)
+{
+  const GeomAbs_SurfaceType aSType = theS.GetType();
+
+  const Handle(Geom_Surface) &aSurf = theS.Surface();
+
+  if (aSType == GeomAbs_OffsetSurface)
+  {
+    const Handle(Geom_OffsetSurface) aOS = Handle(Geom_OffsetSurface)::DownCast(aSurf);
+    return IsVTrimAllowed(GeomAdaptor_Surface(aOS->BasisSurface()),
+                          theNewVFirst, theNewVLast);
+  }
+
+  Standard_Real anIsoParameter = theS.FirstUParameter();
+  if (Precision::IsInfinite(anIsoParameter))
+    anIsoParameter = theS.LastUParameter();
+
+  if (Precision::IsInfinite(anIsoParameter))
+    anIsoParameter = 0.0;
+
+  Handle(Geom_Curve) aC = aSurf->UIso(anIsoParameter);
+
+  if (aC.IsNull())
+    return Standard_False;
+
+  if (aC->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+  {
+    // In order to obtain the default curve's work range
+    aC = Handle(Geom_TrimmedCurve)::DownCast(aC)->BasisCurve();
+  }
+
+  if (!IsTrimAllowed(aC, theNewVFirst, theNewVLast))
+    return Standard_False;
+
+  switch (aSType)
+  {
+    case GeomAbs_OtherSurface:
+      return Standard_True;
+    case GeomAbs_Sphere:
+    {
+      if ((theNewVFirst < -M_PI_2) || (theNewVLast > M_PI_2))
+      {
+        // After extending, the surface isoline will go 
+        // through the sphere pole
+        return Standard_False;
+      }
+    }
+    break;
+    case GeomAbs_Cone:
+    {
+      const Handle(Geom_ConicalSurface) aCone = Handle(Geom_ConicalSurface)::DownCast(aSurf);
+      Standard_Real anApexPrm = 0.0;
+      aCone->Apex(&anApexPrm);
+
+      if ((anApexPrm - theNewVFirst)*(theNewVLast - anApexPrm) > 0.0)
+      {
+        // The new boundaries intersect the cone apex
+        return Standard_False;
+      }
+    }
+    break;
+    case GeomAbs_SurfaceOfRevolution:
+    {
+      const Handle(Adaptor3d_HCurve) aCurv = theS.BasisCurve();
+
+      const Standard_Real aParTol = aCurv->Resolution(Precision::Confusion());
+
+      const Standard_Real aParF = theNewVFirst + aParTol,
+                          aParL = theNewVLast - aParTol;
+
+      const Handle(Geom_Line) aL = new Geom_Line(theS.AxeOfRevolution());
+      const GeomAdaptor_Curve aLin(aL);
+
+      Extrema_ECC anExtr(aCurv->Curve(), aLin);
+      anExtr.Perform();
+      if (anExtr.IsDone() && anExtr.NbExt() > 0)
+      {
+        Extrema_POnCurv aP1, aP2;
+        for (Standard_Integer i = 1; i <= anExtr.NbExt(); i++)
+        {
+          if (anExtr.SquareDistance(i) > Precision::SquareConfusion())
+            continue;
+
+          anExtr.Points(i, aP1, aP2);
+          if ((aParF < aP1.Parameter()) && (aP1.Parameter() < aParL))
+          {
+            // After extending, the surface isoline will go 
+            // through the pole (singular point like pole of sphere)
+
+            return Standard_False;
+          }
+        }
+      }
+    }
+    break;
+    default:
+      break;
+  }
+
+  return Standard_True;
+}
+
 //=======================================================================
 //function : CompareWeightPoles
 //purpose  : Checks if thePoles1(i)*theW1(i) is equal to thePoles2(i)*theW2(i)
 //            with tolerance theTol.
 //           It is necessary for not rational B-splines and Bezier curves
-//            to set theW1 and theW2 adresses to zero.
+//            to set theW1 and theW2 addresses to zero.
 //=======================================================================
 static Standard_Boolean CompareWeightPoles(const TColgp_Array1OfPnt& thePoles1, 
                                            const TColStd_Array1OfReal* const theW1,
index b51028d2fc7d3dbb37f96b58118cca991b923397..f08af33cec9da6ca1eb1ad0c56aa48ca6bb40de6 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <Standard_Real.hxx>
 #include <GeomAbs_Shape.hxx>
+#include <Precision.hxx>
 #include <Standard_Integer.hxx>
 #include <Standard_Boolean.hxx>
 #include <TColgp_Array1OfPnt.hxx>
@@ -34,6 +35,7 @@ class gp_Ax2;
 class Geom2d_Curve;
 class gp_GTrsf2d;
 class Adaptor3d_CurveOnSurface;
+class GeomAdaptor_Surface;
 class Geom_BoundedCurve;
 class gp_Pnt;
 class gp_Vec;
@@ -54,7 +56,6 @@ class GeomLib_Tool;
 class GeomLib_PolyFunc;
 class GeomLib_LogSample;
 
-
 //! Geom    Library.    This   package   provides   an
 //! implementation of  functions for basic computation
 //! on geometric entity from packages Geom and Geom2d.
@@ -193,6 +194,71 @@ public:
   Standard_EXPORT static void IsClosed(const Handle(Geom_Surface)& S, const Standard_Real Tol,
                                        Standard_Boolean& isUClosed, Standard_Boolean& isVClosed);
 
+  //! This method determines if the ends of the given curve are
+  //! coincided with given tolerance.
+  //! This is a template-method. Therefore, it can be applied to 
+  //! 2D- and 3D-curve and to Adaptor-HCurve.
+  template <typename TypeCurve>
+  Standard_EXPORT static Standard_Boolean IsClosed(const Handle(TypeCurve)& theCurve,
+                                                   const Standard_Real theTol)
+  {
+    const Standard_Real aFPar = theCurve->FirstParameter(),
+                        aLPar = theCurve->LastParameter();
+
+    if (Precision::IsInfinite(aFPar) || Precision::IsInfinite(aLPar))
+      return Standard_False;
+
+    return (theCurve->Value(aFPar).SquareDistance(theCurve->Value(aLPar)) < theTol*theTol);
+  }
+
+  //! Returns TRUE if theCurve will keep its validity for OCCT-algorithms
+  //! after its trimming in range [theNewFPar, theNewLPar].
+  //! This is a template-method. Therefore, it can be applied to 
+  //! 2D- and 3D-curve.
+  //! Using trimmed curves or Adaptor_HCurves is possible but undesirable
+  //! because theCurve must be parametrized in its default work-range
+  //! in order for this method to work correctly.
+  template <typename TypeCurve>
+  Standard_EXPORT static Standard_Boolean IsTrimAllowed(const Handle(TypeCurve)& theCurve,
+                                                        const Standard_Real theNewFPar,
+                                                        const Standard_Real theNewLPar)
+  {
+    Standard_Real aFPar = theCurve->FirstParameter(),
+                  aLPar = theCurve->LastParameter();
+
+    if ((aFPar <= theNewFPar) && (theNewLPar <= aLPar) && (theNewFPar < theNewLPar))
+    {
+      //New boundaries are in the current ones
+      return Standard_True;
+    }
+
+    if (!theCurve->IsPeriodic())
+    {
+      return Standard_False;
+    }
+
+    const Standard_Real aPeriod = theCurve->Period();
+
+    if ((theNewLPar - theNewFPar - aPeriod) > Epsilon(aPeriod))
+      return Standard_False;
+
+    return Standard_True;
+  }
+
+  //! Returns TRUE if theS will keep its validity for OCCT-algorithms
+  //! after its trimming in range [theNewUFirst, theNewULast] along U-direction
+  Standard_EXPORT static Standard_Boolean
+                                IsUTrimAllowed(const GeomAdaptor_Surface& theS,
+                                               const Standard_Real theNewUFirst,
+                                               const Standard_Real theNewULast);
+
+  //! Returns TRUE if theS will keep its validity for OCCT-algorithms
+  //! after its trimming in range [theNewVFirst, theNewVLast] along V-direction
+  Standard_EXPORT static Standard_Boolean
+                                IsVTrimAllowed(const GeomAdaptor_Surface& theS,
+                                               const Standard_Real theNewVFirst,
+                                               const Standard_Real theNewVLast);
+
   //! Returns true if the poles of U1 isoline and the poles of
   //! U2 isoline of surface are identical according to tolerance criterion.
   //! For rational surfaces Weights(i)*Poles(i) are checked.
index 9af4c31583804640d134af0185e75fbbae3f9a32..12d97aa70f4881a96ea24a3aa571ddf8082634f0 100644 (file)
@@ -41,10 +41,12 @@ extern "C"
   #pragma warning(disable : 4244)
 #endif
 
+#ifdef HAVE_FFMPEG
   #include <libavcodec/avcodec.h>
   #include <libavformat/avformat.h>
   #include <libswscale/swscale.h>
   #include <libavutil/imgutils.h>
+#endif
 
 #ifdef _MSC_VER
   #pragma warning(default : 4244)
index 54c42a130432c7bf3e58e08a6a0d239e626e1a26..a554c13e808574fe4fcfc4e4e64deaf2f874e4ec 100644 (file)
@@ -687,7 +687,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
   }
   //
   Standard_Boolean Arrive, DejaReparti;
-  const Standard_Integer RejectIndexMAX = 250000;
+  const Standard_Integer RejectIndexMAX = 25000;
   Standard_Integer IncKey, RejectIndex;
   gp_Pnt pf,pl;
   //
@@ -736,6 +736,12 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
   Arrive = Standard_False;
   while(!Arrive) //010
   {
+    if (line->NbPoints() >= RejectIndexMAX)
+    {
+      Arrive = Standard_True;
+      break;
+    }
+
     aPrevStatus = aStatus;
 
     LevelOfIterWithoutAppend++;
@@ -745,7 +751,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
       if(DejaReparti) {
         break;
       }
-      RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+      RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
       LevelOfIterWithoutAppend = 0;
     }
     //
@@ -872,7 +878,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
       Param(2)=SvParam[1]; 
       Param(3)=SvParam[2];
       Param(4)=SvParam[3];
-      RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
+      RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
     }
     else  //009 
     {
@@ -903,7 +909,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
           Arrive=Standard_True;
         }
 
-        RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+        RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
         LevelOfEmptyInmyIntersectionOn2S++;
         //
         if(LevelOfEmptyInmyIntersectionOn2S>10)
@@ -1036,7 +1042,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
         case IntWalk_ArretSurPointPrecedent:
           {
             Arrive = Standard_False;
-            RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
+            RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
             break;
           }
         case IntWalk_PasTropGrand:
@@ -1046,7 +1052,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
             Param(3)=SvParam[2]; 
             Param(4)=SvParam[3];
 
-            if(LevelOfIterWithoutAppend > 5)
+            if ((LevelOfIterWithoutAppend > 5) && (aPrevStatus != IntWalk_StepTooSmall))
             {
               for (Standard_Integer i = 0; i < 4; i++)
               {
@@ -1240,7 +1246,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
 
               if (aStatus == IntWalk_ArretSurPoint)
               {
-                RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+                RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
               }
               else
               {
@@ -1321,13 +1327,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
 
                       //
                       LevelOfIterWithoutAppend=0;
-                      RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+                      RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
                     }
                     else
                     {
                       //fail framing divides the step
                       Arrive = Standard_False;
-                      RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+                      RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
                       NoTestDeflection = Standard_True;
                       ChoixIso = SauvChoixIso;
                     }
@@ -1582,7 +1588,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
                       }
                     }
 
-                    RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+                    RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
 
                     if(Arrive && 
                       myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
@@ -1603,7 +1609,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
                   //echec framing on border; division of step 
                   Arrive = Standard_False;
                   NoTestDeflection = Standard_True;
-                  RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+                  RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive);
                 }
               }//$$$ end framing on border (!close)
             }//004 fin TestArret return Arrive = True
@@ -2769,16 +2775,17 @@ SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1,
   return isPrecise;
 }
 
-void IntWalk_PWalking::
-RepartirOuDiviser(Standard_Boolean& DejaReparti,
-                  IntImp_ConstIsoparametric& ChoixIso,
-                  Standard_Boolean& Arrive) 
-
-                  // at the neighborhood of a point, there is a fail of marching 
-                  // it is required to divide the steps to try to continue
-                  // if the step is too small if we are on border
-                  // restart in another direction if it was not done, otherwise stop
-
+//=======================================================================
+//function : RepartirOuDiviser
+//purpose  : at the neighborhood of a point, there is a fail of marching 
+// it is required to divide the steps to try to continue
+// if the step is too small if we are on border
+// restart in another direction if it was not done, otherwise stop
+//=======================================================================
+void IntWalk_PWalking::RepartirOuDiviser(const IntWalk_StatusDeflection& theCurrentStatus,
+                                         Standard_Boolean& DejaReparti,
+                                         IntImp_ConstIsoparametric& ChoixIso,
+                                         Standard_Boolean& Arrive)
 {
   //  Standard_Integer i;
   if (Arrive) {    //restart in the other direction
@@ -2821,11 +2828,12 @@ RepartirOuDiviser(Standard_Boolean& DejaReparti,
     }
   }  
   else  {
-    if (    pasuv[0]*0.5 < ResoU1
-      &&  pasuv[1]*0.5 < ResoV1
-      &&  pasuv[2]*0.5 < ResoU2
-      &&  pasuv[3]*0.5 < ResoV2
-      ) {
+    if ((theCurrentStatus == IntWalk_StepTooSmall) ||
+            (pasuv[0] * 0.5 < ResoU1
+            &&  pasuv[1] * 0.5 < ResoV1
+            &&  pasuv[2] * 0.5 < ResoU2
+            &&  pasuv[3] * 0.5 < ResoV2))
+    {
         if (!previoustg) {
           tglast = Standard_True;      // IS IT ENOUGH ????
         }
index e4dab8ed9aef327ec066dc93f454fef440b98433..b2efdb1ceab979b3e305808644d55a1e11133d8f 100644 (file)
@@ -130,7 +130,10 @@ public:
   
   Standard_EXPORT Standard_Boolean TestArret (const Standard_Boolean DejaReparti, TColStd_Array1OfReal& Param, IntImp_ConstIsoparametric& ChoixIso);
   
-  Standard_EXPORT void RepartirOuDiviser (Standard_Boolean& DejaReparti, IntImp_ConstIsoparametric& ChoixIso, Standard_Boolean& Arrive);
+  Standard_EXPORT void RepartirOuDiviser(const IntWalk_StatusDeflection& theCurrentStatus, 
+                                         Standard_Boolean& DejaReparti,
+                                         IntImp_ConstIsoparametric& ChoixIso,
+                                         Standard_Boolean& Arrive);
   
     void AddAPoint (Handle(IntSurf_LineOn2S)& line, const IntSurf_PntOn2S& POn2S);
   
index 8da855d76593b460ae0302925faa2e22a8d6b6bf..362a0269f96fdb8defd921b57285bfb0156ee377 100644 (file)
@@ -117,7 +117,7 @@ LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face&  Spine,
 
   myProfile  = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3);
 
-  myDPrism.Perform(mySpine,myProfile,gp::XOY()); 
+  myDPrism.Perform(mySpine,myProfile,gp::XOY(), GeomAbs_Arc, Standard_False); 
 
 
   if (myDPrism.IsDone()) {
@@ -370,7 +370,7 @@ LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face&   Spine,
   myProfile1 = BRepLib_MakeEdge(Vert4, Vert1);
   
   myProfile = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3);
-  myDPrism.Perform(mySpine,myProfile,gp::XOY()); 
+  myDPrism.Perform(mySpine,myProfile,gp::XOY(), GeomAbs_Arc, Standard_False); 
 
 
   if (myDPrism.IsDone()) {
diff --git a/src/OpenGl/OpenGl_AVIWriter.cxx b/src/OpenGl/OpenGl_AVIWriter.cxx
new file mode 100644 (file)
index 0000000..0bb92ca
--- /dev/null
@@ -0,0 +1,471 @@
+// Created on: 2007-04-15
+// Created by: Alexey MORENOV & Alexander GRIGORIEV
+// Copyright (c) 2007-2014 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 <OpenGl_AVIWriter.hxx>
+
+#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
+  #ifdef _MSC_VER
+    #pragma comment (lib, "vfw32.lib")
+  #endif
+
+OpenGl_AVIWriter* OpenGl_AVIWriter::MyAVIWriterInstance = 0L;
+
+OpenGl_AVIWriter * OpenGl_AVIWriter::GetInstance()
+{
+  return MyAVIWriterInstance;
+}
+
+//=======================================================================
+//function : OpenGl_AVIWriter
+//purpose  : 
+//=======================================================================
+
+Standard_EXPORT OpenGl_AVIWriter::OpenGl_AVIWriter
+                 (const wchar_t *  theFileName, 
+                  DWORD            dwCodec /* = mmioFOURCC('M','P','G','4') */,
+                  Standard_Integer theFrameRate /* = 25 */)
+  : myhHeap             (0L),
+    myhWindow           (0L),
+    myhAviDC            (0L),
+    mylpBits            (0L),
+    mylSample           (0L),
+    mypAviFile          (0L),
+    mypAviStream        (0L),
+    mypAviCompressedStream(0L),
+    myFileName          (0L),
+    myIsAllowRecord     (Standard_False),
+    myAppendFuncSelector(1)         //0=Dummy       1=FirstTime     2=Usual
+{
+  ::AVIFileInit();
+  if (theFileName != 0L && theFileName[0] != L'\0') {
+
+    const size_t aLen = wcslen(theFileName) + 1;
+    myFileName = new wchar_t [aLen];
+    memcpy(myFileName, theFileName, aLen * sizeof(wchar_t));
+    myErrMsg = "Method Succeeded";
+
+    pAppendFrame[0]= &OpenGl_AVIWriter::AppendDummy;
+    pAppendFrame[1]= &OpenGl_AVIWriter::AppendFrameFirstTime;
+    pAppendFrame[2]= &OpenGl_AVIWriter::AppendFrameUsual;
+
+    pAppendFrameBits[0]=&OpenGl_AVIWriter::AppendDummyBits;
+    pAppendFrameBits[1]=&OpenGl_AVIWriter::AppendFrameBitsFirstTime;
+    pAppendFrameBits[2]=&OpenGl_AVIWriter::AppendFrameBitsUsual;
+
+    MyAVIWriterInstance = this;
+
+    ZeroMemory(&myAviStreamInfo,sizeof(AVISTREAMINFOW));
+    myAviStreamInfo.fccType             = streamtypeVIDEO;
+    myAviStreamInfo.fccHandler          = dwCodec;
+    myAviStreamInfo.dwScale             = 1;
+    myAviStreamInfo.dwRate              = theFrameRate; // Frames Per Second;
+    myAviStreamInfo.dwQuality           = 100;/*//-1;  // Default Quality*/
+
+    ZeroMemory(&myAviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
+    myAviCompressOptions.fccType        = streamtypeVIDEO;
+    myAviCompressOptions.fccHandler     = myAviStreamInfo.fccHandler;
+    myAviCompressOptions.dwFlags        =
+      AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID|AVICOMPRESSF_DATARATE;
+    myAviCompressOptions.dwKeyFrameEvery  = 1;
+    myAviCompressOptions.dwBytesPerSecond = 125000;
+    myAviCompressOptions.dwQuality      = 100;
+  }
+}
+
+//=======================================================================
+//function : ~OpenGl_AVIWriter
+//purpose  : 
+//=======================================================================
+
+Standard_EXPORT OpenGl_AVIWriter::~OpenGl_AVIWriter(void)
+{
+  ReleaseMemory();
+  AVIFileExit();
+  if (myFileName)
+    delete [] myFileName;
+  MyAVIWriterInstance = 0L;
+}
+
+//=======================================================================
+//function : StartRecording
+//purpose  : 
+//=======================================================================
+
+void OpenGl_AVIWriter::StartRecording(const HANDLE hWin)
+{
+  if (hWin != NULL)
+    myhWindow = hWin;
+  myIsAllowRecord = Standard_True;
+}
+
+//=======================================================================
+//function : StopRecording
+//purpose  : 
+//=======================================================================
+
+void OpenGl_AVIWriter::StopRecording()
+{
+  myIsAllowRecord = Standard_False;
+}
+
+//=======================================================================
+//function : ReleaseMemory
+//purpose  : 
+//=======================================================================
+
+void OpenGl_AVIWriter::ReleaseMemory()
+{
+  myAppendFuncSelector=0;      //Point to DummyFunction
+
+  if (myhAviDC)
+  {
+    DeleteDC(myhAviDC);
+    myhAviDC=NULL;
+  }
+  if (mypAviCompressedStream)
+  {
+    AVIStreamRelease(mypAviCompressedStream);
+    mypAviCompressedStream=NULL;
+  }
+  if (mypAviStream)
+  {
+    AVIStreamRelease(mypAviStream);
+    mypAviStream=NULL;
+  }
+  if (mypAviFile)
+  {
+    AVIFileRelease(mypAviFile);
+    mypAviFile=NULL;
+  }
+  if (mylpBits)
+  {
+    HeapFree(myhHeap,HEAP_NO_SERIALIZE,mylpBits);
+    mylpBits=NULL;
+  }
+  if (myhHeap)
+  {
+    HeapDestroy(myhHeap);
+    myhHeap=NULL;
+  }
+}
+
+//=======================================================================
+//function : SetErrorMessage
+//purpose  : 
+//=======================================================================
+
+void OpenGl_AVIWriter::SetErrorMessage(const char * theErrorMessage)
+{
+  myErrMsg = theErrorMessage;
+}
+
+//=======================================================================
+//function : InitMovieCreation
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::InitMovieCreation (int nFrameWidth,
+                                             int nFrameHeight,
+                                             int nBitsPerPixel)
+{
+  int  nMaxWidth=GetSystemMetrics(SM_CXSCREEN),
+       nMaxHeight=GetSystemMetrics(SM_CYSCREEN);
+
+  myhAviDC = CreateCompatibleDC(NULL);
+  if (myhAviDC == NULL)
+  {
+    SetErrorMessage("Unable to Create Compatible DC");
+    return E_FAIL;
+  }
+
+  if (nFrameWidth > nMaxWidth)
+    nMaxWidth= nFrameWidth;
+  if (nFrameHeight > nMaxHeight)
+    nMaxHeight = nFrameHeight;
+
+  myhHeap = HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0);
+  if (myhHeap == NULL)
+  {
+    SetErrorMessage("Unable to Create Heap");
+    return E_FAIL;
+  }
+
+  mylpBits = HeapAlloc(myhHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE,
+                     nMaxWidth*nMaxHeight*4);
+  if (mylpBits == NULL)
+  {
+    SetErrorMessage("Unable to Allocate Memory on Heap");
+    return E_FAIL;
+  }
+
+  HRESULT hr;
+  hr = ::AVIFileOpenW(&mypAviFile, myFileName, OF_CREATE|OF_WRITE, NULL);
+  if (!hr == AVIERR_OK)
+  {
+    SetErrorMessage("Unable to Create the Movie File");
+    return E_FAIL;
+  }
+
+  myAviStreamInfo.dwSuggestedBufferSize = nMaxWidth * nMaxHeight * 4;
+  SetRect(&myAviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight);
+  wcsncpy(myAviStreamInfo.szName, L"Video Stream", 64);
+
+  if (FAILED(AVIFileCreateStreamW(mypAviFile, &mypAviStream, &myAviStreamInfo)))
+  {
+    SetErrorMessage("Unable to Create Video Stream in the Movie File");
+    return E_FAIL;
+  }
+
+  if (FAILED(AVIMakeCompressedStream(&mypAviCompressedStream,
+                                     mypAviStream,
+                                     &myAviCompressOptions,
+                                     NULL)))
+  {
+    // One reason this error might occur is if you are using a Codec that is not
+    // available on your system. Check the mmioFOURCC() code you are using and
+    // make sure you have that codec installed properly on your machine.
+    SetErrorMessage("Unable to Create Compressed Stream: "
+                    "Check your CODEC options");
+    return E_FAIL;
+  }
+
+  BITMAPINFO bmpInfo;
+  ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
+  bmpInfo.bmiHeader.biPlanes            = 1;
+  bmpInfo.bmiHeader.biWidth             = nFrameWidth;
+  bmpInfo.bmiHeader.biHeight            = nFrameHeight;
+  bmpInfo.bmiHeader.biCompression       = BI_RGB;
+  bmpInfo.bmiHeader.biBitCount          = static_cast<WORD>(nBitsPerPixel);
+  bmpInfo.bmiHeader.biSize              = sizeof(BITMAPINFOHEADER);
+  bmpInfo.bmiHeader.biSizeImage         = (bmpInfo.bmiHeader.biWidth *
+                                           bmpInfo.bmiHeader.biHeight*
+                                           bmpInfo.bmiHeader.biBitCount)/8;
+
+  if (FAILED(AVIStreamSetFormat(mypAviCompressedStream,
+                                0,
+                                (LPVOID)&bmpInfo,
+                                bmpInfo.bmiHeader.biSize)))
+  {
+    // One reason this error might occur is if your bitmap does not meet
+    // the Codec requirements.
+    // For example, 
+    //   your bitmap is 32bpp while the Codec supports only 16 or 24 bpp; Or
+    //   your bitmap is 274 * 258 size, while the Codec supports only sizes
+    //   that are powers of 2; etc...
+    // Possible solution to avoid this is: make your bitmap suit the codec
+    // requirements, or Choose a codec that is suitable for your bitmap.
+    SetErrorMessage("Unable to Set Video Stream Format");
+    return E_FAIL;
+  }
+
+  return S_OK;  // Everything went Fine
+}
+
+//=======================================================================
+//function : AppendFrameFirstTime
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::AppendFrameFirstTime(HBITMAP  hBitmap)
+{
+  BITMAP Bitmap;
+  GetObject(hBitmap, sizeof(BITMAP), &Bitmap);
+
+  if (SUCCEEDED(InitMovieCreation(Bitmap.bmWidth, 
+                                  Bitmap.bmHeight, 
+                                  Bitmap.bmBitsPixel)))
+  {
+    myAppendFuncSelector = 2;      //Point to the UsualAppend Function
+    return AppendFrameUsual(hBitmap);
+  }
+
+  ReleaseMemory();
+  return E_FAIL;
+}
+
+//=======================================================================
+//function : AppendFrameUsual
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::AppendFrameUsual(HBITMAP hBitmap)
+{
+  BITMAPINFO    bmpInfo;
+
+  bmpInfo.bmiHeader.biBitCount=0;
+  bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+
+  GetDIBits(myhAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
+
+  bmpInfo.bmiHeader.biCompression=BI_RGB;
+
+  GetDIBits(myhAviDC,
+            hBitmap,
+            0,
+            bmpInfo.bmiHeader.biHeight,
+            mylpBits,
+            &bmpInfo,
+            DIB_RGB_COLORS);
+
+  if (FAILED(AVIStreamWrite(mypAviCompressedStream,
+                            mylSample++,
+                            1,
+                            mylpBits,
+                            bmpInfo.bmiHeader.biSizeImage,
+                            0,
+                            NULL,
+                            NULL)))
+  {
+    SetErrorMessage("Unable to Write Video Stream to the output Movie File");
+    ReleaseMemory();
+    return E_FAIL;
+  }
+
+  return S_OK;
+}
+
+//=======================================================================
+//function : AppendDummy
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::AppendDummy(HBITMAP)
+{
+  return E_FAIL;
+}
+
+//=======================================================================
+//function : AppendNewFrame
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::AppendNewFrame(HBITMAP hBitmap)
+{
+  return (this->*pAppendFrame[myAppendFuncSelector])((HBITMAP)hBitmap);
+}
+
+//=======================================================================
+//function : AppendNewFrame
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::AppendNewFrame(int nWidth,
+                                         int nHeight,
+                                         LPVOID pBits,
+                                         int nBitsPerPixel)
+{
+  return (this->*pAppendFrameBits[myAppendFuncSelector])(nWidth,
+                                                          nHeight,
+                                                          pBits,
+                                                          nBitsPerPixel);
+}
+
+//=======================================================================
+//function : AppendFrameFirstTime
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::AppendFrameBitsFirstTime(int nWidth,
+                                                   int nHeight,
+                                                   LPVOID pBits,
+                                                   int nBitsPerPixel)
+{
+  if (SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel)))
+  {
+    myAppendFuncSelector=2;    //Point to the UsualAppend Function
+    return AppendFrameBitsUsual(nWidth, nHeight, pBits, nBitsPerPixel);
+  }
+  ReleaseMemory();
+
+  return E_FAIL;
+}
+
+//=======================================================================
+//function : AppendFrameUsual
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::AppendFrameBitsUsual(int nWidth,
+                                               int nHeight,
+                                               LPVOID pBits,
+                                               int nBitsPerPixel)
+{
+  DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8;
+
+  if (FAILED(AVIStreamWrite(mypAviCompressedStream,
+                            mylSample++,
+                            1,
+                            pBits,
+                            dwSize,
+                            0,
+                            NULL,
+                            NULL)))
+  {
+    SetErrorMessage("Unable to Write Video Stream to the output Movie File");
+    ReleaseMemory();
+    return E_FAIL;
+  }
+
+  return S_OK;
+}
+
+//=======================================================================
+//function : AppendDummy
+//purpose  : 
+//=======================================================================
+
+HRESULT OpenGl_AVIWriter::AppendDummyBits(int /*nWidth*/,
+                                          int /*nHeight*/,
+                                          LPVOID /*pBits*/,
+                                          int /*nBitsPerPixel*/)
+{
+  return E_FAIL;
+}
+
+//=======================================================================
+//function : AviWriter
+//purpose  : 
+//=======================================================================
+
+void OpenGl_AVIWriter_AVIWriter(void * pp,
+                                int  nWidth,
+                                int  nHeight,
+                                int  nBitsPerPixel)
+{
+  OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance();
+  if (anInst != 0L)
+    if (anInst->IsRecording())
+    {
+      anInst->AppendNewFrame(nWidth, nHeight, pp, nBitsPerPixel);
+    }
+}
+
+//=======================================================================
+//function : AllowWriting
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin)
+{
+  Standard_Boolean aResult(Standard_False);
+  const OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance();
+  if (anInst != 0L) {
+    if (hWin == NULL || anInst->HWindow() == hWin)
+      aResult = static_cast<Standard_Boolean> (anInst->IsRecording());
+  }
+  return aResult;
+}
+
+#endif
diff --git a/src/OpenGl/OpenGl_AVIWriter.hxx b/src/OpenGl/OpenGl_AVIWriter.hxx
new file mode 100644 (file)
index 0000000..842b5b2
--- /dev/null
@@ -0,0 +1,191 @@
+// Created on: 2007-04-15
+// Created by: Alexey MORENOV & Alexander GRIGORIEV
+// Copyright (c) 2007-2014 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 __OPENGL_AVIWRITER_H
+#define __OPENGL_AVIWRITER_H
+
+#if defined(_WIN32)
+  #include <windows.h>
+#endif
+
+#include <Standard_Macro.hxx>
+
+#if defined(_MSC_VER) && !defined(OCCT_UWP)
+
+#include <stdlib.h>
+#include <vfw.h>
+#include <TCollection_AsciiString.hxx>
+
+/**
+ * Class providing the API to record AVI files using a codec installed in the
+ * system -- Only on Windows NT/2k/XP/Vista platform under MS Visual Studio.
+ * The following tasks are supported:
+ * <ol>
+ *
+ * <li>Creation of AVI data stream: launched by the constructor.
+ * The constructor accepts the filename, FOURCC video code and the frame rate
+ * setting as parameters.
+ * The default codec name used here is MPG4. To use a different codec, pass
+ * its FOURCC value as the input parameter for dwCodec.
+ * For example,
+ * <ul>
+ * <li>pass mmioFOURCC('D','I','V','X') to use DIVX codec, or</li>
+ * <li>pass mmioFOURCC('I','V','5','0') to use IV50 codec etc...</li>
+ * </ul>
+ * Also, you can pass just 0 to avoid the codecs altogether. In that case,
+ * the frames would be saved as they are without any compression; However,
+ * the output movie file size would be very huge in that case.
+ *
+ * Finally, make sure you have the codec installed on the machine before
+ * passing its Fourcc here.
+ * </li>
+ * <li>
+ * Start the recording: call the method StartRecording(). This method should be
+ * called at least once; execution of the constructor does not begin the
+ * process.
+ * </li>
+ * <li>
+ * Stop the recording: call the method StopRecording(). Can be omitted if the
+ * next to execute would be the destructor.
+ * </li>
+ * <li>
+ * Close the AVI file and exit the process of recording. This is done
+ * automatically by the destructor.
+ * </li>
+ * </ol>
+ */
+class OpenGl_AVIWriter
+{
+public:
+
+  /**
+   * Constructor. Initializes the internal data structures, prepares for the
+   * creation of an AVI stream when the first frame is ready to be captured.
+   * @param theFileName
+   *   Name of the output movie file to create.
+   * @param theCodec
+   *   FourCC of the Video Codec to be used for compression
+   * @param theFrameRate
+   *   The Frames Per Second (FPS) setting to be used for the movie
+   */
+  Standard_EXPORT OpenGl_AVIWriter(const wchar_t * theFileName, 
+                                   DWORD theCodec = mmioFOURCC('M','P','G','4'),
+                                   Standard_Integer theFrameRate = 25);
+
+  /**
+   * Destructor: closes the movie file and flushes all the frames
+   */
+  Standard_EXPORT ~OpenGl_AVIWriter     ();
+
+  /**
+   * Begin the recording.
+   */
+  Standard_EXPORT void    StartRecording(const HANDLE hWin = NULL);
+
+  /**
+   * Stop the recording (can be restarted using StartRecording()).
+   */
+  Standard_EXPORT void    StopRecording ();
+
+  /**
+   * Query the state of recording.
+   */
+  Standard_Boolean IsRecording () const { return myIsAllowRecord; }
+
+  /**
+   * Returns the last error message, if any.
+   */
+  const TCollection_AsciiString& GetLastErrorMessage() const
+  { return myErrMsg; }
+
+  /**
+   * Get the instance of AVI Writer class.
+   */ 
+  static Standard_EXPORT OpenGl_AVIWriter * GetInstance ();
+
+  /**
+   * Get the Window handle that contains the actual OpenGl context.
+   */
+  HANDLE HWindow () const
+  { return myhWindow; }
+
+  /// Inserts the given HBitmap into the movie as a new Frame at the end.
+  HRESULT         AppendNewFrame(HBITMAP hBitmap);
+
+  /// Inserts the given bitmap bits into the movie as a new Frame at the end.
+  /// The width, height and nBitsPerPixel are the width, height and bits per pixel
+  /// of the bitmap pointed to by the input pBits.
+  HRESULT         AppendNewFrame(int nWidth,
+                                 int nHeight,
+                                 LPVOID pBits,
+                                 int nBitsPerPixel);
+
+private:
+
+  void call_avi();
+
+private:
+  static OpenGl_AVIWriter       * MyAVIWriterInstance;
+  Standard_Boolean                myIsAllowRecord;
+
+  BYTE                          * mypBits;
+  UINT                            myWidth;
+  UINT                            myHeight;
+
+  HDC                   myhAviDC;
+  HANDLE                myhHeap;
+  HANDLE                myhWindow;   // window containing the OGL context 
+  LPVOID                mylpBits;    // Useful to hold the bitmap content if any
+  LONG                  mylSample;   // Keeps track of the current Frame Index
+  PAVIFILE              mypAviFile;
+  PAVISTREAM            mypAviStream;
+  PAVISTREAM            mypAviCompressedStream;
+  AVISTREAMINFOW        myAviStreamInfo;
+  AVICOMPRESSOPTIONS    myAviCompressOptions;
+  wchar_t *             myFileName; // Holds the Output Movie File Name
+  TCollection_AsciiString myErrMsg; // Holds the Last Error Message, if any
+
+  int                   myAppendFuncSelector;  //0=Dummy 1=FirstTime 2=Usual
+
+  HRESULT               AppendFrameFirstTime(HBITMAP );
+  HRESULT               AppendFrameUsual(HBITMAP);
+  HRESULT               AppendDummy(HBITMAP);
+  HRESULT       (OpenGl_AVIWriter::*pAppendFrame[3])(HBITMAP hBitmap);
+
+  HRESULT               AppendFrameBitsFirstTime(int, int, LPVOID,int );
+  HRESULT               AppendFrameBitsUsual(int, int, LPVOID,int );
+  HRESULT               AppendDummyBits(int, int, LPVOID,int );
+  HRESULT       (OpenGl_AVIWriter::*pAppendFrameBits[3])(int, int, LPVOID, int);
+
+  /// Takes care of creating the memory, streams, compression options etc.
+  /// required for the movie
+  HRESULT InitMovieCreation(int nFrameWidth,int nFrameHeight,int nBitsPerPixel);
+
+  /// Takes care of releasing the memory and movie related handles
+  void ReleaseMemory();
+
+  /// Sets the Error Message
+  void SetErrorMessage(const char * theErrMsg);
+};
+
+Standard_EXPORT void OpenGl_AVIWriter_AVIWriter(void * pp,
+                                                int  nWidth,
+                                                int  nHeight,
+                                                int  nBitsPerPixel);
+
+Standard_EXPORT Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin);
+
+#endif // _MSC_VER
+#endif
index 5b6bb69aa655c6d4d2ccd42068e5d443f17b72f4..711eae6ed5e5467d42cc3451ccd6f0d6960fbeca 100644 (file)
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_ArbFBO.hxx>
 
+#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
+#include <OpenGl_AVIWriter.hxx>
+#endif
+
 namespace
 {
   //! Format Frame Buffer format for logging messages.
@@ -523,6 +527,24 @@ void OpenGl_View::Redraw()
     }
   }
 
+#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
+  if (OpenGl_AVIWriter_AllowWriting(myWindow->PlatformWindow()->NativeHandle()))
+  {
+    GLint params[4];
+    glGetIntegerv(GL_VIEWPORT, params);
+    int nWidth = params[2] & ~0x7;
+    int nHeight = params[3] & ~0x7;
+
+    const int nBitsPerPixel = 24;
+    GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
+
+    glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    glReadPixels(0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
+    OpenGl_AVIWriter_AVIWriter(aDumpData, nWidth, nHeight, nBitsPerPixel);
+    delete[] aDumpData;
+  }
+#endif
+
   if (myRenderParams.Method == Graphic3d_RM_RAYTRACING
    && myRenderParams.IsGlobalIlluminationEnabled)
   {
diff --git a/src/Poly/Poly_IBuffer.cxx b/src/Poly/Poly_IBuffer.cxx
new file mode 100644 (file)
index 0000000..2d88a07
--- /dev/null
@@ -0,0 +1,546 @@
+// File:      Poly_IBuffer.cxx
+// Created:   15.06.07 08:32
+// Author:    Alexander GRIGORIEV
+// Copyright: Open CASCADE 2007
+
+#include <Poly_IBuffer.hxx>
+#include <Precision.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <Standard_ProgramError.hxx>
+
+#pragma warning(disable:4291)
+
+IMPLEMENT_STANDARD_RTTIEXT(Poly_IBuffer, Standard_Transient)
+
+static const Standard_Size INDEXLEN = 10;
+#ifdef _DEBUG
+int Poly_IBuffer::GlobalCount = 0;
+#endif
+
+//=======================================================================
+//function : GetZ
+//purpose  : local function
+//=======================================================================
+
+inline Standard_Real GetZ (const Poly_IBuffer::Interval& theInt,
+                           const Standard_Real           theX)
+{
+  return (theInt.XZ(0).Y() + (theInt.XZ(1).Y() - theInt.XZ(0).Y()) *
+          (theX - theInt.XZ(0).X()) / (theInt.XZ(1).X() - theInt.XZ(0).X()));
+}
+
+//=======================================================================
+//function : Poly_IBuffer
+//purpose  : Constructor
+//=======================================================================
+
+Poly_IBuffer::Poly_IBuffer (const Poly_IBuffer::Interval&            theInterval,
+                            const Standard_Real                      theTol,
+                            const Handle(NCollection_BaseAllocator)& theAlloc)
+{
+  Init (theInterval, theTol, theAlloc);
+#ifdef _DEBUG
+  myCount = GlobalCount++;
+#endif
+}
+
+//=======================================================================
+//function : Init
+//purpose  : Initialization, to be used after the default constructor.
+//=======================================================================
+
+void Poly_IBuffer::Init (const Interval&                          theInterval,
+                         const Standard_Real                      theTol,
+                         const Handle(NCollection_BaseAllocator)& theAlloc)
+{
+  clearIntervals();
+  myTol = theTol;
+  if (theAlloc.IsNull())
+    myAllocator = new NCollection_IncAllocator(1000);
+  else
+    myAllocator = theAlloc;
+
+  myMinOrd = Precision::Infinite();
+  myMaxOrd = -Precision::Infinite();
+  myNIntervals = 1;
+
+  // Create the first interval covering all possible X coordinates 
+  Interval * pInt = &theInterval.Clone(myAllocator);
+  // Create the index array
+  myIndex = static_cast <PInterval *>
+    (myAllocator->Allocate((INDEXLEN+1) * sizeof(PInterval)));
+  const Standard_Real anXmin = theInterval.XZ(0).X();
+  const Standard_Real aXstep = (theInterval.XZ(1).X() - anXmin) / INDEXLEN;
+  for (Standard_Size i = 0; i <= INDEXLEN; i++) {
+    myIndex[i].X   = Standard_Real (anXmin + i*aXstep);
+    myIndex[i].Int = pInt;
+  }
+}
+
+//=======================================================================
+//function : ~Poly_IBuffer
+//purpose  : Destructor
+//=======================================================================
+
+Poly_IBuffer::~Poly_IBuffer ()
+{
+  clearIntervals();
+}
+
+//=======================================================================
+//function : Clone
+//purpose  : Create a copy of the given Interval in the given allocator.
+//=======================================================================
+
+Poly_IBuffer::Interval& Poly_IBuffer::Interval::Clone
+                        (const Handle(NCollection_BaseAllocator)& theAlloc,
+                         Poly_IBuffer::Interval *                 theDest) const
+{
+  if (theDest == 0L)
+    theDest = new (theAlloc) Interval(myXZ[0], myXZ[1], 0UL);
+  else {
+    theDest->myXZ[0] = myXZ[0];
+    theDest->myXZ[1] = myXZ[1];
+    theDest->myNext  = 0L;
+    theDest->myModID = 0UL;
+    theDest->U.myModX  = RealLast();
+  }
+  return * theDest;
+}
+
+//=======================================================================
+//function : NewRejectID
+//purpose  : Generator of unique Reject ID values.
+//=======================================================================
+
+unsigned long Poly_IBuffer::Interval::NewRejectID ()
+{
+  static unsigned long aValue(0UL);
+  aValue += 4;
+  return aValue;
+}
+
+//=======================================================================
+//function : IsIntersect
+//purpose  : Check for intersection, returns the intersection point abscissa.
+//   @return
+//   True if a modification or removal is required. The decision is based
+//   on 2 lower bits of myRejectID value:
+//    - 0 : remove this interval;
+//    - 1 : keep the lower abscisse part, remove the upper part;
+//    - 2 : keep the upper abscisse part, remove the lower part;
+//    - 3 : remove the middle.
+//=======================================================================
+
+Standard_Boolean Poly_IBuffer::Interval::IsIntersect
+                                     (const Poly_IBuffer::Interval& theInt,
+                                      const Standard_Real           theTol,
+                                      const unsigned long           theRejectID)
+{
+  Standard_Boolean aRes(Standard_False);
+  Standard_Integer aResult (-1);
+  Standard_Real anAbscisse (Precision::Infinite());
+  const Standard_Real anXtol[2] = {
+    myXZ[0].X() + theTol,
+    myXZ[1].X() - theTol
+  };
+  if (theInt.myXZ[0].X() < anXtol[1] && theInt.myXZ[1].X() > anXtol[0]) {
+    const gp_XY aVec[3] = {
+      gp_XY(theInt.myXZ[0] - myXZ[0]),
+      gp_XY(myXZ[1] - myXZ[0]),
+      gp_XY(theInt.myXZ[1] - theInt.myXZ[0])
+    };
+    const Standard_Real aDirProd = aVec[1] ^ aVec[2];
+    if (aDirProd  > Precision::Intersection()) {
+      // Intersection coefficients
+      const Standard_Real fInter[2] = {
+        (aVec[0] ^ aVec[2]) / aDirProd,
+        (aVec[0] ^ aVec[1]) / aDirProd
+      };
+      anAbscisse = (myXZ[1].X() * fInter[0] + myXZ[0].X() * (1.-fInter[0]));
+      if (anAbscisse > anXtol[0] && fInter[1] > 0.)
+        if (anAbscisse < anXtol[1] && fInter[1] < 1.) {
+          if (theInt.myXZ[0].X() < anXtol[0])
+            aResult = 2;  // keep upper abscissa
+          else {
+            anAbscisse = theInt.myXZ[0].X();
+            aResult = 3;
+          }
+        } else {
+          if (theInt.myXZ[0].X() > anXtol[0]) {
+            anAbscisse = theInt.myXZ[0].X();
+            if (theInt.myXZ[1].X() > anXtol[1])
+              aResult = 1; // keep lower abscissa
+            else
+              aResult = 3;
+          } else
+            if (theInt.myXZ[1].X() > anXtol[1])
+              aResult = 0; // remove
+            else {
+              anAbscisse = theInt.myXZ[1].X();
+              aResult = 2; // keep upper abscissa
+            }
+        }
+    } else {
+      Standard_Real fInter[2] = { 2., -1. };
+      if (aDirProd  < -Precision::Intersection()) {
+        // Intersection coefficients
+        fInter[0] = (aVec[0] ^ aVec[2]) / aDirProd;
+        fInter[1] = (aVec[0] ^ aVec[1]) / aDirProd;
+        anAbscisse = (myXZ[1].X() * fInter[0] + myXZ[0].X() * (1.-fInter[0]));
+      } else if (GetZ (theInt, myXZ[0].X()) < myXZ[0].Y())
+        anAbscisse = theInt.myXZ[0].X();
+
+      if (anAbscisse < anXtol[1] &&
+          fInter[1] < 1.-Precision::Intersection())
+        if (anAbscisse > anXtol[0] &&
+            fInter[1] > Precision::Intersection())
+        {
+          if (theInt.myXZ[1].X() > anXtol[1])
+            aResult = 1;  // keep lower abscissa
+          else
+            aResult = 3;
+        } else {
+          if (theInt.myXZ[0].X() > anXtol[0]) {
+            anAbscisse = theInt.myXZ[0].X();
+            if (theInt.myXZ[1].X() > anXtol[1])
+              aResult = 1; // keep lower abscissa
+            else
+              aResult = 3;
+          } else
+            if (theInt.myXZ[1].X() > anXtol[1]) {
+              aResult = 0; // remove
+              aRes = Standard_True;
+            } else {
+              anAbscisse = theInt.myXZ[1].X();
+              aResult = 2; //keep upper abscissa
+            }
+        }
+    }
+  }
+  if (aResult >= 0) {
+    myModID = theRejectID + aResult;
+    U.myModX = anAbscisse;
+    aRes = Standard_True;
+  }
+  return aRes;
+}
+
+//=======================================================================
+//function : Trim
+//purpose  : Shorten the interval to the new value of Xmax.
+//=======================================================================
+
+void Poly_IBuffer::Interval::Trim (const Standard_Real    theX,
+                                   const Standard_Integer theMode)
+{
+  const Standard_Real aZ = GetZ(* this, theX);
+  switch (theMode) {
+  case 3:
+    myModID = 0UL;
+  case 1:
+    Standard_ProgramError_Raise_if
+        (theX - myXZ[0].X() < Precision::Confusion() || theX > myXZ[1].X(),
+         "Trim error");
+    myXZ[1].SetCoord(theX, aZ);
+    break;
+  case 2:
+    Standard_ProgramError_Raise_if
+        (theX < myXZ[0].X() || myXZ[1].X() - theX < Precision::Confusion(),
+         "Trim error");
+    myXZ[0].SetCoord(theX, aZ);
+    break;
+  }
+}
+
+//=======================================================================
+//function : AddInterval
+//purpose  : Add one interval to buffer.
+//=======================================================================
+
+Poly_IBuffer::Interval * Poly_IBuffer::AddInterval
+                             (const Poly_IBuffer::Interval& theInterval,
+                              Poly_IBuffer::Interval *      theStart)
+{
+//  Variables:
+// aLastModified: Newly created interval in the buffer. It is returned by
+//                this method so that it can be passed as theStart
+//                for the next call (next interval).
+// aInt:          Currently checked/processed interval
+// aBracket[0,1]: The first and the last in the chain of intervals where
+//                the modification can be done, used for local optimisation.
+// pLastInt:      The last non-modified interval. This pointer is used to set
+//                pLastInt->Next() to the newly created interval.
+// isWaiting:     True if there have been removed intervals, to be replaced by
+//                a new interval.
+// aFirst.Int:    Same as pLastInt. probably we can get rid of pLastInt
+// aFirst.X:      Beginning of the new interval
+
+  Interval * aLastModified = 0L, * aStart;
+  if (theStart == 0L)
+    aStart = const_cast <Interval *>(myIndex[0].Int);
+  else
+    aStart = theStart;
+  Interval * anInt = aStart;
+  Interval * aBracket[2] = { 0L, 0L };
+  unsigned long aRejectID = Interval::NewRejectID();
+  Interval * pLastInt = theStart;
+
+  // Identify the intervals that should be modified
+  for (; anInt; anInt = anInt->Next()) {
+    if (anInt->XZ(0).X() > theInterval.XZ(1).X() - myTol)
+      break;
+    if (anInt->IsIntersect (theInterval, myTol, aRejectID)) {
+      if (aBracket[0] == 0L)
+        aBracket[0] = anInt;
+      aBracket[1] = anInt->Next();
+      const long aModMode = anInt->GetModificationID() - aRejectID;
+      if (aModMode == 3L) {
+        Interval& aNewInt = anInt->Clone(myAllocator);
+        anInt->Trim (anInt->GetModificationAbscisse(), aModMode);
+        aNewInt.myXZ[0] = anInt->XZ(1);
+        aNewInt.myNext = anInt->Next();
+        anInt->myNext = &aNewInt;
+        myNIntervals++;
+      }
+    } else if (aBracket[0] == 0L)
+      pLastInt = anInt;
+  }
+
+  // Modify the intervals
+  Standard_Boolean isWaiting (Standard_False);
+  PInterval aFirst;
+  aFirst.Int = theStart;
+  aFirst.X = aStart->XZ(0).X();
+  for (anInt = aBracket[0]; anInt; anInt = anInt->Next()) {
+    const unsigned long aCurrentID = anInt->GetModificationID();
+    if ((aCurrentID & ~0x3) != aRejectID) {
+      if (isWaiting) {
+        const Standard_Real anX[2] = {
+          aFirst.X,
+          anInt->XZ(0).X()
+        };
+        aLastModified = addInt (theInterval, anX, aFirst.Int);
+        if (aStart == 0L)
+          aStart = aLastModified;
+        aLastModified->myNext = anInt;
+        aFirst.Int = anInt;
+        isWaiting = Standard_False;
+      }
+      if (anInt == aBracket[1])
+        break;
+      pLastInt = anInt;
+    } else {
+      const long aModMode = aCurrentID - aRejectID;
+      switch (aModMode) {
+      case 0:
+        if (aStart == anInt)
+          aStart = 0L;
+        if (isWaiting == Standard_False) {
+          aFirst.Int = pLastInt;
+          aFirst.X = anInt->XZ(0).X();
+          isWaiting = Standard_True;
+        }
+        myNHoles++;
+        break;
+      case 1:
+        aFirst.X = anInt->GetModificationAbscisse();
+        aFirst.Int = anInt;
+        anInt->Trim (aFirst.X, 1);
+        pLastInt = anInt;
+        isWaiting = Standard_True;
+        break;
+      case 2:
+        {
+          if (isWaiting)
+            isWaiting = Standard_False;
+          else {
+            aFirst.Int = pLastInt;
+            aFirst.X = anInt->XZ(0).X();
+          }
+          anInt->Trim (anInt->GetModificationAbscisse(), 2);
+          const Standard_Real anX[2] = {
+            aFirst.X,
+            anInt->GetModificationAbscisse()
+          };
+          aLastModified = addInt (theInterval, anX, aFirst.Int);
+          if (aStart == 0L)
+            aStart = aLastModified;
+          aLastModified->myNext = anInt;
+          aFirst.Int = anInt;
+          pLastInt = anInt;
+        }
+        break;
+      default:
+        Standard_ProgramError::Raise ("Poly_IBuffer::AddInterval");
+      }
+    }
+  }
+  if (isWaiting) {
+    const Standard_Real anX[2] = {
+      aFirst.X,
+      myIndex[INDEXLEN].X
+    };
+    aLastModified = addInt (theInterval, anX, aFirst.Int);
+  }
+  return aLastModified;
+}
+
+//=======================================================================
+//function : CloseBuffer
+//purpose  : Called after all additions of intervals
+//=======================================================================
+
+void Poly_IBuffer::CloseBuffer (const Standard_Boolean isFiltering)
+{
+  const Standard_Real aConf2 =
+    0.01 * Precision::Confusion() * Precision::Confusion();
+  const Standard_Real aTol2 = myTol * myTol;
+  Interval * pPrev = 0L, * pInt = const_cast<Interval *>(myIndex[0].Int);
+  if (pInt) {
+    pInt->U.myPrev = 0L;
+    pInt->myModID = 0UL;
+    pPrev = pInt;
+    pInt = pInt->Next();
+  }
+  while (pInt) {
+    if (isFiltering &&
+        (pPrev->myXZ[1] - pInt->myXZ[0]).SquareModulus() < aConf2)
+    {
+      const gp_XY aV0 = pInt->myXZ[1] - pPrev->myXZ[0];
+      const Standard_Real aL0 = aV0.SquareModulus();
+      if (aL0 > aConf2) {
+        const Standard_Real aVProd = aV0 ^ (pPrev->myXZ[1] - pPrev->myXZ[0]);
+        if (aVProd * aVProd / aL0 < aTol2) {
+          // extend pPrev to take place of pInt
+          pPrev->myXZ[1] = pInt->myXZ[1];
+          pPrev->myNext = pInt->Next();
+          pInt = pInt->Next();
+          continue;
+        }
+      }
+    }
+    pInt->U.myPrev = pPrev;
+    pInt->myModID = 0UL;
+    pPrev = pInt;
+    pInt = pInt->Next();
+  }
+}
+
+//=======================================================================
+//function : addInt
+//purpose  : Internal method, called from AddInterval()
+//=======================================================================
+
+Poly_IBuffer::Interval * Poly_IBuffer::addInt
+                        (const Poly_IBuffer::Interval&  theInterval,
+                         const Standard_Real            theX[2],
+                         const Poly_IBuffer::Interval * thePrevious)
+{
+  const gp_XY aXZ[2] = {
+    gp_XY(theX[0], GetZ (theInterval, theX[0])),
+    gp_XY(theX[1], GetZ (theInterval, theX[1]))
+  };
+  Interval& aNewInt = theInterval.Clone(myAllocator);
+  aNewInt.myXZ[0] = aXZ[0];
+  aNewInt.myXZ[1] = aXZ[1];
+  myNIntervals++;
+  if (thePrevious)
+    const_cast<Interval *>(thePrevious)->myNext = &aNewInt;
+  else {
+    myIndex[0].Int = &aNewInt;
+    if (myMinOrd > aXZ[0].Y())
+      myMinOrd = aXZ[0].Y();
+    if (myMaxOrd < aXZ[0].Y())
+      myMaxOrd = aXZ[0].Y();
+  }
+  if (myMinOrd > aXZ[1].Y())
+    myMinOrd = aXZ[1].Y();
+  if (myMaxOrd < aXZ[1].Y())
+    myMaxOrd = aXZ[1].Y();
+  return &aNewInt;
+}
+
+//=======================================================================
+//function : clearIntervals
+//purpose  : 
+//=======================================================================
+
+void Poly_IBuffer::clearIntervals ()
+{
+  if (myAllocator.IsNull() == Standard_False)
+  {
+    Interval * anInt = const_cast <Interval *>(myIndex[0].Int);
+    while (anInt) {
+      Interval * anInt0 = anInt;
+      anInt = anInt->Next();
+      anInt0->Interval::~Interval();
+      myAllocator->Free(anInt0);
+    }
+    myAllocator->Free (myIndex);
+  }
+  myIndex = 0L;
+  myNIntervals = 0;
+  myNHoles = 0;
+}
+
+//=======================================================================
+//function : Dump
+//purpose  : Debug facility.
+//=======================================================================
+
+void Poly_IBuffer::Dump (Standard_OStream& theStream)
+{
+  const Interval * anInt = First();
+  int aCount(0);
+  for (; anInt; anInt = anInt->Next()) {
+    char buf[256];
+    // if (anInt->XZ(0).Y() > Precision::Infinite() * 0.1 &&
+    //     anInt->XZ(1).Y() > Precision::Infinite() * 0.1)
+    //   continue;
+    sprintf (buf, "%03d (%9.5f %9.5f) - (%9.5f %9.5f)", ++aCount,
+             anInt->XZ(0).X(), anInt->XZ(0).Y(),
+             anInt->XZ(1).X(), anInt->XZ(1).Y());
+    theStream << buf << endl;
+  }
+}
+
+//=======================================================================
+//function : DebugPolyline
+//purpose  : Debug facility.
+//=======================================================================
+
+void Poly_IBuffer::DebugPolyline (Standard_OStream&   theStream,
+                                  const Standard_Real theY)
+{
+  static int aTestCount (0);
+  const Interval * anInt = First();
+  Standard_Real aLastVal[2] = { Precision::Infinite(), Precision::Infinite() };
+  Standard_Boolean isStarted (Standard_True);
+  std::streamsize oldPrec = theStream.precision(8);
+  for (; anInt; anInt = anInt->Next()) {
+    if (anInt->XZ(0).Y() > Precision::Infinite() * 0.1 &&
+        anInt->XZ(1).Y() > Precision::Infinite() * 0.1)
+    {
+      if (isStarted == Standard_False) {
+        theStream << endl;
+        isStarted = Standard_True;
+      }
+      continue;
+    }
+    if (isStarted) {
+      theStream << "polyline ibuf" << aTestCount++;
+      isStarted = Standard_False;
+    }
+    if (fabs(anInt->XZ(0).X() - aLastVal[0]) > Precision::Confusion() ||
+        fabs(anInt->XZ(0).Y() - aLastVal[1]) > Precision::Confusion())
+      theStream << "  " << anInt->XZ(0).X() << ' '
+                << theY << ' ' << anInt->XZ(0).Y() << ' ';
+    theStream << "  " << anInt->XZ(1).X() << ' '
+              << theY << ' ' << anInt->XZ(1).Y() << ' ';
+    aLastVal[0] = anInt->XZ(1).X();
+    aLastVal[1] = anInt->XZ(1).Y();
+  }
+  theStream.precision(oldPrec);
+  theStream << endl;
+}
diff --git a/src/Poly/Poly_IBuffer.hxx b/src/Poly/Poly_IBuffer.hxx
new file mode 100644 (file)
index 0000000..72ceb7d
--- /dev/null
@@ -0,0 +1,253 @@
+// File:      Poly_IBuffer.hxx
+// Created:   15.06.07 08:08
+// Author:    Alexander GRIGORIEV
+// Copyright: Open CASCADE 2007
+
+
+#ifndef Poly_IBuffer_HeaderFile
+#define Poly_IBuffer_HeaderFile
+
+#include <NCollection_List.hxx>
+#include <gp_XY.hxx>
+#include <Standard_DefineHandle.hxx>
+
+DEFINE_STANDARD_HANDLE (Poly_IBuffer, Standard_Transient)
+
+typedef NCollection_List<Handle(Poly_IBuffer)> Poly_ListOfIBuffer;
+
+//! Interval buffer to build outline curve on a set of polygons.
+class Poly_IBuffer: public Standard_Transient
+{
+ public:
+  class Interval
+  {
+  public:
+    // ---------- PUBLIC METHODS ----------
+    Interval (const gp_XY&              theXZfirst,
+              const gp_XY&              theXZlast,
+              const unsigned long       theModID = 0UL);
+
+    /**
+     * Allocator-based operator new for dynamic allocations
+     */
+    DEFINE_NCOLLECTION_ALLOC
+
+    /**
+     * Create a copy of the given Interval in the given allocator.
+     * If theDest==NULL then a new instance is created.
+     */
+    Standard_EXPORT virtual Interval&
+                         Clone        (const Handle(NCollection_BaseAllocator)&,
+                                       Interval * theDest = NULL) const;
+
+    /**
+     * Query the abscisse of the interval.
+     */
+    const gp_XY&         XZ           (const Standard_Integer ind) const;
+
+    /**
+     * Query the interval for modification.
+     */ 
+    gp_XY&               XZ           (const Standard_Integer ind);
+
+    /**
+     * Shorten the interval to the new value of Xmax.
+     */
+    Standard_EXPORT void Trim         (const Standard_Real theX,
+                                       const Standard_Integer   theMode);
+    /**
+     * Query the previous interval in the buffer.
+     */
+    Interval *           Previous     () const;
+
+    /**
+     * Query the next interval in the buffer.
+     */
+    Interval *           Next         () const;
+
+    /**
+     * Query the RejectID indicating the modification status of the interval
+     */
+    unsigned long        GetModificationID   () const;
+
+    /**
+     * Query the abscisse value required for modification.
+     */
+    Standard_Real        GetModificationAbscisse() const;
+
+    /**
+     * Set the modification ID.
+     */
+    void                 SetModificationID   (const unsigned long theValue);
+
+    /**
+     * Check for intersection, returns the intersection point abscissa.
+     * @return
+     *   True if a modification or removal is required. The decision is based
+     *   on 2 lower bits of myRejectID value:
+     *    - 0 : remove this interval;
+     *    - 1 : keep the lower abscisse part, remove the upper part;
+     *    - 2 : keep the upper abscisse part, remove the lower part;
+     *    - 3 : remove the middle.
+     * @param theInt
+     *   The other interval that may intersect this one.
+     * @param theTol
+     *   Tolerance of intersection: smaller intersections are neglected.
+     * @param theRejectID
+     *   Base ID that is stored in the interval with the corresponding
+     *   modification status.
+     */
+    Standard_EXPORT Standard_Boolean
+                         IsIntersect  (const Interval&     theInt,
+                                       const Standard_Real theTol,
+                                       const unsigned long theRejectID);
+    /**
+     * Generator of unique Reject ID values.
+     */
+    static Standard_EXPORT unsigned long
+                         NewRejectID  ();
+
+  private:
+    // ---------- PRIVATE FIELDS ----------
+    Interval            * myNext;
+    gp_XY               myXZ[2];
+    union {
+      Standard_Real     myModX;
+      Interval          * myPrev;
+    }                   U;
+    unsigned long       myModID;
+    friend class Poly_IBuffer;
+  };
+  
+ public:
+  // ---------- PUBLIC METHODS ----------
+
+  /**
+   * Default constructor.
+   */
+  Poly_IBuffer ();
+
+  /**
+   * Constructor.
+   */
+  Standard_EXPORT Poly_IBuffer
+                        (const Interval&                          theInterval,
+                         const Standard_Real                      theTol,
+                         const Handle(NCollection_BaseAllocator)& theAlloc = 0L);
+
+  /**
+   * Get the next IBuffer in the list.
+   */
+  //inline const Poly_IBuffer& YNext() const
+  //{ return * myNext; }
+  inline const Poly_IBuffer *& YNext() 
+  { return  myNext; }
+
+  /**
+   * Get the previous IBuffer in the list.
+   */
+  //inline const Poly_IBuffer& YPrevious() const
+  //{ return * myPrevious; }
+  inline const Poly_IBuffer *& YPrevious() 
+  { return  myPrevious; }
+
+  inline const Standard_Real MyY() const
+  { return myY; }
+
+  /**
+   * Set myY value.
+   */
+  inline void SetY (const Standard_Real theY)
+  { myY = theY; }
+
+#ifdef _DEBUG
+  inline int MyCount()
+  { return myCount; }
+#endif
+
+  /**
+   * Initialization, to be used after the default constructor.
+   */
+  Standard_EXPORT void Init
+                        (const Interval&                          theInterval,
+                         const Standard_Real                      theTol,
+                         const Handle(NCollection_BaseAllocator)& theAlloc = 0L);
+
+  Standard_EXPORT ~Poly_IBuffer ();
+
+  Standard_EXPORT Interval *
+                       AddInterval        (const Interval&      theInterval,
+                                           Interval *           theStart = 0L);
+
+  /**
+   * Called when all intervals are added, just before extraction of data.
+   * This method sets the values 'myPrev' in all Intervals. Can be omittred
+   * if the method Previous() is not to be called afterwards.
+   * @param isFiltering
+   *   If True then the method would merge the intervals that form a straight
+   *   line. It can lead to loss of data attached to intervals, use this only
+   *   when you are only interested in geometry of intervals.
+   */
+  Standard_EXPORT void CloseBuffer        (const Standard_Boolean isFiltering
+                                           = Standard_False);
+
+  const Interval *     First              () const;
+
+  void                 GetOrdinateExtents (Standard_Real& theMin,
+                                           Standard_Real& theMax) const;
+  /**
+   * Debug facility.
+   */
+  Standard_EXPORT void Dump          (Standard_OStream& theStream);
+
+  /**
+   * Debug facility.
+   */
+  Standard_EXPORT void DebugPolyline (Standard_OStream&   theStream,
+                                      const Standard_Real theY = 1.);
+
+ protected:
+  // ---------- PROTECTED METHODS ----------
+
+  typedef struct {
+    Standard_Real  X;
+    const Interval * Int;
+  } PInterval;
+
+  Interval *      addInt        (const Interval&          theInterval,
+                                 const Standard_Real      theX[2],
+                                 const Interval         * thePrevious);
+  void            clearIntervals();
+
+ private:
+  Poly_IBuffer                (const Poly_IBuffer& theOther);
+  Poly_IBuffer& operator =    (const Poly_IBuffer& theOther);
+
+ private:
+  // ---------- PRIVATE FIELDS ----------
+
+  Handle(NCollection_BaseAllocator) myAllocator;
+  Standard_Real                     myTol;
+  Standard_Real                     myMinOrd;
+  Standard_Real                     myMaxOrd;
+  Standard_Size                     myNIntervals;
+  Standard_Size                     myNHoles;
+  PInterval                         * myIndex;
+  //Next IBuffer in the list
+  const Poly_IBuffer*               myNext;
+  //Previous IBuffer in the list
+  const Poly_IBuffer*               myPrevious;
+  Standard_Real                     myY;
+#ifdef _DEBUG
+  int                               myCount;
+  static int                        GlobalCount;
+#endif
+
+public:
+  // Declaration of CASCADE RTTI
+  DEFINE_STANDARD_RTTIEXT (Poly_IBuffer, Standard_Transient)
+};
+
+#include <Poly_IBuffer.lxx>
+
+#endif
diff --git a/src/Poly/Poly_IBuffer.lxx b/src/Poly/Poly_IBuffer.lxx
new file mode 100644 (file)
index 0000000..adf9c99
--- /dev/null
@@ -0,0 +1,87 @@
+// File:      Poly_IBuffer.lxx
+// Created:   15.06.07 07:56
+// Author:    Alexander GRIGORIEV
+// Copyright: Open CASCADE 2007
+
+//! Constructor.
+inline Poly_IBuffer::Interval::Interval (const gp_XY&        theXZfirst,
+                                         const gp_XY&        theXZlast,
+                                         const unsigned long theModID)
+  : myNext      (0L),
+    myModID     (theModID)
+{
+  U.myModX = RealLast();
+  myXZ[0] = theXZfirst;
+  myXZ[1] = theXZlast;
+}
+
+//! Query the beginning (ind==0) or end (ind == 1) of the interval.
+inline const gp_XY& Poly_IBuffer::Interval::XZ (const Standard_Integer i) const
+{
+  return myXZ[i&0x1];
+}
+
+//! Query the beginning (ind==0) or end (ind == 1) of the interval for modif
+inline gp_XY& Poly_IBuffer::Interval::XZ (const Standard_Integer i)
+{
+  return myXZ[i&0x1];
+}
+
+//! Query the next interval in the buffer.
+inline Poly_IBuffer::Interval *  Poly_IBuffer::Interval::Next () const
+{
+  return myNext;
+}
+
+//! Query the previous interval in the buffer.
+inline Poly_IBuffer::Interval *  Poly_IBuffer::Interval::Previous () const
+{
+  return U.myPrev;
+}
+
+//! Set the modification ID.
+inline void Poly_IBuffer::Interval::SetModificationID
+                                        (const unsigned long theValue)
+{
+  myModID = theValue;
+}
+
+//! Query the RejectID field indicating the modification status of the interval
+inline unsigned long Poly_IBuffer::Interval::GetModificationID () const
+{
+  return myModID;
+}
+
+//! Query the abscisse value required for modification.
+inline Standard_Real Poly_IBuffer::Interval::GetModificationAbscisse() const
+{
+  return U.myModX;
+}
+
+//! Returns the head of the list of intervals.
+/** Other intervals can be obtained by iterative calling Next() of each
+ *  returned interval.
+ */
+inline const Poly_IBuffer::Interval * Poly_IBuffer::First () const
+{
+  return myIndex ? myIndex[0].Int : 0L;
+}
+
+//! Default constructor
+inline Poly_IBuffer::Poly_IBuffer()
+  : myTol       (0.),
+    myMinOrd    (0.),
+    myMaxOrd    (0.),
+    myNIntervals(0),
+    myNHoles    (0),
+    myIndex     (0L)
+{}
+
+//! Get extents of the buffer along the ordinate, excepting the 
+//! artificial intervals at infinite ordinate
+inline void Poly_IBuffer::GetOrdinateExtents (Standard_Real& theMin,
+                                              Standard_Real& theMax) const
+{
+  theMin = myMinOrd;
+  theMax = myMaxOrd;
+}
index eb36f0343a7b75255de521eb7cb61de6aa3b87ae..72a8ae2dc79cf1ac6b245d89688570ef5d523fdd 100644 (file)
@@ -370,11 +370,6 @@ void SelectMgr_SelectionManager::Activate (const Handle(SelectMgr_SelectableObje
 
   if (myGlobal.Contains (theObject))
   {
-    const Standard_Integer aGlobalSelMode = theObject->GlobalSelectionMode();
-    if (theMode != aGlobalSelMode && theSelector->IsActive (theObject, aGlobalSelMode))
-    {
-      theSelector->Deactivate (theObject->Selection (aGlobalSelMode));
-    }
     theSelector->Activate (theObject->Selection (theMode));
   }
   else
index 459a60d964b6b70ada5ce1589d36d7ff25ee9afd..158aef8eb977f9216c8837ce9f274136b12debe6 100644 (file)
@@ -393,10 +393,22 @@ Standard_Integer Standard_GUID::Hash(const Standard_Integer Upper) const
     throw Standard_RangeError("Standard_GUID::Hash: Try to apply HashCode method with negative or null argument.");
   }
 
-  char sguid[Standard_GUID_SIZE_ALLOC];
-  ToCString(sguid);
-
-  return ::HashCode(sguid,Upper);
+  // ==== AGV 16/12/2012: More optimal hash function ===
+   //char sguid[Standard_GUID_SIZE_ALLOC];
+   //ToCString(sguid);
+   //return ::HashCode(sguid,Upper);
+  // ===================================================
+  unsigned int aHash = ((static_cast<unsigned int>(my8b6) << 24) |
+                        (static_cast<unsigned int>(my8b5) << 16) |
+                        (static_cast<unsigned int>(my8b4) << 8) |
+                        (static_cast<unsigned int>(my8b3)));
+  aHash = (aHash ^ (aHash >> 11)) & 0x07ffffff;
+  aHash = (aHash * 31 + ((static_cast<unsigned int>(my8b2) << 24) |
+                         (static_cast<unsigned int>(my8b1) << 16) |
+                         (static_cast<unsigned int>(my16b3)))) & 0x07ffffff;
+  aHash = (aHash * 31 + ((static_cast<unsigned int>(my16b2) << 16) |
+                         (static_cast<unsigned int>(my16b1)))) & 0x07ffffff;
+  return (aHash * 31 + my32b) % Upper;
 }
 
 Standard_Boolean Standard_GUID::IsEqual(const Standard_GUID& aGuid1,const Standard_GUID& aGuid2)
index 5293d3706a08b47753a664c96d3d81fe5b99f77a..4850304818f578a115301b3853860befbac9741a 100644 (file)
@@ -54,7 +54,7 @@ void StdSelect_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*PM*/
     else
       StdPrs_WFShape::Add (P, mysh, myDrawer);
   }
-  else if (aMode==0)
+  else
     StdPrs_WFShape::Add (P, mysh, myDrawer);
 }
 
index 00f7522c88b12c7b0228585a98e51dc43f4b4aa8..ab01f019f9102a2277715f6e04c5fda9cf625094 100644 (file)
@@ -117,7 +117,7 @@ public:
   
   //! Adds an Attribute  to the current label. Raises if
   //! there is already one.
-  Standard_EXPORT void AddAttribute (const Handle(TDF_Attribute)& anAttribute, const Standard_Boolean append = Standard_False) const;
+  Standard_EXPORT void AddAttribute (const Handle(TDF_Attribute)& anAttribute, const Standard_Boolean append = Standard_True) const;
   
   //! Forgets an  Attribute   from the  current  label,
   //! setting its   forgotten status true and  its valid
index 53d3d9fea6a63fbd15fc686ea02fe9ecd5d75d12..770b8eb4f7aa00489d11b7811de1635f21ebbc92 100644 (file)
@@ -285,17 +285,17 @@ void TDataXtd_Presentation::SetMode(const Standard_Integer theMode)
 //function : SetSelectionMode
 //purpose  : 
 //=======================================================================
-void TDataXtd_Presentation::SetSelectionMode(const Standard_Integer theSelectionMode)
+void TDataXtd_Presentation::SetSelectionMode(const Standard_Integer theSelectionMode, const Standard_Boolean theTransaction)
 {
   if (! myHasOwnSelectionMode || mySelectionMode != theSelectionMode)
   {
-    Backup();
+    if (theTransaction)
+        Backup();
     mySelectionMode = theSelectionMode;
     myHasOwnSelectionMode = Standard_True;
   }
 }
 
-
 //=======================================================================
 //function : MaterialIndex
 //purpose  : 
index e92dc574ca81e732a8876c0596560158f9b4993e..d319a9f4ec61c743dba983fbcbec98d15e1b3933 100644 (file)
@@ -114,7 +114,12 @@ public:
 
   Standard_EXPORT void SetMode(const Standard_Integer theMode);
 
-  Standard_EXPORT void SetSelectionMode(const Standard_Integer theSelectionMode);
+  //! Sets selection mode.
+  //! If "theTransaction" flag is OFF, modification of the attribute doesn't influence the transaction mechanism
+  //! (the attribute doesn't participate in undo/redo because of this modification).
+  //! Certainly, if any other data of the attribute is modified (display mode, color, ...),
+  //! the attribute will be included into undo/redo.
+  Standard_EXPORT void SetSelectionMode(const Standard_Integer theSelectionMode, const Standard_Boolean theTransaction = Standard_True);
 
   Standard_EXPORT Standard_Integer MaterialIndex() const;
 
index 8297fbe0358c654272a2d2a0ee5d43a1222a5e31..173639ab58d27dfe2d7e63ec47501f20a3598337 100644 (file)
@@ -591,11 +591,16 @@ Standard_Boolean TPrsStd_AISPresentation::HasOwnSelectionMode() const
 //function : SetSelectionMode
 //purpose  : 
 //=======================================================================
-void TPrsStd_AISPresentation::SetSelectionMode(const Standard_Integer theSelectionMode)
+void TPrsStd_AISPresentation::SetSelectionMode(const Standard_Integer theSelectionMode, const Standard_Boolean theTransaction)
 {
-  Backup();
-  getData()->SetSelectionMode (theSelectionMode);
-  AISUpdate();
+  if (theTransaction)
+    Backup();
+  getData()->SetSelectionMode (theSelectionMode, theTransaction);
+  
+  if ( myAIS.IsNull() )
+    AISUpdate();
+  else
+    ActivateSelectionMode();
 }
 
 //=======================================================================
@@ -800,7 +805,7 @@ void TPrsStd_AISPresentation::AISUpdate()
           if ( !(anObj ==  myAIS) )
           {
             if ( !aContext.IsNull() )
-              aContext->Remove (myAIS, Standard_True);
+              aContext->Remove (myAIS, Standard_False);
 
             // Driver has built new AIS.
             myAIS = anObj;
@@ -871,36 +876,7 @@ void TPrsStd_AISPresentation::AISUpdate()
         myAIS->SetDisplayMode(aMode);
     }
 
-    if ( !aContext.IsNull() && IsDisplayed() )
-      aContext->Redisplay(myAIS, Standard_False);
-
-    if (HasOwnSelectionMode()) {
-      if (!aContext.IsNull())
-      {
-        TColStd_ListOfInteger anActivatedModes;
-        aContext->ActivatedModes (myAIS, anActivatedModes);
-        Standard_Boolean isActivated = Standard_False;
-        Standard_Integer aSelectionMode = SelectionMode();
-        if (aSelectionMode == -1)
-        {
-          aContext->Deactivate(myAIS);
-        }
-        else
-        {
-          for (TColStd_ListIteratorOfListOfInteger aModeIter (anActivatedModes); aModeIter.More(); aModeIter.Next())
-          {
-            if (aModeIter.Value() == aSelectionMode)
-            {
-              isActivated = Standard_True;
-              break;
-            }
-          }
-          if (!isActivated)
-            aContext->Activate (myAIS, aSelectionMode, Standard_False);
-        }
-      } 
-    }
-
+    ActivateSelectionMode();
   }
   
   if (IsDisplayed() && !aContext.IsNull())
@@ -1013,3 +989,40 @@ Handle(AIS_InteractiveContext) TPrsStd_AISPresentation::getAISContext() const
 
   return Handle_AIS_InteractiveContext();
 }
+
+//=======================================================================
+//function : ActivateSelectionMode
+//purpose  : Activates selection mode of the interactive object.
+//           It is called internally on change of selection mode and AISUpdate().
+//=======================================================================
+void TPrsStd_AISPresentation::ActivateSelectionMode()
+{
+  if (!myAIS.IsNull() && HasOwnSelectionMode())
+  {
+    Handle(AIS_InteractiveContext) aContext = getAISContext();
+    if (!aContext.IsNull())
+    {
+      TColStd_ListOfInteger anActivatedModes;
+      aContext->ActivatedModes (myAIS, anActivatedModes);
+      Standard_Boolean isActivated = Standard_False;
+      Standard_Integer aSelectionMode = SelectionMode();
+      if (aSelectionMode == -1)
+      {
+        aContext->Deactivate(myAIS);
+      }
+      else
+      {
+        for (TColStd_ListIteratorOfListOfInteger aModeIter (anActivatedModes); aModeIter.More(); aModeIter.Next())
+        {
+          if (aModeIter.Value() == aSelectionMode)
+          {
+            isActivated = Standard_True;
+            break;
+          }
+        }
+        if (!isActivated)
+          aContext->Activate (myAIS, aSelectionMode, Standard_False);
+      }
+    } 
+  }
+}
index 672ff5f9b4e69af6abe6a099253a546c3932576a..2e3660cb8ab6a151b4c63ce708c634d940cd83a0 100644 (file)
@@ -157,8 +157,13 @@ public:
   Standard_EXPORT void UnsetMode();
   
   Standard_EXPORT Standard_Integer SelectionMode() const;
-  
-  Standard_EXPORT void SetSelectionMode (const Standard_Integer theSelectionMode);
+
+  //! Sets selection mode.
+  //! If "theTransaction" flag is OFF, modification of the attribute doesn't influence the transaction mechanism
+  //! (the attribute doesn't participate in undo/redo because of this modification).
+  //! Certainly, if any other data of the attribute is modified (display mode, color, ...),
+  //! the attribute will be included into undo/redo.
+  Standard_EXPORT void SetSelectionMode (const Standard_Integer theSelectionMode, const Standard_Boolean theTransaction = Standard_True);
   
   Standard_EXPORT Standard_Boolean HasOwnSelectionMode() const;
   
@@ -197,6 +202,10 @@ protected:
 private:
 
   Handle(AIS_InteractiveContext) getAISContext() const;
+
+  //! Activates selection mode of the interactive object.
+  //! It is called internally on change of selection mode and AISUpdate().
+  void ActivateSelectionMode();
   
   //! Updates AIS_InteractiveObject stored in the attribute
   //! and applies the visualization settings
@@ -209,7 +218,6 @@ private:
   //! the viewer; If <remove> = True then AISObject is removed
   //! from AIS_InteractiveContext instead of simple erasing in the viewer
   Standard_EXPORT void AISErase (const Standard_Boolean remove = Standard_False);
-
 private:
   Handle(AIS_InteractiveObject) myAIS;
 };
index 151d1978b18ac225979b53ca745d8cd52c11c593..57a3b9f87b02dfa2ca6707ac069b2d1ec0e94590 100644 (file)
@@ -134,6 +134,7 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
         TopoDS_Shape aTestedShape;
         aTestedShape.TShape (aShape.TShape());
         aTestedShape.Orientation (isReverse ? TopAbs_REVERSED : TopAbs_FORWARD);
+        Standard_Boolean isTessellate (Standard_False);
         switch (ShapeType[i]) {
         case TopAbs_FACE:
           {
@@ -147,6 +148,16 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
                 break;
               }
 
+              if (aTri.IsNull())
+                isTessellate = Standard_True;
+              // Check the existing deflection
+              else if (aTri->Deflection() > aDeflection+ Precision::Confusion())
+                isTessellate = Standard_True;
+              if (isTessellate) {
+                // Triangulate the face by the standard OCC mesher
+                BRepMesh_IncrementalMesh IM (aFace, aDeflection, Standard_False, theDeflAngle);
+                aTri = BRep_Tool::Triangulation (aFace, aLoc);
+              }
               if (aTri.IsNull() == Standard_False) {
                 TopoDS_Shape aTestedShapeRev = aTestedShape;
                 aTestedShapeRev.Orientation (isReverse ?
@@ -179,6 +190,8 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
          {
            const TopoDS_Edge& aEdge = TopoDS::Edge (aShape);
             if (aEdge.IsNull() == Standard_False) {
+              Handle(Poly_Polygon3D) aPol = BRep_Tool::Polygon3D (aEdge, aLoc);
+              
               if (aRelMap.IsBound (aTestedShape)) {
                 aTShapeNode = aRelMap(aTestedShape);
                 break;
@@ -191,34 +204,53 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
                 aTShapeNode = aRelMap(aTestedShape);
                 break;
               }
-
-              //try to find PolygonOnTriangulation
-              Handle(Poly_PolygonOnTriangulation) aPT;
-              Handle(Poly_Triangulation) aT;
-              TopLoc_Location aL;
-              BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL);
-
-              // If PolygonOnTriangulation was found -> get the Polygon3D
-              Handle(Poly_Polygon3D) aPol;
-              if(!aPT.IsNull() && !aT.IsNull() && aPT->HasParameters()) {
-                BRepAdaptor_Curve aCurve(aEdge);
-                Handle(TColStd_HArray1OfReal) aPrs = aPT->Parameters();
-                Standard_Integer nbNodes = aPT->NbNodes();
-                TColgp_Array1OfPnt arrNodes(1, nbNodes);
-                TColStd_Array1OfReal arrUVNodes(1, nbNodes);
-
-                for(Standard_Integer j = 1; j <= nbNodes; j++) {
-                  arrUVNodes(j) = aPrs->Value(aPrs->Lower() + j - 1);
-                  arrNodes(j) = aCurve.Value(arrUVNodes(j));
+              
+              if (aPol.IsNull())
+                isTessellate = Standard_True;
+              // Check the existing deflection
+              else if (aPol->Deflection() > aDeflection+ Precision::Confusion()
+                       && BRep_Tool::IsGeometric(aEdge))
+                isTessellate = Standard_True;
+              
+              if (isTessellate && BRep_Tool::IsGeometric(aEdge)) {
+                //try to find PolygonOnTriangulation
+                Handle(Poly_PolygonOnTriangulation) aPT;
+                Handle(Poly_Triangulation) aT;
+                TopLoc_Location aL;
+
+                Standard_Boolean found = Standard_False;
+                Standard_Integer j = 1;
+                for (;;) {
+                  BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL, j);
+
+                  if (aPT.IsNull() || aT.IsNull()) break;
+
+                  if (aPT->Deflection() <= aDeflection + Precision::Confusion()
+                      && aPT->HasParameters())
+                  {
+                    found = Standard_True;
+                    break;
+                  }
+                  j++;
                 }
-                aPol = new Poly_Polygon3D(arrNodes, arrUVNodes);
-                aPol->Deflection (aPT->Deflection());
-              }
-              else {
-                aPol = BRep_Tool::Polygon3D(aEdge, aL);
+                
+                if(found) {
 
-                // If polygon was not found -> generate it
-                if (aPol.IsNull()) {
+                  BRepAdaptor_Curve aCurve(aEdge);
+                  Handle(TColStd_HArray1OfReal) aPrs = aPT->Parameters();
+                  Standard_Integer nbNodes = aPT->NbNodes();
+                  TColgp_Array1OfPnt arrNodes(1, nbNodes);
+                  TColStd_Array1OfReal arrUVNodes(1, nbNodes);
+
+                  for(Standard_Integer j = 1; j <= nbNodes; j++) {
+                    arrUVNodes(j) = aPrs->Value(aPrs->Lower() + j - 1);
+                    arrNodes(j) = aCurve.Value(arrUVNodes(j));
+                  }
+                  aPol = new Poly_Polygon3D(arrNodes, arrUVNodes);
+                  aPol->Deflection (aPT->Deflection());
+                }
+                else{
+                  
                   BRepAdaptor_Curve aCurve(aEdge);
                   const Standard_Real aFirst = aCurve.FirstParameter();
                   const Standard_Real aLast  = aCurve.LastParameter();
@@ -236,11 +268,10 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces,
                   aPol = new Poly_Polygon3D(arrNodes, arrUVNodes);
                   aPol->Deflection (aDeflection);
                 }
+                
+                BRep_Builder aBld;
+                aBld.UpdateEdge (aEdge, aPol);
               }
-
-              if (aPol.IsNull())
-                continue;
-
               aTShapeNode = polToIndexedLineSet (aPol);
               myScene.AddNode (aTShapeNode, Standard_False);
               // Bind the converted face
index d688b6de10914c34dbd1507f5325eb5927551855..d8726779bdf3803bf351ec9469bbc679cdde89d0 100644 (file)
@@ -256,7 +256,10 @@ Standard_Integer XmlMDF::ReadSubTree (const XmlObjMgt_Element&    theElement,
           if (isBound)
             tAtt = Handle(TDF_Attribute)::DownCast(theRelocTable.Find(anID));
           else
+          {
             tAtt = driver -> NewEmpty();
+            tAtt->SetID();
+          }
          if (tAtt->Label().IsNull())
            theLabel.AddAttribute (tAtt);
          else
index 2e0c9662b8dde74087e1060b5f10883420ffd19d..d53930b6bea5de516f15001fefe8cca73375e2c9 100644 (file)
@@ -24,6 +24,7 @@
 #include <XmlObjMgt.hxx>
 #include <XmlObjMgt_Document.hxx>
 #include <XmlObjMgt_Persistent.hxx>
+#include <XmlLDrivers.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(XmlMDataStd_ExtStringArrayDriver,XmlMDF_ADriver)
 IMPLEMENT_DOMSTRING (FirstIndexString, "first")
@@ -238,39 +239,46 @@ void XmlMDataStd_ExtStringArrayDriver::Paste (const Handle(TDF_Attribute)& theSo
 
   // Find a separator.
   Standard_Boolean found(Standard_True);
-  // Preferrable symbols for the separator: - _ . : ^ ~
-  // Don't use a space as a separator: XML low-level parser sometimes "eats" it.
+  // This improvement was defined in the version 8.
+  // So, if the user wants to save the document under the 7th or earlier versions,
+  // don't apply this improvement.
   Standard_Character c = '-';
-  static Standard_Character aPreferable[] = "-_.:^~";
-  for (i = 0; found && aPreferable[i]; i++)
+  if (XmlLDrivers::StorageVersion() > 7)
   {
-    c = aPreferable[i];
-    found = Contains(aExtStringArray, TCollection_ExtendedString(c));
-  }
-  // If all prefferable symbols exist in the array, 
-  // try to use any other simple symbols.
-  if (found)
-  {
-    c = '!';
-    while (found && c < '~')
+    // Preferrable symbols for the separator: - _ . : ^ ~
+    // Don't use a space as a separator: XML low-level parser sometimes "eats" it.
+    Standard_Character c = '-';
+    static Standard_Character aPreferable[] = "-_.:^~";
+    for (i = 0; found && aPreferable[i]; i++)
+    {
+      c = aPreferable[i];
+      found = Contains(aExtStringArray, TCollection_ExtendedString(c));
+    }
+    // If all prefferable symbols exist in the array, 
+    // try to use any other simple symbols.
+    if (found)
     {
-      found = Standard_False;
+      c = '!';
+      while (found && c < '~')
+      {
+        found = Standard_False;
 #ifdef _DEBUG
-      TCollection_AsciiString cseparator(c); // deb
+        TCollection_AsciiString cseparator(c); // deb
 #endif
-      TCollection_ExtendedString separator(c);
-      found = Contains(aExtStringArray, separator);
-      if (found)
-      {
-        c++;
-        // Skip forbidden symbols for XML.
-        while (c < '~' && (c == '&' || c == '<'))
+        TCollection_ExtendedString separator(c);
+        found = Contains(aExtStringArray, separator);
+        if (found)
         {
           c++;
+          // Skip forbidden symbols for XML.
+          while (c < '~' && (c == '&' || c == '<'))
+          {
+            c++;
+          }
         }
       }
     }
-  }
+  }// check doc version
   
   if (found)
   {
index dd326dc1a9a50f0e4cac3614ee965f6d1b79390f..76c2b8cd1bcac4f5eaccdacae67f22baed740142 100644 (file)
@@ -165,15 +165,19 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F,
       Standard_Real aMult = RealLast();
       for(Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++)
       {
+        const Standard_Real anAbsStep = Abs(TheStep(anIdx));
+        if (anAbsStep < gp::Resolution())
+          continue;
+
         if (suivant->Value(anIdx) < myLeft(anIdx))
         {
-          Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / Abs(TheStep(anIdx));
+          Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / anAbsStep;
           aMult = Min (aValue, aMult);
         }
 
         if (suivant->Value(anIdx) > myRight(anIdx))
         {
-          Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / Abs(TheStep(anIdx));
+          Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / anAbsStep;
           aMult = Min (aValue, aMult);
         }
       }