]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
The duplicate and remove parts implementation.
authormpv <mikhail.ponikarov@opencascade.com>
Wed, 21 May 2014 08:44:36 +0000 (12:44 +0400)
committermpv <mikhail.ponikarov@opencascade.com>
Wed, 21 May 2014 08:44:36 +0000 (12:44 +0400)
13 files changed:
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_PluginManager.cpp
src/Model/Model_PluginManager.h
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_Feature.h
src/ModelAPI/ModelAPI_PluginManager.h
src/PartSetPlugin/CMakeLists.txt
src/PartSetPlugin/PartSetPlugin_Duplicate.cpp [new file with mode: 0644]
src/PartSetPlugin/PartSetPlugin_Duplicate.h [new file with mode: 0644]
src/PartSetPlugin/PartSetPlugin_Plugin.cpp
src/PartSetPlugin/PartSetPlugin_Remove.cpp [new file with mode: 0644]
src/PartSetPlugin/PartSetPlugin_Remove.h [new file with mode: 0644]

index 8208461788b13859e6d1d7f4f0d13ce9d4f4dbf2..423de6a37e4864e512ab4d297a942d8071d5c6af 100644 (file)
@@ -164,7 +164,8 @@ void Model_Document::close()
     subDocument(*aSubIter)->close();
   mySubs.clear();
   // close this
-  myDoc->Close();
+  if (myDoc->CanClose() == CDM_CCS_OK)
+    myDoc->Close();
   Model_Application::getApplication()->deleteDocument(myID);
 }
 
