From 7d0afaec5461e074d011ccde06bafe60e53a2f1b Mon Sep 17 00:00:00 2001 From: bgbsww Date: Tue, 27 Feb 2024 10:11:35 -0500 Subject: [PATCH] Toposhape/Part: cleanup and test getElementName --- src/App/GeoFeature.cpp | 4 +- src/App/IndexedName.h | 12 ----- src/App/MappedName.h | 22 --------- src/Mod/Part/App/PartFeature.cpp | 2 +- src/Mod/Part/App/PartFeature.h | 30 ------------ src/Mod/Part/App/TopoShapeExpansion.cpp | 54 ++++++++++++--------- tests/src/Mod/Part/App/CMakeLists.txt | 1 + tests/src/Mod/Part/App/PartFeature.cpp | 62 +++++++++++++++++++++++++ 8 files changed, 98 insertions(+), 89 deletions(-) create mode 100644 tests/src/Mod/Part/App/PartFeature.cpp diff --git a/src/App/GeoFeature.cpp b/src/App/GeoFeature.cpp index c6a5b8762c..92421cb912 100644 --- a/src/App/GeoFeature.cpp +++ b/src/App/GeoFeature.cpp @@ -105,7 +105,7 @@ GeoFeature::_getElementName(const char *name, const Data::MappedElement &mapped) ss << Data::ComplexGeoData::elementMapPrefix() << mapped.name << '.' << mapped.index; ret.first = ss.str(); - mapped.index.toString(ret.second); + mapped.index.appendToStringBuffer(ret.second); } else if (mapped.name) { // FC_TRACE("element mapped name " << name << " not found in " << getFullName()); ret.first = name; @@ -117,7 +117,7 @@ GeoFeature::_getElementName(const char *name, const Data::MappedElement &mapped) ret.second += dot+1; } } else { - mapped.index.toString(ret.second); + mapped.index.appendToStringBuffer(ret.second); } return ret; } diff --git a/src/App/IndexedName.h b/src/App/IndexedName.h index 4d5d470e9b..85282b9545 100644 --- a/src/App/IndexedName.h +++ b/src/App/IndexedName.h @@ -147,18 +147,6 @@ public: return result; } - const char * toString(std::string & s) const - { - // Note! s is not cleared on purpose. - std::size_t offset = s.size(); - s += this->type; - if (this->index > 0) - s += std::to_string(this->index); - return s.c_str() + offset; - } - - - /// An indexedName is represented as the simple concatenation of the name and its index, e.g. /// "EDGE1" or "FACE42". friend std::ostream & operator<<(std::ostream & stream, const IndexedName & indexedName) diff --git a/src/App/MappedName.h b/src/App/MappedName.h index 0d8c30d6d6..355533e1bd 100644 --- a/src/App/MappedName.h +++ b/src/App/MappedName.h @@ -474,28 +474,6 @@ public: return appendToBuffer(res, startPosition, len); } - const char * toString(std::string &s, int from=0, int len=-1) const - { - std::size_t offset = s.size(); - int count = this->size(); - if (from < 0) - from = 0; - else if (from >= count) - return s.c_str()+s.size(); - if (len < 0 || len > count - from) - len = count - from; - s.reserve(s.size() + len); - if (from < this->data.size()) { - count = this->data.size() - from; - if (len < count) - count = len; - s.append(this->data.constData()+from, count); - len -= count; - } - s.append(this->postfix.constData(), len); - return s.c_str() + offset; - } - /// Given a (possibly non-empty) std::string buffer, append this instance to it, starting at a /// specified position, and continuing for a specified number of bytes. /// diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp index 98893da657..2212f4695a 100644 --- a/src/Mod/Part/App/PartFeature.cpp +++ b/src/Mod/Part/App/PartFeature.cpp @@ -988,4 +988,4 @@ std::pair Feature::getElementName(const char* name, } return App::GeoFeature::getElementName(name, type); -} \ No newline at end of file +} diff --git a/src/Mod/Part/App/PartFeature.h b/src/Mod/Part/App/PartFeature.h index b93d80b6e0..5e377e6e55 100644 --- a/src/Mod/Part/App/PartFeature.h +++ b/src/Mod/Part/App/PartFeature.h @@ -67,36 +67,6 @@ public: std::pair getElementName( const char *name, ElementNameType type=Normal) const override; -// static std::list getElementHistory(App::DocumentObject *obj, -// const char *name, bool recursive=true, bool sameType=false); -// -// static QVector -// getRelatedElements(App::DocumentObject *obj, const char *name, bool sameType=true, bool withCache=true); -// -// /** Obtain the element name from a feature based of the element name of its source feature -// * -// * @param obj: current feature -// * @param subname: sub-object/element reference -// * @param src: source feature -// * @param srcSub: sub-object/element reference of the source -// * @param single: if true, then return upon first match is found, or else -// * return all matches. Multiple matches are possible for -// * compound of multiple instances of the same source shape. -// * -// * @return Return a vector of pair of new style and old style element names. -// */ -// static QVector -// getElementFromSource(App::DocumentObject *obj, -// const char *subname, -// App::DocumentObject *src, -// const char *srcSub, -// bool single = false); -// -// TopLoc_Location getLocation() const; -// -// virtual DocumentObject *getSubObject(const char *subname, PyObject **pyObj, -// Base::Matrix4D *mat, bool transform, int depth) const override; - TopLoc_Location getLocation() const; DocumentObject *getSubObject(const char *subname, PyObject **pyObj, diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 44ad847205..93ce4de8e6 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -4054,17 +4054,18 @@ Data::MappedName TopoShape::setElementComboName(const Data::IndexedName& element return elementMap()->setElementName(element, newName, Tag, &sids); } -std::vector -TopoShape::decodeElementComboName(const Data::IndexedName &element, - const Data::MappedName &name, - const char *marker, - std::string *postfix) const +std::vector TopoShape::decodeElementComboName(const Data::IndexedName& element, + const Data::MappedName& name, + const char* marker, + std::string* postfix) const { std::vector names; - if (!element) + if (!element) { return names; - if (!marker) + } + if (!marker) { marker = ""; + } int plen = (int)elementMapPrefix().size(); int markerLen = strlen(marker); int len; @@ -4079,7 +4080,8 @@ TopoShape::decodeElementComboName(const Data::IndexedName &element, if (len < 0) { // No bracket is also possible, if there is only one name in the combo pos = len = name.size(); - } else { + } + else { pos = name.find(")"); if (pos < 0) { // non closing bracket? @@ -4087,20 +4089,21 @@ TopoShape::decodeElementComboName(const Data::IndexedName &element, } ++pos; } - if (len <= (int)markerLen) + if (len <= (int)markerLen) { return {}; - len -= markerLen+plen; + } + len -= markerLen + plen; } - if (name.find(elementMapPrefix(), len) != len - || name.find(marker, len+plen) != len+plen) + if (name.find(elementMapPrefix(), len) != len || name.find(marker, len + plen) != len + plen) { return {}; + } names.emplace_back(name, 0, len); std::string text; len += plen + markerLen; - name.toString(text, len, pos-len); + name.appendToBuffer(text, len, pos - len); if (this->Hasher) { if (auto id = App::StringID::fromString(names.back().toRawBytes())) { @@ -4108,30 +4111,37 @@ TopoShape::decodeElementComboName(const Data::IndexedName &element, names.pop_back(); names.emplace_back(sid); } - else + else { return names; + } } if (auto id = App::StringID::fromString(text.c_str())) { - if (App::StringIDRef sid = this->Hasher->getID(id)) + if (App::StringIDRef sid = this->Hasher->getID(id)) { text = sid.dataToText(); - else + } + else { return names; + } } } - if (text.empty() || text[0] != '(') + if (text.empty() || text[0] != '(') { return names; + } auto endPos = text.rfind(')'); - if (endPos == std::string::npos) + if (endPos == std::string::npos) { return names; + } - if (postfix) - *postfix = text.substr(endPos+1); + if (postfix) { + *postfix = text.substr(endPos + 1); + } text.resize(endPos); - std::istringstream iss(text.c_str()+1); + std::istringstream iss(text.c_str() + 1); std::string token; - while(std::getline(iss, token, '|')) + while (std::getline(iss, token, '|')) { names.emplace_back(token); + } return names; } diff --git a/tests/src/Mod/Part/App/CMakeLists.txt b/tests/src/Mod/Part/App/CMakeLists.txt index ee397c0f81..ceea6c5787 100644 --- a/tests/src/Mod/Part/App/CMakeLists.txt +++ b/tests/src/Mod/Part/App/CMakeLists.txt @@ -11,6 +11,7 @@ target_sources( ${CMAKE_CURRENT_SOURCE_DIR}/FeaturePartCut.cpp ${CMAKE_CURRENT_SOURCE_DIR}/FeaturePartFuse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/FeatureRevolution.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/PartFeature.cpp ${CMAKE_CURRENT_SOURCE_DIR}/PartFeatures.cpp ${CMAKE_CURRENT_SOURCE_DIR}/PartTestHelpers.cpp ${CMAKE_CURRENT_SOURCE_DIR}/TopoShape.cpp diff --git a/tests/src/Mod/Part/App/PartFeature.cpp b/tests/src/Mod/Part/App/PartFeature.cpp new file mode 100644 index 0000000000..f42d306245 --- /dev/null +++ b/tests/src/Mod/Part/App/PartFeature.cpp @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "gtest/gtest.h" + +#include "Mod/Part/App/FeaturePartCommon.h" +#include +#include +#include "PartTestHelpers.h" + +using namespace Part; +using namespace PartTestHelpers; + +class FeaturePartTest: public ::testing::Test, public PartTestHelperClass +{ +protected: + static void SetUpTestSuite() + { + tests::initApplication(); + } + + + void SetUp() override + { + createTestDoc(); + _common = dynamic_cast(_doc->addObject("Part::Common")); + } + + void TearDown() override + {} + + Common* _common = nullptr; // NOLINT Can't be private in a test framework +}; + +TEST_F(FeaturePartTest, testGetElementName) +{ + // Arrange + _boxes[0]->Shape.getShape().Tag = 1L; + _boxes[1]->Shape.getShape().Tag = 2L; + _common->Base.setValue(_boxes[0]); + _common->Tool.setValue(_boxes[1]); + + // Act + _common->execute(); + const TopoShape& ts = _common->Shape.getShape(); + + auto namePair = _common->getElementName("test"); + auto namePairExport = _common->getElementName("test", App::GeoFeature::Export); + auto namePairSelf = _common->getElementName(nullptr); + // Assert + EXPECT_STREQ(namePair.first.c_str(), ""); + EXPECT_STREQ(namePair.second.c_str(), "test"); + EXPECT_STREQ(namePairExport.first.c_str(), ""); + EXPECT_STREQ(namePairExport.second.c_str(), "test"); + EXPECT_STREQ(namePairSelf.first.c_str(), ""); + EXPECT_STREQ(namePairSelf.second.c_str(), ""); +#ifndef FC_USE_TNP_FIX + EXPECT_EQ(ts.getElementMap().size(), 0); +#else + EXPECT_EQ(ts.getElementMap().size(), 26); // Value and code TBD +#endif + // TBD +}