Salome HOME
Issue #2358: Ability to put consecutive Features in a folder
[modules/shaper.git] / src / ModelAPI / ModelAPI_Tools.cpp
index f22b73c23c1ce295cf320d64d933fa12440a4992..ddd809ed663406e81dc2b5ac33420137c41a8ed9 100755 (executable)
@@ -254,7 +254,7 @@ FeaturePtr findPartFeature(const DocumentPtr& theMain, const DocumentPtr& theSub
 
 CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature)
 {
-  if (theFeature.get() && theFeature->data()->isValid()) {
+  if (theFeature.get() && theFeature->data() && theFeature->data()->isValid()) {
     const std::set<std::shared_ptr<ModelAPI_Attribute> >& aRefs = theFeature->data()->refsToMe();
     std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aRefIter = aRefs.begin();
     for(; aRefIter != aRefs.end(); aRefIter++) {
@@ -382,6 +382,7 @@ bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,
   return ModelAPI_Tools::removeFeatures(aFeatures, false);
 }
 
+//***********************************************************************
 bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
                     const bool theFlushRedisplay)
 {
@@ -406,6 +407,7 @@ bool removeFeatures(const std::set<FeaturePtr>& theFeatures,
   return true;
 }
 
+//***********************************************************************
 // Fills the references list by all references of the feature from the references map.
 // This is a recusive method to find references by next found feature in the map of references.
 // \param theFeature a feature to find references
@@ -623,8 +625,9 @@ void getConcealedResults(const FeaturePtr& theFeature,
   }
 }
 
-std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
-                           const int theResultIndex)
+std::pair<std::string, bool> getDefaultName(
+    const std::shared_ptr<ModelAPI_Result>& theResult,
+    const int theResultIndex)
 {
   typedef std::list< std::pair < std::string, std::list<ObjectPtr> > > ListOfReferences;
 
@@ -646,7 +649,7 @@ std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
       if (aCompSolidRes == *anIt)
         break;
     aDefaultName << "_" << (aCompSolidResultIndex + 1) << "_" << (theResultIndex + 1);
-    return aDefaultName.str();
+    return std::pair<std::string, bool>(aDefaultName.str(), false);
   }
 
   DataPtr aData = anOwner->data();
@@ -677,9 +680,21 @@ std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
 
   // find an object which is concealed by theResult
   if (aFoundRef != aReferences.end() && !aFoundRef->second.empty()) {
+    // store number of references for each object
+    std::map<ResultPtr, int> aNbRefToObject;
+    // search the object by result index
     std::list<ObjectPtr>::const_iterator anObjIt = aFoundRef->second.begin();
     int aResultIndex = theResultIndex;
     while (--aResultIndex >= 0) {
+      ResultPtr aCurRes = std::dynamic_pointer_cast<ModelAPI_Result>(*anObjIt);
+      ResultCompSolidPtr aParentCompSolid = ModelAPI_Tools::compSolidOwner(aCurRes);
+      if (aParentCompSolid)
+        aCurRes = aParentCompSolid;
+      if (aNbRefToObject.find(aCurRes) == aNbRefToObject.end())
+        aNbRefToObject[aCurRes] = 1;
+      else
+        aNbRefToObject[aCurRes] += 1;
+
       ++anObjIt;
       if (anObjIt == aFoundRef->second.end()) {
         anObjIt = aFoundRef->second.begin();
@@ -693,7 +708,20 @@ std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
       ResultCompSolidPtr aParentCompSolid = ModelAPI_Tools::compSolidOwner(anObjRes);
       if (aParentCompSolid)
         anObjRes = aParentCompSolid;
-      return anObjRes->data()->name();
+
+      // return name of reference result only if it has been renamed by the user,
+      // in other case compose a default name
+      if (anObjRes->data()->hasUserDefinedName()) {
+        std::stringstream aName;
+        aName << anObjRes->data()->name();
+        std::map<ResultPtr, int>::iterator aFound = aNbRefToObject.find(anObjRes);
+        if (aFound != aNbRefToObject.end()) {
+          // to generate unique name, add suffix if there are several results
+          // referring to the same shape
+          aName << "_" << aFound->second + 1;
+        }
+        return std::pair<std::string, bool>(aName.str(), true);
+      }
     }
   }
 
@@ -704,7 +732,7 @@ std::string getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
   // add unique prefix starting from second
   if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group())
     aDefaultName << "_" << theResultIndex + 1;
-  return aDefaultName.str();
+  return std::pair<std::string, bool>(aDefaultName.str(), false);
 }
 
 } // namespace ModelAPI_Tools