]> OCCT Git - occt.git/commitdiff
Add autosectioning
authorika <ika@opencascade.com>
Wed, 22 Nov 2023 17:54:46 +0000 (17:54 +0000)
committerika <ika@opencascade.com>
Thu, 30 Nov 2023 23:42:55 +0000 (23:42 +0000)
src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.cxx [new file with mode: 0644]
src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.hxx [new file with mode: 0644]
src/BRepAlgoAPI/FILES
src/BRepBuilderAPI/BRepBuilderAPI_HullTransform.cxx
src/BRepTest/BRepTest_BasicCommands.cxx

diff --git a/src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.cxx b/src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.cxx
new file mode 100644 (file)
index 0000000..7a0b233
--- /dev/null
@@ -0,0 +1,199 @@
+#include <BRepAlgoAPI_HullTransform.hxx>
+
+#include <BOPAlgo_Splitter.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_NurbsConvert.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom_Plane.hxx>
+#include <ShapeAnalysis_ShapeTolerance.hxx>
+#include <ShapeFix_Shape.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+
+//=======================================================================
+//function : BRepAlgoAPI_HullTransform
+//purpose  : 
+//=======================================================================
+BRepAlgoAPI_HullTransform::BRepAlgoAPI_HullTransform()
+{
+  myIsAutoSection = false;
+  myTolerance = 0;
+}
+
+//=======================================================================
+//function : InitLinear
+//purpose  : 
+//=======================================================================
+void BRepAlgoAPI_HullTransform::InitLinear(const double theCM,
+                                           const double theCBNew,
+                                           const double theCBOld,
+                                           const double theLPP)
+{
+  myLinear = true;
+  _cm = theCM;
+  _cb_new = theCBNew;
+  _cb_old = theCBOld;
+  _lpp = theLPP;
+}
+
+//=======================================================================
+//function : InitQuad
+//purpose  : 
+//=======================================================================
+void BRepAlgoAPI_HullTransform::InitQuad(const double theAftlim,
+                                         const double theCCA,
+                                         const double theCCF,
+                                         const double theForelim,
+                                         const double theAftCoef,
+                                         const double theForeCoef,
+                                         const bool theModifyAftZone,
+                                         const bool theModifyForeZone)
+{
+  myLinear = false;
+
+  _aftlim = theAftlim;
+  _cca = theCCA;
+  _ccf = theCCF;
+  _forelim = theForelim;
+  _aft_coef = theAftCoef;
+  _fore_coef = theForeCoef;
+  _modify_aft_zone = theModifyAftZone;
+  _modify_fore_zone = theModifyForeZone;
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+TopoDS_Shape BRepAlgoAPI_HullTransform::Perform()
+{
+  // Do Nurbs convert
+  BRepBuilderAPI_NurbsConvert aNC;
+  aNC.Perform(myHull);
+  myHull = aNC.Shape();
+
+  // Pre calculations for automatic sectioning
+  std::list<TopoDS_Shape> aHullsList;
+  std::list<std::list<double>> aSectionsList;
+  std::list<double> aTolerances;
+  bool isToProceed = myIsAutoSection;
+
+  // Set tolerance to 5% of the Hull length if it was not specified.
+  if (fabs(myTolerance) < Precision::Confusion())
+  {
+    myTolerance = (myLinear) ? _lpp : _forelim;
+    myTolerance *= 0.05;
+  }
+
+  // Perform
+  do
+  {
+    TopoDS_Shape aCurShape = myHull;
+    if (mySections.size() > 0)
+    {
+      // Add splitting edges
+      aCurShape = split();
+    }
+
+    // Perform transformation
+    BRepBuilderAPI_HullTransform aHTrsf;
+    if (myLinear)
+      aHTrsf.InitLinear(_cm, _cb_new, _cb_old, _lpp);
+    else
+      aHTrsf.InitQuad(_aftlim, _cca, _ccf, _forelim, _aft_coef, _fore_coef, _modify_aft_zone, _modify_fore_zone);
+    aHTrsf.Perform(aCurShape, true);
+
+    if (aHTrsf.IsDone())
+    {
+      // Fix shape
+      Handle(ShapeFix_Shape) aShapeFixTool = new ShapeFix_Shape;
+      aShapeFixTool->Init(aHTrsf.Shape());
+      aShapeFixTool->Perform();
+      ShapeAnalysis_ShapeTolerance aSat;
+      aSat.InitTolerance();
+      aSat.AddTolerance(aShapeFixTool->Shape());
+
+      // Check the necessarity of the next step
+      if (myIsAutoSection && aHullsList.size() > 0 && aSat.GlobalTolerance(1) >= aTolerances.back())
+      {
+        isToProceed = false;
+        mySections.pop_back();
+      }
+      else
+      {
+        aTolerances.push_back(aSat.GlobalTolerance(1));
+        aHullsList.push_back(aShapeFixTool->Shape());
+        aSectionsList.push_back(mySections);
+        if (myIsAutoSection)
+          addSection(aShapeFixTool->Shape());
+      }
+    }
+  } while (isToProceed);
+
+  // Return the result
+  if (aHullsList.size() == 0)
+    return TopoDS_Shape();
+  return aHullsList.back();
+}
+
+//=======================================================================
+//function : split
+//purpose  : 
+//=======================================================================
+TopoDS_Shape BRepAlgoAPI_HullTransform::split()
+{
+  TopTools_ListOfShape aLSObjects;
+  aLSObjects.Append(myHull);
+  TopTools_ListOfShape aLSTools;
+  for (double aPlaneX : mySections)
+  {
+    Handle(Geom_Plane) aPlane = new Geom_Plane(gp_Pnt(aPlaneX, 0, 0), gp_Dir(1, 0, 0));
+    TopoDS_Face aFace =
+      BRepBuilderAPI_MakeFace(aPlane, -1000, 1000, -1000, 1000, Precision::Confusion());
+    aLSTools.Append(aFace);
+  }
+
+  BOPAlgo_Splitter pSplitter;
+  pSplitter.Clear();
+  pSplitter.SetArguments(aLSObjects);
+  pSplitter.SetTools(aLSTools);
+  pSplitter.Perform();
+  return pSplitter.Shape();
+}
+
+//=======================================================================
+//function : addSection
+//purpose  : 
+//=======================================================================
+void BRepAlgoAPI_HullTransform::addSection(const TopoDS_Shape& theHull)
+{
+  std::list<std::pair<double, double>> aVertices;
+  TopExp_Explorer anExp(theHull, TopAbs_VERTEX);
+  for (; anExp.More(); anExp.Next())
+  {
+    TopoDS_Vertex aVrt = TopoDS::Vertex(anExp.Current());
+    gp_Pnt aPnt = BRep_Tool::Pnt(aVrt);
+    double aTol = BRep_Tool::Tolerance(aVrt);
+    aVertices.push_back(std::pair<double, double>(aTol, aPnt.X()));
+  }
+  aVertices.sort();
+  aVertices.reverse();
+
+  bool isToStop = false;
+
+  // Find new section not too close for the existing set
+  for (const auto& aVertex : aVertices)
+  {
+    if (isToStop)
+      break;
+    bool isToAdd = true;
+    for (const double aSection : mySections)
+      if (fabs(aVertex.second - aSection) < myTolerance)
+        isToAdd = false;
+    if (isToAdd)
+    {
+      mySections.push_back(aVertex.second);
+      isToStop = true;
+    }
+  }
+}
diff --git a/src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.hxx b/src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.hxx
new file mode 100644 (file)
index 0000000..c90c1ca
--- /dev/null
@@ -0,0 +1,126 @@
+// Created on: 2023-29-11
+// Created by: Irina KOCHETKOVA
+// Copyright (c) 2023 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 _BRepAlgoAPI_HullTransform_HeaderFile
+#define _BRepAlgoAPI_HullTransform_HeaderFile
+
+#include <Standard.hxx>
+#include <BRepBuilderAPI_HullTransform.hxx>
+
+#include <list>
+
+//! The class implements an algorithm of hull transformtation according to the custom transformation function
+//! (see BRepTools_HullTransformation for more information).
+//! Steps of preparation before transformation
+//! - Convert to nurbs
+//! - Add sections parallel to YZ plane to decrease the tolerance.
+//! The class also implements an autosectioning method, which calculates the set of sections
+//! to decrease the tolerance as much as possible.
+//! It iterationally tries to do a transformation, find the most problematic (with the biggest tolerance) place,
+//! and add the section there.
+class BRepAlgoAPI_HullTransform
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+public: 
+
+  //! Empty constructor.
+  Standard_EXPORT BRepAlgoAPI_HullTransform();
+
+  //! Sets flag for performing auto generation of sections.
+  //! @param theAutoFlag [in] true if the autosection is necessary, false otherwise.
+  //! @param theTolerance [in] minimal distance between two sections.
+  void SetAutoSections(const bool theAutoFlag, double theTolerance = 0)
+  {
+    myIsAutoSection = theAutoFlag;
+    myTolerance = theTolerance;
+  }
+
+  //! Sets predefined sections
+  void SetSections(const std::list<double>& theSections)
+  {
+    mySections = theSections;
+  }
+
+  //! Sets the Hull.
+  void SetHull(const TopoDS_Shape& theHull)
+  {
+    myHull = theHull;
+  }
+
+  //! Initialize parameters for linear transformation function.
+  Standard_EXPORT void InitLinear(const double theCM,
+                                  const double theCBNew,
+                                  const double theCBOld,
+                                  const double theLPP);
+
+  //! Initialize parameters for quad transformation function.
+  Standard_EXPORT void InitQuad(const double theAftlim,
+                                const double theCCA,
+                                const double theCCF,
+                                const double theForelim,
+                                const double theAftCoef,
+                                const double theForeCoef,
+                                const bool theModifyAftZone,
+                                const bool theModifyForeZone);
+
+  //! Performs the main calculations.
+  //! @return the result shape, empty in case of fail.
+  Standard_EXPORT TopoDS_Shape Perform();
+
+  //! Returns sections, used for the transformatoin.
+  std::list<double> Sections()
+  {
+    return mySections;
+  }
+
+private:
+
+  //! Returns the result of splitting myHyll by mySections
+  TopoDS_Shape split();
+
+  //! Finds the first vertex in theHull with the biggest tolerance, with valid X position using already added
+  //! sections and myTolerance and add its X position to the mySections.
+  void addSection(const TopoDS_Shape& theHull);
+
+private:
+
+  bool myIsAutoSection;         //!< auto section mode
+  double myTolerance;           //!< tolerance for autosectioning algorithm
+  std::list<double> mySections; //!< sections
+  TopoDS_Shape myHull;          //!< the initial Hull, converted to nurbs in Perform()
+
+  bool myLinear;                //!< Flag of linear.quad transformation function
+
+  //! Linear parameters
+  double _cm;
+  double _cb_new;
+  double _cb_old;
+  double _lpp;
+
+  //! Quad parameters
+  double _aftlim;
+  double _cca;
+  double _ccf;
+  double _forelim;
+  double _aft_coef;
+  double _fore_coef;
+  bool _modify_aft_zone;
+  bool _modify_fore_zone;
+};
+
+#endif // _BRepAlgoAPI_HullTransform_HeaderFile
index ac68df71e2d7efab4f5b03247a67ab067d0e3193..cddebce18be7b79467e41e34461669d06d9b7bd7 100644 (file)
@@ -14,6 +14,8 @@ BRepAlgoAPI_Defeaturing.cxx
 BRepAlgoAPI_Defeaturing.hxx
 BRepAlgoAPI_Fuse.cxx
 BRepAlgoAPI_Fuse.hxx
