]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Task 5.1.7: To be able to export a part to a file and import it into an existing...
authorazv <azv@opencascade.com>
Mon, 28 Oct 2019 11:02:32 +0000 (14:02 +0300)
committerazv <azv@opencascade.com>
Fri, 1 Nov 2019 13:28:24 +0000 (16:28 +0300)
Implement exporting/importing of the part to binary file.

20 files changed:
src/ExchangePlugin/CMakeLists.txt
src/ExchangePlugin/ExchangePlugin_ExportPart.cpp [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_ExportPart.h [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_ImportPart.cpp [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_ImportPart.h [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_Plugin.cpp
src/ExchangePlugin/icons/export_part.png [new file with mode: 0644]
src/ExchangePlugin/icons/import_part.png [new file with mode: 0644]
src/ExchangePlugin/plugin-Exchange.xml
src/Model/CMakeLists.txt
src/Model/Model_Application.cpp
src/Model/Model_Data.cpp
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Tools.cpp [new file with mode: 0644]
src/Model/Model_Tools.h [new file with mode: 0644]
src/ModelAPI/ModelAPI_Document.h
src/XGUI/CMakeLists.txt
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index 222f2e6eaea1ac3bea1cbbb0aa44e8d0b8465cd8..4094385a5519021c968b78e5fa2b139892de4c14 100644 (file)
@@ -37,6 +37,8 @@ SET(PROJECT_HEADERS
     ExchangePlugin_Validators.h
     ExchangePlugin_Tools.h
     ExchangePlugin_Dump.h
+    ExchangePlugin_ImportPart.h
+    ExchangePlugin_ExportPart.h
 )
 
 SET(PROJECT_SOURCES
@@ -46,6 +48,8 @@ SET(PROJECT_SOURCES
     ExchangePlugin_Validators.cpp
     ExchangePlugin_Tools.cpp
     ExchangePlugin_Dump.cpp
+    ExchangePlugin_ImportPart.cpp
+    ExchangePlugin_ExportPart.cpp
 )
 
 SET(XML_RESOURCES
diff --git a/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp b/src/ExchangePlugin/ExchangePlugin_ExportPart.cpp
new file mode 100644 (file)
index 0000000..dbf476c
--- /dev/null
@@ -0,0 +1,154 @@
+// Copyright (C) 2014-2019  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
+//
+
+#include <ExchangePlugin_ExportPart.h>
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+// Obtain all features to be exported to get the list of selected results.
+static void collectFeatures(AttributeSelectionListPtr theSelected,
+                            std::list<FeaturePtr>& theExport);
+// Obtain all constuction elements of the document.
+static void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport);
+
+
+ExchangePlugin_ExportPart::ExchangePlugin_ExportPart()
+{
+}
+
+void ExchangePlugin_ExportPart::initAttributes()
+{
+  data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(FILE_FORMAT_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(SELECTION_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SELECTION_LIST_ID());
+}
+
+void ExchangePlugin_ExportPart::execute()
+{
+  AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
+  std::string aFilename = aFilePathAttr->value();
+  if (aFilename.empty()) {
+    setError("File path is empty.");
+    return;
+  }
+
+  std::list<FeaturePtr> aFeaturesToExport;
+
+  SessionPtr aSession = ModelAPI_Session::get();
+  AttributeSelectionListPtr aSelected = selectionList(SELECTION_LIST_ID());
+  DocumentPtr anExportDoc;
+  if (aSelected && aSelected->size() == 0 &&
+      aSession->activeDocument() == aSession->moduleDocument()) {
+    // no result is selected, thus have to export all features of the current document,
+    // but the document is a PartSet; and it is forbidden to copy results of Parts,
+    // thus copy construction elements only
+    collectConstructions(aSession->moduleDocument(), aFeaturesToExport);
+  }
+  else
+    collectFeatures(aSelected, aFeaturesToExport);
+
+  if (!aFeaturesToExport.empty()) {
+    // remove 'ExportPart' feature is any
+    if (aFeaturesToExport.back()->getKind() == ExchangePlugin_ExportPart::ID())
+      aFeaturesToExport.pop_back();
+    // save the document
+    if (!aSession->activeDocument()->save(aFilename.c_str(), aFeaturesToExport))
+      setError("Cannot save the document.");
+  }
+}
+
+
+// ================================     Auxiliary functions     ===================================
+
+static void allReferencedFeatures(std::set<FeaturePtr>& theFeatures)
+{
+  std::set<FeaturePtr> aReferences;
+  for (std::set<FeaturePtr>::iterator anIt = theFeatures.begin();
+       anIt != theFeatures.end(); ++anIt) {
+    std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
+    (*anIt)->data()->referencesToObjects(aRefs);
+
+    for (std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRIt = aRefs.begin();
+         aRIt != aRefs.end(); ++aRIt) {
+      for (std::list<ObjectPtr>::iterator anObjIt = aRIt->second.begin();
+           anObjIt != aRIt->second.end(); ++anObjIt) {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt);
+        if (aFeature)
+          aReferences.insert(aFeature);
+      }
+    }
+  }
+
+  if (!aReferences.empty()) {
+    allReferencedFeatures(aReferences);
+    theFeatures.insert(aReferences.begin(), aReferences.end());
+  }
+}
+
+void collectFeatures(AttributeSelectionListPtr theSelected, std::list<FeaturePtr>& theExport)
+{
+  theExport = ModelAPI_Session::get()->activeDocument()->allFeatures();
+
+  if (!theSelected || theSelected->size() == 0) {
+    // nothing is selected, return all features of the document
+    return;
+  }
+
+  // collect initial list of features basing on the selected results
+  std::set<FeaturePtr> aFeaturesToExport;
+  for (int anIndex = 0, aSize = theSelected->size(); anIndex < aSize; ++anIndex) {
+    AttributeSelectionPtr aCurrent = theSelected->value(anIndex);
+    FeaturePtr aCurrentFeature = ModelAPI_Feature::feature(aCurrent->context());
+    if (aCurrentFeature)
+      aFeaturesToExport.insert(aCurrentFeature);
+  }
+  // recursively collect all features used for the selected results
+  allReferencedFeatures(aFeaturesToExport);
+
+  // remove the features which are not affect the selected results
+  std::list<FeaturePtr>::iterator anIt = theExport.begin();
+  while (anIt != theExport.end()) {
+    if (aFeaturesToExport.find(*anIt) == aFeaturesToExport.end()) {
+      std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
+      theExport.erase(aRemoveIt);
+    }
+    else
+      ++anIt;
+  }
+}
+
+void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport)
+{
+  theExport = theDocument->allFeatures();
+  // keep constructions only
+  std::list<FeaturePtr>::iterator anIt = theExport.begin();
+  while (anIt != theExport.end()) {
+    if ((*anIt)->lastResult()->groupName() == ModelAPI_ResultConstruction::group())
+      ++anIt;
+    else {
+      std::list<FeaturePtr>::iterator aRemoveIt = anIt++;
+      theExport.erase(aRemoveIt);
+    }
+  }
+}
diff --git a/src/ExchangePlugin/ExchangePlugin_ExportPart.h b/src/ExchangePlugin/ExchangePlugin_ExportPart.h
new file mode 100644 (file)
index 0000000..504d777
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (C) 2014-2019  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
+//
+
+#ifndef EXCHANGEPLUGIN_EXPORTPART_H_
+#define EXCHANGEPLUGIN_EXPORTPART_H_
+
+#include <ExchangePlugin.h>
+#include <ModelAPI_Feature.h>
+
+/**
+ * \class ExchangePlugin_ExportPart
+ * \ingroup Plugins
+ * \brief Feature for export some results of a Part to the binary format for the further import.
+ */
+class ExchangePlugin_ExportPart : public ModelAPI_Feature
+{
+public:
+  /// Feature kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_EXPORT_ID("ExportPart");
+    return MY_EXPORT_ID;
+  }
+  /// attribute name of file path
+  inline static const std::string& FILE_PATH_ID()
+  {
+    static const std::string MY_FILE_PATH_ID("file_path");
+    return MY_FILE_PATH_ID;
+  }
+  /// attribute name of file format
+  inline static const std::string& FILE_FORMAT_ID()
+  {
+    static const std::string MY_FILE_FORMAT_ID("file_format");
+    return MY_FILE_FORMAT_ID;
+  }
+  /// attribute name of selection list
+  inline static const std::string& SELECTION_LIST_ID()
+  {
+    static const std::string MY_SELECTION_LIST_ID("selection_list");
+    return MY_SELECTION_LIST_ID;
+  }
+  /// Default constructor
+  ExchangePlugin_ExportPart();
+
+  /// Returns the unique kind of a feature
+  EXCHANGEPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    return ExchangePlugin_ExportPart::ID();
+  }
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  EXCHANGEPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Computes or recomputes the results
+  EXCHANGEPLUGIN_EXPORT virtual void execute();
+
+  /// Returns true if this feature is used as macro: creates other features and then removed.
+  EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+
+  /// Reimplemented from ModelAPI_Feature::isPreviewNeeded(). Returns false.
+  EXCHANGEPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }
+
+  /// Do not put in history.
+  /// Since it is not a macro, it is not deleted, but we don't want to see it.
+  bool isInHistory()  { return false; }
+};
+
+#endif /* EXCHANGEPLUGIN_EXPORTPART_H_ */
diff --git a/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp b/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp
new file mode 100644 (file)
index 0000000..ed0c456
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2014-2019  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
+//
+
+#include <ExchangePlugin_ImportPart.h>
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Session.h>
+
+ExchangePlugin_ImportPart::ExchangePlugin_ImportPart()
+{
+}
+
+void ExchangePlugin_ImportPart::initAttributes()
+{
+  data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
+}
+
+void ExchangePlugin_ImportPart::execute()
+{
+  AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
+  std::string aFilename = aFilePathAttr->value();
+  if (aFilename.empty()) {
+    setError("File path is empty.");
+    return;
+  }
+
+  // load the file into the active document
+  SessionPtr aSession = ModelAPI_Session::get();
+  if (!aSession->activeDocument()->import(aFilename.c_str()))
+    setError("Cannot import the document.");
+}
diff --git a/src/ExchangePlugin/ExchangePlugin_ImportPart.h b/src/ExchangePlugin/ExchangePlugin_ImportPart.h
new file mode 100644 (file)
index 0000000..b10ba54
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2014-2019  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
+//
+
+#ifndef EXCHANGEPLUGIN_IMPORTPART_H_
+#define EXCHANGEPLUGIN_IMPORTPART_H_
+
+#include <ExchangePlugin.h>
+#include <ModelAPI_Feature.h>
+
+/**
+ * \class ExchangePlugin_ImportPart
+ * \ingroup Plugins
+ * \brief Feature for import the structure of Part into the current document.
+ */
+class ExchangePlugin_ImportPart : public ModelAPI_Feature
+{
+public:
+  /// Feature kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_IMPORT_ID("ImportPart");
+    return MY_IMPORT_ID;
+  }
+  /// attribute name of file path
+  inline static const std::string& FILE_PATH_ID()
+  {
+    static const std::string MY_FILE_PATH_ID("file_path");
+    return MY_FILE_PATH_ID;
+  }
+  /// Default constructor
+  ExchangePlugin_ImportPart();
+
+  /// Returns the unique kind of a feature
+  EXCHANGEPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    return ExchangePlugin_ImportPart::ID();
+  }
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  EXCHANGEPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Computes or recomputes the results
+  EXCHANGEPLUGIN_EXPORT virtual void execute();
+
+  /// Returns true if this feature is used as macro: creates other features and then removed.
+  EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+
+  /// Reimplemented from ModelAPI_Feature::isPreviewNeeded(). Returns false.
+  EXCHANGEPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }
+};
+
+#endif /* EXCHANGEPLUGIN_IMPORTPART_H_ */
index 34c3c1b61a3f923ba84384e37867f86c1e235717..3d07a73cd645f9c3bf14b0a61dc3e9b8ed3f4e3f 100644 (file)
@@ -21,6 +21,8 @@
 #include <ExchangePlugin_Dump.h>
 #include <ExchangePlugin_ImportFeature.h>
 #include <ExchangePlugin_ExportFeature.h>
