Salome HOME
Initial implementation of Import Result feature.
authormpv <mpv@opencascade.com>
Mon, 27 Jan 2020 13:49:10 +0000 (16:49 +0300)
committermpv <mpv@opencascade.com>
Mon, 27 Jan 2020 13:49:10 +0000 (16:49 +0300)
26 files changed:
src/FeaturesAPI/CMakeLists.txt
src/FeaturesAPI/FeaturesAPI.i
src/FeaturesAPI/FeaturesAPI_Copy.h
src/FeaturesAPI/FeaturesAPI_ImportResult.cpp [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_ImportResult.h [new file with mode: 0644]
src/FeaturesAPI/FeaturesAPI_swig.h
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_ImportResult.cpp [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_ImportResult.h [new file with mode: 0644]
src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp
src/FeaturesPlugin/FeaturesPlugin_msg_fr.ts
src/FeaturesPlugin/Test/TestImportResult.py [new file with mode: 0644]
src/FeaturesPlugin/doc/FeaturesPlugin.rst
src/FeaturesPlugin/doc/TUI_importResultFeature.rst [new file with mode: 0644]
src/FeaturesPlugin/doc/examples/import_result.py [new file with mode: 0644]
src/FeaturesPlugin/doc/images/CreatedImportResult.png [new file with mode: 0644]
src/FeaturesPlugin/doc/images/ImportResult.png [new file with mode: 0644]
src/FeaturesPlugin/doc/images/import_result_btn.png [new file with mode: 0644]
src/FeaturesPlugin/doc/importResultFeature.rst [new file with mode: 0644]
src/FeaturesPlugin/icons/import_result.png [new file with mode: 0644]
src/FeaturesPlugin/import_result_widget.xml [new file with mode: 0644]
src/FeaturesPlugin/plugin-Features.xml
src/Model/Model_AttributeReference.cpp
src/Model/Model_AttributeSelection.cpp
src/ModuleBase/ModuleBase_ViewerFilters.cpp
src/PythonAPI/model/features/__init__.py

index dbdb6bc5b388d7926537c898e7f2ac04651da234..921b2eec785f6bdb58b940705b9a2a52ab3c1bcc 100644 (file)
@@ -49,6 +49,7 @@ SET(PROJECT_HEADERS
   FeaturesAPI_Union.h
   FeaturesAPI_FusionFaces.h
   FeaturesAPI_Copy.h
+  FeaturesAPI_ImportResult.h
 )
 
 SET(PROJECT_SOURCES
@@ -80,6 +81,7 @@ SET(PROJECT_SOURCES
   FeaturesAPI_Union.cpp
   FeaturesAPI_FusionFaces.cpp
   FeaturesAPI_Copy.cpp
+  FeaturesAPI_ImportResult.cpp
 )
 
 SET(PROJECT_LIBRARIES
index 9ed6db0d36611bac85dad93aa0d4e611d6535ef5..41999dee9d046104a61c665faa65ee525b38842d 100644 (file)
@@ -78,6 +78,7 @@
 %shared_ptr(FeaturesAPI_FusionFaces)
 %shared_ptr(FeaturesAPI_RemoveResults)
 %shared_ptr(FeaturesAPI_Copy)
+%shared_ptr(FeaturesAPI_ImportResult)
 
 
 %typecheck(SWIG_TYPECHECK_POINTER) std::pair<std::list<ModelHighAPI_Selection>, bool>, const std::pair<std::list<ModelHighAPI_Selection>, bool> & {
 %include "FeaturesAPI_FusionFaces.h"
 %include "FeaturesAPI_RemoveResults.h"
 %include "FeaturesAPI_Copy.h"
+%include "FeaturesAPI_ImportResult.h"
index 92174f9f407e20ce8d8ce4fe936942e684922acf..1fa43de5bc54c5a43db1c72f172528835ddac886 100644 (file)
@@ -44,7 +44,7 @@ public:
   FEATURESAPI_EXPORT
   explicit FeaturesAPI_Copy(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                             const std::list<ModelHighAPI_Selection>& theBaseObjects,
-                            const int theVersion = 0);
+                            const int theNumber);
 
   /// Destructor.
   FEATURESAPI_EXPORT virtual ~FeaturesAPI_Copy();
diff --git a/src/FeaturesAPI/FeaturesAPI_ImportResult.cpp b/src/FeaturesAPI/FeaturesAPI_ImportResult.cpp
new file mode 100644 (file)
index 0000000..cf72de3
--- /dev/null
@@ -0,0 +1,70 @@
+// 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 "FeaturesAPI_ImportResult.h"
+
+#include <ModelHighAPI_Dumper.h>
+#include <ModelHighAPI_Tools.h>
+
+//================================================================================================
+FeaturesAPI_ImportResult::FeaturesAPI_ImportResult(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature) : ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+}
+
+//================================================================================================
+FeaturesAPI_ImportResult::FeaturesAPI_ImportResult(
+  const std::shared_ptr<ModelAPI_Feature>& theFeature,
+  const std::list<ModelHighAPI_Selection>& theObjects) : ModelHighAPI_Interface(theFeature)
+{
+  if(initialize()) {
+    setObjects(theObjects);
+  }
+}
+
+//=================================================================================================
+FeaturesAPI_ImportResult::~FeaturesAPI_ImportResult() {}
+
+//=================================================================================================
+void FeaturesAPI_ImportResult::setObjects(const std::list<ModelHighAPI_Selection>& theObjects)
+{
+  fillAttribute(theObjects, myobjects);
+  execute();
+}
+
+//=================================================================================================
+void FeaturesAPI_ImportResult::dump(ModelHighAPI_Dumper& theDumper) const
+{
+  FeaturePtr aBase = feature();
+  const std::string& aDocName = theDumper.name(aBase->document());
+  AttributeSelectionListPtr anObjects =
+    aBase->selectionList(FeaturesPlugin_ImportResult::OBJECTS());
+
+  theDumper << aBase << " = model.addImportResult("
+            << aDocName << ", " << anObjects << ")" << std::endl;
+}
+
+//=================================================================================================
+ImportResultPtr addImportResult(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                const std::list<ModelHighAPI_Selection>& theObjects)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_ImportResult::ID());
+  return ImportResultPtr(new FeaturesAPI_ImportResult(aFeature, theObjects));
+}
diff --git a/src/FeaturesAPI/FeaturesAPI_ImportResult.h b/src/FeaturesAPI/FeaturesAPI_ImportResult.h
new file mode 100644 (file)
index 0000000..a461f3d
--- /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
+//
+
+#ifndef FeaturesAPI_ImportResult_H_
+#define FeaturesAPI_ImportResult_H_
+
+#include "FeaturesAPI.h"
+
+#include <FeaturesPlugin_ImportResult.h>
+
+#include <ModelHighAPI_Interface.h>
+#include <ModelHighAPI_Macro.h>
+
+class ModelHighAPI_Dumper;
+class ModelHighAPI_Selection;
+
+/// \class FeaturesAPI_ImportResult
+/// \ingroup CPPHighAPI
+/// \brief Interface for ImportResult feature.
+class FeaturesAPI_ImportResult: public ModelHighAPI_Interface
+{
+public:
+  /// Constructor without values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_ImportResult(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
+  /// Constructor with values.
+  FEATURESAPI_EXPORT
+  explicit FeaturesAPI_ImportResult(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                    const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Destructor.
+  FEATURESAPI_EXPORT virtual ~FeaturesAPI_ImportResult();
+
+  INTERFACE_1(FeaturesPlugin_ImportResult::ID(),
+              objects, FeaturesPlugin_ImportResult::OBJECTS(),
+              ModelAPI_AttributeSelectionList, /** Source objects */)
+
+  /// Modify objects attribute of the feature.
+  FEATURESAPI_EXPORT void setObjects(const std::list<ModelHighAPI_Selection>& theBaseObjects);
+
+  /// Dump wrapped feature
+  FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+};
+
+/// Pointer on ImportResult object.
+typedef std::shared_ptr<FeaturesAPI_ImportResult> ImportResultPtr;
+
+/// \ingroup CPPHighAPI
+/// \brief Create ImportResult feature.
+FEATURESAPI_EXPORT
+ImportResultPtr addImportResult(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                const std::list<ModelHighAPI_Selection>& theObjects);
+
+#endif // FeaturesAPI_ImportResult_H_
index 767e0966fda6e81afa2a17b84e0e484c8a62d266..ca0d4b6dbdc894c4ab0a1a6a7d86581ea3383a69 100644 (file)
@@ -51,5 +51,6 @@
   #include "FeaturesAPI_FusionFaces.h"
   #include "FeaturesAPI_RemoveResults.h"
   #include "FeaturesAPI_Copy.h"
+  #include "FeaturesAPI_ImportResult.h"
 
 #endif // FeaturesAPI_swig_H_
index 913a83aff1bd71a27cb4b307822a6d3f49f7fe82..b5b856d714d9b48314dbdbc8b9aa8b643c86838a 100644 (file)
@@ -62,6 +62,7 @@ SET(PROJECT_HEADERS
     FeaturesPlugin_RemoveResults.h
     FeaturesPlugin_Chamfer.h
     FeaturesPlugin_Copy.h
+    FeaturesPlugin_ImportResult.h
 )
 
 SET(PROJECT_SOURCES
@@ -105,6 +106,7 @@ SET(PROJECT_SOURCES
     FeaturesPlugin_RemoveResults.cpp
     FeaturesPlugin_Chamfer.cpp
     FeaturesPlugin_Copy.cpp
+    FeaturesPlugin_ImportResult.cpp
 )
 
 SET(XML_RESOURCES
@@ -138,6 +140,7 @@ SET(XML_RESOURCES
   fusion_faces_widget.xml
   chamfer_widget.xml
   copy_widget.xml
+  import_result_widget.xml
 )
 
 SET(TEXT_RESOURCES
@@ -551,4 +554,5 @@ ADD_UNIT_TESTS(TestExtrusion.py
                TestCopyNames.py
                TestCopySubShapes.py
                TestCopyWholeFeature.py
+               TestImportResult.py
 )
diff --git a/src/FeaturesPlugin/FeaturesPlugin_ImportResult.cpp b/src/FeaturesPlugin/FeaturesPlugin_ImportResult.cpp
new file mode 100644 (file)
index 0000000..80e61c0
--- /dev/null
@@ -0,0 +1,117 @@
+// Copyright (C) 2017-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 "FeaturesPlugin_ImportResult.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_ResultPart.h>
+#include <Events_InfoMessage.h>
+
+void FeaturesPlugin_ImportResult::initAttributes()
+{
+  data()->addAttribute(OBJECTS(), ModelAPI_AttributeSelectionList::typeId());
+}
+
+void FeaturesPlugin_ImportResult::execute()
+{
+  AttributeSelectionListPtr aList = selectionList(OBJECTS());
+  int aResultIndex = 0;
+  for (int aSelIndex = 0; aSelIndex < aList->size(); aSelIndex++) {
+    AttributeSelectionPtr aSel = aList->value(aSelIndex);
+    ResultPtr aContext = aSel->context();
+    if (!aContext.get())
+      continue;
+    GeomShapePtr aShape = aContext->shape();
+    if (!aShape.get() || aShape->isNull())
+      continue;
+    std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
+    aResultBody->store(aShape);
+    aResultBody->loadFirstLevel(aShape, "ImportResult");
+    setResult(aResultBody, aResultIndex++);
+  }
+  removeResults(aResultIndex);
+}
+
+bool FeaturesPlugin_ValidatorImportResults::isValid(const AttributePtr& theAttribute,
+  const std::list<std::string>&, Events_InfoMessage& theError) const
+{
+  AttributeSelectionListPtr aList =
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+  if (aList->size() == 0) {
+    // LCOV_EXCL_START
+    theError = "Please select sources.";
+    return false;
+    // LCOV_EXCL_STOP
+  }
+  // store documents in the Part-fesatures in order to check
+  // the selection is located in the previous documents
+  std::map<DocumentPtr, int> aDocIndices;
+  DocumentPtr aRoot = ModelAPI_Session::get()->moduleDocument();
+  int aNum = aRoot->size(ModelAPI_Feature::group());
+  for (int a = 0; a < aNum; a++) {
+    FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(
+      aRoot->object(ModelAPI_Feature::group(), a));
+    if (aFeat.get() && aFeat->data() && aFeat->data()->isValid() && aFeat->getKind() == "Part" &&
+      aFeat->results().size()) {
+      ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aFeat->firstResult());
+      if (aPart.get() && aPart->partDoc()) {
+        aDocIndices[aPart->partDoc()] = a;
+      }
+    }
+  }
+  int aThisIndex = aDocIndices[aList->owner()->document()];
+  for (int aSelIndex = 0; aSelIndex < aList->size(); aSelIndex++) {
+    AttributeSelectionPtr aSel = aList->value(aSelIndex);
+    ResultPtr aContext = aSel->context();
+    if (!aContext.get()) {
+      // LCOV_EXCL_START
+      theError = "Empty context.";
+      return false;
+      // LCOV_EXCL_STOP
+    }
+    GeomShapePtr aShape = aSel->value();
+    if (aShape.get() && !aShape->isNull() && !aShape->isSame(aContext->shape())) {
+      // LCOV_EXCL_START
+      theError = "Import results does not support selection of sub-shapes";
+      return false;
+      // LCOV_EXCL_STOP
+    }
+    ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
+    if (!aBody.get()) {
+      // LCOV_EXCL_START
+      theError = "Only results may be selected.";
+      return false;
+      // LCOV_EXCL_STOP
+    }
+    if (!aBody->shape()) {
+      // LCOV_EXCL_START
+      theError = "Result is empty.";
+      return false;
+      // LCOV_EXCL_STOP
+    }
+    int aBodyIndex = aDocIndices[aBody->document()];
+    if (aBodyIndex >= aThisIndex) {
+      theError = "The selected result must be located in earlier part.";
+      return false;
+    }
+  }
+  return true;
+}
diff --git a/src/FeaturesPlugin/FeaturesPlugin_ImportResult.h b/src/FeaturesPlugin/FeaturesPlugin_ImportResult.h
new file mode 100644 (file)
index 0000000..4b5df61
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (C) 2017-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 FeaturesPlugin_ImportResult_H_
+#define FeaturesPlugin_ImportResult_H_
+
+#include "FeaturesPlugin.h"
+
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_AttributeValidator.h>
+
+/// \class FeaturesPlugin_ImportResult
+/// \ingroup Plugins
+/// \brief The Import Result feature allows the user to import one or several results
+///        from another Part.
+
+class FeaturesPlugin_ImportResult : public ModelAPI_Feature
+{
+public:
+  /// Feature kind.
+  inline static const std::string& ID()
+  {
+    static const std::string MY_ID("ImportResult");
+    return MY_ID;
+  }
+
+  /// \return the kind of a feature.
+  FEATURESPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = FeaturesPlugin_ImportResult::ID();
+    return MY_KIND;
+  }
+
+  /// Selection list attribute that contains all copied shapes selection.
+  inline static const std::string& OBJECTS()
+  {
+    static const std::string MY_OBJECTS("objects");
+    return MY_OBJECTS;
+  }
+
+  /// Performs the algorithm and stores results it in the data structure.
+  FEATURESPLUGIN_EXPORT virtual void execute();
+
+  /// Request for initialization of data model of the feature: adding all attributes.
+  FEATURESPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Use plugin manager for features creation.
+  FeaturesPlugin_ImportResult() {}
+};
+
+/// \class FeaturesPlugin_ValidatorImportResults
+/// \ingroup Validators
+/// \brief A validator for selection of objects that may be imported:
+///        from another part, result bodies.
+class FeaturesPlugin_ValidatorImportResults : public ModelAPI_AttributeValidator
+{
+public:
+  //! \return True if selection is valid.
+  //! \param[in] theAttribute the checked attribute.
+  //! \param[in] theArguments arguments of the attribute.
+  //! \param[out] theError error message.
+  virtual bool isValid(const AttributePtr& theAttribute,
+    const std::list<std::string>& theArguments, Events_InfoMessage& theError) const;
+};
+
+#endif
index 5a2ff7c5c99ab3c69b6a166de124e61d46966ac6..8ade62615bd4d976d6a43b051f9306c6c5d614a3 100644 (file)
@@ -49,6 +49,7 @@
 #include <FeaturesPlugin_FusionFaces.h>
 #include <FeaturesPlugin_RemoveResults.h>
 #include <FeaturesPlugin_Copy.h>
+#include <FeaturesPlugin_ImportResult.h>
 #include <FeaturesPlugin_ValidatorTransform.h>
 #include <FeaturesPlugin_Validators.h>
 
@@ -115,6 +116,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin()
                               new FeaturesPlugin_ValidatorBooleanCommonSelection);
   aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanCommonArguments",
                               new FeaturesPlugin_ValidatorBooleanCommonArguments);
+  aFactory->registerValidator("FeaturesPlugin_ValidatorImportResults",
+                              new FeaturesPlugin_ValidatorImportResults);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
@@ -182,6 +185,8 @@ FeaturePtr FeaturesPlugin_Plugin::createFeature(std::string theFeatureID)
     return FeaturePtr(new FeaturesPlugin_Chamfer);
   } else if (theFeatureID == FeaturesPlugin_Copy::ID()) {
     return FeaturePtr(new FeaturesPlugin_Copy);
+  } else if (theFeatureID == FeaturesPlugin_ImportResult::ID()) {
+    return FeaturePtr(new FeaturesPlugin_ImportResult);
   }
 
 