@@ -296,6 +297,8 @@ static void AddToRefArray(TDF_Label& theArrayLab, TDF_Label& theReferenced) {
 
 void Model_Document::addFeature(const boost::shared_ptr<ModelAPI_Feature> theFeature)
 {
+  if (theFeature->isAction()) return; // do not add action to the data model
+
   boost::shared_ptr<ModelAPI_Document> aThis = 
     Model_Application::getApplication()->getDocument(myID);
   TDF_Label aFeaturesLab = groupLabel(FEATURES_GROUP);
@@ -333,6 +336,63 @@ void Model_Document::addFeature(const boost::shared_ptr<ModelAPI_Feature> theFea
   Events_Loop::loop()->send(aMsg);
 }
 
+/// Appenad to the array of references a new referenced label.
+/// If theIndex is not -1, removes element at thisindex, not theReferenced.
+/// \returns the index of removed element
+static int RemoveFromRefArray(
+  TDF_Label theArrayLab, TDF_Label theReferenced, const int theIndex = -1) {
+  int aResult = -1; // no returned
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (theArrayLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
+    if (aRefs->Length() == 1) { // just erase an array
+      if ((theIndex == -1 && aRefs->Value(0) == theReferenced) || theIndex == 0)
+        theArrayLab.ForgetAttribute(TDataStd_ReferenceArray::GetID());
+      aResult = 0;
+    } else { // reduce the array
+      Handle(TDataStd_HLabelArray1) aNewArray = 
+        new TDataStd_HLabelArray1(aRefs->Lower(), aRefs->Upper() - 1);
+      int aCount = aRefs->Lower();
+      for(int a = aCount; a <= aRefs->Upper(); a++, aCount++) {
+        if ((theIndex == -1 && aRefs->Value(a) == theReferenced) || theIndex == a) {
+          aCount--;
+          aResult = a;
+        } else {
+          aNewArray->SetValue(aCount, aRefs->Value(a));
+        }
+      }
+    aRefs->SetInternalArray(aNewArray);
+    }
+  }
+  return aResult;
+}
+
+void Model_Document::removeFeature(boost::shared_ptr<ModelAPI_Feature> theFeature)
+{
+  boost::shared_ptr<Model_Data> aData = boost::static_pointer_cast<Model_Data>(theFeature->data());
+  TDF_Label aFeatureLabel = aData->label();
+  // remove the object
+  TDF_Label aGroupLabel = groupLabel(theFeature->getGroup());
+  int aRemovedIndex = RemoveFromRefArray(aGroupLabel, aFeatureLabel);
+  RemoveFromRefArray(aGroupLabel.FindChild(1), TDF_Label(), aRemovedIndex);
+  // remove feature from the myFeatures list
+  std::vector<boost::shared_ptr<ModelAPI_Feature> >::iterator aFIter = myFeatures.begin();
+  while(aFIter != myFeatures.end()) {
+    if (*aFIter == theFeature) {
+      aFIter = myFeatures.erase(aFIter);
+    } else {
+      aFIter++;
+    }
+  }
+  // erase all attributes under the label of feature
+  aFeatureLabel.ForgetAllAttributes();
+  // remove it from the references array
+  RemoveFromRefArray(groupLabel(FEATURES_GROUP), aData->label());
+
+  // event: feature is added
+  Model_FeatureDeletedMessage aMsg(theFeature->document(), theFeature->getGroup());
+  Events_Loop::loop()->send(aMsg);
+}
+
 boost::shared_ptr<ModelAPI_Feature> Model_Document::feature(TDF_Label& theLabel)
 {
   // iterate all features, may be optimized later by keeping labels-map
@@ -443,6 +503,7 @@ void Model_Document::setUniqueName(boost::shared_ptr<ModelAPI_Feature> theFeatur
         aNumObjects++;
         stringstream aNameStream;
         aNameStream<<theFeature->getKind()<<"_"<<aNumObjects + 1;
+        aName = aNameStream.str();
         // reinitialize iterator to make sure a new name is unique
         a = 0;
       } else a++;
index ce16a5de7b9874df9af7fe58d63758d26d2add71..b1945bae1eb878d7df5615b07e3ef4c6781d33c1 100644 (file)
@@ -63,6 +63,9 @@ public:
   //! \param creates feature and puts it in the document
   MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> addFeature(std::string theID);
 
+  //! Removes the feature from the document
+  MODEL_EXPORT virtual void removeFeature(boost::shared_ptr<ModelAPI_Feature> theFeature);
+
   //! Returns the existing feature by the label
   //! \param theLabel base label of the feature
   MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> feature(TDF_Label& theLabel);
@@ -105,7 +108,10 @@ protected:
   //! Creates new document with binary file format
   Model_Document(const std::string theID);
 
+  Handle_TDocStd_Document document() {return myDoc;}
+
   friend class Model_Application;
+  friend class Model_PluginManager;
 
 private:
   std::string myID; ///< identifier of the document in the application
index cbb917a76fa9a7238bbd401865464e239cc4fba0..d6fca2bf745c915f148772cc187cb06f22d8752d 100644 (file)
@@ -9,9 +9,16 @@
 #include <Model_Document.h>
 #include <Model_Application.h>
 #include <Events_Loop.h>
+#include <Events_Error.h>
 #include <Config_FeatureMessage.h>
 #include <Config_ModuleReader.h>
 
+#include <TDF_CopyTool.hxx>
+#include <TDF_DataSet.hxx>
+#include <TDF_RelocationTable.hxx>
+#include <TDF_ClosureTool.hxx>
+
+
 using namespace std;
 
 static Model_PluginManager* myImpl = new Model_PluginManager();
@@ -30,7 +37,13 @@ boost::shared_ptr<ModelAPI_Feature> Model_PluginManager::createFeature(string th
     if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) {
       boost::shared_ptr<ModelAPI_Feature> aCreated = 
         myPluginObjs[myCurrentPluginName]->createFeature(theFeatureID);
+      if (!aCreated) {
+        Events_Error::send(string("Can not initialize feature '") + theFeatureID +
+          "' in plugin '" + myCurrentPluginName + "'");
+      }
       return aCreated;
+    } else {
+      Events_Error::send(string("Can not load plugin '") + myCurrentPluginName + "'");
     }
   }
 
@@ -60,6 +73,27 @@ void Model_PluginManager::setCurrentDocument(boost::shared_ptr<ModelAPI_Document
   myCurrentDoc = theDoc;
 }
 
+boost::shared_ptr<ModelAPI_Document> Model_PluginManager::copy(
+  boost::shared_ptr<ModelAPI_Document> theSource, std::string theID) 
+{
+  // create a new document
+  boost::shared_ptr<Model_Document> aNew = boost::dynamic_pointer_cast<Model_Document>(
+    Model_Application::getApplication()->getDocument(theID));
+  // make a copy of all labels
+  TDF_Label aSourceRoot = 
+    boost::dynamic_pointer_cast<Model_Document>(theSource)->document()->Main().Father();
+  TDF_Label aTargetRoot = aNew->document()->Main().Father();
+  Handle(TDF_DataSet) aDS = new TDF_DataSet;
+  aDS->AddLabel(aSourceRoot);
+  TDF_ClosureTool::Closure(aDS);
+  Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable;
+  aRT->SetRelocation(aSourceRoot, aTargetRoot);
+  TDF_CopyTool::Copy(aDS, aRT);
+
+  aNew->synchronizeFeatures();
+  return aNew;
+}
+
 Model_PluginManager::Model_PluginManager()
 {
   myPluginsInfoLoaded = false;
index 7f405573fea644010a96dc6c53757e2be75b83af..aa230700a1dc5d44e33bd8020402a25ad5971a8a 100644 (file)
@@ -47,6 +47,10 @@ public:
   /// Processes the configuration file reading
   MODEL_EXPORT virtual void processEvent(const Events_Message* theMessage);
 
+  /// Copies the document to the new one wit hthe given id
+  MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Document> copy(
+    boost::shared_ptr<ModelAPI_Document> theSource, std::string theID);
+
   /// Is called only once, on startup of the application
   Model_PluginManager();
 
index bed11f88617854a642e8676659ade04bb3dda2c8..9070718b48974151d3b0a4ea2332f65438340f71 100644 (file)
@@ -69,8 +69,12 @@ public:
   //! \param creates feature and puts it in the document
   MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> addFeature(std::string theID) = 0;
 
+  //! Removes the feature from the document
+  MODELAPI_EXPORT virtual void removeFeature(boost::shared_ptr<ModelAPI_Feature> theFeature) = 0;
+
   ///! Adds a new sub-document by the identifier, or returns existing one if it is already exist
-  MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Document> subDocument(std::string theDocID) = 0;
+  MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Document> 
+    subDocument(std::string theDocID) = 0;
 
   ///! Returns the id of hte document
   MODELAPI_EXPORT virtual const std::string& id() const = 0;
index eb4ba54f992dc60664127fa71ba529a540dea8c8..dd98c597a02c7f466f9caa61a01ec77d804e5c38 100644 (file)
@@ -40,6 +40,10 @@ public:
   /// Returns true if this feature must be displayed in the history (top level of Part tree)
   MODELAPI_EXPORT virtual bool isInHistory() {return true;}
 
+  /// Returns true if this feature must not be created: this is just an action
+  /// that is not stored in the features history (like delete part).
+  MODELAPI_EXPORT virtual bool isAction() {return false;}
+
   /// Returns the data manager of this feature
   MODELAPI_EXPORT virtual boost::shared_ptr<ModelAPI_Data> data() {return myData;}
 
index 47c42562ffdcd87682973ccdd152d595593a0290..6b25bf4a378dfc68758dc6f500b33ee692219054 100644 (file)
@@ -43,6 +43,10 @@ public:
   /// Defines the current document that used for current work in the application
   virtual void setCurrentDocument(boost::shared_ptr<ModelAPI_Document> theDoc) = 0;
 
+  /// Copies the document to the new one wit hthe given id
+  virtual boost::shared_ptr<ModelAPI_Document> copy(
+    boost::shared_ptr<ModelAPI_Document> theSource, std::string theID) = 0;
+
   /// Is needed for python wrapping by swig, call Get to get an instance
   ModelAPI_PluginManager();
 
index d9715d5901bb3c088e605ae9d799a08705bc283c..119d74843b938d8318c0fd2cb42eee5bcde9a2a8 100644 (file)
@@ -4,11 +4,15 @@ SET(PROJECT_HEADERS
     PartSetPlugin.h
     PartSetPlugin_Plugin.h
     PartSetPlugin_Part.h
+    PartSetPlugin_Duplicate.h
+    PartSetPlugin_Remove.h
 )
 
 SET(PROJECT_SOURCES
     PartSetPlugin_Plugin.cpp
     PartSetPlugin_Part.cpp
+    PartSetPlugin_Duplicate.cpp
+    PartSetPlugin_Remove.cpp
 )
 
 ADD_DEFINITIONS(-DPARTSETPLUGIN_EXPORTS ${BOOST_DEFINITIONS})
diff --git a/src/PartSetPlugin/PartSetPlugin_Duplicate.cpp b/src/PartSetPlugin/PartSetPlugin_Duplicate.cpp
new file mode 100644 (file)
index 0000000..9b6a47e
--- /dev/null
@@ -0,0 +1,40 @@
+// File:        PartSetPlugin_Duplicate.cxx
+// Created:     20 May 2014
+// Author:      Mikhail PONIKAROV
+
+#include "PartSetPlugin_Duplicate.h"
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+
+using namespace std;
+
+PartSetPlugin_Duplicate::PartSetPlugin_Duplicate()
+{
+}
+
+void PartSetPlugin_Duplicate::initAttributes()
+{
+  PartSetPlugin_Part::initAttributes();
+  data()->addAttribute(PART_DUPLICATE_ATTR_REF, ModelAPI_AttributeRefAttr::type());
+
+  boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef = data()->refattr(PART_DUPLICATE_ATTR_REF);
+  if (!aRef->attr()) { // create a copy: if not created yet attribute is not initialized
+    boost::shared_ptr<ModelAPI_PluginManager> aPManager = ModelAPI_PluginManager::get();
+    boost::shared_ptr<ModelAPI_Document> aRoot = aPManager->rootDocument();
+    boost::shared_ptr<PartSetPlugin_Part> aSource; // searching for source document attribute
+    for(int a = aRoot->size(getGroup()) - 1; a >= 0; a--) {
+      aSource = boost::dynamic_pointer_cast<PartSetPlugin_Part>(
+        aRoot->feature(getGroup(), a, true));
+      if (aSource->data()->docRef(PART_ATTR_DOC_REF)->value() == aPManager->currentDocument())
+        break;
+      aSource.reset();
+    }
+    if (aSource) {
+      boost::shared_ptr<ModelAPI_Document> aCopy = 
+        aPManager->copy(aSource->data()->docRef(PART_ATTR_DOC_REF)->value(), data()->getName());
+      aRef->setFeature(aSource);
+    }
+  }
+}
diff --git a/src/PartSetPlugin/PartSetPlugin_Duplicate.h b/src/PartSetPlugin/PartSetPlugin_Duplicate.h
new file mode 100644 (file)
index 0000000..9bab4d6
--- /dev/null
@@ -0,0 +1,27 @@
+// File:        PartSetPlugin_Duplicate.h
+// Created:     20 May 2014
+// Author:      Mikhail PONIKAROV
+
+#ifndef PartSetPlugin_Duplicate_HeaderFile
+#define PartSetPlugin_Duplicate_HeaderFile
+
+#include "PartSetPlugin_Part.h"
+
+/// the reference to copy: reference to the attribute
+const std::string PART_DUPLICATE_ATTR_REF = "Origin";
+
+/**\class PartSetPlugin_Duplicate
+ * \ingroup DataModel
+ * \brief Duplicates the active part (not root). Creates a new "part" feature.
+ */
+class PartSetPlugin_Duplicate: public PartSetPlugin_Part
+{
+public:
+  /// Makes a new part, copy of active
+  PartSetPlugin_Duplicate();
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  PARTSETPLUGIN_EXPORT virtual void initAttributes();
+};
+
+#endif
index 85ea1c37eacf527337a523ae115b3684134ef227..76ea7b441c0f6ae5375b48bdb1ed5c4bc498ddcc 100644 (file)
@@ -1,5 +1,7 @@
 #include "PartSetPlugin_Plugin.h"
 #include "PartSetPlugin_Part.h"
+#include "PartSetPlugin_Duplicate.h"
+#include "PartSetPlugin_Remove.h"
 #include <ModelAPI_PluginManager.h>
 #include <ModelAPI_Document.h>
 
@@ -19,6 +21,12 @@ boost::shared_ptr<ModelAPI_Feature> PartSetPlugin_Plugin::createFeature(string t
   if (theFeatureID == "Part") {
     return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Part);
   }
-  // feature of such kind is not found
+  if (theFeatureID == "duplicate") {
+    return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Duplicate);
+  }
+  if (theFeatureID == "remove") {
+    return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_Remove);
+  }
+    // feature of such kind is not found
   return boost::shared_ptr<ModelAPI_Feature>();
 }