+#include <ExchangePlugin_ImportPart.h>
+#include <ExchangePlugin_ExportPart.h>
 #include <ExchangePlugin_Validators.h>
 
 #include <Config_PropManager.h>
@@ -53,6 +55,12 @@ FeaturePtr ExchangePlugin_Plugin::createFeature(std::string theFeatureID)
   if (theFeatureID == ExchangePlugin_ExportFeature::ID()) {
     return FeaturePtr(new ExchangePlugin_ExportFeature);
   } else
+  if (theFeatureID == ExchangePlugin_ImportPart::ID()) {
+    return FeaturePtr(new ExchangePlugin_ImportPart);
+  } else
+  if (theFeatureID == ExchangePlugin_ExportPart::ID()) {
+    return FeaturePtr(new ExchangePlugin_ExportPart);
+  } else
   if (theFeatureID == ExchangePlugin_Dump::ID()) {
     return FeaturePtr(new ExchangePlugin_Dump);
   }
diff --git a/src/ExchangePlugin/icons/export_part.png b/src/ExchangePlugin/icons/export_part.png
new file mode 100644 (file)
index 0000000..98e423e
Binary files /dev/null and b/src/ExchangePlugin/icons/export_part.png differ
diff --git a/src/ExchangePlugin/icons/import_part.png b/src/ExchangePlugin/icons/import_part.png
new file mode 100644 (file)
index 0000000..8443bd1
Binary files /dev/null and b/src/ExchangePlugin/icons/import_part.png differ
index 59a246ecdcbe081fbe1eaa540f736ffad1039893..8b8cd1a1d3bf3cea928b583a5fd025b706901a73 100644 (file)
              tooltip="To use geometrical order for identification of selected shapes"
              default="false"/> -->
       </feature>