+BRepAlgoAPI_HullTransform.cxx
+BRepAlgoAPI_HullTransform.hxx
 BRepAlgoAPI_Section.cxx
 BRepAlgoAPI_Section.hxx
 BRepAlgoAPI_Splitter.cxx
index 1f7fa2388d3f7e2daf22e010f5f95dac566bbf38..29e45568d3d41575672b47d57313e80b2af8d5f6 100644 (file)
@@ -15,7 +15,6 @@
 
 
 #include <BRepBuilderAPI_HullTransform.hxx>
-#include <BRepBuilderAPI_NurbsConvert.hxx>
 #include <BRepTools_HullTransformation.hxx>
 
 //=======================================================================
@@ -64,15 +63,11 @@ void BRepBuilderAPI_HullTransform::InitQuad(const double theAftlim,
 //=======================================================================
 
 void BRepBuilderAPI_HullTransform::Perform(const TopoDS_Shape& S,
-                                           const Standard_Boolean Copy)
+                                           const Standard_Boolean)
 {
-  BRepBuilderAPI_NurbsConvert nc;
-  nc.Perform(S, Copy);
-  myHist.Add(S,nc);
-  TopoDS_Shape Slocal = nc.Shape();
   Handle(BRepTools_HullTransformation) theModif =
     Handle(BRepTools_HullTransformation)::DownCast(myModification);
-  DoModif(Slocal,myModification);
+  DoModif(S,myModification);
 }
 
 