diff --git a/src/PartSetPlugin/PartSetPlugin_Remove.cpp b/src/PartSetPlugin/PartSetPlugin_Remove.cpp
new file mode 100644 (file)
index 0000000..5e99cb1
--- /dev/null
@@ -0,0 +1,29 @@
+// File:        PartSetPlugin_Remove.cxx
+// Created:     20 May 2014
+// Author:      Mikhail PONIKAROV
+
+#include "PartSetPlugin_Remove.h"
+#include "PartSetPlugin_Part.h"
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_AttributeDocRef.h>
+
+void PartSetPlugin_Remove::execute()
+{
+  boost::shared_ptr<ModelAPI_PluginManager> aPManager = ModelAPI_PluginManager::get();
+  boost::shared_ptr<ModelAPI_Document> aRoot = aPManager->rootDocument();
+  boost::shared_ptr<ModelAPI_Document> aCurrent;
+  boost::shared_ptr<PartSetPlugin_Part> a;
+  for(int a = aRoot->size(getGroup()) - 1; a >= 0; a--) {
+    boost::shared_ptr<ModelAPI_Feature> aFeature = aRoot->feature(getGroup(), a, true);
+    if (aFeature->getKind() == "Part") {
+      boost::shared_ptr<PartSetPlugin_Part> aPart = 
+        boost::static_pointer_cast<PartSetPlugin_Part>(aFeature);
+      if (aPart->data()->docRef(PART_ATTR_DOC_REF)->value() == aPManager->currentDocument()) {
+        // do remove
+        aPart->data()->docRef(PART_ATTR_DOC_REF)->value()->close();
+        aRoot->removeFeature(aPart);
+      }
+    }
+  }
+}
diff --git a/src/PartSetPlugin/PartSetPlugin_Remove.h b/src/PartSetPlugin/PartSetPlugin_Remove.h
new file mode 100644 (file)
index 0000000..f12066c
--- /dev/null
@@ -0,0 +1,39 @@
+// File:        PartSetPlugin_Remove.h
+// Created:     20 May 2014
+// Author:      Mikhail PONIKAROV
+
+#ifndef PartSetPlugin_Remove_HeaderFile
+#define PartSetPlugin_Remove_HeaderFile
+
+#include "PartSetPlugin.h"
+#include <ModelAPI_Feature.h>
+
+/**\class PartSetPlugin_Remove
+ * \ingroup DataModel
+ * \brief Feature for creation of the new part in PartSet.
+ */
+class PartSetPlugin_Remove: public ModelAPI_Feature
+{
+public:
+  /// Returns the kind of a feature
+  PARTSETPLUGIN_EXPORT virtual const std::string& getKind() 
+  {static std::string MY_KIND = "Remove"; return MY_KIND;}
+
+  /// Returns to which group in the document must be added feature
+  PARTSETPLUGIN_EXPORT virtual const std::string& getGroup() 
+  {static std::string MY_GROUP = "Parts"; return MY_GROUP;}
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  PARTSETPLUGIN_EXPORT virtual void initAttributes() {}
+
+  /// Not normal feature that stored in the tree
+  PARTSETPLUGIN_EXPORT virtual bool isAction() {return true;}
+
+  /// Performs the "remove"
+  PARTSETPLUGIN_EXPORT virtual void execute();
+
+  /// Use plugin manager for features creation
+  PartSetPlugin_Remove() {}
+};
+
+#endif