Salome HOME
Issue #3138: "Import" feature improvement
authorvsv <vsv@opencascade.com>
Thu, 6 Feb 2020 14:12:31 +0000 (17:12 +0300)
committervsr <vsr@opencascade.com>
Mon, 10 Feb 2020 14:15:57 +0000 (17:15 +0300)
src/ExchangePlugin/CMakeLists.txt
src/ExchangePlugin/ExchangePlugin_Import.cpp [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_Import.h [new file with mode: 0644]
src/ExchangePlugin/ExchangePlugin_Plugin.cpp
src/ExchangePlugin/plugin-Exchange.xml
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index 83a6dd5702c79a2945df917a20c5df4736633365..4a9c594161def51bc3d8bd7ed70d5145a014b303 100644 (file)
@@ -42,6 +42,7 @@ SET(PROJECT_HEADERS
     ExchangePlugin_Dump.h
     ExchangePlugin_ImportPart.h
     ExchangePlugin_ExportPart.h
+    ExchangePlugin_Import.h
 )
 
 SET(PROJECT_SOURCES
@@ -53,6 +54,7 @@ SET(PROJECT_SOURCES
     ExchangePlugin_Dump.cpp
     ExchangePlugin_ImportPart.cpp
     ExchangePlugin_ExportPart.cpp
+    ExchangePlugin_Import.cpp
 )
 
 SET(XML_RESOURCES
diff --git a/src/ExchangePlugin/ExchangePlugin_Import.cpp b/src/ExchangePlugin/ExchangePlugin_Import.cpp
new file mode 100644 (file)
index 0000000..0f22369
--- /dev/null
@@ -0,0 +1,160 @@
+// 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_Import.h"
+#include "ExchangePlugin_ImportFeature.h"
+
+#include <PartSetPlugin_Part.h>
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeStringArray.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_Tools.h>
+
+
+static const std::string THE_NEW_PART_STR("New Part");
+
+DocumentPtr findDocument(DocumentPtr thePartSetDoc, const std::string& thePartName)
+{
+  DocumentPtr aDoc;
+  FeaturePtr aPartFeature;
+  if (thePartName == THE_NEW_PART_STR) {
+    // create new part
+    aPartFeature = thePartSetDoc->addFeature(PartSetPlugin_Part::ID());
+    if (aPartFeature)
+      aPartFeature->execute();
+  }
+  else {
+    // find existing part by its name
+    std::list<FeaturePtr> aSubFeatures = thePartSetDoc->allFeatures();
+    for (std::list<FeaturePtr>::iterator aFIt = aSubFeatures.begin();
+      aFIt != aSubFeatures.end(); ++aFIt) {
+      if ((*aFIt)->getKind() == PartSetPlugin_Part::ID() && (*aFIt)->name() == thePartName) {
+        aPartFeature = *aFIt;
+        break;
+      }
+    }
+  }
+
+  if (aPartFeature) {
+    ResultPartPtr aPartResult =
+      std::dynamic_pointer_cast<ModelAPI_ResultPart>(aPartFeature->lastResult());
+    if (aPartResult)
+      aDoc = aPartResult->partDoc();
+  }
+  return aDoc;
+}
+
+
+ExchangePlugin_Import::ExchangePlugin_Import()
+{
+}
+
+ExchangePlugin_Import::~ExchangePlugin_Import()
+{
+  // TODO Auto-generated destructor stub
+}
+
+/*
+ * Request for initialization of data model of the feature: adding all attributes
+ */
+void ExchangePlugin_Import::initAttributes()
+{
+  data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(TARGET_PART_ID(), ModelAPI_AttributeInteger::typeId());
+  data()->addAttribute(TARGET_PARTS_LIST_ID(), ModelAPI_AttributeStringArray::typeId());
+}
+
+/*
+ * Computes or recomputes the results
+ */
+void ExchangePlugin_Import::execute()
+{
+  AttributeStringPtr aFilePathAttr = string(ExchangePlugin_Import::FILE_PATH_ID());
+  std::string aFilePath = aFilePathAttr->value();
+  if (aFilePath.empty()) {
+    setError("File path is empty.");
+    return;
+  }
+
+  // get the document where to import
+  AttributeStringArrayPtr aPartsAttr = stringArray(TARGET_PARTS_LIST_ID());
+  AttributeIntegerPtr aTargetAttr = integer(TARGET_PART_ID());
+  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr aDoc =
+    findDocument(aSession->moduleDocument(), aPartsAttr->value(aTargetAttr->value()));
+
+  if (aDoc.get()) {
+    FeaturePtr aImportFeature = aDoc->addFeature(ExchangePlugin_ImportFeature::ID());
+    DataPtr aData = aImportFeature->data();
+    AttributeStringPtr aPathAttr = aData->string(ExchangePlugin_ImportFeature::FILE_PATH_ID());
+    aPathAttr->setValue(aFilePathAttr->value());
+    aImportFeature->execute();
+  }
+}
+
+
+void ExchangePlugin_Import::attributeChanged(const std::string& theID)
+{
+  if (theID == FILE_PATH_ID()) {
+    AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
+    if (aFilePathAttr->value().empty())
+      return;
+
+    AttributeStringArrayPtr aPartsAttr = stringArray(TARGET_PARTS_LIST_ID());
+    AttributeIntegerPtr aTargetAttr = integer(TARGET_PART_ID());
+
+    // update the list of target parts
+    SessionPtr aSession = ModelAPI_Session::get();
+    DocumentPtr aDoc = document();
+    bool isPartSet = aDoc == aSession->moduleDocument();
+    if (isPartSet) {
+      std::list<std::string> anAcceptedValues;
+      anAcceptedValues.push_back(THE_NEW_PART_STR);
+
+      // append names of all parts
+      std::list<FeaturePtr> aSubFeatures = aDoc->allFeatures();
+      for (std::list<FeaturePtr>::iterator aFIt = aSubFeatures.begin();
+        aFIt != aSubFeatures.end(); ++aFIt) {
+        if ((*aFIt)->getKind() == PartSetPlugin_Part::ID())
+          anAcceptedValues.push_back((*aFIt)->name());
+      }
+
+      if (aPartsAttr->size() != anAcceptedValues.size())
+        aTargetAttr->setValue(0);
+
+      aPartsAttr->setSize((int)anAcceptedValues.size());
+      std::list<std::string>::iterator anIt = anAcceptedValues.begin();
+      for (int anInd = 0; anIt != anAcceptedValues.end(); ++anIt, ++anInd)
+        aPartsAttr->setValue(anInd, *anIt);
+    }
+    else {
+      // keep only the name of the current part
+      if (aPartsAttr->size() == 0) {
+        FeaturePtr aPartFeature = ModelAPI_Tools::findPartFeature(aSession->moduleDocument(), aDoc);
+
+        aPartsAttr->setSize(1);
+        aPartsAttr->setValue(0, aPartFeature->name());
+        aTargetAttr->setValue(0);
+      }
+    }
+  }
+}
diff --git a/src/ExchangePlugin/ExchangePlugin_Import.h b/src/ExchangePlugin/ExchangePlugin_Import.h
new file mode 100644 (file)
index 0000000..7869483
--- /dev/null
@@ -0,0 +1,92 @@
+// 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_IMPORT_H_
+#define EXCHANGEPLUGIN_IMPORT_H_
+
+#include "ExchangePlugin.h"
+
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Result.h>
+
+#include <map>
+
+/**
+ * \class ExchangePlugin_ImportFeature
+ * \ingroup Plugins
+ * \brief Feature for import shapes from the external files in CAD formats.
+ *
+ * The list of supported formats is defined in the configuration file.
+ */
+class ExchangePlugin_Import : public ModelAPI_Feature
+{
+ public:
+  /// Feature kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_IMPORT_ID("ImportMacro");
+    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;
+  }
+  /// attribute name of target part
+  inline static const std::string& TARGET_PART_ID()
+  {
+    static const std::string MY_TARGET_PART_ID("target_part");
+    return MY_TARGET_PART_ID;
+  }
+  /// attribute name of list of target parts
+  inline static const std::string& TARGET_PARTS_LIST_ID()
+  {
+    static const std::string MY_TARGET_PARTS_LIST_ID("target_parts_list");
+    return MY_TARGET_PARTS_LIST_ID;
+  }
+  /// Default constructor
+  EXCHANGEPLUGIN_EXPORT ExchangePlugin_Import();
+  /// Default destructor
+  EXCHANGEPLUGIN_EXPORT virtual ~ExchangePlugin_Import();
+
+  /// Returns the unique kind of a feature
+  EXCHANGEPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    return ExchangePlugin_Import::ID();
+  }
+
+  /// Request for initialization of data model of the feature: adding all attributes
+  EXCHANGEPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Called on change of any argument-attribute of this object
+  /// \param theID identifier of changed attribute
+  EXCHANGEPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+  /// 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 /* IMPORT_IMPORTFEATURE_H_ */
index ccb5439e7b331337437d4a8b17ad19d2a0586693..078b50873657489c73580b1ff196f966f1d8cc2f 100644 (file)
@@ -23,6 +23,7 @@
 #include <ExchangePlugin_ExportFeature.h>
 #include <ExchangePlugin_ImportPart.h>
 #include <ExchangePlugin_ExportPart.h>
+#include <ExchangePlugin_Import.h>
 #include <ExchangePlugin_Validators.h>
 
 #include <Config_PropManager.h>
@@ -65,6 +66,9 @@ FeaturePtr ExchangePlugin_Plugin::createFeature(std::string theFeatureID)
   } else
   if (theFeatureID == ExchangePlugin_Dump::ID()) {
     return FeaturePtr(new ExchangePlugin_Dump);
+  } else
+  if (theFeatureID == ExchangePlugin_Import::ID()) {
+    return FeaturePtr(new ExchangePlugin_Import);
   }
   // feature of such kind is not found
   return FeaturePtr();
index ac0ad0711fc51012eed6a3f00254d01aaaaa232a..f6248194572dc893fb1fb65b91e99adfd10a415e 100644 (file)
@@ -1,8 +1,20 @@
 <plugin>
   <workbench id="Part">
     <group id="Exchange">
-      <feature id="Import" title="Import" tooltip="Import a file" icon="icons/Exchange/import.png" document="Part"
-               helpfile="importFeature.html">
+      <feature id="ImportMacro" title="Import" tooltip="Import a file" icon="icons/Exchange/import.png"
+               helpfile="importFeature.html"
+               internal="1">
+        <file_selector id="file_path" title="Import file" path="">
+          <validator id="ExchangePlugin_ImportFormat" parameters="BREP|BRP:BREP,STEP|STP:STEP,IGES|IGS:IGES,XAO:XAO" />
+        </file_selector>
+        <choice id="target_part"
+                string_list_attribute="target_parts_list"
+                label="Import to"
+                tooltip="Select the part to import the document" />
+      </feature>
+      <feature id="Import" title="Import" tooltip="Import a file" icon="icons/Exchange/import.png"
+               helpfile="importFeature.html"
+               internal="1">
         <file_selector id="file_path" title="Import file" path="">
           <validator id="ExchangePlugin_ImportFormat" parameters="BREP|BRP:BREP,STEP|STP:STEP,IGES|IGS:IGES,XAO:XAO" />
         </file_selector>
index 0b587f157be4582fc72091862fd9f7159c6a27ae..e7dcbfc72ac92d1569dc4fe0c05490a0456a615f 100644 (file)
@@ -80,6 +80,7 @@
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_Tools.h>
 #include <ModelAPI_ResultField.h>
+#include <ModuleBase_IconFactory.h>
 
 //#include <PartSetPlugin_Part.h>
 
@@ -89,6 +90,7 @@
 
 #include <ExchangePlugin_ExportPart.h>
 #include <ExchangePlugin_ImportPart.h>
+#include <ExchangePlugin_Import.h>
 
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_ShapeExplorer.h>
@@ -491,6 +493,13 @@ void XGUI_Workshop::initMenu()
                                           QIcon(), QKeySequence(),
                                           false, "MEN_DESK_FILE");
   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportPart()));
