diff --git a/src/App/GeoFeature.cpp b/src/App/GeoFeature.cpp index b2d639591fb8..b140fdb96526 100644 --- a/src/App/GeoFeature.cpp +++ b/src/App/GeoFeature.cpp @@ -279,4 +279,13 @@ std::vector GeoFeature::getElementTypes(bool /*all*/) const return prop->getComplexData()->getElementTypes(); } +std::vector +GeoFeature::getHigherElements(const char *element, bool silent) const +{ + auto prop = getPropertyOfGeometry(); + if (!prop) + return {}; + return prop->getComplexData()->getHigherElements(element, silent); +} + #endif diff --git a/src/App/GeoFeature.h b/src/App/GeoFeature.h index 3e0107fc0df8..2f1b9b86a112 100644 --- a/src/App/GeoFeature.h +++ b/src/App/GeoFeature.h @@ -177,6 +177,8 @@ class AppExport GeoFeature : public App::DocumentObject virtual std::vector getElementTypes(bool all=true) const; + /// Return the higher level element names of the given element + virtual std::vector getHigherElements(const char *name, bool silent=false) const; protected: void onChanged(const Property* prop) override; diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index ffd4876cc2c5..b82777896461 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -1496,6 +1496,9 @@ class PartExport TopoShape: public Data::ComplexGeoData Data::ElementMapPtr resetElementMap( Data::ElementMapPtr elementMap=Data::ElementMapPtr()) override; + std::vector getHigherElements(const char *element, + bool silent = false) const override; + /** Helper class to return the generated and modified shape given an input shape * * Shape history information is extracted using OCCT APIs diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 54e0143eafa7..426ed4361072 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -3714,7 +3714,7 @@ struct MapperPrism: MapperMaker } } } - virtual const std::vector& generated(const TopoDS_Shape& s) const override + const std::vector& generated(const TopoDS_Shape& s) const override { _res.clear(); switch (s.ShapeType()) { @@ -4775,6 +4775,25 @@ TopoShape& TopoShape::makeElementRefine(const TopoShape& shape, const char* op, return *this; } + std::vector + TopoShape::getHigherElements(const char *element, bool silent) const + { + TopoShape shape = getSubTopoShape(element, silent); + if(shape.isNull()) + return {}; + + std::vector res; + int type = shape.shapeType(); + for(;;) { + if(--type < 0) + break; + const char *shapetype = shapeName((TopAbs_ShapeEnum)type).c_str(); + for(int idx : findAncestors(shape.getShape(), (TopAbs_ShapeEnum)type)) + res.emplace_back(shapetype, idx); + } + return res; + } + TopoShape& TopoShape::makeElementBSplineFace(const TopoShape& shape, FillingStyle style, bool keepBezier, diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 69cd293deafb..103828376153 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -9695,6 +9695,64 @@ App::DocumentObject *SketchObject::getSubObject( return const_cast(this); } +std::vector +SketchObject::getHigherElements(const char *element, bool silent) const +{ + std::vector res; + if (boost::istarts_with(element, "vertex")) { + int n = 0; + int index = atoi(element+6); + for (auto cstr : Constraints.getValues()) { + ++n; + if (cstr->Type != Sketcher::Coincident) + continue; + if(cstr->First >= 0 && index == getSolvedSketch().getPointId(cstr->First, cstr->FirstPos) + 1) + res.push_back(Data::IndexedName::fromConst("Constraint", n)); + if(cstr->Second >= 0 && index == getSolvedSketch().getPointId(cstr->Second, cstr->SecondPos) + 1) + res.push_back(Data::IndexedName::fromConst("Constraint", n)); + } + } + return res; + + auto getNames = [this, &silent, &res](const char *element) { + bool internal = boost::starts_with(element, internalPrefix()); + const auto &shape = internal ? InternalShape.getShape() : Shape.getShape(); + for (const auto &indexedName : shape.getHigherElements(element+(internal?internalPrefix().size() : 0), silent)) { + if (!internal) { + res.push_back(indexedName); + } + else if (boost::equals(indexedName.getType(), "Face") + || boost::equals(indexedName.getType(), "Edge") + || boost::equals(indexedName.getType(), "Wire")) { + res.emplace_back((internalPrefix() + indexedName.getType()).c_str(), indexedName.getIndex()); + } + } + }; + getNames(element); + const auto &elementMap = getInternalElementMap(); + auto it = elementMap.find(element); + if (it != elementMap.end()) { + res.emplace_back(it->second.c_str()); + getNames(it->second.c_str()); + } + return res; +} + +std::vector SketchObject::getElementTypes(bool all) const +{ + if (!all) + return Part::Part2DObject::getElementTypes(); + static std::vector res { Part::TopoShape::shapeName(TopAbs_VERTEX).c_str(), + Part::TopoShape::shapeName(TopAbs_EDGE).c_str(), + "ExternalEdge", + "Constraint", + "InternalEdge", + "InternalFace", + "InternalVertex", + }; + return res; +} + void SketchObject::setExpression(const App::ObjectIdentifier& path, std::shared_ptr expr) { diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index 3279273e686b..54921dfdc8c8 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -684,6 +684,11 @@ class SketcherExport SketchObject: public Part::Part2DObject Part::TopoShape getEdge(const Part::Geometry* geo, const char* name) const; + std::vector getElementTypes(bool all = true) const override; + + std::vector getHigherElements(const char* element, + bool silent = false) const override; + Data::IndexedName checkSubName(const char* subname) const; bool geoIdFromShapeType(const Data::IndexedName&, int& geoId, PointPos& posId) const;