index 1a043413bbe5ded849c2ae1f481d21515f0d4cae..df8d45ad1f03249b7da4f1e1311ad6a2f7e20771 100644 (file)
       <source>Copy</source>
       <translation>Copie</translation>
     </message>
+    <message>
+      <source>Import Result</source>
+      <translation>Importer le résultat</translation>
+    </message>
     <message>
       <source>Remove Sub-Shapes</source>
       <translation>Supprimer les sous-formes</translation>
     </message>
   </context>
 
+  <!-- Import result -->
+  <context>
+    <name>ImportResult</name>
+    <message>
+      <source>ImportResult</source>
+      <translation>Importer le résultat</translation>
+    </message>
+    <message>
+      <source>Copies results from other parts</source>
+      <translation>Copie les résultats d'autres pièces</translation>
+    </message>
+  </context>
+  <context>
+    <name>ImportResult:objects</name>
+    <message>
+      <source>Sources:</source>
+      <translation>Sources:</translation>
+    </message>
+    <message>
+      <source>Select copied results</source>
+      <translation>Sélectionnez les résultats copiés</translation>
+    </message>
+  </context>
+
   <!-- Remove_SubShapes -->
   <context>
     <name>Remove_SubShapes</name>
diff --git a/src/FeaturesPlugin/Test/TestImportResult.py b/src/FeaturesPlugin/Test/TestImportResult.py
new file mode 100644 (file)
index 0000000..bd6a0c0
--- /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
+#
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(15, 13, 11)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0)
+model.do()
+
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+Sketch_2 = model.addSketch(Part_2_doc, model.defaultPlane("XOZ"))
+SketchCircle_2 = Sketch_2.addCircle(-13, -9, 5)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_2_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0)
+ImportResult_1 = model.addImportResult(Part_2_doc, [model.selection("SOLID", "Part_1/Extrusion_1_1")])
+model.do()
+
+Part_3 = model.addPart(partSet)
+Part_3_doc = Part_3.document()
+Extrusion_3 = model.addExtrusion(Part_3_doc, [], model.selection(), 1, 0)
+Sketch_3 = model.addSketch(Part_3_doc, model.defaultPlane("XOZ"))
+SketchCircle_3 = Sketch_3.addCircle(-4, 2, 5)
+Extrusion_3.setNestedSketch(Sketch_3)
+model.do()
+
+model.end()
+
+# check Part_2 is ok and contains 2 solids in result
+assert(Part_2.feature().results().size() == 1)
+aPartShape = Part_2.feature().firstResult().shape()
+assert(aPartShape.shapeTypeStr() == "COMPOUND")
+aShapeExplorer = GeomAPI_ShapeExplorer(aPartShape, GeomAPI_Shape.SOLID)
+assert(aShapeExplorer.more())
+aShapeExplorer.next()
+assert(aShapeExplorer.more())
+
+# check that selection of this part and the lower part is impossible (by validator)
+model.begin()
+aSel = ImportResult_1.feature().selectionList("objects").value(0)
+aSel.selectSubShape("SOLID", "Part_2/Extrusion_1_1")
+model.end()
+aFactory = ModelAPI_Session.get().validators()
+assert(not aFactory.validate(ImportResult_1.feature()))
+
+model.begin()
+aSel = ImportResult_1.feature().selectionList("objects").value(0)
+aSel.selectSubShape("SOLID", "Part_3/Extrusion_1_1")
+model.end()
+assert(not aFactory.validate(ImportResult_1.feature()))
+
+# back to correct value
+model.begin()
+aSel = ImportResult_1.feature().selectionList("objects").value(0)
+aSel.selectSubShape("SOLID", "Part_1/Extrusion_1_1")
+model.end()
+assert(aFactory.validate(ImportResult_1.feature()))
+
+# TODO: implement for GEOMOETRICAL also
+assert(model.checkPythonDump(model.ModelHighAPI.CHECK_NAMING))
index 6298dd1f885239c969bcc99f8085fb6dbb5f4fb4..4d4a52d77d842318766e55784c102f6d22fa4a4c 100644 (file)
@@ -21,6 +21,7 @@ Features plug-in provides a set of common topological operations. It implements
    filletFeature.rst
    fuseFeature.rst
    fuseFeatureFaces.rst