index adff1cbc7ea831540de1bbbc948773f7e7410b7c..123c76b96e0b7f560869b4f4ebd25af26cfbe256 100644 (file)
@@ -29,7 +29,7 @@
 #include <BRepBuilderAPI_Copy.hxx>
 #include <BRepBuilderAPI_Transform.hxx>
 #include <BRepBuilderAPI_GTransform.hxx>
-#include <BRepBuilderAPI_HullTransform.hxx>
+#include <BRepAlgoAPI_HullTransform.hxx>
 #include <BRepBuilderAPI_NurbsConvert.hxx>
 #include <gp_Ax2.hxx>
 #include <gp_Mat.hxx>
 
 #include <Standard_Dump.hxx>
 
-#include <ShapeFix_Shape.hxx>
-#include <BOPAlgo_PaveFiller.hxx>
-#include <BOPTest_Objects.hxx>
-#include <BOPAlgo_Splitter.hxx>
-#include <BRepBuilderAPI_MakeFace.hxx>
-#include <list>
-
 #include <stdio.h>
 
 Standard_IMPORT Draw_Viewer dout;
@@ -1397,7 +1390,7 @@ static Standard_Integer issubshape(Draw_Interpretor& di,
   return 0;
 }
 
-///=======================================================================
+//=======================================================================
 // hulltrsf
 //=======================================================================
 static Standard_Integer hulltrsf(Draw_Interpretor& di, Standard_Integer n, const char** a)
