From a7bdbaa662ac8c79d900841770f2836918f09f64 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Thu, 18 Jul 2024 17:20:01 -0400 Subject: [PATCH 1/3] Toponaming: Transfer in getHigherElement --- src/App/GeoFeature.cpp | 11 ++++- src/App/GeoFeature.h | 4 +- src/Mod/Part/App/TopoShapeExpansion.cpp | 19 ++++++++ src/Mod/Sketcher/App/SketchObject.cpp | 65 +++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 2 deletions(-) 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) { From b29abf7ffe22f9e7cb8e99a3c85afb4b1f89b975 Mon Sep 17 00:00:00 2001 From: bgbsww Date: Sun, 21 Jul 2024 22:28:59 -0400 Subject: [PATCH 2/3] Cleanup, format --- src/App/GeoFeature.cpp | 2 +- src/App/GeoFeature.h | 2 +- src/Mod/Part/App/TopoShape.h | 3 ++ src/Mod/Part/App/TopoShapeExpansion.cpp | 2 +- src/Mod/Sketcher/App/SketchObject.cpp | 69 ++++++++++--------------- src/Mod/Sketcher/App/SketchObject.h | 5 ++ 6 files changed, 37 insertions(+), 46 deletions(-) diff --git a/src/App/GeoFeature.cpp b/src/App/GeoFeature.cpp index 2a8b36a13e..b140fdb965 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; } -const std::vector& GeoFeature::getElementTypes(bool /*all*/) const +std::vector GeoFeature::getElementTypes(bool /*all*/) const { static std::vector nil; auto prop = getPropertyOfGeometry(); diff --git a/src/App/GeoFeature.h b/src/App/GeoFeature.h index 0d490c26f0..2f1b9b86a1 100644 --- a/src/App/GeoFeature.h +++ b/src/App/GeoFeature.h @@ -175,7 +175,7 @@ public: virtual DocumentObject *getElementOwner(const Data::MappedName & /*name*/) const {return nullptr;} - virtual const std::vector& getElementTypes(bool all=true) const; + 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; diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index ffd4876cc2..b827778964 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -1496,6 +1496,9 @@ public: 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 f05b01d37b..426ed43610 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()) { diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index c78d0c04c7..4698d1b508 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -201,9 +201,6 @@ void SketchObject::setupObject() { ParameterGrp::handle hGrpp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Sketcher"); -// ArcFitTolerance.setValue(hGrpp->GetFloat("ArcFitTolerance", Precision::Confusion()*10.0)); -// ExternalBSplineMaxDegree.setValue(hGrpp->GetInt("ExternalBSplineMaxDegree", 5)); -// ExternalBSplineTolerance.setValue(hGrpp->GetFloat("ExternalBSplineTolerance", 1e-4)); MakeInternals.setValue(hGrpp->GetBool("MakeInternals", false)); inherited::setupObject(); } @@ -402,42 +399,31 @@ const std::map SketchObject::getInternalElementMap() co return internalElementMap; } -Part::TopoShape SketchObject::buildInternals(const Part::TopoShape &edges) const -{ +Part::TopoShape SketchObject::buildInternals(const Part::TopoShape &edges) const { if (!MakeInternals.getValue()) return Part::TopoShape(); try { Part::WireJoiner joiner; -// joiner.setTolerance(InternalTolerance.getValue()); joiner.setTightBound(true); joiner.setMergeEdges(true); joiner.addShape(edges); Part::TopoShape result(getID(), getDocument()->getStringHasher()); if (!joiner.Shape().IsNull()) { joiner.getResultWires(result, "SKF"); - - // NOTE: we set minElementNames to 2 (i.e to use at least two - // unused edge name to construct face name) in order to reduce the - // chance of face jumping. result = result.makeElementFace(result.getSubTopoShapes(TopAbs_WIRE), - /*op*/"", - /*maker*/"Part::FaceMakerRing", - /*pln*/nullptr -#if 1 -// /*minElementNames (revert to 1 for now, see how it fares)*/1 -#else - /*minElementNames*/2 -#endif - ); + /*op*/"", + /*maker*/"Part::FaceMakerRing", + /*pln*/nullptr + ); } Part::TopoShape openWires(getID(), getDocument()->getStringHasher()); joiner.getOpenWires(openWires, "SKF"); if (openWires.isNull()) - return result; + return result; // No open wires, return either face or empty toposhape if (result.isNull()) - return openWires; - return result.makeElementCompound({result, openWires}); + return openWires; // No face, but we have open wires to return as a shape + return result.makeElementCompound({result, openWires}); // Compound and return both } catch (Base::Exception &e) { FC_WARN("Failed to make face for sketch: " << e.what()); } catch (Standard_Failure &e) { @@ -9713,7 +9699,6 @@ 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); @@ -9730,7 +9715,6 @@ SketchObject::getHigherElements(const char *element, bool silent) const } } return res; -// } auto getNames = [&](const char *element) { bool internal = boost::starts_with(element, internalPrefix()); @@ -9756,7 +9740,7 @@ SketchObject::getHigherElements(const char *element, bool silent) const return res; } -const std::vector& SketchObject::getElementTypes(bool all) const +std::vector SketchObject::getElementTypes(bool all) const { if (!all) return Part::Part2DObject::getElementTypes(); @@ -9836,7 +9820,7 @@ App::ElementNamePair SketchObject::getElementName( if (mapped) mappedElement = InternalShape.getShape().getElementName(name); else if (type == ElementNameType::Export) - ret.first = getExportElementName(InternalShape.getShape(), realName).first; + ret.newName = getExportElementName(InternalShape.getShape(), realName).newName; else mappedElement = InternalShape.getShape().getElementName(realName); @@ -10002,12 +9986,11 @@ bool SketchObject::geoIdFromShapeType(const Data::IndexedName & indexedName, return true; } -std::string SketchObject::convertSubName(const char *subname, bool postfix) const -{ +std::string SketchObject::convertSubName(const char *subname, bool postfix) const { return convertSubName(checkSubName(subname), postfix); } -std::string SketchObject::convertSubName(const Data::IndexedName & indexedName, bool postfix) const{ +std::string SketchObject::convertSubName(const Data::IndexedName &indexedName, bool postfix) const { std::ostringstream ss; if (auto realType = convertInternalName(indexedName.getType())) { auto mapped = InternalShape.getShape().getMappedName( @@ -10023,40 +10006,40 @@ std::string SketchObject::convertSubName(const Data::IndexedName & indexedName, } int geoId; PointPos posId; - if(!geoIdFromShapeType(indexedName,geoId,posId)) { + if (!geoIdFromShapeType(indexedName, geoId, posId)) { ss << indexedName; return ss.str(); } - if(geoId == Sketcher::GeoEnum::HAxis || - geoId == Sketcher::GeoEnum::VAxis || - geoId == Sketcher::GeoEnum::RtPnt) { + if (geoId == Sketcher::GeoEnum::HAxis || + geoId == Sketcher::GeoEnum::VAxis || + geoId == Sketcher::GeoEnum::RtPnt) { if (postfix) ss << Data::ELEMENT_MAP_PREFIX; ss << indexedName; - if(postfix) - ss << '.' << indexedName; + if (postfix) + ss << '.' << indexedName; return ss.str(); } auto geo = getGeometry(geoId); - if(!geo) { + if (!geo) { std::string res = indexedName.toString(); return res; } if (postfix) ss << Data::ELEMENT_MAP_PREFIX; - ss << (geoId>=0?'g':'e') << GeometryFacade::getFacade(geo)->getId(); - if(posId!=PointPos::none) + ss << (geoId >= 0 ? 'g' : 'e') << GeometryFacade::getFacade(geo)->getId(); + if (posId != PointPos::none) ss << 'v' << static_cast(posId); - if(postfix) { + if (postfix) { // rename Edge to edge, and Vertex to vertex to avoid ambiguous of // element mapping of the public shape and internal geometry. if (indexedName.getIndex() <= 0) ss << '.' << indexedName; - else if(boost::starts_with(indexedName.getType(),"Edge")) - ss << ".e" << (indexedName.getType()+1) << indexedName.getIndex(); - else if(boost::starts_with(indexedName.getType(),"Vertex")) - ss << ".v" << (indexedName.getType()+1) << indexedName.getIndex(); + else if (boost::starts_with(indexedName.getType(), "Edge")) + ss << ".e" << (indexedName.getType() + 1) << indexedName.getIndex(); + else if (boost::starts_with(indexedName.getType(), "Vertex")) + ss << ".v" << (indexedName.getType() + 1) << indexedName.getIndex(); else ss << '.' << indexedName; } diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index 3279273e68..54921dfdc8 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -684,6 +684,11 @@ public: 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; From d92029f0bae4772ce90304b18ace5858f163136a Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Wed, 24 Jul 2024 21:48:59 -0500 Subject: [PATCH 3/3] Apply suggestions from code review --- src/Mod/Sketcher/App/SketchObject.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 4698d1b508..1038283761 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -9706,20 +9706,18 @@ SketchObject::getHigherElements(const char *element, bool silent) const ++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)); - }; + 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 = [&](const char *element) { + 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)) { + for (const auto &indexedName : shape.getHigherElements(element+(internal?internalPrefix().size() : 0), silent)) { if (!internal) { res.push_back(indexedName); } @@ -9744,9 +9742,7 @@ 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(), + static std::vector res { Part::TopoShape::shapeName(TopAbs_VERTEX).c_str(), Part::TopoShape::shapeName(TopAbs_EDGE).c_str(), "ExternalEdge", "Constraint", @@ -9754,7 +9750,6 @@ std::vector SketchObject::getElementTypes(bool all) const "InternalFace", "InternalVertex", }; - } return res; }