From c6d443dfa51e1c4ae31bb0e13a10dd77a26c5801 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Tue, 20 Feb 2024 13:25:28 -0500 Subject: [PATCH] Toposhape/Part: Transfer in makESolid --- src/Mod/Part/App/TopoShape.h | 39 ++++++++++ src/Mod/Part/App/TopoShapeExpansion.cpp | 97 +++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index 60e295f000..f5b27c0eb3 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -1653,6 +1653,45 @@ public: CN, }; + /** Make a solid using shells or CompSolid + * + * @param shapes: input shapes of either shells or CompSolid. + * @param op: optional string to be encoded into topo naming for indicating + * the operation + * + * @return The function produces a solid. The original content of this + * TopoShape is discarded and replaced with the new shape. The + * function returns the TopoShape itself as a self reference so + * that multiple operations can be carried out for the same shape + * in the same line of code. + */ + TopoShape &makESolid(const std::vector &shapes, const char *op=nullptr); + /** Make a solid using shells or CompSolid + * + * @param shape: input shape of either a shell, a compound of shells, or a + * CompSolid. + * @param op: optional string to be encoded into topo naming for indicating + * the operation + * + * @return The function produces a solid. The original content of this + * TopoShape is discarded and replaced with the new shape. The + * function returns the TopoShape itself as a self reference so + * that multiple operations can be carried out for the same shape + * in the same line of code. + */ + TopoShape &makESolid(const TopoShape &shape, const char *op=nullptr); + /** Make a solid using this shape + * + * @param op: optional string to be encoded into topo naming for indicating + * the operation + * + * @return The function returns a new solid using the shell or CompSolid + * inside this shape. The shape itself is not modified. + */ + TopoShape makESolid(const char *op=nullptr) const { + return TopoShape(0,Hasher).makESolid(*this,op); + } + /** Generic shape making with mapped element name from shape history * diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 6fd47e438e..45f0c3fd8e 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -2641,6 +2641,103 @@ struct MapperThruSections: MapperMaker } }; +TopoShape &TopoShape::makESolid(const std::vector &shapes, const char *op) { + return makESolid(TopoShape().makECompound(shapes),op); +} + +bool TopoShape::fixSolidOrientation() +{ + if (isNull()) + return false; + + if (shapeType() == TopAbs_SOLID) { + TopoDS_Solid solid = TopoDS::Solid(_Shape); + BRepLib::OrientClosedSolid(solid); + if (solid.IsEqual(_Shape)) + return false; + setShape(solid, false); + return true; + } + + if (shapeType() == TopAbs_COMPOUND + || shapeType() == TopAbs_COMPSOLID) + { + auto shapes = getSubTopoShapes(); + bool touched = false; + for (auto &s : shapes) { + if (s.fixSolidOrientation()) + touched = true; + } + if (!touched) + return false; + + BRep_Builder builder; + if (shapeType() == TopAbs_COMPOUND) { + TopoDS_Compound comp; + builder.MakeCompound(comp); + for(auto &s : shapes) { + if (!s.isNull()) + builder.Add(comp, s.getShape()); + } + setShape(comp, false); + } else { + TopoDS_CompSolid comp; + builder.MakeCompSolid(comp); + for(auto &s : shapes) { + if (!s.isNull()) + builder.Add(comp, s.getShape()); + } + setShape(comp, false); + } + return true; + } + + return false; +} + +TopoShape &TopoShape::makESolid(const TopoShape &shape, const char *op) { + if(!op) op = Part::OpCodes::Solid; + + if(shape.isNull()) + HANDLE_NULL_SHAPE; + + //first, if we were given a compsolid, try making a solid out of it + TopoDS_CompSolid compsolid; + int count=0; + for(const auto &s : shape.getSubShapes(TopAbs_COMPSOLID)) { + ++count; + compsolid = TopoDS::CompSolid(s); + if (count > 1) + break; + } + if (count == 0) { + //no compsolids. Get shells... + BRepBuilderAPI_MakeSolid mkSolid; + count=0; + for (const auto &s : shape.getSubShapes(TopAbs_SHELL)) { + ++count; + mkSolid.Add(TopoDS::Shell(s)); + } + + if (count == 0)//no shells? + FC_THROWM(Base::CADKernelError,"No shells or compsolids found in shape"); + + makEShape(mkSolid,shape,op); + + TopoDS_Solid solid = TopoDS::Solid(_Shape); + BRepLib::OrientClosedSolid(solid); + setShape(solid, false); + + } else if (count == 1) { + BRepBuilderAPI_MakeSolid mkSolid(compsolid); + makEShape(mkSolid,shape,op); + } else { // if (count > 1) + FC_THROWM(Base::CADKernelError,"Only one compsolid can be accepted. " + "Provided shape has more than one compsolid."); + } + return *this; +} + TopoShape& TopoShape::makeElementGeneralFuse(const std::vector& _shapes, std::vector>& modifies, double tol,