+
+      <feature id="ImportPart" title="Import part" tooltip="Import features from file" icon="icons/Exchange/import_part.png"
+               helpfile="importPart.html"
+               internal="1">
+        <file_selector id="file_path" title="Import file" path="">
+          <validator id="ExchangePlugin_ImportFormat" parameters="shaperpart:Part" />
+        </file_selector>
+      </feature>
+      <feature id="ExportPart" title="Export part" tooltip="Export structure of the Part to file" icon="icons/Exchange/export_part.png"
+               helpfile="exportPart.html"
+               internal="1">
+        <export_file_selector id="file_path"
+                              type="save"
+                              title="Export file"
+                              path="">
+          <validator id="ExchangePlugin_ExportFormat"
+                     parameters="shaperpart:Part" />
+        </export_file_selector>
+        <multi_selector id="selection_list"
+                        tooltip="Select features or results"
+                        shape_types="Vertices Edges Faces Solids Compsolids Objects">
+        </multi_selector>
+      </feature>
     </group>
   </workbench>
 </plugin>
\ No newline at end of file
index 554b8c03a56b0d03c8040699d627ca1f5043565b..348761424e3bcb49e95e9bfc0c87dab64cd36e07 100644 (file)
@@ -53,6 +53,7 @@ SET(PROJECT_HEADERS
     Model_ResultField.h
     Model_ResultGroup.h
     Model_ResultParameter.h
+    Model_Tools.h
     Model_Update.h
     Model_Validator.h
 )
