From 2e60d80d7d0b998fded953311cc8d2931ef5bb4b Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 17 Oct 2018 19:11:41 +0300 Subject: [PATCH] Initial implementation of restoreByName selector method --- src/Model/Model_AttributeSelection.cpp | 315 ++++++++++++++----------- src/Model/Model_AttributeSelection.h | 7 + src/Model/Model_BodyBuilder.cpp | 3 - src/Model/Model_Data.cpp | 12 +- src/Model/Model_Data.h | 2 +- src/Model/Model_Document.cpp | 2 +- src/Model/Model_Objects.cpp | 1 - src/Model/Model_SelectionNaming.cpp | 10 +- src/Selector/Selector_NameGenerator.h | 9 +- src/Selector/Selector_Selector.cpp | 15 ++ src/Selector/Selector_Selector.h | 5 + 11 files changed, 229 insertions(+), 152 deletions(-) diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index b4739045f..17120173b 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -955,172 +955,85 @@ void Model_AttributeSelection::selectSubShape( CenterType aCenterType = theType[0] == 'v' || theType[0] == 'V' ? // only for vertex-type centerTypeByName(aSubShapeName) : NOT_CENTER; std::string aType = aCenterType == NOT_CENTER ? theType : "EDGE"; // search for edge now + static const GeomShapePtr anEmptyShape; // first iteration is selection by name without center prefix, second - in case of problem, // try with initial name - for(int aUseCenter = 1; aUseCenter >= 0; aUseCenter--) { + for(int aUseCenter = 1; aUseCenter >= 0; aUseCenter--) { + std::string aSubShapeName = theSubShapeName; if (aUseCenter == 0 && aCenterType != NOT_CENTER) { - aSubShapeName = theSubShapeName; aCenterType = NOT_CENTER; aType = theType; } else if (aUseCenter != 1) continue; + std::shared_ptr aDoc = + std::dynamic_pointer_cast(owner()->document()); // check this is Part-name: 2 delimiters in the name std::size_t aPartEnd = aSubShapeName.find('/'); - if (aPartEnd != std::string::npos && aPartEnd != aSubShapeName.rfind('/')) { + if (aPartEnd != std::string::npos) { std::string aPartName = aSubShapeName.substr(0, aPartEnd); - ObjectPtr aFound = owner()->document()->objectByName(ModelAPI_ResultPart::group(), aPartName); - if (aFound.get()) { // found such part, so asking it for the name - ResultPartPtr aPart = std::dynamic_pointer_cast(aFound); - std::string aNameInPart = aSubShapeName.substr(aPartEnd + 1); - int anIndex; - std::shared_ptr aSelected = aPart->shapeInPart(aNameInPart, aType, anIndex); - if (aSelected.get()) { - if (aCenterType != NOT_CENTER) { - if (!aSelected->isEdge()) - continue; - std::shared_ptr aSelectedEdge(new GeomAPI_Edge(aSelected)); - setValueCenter(aPart, aSelectedEdge, aCenterType); - } else - setValue(aPart, aSelected); - TDataStd_Integer::Set(selectionLabel(), anIndex); - return; + DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); + if (aPartName == aRootDoc->kind()) { + aDoc = std::dynamic_pointer_cast(aRootDoc); + aSubShapeName = aSubShapeName.substr(aPartEnd + 1); + } else { + ObjectPtr aFound = owner()->document()->objectByName(ModelAPI_ResultPart::group(), aPartName); + if (aFound.get()) { // found such part, so asking it for the name + ResultPartPtr aPart = std::dynamic_pointer_cast(aFound); + aDoc = std::dynamic_pointer_cast(aPart->partDoc()); + aSubShapeName = aSubShapeName.substr(aPartEnd +1); } } } - std::shared_ptr aDoc = - std::dynamic_pointer_cast(owner()->document()); // check this is a whole feature context if (aSubShapeName.size() > kWHOLE_FEATURE.size() && aSubShapeName.substr(0, kWHOLE_FEATURE.size()) == kWHOLE_FEATURE) { std::string aFeatureName = aSubShapeName.substr(kWHOLE_FEATURE.size()); ObjectPtr anObj = aDoc->objectByName(ModelAPI_Feature::group(), aFeatureName); if (anObj.get()) { - static const GeomShapePtr anEmptyShape; setValue(anObj, anEmptyShape); return; } } - Model_SelectionNaming aSelNaming(selectionLabel()); - std::shared_ptr aShapeToBeSelected; - ResultPtr aCont; - if (aSelNaming.selectSubShape(aType, aSubShapeName, aDoc, aShapeToBeSelected, aCont)) { - // try to find the last context to find the up to date shape - if (aCont->shape().get() && !aCont->shape()->isNull() && - aCont->groupName() == ModelAPI_ResultBody::group() && aDoc == owner()->document()) { - const TopoDS_Shape aConShape = aCont->shape()->impl(); - if (!aConShape.IsNull()) { - Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aConShape, selectionLabel()); - if (!aNS.IsNull()) { - aNS = TNaming_Tool::CurrentNamedShape(aNS); - if (!aNS.IsNull() && scope().Contains(aNS->Label())) { // scope check is for 2228 - TDF_Label aLab = aNS->Label(); - if (aLab.Depth() % 2 == 0) - aLab = aLab.Father(); - ObjectPtr anObj = aDoc->objects()->object(aLab); - while(!anObj.get() && aLab.Depth() > 5) { - aLab = aLab.Father().Father(); - anObj = aDoc->objects()->object(aLab); - } - - if (anObj.get()) { - ResultPtr aRes = std::dynamic_pointer_cast(anObj); - if (aRes) - aCont = aRes; - } - } - } - } - } - // if compsolid is context, try to take sub-solid as context: like in GUI and scripts - if (aCont.get() && aShapeToBeSelected.get()) { - ResultBodyPtr aComp = std::dynamic_pointer_cast(aCont); - if (aComp && aComp->numberOfSubs()) { - std::list allSubs; - ModelAPI_Tools::allSubs(aComp, allSubs); - std::list::iterator aS = allSubs.begin(); - for(; aS != allSubs.end(); aS++) { - ResultBodyPtr aSub = std::dynamic_pointer_cast(*aS); - if (aSub && aSub->numberOfSubs() == 0 && aSub->shape().get() && - aSub->shape()->isSubShape(aShapeToBeSelected)) { - aCont = aSub; - break; - } - } - } + // the whole result selection check + if (aSubShapeName.find('/') == std::string::npos) { + ObjectPtr aRes = aDoc->objectByName(ModelAPI_ResultConstruction::group(), aSubShapeName); + if (!aRes.get()) + aRes = aDoc->objectByName(ModelAPI_ResultBody::group(), aSubShapeName); + if (aRes.get()) { + setValue(aRes, anEmptyShape); + return; } - // try to find the latest active result that must be used instead of the selected - // to set the active context (like in GUI selection), not concealed one - bool aFindNewContext = true; - while(aFindNewContext && aCont.get()) { - aFindNewContext = false; - // take references to all results: root one, any sub - ResultBodyPtr aCompContext = ModelAPI_Tools::bodyOwner(aCont, true); - std::list allRes; - if (aCompContext.get()) { - ModelAPI_Tools::allSubs(aCompContext, allRes); - allRes.push_back(aCompContext); - } else { - allRes.push_back(aCont); - } - for(std::list::iterator aSub = allRes.begin(); aSub != allRes.end(); aSub++) { - ResultPtr aResCont = *aSub; - ResultBodyPtr aResBody = std::dynamic_pointer_cast(aResCont); - // only lower and higher level subs are counted - if (aResBody.get() && aResBody->numberOfSubs() > 0 && aResBody != aCompContext) - continue; - const std::set& aRefs = aResCont->data()->refsToMe(); - std::set::const_iterator aRef = aRefs.begin(); - for(; !aFindNewContext && aRef != aRefs.end(); aRef++) { - if (!aRef->get() || !(*aRef)->owner().get()) - continue; - // concealed attribute only - FeaturePtr aRefFeat = std::dynamic_pointer_cast((*aRef)->owner()); - if (!ModelAPI_Session::get()->validators()->isConcealed( - aRefFeat->getKind(), (*aRef)->id())) + } + + Selector_Selector aSelector(aDoc->generalLabel()); + myRestoreDocument = aDoc; + TDF_Label aContextLabel = aSelector.restoreByName(aSubShapeName, this); + myRestoreDocument.reset(); + if (!aContextLabel.IsNull()) { + ResultPtr aContext = aDoc->resultByLab(aContextLabel); // any label for document access + if (aContext.get() && aContext->shape().get()) { + TopoDS_Shape aContextShape = aContext->shape()->impl(); + if (aSelector.solve(aContextShape)) { + GeomShapePtr aShapeToBeSelected(new GeomAPI_Shape); + aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelector.value())); + if (aCenterType != NOT_CENTER) { + if (!aShapeToBeSelected->isEdge()) continue; - // search the feature result that contains sub-shape selected - std::list > aResults; - - // take all sub-results or one result - std::list aRefFeatResults; - ModelAPI_Tools::allResults(aRefFeat, aRefFeatResults); - std::list::iterator aRefResIter = aRefFeatResults.begin(); - for(; aRefResIter != aRefFeatResults.end(); aRefResIter++) { - ResultBodyPtr aBody = std::dynamic_pointer_cast(*aRefResIter); - if (aBody.get() && aBody->numberOfSubs() == 0) // add only lower level subs - aResults.push_back(aBody); - } - std::list >::iterator aResIter = aResults.begin(); - for(; aResIter != aResults.end(); aResIter++) { - if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled()) - continue; - GeomShapePtr aShape = (*aResIter)->shape(); - GeomShapePtr aSelectedShape = - aShapeToBeSelected.get() ? aShapeToBeSelected : aCont->shape(); - if (aShape.get() && aShape->isSubShape(aSelectedShape, false)) { - aCont = *aResIter; // found new context (produced from this) with same subshape - aFindNewContext = true; // continue searching futher - break; - } - } + std::shared_ptr aSelectedEdge(new GeomAPI_Edge(aShapeToBeSelected)); + setValueCenter(aContext, aSelectedEdge, aCenterType); } + else + setValue(aContext, aShapeToBeSelected); + return; } } - - if (aCenterType != NOT_CENTER) { - if (!aShapeToBeSelected->isEdge()) - continue; - std::shared_ptr aSelectedEdge(new GeomAPI_Edge(aShapeToBeSelected)); - setValueCenter(aCont, aSelectedEdge, aCenterType); - } else - setValue(aCont, aShapeToBeSelected); - return; } + aSubShapeName = theSubShapeName; } - + // invalid TDF_Label aSelLab = selectionLabel(); setInvalidIfFalse(aSelLab, false); reset(); @@ -1695,3 +1608,139 @@ std::string Model_AttributeSelection::contextName(const TDF_Label theSelectionLa } return ""; // invalid case } + +/// This method restores by the context and value name the context label and +/// sub-label where the value is. Returns true if it is valid. +bool Model_AttributeSelection::restoreContext(std::string theName, + TDF_Label& theContext, TDF_Label& theValue) +{ + static const GeomShapePtr anEmptyShape; // to store context only + std::string aName = theName; + std::shared_ptr aDoc = myRestoreDocument.get() ? myRestoreDocument : + std::dynamic_pointer_cast(owner()->document()); + + // remove the sub-value part if exists + std::string aSubShapeName = aName; + std::string::size_type n = aName.find('/'); + if (n != std::string::npos) { + aName = aName.substr(0, n); + } + + if (aName.empty()) return false; + bool anUniqueContext = false; + ResultPtr aCont = aDoc->findByName(aName, aSubShapeName, anUniqueContext); + if (!aCont.get() || !aCont->shape().get() || aCont->shape()->isNull()) + return false; + + // searching the sub-shape + static const ResultPtr anEmpty; + theValue = aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty); + + /* to find the latest lower result that keeps given shape + bool aFindNewContext = true; + while(aFindNewContext && aCont.get()) { + aFindNewContext = false; + // try to find the last context to find the up to date shape + TopoDS_Shape aConShape = aCont->shape()->impl(); + Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aConShape, selectionLabel()); + if (!aNS.IsNull()) { + aNS = TNaming_Tool::CurrentNamedShape(aNS); + if (!aNS.IsNull() && isOlderThanMe(aNS->Label())) { // scope check is for 2228 + TDF_Label aLab = aNS->Label(); + if (aLab.Depth() % 2 == 0) + aLab = aLab.Father(); + ObjectPtr anObj = aDoc->objects()->object(aLab); + while (!anObj.get() && aLab.Depth() > 5) { + aLab = aLab.Father().Father(); + anObj = aDoc->objects()->object(aLab); + } + + if (anObj.get()) { + ResultPtr aRes = std::dynamic_pointer_cast(anObj); + if (aRes) { + aCont = aRes; + aFindNewContext = true; + } + } + } + } else if (aCont->groupName() == ModelAPI_ResultBody::group()) { + // try to search newer context by the concealment references + // take references to all results: root one, any sub + std::list allRes; + ResultPtr aCompContext; + if (aCont->groupName() == ModelAPI_ResultBody::group()) { + ResultBodyPtr aCompBody = ModelAPI_Tools::bodyOwner(aCont, true); + if (aCompBody.get()) { + ModelAPI_Tools::allSubs(aCompBody, allRes); + allRes.push_back(aCompBody); + aCompContext = aCompBody; + } + } + if (allRes.empty()) + allRes.push_back(aCont); + + for(std::list::iterator aSub = allRes.begin(); aSub != allRes.end(); aSub++) { + ResultPtr aResCont = *aSub; + ResultBodyPtr aResBody = std::dynamic_pointer_cast(aResCont); + if (aResBody.get() && aResBody->numberOfSubs() > 0 && aResBody != aCompContext) + continue; // only lower and higher level subs are counted + const std::set& aRefs = aResCont->data()->refsToMe(); + std::set::const_iterator aRef = aRefs.begin(); + for(; !aFindNewContext && aRef != aRefs.end(); aRef++) { + if (!aRef->get() || !(*aRef)->owner().get()) + continue; + // concealed attribute only + FeaturePtr aRefFeat = std::dynamic_pointer_cast((*aRef)->owner()); + if (!ModelAPI_Session::get()->validators()->isConcealed( + aRefFeat->getKind(), (*aRef)->id())) + continue; + // search the feature result that contains sub-shape selected + std::list > aResults; + + // take all sub-results or one result + std::list aRefFeatResults; + ModelAPI_Tools::allResults(aRefFeat, aRefFeatResults); + std::list::iterator aRefResIter = aRefFeatResults.begin(); + for(; aRefResIter != aRefFeatResults.end(); aRefResIter++) { + ResultBodyPtr aBody = std::dynamic_pointer_cast(*aRefResIter); + if (aBody.get() && aBody->numberOfSubs() == 0) // add only lower level subs + aResults.push_back(aBody); + } + std::list >::iterator aResIter = aResults.begin(); + for(; aResIter != aResults.end(); aResIter++) { + if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled()) + continue; + GeomShapePtr aShape = (*aResIter)->shape(); + GeomShapePtr aSelectedShape = + aShapeToBeSelected.get() ? aShapeToBeSelected : aCont->shape(); + if (aShape.get() && aShape->isSubShape(aSelectedShape, false)) { + aCont = *aResIter; // found new context (produced from this) with same subshape + aFindNewContext = true; // continue searching futher + break; + } + } + } + } + } + } + // if compsolid is context, try to take sub-solid as context: like in GUI and scripts + ResultBodyPtr aComp = std::dynamic_pointer_cast(aCont); + if (aComp && aComp->numberOfSubs()) { + std::list allSubs; + ModelAPI_Tools::allSubs(aComp, allSubs); + std::list::iterator aS = allSubs.begin(); + for (; aS != allSubs.end(); aS++) { + ResultBodyPtr aSub = std::dynamic_pointer_cast(*aS); + if (aSub && aSub->numberOfSubs() == 0 && aSub->shape().get() && + aSub->shape()->isSubShape(aShapeToBeSelected)) { + aCont = aSub; + break; + } + } + } + */ + if (aCont.get()) { + theContext = std::dynamic_pointer_cast(aCont->data())->label(); + } + return true; +} diff --git a/src/Model/Model_AttributeSelection.h b/src/Model/Model_AttributeSelection.h index b0c3034d6..187115e51 100644 --- a/src/Model/Model_AttributeSelection.h +++ b/src/Model/Model_AttributeSelection.h @@ -49,6 +49,8 @@ class Model_AttributeSelection : public ModelAPI_AttributeSelection, CenterType myTmpCenterType; /// Reference to the partent attribute, if any (to split selection compounds in issue 1799) Model_AttributeSelectionList* myParent; + + std::shared_ptr myRestoreDocument; // current document to restore by name public: /// Defines the result and its selected sub-shape /// \param theContext object where the sub-shape was selected @@ -134,6 +136,11 @@ public: // This method returns the context name by the label of the sub-selected shape MODEL_EXPORT virtual std::string contextName(const TDF_Label theSelectionLab) override; + /// This method restores by the context and value name the context label and + /// sub-label where the value is. Returns true if it is valid. + MODEL_EXPORT virtual bool restoreContext(std::string theName, + TDF_Label& theContext, TDF_Label& theValue) override; + protected: /// Objects are created for features automatically MODEL_EXPORT Model_AttributeSelection(TDF_Label& theLabel); diff --git a/src/Model/Model_BodyBuilder.cpp b/src/Model/Model_BodyBuilder.cpp index 6d7fe12db..ae6f60d88 100755 --- a/src/Model/Model_BodyBuilder.cpp +++ b/src/Model/Model_BodyBuilder.cpp @@ -225,7 +225,6 @@ void Model_BodyBuilder::storeModified(const GeomShapePtr& theOldShape, { std::shared_ptr aData = std::dynamic_pointer_cast(data()); if (aData) { - TDF_Label& aShapeLab = aData->shapeLab(); // clean builders if (theIsCleanStored) clean(); // store the new shape as primitive @@ -295,7 +294,6 @@ Model_BodyBuilder::~Model_BodyBuilder() void Model_BodyBuilder::buildName(const int theTag, const std::string& theName) { - std::shared_ptr aDoc = std::dynamic_pointer_cast(document()); std::string aName = theName; std::string aPrefix = ""; switch (theTag) { @@ -318,7 +316,6 @@ void Model_BodyBuilder::generated(const GeomShapePtr& theNewShape, if (!theName.empty()) { buildName(myFreePrimitiveTag, theName); } - ++myFreePrimitiveTag; } diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index d7d14ad8c..d75a917de 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -111,7 +111,7 @@ void Model_Data::setLabel(TDF_Label theLab) std::string Model_Data::name() { Handle(TDataStd_Name) aName; - if (myLab.FindAttribute(TDataStd_Name::GetID(), aName)) { + if (shapeLab().FindAttribute(TDataStd_Name::GetID(), aName)) { #ifdef DEBUG_NAMES myObject->myName = TCollection_AsciiString(aName->Get()).ToCString(); #endif @@ -125,8 +125,8 @@ void Model_Data::setName(const std::string& theName) bool isModified = false; std::string anOldName = name(); Handle(TDataStd_Name) aName; - if (!myLab.FindAttribute(TDataStd_Name::GetID(), aName)) { - TDataStd_Name::Set(myLab, theName.c_str()); + if (!shapeLab().FindAttribute(TDataStd_Name::GetID(), aName)) { + TDataStd_Name::Set(shapeLab(), theName.c_str()); isModified = true; } else { isModified = !aName->Get().IsEqual(theName.c_str()); @@ -143,7 +143,7 @@ void Model_Data::setName(const std::string& theName) } if (isUserDefined) { // name is user-defined, thus special attribute is set - TDataStd_UAttribute::Set(myLab, kUSER_DEFINED_NAME); + TDataStd_UAttribute::Set(shapeLab(), kUSER_DEFINED_NAME); } } } @@ -151,7 +151,7 @@ void Model_Data::setName(const std::string& theName) ModelAPI_ObjectRenamedMessage::send(myObject, anOldName, theName, this); if (isModified && myObject && myObject->document()) { std::dynamic_pointer_cast(myObject->document())-> - changeNamingName(anOldName, theName, myLab); + changeNamingName(anOldName, theName, shapeLab()); } #ifdef DEBUG_NAMES myObject->myName = theName; @@ -160,7 +160,7 @@ void Model_Data::setName(const std::string& theName) bool Model_Data::hasUserDefinedName() const { - return myLab.IsAttribute(kUSER_DEFINED_NAME); + return shapeLab().IsAttribute(kUSER_DEFINED_NAME); } AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType) diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index e2a6a7994..2ed26625f 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -172,7 +172,7 @@ class Model_Data : public ModelAPI_Data MODEL_EXPORT virtual bool isValid(); /// Returns the label where the shape must be stored (used in ResultBody) - TDF_Label shapeLab() + TDF_Label shapeLab() const { return myLab.IsNull() ? myLab : myLab.Father().FindChild(2); } diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 86c89c420..548e3174b 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -1549,7 +1549,7 @@ ResultPtr Model_Document::findByName( std::string aName = theName; ResultPtr aRes = myObjs->findByName(aName); theUniqueContext = !(aRes.get() && myNamingNames.find(aName) != myNamingNames.end()); - while(!aRes.get() && aName[0] == '_') { // this may be thecontext with the history index + while(!aRes.get() && aName[0] == '_') { // this may be theContext with the history index aNumInHistory++; aName = aName.substr(1); aRes = myObjs->findByName(aName); diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index dc1067ec6..8b6d87d57 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/src/Model/Model_SelectionNaming.cpp b/src/Model/Model_SelectionNaming.cpp index 1075ef610..d16fdf724 100644 --- a/src/Model/Model_SelectionNaming.cpp +++ b/src/Model/Model_SelectionNaming.cpp @@ -584,11 +584,11 @@ size_t ParseName(const std::string& theSubShapeName, std::list& t std::string getContextName(const std::string& theSubShapeName) { - std::string aName; - std::string::size_type n = theSubShapeName.find('/'); - if (n == std::string::npos) return theSubShapeName; - aName = theSubShapeName.substr(0, n); - return aName; + std::string aName; + std::string::size_type n = theSubShapeName.find('/'); + if (n == std::string::npos) return theSubShapeName; + aName = theSubShapeName.substr(0, n); + return aName; } /// Parses naming name of sketch sub-elements: takes indices and orientation diff --git a/src/Selector/Selector_NameGenerator.h b/src/Selector/Selector_NameGenerator.h index 80fb8650c..079316afa 100644 --- a/src/Selector/Selector_NameGenerator.h +++ b/src/Selector/Selector_NameGenerator.h @@ -34,11 +34,16 @@ class Selector_NameGenerator { public: - // empty constructor, nothing to add + /// empty constructor, nothing to add Selector_NameGenerator() {}; - // This method returns the context name by the label of the sub-selected shape + /// This method returns the context name by the label of the sub-selected shape virtual std::string contextName(const TDF_Label theSelectionLab) = 0; + + /// This method restores by the context and value name the context label and + /// sub-label where the value is. Returns true if it is valid. + virtual bool restoreContext(std::string theName, + TDF_Label& theContext, TDF_Label& theValue) = 0; }; #endif diff --git a/src/Selector/Selector_Selector.cpp b/src/Selector/Selector_Selector.cpp index 2d8089485..22238b816 100644 --- a/src/Selector/Selector_Selector.cpp +++ b/src/Selector/Selector_Selector.cpp @@ -793,6 +793,21 @@ std::string Selector_Selector::name(Selector_NameGenerator* theNameGenerator) { return ""; } +TDF_Label Selector_Selector::restoreByName(std::string theName, + Selector_NameGenerator* theNameGenerator) +{ + if (theName.find('&') == std::string::npos) { // wihtout '&' it can be only primitive + myType = SELTYPE_PRIMITIVE; + TDF_Label aContext; + if (theNameGenerator->restoreContext(theName, aContext, myFinal)) { + if (!myFinal.IsNull()) + return aContext; + } + } else { + } + return TDF_Label(); +} + bool Selector_Selector::selectBySubSelector( const TopoDS_Shape theContext, const TopoDS_Shape theValue, const bool theUseNeighbors) { diff --git a/src/Selector/Selector_Selector.h b/src/Selector/Selector_Selector.h index 2fe4dcdda..5836c2874 100644 --- a/src/Selector/Selector_Selector.h +++ b/src/Selector/Selector_Selector.h @@ -76,6 +76,11 @@ class Selector_Selector /// Returns true if it can restore structure correctly SELECTOR_EXPORT bool restore(); + /// Restores the selected shape by the topological name string. + /// Returns not empty label of the context. + SELECTOR_EXPORT TDF_Label restoreByName(std::string theName, + Selector_NameGenerator* theNameGenerator); + /// Updates the current shape by the stored topological name SELECTOR_EXPORT bool solve(const TopoDS_Shape& theContext); -- 2.30.2