From 4f3d23fe988ba419037c8f874db125d45cf17414 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Mon, 26 Feb 2024 15:52:22 -0500 Subject: [PATCH 1/2] Toposhape/Part: Transfer in FeatureFillet, FeatureChamfer and dependencies --- src/Mod/Part/App/FeatureChamfer.cpp | 32 +++++- src/Mod/Part/App/FeatureFillet.cpp | 33 +++++- src/Mod/Part/App/PartFeature.cpp | 55 ++++++++- src/Mod/Part/App/PartFeature.h | 7 ++ src/Mod/Part/App/TopoShapeExpansion.cpp | 145 ++++++++++++++++++++++++ src/Mod/Part/Gui/DlgFilletEdges.cpp | 44 +++++++ 6 files changed, 313 insertions(+), 3 deletions(-) diff --git a/src/Mod/Part/App/FeatureChamfer.cpp b/src/Mod/Part/App/FeatureChamfer.cpp index 1ba61d65f3..d6393040eb 100644 --- a/src/Mod/Part/App/FeatureChamfer.cpp +++ b/src/Mod/Part/App/FeatureChamfer.cpp @@ -53,7 +53,7 @@ App::DocumentObjectExecReturn *Chamfer::execute() TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; TopExp::MapShapesAndAncestors(baseShape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfEdges); - +#ifndef FC_USE_TNP_FIX std::vector values = Edges.getValues(); for (const auto & value : values) { int id = value.edgeid; @@ -89,6 +89,36 @@ App::DocumentObjectExecReturn *Chamfer::execute() prop.touch(); return App::DocumentObject::StdReturn; +#else + const auto &vals = EdgeLinks.getSubValues(); + const auto &subs = EdgeLinks.getShadowSubs(); + if(subs.size()!=(size_t)Edges.getSize()) + return new App::DocumentObjectExecReturn("Edge link size mismatch"); + size_t i=0; + for(const auto &info : Edges.getValues()) { + auto &sub = subs[i]; + auto &ref = sub.first.size()?sub.first:vals[i]; + ++i; + TopoDS_Shape edge; + try { + edge = baseTopoShape.getSubShape(ref.c_str()); + }catch(...){} + if(edge.IsNull()) + return new App::DocumentObjectExecReturn("Invalid edge link"); + double radius1 = info.radius1; + double radius2 = info.radius2; + const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); + mkChamfer.Add(radius1, radius2, TopoDS::Edge(edge), face); + } + + TopoDS_Shape shape = mkChamfer.Shape(); + if (shape.IsNull()) + return new App::DocumentObjectExecReturn("Resulting shape is null"); + + TopoShape res(0,getDocument()->getStringHasher()); + this->Shape.setValue(res.makEShape(mkChamfer,baseTopoShape,Part::OpCodes::Chamfer)); + return Part::Feature::execute(); +#endif } catch (Standard_Failure& e) { return new App::DocumentObjectExecReturn(e.GetMessageString()); diff --git a/src/Mod/Part/App/FeatureFillet.cpp b/src/Mod/Part/App/FeatureFillet.cpp index 3fb6d696f0..4090da8250 100644 --- a/src/Mod/Part/App/FeatureFillet.cpp +++ b/src/Mod/Part/App/FeatureFillet.cpp @@ -48,13 +48,15 @@ App::DocumentObjectExecReturn *Fillet::execute() if (!link) return new App::DocumentObjectExecReturn("No object linked"); - auto baseShape = Feature::getShape(link); try { #if defined(__GNUC__) && defined (FC_OS_LINUX) Base::SignalException se; #endif + auto baseShape = Feature::getShape(link); + TopoShape baseTopoShape = Feature::getTopoShape(link); BRepFilletAPI_MakeFillet mkFillet(baseShape); +#ifndef FC_USE_TNP_FIX TopTools_IndexedMapOfShape mapOfShape; TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfShape); @@ -92,6 +94,35 @@ App::DocumentObjectExecReturn *Fillet::execute() prop.touch(); return App::DocumentObject::StdReturn; +#else + const auto &vals = EdgeLinks.getSubValues(); + const auto &subs = EdgeLinks.getShadowSubs(); + if(subs.size()!=(size_t)Edges.getSize()) + return new App::DocumentObjectExecReturn("Edge link size mismatch"); + size_t i=0; + for(const auto &info : Edges.getValues()) { + auto &sub = subs[i]; + auto &ref = sub.first.size()?sub.first:vals[i]; + ++i; + TopoDS_Shape edge; + try { + edge = baseTopoShape.getSubShape(ref.c_str()); + }catch(...){} + if(edge.IsNull()) + return new App::DocumentObjectExecReturn("Invalid edge link"); + double radius1 = info.radius1; + double radius2 = info.radius2; + mkFillet.Add(radius1, radius2, TopoDS::Edge(edge)); + } + + TopoDS_Shape shape = mkFillet.Shape(); + if (shape.IsNull()) + return new App::DocumentObjectExecReturn("Resulting shape is null"); + + TopoShape res(0,getDocument()->getStringHasher()); + this->Shape.setValue(res.makEShape(mkFillet,baseTopoShape,Part::OpCodes::Fillet)); + return Part::Feature::execute(); +#endif } catch (Standard_Failure& e) { return new App::DocumentObjectExecReturn(e.GetMessageString()); diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp index 5c0fca6fb1..9c0cb0088c 100644 --- a/src/Mod/Part/App/PartFeature.cpp +++ b/src/Mod/Part/App/PartFeature.cpp @@ -1217,16 +1217,69 @@ FilletBase::FilletBase() { ADD_PROPERTY(Base,(nullptr)); ADD_PROPERTY(Edges,(0,0,0)); + ADD_PROPERTY_TYPE(EdgeLinks,(0), 0, + (App::PropertyType)(App::Prop_ReadOnly|App::Prop_Hidden),0); Edges.setSize(0); } short FilletBase::mustExecute() const { - if (Base.isTouched() || Edges.isTouched()) + if (Base.isTouched() || Edges.isTouched() || EdgeLinks.isTouched()) return 1; return 0; } +void FilletBase::onChanged(const App::Property *prop) { + if(getDocument() && !getDocument()->testStatus(App::Document::Restoring)) { + if(prop == &Edges || prop == &Base) { + if(!prop->testStatus(App::Property::User3)) + syncEdgeLink(); + } + } + Feature::onChanged(prop); +} + +void FilletBase::onDocumentRestored() { + if(EdgeLinks.getSubValues().empty()) + syncEdgeLink(); + Feature::onDocumentRestored(); +} + +void FilletBase::syncEdgeLink() { + if(!Base.getValue() || !Edges.getSize()) { + EdgeLinks.setValue(0); + return; + } + std::vector subs; + std::string sub("Edge"); + for(auto &info : Edges.getValues()) + subs.emplace_back(sub+std::to_string(info.edgeid)); + EdgeLinks.setValue(Base.getValue(),subs); +} + +void FilletBase::onUpdateElementReference(const App::Property *prop) { + if(prop!=&EdgeLinks || !getNameInDocument()) + return; + auto values = Edges.getValues(); + const auto &subs = EdgeLinks.getSubValues(); + for(size_t i=0;i=subs.size()) { + FC_WARN("fillet edge count mismatch in object " << getFullName()); + break; + } + int idx = 0; + sscanf(subs[i].c_str(),"Edge%d",&idx); + if(idx) + values[i].edgeid = idx; + else + FC_WARN("invalid fillet edge link '" << subs[i] << "' in object " + << getFullName()); + } + Edges.setStatus(App::Property::User3,true); + Edges.setValues(values); + Edges.setStatus(App::Property::User3,false); +} + // --------------------------------------------------------- PROPERTY_SOURCE(Part::FeatureExt, Part::Feature) diff --git a/src/Mod/Part/App/PartFeature.h b/src/Mod/Part/App/PartFeature.h index 31975fdc08..34adae3b69 100644 --- a/src/Mod/Part/App/PartFeature.h +++ b/src/Mod/Part/App/PartFeature.h @@ -175,8 +175,15 @@ public: App::PropertyLink Base; PropertyFilletEdges Edges; + App::PropertyLinkSub EdgeLinks; short mustExecute() const override; + virtual void onUpdateElementReference(const App::Property *prop) override; + +protected: + virtual void onDocumentRestored() override; + virtual void onChanged(const App::Property *) override; + void syncEdgeLink(); }; using FeaturePython = App::FeaturePythonT; diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 225c114fa2..a60c75c618 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -102,6 +102,7 @@ #include "Geometry.h" #include "BRepOffsetAPI_MakeOffsetFix.h" +#include #include #include #include @@ -814,6 +815,7 @@ void TopoShape::mapSubElementForShape(const TopoShape& other, const char* op) void TopoShape::mapSubElement(const TopoShape& other, const char* op, bool forceHasher) { +#ifndef FC_USE_TNP_FIX if (!canMapElement(other)) { return; } @@ -831,6 +833,102 @@ void TopoShape::mapSubElement(const TopoShape& other, const char* op, bool force } mapSubElementForShape(other, op); +#else + if(!canMapElement(other)) + return; + + if (!getElementMapSize(false) && this->_Shape.IsPartner(other._Shape)) { + if (!this->Hasher) + this->Hasher = other.Hasher; + copyElementMap(other, op); + return; + } + + bool warned = false; + static const std::array types = {TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE}; + + auto checkHasher = [this](const TopoShape &other) { + if(Hasher) { + if(other.Hasher!=Hasher) { + if(!getElementMapSize(false)) { + if(FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) + FC_WARN("hasher mismatch"); + }else { + // FC_THROWM(Base::RuntimeError, "hasher mismatch"); + FC_ERR("hasher mismatch"); + } + Hasher = other.Hasher; + } + }else + Hasher = other.Hasher; + }; + + for(auto type : types) { + auto &shapeMap = _cache->getAncestry(type); + auto &otherMap = other._cache->getAncestry(type); + if(!shapeMap.count() || !otherMap.count()) + continue; + if(!forceHasher && other.Hasher) { + forceHasher = true; + checkHasher(other); + } + const char *shapetype = shapeName(type).c_str(); + std::ostringstream ss; + + bool forward; + int count; + if(otherMap.count()<=shapeMap.count()) { + forward = true; + count = otherMap.count(); + }else{ + forward = false; + count = shapeMap.count(); + } + for(int k=1;k<=count;++k) { + int i,idx; + if(forward) { + i = k; + idx = shapeMap.find(_Shape,otherMap.find(other._Shape,k)); + if(!idx) continue; + } else { + idx = k; + i = otherMap.find(other._Shape,shapeMap.find(_Shape,k)); + if(!i) continue; + } + Data::IndexedName element = Data::IndexedName::fromConst(shapetype, idx); + for(auto &v : other.getElementMappedNames( + Data::IndexedName::fromConst(shapetype,i),true)) + { + auto &name = v.first; + auto &sids = v.second; + if(sids.size()) { + if (!Hasher) + Hasher = sids[0].getHasher(); + else if (!sids[0].isFromSameHasher(Hasher)) { + if (!warned) { + warned = true; + FC_WARN("hasher mismatch"); + } + sids.clear(); + } + } + ss.str(""); + + // Originally in ComplexGeoData::setElementName + // LinkStable/src/App/ComplexGeoData.cpp#L1631 + // No longer possible after map separated in ElementMap.cpp + + if (!elementMap()) { + resetElementMap(std::make_shared()); + } + + elementMap()->encodeElementName(shapetype[0],name,ss,&sids,Tag,op,other.Tag); + elementMap()->setElementName(element,name,Tag,&sids); + } + } + } + +#endif } void TopoShape::mapSubElementsTo(std::vector& shapes, const char* op) const @@ -892,6 +990,7 @@ void TopoShape::mapCompoundSubElements(const std::vector& shapes, con void TopoShape::mapSubElement(const std::vector& shapes, const char* op) { +#ifndef FC_USE_TNP_FIX if (shapes.empty()) { return; } @@ -904,6 +1003,52 @@ void TopoShape::mapSubElement(const std::vector& shapes, const char* mapSubElement(shape, op); } } +#else + if (shapes.empty()) + return; + + if (shapeType(true) == TopAbs_COMPOUND) { + int count = 0; + for (auto & s : shapes) { + if (s.isNull()) + continue; + if (!getSubShape(TopAbs_SHAPE, ++count, true).IsPartner(s._Shape)) { + count = 0; + break; + } + } + if (count) { + std::vector children; + children.reserve(count*3); + TopAbs_ShapeEnum types[] = {TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE}; + for (unsigned i=0; i TopoShape::getSubShapes(TopAbs_ShapeEnum type, diff --git a/src/Mod/Part/Gui/DlgFilletEdges.cpp b/src/Mod/Part/Gui/DlgFilletEdges.cpp index 28971ff8df..99a562c78a 100644 --- a/src/Mod/Part/Gui/DlgFilletEdges.cpp +++ b/src/Mod/Part/Gui/DlgFilletEdges.cpp @@ -592,6 +592,16 @@ void DlgFilletEdges::setupFillet(const std::vector& objs) { App::DocumentObject* base = d->fillet->Base.getValue(); const std::vector& e = d->fillet->Edges.getValues(); + const auto &subs = d->fillet->EdgeLinks.getShadowSubs(); + if(subs.size()!=e.size()) { + FC_ERR("edge link size mismatch"); + return; + } + std::set subSet; + for(auto &sub : subs) + subSet.insert(sub.first.empty()?sub.second:sub.first); + + std::string tmp; std::vector::const_iterator it = std::find(objs.begin(), objs.end(), base); if (it != objs.end()) { // toggle visibility @@ -613,6 +623,40 @@ void DlgFilletEdges::setupFillet(const std::vector& objs) std::vector subElements; QStandardItemModel *model = qobject_cast(ui->treeView->model()); bool block = model->blockSignals(true); // do not call toggleCheckState + auto baseShape = Part::Feature::getTopoShape(base); + std::set elements; + for(size_t i=0;igetFullName() << "." << ref); + + for(auto &mapped : Part::Feature::getRelatedElements(base,ref.c_str())) { + tmp.clear(); + if(!subSet.insert(mapped.index.toString(tmp)).second + || !subSet.insert(mapped.name.toString(0)).second) + continue; + FC_WARN("guess element reference: " << ref << " -> " << mapped.index); + elements.emplace(mapped.index.getIndex(),e[i].radius1,e[i].radius2); + } + } + for (const auto & et : e) { std::vector::iterator it = std::find(d->edge_ids.begin(), d->edge_ids.end(), et.edgeid); if (it != d->edge_ids.end()) { From 28cb50848933ed2d616391c726ac4d5b4ae09078 Mon Sep 17 00:00:00 2001 From: bgbsww Date: Mon, 26 Feb 2024 16:51:15 -0500 Subject: [PATCH 2/2] Toposhape/Part: Cleanup FeatureFillet, FeatureChamfer and dependencies --- src/App/ComplexGeoData.h | 2 +- src/App/IndexedName.h | 6 +- src/Mod/Part/App/FeatureChamfer.cpp | 20 +- src/Mod/Part/App/FeatureFillet.cpp | 20 +- src/Mod/Part/App/PartFeature.h | 6 +- src/Mod/Part/App/TopoShape.cpp | 1 + src/Mod/Part/App/TopoShapeExpansion.cpp | 253 ++++++++++-------- src/Mod/Part/Gui/DlgFilletEdges.cpp | 3 +- tests/src/Mod/Part/App/FeatureChamfer.cpp | 1 - tests/src/Mod/Part/App/TopoShapeExpansion.cpp | 72 +++++ 10 files changed, 254 insertions(+), 130 deletions(-) diff --git a/src/App/ComplexGeoData.h b/src/App/ComplexGeoData.h index ab91d9acac..9fb24abc27 100644 --- a/src/App/ComplexGeoData.h +++ b/src/App/ComplexGeoData.h @@ -52,7 +52,7 @@ using BoundBox3d = BoundBox3; namespace Data { -struct MappedChildElements; +//struct MappedChildElements; /** Segments * Sub-element type of the ComplexGeoData type diff --git a/src/App/IndexedName.h b/src/App/IndexedName.h index 85282b9545..7b152a2506 100644 --- a/src/App/IndexedName.h +++ b/src/App/IndexedName.h @@ -129,12 +129,16 @@ public: /// include the index. /// /// \param buffer A (possibly non-empty) string buffer to append the name to. - void appendToStringBuffer(std::string & buffer) const + /// \return A const char pointer to the name we appended to the buffer. + const char * appendToStringBuffer(std::string & buffer) const { + // Note! buffer is not cleared on purpose. + std::size_t offset = buffer.size(); buffer += this->type; if (this->index > 0) { buffer += std::to_string(this->index); } + return buffer.c_str() + offset; } /// Create and return a new std::string with this name in it. diff --git a/src/Mod/Part/App/FeatureChamfer.cpp b/src/Mod/Part/App/FeatureChamfer.cpp index d6393040eb..45ee4f748a 100644 --- a/src/Mod/Part/App/FeatureChamfer.cpp +++ b/src/Mod/Part/App/FeatureChamfer.cpp @@ -32,6 +32,7 @@ #endif #include "FeatureChamfer.h" +#include "TopoShapeOpCode.h" using namespace Part; @@ -47,13 +48,15 @@ App::DocumentObjectExecReturn *Chamfer::execute() return new App::DocumentObjectExecReturn("No object linked"); try { + TopoShape baseTopoShape = Feature::getTopoShape(link); auto baseShape = Feature::getShape(link); BRepFilletAPI_MakeChamfer mkChamfer(baseShape); - TopTools_IndexedMapOfShape mapOfEdges; TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; TopExp::MapShapesAndAncestors(baseShape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); + TopTools_IndexedMapOfShape mapOfEdges; TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfEdges); #ifndef FC_USE_TNP_FIX + std::vector values = Edges.getValues(); for (const auto & value : values) { int id = value.edgeid; @@ -99,10 +102,13 @@ App::DocumentObjectExecReturn *Chamfer::execute() auto &sub = subs[i]; auto &ref = sub.first.size()?sub.first:vals[i]; ++i; - TopoDS_Shape edge; - try { - edge = baseTopoShape.getSubShape(ref.c_str()); - }catch(...){} + // Toponaming project March 2024: Replaced this code because it wouldn't work: +// TopoDS_Shape edge; +// try { +// edge = baseTopoShape.getSubShape(ref.c_str()); +// }catch(...){} + auto id = Data::MappedName(ref.c_str()).toIndexedName().getIndex(); + const TopoDS_Edge& edge = TopoDS::Edge(mapOfEdges.FindKey(id)); if(edge.IsNull()) return new App::DocumentObjectExecReturn("Invalid edge link"); double radius1 = info.radius1; @@ -115,8 +121,8 @@ App::DocumentObjectExecReturn *Chamfer::execute() if (shape.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is null"); - TopoShape res(0,getDocument()->getStringHasher()); - this->Shape.setValue(res.makEShape(mkChamfer,baseTopoShape,Part::OpCodes::Chamfer)); + TopoShape res(0); + this->Shape.setValue(res.makeElementShape(mkChamfer,baseTopoShape,Part::OpCodes::Chamfer)); return Part::Feature::execute(); #endif } diff --git a/src/Mod/Part/App/FeatureFillet.cpp b/src/Mod/Part/App/FeatureFillet.cpp index 4090da8250..d9a574fcc3 100644 --- a/src/Mod/Part/App/FeatureFillet.cpp +++ b/src/Mod/Part/App/FeatureFillet.cpp @@ -34,6 +34,7 @@ #include #include "FeatureFillet.h" +#include "TopoShapeOpCode.h" using namespace Part; @@ -56,9 +57,11 @@ App::DocumentObjectExecReturn *Fillet::execute() auto baseShape = Feature::getShape(link); TopoShape baseTopoShape = Feature::getTopoShape(link); BRepFilletAPI_MakeFillet mkFillet(baseShape); -#ifndef FC_USE_TNP_FIX TopTools_IndexedMapOfShape mapOfShape; TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfShape); + TopTools_IndexedMapOfShape mapOfEdges; + TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfEdges); +#ifndef FC_USE_TNP_FIX std::vector values = Edges.getValues(); for (const auto & value : values) { @@ -104,10 +107,13 @@ App::DocumentObjectExecReturn *Fillet::execute() auto &sub = subs[i]; auto &ref = sub.first.size()?sub.first:vals[i]; ++i; - TopoDS_Shape edge; - try { - edge = baseTopoShape.getSubShape(ref.c_str()); - }catch(...){} + // Toponaming project March 2024: Replaced this code because it wouldn't work: +// TopoDS_Shape edge; +// try { +// edge = baseTopoShape.getSubShape(ref.c_str()); +// }catch(...){} + auto id = Data::MappedName(ref.c_str()).toIndexedName().getIndex(); + const TopoDS_Edge& edge = TopoDS::Edge(mapOfEdges.FindKey(id)); if(edge.IsNull()) return new App::DocumentObjectExecReturn("Invalid edge link"); double radius1 = info.radius1; @@ -119,8 +125,8 @@ App::DocumentObjectExecReturn *Fillet::execute() if (shape.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is null"); - TopoShape res(0,getDocument()->getStringHasher()); - this->Shape.setValue(res.makEShape(mkFillet,baseTopoShape,Part::OpCodes::Fillet)); + TopoShape res(0); + this->Shape.setValue(res.makeElementShape(mkFillet,baseTopoShape,Part::OpCodes::Fillet)); return Part::Feature::execute(); #endif } diff --git a/src/Mod/Part/App/PartFeature.h b/src/Mod/Part/App/PartFeature.h index 34adae3b69..f4888669ea 100644 --- a/src/Mod/Part/App/PartFeature.h +++ b/src/Mod/Part/App/PartFeature.h @@ -178,11 +178,11 @@ public: App::PropertyLinkSub EdgeLinks; short mustExecute() const override; - virtual void onUpdateElementReference(const App::Property *prop) override; + void onUpdateElementReference(const App::Property *prop) override; protected: - virtual void onDocumentRestored() override; - virtual void onChanged(const App::Property *) override; + void onDocumentRestored() override; + void onChanged(const App::Property *) override; void syncEdgeLink(); }; diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 845146ea3b..b25190f94c 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -336,6 +336,7 @@ Data::Segment* TopoShape::getSubElement(const char* Type, unsigned long n) const return new ShapeSegment(getSubShape(temp.c_str())); } +// Type can be (should be?) a subshape name, not a type, E.G. Edge3 TopoDS_Shape TopoShape::getSubShape(const char* Type, bool silent) const { TopoShape s(*this); s.Tag = 0; diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index a60c75c618..cce20f8e4a 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -272,7 +272,7 @@ TopoDS_Shape TopoShape::located(const TopoDS_Shape& tds, const gp_Trsf& transfer return moved(sCopy, transfer); } -void TopoShape::operator = (const TopoShape& sh) +void TopoShape::operator=(const TopoShape& sh) { if (this != &sh) { this->setShape(sh._Shape, true); @@ -834,12 +834,14 @@ void TopoShape::mapSubElement(const TopoShape& other, const char* op, bool force mapSubElementForShape(other, op); #else - if(!canMapElement(other)) + if (!canMapElement(other)) { return; + } if (!getElementMapSize(false) && this->_Shape.IsPartner(other._Shape)) { - if (!this->Hasher) + if (!this->Hasher) { this->Hasher = other.Hasher; + } copyElementMap(other, op); return; } @@ -847,63 +849,74 @@ void TopoShape::mapSubElement(const TopoShape& other, const char* op, bool force bool warned = false; static const std::array types = {TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE}; - auto checkHasher = [this](const TopoShape &other) { - if(Hasher) { - if(other.Hasher!=Hasher) { - if(!getElementMapSize(false)) { - if(FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) + auto checkHasher = [this](const TopoShape& other) { + if (Hasher) { + if (other.Hasher != Hasher) { + if (!getElementMapSize(false)) { + if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) { FC_WARN("hasher mismatch"); - }else { + } + } + else { // FC_THROWM(Base::RuntimeError, "hasher mismatch"); FC_ERR("hasher mismatch"); } Hasher = other.Hasher; } - }else + } + else { Hasher = other.Hasher; + } }; - for(auto type : types) { - auto &shapeMap = _cache->getAncestry(type); - auto &otherMap = other._cache->getAncestry(type); - if(!shapeMap.count() || !otherMap.count()) + for (auto type : types) { + auto& shapeMap = _cache->getAncestry(type); + auto& otherMap = other._cache->getAncestry(type); + if (!shapeMap.count() || !otherMap.count()) { continue; - if(!forceHasher && other.Hasher) { + } + if (!forceHasher && other.Hasher) { forceHasher = true; checkHasher(other); } - const char *shapetype = shapeName(type).c_str(); + const char* shapetype = shapeName(type).c_str(); std::ostringstream ss; bool forward; int count; - if(otherMap.count()<=shapeMap.count()) { + if (otherMap.count() <= shapeMap.count()) { forward = true; count = otherMap.count(); - }else{ + } + else { forward = false; count = shapeMap.count(); } - for(int k=1;k<=count;++k) { - int i,idx; - if(forward) { + for (int k = 1; k <= count; ++k) { + int i, idx; + if (forward) { i = k; - idx = shapeMap.find(_Shape,otherMap.find(other._Shape,k)); - if(!idx) continue; - } else { + idx = shapeMap.find(_Shape, otherMap.find(other._Shape, k)); + if (!idx) { + continue; + } + } + else { idx = k; - i = otherMap.find(other._Shape,shapeMap.find(_Shape,k)); - if(!i) continue; + i = otherMap.find(other._Shape, shapeMap.find(_Shape, k)); + if (!i) { + continue; + } } Data::IndexedName element = Data::IndexedName::fromConst(shapetype, idx); - for(auto &v : other.getElementMappedNames( - Data::IndexedName::fromConst(shapetype,i),true)) - { - auto &name = v.first; - auto &sids = v.second; - if(sids.size()) { - if (!Hasher) + for (auto& v : + other.getElementMappedNames(Data::IndexedName::fromConst(shapetype, i), true)) { + auto& name = v.first; + auto& sids = v.second; + if (sids.size()) { + if (!Hasher) { Hasher = sids[0].getHasher(); + } else if (!sids[0].isFromSameHasher(Hasher)) { if (!warned) { warned = true; @@ -922,8 +935,8 @@ void TopoShape::mapSubElement(const TopoShape& other, const char* op, bool force resetElementMap(std::make_shared()); } - elementMap()->encodeElementName(shapetype[0],name,ss,&sids,Tag,op,other.Tag); - elementMap()->setElementName(element,name,Tag,&sids); + elementMap()->encodeElementName(shapetype[0], name, ss, &sids, Tag, op, other.Tag); + elementMap()->setElementName(element, name, Tag, &sids); } } } @@ -1004,14 +1017,16 @@ void TopoShape::mapSubElement(const std::vector& shapes, const char* } } #else - if (shapes.empty()) + if (shapes.empty()) { return; + } if (shapeType(true) == TopAbs_COMPOUND) { int count = 0; - for (auto & s : shapes) { - if (s.isNull()) + for (auto& s : shapes) { + if (s.isNull()) { continue; + } if (!getSubShape(TopAbs_SHAPE, ++count, true).IsPartner(s._Shape)) { count = 0; break; @@ -1019,26 +1034,30 @@ void TopoShape::mapSubElement(const std::vector& shapes, const char* } if (count) { std::vector children; - children.reserve(count*3); + children.reserve(count * 3); TopAbs_ShapeEnum types[] = {TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE}; - for (unsigned i=0; i& shapes, const char* } } - for(auto &shape : shapes) - mapSubElement(shape,op); + for (auto& shape : shapes) { + mapSubElement(shape, op); + } #endif } @@ -3506,18 +3526,20 @@ struct MapperThruSections: MapperMaker } }; -struct MapperPrism: MapperMaker { +struct MapperPrism: MapperMaker +{ std::unordered_map vertexMap; ShapeMapper::ShapeMap edgeMap; - MapperPrism(BRepFeat_MakePrism &maker, const TopoShape &upTo) - :MapperMaker(maker) + MapperPrism(BRepFeat_MakePrism& maker, const TopoShape& upTo) + : MapperMaker(maker) { (void)upTo; std::vector shapes; - for(TopTools_ListIteratorOfListOfShape it(maker.FirstShape());it.More();it.Next()) + for (TopTools_ListIteratorOfListOfShape it(maker.FirstShape()); it.More(); it.Next()) { shapes.push_back(it.Value()); + } if (shapes.size()) { // It seems that BRepFeat_MakePrism::newEdges() does not return @@ -3527,18 +3549,21 @@ struct MapperPrism: MapperMaker { // i.e. the bottom profile, and add all edges that shares a // vertex with the profiles as new edges. - std::unordered_set edgeSet; + std::unordered_set edgeSet; TopoShape bottom; - bottom.makeElementCompound(shapes, nullptr, TopoShape::SingleShapeCompoundCreationPolicy::returnShape); + bottom.makeElementCompound(shapes, + nullptr, + TopoShape::SingleShapeCompoundCreationPolicy::returnShape); TopoShape shape(maker.Shape()); - for (auto &vertex : bottom.getSubShapes(TopAbs_VERTEX)) { - for (auto &e : shape.findAncestorsShapes(vertex, TopAbs_EDGE)) { + for (auto& vertex : bottom.getSubShapes(TopAbs_VERTEX)) { + for (auto& e : shape.findAncestorsShapes(vertex, TopAbs_EDGE)) { // Make sure to not visit the the same edge twice. // And check only edge that are not found in the bottom profile if (!edgeSet.insert(e).second && !bottom.findShape(e)) { auto otherVertex = TopExp::FirstVertex(TopoDS::Edge(e)); - if (otherVertex.IsSame(vertex)) + if (otherVertex.IsSame(vertex)) { otherVertex = TopExp::LastVertex(TopoDS::Edge(e)); + } vertexMap[vertex] = otherVertex; } } @@ -3550,37 +3575,44 @@ struct MapperPrism: MapperMaker { // corresponding edges in the top profile, what an extra criteria // for disambiguation. That is, the pair of edges (bottom and top) // must belong to the same face. - for (auto &edge : bottom.getSubShapes(TopAbs_EDGE)) { + for (auto& edge : bottom.getSubShapes(TopAbs_EDGE)) { std::vector indices; auto first = TopExp::FirstVertex(TopoDS::Edge(edge)); auto last = TopExp::LastVertex(TopoDS::Edge(edge)); auto itFirst = vertexMap.find(first); auto itLast = vertexMap.find(last); - if (itFirst == vertexMap.end() || itLast ==vertexMap.end()) + if (itFirst == vertexMap.end() || itLast == vertexMap.end()) { continue; + } std::vector faces; - for (int idx : shape.findAncestors(edge, TopAbs_FACE)) + for (int idx : shape.findAncestors(edge, TopAbs_FACE)) { faces.push_back(shape.getSubTopoShape(TopAbs_FACE, idx)); - if (faces.empty()) + } + if (faces.empty()) { continue; + } for (int idx : shape.findAncestors(itFirst->second, TopAbs_EDGE)) { auto e = shape.getSubTopoShape(TopAbs_EDGE, idx); - if (!e.findShape(itLast->second)) + if (!e.findShape(itLast->second)) { continue; - for (auto &face : faces) { - if (!face.findShape(e.getShape())) + } + for (auto& face : faces) { + if (!face.findShape(e.getShape())) { continue; - auto &entry = edgeMap[edge]; - if (entry.shapeSet.insert(e.getShape()).second) + } + auto& entry = edgeMap[edge]; + if (entry.shapeSet.insert(e.getShape()).second) { entry.shapes.push_back(e.getShape()); + } } } } } } - virtual const std::vector &generated(const TopoDS_Shape &s) const override { + virtual const std::vector& generated(const TopoDS_Shape& s) const override + { _res.clear(); - switch(s.ShapeType()) { + switch (s.ShapeType()) { case TopAbs_VERTEX: { auto it = vertexMap.find(s); if (it != vertexMap.end()) { @@ -3591,9 +3623,10 @@ struct MapperPrism: MapperMaker { } case TopAbs_EDGE: { auto it = edgeMap.find(s); - if (it != edgeMap.end()) - return it->second.shapes; - break; + if (it != edgeMap.end()) { + return it->second.shapes; + } + break; } default: break; @@ -3796,7 +3829,7 @@ TopoShape& TopoShape::makeElementFilledFace(const std::vector& _shape // TODO: This method does not appear to ever be called in the codebase, and it is probably // broken, because using TopoShape() with no parameters means the result will not have an // element Map. -//TopoShape& TopoShape::makeElementSolid(const std::vector& shapes, const char* op) +// TopoShape& TopoShape::makeElementSolid(const std::vector& shapes, const char* op) //{ // return makeElementSolid(TopoShape().makeElementCompound(shapes), op); //} @@ -4096,22 +4129,25 @@ TopoShape& TopoShape::makeElementShape(BRepBuilderAPI_MakeShape& mkShape, { TopoDS_Shape shape; // OCCT 7.3.x requires calling Solid() and not Shape() to function correctly - if ( typeid(mkShape) == typeid(BRepPrimAPI_MakeHalfSpace) ) { + if (typeid(mkShape) == typeid(BRepPrimAPI_MakeHalfSpace)) { shape = static_cast(mkShape).Solid(); - } else { + } + else { shape = mkShape.Shape(); } return makeShapeWithElementMap(shape, MapperMaker(mkShape), shapes, op); } -TopoShape &TopoShape::makeElementShape(BRepFeat_MakePrism &mkShape, - const std::vector &sources, - const TopoShape &upTo, - const char *op) +TopoShape& TopoShape::makeElementShape(BRepFeat_MakePrism& mkShape, + const std::vector& sources, + const TopoShape& upTo, + const char* op) { - if(!op) op = Part::OpCodes::Prism; + if (!op) { + op = Part::OpCodes::Prism; + } MapperPrism mapper(mkShape, upTo); - makeShapeWithElementMap(mkShape.Shape(),mapper,sources,op); + makeShapeWithElementMap(mkShape.Shape(), mapper, sources, op); return *this; } @@ -4197,7 +4233,7 @@ TopoShape& TopoShape::makeElementPrism(const TopoShape& base, const gp_Vec& vec, // TODO: This code was transferred in Feb 2024 as part of the toponaming project, but appears to be // unused. It is potentially useful if debugged. -//TopoShape& TopoShape::makeElementPrismUntil(const TopoShape& _base, +// TopoShape& TopoShape::makeElementPrismUntil(const TopoShape& _base, // const TopoShape& profile, // const TopoShape& supportFace, // const TopoShape& __uptoface, @@ -4266,9 +4302,9 @@ TopoShape& TopoShape::makeElementPrism(const TopoShape& base, const gp_Vec& vec, // } // // if (remove_limits) { -// // Note: Using an unlimited face every time gives unnecessary failures for concave faces -// TopLoc_Location loc = face.Location(); -// BRepAdaptor_Surface adapt(face, Standard_False); +// // Note: Using an unlimited face every time gives unnecessary failures for concave +// faces TopLoc_Location loc = face.Location(); BRepAdaptor_Surface adapt(face, +// Standard_False); // // use the placement of the adapter, not of the upToFace // loc = TopLoc_Location(adapt.Trsf()); // BRepBuilderAPI_MakeFace mkFace(adapt.Surface().Surface(), Precision::Confusion()); @@ -4801,7 +4837,7 @@ TopoShape& TopoShape::makeElementBSplineFace(const std::vector& input } unsigned ind = 0; for (auto& edge : newEdges) { - if ( ind < edges.size() ) { + if (ind < edges.size()) { edge.resetElementMap(edges[ind++].elementMap()); } } @@ -5655,33 +5691,32 @@ TopoShape& TopoShape::makeElementBoolean(const char* maker, return *this; } -bool TopoShape::isSame(const Data::ComplexGeoData &_other) const +bool TopoShape::isSame(const Data::ComplexGeoData& _other) const { - if(!_other.isDerivedFrom(TopoShape::getClassTypeId())) - return false; - - const auto &other = static_cast(_other); - return Tag == other.Tag - && Hasher == other.Hasher - && _Shape.IsEqual(other._Shape); -} -void TopoShape::cacheRelatedElements(const Data::MappedName &name, - HistoryTraceType sameType, - const QVector & names) const -{ - initCache(); - _cache->insertRelation(ShapeRelationKey(name,sameType), names); -} - -bool TopoShape::getRelatedElementsCached(const Data::MappedName &name, - HistoryTraceType sameType, - QVector &names) const -{ - if(!_cache) { + if (!_other.isDerivedFrom(TopoShape::getClassTypeId())) { return false; } - auto it = _cache->relations.find(ShapeRelationKey(name,sameType)); - if(it == _cache->relations.end()) { + + const auto& other = static_cast(_other); + return Tag == other.Tag && Hasher == other.Hasher && _Shape.IsEqual(other._Shape); +} +void TopoShape::cacheRelatedElements(const Data::MappedName& name, + HistoryTraceType sameType, + const QVector& names) const +{ + initCache(); + _cache->insertRelation(ShapeRelationKey(name, sameType), names); +} + +bool TopoShape::getRelatedElementsCached(const Data::MappedName& name, + HistoryTraceType sameType, + QVector& names) const +{ + if (!_cache) { + return false; + } + auto it = _cache->relations.find(ShapeRelationKey(name, sameType)); + if (it == _cache->relations.end()) { return false; } names = it->second; diff --git a/src/Mod/Part/Gui/DlgFilletEdges.cpp b/src/Mod/Part/Gui/DlgFilletEdges.cpp index 99a562c78a..706a76c208 100644 --- a/src/Mod/Part/Gui/DlgFilletEdges.cpp +++ b/src/Mod/Part/Gui/DlgFilletEdges.cpp @@ -70,6 +70,7 @@ #include "SoBrepFaceSet.h" #include "SoBrepPointSet.h" +FC_LOG_LEVEL_INIT("Part", true, true) using namespace PartGui; namespace sp = std::placeholders; @@ -649,7 +650,7 @@ void DlgFilletEdges::setupFillet(const std::vector& objs) for(auto &mapped : Part::Feature::getRelatedElements(base,ref.c_str())) { tmp.clear(); - if(!subSet.insert(mapped.index.toString(tmp)).second + if(!subSet.insert(mapped.index.appendToStringBuffer(tmp)).second || !subSet.insert(mapped.name.toString(0)).second) continue; FC_WARN("guess element reference: " << ref << " -> " << mapped.index); diff --git a/tests/src/Mod/Part/App/FeatureChamfer.cpp b/tests/src/Mod/Part/App/FeatureChamfer.cpp index 1f9f5027e6..0caf4c115e 100644 --- a/tests/src/Mod/Part/App/FeatureChamfer.cpp +++ b/tests/src/Mod/Part/App/FeatureChamfer.cpp @@ -71,7 +71,6 @@ TEST_F(FeatureChamferTest, testOther) // Assert EXPECT_EQ(sec, 24); // Act - // _chamfer->Edges.setValues(PartTestHelpers::_getFilletEdges({1, 2}, chamfer, chamfer)); _chamfer->Edges.setValues(PartTestHelpers::_getFilletEdges({1, 2}, chamfer, chamfer)); double fusedVolume = PartTestHelpers::getVolume(_fused->Shape.getValue()); double chamferVolume = PartTestHelpers::getVolume(_chamfer->Shape.getValue()); diff --git a/tests/src/Mod/Part/App/TopoShapeExpansion.cpp b/tests/src/Mod/Part/App/TopoShapeExpansion.cpp index c33902795f..3e4516624f 100644 --- a/tests/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/tests/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -1422,12 +1422,16 @@ TEST_F(TopoShapeExpansionTest, makeElementBooleanCut) // Assert elementMap is correct EXPECT_EQ(elements.size(), 38); EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); +#ifndef FC_USE_TNP_FIX EXPECT_EQ( elements[IndexedName("Face", 1)], MappedName( "Face3;:M;CUT;:H1:7,F;:U;CUT;:H1:7,E;:L(Face5;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E|Face5;:M;" "CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;CUT;:H1:7,V;:L(Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;" "CUT;:H1:7,V);CUT;:H1:3c,E|Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E);CUT;:H1:cb,F")); +#else + EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;CUT;:H1:4,F")); +#endif } TEST_F(TopoShapeExpansionTest, makeElementBooleanFuse) @@ -1448,12 +1452,16 @@ TEST_F(TopoShapeExpansionTest, makeElementBooleanFuse) // Assert element map is correct EXPECT_EQ(elements.size(), 66); EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); +#ifndef FC_USE_TNP_FIX EXPECT_EQ( elements[IndexedName("Face", 1)], MappedName( "Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;" "FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;" "FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F")); +#else + EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;FUS;:H1:4,F")); +#endif } TEST_F(TopoShapeExpansionTest, makeElementDraft) @@ -1707,12 +1715,16 @@ TEST_F(TopoShapeExpansionTest, makeElementGeneralFuse) // Assert elementMap is correct EXPECT_EQ(elements.size(), 72); EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); +#ifndef FC_USE_TNP_FIX EXPECT_EQ( elements[IndexedName("Face", 1)], MappedName( "Face3;:M;GFS;:H1:7,F;:U;GFS;:H1:7,E;:L(Face5;:M;GFS;:H1:7,F;:U2;GFS;:H1:8,E|Face5;:M;" "GFS;:H1:7,F;:U2;GFS;:H1:8,E;:U;GFS;:H1:7,V;:L(Face6;:M;GFS;:H1:7,F;:U2;GFS;:H1:8,E;:U;" "GFS;:H1:7,V);GFS;:H1:3c,E|Face6;:M;GFS;:H1:7,F;:U2;GFS;:H1:8,E);GFS;:H1:cb,F")); +#else + EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;GFS;:H1:4,F")); +#endif } TEST_F(TopoShapeExpansionTest, makeElementFuse) @@ -1732,12 +1744,16 @@ TEST_F(TopoShapeExpansionTest, makeElementFuse) // Assert elementMap is correct EXPECT_EQ(elements.size(), 66); EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); +#ifndef FC_USE_TNP_FIX EXPECT_EQ( elements[IndexedName("Face", 1)], MappedName( "Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;" "FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;" "FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F")); +#else + EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;FUS;:H1:4,F")); +#endif } TEST_F(TopoShapeExpansionTest, makeElementCut) @@ -1758,12 +1774,16 @@ TEST_F(TopoShapeExpansionTest, makeElementCut) // Assert elementMap is correct EXPECT_EQ(elements.size(), 38); EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); +#ifndef FC_USE_TNP_FIX EXPECT_EQ( elements[IndexedName("Face", 1)], MappedName( "Face3;:M;CUT;:H1:7,F;:U;CUT;:H1:7,E;:L(Face5;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E|Face5;:M;" "CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;CUT;:H1:7,V;:L(Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;" "CUT;:H1:7,V);CUT;:H1:3c,E|Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E);CUT;:H1:cb,F")); +#else + EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;CUT;:H1:4,F")); +#endif } TEST_F(TopoShapeExpansionTest, makeElementChamfer) @@ -2170,12 +2190,16 @@ TEST_F(TopoShapeExpansionTest, makeElementTransformWithMap) // Assert elementMap is correct EXPECT_EQ(elements.size(), 66); EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); +#ifndef FC_USE_TNP_FIX EXPECT_EQ( elements[IndexedName("Face", 1)], MappedName( "Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;" "FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;" "FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F")); +#else + EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;FUS;:H1:4,F")); +#endif } TEST_F(TopoShapeExpansionTest, makeElementGTransformWithoutMap) @@ -2216,12 +2240,16 @@ TEST_F(TopoShapeExpansionTest, makeElementGTransformWithMap) // Assert elementMap is correct EXPECT_EQ(elements.size(), 66); EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1); +#ifndef FC_USE_TNP_FIX EXPECT_EQ( elements[IndexedName("Face", 1)], MappedName( "Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;" "FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;" "FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F")); +#else + EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;FUS;:H1:4,F")); +#endif } // Not testing _makeElementTransform as it is a thin wrapper that calls the same places as the four @@ -2594,6 +2622,7 @@ TEST_F(TopoShapeExpansionTest, traceElement) // Act result.traceElement(mappedName, cb); // Assert we have the element map we think we do. +#ifndef FC_USE_TNP_FIX EXPECT_TRUE(allElementsMatch( result, { @@ -2641,6 +2670,49 @@ TEST_F(TopoShapeExpansionTest, traceElement) "Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;CUT;:H1:7,V", "Face6;:M;CUT;:H1:7,F;:U;CUT;:H1:7,E", })); +#else + EXPECT_TRUE(allElementsMatch(result, + { + "Edge10;:G(Edge2;K-1;:H2:4,E);CUT;:H1:1a,V", + "Edge10;:M;CUT;:H1:7,E", + "Edge11;:M;CUT;:H2:7,E", + "Edge11;CUT;:H1:4,E", + "Edge12;:M;CUT;:H2:7,E", + "Edge12;CUT;:H1:4,E", + "Edge1;CUT;:H1:4,E", + "Edge2;:M;CUT;:H2:7,E", + "Edge2;CUT;:H1:4,E", + "Edge3;CUT;:H1:4,E", + "Edge3;CUT;:H2:4,E", + "Edge4;:M;CUT;:H2:7,E", + "Edge4;CUT;:H1:4,E", + "Edge6;:G(Edge12;K-1;:H2:4,E);CUT;:H1:1b,V", + "Edge6;:M;CUT;:H1:7,E", + "Edge7;CUT;:H1:4,E", + "Edge8;:G(Edge11;K-1;:H2:4,E);CUT;:H1:1b,V", + "Edge8;:M;CUT;:H1:7,E", + "Edge9;:G(Edge4;K-1;:H2:4,E);CUT;:H1:1a,V", + "Edge9;:M;CUT;:H1:7,E", + "Face1;:M;CUT;:H2:7,F", + "Face1;CUT;:H1:4,F", + "Face2;:G(Face4;K-1;:H2:4,F);CUT;:H1:1a,E", + "Face2;:M;CUT;:H1:7,F", + "Face3;:G(Face1;K-1;:H2:4,F);CUT;:H1:1a,E", + "Face3;:M;CUT;:H1:7,F", + "Face4;:M;CUT;:H2:7,F", + "Face4;CUT;:H1:4,F", + "Face5;:M;CUT;:H1:7,F", + "Face6;:M;CUT;:H1:7,F", + "Vertex1;CUT;:H1:4,V", + "Vertex2;CUT;:H1:4,V", + "Vertex3;CUT;:H1:4,V", + "Vertex3;CUT;:H2:4,V", + "Vertex4;CUT;:H1:4,V", + "Vertex4;CUT;:H2:4,V", + "Vertex7;CUT;:H1:4,V", + "Vertex8;CUT;:H1:4,V", + })); +#endif } TEST_F(TopoShapeExpansionTest, makeElementOffset)