@@ -90,6 +91,7 @@ SET(PROJECT_SOURCES
     Model_ResultField.cpp
     Model_ResultGroup.cpp
     Model_ResultParameter.cpp
+    Model_Tools.cpp
     Model_Update.cpp
     Model_Validator.cpp
 )
index 6cfb6a3a38db0fce52b852cab4547a685ca39aaf..0d5e6eeb0c3bda1424481d14a9ae0bab13836bae 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <ModelAPI_Events.h>
 
+#include <PCDM_RetrievalDriver.hxx>
+
 IMPLEMENT_STANDARD_RTTIEXT(Model_Application, TDocStd_Application)
 
 static Handle_Model_Application TheApplication = new Model_Application;
@@ -168,6 +170,14 @@ Model_Application::Model_Application()
   // store handle to the application to avoid nullification
   static Handle(Model_Application) TheKeepHandle;
   TheKeepHandle = this;
+  // additional file format supported
+  static TCollection_ExtendedString THE_DOC_FORMAT("BinOcaf"/*"BinShaperPart"*/);
+  static TCollection_ExtendedString THE_FILE_EXT("shaperpart");
+  Handle(PCDM_RetrievalDriver) aReader =
+      Handle(PCDM_RetrievalDriver)::DownCast(TheKeepHandle->ReaderFromFormat("BinOcaf"));
+  Handle(PCDM_StorageDriver) aWriter = TheKeepHandle->WriterFromFormat("BinOcaf");
+  TheKeepHandle->DefineFormat(THE_DOC_FORMAT, "Shaper Part document", THE_FILE_EXT,
+                              aReader, aWriter);
 }
 
 //=======================================================================
index 10d11678d642420f5bde838baabe2072dce78114..45798a12fc36a93d98911e2e3cc0cfa6b8c0a38f 100644 (file)
@@ -35,6 +35,9 @@
 #include <Model_AttributeTables.h>
 #include <Model_Events.h>
 #include <Model_Expression.h>
+#include <Model_Tools.h>
+#include <Model_Validator.h>
+
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_Result.h>
 #include <ModelAPI_ResultParameter.h>
@@ -43,7 +46,6 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Tools.h>
-#include <Model_Validator.h>
 
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 
 #include <TDataStd_Name.hxx>
 #include <TDataStd_AsciiString.hxx>
-#include <TDataStd_IntegerArray.hxx>
 #include <TDataStd_UAttribute.hxx>
-#include <TDF_AttributeIterator.hxx>
-#include <TDF_ChildIterator.hxx>
-#include <TDF_RelocationTable.hxx>
 #include <TDF_ChildIDIterator.hxx>
-#include <TColStd_HArray1OfByte.hxx>
 
 #include <string>
 
@@ -797,37 +794,10 @@ void Model_Data::referencesToObjects(
   }
 }
 
