From b8436388794858458c580bac2d2f890c5ebc3c14 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Sat, 17 Feb 2024 18:06:56 -0500 Subject: [PATCH] Toponaming/Part: transfer in and clean getSubShapes, getSubTopoShapes, getOrderedEdges --- src/Mod/Part/App/TopoShape.cpp | 8 -- src/Mod/Part/App/TopoShape.h | 34 +++++++- src/Mod/Part/App/TopoShapeExpansion.cpp | 104 +++++++++++++++++++++++- 3 files changed, 135 insertions(+), 11 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 431fb74645..b3b6ee6641 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -439,14 +439,6 @@ static inline std::vector _getSubShapes(const TopoDS_Shape &s, TopAbs_ShapeEn return shapes; } -std::vector TopoShape::getSubTopoShapes(TopAbs_ShapeEnum type) const { - return _getSubShapes(_Shape,type); -} - -std::vector TopoShape::getSubShapes(TopAbs_ShapeEnum type) const { - return _getSubShapes(_Shape,type); -} - static std::array _ShapeNames; static void initShapeNameMap() { diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index 4bdd9243c3..a15c929dc5 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -188,6 +188,12 @@ enum class MakeSolid makeSolid }; +enum class MapElement +{ + noMap, + map +}; + /** The representation for a CAD Shape */ // NOLINTNEXTLINE cppcoreguidelines-special-member-functions @@ -330,8 +336,32 @@ public: * @return The shape, or a null TopoShape. */ TopoShape getSubTopoShape(TopAbs_ShapeEnum type, int idx, bool silent = false) const; - std::vector getSubTopoShapes(TopAbs_ShapeEnum type = TopAbs_SHAPE) const; - std::vector getSubShapes(TopAbs_ShapeEnum type = TopAbs_SHAPE) const; + /** + * Locate all of the sub TopoShapes of a given type, while avoiding a given type + * @param type The type to find + * @param avoid The type to avoid + * @return The sub TopoShapes. + */ + std::vector getSubTopoShapes(TopAbs_ShapeEnum type=TopAbs_SHAPE, TopAbs_ShapeEnum avoid=TopAbs_SHAPE) const; + /** + * Locate all of the sub TopoDS_Shapes of a given type, while avoiding a given type + * @param type The type to find + * @param avoid The type to avoid + * @return The sub TopoDS_Shapes. + */ + std::vector getSubShapes(TopAbs_ShapeEnum type=TopAbs_SHAPE, TopAbs_ShapeEnum avoid=TopAbs_SHAPE) const; + /** + * Locate all the Edges in the Wires of this shape + * @param mapElement If True, map the subelements ( Edges ) found + * @return Vector of the edges + */ + std::vector getOrderedEdges(MapElement mapElement=MapElement::map) const; + /** + * Locate all the Vertexes in the Wires of this shape + * @param mapElement If True, map the subelements ( Vertexes ) found + * @return Vector of the Vertexes + */ + std::vector getOrderedVertexes(MapElement mapElement=MapElement::map) const; unsigned long countSubShapes(const char* Type) const; unsigned long countSubShapes(TopAbs_ShapeEnum type) const; bool hasSubShape(const char* Type) const; diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 19c0472c90..a9771be3c7 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -691,7 +692,7 @@ void TopoShape::mapSubElementTypeForShape(const TopoShape& other, } char elementType {shapeName(type)[0]}; if (!elementMap()) { - FC_THROWM(NullShapeException, "No element map"); // NOLINT + resetElementMap(); // TODO: Should never happen, but does while code is in transit } std::ostringstream ss; elementMap()->encodeElementName(elementType, name, ss, &sids, Tag, op, other.Tag); @@ -820,6 +821,107 @@ void TopoShape::mapSubElement(const std::vector& shapes, const char* } } +std::vector TopoShape::getSubShapes(TopAbs_ShapeEnum type, TopAbs_ShapeEnum avoid) const { + std::vector ret; + if(isNull()) + return ret; + if (avoid != TopAbs_SHAPE) { + for (TopExp_Explorer exp(getShape(), type, avoid); exp.More(); exp.Next()) + ret.push_back(exp.Current()); + return ret; + } + initCache(); + auto &ancestry = _cache->getAncestry(type); + int count = ancestry.count(); + ret.reserve(count); + for(int i=1;i<=count;++i) + ret.push_back(ancestry.find(_Shape,i)); + return ret; +} + +std::vector TopoShape::getSubTopoShapes(TopAbs_ShapeEnum type, TopAbs_ShapeEnum avoid) const { + if(isNull()) + return std::vector(); + initCache(); + + auto res = _cache->getAncestry(type).getTopoShapes(*this); + if (avoid != TopAbs_SHAPE && hasSubShape(avoid)) { + for (auto it = res.begin(); it != res.end(); ) { + if (_cache->findAncestor(_Shape, it->getShape(), avoid).IsNull()) + ++it; + else + it = res.erase(it); + } + } + return res; +} + +std::vector TopoShape::getOrderedEdges(MapElement mapElement) const +{ + if(isNull()) + return std::vector(); + + std::vector shapes; + if (shapeType() == TopAbs_WIRE) { + BRepTools_WireExplorer xp(TopoDS::Wire(getShape())); + while (xp.More()) { + shapes.push_back(TopoShape(xp.Current())); + xp.Next(); + } + } + else { +// INIT_SHAPE_CACHE(); + initCache(); + for (const auto &w : getSubShapes(TopAbs_WIRE)) { + BRepTools_WireExplorer xp(TopoDS::Wire(w)); + while (xp.More()) { + shapes.push_back(TopoShape(xp.Current())); + xp.Next(); + } + } + } + if (mapElement == MapElement::map) + mapSubElementsTo(shapes); + return shapes; +} + +std::vector TopoShape::getOrderedVertexes(MapElement mapElement) const +{ + if(isNull()) + return std::vector(); + + std::vector shapes; + + auto collect = [&](const TopoDS_Shape &s) { + auto wire = TopoDS::Wire(s); + BRepTools_WireExplorer xp(wire); + while (xp.More()) { + shapes.push_back(TopoShape(xp.CurrentVertex())); + xp.Next(); + } + // special treatment for open wires + TopoDS_Vertex Vfirst, Vlast; + TopExp::Vertices(wire, Vfirst, Vlast); + if (!Vfirst.IsNull() && !Vlast.IsNull()) { + if (!Vfirst.IsSame(Vlast)) { + shapes.push_back(TopoShape(Vlast)); + } + } + }; + + if (shapeType() == TopAbs_WIRE) + collect(getShape()); + else { +// INIT_SHAPE_CACHE(); + initCache(); + for (const auto &s : getSubShapes(TopAbs_WIRE)) + collect(s); + } + if (mapElement == MapElement::map) + mapSubElementsTo(shapes); + return shapes; +} + struct ShapeInfo { const TopoDS_Shape& shape;