From 6e23ad2aa4923a49f5f04feed5cae513a1e403db Mon Sep 17 00:00:00 2001 From: mpv Date: Tue, 14 Nov 2017 15:21:35 +0300 Subject: [PATCH] Make the same named results distinguished in the python dump and execution of these scripts. --- src/Model/Model_Document.cpp | 103 ++++++++++++++++++++++++++-- src/Model/Model_Document.h | 7 +- src/Model/Model_SelectionNaming.cpp | 50 ++++++++++---- 3 files changed, 140 insertions(+), 20 deletions(-) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 26329090f..2272a8f33 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -1273,6 +1273,19 @@ Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLab2) void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName) { + std::map >::iterator aFind = myNamingNames.find(theName); + if (aFind != myNamingNames.end()) { // to avoid duplicate-labels + std::list::iterator aLabIter = aFind->second.begin(); + while(aLabIter != aFind->second.end()) { + if (theLabel.IsEqual(*aLabIter)) { + std::list::iterator aTmpIter = aLabIter; + aLabIter++; + aFind->second.erase(aTmpIter); + } else { + aLabIter++; + } + } + } myNamingNames[theName].push_back(theLabel); } @@ -1297,11 +1310,19 @@ void Model_Document::changeNamingName(const std::string theOldName, } } -TDF_Label Model_Document::findNamingName(std::string theName) +TDF_Label Model_Document::findNamingName(std::string theName, ResultPtr theContext) { std::map >::iterator aFind = myNamingNames.find(theName); if (aFind != myNamingNames.end()) { - return *(aFind->second.rbegin()); + std::list::reverse_iterator aLabIter = aFind->second.rbegin(); + for(; aLabIter != aFind->second.rend(); aLabIter++) { + if (theContext.get()) { + // context is defined and not like this, so, skip + if (theContext == myObjs->object(aLabIter->Father())) + return *aLabIter; + } + } + return *(aFind->second.rbegin()); // no more variannts, so, return the last } // not found exact name, try to find by sub-components std::string::size_type aSlash = theName.rfind('/'); @@ -1313,6 +1334,11 @@ TDF_Label Model_Document::findNamingName(std::string theName) // iterate all possible same-named labels starting from the last one (the recent) std::list::reverse_iterator aLabIter = aFind->second.rbegin(); for(; aLabIter != aFind->second.rend(); aLabIter++) { + if (theContext.get()) { + // context is defined and not like this, so, skip + if (theContext != myObjs->object(aLabIter->Father())) + continue; + } // searching sub-labels with this name TDF_ChildIDIterator aNamesIter(*aLabIter, TDataStd_Name::GetID(), Standard_True); for(; aNamesIter.More(); aNamesIter.Next()) { @@ -1340,9 +1366,78 @@ TDF_Label Model_Document::findNamingName(std::string theName) return TDF_Label(); // not found } -ResultPtr Model_Document::findByName(const std::string theName) +int Model_Document::numberOfNameInHistory( + const ObjectPtr& theNameObject, const TDF_Label& theStartFrom) { - return myObjs->findByName(theName); + std::map >::iterator aFind = + myNamingNames.find(theNameObject->data()->name()); + if (aFind == myNamingNames.end() || aFind->second.size() < 2) { + return 1; // no need to specify the name by additional identifiers + } + // get the feature of the object for relative compare + FeaturePtr aStart = myObjs->feature(theStartFrom); + if (!aStart.get()) // strange, but can not find feature by the label + return 1; + // feature that contain result with this name + FeaturePtr aNameFeature; + ResultPtr aNameResult = std::dynamic_pointer_cast(theNameObject); + if (aNameResult) + aNameFeature = myObjs->feature(aNameResult); + else + aNameFeature = std::dynamic_pointer_cast(theNameObject); + // iterate all labels with this name to find the nearest just before or equal relative + std::list::reverse_iterator aLabIter = aFind->second.rbegin(); + for(; aLabIter != aFind->second.rend(); aLabIter++) { + TDF_Label aCurrentLab = *aLabIter; + while(aCurrentLab.Depth() > 3) + aCurrentLab = aCurrentLab.Father(); + FeaturePtr aLabFeat = myObjs->feature(aCurrentLab); + if (!aLabFeat.get()) + continue; + if (aLabFeat == aStart || myObjs->isLater(aStart, aLabFeat)) + break; + } + int aResIndex = 1; + for(; aLabIter != aFind->second.rend(); aLabIter++) { + TDF_Label aCurrentLab = *aLabIter; + while(aCurrentLab.Depth() > 3) + aCurrentLab = aCurrentLab.Father(); + FeaturePtr aLabFeat = myObjs->feature(aCurrentLab); + if (!aLabFeat.get()) + continue; + if (aLabFeat == aNameFeature || myObjs->isLater(aNameFeature, aLabFeat)) + return aResIndex; + aResIndex++; + } + return aResIndex; // strange +} + +ResultPtr Model_Document::findByName(std::string& theName, std::string& theSubShapeName) +{ + int aNumInHistory = 0; + std::string aName = theName; + ResultPtr aRes = myObjs->findByName(aName); + while(!aRes.get() && aName[0] == '_') { // this may be thecontext with the history index + aNumInHistory++; + aName = aName.substr(1); + aRes = myObjs->findByName(aName); + } + if (aNumInHistory) { + std::map >::iterator aFind = myNamingNames.find(aName); + if (aFind != myNamingNames.end() && aFind->second.size() > aNumInHistory) { + std::list::reverse_iterator aLibIt = aFind->second.rbegin(); + for(; aNumInHistory != 0; aNumInHistory--) + aLibIt++; + const TDF_Label& aResultLab = *aLibIt; + aRes = std::dynamic_pointer_cast(myObjs->object(aResultLab.Father())); + if (aRes) { // modify the incoming names + if (!theSubShapeName.empty()) + theSubShapeName = theSubShapeName.substr(theName.size() - aName.size()); + theName = aName; + } + } + } + return aRes; } std::list > Model_Document::allFeatures() diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 6114e759b..93f50e359 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -209,10 +209,13 @@ class Model_Document : public ModelAPI_Document void changeNamingName(std::string theOldName, const std::string theNewName, const TDF_Label& theLabel); //! Returns the label, keeper of the name for the topological naming needs - TDF_Label findNamingName(std::string theName); + TDF_Label findNamingName(std::string theName, ResultPtr theContext); + //! Returns the number of the name in the history relatively to the given object (by label). + //! Start from 1 (this object). + int numberOfNameInHistory(const ObjectPtr& theNameObject, const TDF_Label& theStartFrom); //! Returns the result by name of the result (names of results must be unique, used for naming //! selection by name. - ResultPtr findByName(const std::string theName); + ResultPtr findByName(std::string& theName, std::string& theSubShapeName); ///! Returns all features of the document including the hidden features which are not in ///! history. Not very fast method, for calling once, not in big cycles. diff --git a/src/Model/Model_SelectionNaming.cpp b/src/Model/Model_SelectionNaming.cpp index 11473dcaa..ad202ae1b 100644 --- a/src/Model/Model_SelectionNaming.cpp +++ b/src/Model/Model_SelectionNaming.cpp @@ -112,7 +112,21 @@ std::string Model_SelectionNaming::getShapeName( aNewContext = theDoc->objects()->object(aNSDataLab); } if (aNewContext.get()) { - aName = aNewContext->data()->name() + "/" + aName; + // this is to avoid duplicated names of results problem + std::string aContextName = aNewContext->data()->name(); + // myLab corresponds to the current time + TDF_Label aCurrentLab = myLab; + while(aCurrentLab.Depth() > 3) + aCurrentLab = aCurrentLab.Father(); + + int aNumInHistoryNames = + theDoc->numberOfNameInHistory(aNewContext, aCurrentLab); + while(aNumInHistoryNames > 1) { // add "_" before name the needed number of times + aContextName = "_" + aContextName; + aNumInHistoryNames--; + } + + aName = aContextName + "/" + aName; } } } @@ -469,17 +483,18 @@ const TopoDS_Shape getShapeFromNS( } const TopoDS_Shape findFaceByName( - const std::string& theSubShapeName, std::shared_ptr theDoc) + const std::string& theSubShapeName, std::shared_ptr theDoc, + const ResultPtr theDetectedContext) { TopoDS_Shape aFace; std::string aSubString = theSubShapeName; - TDF_Label aLabel = theDoc->findNamingName(aSubString); + TDF_Label aLabel = theDoc->findNamingName(aSubString, theDetectedContext); if (aLabel.IsNull()) { // try to remove additional artificial suffix std::string::size_type n = aSubString.rfind('_'); if (n != std::string::npos) { aSubString = aSubString.substr(0, n); - aLabel = theDoc->findNamingName(aSubString); + aLabel = theDoc->findNamingName(aSubString, theDetectedContext); } } if(aLabel.IsNull()) return aFace; @@ -718,7 +733,7 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType, std::string aContName = getContextName(aSubShapeName); if(aContName.empty()) return false; - ResultPtr aCont = aDoc->findByName(aContName); + ResultPtr aCont = aDoc->findByName(aContName, aSubShapeName); // possible this is body where postfix is added to distinguish several shapes on the same label int aSubShapeId = -1; // -1 means sub shape not found // for result body the name wihtout "_" has higher priority than with it: it is always added @@ -726,8 +741,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType, aContName == aSubShapeName) { size_t aPostIndex = aContName.rfind('_'); if (aPostIndex != std::string::npos) { - std::string aSubContName = aContName.substr(0, aPostIndex); - ResultPtr aSubCont = aDoc->findByName(aSubContName); + std::string anEmpty, aSubContName = aContName.substr(0, aPostIndex); + ResultPtr aSubCont = aDoc->findByName(aSubContName, anEmpty); if (aSubCont.get()) { try { std::string aNum = aContName.substr(aPostIndex + 1); @@ -750,12 +765,12 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType, case TopAbs_FACE: case TopAbs_WIRE: { - aSelection = findFaceByName(aSubShapeName, aDoc); + aSelection = findFaceByName(aSubShapeName, aDoc, aCont); } break; case TopAbs_EDGE: { - const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName); + const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName, aCont); if(!aLabel.IsNull()) { Handle(TNaming_NamedShape) aNS; if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { @@ -766,7 +781,7 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType, break; case TopAbs_VERTEX: { - const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName); + const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName, aCont); if(!aLabel.IsNull()) { Handle(TNaming_NamedShape) aNS; if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { @@ -814,8 +829,15 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType, if(aN >= 1) { TopTools_ListOfShape aList; std::list::iterator it = aListofNames.begin(); - for(; it != aListofNames.end(); it++){ - const TopoDS_Shape aFace = findFaceByName(*it, aDoc); + for(; it != aListofNames.end(); it++) { + ResultPtr aFaceContext = aCont; + if (it != aListofNames.begin()) { // there may be other context for different sub-faces + std::string aContName = getContextName(*it); + if(!aContName.empty()) { + aFaceContext = aDoc->findByName(aContName, *it); + } + } + const TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext); if(!aFace.IsNull()) aList.Append(aFace); } @@ -827,8 +849,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType, if (aN < 2) { size_t aConstrNamePos = aSubShapeName.find("/"); bool isFullName = aConstrNamePos == std::string::npos; - std::string aContrName = aContName; - ResultPtr aConstr = aDoc->findByName(aContrName); + std::string anEmpty, aContrName = aContName; + ResultPtr aConstr = aDoc->findByName(aContrName, anEmpty); if (aConstr.get() && aConstr->groupName() == ModelAPI_ResultConstruction::group()) { theCont = aConstr; if (isFullName) { -- 2.39.2