@@ -1405,17 +1398,23 @@ static Standard_Integer hulltrsf(Draw_Interpretor& di, Standard_Integer n, const
   if (n < 3)
   {
     di << "Usage result hull [-l cm cb_new cb_old lpp] or [-q aftlim cca ccf forelim aft_coef fore_coef modify_aft_zone modify_fore_zone] ";
-    di << "[-s XCoord_section1 ... XCoord_sectionN]\n";
+    di << "[-s XCoord_section1 ... XCoord_sectionN] or [-a minSectionTol]\n";
     return 1;
   }
 
-  TopoDS_Shape S = DBRep::Get(a[2]);
-  if (S.IsNull()) {
+  //
+  // Load data
+  //
+  TopoDS_Shape aS = DBRep::Get(a[2]);
+  if (aS.IsNull()) {
     di << a[2] << " is not a valid shape\n";
     return 0;
   }
-  BRepBuilderAPI_HullTransform aHTrsf;
+  BRepAlgoAPI_HullTransform aHTrsf;
+  aHTrsf.SetHull(aS);
+
   std::list<double> aSections;
+  bool isAutoSection = false;
   int i = 3;
   while (i < n)
   {
@@ -1428,6 +1427,7 @@ static Standard_Integer hulltrsf(Draw_Interpretor& di, Standard_Integer n, const
       double _lpp = Atof(a[i + 4]);
       aHTrsf.InitLinear(_cm, _cb_new, _cb_old, _lpp);
       i += 4;
+      continue;
     }
     if (a[i][0] == '-' && a[i][1] == 'q' && n > i+8)
     {
@@ -1442,6 +1442,7 @@ static Standard_Integer hulltrsf(Draw_Interpretor& di, Standard_Integer n, const
       bool _modify_fore_zone = (Draw::Atoi(a[i + 8]) == 1);
       aHTrsf.InitQuad(_aftlim, _cca, _ccf, _forelim, _aft_coef, _fore_coef, _modify_aft_zone, _modify_fore_zone);
       i += 8;
+      continue;
     }
     if (a[i][0] == '-' && a[i][1] == 's')
     {
@@ -1451,45 +1452,31 @@ static Standard_Integer hulltrsf(Draw_Interpretor& di, Standard_Integer n, const
         aSections.push_back(Atof(a[i]));
         i++;
       }
+      aHTrsf.SetSections(aSections);
+      continue;
     }
-    i++;
-  }
-  if (aSections.size() > 0)
-  {
-    // Add splitting edges
-    TopTools_ListOfShape aLSObjects;
-    aLSObjects.Append(S);
-    TopTools_ListOfShape aLSTools;
-    for each (double aPlaneX in aSections)
+    if (a[i][0] == '-' && a[i][1] == 'a')
     {
-      Handle(Geom_Plane) aPlane = new Geom_Plane(gp_Pnt(aPlaneX, 0, 0), gp_Dir(1, 0, 0));
-      TopoDS_Face aFace =
-        BRepBuilderAPI_MakeFace(aPlane, -1000, 1000, -1000, 1000, Precision::Confusion());
-      aLSTools.Append(aFace);
+      isAutoSection = true;
+      double aTol = Atof(a[i + 1]);
+      i+=2;
+      aHTrsf.SetAutoSections(true, aTol);
+      continue;
     }
-
-    BOPAlgo_Splitter pSplitter;
-    pSplitter.Clear();
-    pSplitter.SetArguments(aLSObjects);
-    pSplitter.SetTools(aLSTools);
-    pSplitter.Perform();
-    S = pSplitter.Shape();
+    i++;
   }
 
-  // Perform transformation
-  aHTrsf.Perform(S, true);
-  if (aHTrsf.IsDone()) {
-    // Fix shape
-    Handle(ShapeFix_Shape) aShapeFixTool = new ShapeFix_Shape;
-    aShapeFixTool->Init(aHTrsf.Shape());
-    aShapeFixTool->Perform();
-    DBRep::Set(a[1], aShapeFixTool->Shape());
-    //DBRep::Set(a[1], aHTrsf.Shape());
-  }
-  else {
-    return 1;
-  }
+  TopoDS_Shape aResult = aHTrsf.Perform();
 
+  DBRep::Set(a[1], aResult);
+  auto aResSections = aHTrsf.Sections();
+  if (aResSections.size() > 0)
+  {
+    std::cout << "Sections: ";
+    for (const double aSection : aResSections)
+      std::cout << aSection << " ";
+    std::cout << std::endl;
+  }
   return 0;
 }
 
@@ -1661,10 +1648,11 @@ void  BRepTest::BasicCommands(Draw_Interpretor& theCommands)
                   "hulltrsf result hull "
                   "[-l cm cb_new cb_old lpp] for linear or "
                   "[-q aftlim cca ccf forelim aft_coef fore_coef modify_aft_zone modify_fore_zone] for quad "
-                  "[-s XCoord_section1 ... XCoord_sectionN] to add sections\n",
+                  "[-s XCoord_section1 ... XCoord_sectionN] to add sections or "
+                  "[-a tol (min distance between sections)] for auto sectioning\n",
                   __FILE__,
                   hulltrsf, g);
-  
+
   theCommands.Add("findplane",
                  "findplane name planename ",
                  __FILE__,