+   importResult.rst
    intersectionFeature.rst
    linearCopyFeature.rst
    measurementFeature.rst
diff --git a/src/FeaturesPlugin/doc/TUI_importResultFeature.rst b/src/FeaturesPlugin/doc/TUI_importResultFeature.rst
new file mode 100644 (file)
index 0000000..5d27dbe
--- /dev/null
@@ -0,0 +1,12 @@
+
+  .. _tui_create_import_result:
+
+Create Import Result
+============
+
+.. literalinclude:: examples/import_result.py
+    :linenos:
+    :language: python
+
+:download:`Download this script <examples/import_result.py>` 
+   
diff --git a/src/FeaturesPlugin/doc/examples/import_result.py b/src/FeaturesPlugin/doc/examples/import_result.py
new file mode 100644 (file)
index 0000000..b0293b4
--- /dev/null
@@ -0,0 +1,15 @@
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(21, 16, 6)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0)
+model.do()
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+ImportResult_1 = model.addImportResult(Part_2_doc, [model.selection("SOLID", "Part_1/Extrusion_1_1")])
+model.end()
diff --git a/src/FeaturesPlugin/doc/images/CreatedImportResult.png b/src/FeaturesPlugin/doc/images/CreatedImportResult.png
new file mode 100644 (file)
index 0000000..3c35440
Binary files /dev/null and b/src/FeaturesPlugin/doc/images/CreatedImportResult.png differ
diff --git a/src/FeaturesPlugin/doc/images/ImportResult.png b/src/FeaturesPlugin/doc/images/ImportResult.png
new file mode 100644 (file)
index 0000000..3ade302
Binary files /dev/null and b/src/FeaturesPlugin/doc/images/ImportResult.png differ
diff --git a/src/FeaturesPlugin/doc/images/import_result_btn.png b/src/FeaturesPlugin/doc/images/import_result_btn.png
new file mode 100644 (file)
index 0000000..2bdd0be
Binary files /dev/null and b/src/FeaturesPlugin/doc/images/import_result_btn.png differ
diff --git a/src/FeaturesPlugin/doc/importResultFeature.rst b/src/FeaturesPlugin/doc/importResultFeature.rst
new file mode 100644 (file)
index 0000000..28741a3
--- /dev/null
@@ -0,0 +1,54 @@
+.. |import_result_btn.icon|    image:: images/import_result_btn.png
+
+Import Result
+=====
+
+The Import Result feature allows the user to import one or several results from another Part. If the result of the source-part is
+changed, the part and part result that contains the copy-results will be updated. The feature keeps the
+copy-shape, so, even the document was opened and the source-part was not activated (loaded), the part with copy-feature works well
+with this result-shape.
+
+It may be necessary for the user to load the other parts before using this feature otherwise the content of the **Results** folders will be empty.
+
+To create a Copy in the active part:
+
+#. select in the Main Menu *Features - > Import Result* item  or
+#. click |import_result_btn.icon| **Import Result** button in the toolbar
+
+
+The following property panel will be opened:
+
+.. image:: images/ImportResult.png
+  :align: center
+
+.. centered::
+   **Import result operation**
+
+Here it is necessary to select one or several objects. It is only possible to import results from Parts placed before the
+current Part where the import is done. Only results from the **Results** folder of previously created parts may be selected.
+
+
+**Apply** button creates a copy.
+  
+**Cancel** button cancels the operation.
+
+**TUI Command**:
+
+.. py:function:: model.addImportResult(Part_doc, results)
+
+    :param part: The current part object.
+    :param results: A list of results from another part.
+    :return: Result feature Import Result.
+
+Result
+""""""
+
+The Result of the operation will be copy of one or several results selected in another part located in the same place:
+
+.. image:: images/CreatedImportResult.png
+          :align: center
+
+.. centered::
+   **Import result created**
+
+**See Also** a sample TUI Script of :ref:`tui_create_import_result` operation.
diff --git a/src/FeaturesPlugin/icons/import_result.png b/src/FeaturesPlugin/icons/import_result.png
new file mode 100644 (file)
index 0000000..2bdd0be
Binary files /dev/null and b/src/FeaturesPlugin/icons/import_result.png differ
diff --git a/src/FeaturesPlugin/import_result_widget.xml b/src/FeaturesPlugin/import_result_widget.xml
new file mode 100644 (file)
index 0000000..94d1f5e
--- /dev/null
@@ -0,0 +1,11 @@
+<source>
+  <multi_selector id="objects"
+                  label="Sources:"
+                  tooltip="Select copied results"
+                  shape_types="objects"
+                  use_choice="false"
+                  concealment="false"
+                  allow_parts_content="true">
+    <validator id="FeaturesPlugin_ValidatorImportResults"/>
+  </multi_selector>
+</source>
index a61e26b672425c2b8ef74f5271ab313b1028869a..3477954d1e4987982a59579aaa3724cfee276cfa 100644 (file)
         helpfile="copyFeature.html">
         <source path="copy_widget.xml"/>
       </feature>