+
+  aAction = salomeConnector()->addDesktopCommand("IMPORT_SHAPE_CMD", tr("Import shape..."),
+    tr("Import shape from a file"),
+    ModuleBase_IconFactory::loadIcon("icons/Exchange/import.png"),
+    QKeySequence(), false, "MEN_DESK_FILE");
+  connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onImportShape()));
+
   salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE");
 
 #else
@@ -1297,6 +1306,16 @@ void XGUI_Workshop::onImportPart()
   }
 }
 
+//******************************************************
+void XGUI_Workshop::onImportShape()
+{
+  if (abortAllOperations()) {
+    ModuleBase_OperationFeature* anImportOp = dynamic_cast<ModuleBase_OperationFeature*>(
+        module()->createOperation(ExchangePlugin_Import::ID()));
+    operationMgr()->startOperation(anImportOp);
+  }
+}
+
 //******************************************************
 void XGUI_Workshop::onExportPart()
 {
index 37ae6a8a2be07ea5265ba5463d38f4670c141f45..45f9d4a6e7342d3004fc41e6b6b34e77c02d4998 100644 (file)
@@ -401,6 +401,9 @@ signals:
   /// Import part structure from a file
   void onImportPart();
 
+  /// Import part structure from a file
+  void onImportShape();
+
   /// Export features to a file
   void onExportPart();