-/// makes copy of all attributes on the given label and all sub-labels
-static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) {
-  TDF_AttributeIterator anAttrIter(theSource);
-  for(; anAttrIter.More(); anAttrIter.Next()) {
-    Handle(TDF_Attribute) aTargetAttr;
-    if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
-      // create a new attribute if not yet exists in the destination
-           aTargetAttr = anAttrIter.Value()->NewEmpty();
-      theDestination.AddAttribute(aTargetAttr);
-    }
-    // no special relocation, empty map, but self-relocation is on: copy references w/o changes
-    Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
-    anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
-    // an exception: if a source reference refers itself, a copy must also refer itself
-    if (aTargetAttr->ID() == TDF_Reference::GetID()) {
-      Handle(TDF_Reference) aTargetRef = Handle(TDF_Reference)::DownCast(aTargetAttr);
-      if (aTargetRef->Get().IsEqual(anAttrIter.Value()->Label()))
-        aTargetRef->Set(aTargetRef->Label());
-    }
-  }
-  // copy the sub-labels content
-  TDF_ChildIterator aSubLabsIter(theSource);
-  for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
-    copyAttrs(aSubLabsIter.Value(), theDestination.FindChild(aSubLabsIter.Value().Tag()));
-  }
-}
-
 void Model_Data::copyTo(std::shared_ptr<ModelAPI_Data> theTarget)
 {
   TDF_Label aTargetRoot = std::dynamic_pointer_cast<Model_Data>(theTarget)->label();
-  copyAttrs(myLab, aTargetRoot);
+  Model_Tools::copyAttrs(myLab, aTargetRoot);
   // reinitialize Model_Attributes by TDF_Attributes set
   std::shared_ptr<Model_Data> aTData = std::dynamic_pointer_cast<Model_Data>(theTarget);
   aTData->myAttrs.clear();
index be2877848b1a34b891a39b3dae19561fb94e780a..8773abc2ae44de88d0d4ee6aea2b643581a98334 100644 (file)
@@ -23,6 +23,7 @@
 #include <Model_Application.h>
 #include <Model_Session.h>
 #include <Model_Events.h>
+#include <Model_Tools.h>
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_CompositeFeature.h>
@@ -59,7 +60,7 @@
 #include <TNaming_Iterator.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Tool.hxx>
-#include<TNaming_OldShapeIterator.hxx>
+#include <TNaming_OldShapeIterator.hxx>
 #include <TopTools_DataMapOfShapeShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 
@@ -221,24 +222,20 @@ static void updateShapesFromRoot(const TDF_Label theThisAccess, const TDF_Label
 }
 // LCOV_EXCL_STOP
 
-bool Model_Document::load(const char* theDirName, const char* theFileName, DocumentPtr theThis)
+static bool loadDocument(Handle(Model_Application) theApp,
+                         Handle(TDocStd_Document)& theDoc,
+                         const TCollection_ExtendedString& theFilename)
 {
-  Handle(Model_Application) anApp = Model_Application::getApplication();
-  if (isRoot()) {
-    anApp->setLoadPath(theDirName);
-  }
-  TCollection_ExtendedString aPath(DocFileName(theDirName, theFileName));
-  PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus) -1;
-  Handle(TDocStd_Document) aLoaded;
+  PCDM_ReaderStatus aStatus = (PCDM_ReaderStatus)-1;
   try {
-    aStatus = anApp->Open(aPath, aLoaded);
+    aStatus = theApp->Open(theFilename, theDoc);
   } catch (Standard_Failure const& anException) {
     Events_InfoMessage("Model_Document",
         "Exception in opening of document: %1").arg(anException.GetMessageString()).send();
     return false;
   }
-  bool isError = aStatus != PCDM_RS_OK;
-  if (isError) {
+  bool isOk = aStatus == PCDM_RS_OK;
+  if (!isOk) {
     // LCOV_EXCL_START
     switch (aStatus) {
       case PCDM_RS_UnknownDocument:
@@ -296,9 +293,22 @@ bool Model_Document::load(const char* theDirName, const char* theFileName, Docum
     }
     // LCOV_EXCL_STOP
   }
+  return isOk;
+}
+
+bool Model_Document::load(const char* theDirName, const char* theFileName, DocumentPtr theThis)
+{
+  Handle(Model_Application) anApp = Model_Application::getApplication();
+  if (isRoot()) {
+    anApp->setLoadPath(theDirName);
+  }
+  TCollection_ExtendedString aPath(DocFileName(theDirName, theFileName));
+  Handle(TDocStd_Document) aLoaded;
+  bool isOk = loadDocument(anApp, aLoaded, aPath);
+
   std::shared_ptr<Model_Session> aSession =
     std::dynamic_pointer_cast<Model_Session>(Model_Session::get());
-  if (!isError) {
+  if (isOk) {
     myDoc = aLoaded;
     myDoc->SetUndoLimit(UNDO_LIMIT);
 
@@ -333,7 +343,89 @@ bool Model_Document::load(const char* theDirName, const char* theFileName, Docum
   } else { // open failed, but new document was created to work with it: inform the model
     aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false);
   }
-  return !isError;
+  return isOk;
+}
+
+bool Model_Document::import(const char* theFileName)
+{
+  Handle(Model_Application) anApp = Model_Application::getApplication();
+  TCollection_ExtendedString aFormat;
+  if (!anApp->Format(theFileName, aFormat))
+    return false;
+
+  Handle(TDocStd_Document) aTempDoc;
+  bool isOk = loadDocument(anApp, aTempDoc, theFileName);
+
+  // copy features from the temporary document to the current
+  Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
+  TDF_LabelList anAllNewFeatures;
+  // Perform the copying twice for correct references:
+  // 1. copy labels hierarchy and fill the relocation table
+  TDF_Label aMain = myDoc->Main();
+  for (TDF_ChildIterator anIt(aTempDoc->Main()); anIt.More(); anIt.Next()) {
+    TDF_Label aCurrentLab = anIt.Value();
+    Handle(TDataStd_Comment) aFeatureID;
+    TDF_Label aNewFeatuerLab;
+    if (aCurrentLab.FindAttribute(TDataStd_Comment::GetID(), aFeatureID)) {
+      TCollection_AsciiString anID(aFeatureID->Get());
+      FeaturePtr aNewFeature = addFeature(anID.ToCString());
+      std::shared_ptr<Model_Data> aData =
+          std::dynamic_pointer_cast<Model_Data>(aNewFeature->data());
+      aNewFeatuerLab = aData->label().Father();
+      Model_Tools::copyLabels(aCurrentLab, aNewFeatuerLab, aRelocTable);
+    }
+    anAllNewFeatures.Append(aNewFeatuerLab);
+  }
+  // 2. copy attributes
+  TDF_ListIteratorOfLabelList aNewIt(anAllNewFeatures);
+  for (TDF_ChildIterator anIt(aTempDoc->Main()); anIt.More(); anIt.Next()) {
+    TDF_Label aCurrentLab = anIt.Value();
+    TDF_Label aFeatureLab = aNewIt.Value();
+    if (aFeatureLab.IsNull())
+      anAllNewFeatures.Remove(aNewIt);
+    else {
+      Model_Tools::copyAttrs(aCurrentLab, aFeatureLab, aRelocTable);
+      aNewIt.Next();
+    }
+  }
+
+  myObjs->synchronizeFeatures(anAllNewFeatures, true, false, false, true);
+
+  if (aTempDoc->CanClose() == CDM_CCS_OK)
+    aTempDoc->Close();
+  return isOk;
+}
+
+static bool saveDocument(Handle(Model_Application) theApp,
+                         Handle(TDocStd_Document) theDoc,
+                         const TCollection_ExtendedString& theFilename)
+{
+  PCDM_StoreStatus aStatus;
+  try {
+    aStatus = theApp->SaveAs(theDoc, theFilename);
+  }
+  catch (Standard_Failure const& anException) {
+    Events_InfoMessage("Model_Document",
+      "Exception in saving of document: %1").arg(anException.GetMessageString()).send();
+    return false;
+  }
+  bool isDone = aStatus == PCDM_SS_OK || aStatus == PCDM_SS_No_Obj;
+  if (!isDone) {
+    switch (aStatus) {
+    case PCDM_SS_DriverFailure:
+      Events_InfoMessage("Model_Document",
+        "Can not save document: save driver-library failure").send();
+      break;
+    case PCDM_SS_WriteFailure:
+      Events_InfoMessage("Model_Document", "Can not save document: file writing failure").send();
+      break;
+    case PCDM_SS_Failure:
+    default:
+      Events_InfoMessage("Model_Document", "Can not save document").send();
+      break;
+    }
+  }
+  return isDone;
 }
 
 bool Model_Document::save(
@@ -374,34 +466,7 @@ bool Model_Document::save(
   }
   // filename in the dir is id of document inside of the given directory
   TCollection_ExtendedString aPath(DocFileName(theDirName, theFileName));
-  PCDM_StoreStatus aStatus;
-  try {
-    aStatus = anApp->SaveAs(myDoc, aPath);
-  } catch (Standard_Failure const& anException) {
-    Events_InfoMessage("Model_Document",
-        "Exception in saving of document: %1").arg(anException.GetMessageString()).send();
-    if (aWasCurrent.get()) { // return the current feature to the initial position
-      setCurrentFeature(aWasCurrent, false);
-      aSession->setCheckTransactions(true);
-    }
-    return false;
-  }
-  bool isDone = aStatus == PCDM_SS_OK || aStatus == PCDM_SS_No_Obj;
-  if (!isDone) {
-    switch (aStatus) {
-      case PCDM_SS_DriverFailure:
-        Events_InfoMessage("Model_Document",
-                           "Can not save document: save driver-library failure").send();
-        break;
-      case PCDM_SS_WriteFailure:
-        Events_InfoMessage("Model_Document", "Can not save document: file writing failure").send();
-        break;
-      case PCDM_SS_Failure:
-      default:
-        Events_InfoMessage("Model_Document", "Can not save document").send();
-        break;
-    }
-  }
+  bool isDone = saveDocument(anApp, myDoc, aPath);
 
   if (aWasCurrent.get()) { // return the current feature to the initial position
     setCurrentFeature(aWasCurrent, false);
@@ -444,6 +509,41 @@ bool Model_Document::save(
   return isDone;
 }
 
+bool Model_Document::save(const char* theFilename,
+                          const std::list<FeaturePtr>& theExportFeatures) const
+{
+  Handle(Model_Application) anApp = Model_Application::getApplication();
+  TCollection_ExtendedString aFormat;
+  if (!anApp->Format(theFilename, aFormat))
+    return false;
+
+  Handle(TDocStd_Document) aTempDoc = new TDocStd_Document(aFormat);
+  TDF_Label aMain = aTempDoc->Main();
+
+  Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
+  std::list<FeaturePtr>::const_iterator anIt = theExportFeatures.begin();
+  // Perform the copying twice for correct references:
+  // 1. copy labels hierarchy and fill the relocation table
+  for (; anIt != theExportFeatures.end(); ++anIt) {
+    TDF_Label aFeatureLab = aMain.NewChild();
+    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>((*anIt)->data());
+    Model_Tools::copyLabels(aData->label().Father(), aFeatureLab, aRelocTable);
+  }
+  // 2. copy attributes
+  TDF_ChildIterator aChildIt(aMain);
+  for (anIt = theExportFeatures.begin(); anIt != theExportFeatures.end(); ++anIt) {
+    TDF_Label aFeatureLab = aChildIt.Value();
+    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>((*anIt)->data());
+    Model_Tools::copyAttrs(aData->label().Father(), aFeatureLab, aRelocTable);
+    aChildIt.Next();
+  }
+
+  bool isDone = saveDocument(anApp, aTempDoc, theFilename);
+  if (aTempDoc->CanClose() == CDM_CCS_OK)
+    aTempDoc->Close();
+  return isDone;
+}
+
 void Model_Document::close(const bool theForever)
 {
   std::shared_ptr<ModelAPI_Session> aPM = Model_Session::get();
index 72a570738b5080a167838dc2fa0830d3f43eeebf..2cf44cbd0bcdb7b1d6eadf65e7036cf8d7977138 100644 (file)
@@ -56,6 +56,12 @@ class Model_Document : public ModelAPI_Document
   MODEL_EXPORT virtual bool load(
     const char* theDirName, const char* theFileName, DocumentPtr theThis);
 
+  //! Loads the OCAF document from the file into the current document.
+  //! All the features are added after the active feature.
+  //! \param theFileName name of the file to import
+  //! \returns true if file was loaded successfully
+  MODEL_EXPORT virtual bool import(const char* theFileName);
+
   //! Saves the OCAF document to the file.
   //! \param theDirName directory where the document will be saved
   //! \param theFileName a name of the document file to store
@@ -64,6 +70,12 @@ class Model_Document : public ModelAPI_Document
   MODEL_EXPORT virtual bool save(
     const char* theDirName, const char* theFileName, std::list<std::string>& theResults);
 
+  //! Export the list of features to the file
+  //! \param theFilename path to save the file
+  //! \param theExportFeatures list of features to export
+  MODEL_EXPORT virtual bool save(const char* theFilename,
+    const std::list<std::shared_ptr<ModelAPI_Feature> >& theExportFeatures) const;
+
   //! Removes document data
   //! \param theForever if it is false, document is just hidden
   //!                   (to keep possibility make it back on Undo/Redo)
diff --git a/src/Model/Model_Tools.cpp b/src/Model/Model_Tools.cpp
new file mode 100644 (file)
index 0000000..33bafd0
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright (C) 2014-2019  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
+//
+
+#include <Model_Tools.h>
+
+#include <Standard_GUID.hxx>
+
+#include <TDF_AttributeIterator.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDF_Reference.hxx>
+#include <TDF_RelocationTable.hxx>
+
+void Model_Tools::copyLabels(TDF_Label theSource, TDF_Label theDestination,
+                             Handle(TDF_RelocationTable) theRelocTable)
+{
+  theRelocTable->SetRelocation(theSource, theDestination);
+  // copy the sub-labels hierarchy
+  TDF_ChildIterator aSubLabsIter(theSource);
+  for (; aSubLabsIter.More(); aSubLabsIter.Next()) {
+    copyLabels(aSubLabsIter.Value(),
+               theDestination.FindChild(aSubLabsIter.Value().Tag()),
+               theRelocTable);
+  }
+}
+
+void Model_Tools::copyAttrs(TDF_Label theSource, TDF_Label theDestination,
+                            Handle(TDF_RelocationTable) theRelocTable)
+{
+  TDF_AttributeIterator anAttrIter(theSource);
+  for(; anAttrIter.More(); anAttrIter.Next()) {
+    Handle(TDF_Attribute) aTargetAttr;
+    if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
+      // create a new attribute if not yet exists in the destination
+           aTargetAttr = anAttrIter.Value()->NewEmpty();
+      theDestination.AddAttribute(aTargetAttr);
+    }
+    // no special relocation, empty map, but self-relocation is on: copy references w/o changes
+    Handle(TDF_RelocationTable) aRelocTable =
+        theRelocTable.IsNull() ? new TDF_RelocationTable(Standard_True) : theRelocTable;
+    anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
+    // an exception: if a source reference refers itself, a copy must also refer itself
+    if (aTargetAttr->ID() == TDF_Reference::GetID()) {
+      Handle(TDF_Reference) aTargetRef = Handle(TDF_Reference)::DownCast(aTargetAttr);
+      if (aTargetRef->Get().IsEqual(anAttrIter.Value()->Label()))
+        aTargetRef->Set(aTargetRef->Label());
+    }
+  }
+  // copy the sub-labels content
+  TDF_ChildIterator aSubLabsIter(theSource);
+  for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
+    copyAttrs(aSubLabsIter.Value(),
+              theDestination.FindChild(aSubLabsIter.Value().Tag()),
+              theRelocTable);
+  }
+}
diff --git a/src/Model/Model_Tools.h b/src/Model/Model_Tools.h
new file mode 100644 (file)
index 0000000..b1d79a5
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2014-2019  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
+//
+
+#ifndef Model_Tools_H_
+#define Model_Tools_H_
+
+#include <Model.h>
+
+#include <TDF_Label.hxx>
+#include <TDF_RelocationTable.hxx>
+
+/// A collection of methods useful for different parts of data model.
+namespace Model_Tools
+{
+  /// makes copy of label and all its sub-labels without copying the attributes;
+  /// and feel the relocation table
+  void copyLabels(TDF_Label theSource, TDF_Label theDestination,
+                  Handle(TDF_RelocationTable) theRelocTable);
+
+  /// makes copy of all attributes on the given label and all sub-labels
+  void copyAttrs(TDF_Label theSource, TDF_Label theDestination,
+                 Handle(TDF_RelocationTable) theRelocTable = Handle(TDF_RelocationTable)());
+};
+
+#endif
index 9cc95bad2be1874f0205d34a714ba8fb5cea26ce..101910fc62aeb06dbfb2dcb5a79363409624c75f 100644 (file)
@@ -259,6 +259,18 @@ public:
   MODELAPI_EXPORT virtual std::shared_ptr<ModelAPI_Feature> nextFeature(
     std::shared_ptr<ModelAPI_Feature> theCurrent, const bool theReverse = false) const = 0;
 
+  /// Loads the OCAF document from the file into the current document.
+  /// All the features are added after the active feature.
+  /// \param theFileName name of the file to import
+  /// \returns true if file was loaded successfully
+  MODELAPI_EXPORT virtual bool import(const char* theFileName) = 0;
+
+  /// Export the list of features to the file
+  /// \param theFilename path to save the file
+  /// \param theExportFeatures list of features to export
+  MODELAPI_EXPORT virtual bool save(const char* theFilename,
+    const std::list<std::shared_ptr<ModelAPI_Feature> >& theExportFeatures) const = 0;
+
 protected:
   //! Only for SWIG wrapping it is here
   MODELAPI_EXPORT ModelAPI_Document();
index cf51cc8b29ba01c777d4a5db8cf68cf33d18d8f7..ac49c4ae1481fc095b88f46e220b1991cb398e84 100644 (file)
@@ -199,6 +199,7 @@ ADD_DEFINITIONS( -DXGUI_EXPORTS ${OpenCASCADE_DEFINITIONS} -D_CRT_SECURE_NO_WARN
 SET(PROJECT_INCLUDES
     ${PROJECT_SOURCE_DIR}/src/Events
     ${PROJECT_SOURCE_DIR}/src/Config
+    ${PROJECT_SOURCE_DIR}/src/ExchangePlugin
     ${PROJECT_SOURCE_DIR}/src/ModelAPI
     ${PROJECT_SOURCE_DIR}/src/GeomAPI
     ${PROJECT_SOURCE_DIR}/src/ModuleBase
index 3e552186df412c9db79d1f4484239e18c2992397..8198f5f1131d2dd80e5f329d87c23deb907ccf9c 100644 (file)
@@ -67,6 +67,7 @@
 #include <ModelAPI_AttributeDocRef.h>
 #include <ModelAPI_AttributeIntArray.h>
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Feature.h>
@@ -87,6 +88,9 @@
 #include <Events_InfoMessage.h>
 #include <Events_LongOp.h>
 
+#include <ExchangePlugin_ExportPart.h>
+#include <ExchangePlugin_ImportPart.h>
+
 #include <GeomAPI_Pnt.h>
 
 #include <ModuleBase_IModule.h>
@@ -183,6 +187,8 @@ static QString MyFilter2(QObject::tr("CAD Builder files (*.cadbld)"));
 static QString MyExtension(".cadbld");
 #endif
 
+static QString MyImportPartFilter(QObject::tr("Part files (*.shaperpart);;All files (*.*)"));
+
 
 //******************************************************
 XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector)
@@ -470,6 +476,19 @@ void XGUI_Workshop::initMenu()
   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onOpen()));
   salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE");
 
+  aAction = salomeConnector()->addDesktopCommand("EXPORT_PART_CMD", tr("Export part..."),
+                                          tr("Export a part of the current document into a file"),
+                                          QIcon(), QKeySequence(),
+                                          false, "MEN_DESK_FILE");
+  connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onExportPart()));
+
+  aAction = salomeConnector()->addDesktopCommand("IMPORT_PART_CMD", tr("Import part..."),
+                                          tr("Import structure of a part"),
+                                          QIcon(), QKeySequence(),
+                                          false, "MEN_DESK_FILE");
+  connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportPart()));
+  salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE");
+
 #else
   // File commands group
   AppElements_MenuGroupPanel* aGroup = myMainWindow->menuObject()->generalPage();