+      <feature id="ImportResult"
+        title="Import Result"
+        tooltip="Copies results from other parts"
+        icon="icons/Features/import_result.png"
+        helpfile="importResultFeature.html">
+        <source path="import_result_widget.xml"/>
+      </feature>
       <feature id="RemoveResults" title="Remove results" tooltip="Internal feature for results removal" internal="1">
         <multi_selector id="results" concealment="true"/>
       </feature>
index 0b2d2869a3ed7f120f5f1449c405a21d598d94d9..be0964ef5ccaf3fb4f432620472a182303edbfea 100644 (file)
@@ -82,11 +82,13 @@ ObjectPtr Model_AttributeReference::value()
       Handle(TDataStd_AsciiString) anEntry;
       if (myRef->Label().FindAttribute(TDataStd_AsciiString::GetID(), anEntry)) {
         std::shared_ptr<Model_Document> aDR = std::dynamic_pointer_cast<Model_Document>(aRefDoc);
-        TDF_Label aRefLab;
-        TDF_Tool::Label(aDR->objects()->featuresLabel().Data(),
-          anEntry->Get().ToCString(), aRefLab);
-        if (!aRefLab.IsNull()) {
-          return aDR->objects()->object(aRefLab);
+        if (aDR.get() && aDR->objects()) {
+          TDF_Label aRefLab;
+          TDF_Tool::Label(aDR->objects()->featuresLabel().Data(),
+            anEntry->Get().ToCString(), aRefLab);
+          if (!aRefLab.IsNull()) {
+            return aDR->objects()->object(aRefLab);
+          }
         }
       }
     }
