Salome HOME
Issue #2092: Middle constraint not removed when creating a fillet
[modules/shaper.git] / src / Model / Model_Session.cpp
index 75cb32ee044bc5eb327ba56372f7ce2dff19de79..98a1340f9c4b41eb0ed3a87a6da69aea163445f7 100644 (file)
 #include <Config_ValidatorMessage.h>
 #include <Config_ModuleReader.h>
 #include <Config_ValidatorReader.h>
+
+#include <ModelAPI_CompositeFeature.h>
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Tools.h>
 
+#include <TDF_ChildIDIterator.hxx>
 #include <TDF_CopyTool.hxx>
 #include <TDF_DataSet.hxx>
 #include <TDF_RelocationTable.hxx>
 #include <TDF_ClosureTool.hxx>
 
-using namespace std;
+#include <TNaming_Builder.hxx>
+#include <TNaming_Iterator.hxx>
+#include <TNaming_NamedShape.hxx>
+
+#include <TopoDS_Shape.hxx>
 
 static Model_Session* myImpl = new Model_Session();
 
@@ -144,7 +151,7 @@ std::list<std::string> Model_Session::redoList()
   return ROOT_DOC->redoList();
 }
 
-FeaturePtr Model_Session::createFeature(string theFeatureID, Model_Document* theDocOwner)
+FeaturePtr Model_Session::createFeature(std::string theFeatureID, Model_Document* theDocOwner)
 {
   if (this != myImpl) {
     return myImpl->createFeature(theFeatureID, theDocOwner);
@@ -193,6 +200,7 @@ std::shared_ptr<ModelAPI_Document> Model_Session::moduleDocument()
   if (aFirstCall) {
     // to be sure that plugins are loaded,
     // even before the first "createFeature" call (in unit tests)
+
     LoadPluginsInfo();
     // creation of the root document is always outside of the transaction, so, avoid checking it
     setCheckTransactions(false);
@@ -268,7 +276,7 @@ void Model_Session::setActiveDocument(
         bool aWasChecked = myCheckTransactions;
         setCheckTransactions(false);
         TDF_LabelList anEmptyUpdated;
-        aDoc->objects()->synchronizeFeatures(anEmptyUpdated, true, true, true);
+        aDoc->objects()->synchronizeFeatures(anEmptyUpdated, true, true, false, true);
         if (aWasChecked)
             setCheckTransactions(true);
       }
@@ -292,10 +300,10 @@ void Model_Session::setActiveDocument(
 
 std::list<std::shared_ptr<ModelAPI_Document> > Model_Session::allOpenedDocuments()
 {
-  list<std::shared_ptr<ModelAPI_Document> > aResult;
+  std::list<std::shared_ptr<ModelAPI_Document> > aResult;
   aResult.push_back(moduleDocument());
   // add subs recursively
-  list<std::shared_ptr<ModelAPI_Document> >::iterator aDoc = aResult.begin();
+  std::list<std::shared_ptr<ModelAPI_Document> >::iterator aDoc = aResult.begin();
   for(; aDoc != aResult.end(); aDoc++) {
     DocumentPtr anAPIDoc = *aDoc;
     std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(anAPIDoc);
@@ -326,12 +334,56 @@ std::shared_ptr<ModelAPI_Document> Model_Session::copy(
   Handle(TDF_DataSet) aDS = new TDF_DataSet;
   aDS->AddLabel(aSourceRoot);
   TDF_ClosureTool::Closure(aDS);
-  Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable;
+  Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable(Standard_True);
   aRT->SetRelocation(aSourceRoot, aTargetRoot);
   TDF_CopyTool::Copy(aDS, aRT);
 
+  // TODO: remove after fix in OCCT.
+  // All named shapes are stored in reversed order, so to fix this we reverse them back.
+  for(TDF_ChildIDIterator aChildIter(aTargetRoot, TNaming_NamedShape::GetID(), true);
+      aChildIter.More();
+      aChildIter.Next()) {
+    Handle(TNaming_NamedShape) aNamedShape =
+      Handle(TNaming_NamedShape)::DownCast(aChildIter.Value());
+    if (aNamedShape.IsNull()) {
+      continue;
+    }
+
+    TopoDS_Shape aShape = aNamedShape->Get();
+    if(aShape.IsNull() || aShape.ShapeType() != TopAbs_COMPOUND) {
+      continue;
+    }
+
+    TNaming_Evolution anEvol = aNamedShape->Evolution();
+    std::list<std::pair<TopoDS_Shape, TopoDS_Shape> > aShapePairs; // to store old and new shapes
+    for(TNaming_Iterator anIter(aNamedShape); anIter.More(); anIter.Next()) {
+      aShapePairs.push_back(
+        std::pair<TopoDS_Shape, TopoDS_Shape>(anIter.OldShape(), anIter.NewShape()));
+    }
+
+    // Add in reverse order.
+    TDF_Label aLabel = aNamedShape->Label();
+    TNaming_Builder aBuilder(aLabel);
+    for(std::list<std::pair<TopoDS_Shape, TopoDS_Shape> >::iterator aPairsIter =
+          aShapePairs.begin();
+        aPairsIter != aShapePairs.end();
+        aPairsIter++) {
+      if (anEvol == TNaming_GENERATED) {
+        aBuilder.Generated(aPairsIter->first, aPairsIter->second);
+      } else if (anEvol == TNaming_MODIFY) {
+        aBuilder.Modify(aPairsIter->first, aPairsIter->second);
+      } else if (anEvol == TNaming_DELETE) {
+        aBuilder.Delete(aPairsIter->first);
+      } else if (anEvol == TNaming_PRIMITIVE) {
+        aBuilder.Generated(aPairsIter->second);
+      } else if (anEvol == TNaming_SELECTED) {
+        aBuilder.Select(aPairsIter->second, aPairsIter->first);
+      }
+    }
+  }
+
   TDF_LabelList anEmptyUpdated;
-  aNew->objects()->synchronizeFeatures(anEmptyUpdated, true, true, true);
+  aNew->objects()->synchronizeFeatures(anEmptyUpdated, true, true, true, true);
   return aNew;
 }
 
@@ -424,7 +476,8 @@ void Model_Session::processEvent(const std::shared_ptr<Events_Message>& theMessa
           }
         }
         if (!aFound) { // if not, the part was removed, so activate the module document
-          setActiveDocument(moduleDocument());
+          if (myCurrentDoc.get())
+            setActiveDocument(moduleDocument());
         }
       }
     }
@@ -435,7 +488,6 @@ void Model_Session::LoadPluginsInfo()
 {
   if (myPluginsInfoLoaded)  // nothing to do
     return;
-
   // Read plugins information from XML files
   Config_ModuleReader aModuleReader(Config_FeatureMessage::MODEL_EVENT());
   aModuleReader.readAll();
@@ -452,8 +504,7 @@ void Model_Session::registerPlugin(ModelAPI_Plugin* thePlugin)
 {
   myPluginObjs[myCurrentPluginName] = thePlugin;
   static Events_ID EVENT_LOAD = Events_Loop::loop()->eventByName(EVENT_PLUGIN_LOADED);
-  ModelAPI_EventCreator::get()->sendUpdated(ObjectPtr(), EVENT_LOAD);
-  Events_Loop::loop()->flush(EVENT_LOAD);
+  ModelAPI_EventCreator::get()->sendUpdated(ObjectPtr(), EVENT_LOAD, false);
   // If the plugin has an ability to process GUI events, register it
   Events_Listener* aListener = dynamic_cast<Events_Listener*>(thePlugin);
   if (aListener) {