diff --git a/src/App/GeoFeature.cpp b/src/App/GeoFeature.cpp index b2d639591f..2a8b36a13e 100644 --- a/src/App/GeoFeature.cpp +++ b/src/App/GeoFeature.cpp @@ -269,7 +269,7 @@ const std::vector& GeoFeature::searchElementCache(const std::string return none; } -std::vector GeoFeature::getElementTypes(bool /*all*/) const +const std::vector& GeoFeature::getElementTypes(bool /*all*/) const { static std::vector nil; auto prop = getPropertyOfGeometry(); @@ -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 3e0107fc0d..0d490c26f0 100644 --- a/src/App/GeoFeature.h +++ b/src/App/GeoFeature.h @@ -175,8 +175,10 @@ public: virtual DocumentObject *getElementOwner(const Data::MappedName & /*name*/) const {return nullptr;} - virtual std::vector getElementTypes(bool all=true) const; + virtual const 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/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 54e0143eaf..f05b01d37b 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -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 5e8c45ed75..c78d0c04c7 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -9709,6 +9709,71 @@ App::DocumentObject *SketchObject::getSubObject( return const_cast(this); } +std::vector +SketchObject::getHigherElements(const char *element, bool silent) const +{ + std::vector res; +// if (testStatus(App::ObjEditing)) { + 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; + for (int i=0; i<2; ++i) { + int geoid = i ? cstr->Second : cstr->First; + const Sketcher::PointPos &pos = i ? cstr->SecondPos : cstr->FirstPos; + if(geoid >= 0 && index == getSolvedSketch().getPointId(geoid, pos) + 1) + res.push_back(Data::IndexedName::fromConst("Constraint", n)); + }; + } + } + return res; +// } + + auto getNames = [&](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; +} + +const std::vector& SketchObject::getElementTypes(bool all) const +{ + if (!all) + return Part::Part2DObject::getElementTypes(); + static std::vector res; + if (res.empty()) { + 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) {