index 48a42bd8908aa24dde7046b28741e70826de0739..10dfe84b296c08413ce33958f1bf576bd0711ab9 100644 (file)
@@ -875,7 +875,8 @@ void Model_AttributeSelection::selectSubShape(
       if (aPartName == aRootDoc->kind()) {
         aDoc = std::dynamic_pointer_cast<Model_Document>(aRootDoc);
         aSubShapeName = aSubShapeName.substr(aPartEnd + 1);
-      } else {
+      }
+      else {
         ObjectPtr aFound =
           owner()->document()->objectByName(ModelAPI_ResultPart::group(), aPartName);
         if (aFound.get()) { // found such part, so asking it for the name
@@ -894,11 +895,28 @@ void Model_AttributeSelection::selectSubShape(
                 continue;
               std::shared_ptr<GeomAPI_Edge> aSelectedEdge(new GeomAPI_Edge(aSelected));
               setValueCenter(aPart, aSelectedEdge, aCenterType);
-            } else
+            }
+            else
               setValue(aPart, aSelected);
             TDataStd_Integer::Set(selectionLabel(), anIndex);
             return;
           }
+        } else { // for the ImportResult feature Objects widget this may be a result in other part
+       // result may be hidden (like, tranlsatiomn of part) in PartSet, so iterate Part-features
+          int aNum = aRootDoc->size(ModelAPI_Feature::group());
+          for (int a = 0; a < aNum; a++) {
+            FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(
+              aRootDoc->object(ModelAPI_Feature::group(), a));
+            if (aFeat.get() && aFeat->data() && aFeat->data()->isValid() &&
+              aFeat->getKind() == "Part" && aFeat->results().size()) {
+              ResultPartPtr aPart =
+                std::dynamic_pointer_cast<ModelAPI_ResultPart>(aFeat->firstResult());
+              if (aPart.get() && aPart->partDoc().get() && aPart->data()->name() == aPartName) {
+                aDoc = std::dynamic_pointer_cast<Model_Document>(aPart->partDoc());
+                aSubShapeName = aSubShapeName.substr(aPartEnd + 1);
+              }
+            }
+          }
         }
       }
     }
index 70b885f451047bdd8fe1d487169c19824e0a2443..2777049f802ed492c08d8bf78cb0d2affef2252c 100644 (file)
@@ -76,6 +76,7 @@ Standard_Boolean ModuleBase_ShapeDocumentFilter::IsOk(
     if (aObj) {
       DocumentPtr aDoc = aObj->document();
       SessionPtr aMgr = ModelAPI_Session::get();
+      // TODO: disable the next line for the ImportResult feature "objects" widget only
       aValid = (aDoc == aMgr->activeDocument() || aDoc == aMgr->moduleDocument());
     }
     else {
index b5afae0d06a957c5ac9253c7661b55dae2132c0f..74d9637b97ed5d218b36bdb914ec258cb49f3a04 100644 (file)
@@ -31,4 +31,4 @@ from FeaturesAPI import addFillet, addChamfer
 from FeaturesAPI import addFusionFaces
 from FeaturesAPI import measureLength, measureDistance, measureRadius, measureAngle
 from FeaturesAPI import addRemoveResults
-from FeaturesAPI import addCopy
+from FeaturesAPI import addCopy, addImportResult