--- /dev/null
+#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;
+ }
+ }
+}
--- /dev/null
+// 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
BRepAlgoAPI_Defeaturing.hxx
BRepAlgoAPI_Fuse.cxx
BRepAlgoAPI_Fuse.hxx
+BRepAlgoAPI_HullTransform.cxx
+BRepAlgoAPI_HullTransform.hxx
BRepAlgoAPI_Section.cxx
BRepAlgoAPI_Section.hxx
BRepAlgoAPI_Splitter.cxx
#include <BRepBuilderAPI_HullTransform.hxx>
-#include <BRepBuilderAPI_NurbsConvert.hxx>
#include <BRepTools_HullTransformation.hxx>
//=======================================================================
//=======================================================================
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);
}
#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;
return 0;
}
-///=======================================================================
+//=======================================================================
// hulltrsf
//=======================================================================
static Standard_Integer hulltrsf(Draw_Interpretor& di, Standard_Integer n, const char** a)
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)
{
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)
{
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')
{
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;
}
"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__,