+ std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
+
+ if (aFind != myNamingNames.end()) { // to avoid duplicate-labels
+ // to keep correct order inspite of history line management
+ std::list<TDF_Label>::iterator anAddAfterThis = aFind->second.end();
+ FeaturePtr anAddedFeature = featureByLab(theLabel);
+ std::list<TDF_Label>::iterator aLabIter = aFind->second.begin();
+ while(aLabIter != aFind->second.end()) {
+ if (theLabel.IsEqual(*aLabIter)) {
+ std::list<TDF_Label>::iterator aTmpIter = aLabIter;
+ aLabIter++;
+ aFind->second.erase(aTmpIter);
+ } else {
+ FeaturePtr aCurFeature = featureByLab(*aLabIter);
+ if (aCurFeature.get() && anAddedFeature.get() &&
+ myObjs->isLater(anAddedFeature, aCurFeature))
+ anAddAfterThis = aLabIter;
+
+ aLabIter++;
+ }
+ }
+ if (anAddAfterThis != aFind->second.end()) {
+ anAddAfterThis++;
+ if (anAddAfterThis != aFind->second.end()) {
+ myNamingNames[theName].insert(anAddAfterThis, theLabel); // inserts before anAddAfterThis
+ return;
+ }
+ }
+ }
+ myNamingNames[theName].push_back(theLabel);
+}
+
+void Model_Document::changeNamingName(const std::string theOldName,
+ const std::string theNewName,
+ const TDF_Label& theLabel)
+{
+ std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theOldName);
+ if (aFind != myNamingNames.end()) {
+ std::list<TDF_Label>::iterator aLabIter = aFind->second.begin();
+ for(; aLabIter != aFind->second.end(); aLabIter++) {
+ if (theLabel.IsEqual(*aLabIter)) { // found the label
+ myNamingNames[theNewName].push_back(theLabel);
+ if (aFind->second.size() == 1) { // only one element, so, just change the name
+ myNamingNames.erase(theOldName);
+ } else { // remove from the list
+ aFind->second.erase(aLabIter);
+ }
+ return;
+ }
+ }
+ }
+}
+
+TDF_Label Model_Document::findNamingName(std::string theName, ResultPtr theContext)
+{
+ std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
+ if (aFind != myNamingNames.end()) {
+ std::list<TDF_Label>::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('/');
+ if (aSlash != std::string::npos) {
+ std::string anObjName = theName.substr(0, aSlash);
+ aFind = myNamingNames.find(anObjName);
+ if (aFind != myNamingNames.end()) {
+ TCollection_ExtendedString aSubName(theName.substr(aSlash + 1).c_str());
+ // iterate all possible same-named labels starting from the last one (the recent)
+ std::list<TDF_Label>::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;
+ }
+ // copy aSubName to avoid incorrect further processing after its suffix cutting
+ TCollection_ExtendedString aSubNameCopy(aSubName);
+ // searching sub-labels with this name
+ TDF_ChildIDIterator aNamesIter(*aLabIter, TDataStd_Name::GetID(), Standard_True);
+ for(; aNamesIter.More(); aNamesIter.Next()) {
+ Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value());
+ if (aName->Get() == aSubNameCopy)
+ return aName->Label();
+ }
+ // If not found child label with the exact sub-name, then try to find compound with
+ // such sub-name without suffix.
+ Standard_Integer aSuffixPos = aSubNameCopy.SearchFromEnd('_');
+ if (aSuffixPos != -1 && aSuffixPos != aSubNameCopy.Length()) {
+ TCollection_ExtendedString anIndexStr = aSubNameCopy.Split(aSuffixPos);
+ aSubNameCopy.Remove(aSuffixPos);
+ aNamesIter.Initialize(*aLabIter, TDataStd_Name::GetID(), Standard_True);
+ for(; aNamesIter.More(); aNamesIter.Next()) {
+ Handle(TDataStd_Name) aName = Handle(TDataStd_Name)::DownCast(aNamesIter.Value());
+ if (aName->Get() == aSubNameCopy) {
+ return aName->Label();
+ }
+ }
+ // check also "this" label
+ Handle(TDataStd_Name) aName;
+ if (aLabIter->FindAttribute(TDataStd_Name::GetID(), aName)) {
+ if (aName->Get() == aSubNameCopy) {
+ return aName->Label();
+ }
+ }
+ }
+ }
+ // verify context's name is same as sub-component's and use context's label
+ if (aSubName.IsEqual(anObjName.c_str()))
+ return *(aFind->second.rbegin());
+ }
+ }
+ return TDF_Label(); // not found
+}
+
+bool Model_Document::isLaterByDep(FeaturePtr theThis, FeaturePtr theOther) {
+ // check dependencies first: if theOther depends on theThis, theThis is not later
+ std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > > aRefs;
+ theOther->data()->referencesToObjects(aRefs);
+ std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > >::iterator
+ aRefIt = aRefs.begin();
+ for(; aRefIt != aRefs.end(); aRefIt++) {
+ std::list<ObjectPtr>::iterator aRefObjIt = aRefIt->second.begin();
+ for(; aRefObjIt != aRefIt->second.end(); aRefObjIt++) {
+ ObjectPtr aRefObj = *aRefObjIt;
+ if (aRefObj.get()) {
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObj);
+ if (!aRefFeat.get()) { // take feature of the result
+ aRefFeat = feature(std::dynamic_pointer_cast<ModelAPI_Result>(aRefObj));
+ }
+ if (aRefFeat.get() && aRefFeat == theThis) {
+ return false; // other references to this, so this later than other
+ }
+ }
+ }
+ }
+ return myObjs->isLater(theThis, theOther);