@@ -1243,6 +1262,42 @@ void XGUI_Workshop::onWidgetObjectUpdated()
   myDisplayer->updateViewer();
 }
 
+//******************************************************
+void XGUI_Workshop::onImportPart()
+{
+  if (!abortAllOperations())
+    return;
+
+  //show file dialog, check if readable and open
+  qreal aRatio = ModuleBase_Tools::currentPixelRatio();
+  // If the ratio is > 1 (HD screen) then QT has a bug in
+  // displaying of system open file dialog (too small)
+  QString aFile = QFileDialog::getOpenFileName(desktop(), tr("Import part"), QString(),
+        MyImportPartFilter, Q_NULLPTR,
+        ((aRatio > 1) ? QFileDialog::DontUseNativeDialog : QFileDialog::Options()));
+  if (!aFile.isNull()) {
+    ModuleBase_OperationFeature* anImportPartOp = dynamic_cast<ModuleBase_OperationFeature*>(
+        module()->createOperation(ExchangePlugin_ImportPart::ID()));
+    if (operationMgr()->startOperation(anImportPartOp)) {
+      // initialize the filename to be imported
+      FeaturePtr aFeature = anImportPartOp->feature();
+      aFeature->string(ExchangePlugin_ImportPart::FILE_PATH_ID())->setValue(aFile.toStdString());
+      ModuleBase_Tools::flushUpdated(aFeature);
+      operationMgr()->commitOperation();
+    }
+  }
+}
+
+//******************************************************
+void XGUI_Workshop::onExportPart()
+{
+  if (abortAllOperations()) {
+    ModuleBase_OperationFeature* anExportPartOp = dynamic_cast<ModuleBase_OperationFeature*>(
+        module()->createOperation(ExchangePlugin_ExportPart::ID()));
+    operationMgr()->startOperation(anExportPartOp);
+  }
+}
+
 //******************************************************
 ModuleBase_IModule* XGUI_Workshop::loadModule(const QString& theModule)
 {
index 982758244fa3eecb338fcb879d0e8d3b037573fc..1bf77ba3f64671aaf395bf345b69da750ff2282a 100644 (file)
@@ -397,6 +397,12 @@ signals:
   /// Create a new document
   void onNew();
 
+  /// Import part structure from a file
+  void onImportPart();
+
+  /// Export features to a file
+  void onExportPart();
+
 #ifndef HAVE_SALOME
   /// Exit application
   void onExit();