Salome HOME
Correct names generation for tests.
[modules/shaper.git] / src / Model / Model_Objects.cpp
index f635941b3aeecb60a10eb7658f76405799351d1c..85460450ce703b410da807ee6836e5cd974a2f19 100644 (file)
@@ -1,8 +1,22 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        Model_Objects.cxx
-// Created:     15 May 2015
-// Author:      Mikhail PONIKAROV
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
 
 #include <Model_Objects.h>
 #include <Model_Data.h>
@@ -269,6 +283,34 @@ void Model_Objects::removeFeature(FeaturePtr theFeature)
   }
 }
 
+void Model_Objects::eraseAllFeatures()
+{
+  static Events_ID kDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static const ModelAPI_EventCreator* kCreator = ModelAPI_EventCreator::get();
+  // make all features invalid (like deleted)
+  NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFIter(myFeatures);
+  for(; aFIter.More(); aFIter.Next()) {
+    FeaturePtr aFeature = aFIter.Value();
+    std::list<ResultPtr> aResList;
+    ModelAPI_Tools::allResults(aFeature, aResList);
+    std::list<ResultPtr>::iterator aRIter = aResList.begin();
+    for(; aRIter != aResList.end(); aRIter++) {
+      ResultPtr aRes = *aRIter;
+      if (aRes && aRes->data()->isValid()) {
+        kCreator->sendDeleted(myDoc, aRes->groupName());
+        kCreator->sendUpdated(aRes, kDispEvent);
+        aRes->setData(aRes->data()->invalidPtr());
+
+      }
+    }
+    kCreator->sendUpdated(aFeature, kDispEvent);
+    aFeature->setData(aFeature->data()->invalidPtr());
+  }
+  kCreator->sendDeleted(myDoc, ModelAPI_Feature::group());
+  myFeatures.Clear(); // just remove features without modification of DS
+  updateHistory(ModelAPI_Feature::group());
+}
+
 void Model_Objects::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis)
 {
   TDF_Label aFeaturesLab = featuresLabel();
@@ -667,7 +709,7 @@ void Model_Objects::synchronizeFeatures(
       aFeature = myFeatures.Find(aFeatureLabel);
       aKeptFeatures.insert(aFeature);
       if (anUpdatedMap.Contains(aFeatureLabel)) {
-        if (!theOpen) { // on abort/undo/redo reinitialize attributes is something is changed
+        if (!theOpen) { // on abort/undo/redo reinitialize attributes if something is changed
           std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
             aFeature->data()->attributes("");
           std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
@@ -891,22 +933,57 @@ TDF_Label Model_Objects::resultLabel(
   return aData->label().Father().FindChild(TAG_FEATURE_RESULTS).FindChild(theResultIndex + 1);
 }
 
+bool Model_Objects::hasCustomName(DataPtr theFeatureData,
+                                  ResultPtr theResult,
+                                  int theResultIndex,
+                                  std::string& theParentName) const
+{
+  ResultCompSolidPtr aCompSolidRes =
+      std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theFeatureData->owner());
+  if (aCompSolidRes) {
+    FeaturePtr anOwner = ModelAPI_Feature::feature(theResult->data()->owner());
+
+    // names of sub-solids in CompSolid should be default (for example,
+    // result of boolean operation 'Boolean_1' is a CompSolid which is renamed to 'MyBOOL',
+    // however, sub-elements of 'MyBOOL' should be named 'Boolean_1_1', 'Boolean_1_2' etc.)
+    std::ostringstream aDefaultName;
+    aDefaultName << anOwner->name();
+    // compute default name of CompSolid (name of feature + index of CompSolid's result)
+    int aCompSolidResultIndex = 0;
+    const std::list<ResultPtr>& aResults = anOwner->results();
+    for (std::list<ResultPtr>::const_iterator anIt = aResults.begin();
+         anIt != aResults.end(); ++anIt, ++aCompSolidResultIndex)
+      if (aCompSolidRes == *anIt)
+        break;
+    aDefaultName << "_" << (aCompSolidResultIndex + 1);
+    theParentName = aDefaultName.str();
+    return false;
+  }
+
+  theParentName = ModelAPI_Tools::getDefaultName(theResult, theResultIndex);
+  return true;
+}
+
 void Model_Objects::storeResult(std::shared_ptr<ModelAPI_Data> theFeatureData,
-                                 std::shared_ptr<ModelAPI_Result> theResult,
-                                 const int theResultIndex)
+                                std::shared_ptr<ModelAPI_Result> theResult,
+                                const int theResultIndex)
 {
   theResult->init();
   theResult->setDoc(myDoc);
   initData(theResult, resultLabel(theFeatureData, theResultIndex), TAG_FEATURE_ARGUMENTS);
   if (theResult->data()->name().empty()) {
     // if was not initialized, generate event and set a name
-    std::stringstream aNewName;
-    aNewName<<theFeatureData->name();
-    // if there are several results (issue #899: any number of result),
-    // add unique prefix starting from second
-    if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group())
-      aNewName<<"_"<<theResultIndex + 1;
-    theResult->data()->setName(aNewName.str());
+    std::string aNewName = theFeatureData->name();
+    if (!hasCustomName(theFeatureData, theResult, theResultIndex, aNewName)) {
+      std::stringstream aName;
+      aName << aNewName;
+      // if there are several results (issue #899: any number of result),
+      // add unique prefix starting from second
+      if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group())
+        aName << "_" << theResultIndex + 1;
+      aNewName = aName.str();
+    }
+    theResult->data()->setName(aNewName);
   }
 }
 
@@ -1073,7 +1150,7 @@ void Model_Objects::updateResults(FeaturePtr theFeature, std::set<FeaturePtr>& t
   theProcessed.insert(theFeature);
   // for composites update subs recursively (sketch elements results are needed for the sketch)
   CompositeFeaturePtr aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
-  if (aComp.get()) {
+  if (aComp.get() && aComp->getKind() != "Part") { // don't go inside of parts sub-features
     // update subs of composites first
     int aSubNum = aComp->numberOfSubs();
     for(int a = 0; a < aSubNum; a++) {
@@ -1145,6 +1222,8 @@ void Model_Objects::updateResults(FeaturePtr theFeature, std::set<FeaturePtr>& t
 
 ResultPtr Model_Objects::findByName(const std::string theName)
 {
+  ResultPtr aResult;
+  FeaturePtr aResFeature; // keep feature to return the latest one
   NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator anObjIter(myFeatures);
   for(; anObjIter.More(); anObjIter.Next()) {
     FeaturePtr& aFeature = anObjIter.ChangeValue();
@@ -1156,13 +1235,16 @@ ResultPtr Model_Objects::findByName(const std::string theName)
     for (; aRIter != allResults.cend(); aRIter++) {
       ResultPtr aRes = *aRIter;
       if (aRes.get() && aRes->data() && aRes->data()->isValid() && !aRes->isDisabled() &&
-          aRes->data()->name() == theName) {
-        return aRes;
+          aRes->data()->name() == theName)
+      {
+        if (!aResult.get() || isLater(aFeature, aResFeature)) { // select the latest
+          aResult = aRes;
+          aResFeature = aFeature;
+        }
       }
     }
   }
-  // not found
-  return ResultPtr();
+  return aResult;
 }
 
 FeaturePtr Model_Objects::nextFeature(FeaturePtr theCurrent, const bool theReverse)