From: ika Date: Wed, 22 Nov 2023 17:54:46 +0000 (+0000) Subject: Add autosectioning X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=3f1087ea3050440b3b81e1d7e58a70564b273af7;p=occt.git Add autosectioning --- diff --git a/src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.cxx b/src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.cxx new file mode 100644 index 0000000000..7a0b233870 --- /dev/null +++ b/src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.cxx @@ -0,0 +1,199 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//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 aHullsList; + std::list> aSectionsList; + std::list 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> 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(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 index 0000000000..c90c1ca0af --- /dev/null +++ b/src/BRepAlgoAPI/BRepAlgoAPI_HullTransform.hxx @@ -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 +#include + +#include + +//! 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& 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 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 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 diff --git a/src/BRepAlgoAPI/FILES b/src/BRepAlgoAPI/FILES index ac68df71e2..cddebce18b 100644 --- a/src/BRepAlgoAPI/FILES +++ b/src/BRepAlgoAPI/FILES @@ -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 diff --git a/src/BRepBuilderAPI/BRepBuilderAPI_HullTransform.cxx b/src/BRepBuilderAPI/BRepBuilderAPI_HullTransform.cxx index 1f7fa2388d..29e45568d3 100644 --- a/src/BRepBuilderAPI/BRepBuilderAPI_HullTransform.cxx +++ b/src/BRepBuilderAPI/BRepBuilderAPI_HullTransform.cxx @@ -15,7 +15,6 @@ #include -#include #include //======================================================================= @@ -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); } diff --git a/src/BRepTest/BRepTest_BasicCommands.cxx b/src/BRepTest/BRepTest_BasicCommands.cxx index adff1cbc7e..123c76b96e 100644 --- a/src/BRepTest/BRepTest_BasicCommands.cxx +++ b/src/BRepTest/BRepTest_BasicCommands.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -60,13 +60,6 @@ #include -#include -#include -#include -#include -#include -#include - #include 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 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__,