Salome HOME
[bos #35140] [EDF] (2023-T1) Memory communication between SHAPER and GEOM
authorjfa <jfa@opencascade.com>
Wed, 21 Jun 2023 11:12:34 +0000 (12:12 +0100)
committerjfa <jfa@opencascade.com>
Tue, 8 Aug 2023 16:02:30 +0000 (17:02 +0100)
27 files changed:
src/ConnectorAPI/Test/CTestTestfileInstall.cmake
src/ConnectorAPI/Test/TestExportXAOMem.py [new file with mode: 0644]
src/ConnectorAPI/Test/TestImportXAOMem.py [new file with mode: 0644]
src/ConnectorAPI/Test/tests.set
src/ExchangeAPI/CMakeLists.txt
src/ExchangeAPI/ExchangeAPI_Export.cpp
src/ExchangeAPI/ExchangeAPI_Export.h
src/ExchangeAPI/ExchangeAPI_Import.cpp
src/ExchangeAPI/ExchangeAPI_Import.h
src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp
src/ExchangePlugin/ExchangePlugin_ExportFeature.h
src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp
src/ExchangePlugin/ExchangePlugin_ImportFeature.h
src/ExchangePlugin/doc/exportFeature.rst
src/ExchangePlugin/doc/importFeature.rst
src/ExchangePlugin/export_widget.xml
src/ExchangePlugin/plugin-Exchange.xml
src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.cpp
src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.h
src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.cpp
src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.h
src/ModelAPI/ModelAPI_Feature.cpp
src/ModelAPI/ModelAPI_Feature.h
src/ModuleBase/ModuleBase_WidgetFactory.cpp
src/PartSet/PartSet_Module.cpp
src/PythonAPI/model/exchange/__init__.py
src/XAO/XAO_XaoExporter.cxx

index ed4901cfd54dc47d2aa8ed12666a2df8350041de..39752fc091d96e2ac72f3b9b1b9340cadfaf5689 100644 (file)
@@ -24,8 +24,14 @@ SET(PYTHON_TEST_DRIVER "$ENV{KERNEL_ROOT_DIR}/bin/salome/appliskel/python_test_d
 SET(TIMEOUT        300)
 
 
-FOREACH(tfile ${TEST_NAMES})
+FOREACH(tfile ${TEST_NAMES_SPR})
   SET(TEST_NAME ${COMPONENT_NAME}_${tfile})
   ADD_TEST(${TEST_NAME} python ${PYTHON_TEST_DRIVER} ${TIMEOUT} ${tfile}.py)
   SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${COMPONENT_NAME}")
 ENDFOREACH()
+
+FOREACH(tfile ${TEST_NAMES_ADV})
+  SET(TEST_NAME ${COMPONENT_NAME}_${tfile})
+  ADD_TEST(${TEST_NAME} python ${PYTHON_TEST_DRIVER} ${TIMEOUT} ${tfile}.py)
+  SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES LABELS "${SALOME_TEST_LABEL_ADV}")
+ENDFOREACH()
diff --git a/src/ConnectorAPI/Test/TestExportXAOMem.py b/src/ConnectorAPI/Test/TestExportXAOMem.py
new file mode 100644 (file)
index 0000000..482e372
--- /dev/null
@@ -0,0 +1,108 @@
+# Copyright (C) 2022-2023  CEA, EDF, OPEN CASCADE
+#
+# 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
+#
+
+"""
+      TestExportXAOMem.py
+      Unit test of ExchangePlugin_ExportFeature class
+"""
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+import salome
+salome.standalone()
+salome.salome_init(1)
+
+import os
+import math
+import tempfile
+
+from ModelAPI import *
+from GeomAlgoAPI import *
+from salome.shaper import model
+
+import GEOM
+from salome.geom import geomBuilder
+geompy = geomBuilder.New()
+
+#=========================================================================
+# test Export XAO to memory buffer (bytes array) 
+#=========================================================================
+def testExportXAOMem():
+
+    model.begin()
+    partSet = model.moduleDocument()
+    Part_1 = model.addPart(partSet)
+    Part_1_doc = Part_1.document()
+    Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+    Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Box_1_1/Top")])
+    Box_2 = model.addBox(Part_1_doc, 20, 20, 20)
+    model.do()
+
+    # Export to memory buffer (bytes array)
+    Export_buff1 = model.exportToXAOMem(Part_1_doc, model.selection("SOLID", "Box_1_1"), 'XAO')
+    Export_buff2 = model.exportToXAOMem(Part_1_doc, model.selection("SOLID", "Box_2_1"), 'XAO')
+    model.end()
+
+    # check buffer length
+    # export to XAO file and compare size of file and size of buffer
+    #assert(len(Export_buff1) == 4392)
+    #assert(len(Export_buff2) == 4287)
+    with tempfile.TemporaryDirectory() as tmpdirname:
+        tmpfilename = os.path.join(tmpdirname, "Box.xao")
+        Export_1 = model.exportToXAO(Part_1_doc, tmpfilename, model.selection("SOLID", "Box_1_1"), 'XAO')
+        file_stats = os.stat(tmpfilename)
+        assert(len(Export_buff1) == file_stats.st_size)
+
+        Export_2 = model.exportToXAO(Part_1_doc, tmpfilename, model.selection("SOLID", "Box_2_1"), 'XAO')
+        file_stats = os.stat(tmpfilename)
+        assert(len(Export_buff2) == file_stats.st_size)
+        pass
+
+    # Import to GEOM
+    (imported1, b1, [], [Group_1], []) = geompy.ImportXAOMem(Export_buff1, theName="Box1")
+    (imported2, b2, [], []       , []) = geompy.ImportXAOMem(Export_buff2, theName="Box2")
+
+    # Check result 1
+    aTol = 1.e-7
+    Props = geompy.BasicProperties(b1)
+    # surface area
+    aSurface = 600
+    assert (math.fabs(Props[1] - aSurface) < aTol), "The surface is wrong: expected = {0}, real = {1}".format(aSurface, Props[1])
+
+    Props = geompy.BasicProperties(Group_1)
+    # surface area
+    aSurface = 100
+    assert (math.fabs(Props[1] - aSurface) < aTol), "The surface is wrong: expected = {0}, real = {1}".format(aSurface, Props[1])
+
+    # Check result 2
+    Props = geompy.BasicProperties(b2)
+    # surface area
+    aSurface = 2400
+    assert (math.fabs(Props[1] - aSurface) < aTol), "The surface is wrong: expected = {0}, real = {1}".format(aSurface, Props[1])
+
+if __name__ == '__main__':
+    #=========================================================================
+    # Export a shape into XAO memory buffer
+    #=========================================================================
+    testExportXAOMem()
+    #=========================================================================
+    # End of test
+    #=========================================================================
diff --git a/src/ConnectorAPI/Test/TestImportXAOMem.py b/src/ConnectorAPI/Test/TestImportXAOMem.py
new file mode 100644 (file)
index 0000000..ea79ead
--- /dev/null
@@ -0,0 +1,117 @@
+# Copyright (C) 2022-2023  CEA, EDF, OPEN CASCADE
+#
+# 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
+#
+
+"""
+      TestImportXAOMem.py
+      Unit test of ExchangePlugin_ImportFeature class
+"""
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+import salome
+salome.standalone()
+salome.salome_init(1)
+
+import os
+import math
+import tempfile
+
+from ModelAPI import *
+from GeomAPI import *
+from GeomAlgoAPI import *
+from salome.shaper import model
+
+import GEOM
+from salome.geom import geomBuilder
+geompy = geomBuilder.New()
+
+#=========================================================================
+# test Import XAO from memory buffer (bytes array) 
+#=========================================================================
+def testImportXAOMem():
+
+    # Export from GEOM
+    Box_1 = geompy.MakeBoxDXDYDZ(10, 10, 10)
+    Group_1 = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
+    geompy.UnionIDs(Group_1, [33])
+    geompy.addToStudy( Box_1, 'Box_1_1' )
+    geompy.addToStudyInFather( Box_1, Group_1, 'Group_1' )
+
+    Export_buff = geompy.ExportXAOMem(Box_1, [Group_1], [], "XAO")
+
+    # check buffer length
+    # export to XAO file and compare size of file and size of buffer
+    #assert(len(Export_buff) == 4392)
+    with tempfile.TemporaryDirectory() as tmpdirname:
+        tmpfilename = os.path.join(tmpdirname, "Box.xao")
+        exported = geompy.ExportXAO(Box_1, [Group_1], [], "XAO", tmpfilename, "")
+        file_stats = os.stat(tmpfilename)
+        print(file_stats.st_size)
+        assert(len(Export_buff) == file_stats.st_size)
+        pass
+
+    # Import to SHAPER
+    model.begin()
+    partSet = model.moduleDocument()
+    Part_1 = model.addPart(partSet)
+    Part_1_doc = Part_1.document()
+
+    Import_1 = model.addImportXAOMem(Part_1_doc, Export_buff)
+    model.do()
+    Import_1.subFeature(0).setName("Group_1")
+    Import_1.subFeature(0).result().setName("Group_1")
+    Import_1.setName("Box_1")
+    Import_1.result().setName("Box_1_1")
+
+    model.end()
+
+    # Check result
+    assert(Import_1.feature().error() == "")
+    model.testNbResults(Import_1, 1)
+    model.testNbSubResults(Import_1, [0])
+    model.testNbSubShapes(Import_1, GeomAPI_Shape.SOLID, [1])
+    model.testNbSubShapes(Import_1, GeomAPI_Shape.FACE, [6])
+    model.testNbSubShapes(Import_1, GeomAPI_Shape.EDGE, [24])
+    model.testNbSubShapes(Import_1, GeomAPI_Shape.VERTEX, [48])
+    model.testResultsVolumes(Import_1, [1000])
+    model.testResultsAreas(Import_1, [600])
+
+    # check groups are the same in both parts
+    assert(Part_1_doc.size("Groups") == 1)
+    res1 = objectToResult(Part_1_doc.object("Groups", 0))
+    assert(res1 is not None)
+    res1It = GeomAPI_ShapeExplorer(res1.shape(), GeomAPI_Shape.FACE)
+    assert(res1It.more())
+    shape1 = res1It.current()
+    res1It.next()
+    assert(not res1It.more())
+    p1 = res1.shape().middlePoint()
+    aTol = 1.e-7
+    assert(math.fabs(p1.x() - 5) <= aTol and math.fabs(p1.y() - 5) <= aTol and math.fabs(p1.z() - 10) <= aTol), "({}, {}, {}) != ({}, {}, {})".format(p1.x(), p1.y(), p1.z(), 5, 5, 10)
+
+if __name__ == '__main__':
+    #=========================================================================
+    # Import a shape from XAO memory buffer
+    #=========================================================================
+    testImportXAOMem()
+    #=========================================================================
+    # End of test
+    #=========================================================================
index a42f17c80cef53bc29db83ed9134c7ea390049aa..ecfb7de7506b0a37c14de86a203bbc1a6cec6a19 100755 (executable)
@@ -17,7 +17,7 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-SET(TEST_NAMES
+SET(TEST_NAMES_SPR
   TestExportToGEOM
   TestExportToGEOMAllGroupsAndFields
   TestExportToGEOMPartSet
@@ -31,3 +31,10 @@ SET(TEST_NAMES
   TestImportSTL
   TestImportSTEP
 )
+
+SET(TEST_NAMES_ADV
+  TestExportXAOMem
+  TestImportXAOMem
+)
+
+set(TEST_NAMES ${TEST_NAMES_SPR} ${TEST_NAMES_ADV})
index 736d7b062eb5bd1cc3a0777aa1239b7dae4f503b..38506bea945206f79e5daacf063cebb71ff79422 100644 (file)
@@ -32,6 +32,7 @@ SET(PROJECT_SOURCES
 )
 
 SET(PROJECT_LIBRARIES
+  Locale
   ModelAPI
   ModelHighAPI
   GeomAlgoAPI
@@ -40,6 +41,7 @@ SET(PROJECT_LIBRARIES
 
 INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/Events
+  ${PROJECT_SOURCE_DIR}/src/Locale
   ${PROJECT_SOURCE_DIR}/src/ModelAPI
   ${PROJECT_SOURCE_DIR}/src/ModelHighAPI
   ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
index 8ee3b8bd7d86114af5628b477fd5cf625e50cec3..e22ff2255c2bc1c4948c149026e96aa0829e8df8 100644 (file)
@@ -21,6 +21,8 @@
 //--------------------------------------------------------------------------------------
 #include <ExchangePlugin_ExportPart.h>
 //--------------------------------------------------------------------------------------
+#include <Locale_Convert.h>
+//--------------------------------------------------------------------------------------
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Feature.h>
 #include <ModelHighAPI_Tools.h>
@@ -28,6 +30,8 @@
 #include <ModelHighAPI_Services.h>
 #include <ModelHighAPI_Selection.h>
 //--------------------------------------------------------------------------------------
+#include <algorithm>
+//--------------------------------------------------------------------------------------
 
 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature)
 : ModelHighAPI_Interface(theFeature)
@@ -97,11 +101,12 @@ ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>&
   apply(); // finish operation to make sure the export is done on the current state of the history
 }
 
-
-
+/// Constructor with values for XAO of selected result export.
 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-  const std::string & theFilePath, const ModelHighAPI_Selection& theResult,
-  const std::string & theAuthor, const std::string & theGeometryName)
+                                       const std::string & theFilePath,
+                                       const ModelHighAPI_Selection& theResult,
+                                       const std::string & theAuthor,
+                                       const std::string & theGeometryName)
   : ModelHighAPI_Interface(theFeature)
 {
   initialize();
@@ -119,7 +124,26 @@ ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>&
   apply(); // finish operation to make sure the export is done on the current state of the history
 }
 
-
+/// Constructor with values for XAO of selected result export to memory buffer.
+ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                       const ModelHighAPI_Selection& theResult,
+                                       const std::string & theAuthor,
+                                       const std::string & theGeometryName)
+  : ModelHighAPI_Interface(theFeature)
+{
+  initialize();
+  fillAttribute("XAOMem", theFeature->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID()));
+  fillAttribute(theAuthor, theFeature->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID()));
+  fillAttribute(theGeometryName,
+                theFeature->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID()));
+  fillAttribute("XAO", theFeature->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID()));
+  std::list<ModelHighAPI_Selection> aListOfOneSel;
+  aListOfOneSel.push_back(theResult);
+  fillAttribute(aListOfOneSel,
+                theFeature->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID()));
+  execute(true);
+  apply(); // finish operation to make sure the export is done on the current state of the history
+}
 
 /// Constructor with values for export in other formats than XAO.
 ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
@@ -167,13 +191,46 @@ void ExchangeAPI_Export::dump(ModelHighAPI_Dumper& theDumper) const
   FeaturePtr aBase = feature();
   const std::string& aDocName = theDumper.name(aBase->document());
 
-  theDumper << aBase << " = model.";
-
   std::string exportType = aBase->string(ExchangePlugin_ExportFeature::EXPORT_TYPE_ID())->value();
 
+  if (exportType == "XAOMem") {
+    std::string aGeometryName =
+      aBase->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
+
+    theDumper << "aXAOBuff";
+    std::string aGeometryNamePy;
+    if (! aGeometryName.empty()) {
+      aGeometryNamePy = aGeometryName;
+    }
+    else {
+      aGeometryNamePy = Locale::Convert::toString(aBase->data()->name());
+    }
+    if (! aGeometryNamePy.empty()) {
+      // add shape name
+      std::replace(aGeometryNamePy.begin(), aGeometryNamePy.end(), ' ', '_');
+      theDumper << "_" << aGeometryNamePy;
+    }
+    theDumper << " = model.exportToXAOMem(" << aDocName;
+    AttributeSelectionListPtr aShapeSelected =
+      aBase->selectionList(ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID());
+    if (aShapeSelected->isInitialized() && aShapeSelected->size() == 1) {
+      theDumper << ", " << aShapeSelected->value(0);
+    }
+
+    std::string theAuthor = aBase->string(ExchangePlugin_ExportFeature::XAO_AUTHOR_ID())->value();
+    if (! theAuthor.empty())
+      theDumper << ", '" << theAuthor << "'";
+    if (! aGeometryName.empty())
+      theDumper << ", '" << aGeometryName << "'";
+    theDumper << ")" << std::endl;
+    return;
+  }
+
+  theDumper << aBase << " = model.";
+
   if (exportType == "XAO") {
     std::string aTmpXAOFile =
-                aBase->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID())->value();
+      aBase->string(ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID())->value();
     correctSeparators(aTmpXAOFile);
     theDumper << "exportToXAO(" << aDocName << ", '" << aTmpXAOFile << "'" ;
     AttributeSelectionListPtr aShapeSelected =
@@ -186,7 +243,7 @@ void ExchangeAPI_Export::dump(ModelHighAPI_Dumper& theDumper) const
     if (! theAuthor.empty())
       theDumper << ", '" << theAuthor << "'";
     std::string theGeometryName =
-                aBase->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
+      aBase->string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
     if (! theGeometryName.empty())
       theDumper << ", '" << theGeometryName << "'";
     theDumper << ")" << std::endl;
@@ -276,8 +333,10 @@ ExportPtr exportToSTL(const std::shared_ptr<ModelAPI_Document> & thePart,
 }
 
 ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
-  const std::string & theFilePath, const ModelHighAPI_Selection& theSelectedShape,
-  const std::string & /*theAuthor*/, const std::string & /*theGeometryName*/)
+                      const std::string & theFilePath,
+                      const ModelHighAPI_Selection& theSelectedShape,
+                      const std::string & /*theAuthor*/,
+                      const std::string & /*theGeometryName*/)
 {
   apply(); // finish previous operation to make sure all previous operations are done
   std::shared_ptr<ModelAPI_Feature> aFeature =
@@ -286,6 +345,20 @@ ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
   return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theSelectedShape, "XAO"));
 }
 
+PyObject* exportToXAOMem(const std::shared_ptr<ModelAPI_Document> & thePart,
+                           const ModelHighAPI_Selection& theSelectedShape,
+                           const std::string & theAuthor,
+                           const std::string & theGeometryName)
+{
+  apply(); // finish previous operation to make sure all previous operations are done
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+    thePart->addFeature(ExchangePlugin_ExportFeature::ID());
+  ExportPtr aXAOExportAPI (new ExchangeAPI_Export
+                           (aFeature, theSelectedShape, theAuthor, theGeometryName));
+  std::string aBuff = aFeature->string(ExchangePlugin_ExportFeature::MEMORY_BUFFER_ID())->value();
+  return PyBytes_FromString(aBuff.c_str());
+}
+
 void exportPart(const std::shared_ptr<ModelAPI_Document> & thePart,
                 const std::string & theFilePath,
                 const std::list<ModelHighAPI_Selection> & theSelected)
index d948c8376b19df40ee1419c408389ea62482863d..c23bc9e667a158d9763fa6e0a3383fb11d2fcf8a 100644 (file)
@@ -30,6 +30,9 @@
 #include <ModelHighAPI_Macro.h>
 
 #include <ExchangePlugin_ExportFeature.h>
+
+#include <Python.h>
+
 //--------------------------------------------------------------------------------------
 class ModelHighAPI_Selection;
 class ModelHighAPI_Double;
@@ -55,21 +58,28 @@ public:
 
   /// Constructor with values for STL of selected result export.
   EXCHANGEAPI_EXPORT
-    explicit ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                                const std::string & theFilePath,
-                                const ModelHighAPI_Selection& theSelectedShape,
-                                const ModelHighAPI_Double&  theDeflectionRelative ,
-                                const ModelHighAPI_Double&  theDeflectionAbsolute,
-                                const bool theIsRelative,
-                                const bool theIsASCII);
+  explicit ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                              const std::string & theFilePath,
+                              const ModelHighAPI_Selection& theSelectedShape,
+                              const ModelHighAPI_Double&  theDeflectionRelative ,
+                              const ModelHighAPI_Double&  theDeflectionAbsolute,
+                              const bool theIsRelative,
+                              const bool theIsASCII);
 
   /// Constructor with values for XAO of selected result export.
   EXCHANGEAPI_EXPORT
-    explicit ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-      const std::string & theFilePath,
-      const ModelHighAPI_Selection& theResult,
-      const std::string & theAuthor,
-      const std::string & theGeometryName = std::string());
+  explicit ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                              const std::string & theFilePath,
+                              const ModelHighAPI_Selection& theResult,
+                              const std::string & theAuthor,
+                              const std::string & theGeometryName = std::string());
+
+  /// Constructor with values for XAO of selected result export to memory buffer.
+  EXCHANGEAPI_EXPORT
+  explicit ExchangeAPI_Export(const std::shared_ptr<ModelAPI_Feature>& theFeature,
+                              const ModelHighAPI_Selection& theResult,
+                              const std::string & theAuthor,
+                              const std::string & theGeometryName = std::string());
 
   /// Constructor with values for export in other formats than XAO.
   EXCHANGEAPI_EXPORT
@@ -82,39 +92,41 @@ public:
   EXCHANGEAPI_EXPORT
   virtual ~ExchangeAPI_Export();
 
-  INTERFACE_15(ExchangePlugin_ExportFeature::ID(),
-             exportType, ExchangePlugin_ExportFeature::EXPORT_TYPE_ID(),
-             ModelAPI_AttributeString, /** ExportType */,
-             filePath, ExchangePlugin_ExportFeature::FILE_PATH_ID(),
-             ModelAPI_AttributeString, /** file path */,
-             xaoFilePath, ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID(),
-             ModelAPI_AttributeString, /** xao_file_path */,
-             fileFormat, ExchangePlugin_ExportFeature::FILE_FORMAT_ID(),
-             ModelAPI_AttributeString, /** file format */,
-             selectionList, ExchangePlugin_ExportFeature::SELECTION_LIST_ID(),
-             ModelAPI_AttributeString, /** selection list */,
-             xaoAuthor, ExchangePlugin_ExportFeature::XAO_AUTHOR_ID(),
-             ModelAPI_AttributeString, /** xao author */,
-             xaoGeometryName, ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID(),
-             ModelAPI_AttributeString, /** xao geometry name */,
-             stlFilePath, ExchangePlugin_ExportFeature::STL_FILE_PATH_ID(),
-             ModelAPI_AttributeString, /** stl_file_path */,
-             stlobjectselected, ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED(),
-             ModelAPI_AttributeSelection, /** Object selected to export in stl file*/,
-             stldeflectionType, ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE(),
-             ModelAPI_AttributeString, /** Type of the defelection */,
-             stlrelative, ExchangePlugin_ExportFeature::STL_RELATIVE(),
-             ModelAPI_AttributeDouble, /** Relative*/,
-             stlabsolute, ExchangePlugin_ExportFeature::STL_ABSOLUTE(),
-             ModelAPI_AttributeDouble, /** Absolute */,
-             stlfileType, ExchangePlugin_ExportFeature::STL_FILE_TYPE(),
-             ModelAPI_AttributeString, /** Type of the stl file*/,
-             stldeflectionTypeabsolute,
+  INTERFACE_16(ExchangePlugin_ExportFeature::ID(),
+               exportType, ExchangePlugin_ExportFeature::EXPORT_TYPE_ID(),
+               ModelAPI_AttributeString, /** ExportType */,
+               filePath, ExchangePlugin_ExportFeature::FILE_PATH_ID(),
+               ModelAPI_AttributeString, /** file path */,
+               xaoFilePath, ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID(),
+               ModelAPI_AttributeString, /** xao_file_path */,
+               fileFormat, ExchangePlugin_ExportFeature::FILE_FORMAT_ID(),
+               ModelAPI_AttributeString, /** file format */,
+               selectionList, ExchangePlugin_ExportFeature::SELECTION_LIST_ID(),
+               ModelAPI_AttributeString, /** selection list */,
+               xaoAuthor, ExchangePlugin_ExportFeature::XAO_AUTHOR_ID(),
+               ModelAPI_AttributeString, /** xao author */,
+               xaoGeometryName, ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID(),
+               ModelAPI_AttributeString, /** xao geometry name */,
+               stlFilePath, ExchangePlugin_ExportFeature::STL_FILE_PATH_ID(),
+               ModelAPI_AttributeString, /** stl_file_path */,
+               stlobjectselected, ExchangePlugin_ExportFeature::STL_OBJECT_SELECTED(),
+               ModelAPI_AttributeSelection, /** Object selected to export in stl file*/,
+               stldeflectionType, ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE(),
+               ModelAPI_AttributeString, /** Type of the defelection */,
+               stlrelative, ExchangePlugin_ExportFeature::STL_RELATIVE(),
+               ModelAPI_AttributeDouble, /** Relative*/,
+               stlabsolute, ExchangePlugin_ExportFeature::STL_ABSOLUTE(),
+               ModelAPI_AttributeDouble, /** Absolute */,
+               stlfileType, ExchangePlugin_ExportFeature::STL_FILE_TYPE(),
+               ModelAPI_AttributeString, /** Type of the stl file*/,
+               stldeflectionTypeabsolute,
                       ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_ABSOLUTE(),
-             ModelAPI_AttributeString, /** Type of the defelection */,
-             stldeflectionTyperelative,
+               ModelAPI_AttributeString, /** Type of the defelection */,
+               stldeflectionTyperelative,
                       ExchangePlugin_ExportFeature::STL_DEFLECTION_TYPE_RELATIVE(),
-             ModelAPI_AttributeString, /** Type of the defelection */)
+               ModelAPI_AttributeString, /** Type of the defelection */,
+               memoryBuff, ExchangePlugin_ExportFeature::MEMORY_BUFFER_ID(),
+               ModelAPI_AttributeString, /** Bytes*/)
 
   /// Dump wrapped feature
   EXCHANGEAPI_EXPORT
@@ -159,10 +171,19 @@ ExportPtr exportToSTL(const std::shared_ptr<ModelAPI_Document> & thePart,
 */
 EXCHANGEAPI_EXPORT
 ExportPtr exportToXAO(const std::shared_ptr<ModelAPI_Document> & thePart,
-  const std::string & theFilePath,
-  const ModelHighAPI_Selection& theSelectedShape,
-  const std::string & theAuthor = std::string(),
-  const std::string & theGeometryName = std::string());
+                      const std::string & theFilePath,
+                      const ModelHighAPI_Selection& theSelectedShape,
+                      const std::string & theAuthor = std::string(),
+                      const std::string & theGeometryName = std::string());
+
+/**\ingroup CPPHighAPI
+* \brief Exports to XAO format buffer the selected result with groups parts related to it only.
+*/
+EXCHANGEAPI_EXPORT
+PyObject* exportToXAOMem(const std::shared_ptr<ModelAPI_Document> & thePart,
+                           const ModelHighAPI_Selection& theSelectedShape,
+                           const std::string & theAuthor = std::string(),
+                           const std::string & theGeometryName = std::string());
 
 
 /** \ingroup CPPHighAPI
index d29f7b2d2d870d876c0c9081d069a92df59c31bb..09df54f08476a3688f90f3a5b62cddd0fc3e6695 100644 (file)
@@ -21,6 +21,8 @@
 //--------------------------------------------------------------------------------------
 #include <ExchangePlugin_ImportPart.h>
 //--------------------------------------------------------------------------------------
+#include <Locale_Convert.h>
+//--------------------------------------------------------------------------------------
 #include <ModelHighAPI_Dumper.h>
 #include <ModelHighAPI_Services.h>
 #include <ModelHighAPI_Tools.h>
@@ -54,6 +56,19 @@ ExchangeAPI_Import::ExchangeAPI_Import(
     setFilePath(theFilePath);
 }
 
+ExchangeAPI_Import::ExchangeAPI_Import(
+    const std::shared_ptr<ModelAPI_Feature> & theFeature,
+    const std::string & /*theFilePath*/,
+    const std::string & theBuffer)
+: ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    fillAttribute("XAOMem", myimportType);
+    fillAttribute(theBuffer, mymemoryBuffer);
+    execute();
+  }
+}
+
 ExchangeAPI_Import::ExchangeAPI_Import(
     const std::shared_ptr<ModelAPI_Feature> & theFeature,
     const std::string & theFilePath,
@@ -106,35 +121,48 @@ void ExchangeAPI_Import::dump(ModelHighAPI_Dumper& theDumper) const
   std::string aPartName = theDumper.name(aBase->document());
 
   AttributeStringPtr aImportTypeAttr =
-                    aBase->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID());
+    aBase->string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID());
   std::string aFormat = aImportTypeAttr->value();
-  std::string aFilePath;
-  if (aFormat == "STEP" || aFormat == "STP")
-  {
-    aFilePath = aBase->string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID())->value();
-  } else {
-    aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value();
-  }
 
-  std::string aFrom = "\\";
-  std::string aTo = "\\\\";
-  for(std::size_t aPos = aFilePath.find(aFrom);
-      aPos != std::string::npos;
-      aPos = aFilePath.find(aFrom, aPos)) {
-    aFilePath.replace(aPos, aFrom.size(), aTo);
-    aPos += aTo.size();
+  if (aFormat == "XAOMem") {
+    theDumper << aBase << " = model.addImportXAOMem(" << aPartName << ", aXAOBuff";
+    std::string aGeometryNamePy = Locale::Convert::toString(aBase->data()->name());
+    if (! aGeometryNamePy.empty()) {
+      // add shape name
+      std::replace(aGeometryNamePy.begin(), aGeometryNamePy.end(), ' ', '_');
+      theDumper << "_" << aGeometryNamePy;
+    }
+    theDumper << ")" << std::endl;
   }
-  std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(aFilePath);
-  if (anExtension == "STP" || anExtension == "STEP"){
+  else {
+    std::string aFilePath;
+    if (aFormat == "STEP" || aFormat == "STP") {
+      aFilePath = aBase->string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID())->value();
+    } else {
+      aFilePath = aBase->string(ExchangePlugin_ImportFeature::FILE_PATH_ID())->value();
+    }
+
+    std::string aFrom = "\\";
+    std::string aTo = "\\\\";
+    for (std::size_t aPos = aFilePath.find(aFrom);
+         aPos != std::string::npos;
+         aPos = aFilePath.find(aFrom, aPos)) {
+      aFilePath.replace(aPos, aFrom.size(), aTo);
+      aPos += aTo.size();
+    }
+    std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(aFilePath);
+    if (anExtension == "STP" || anExtension == "STEP") {
       theDumper << aBase << " = model.addImportSTEP(" << aPartName << ", \""
                 << aFilePath << "\"" ;
 
       theDumper << ", " << scalInterUnits()->value()
                 << ", " << materials()->value()
                 << ", " << colors()->value() << ")"<< std::endl;
-  } else {
+    }
+    else {
       theDumper << aBase << " = model.addImport(" << aPartName << ", \""
-            << aFilePath << "\")" << std::endl;
+                << aFilePath << "\")" << std::endl;
+    }
   }
 
   // to make import have results
@@ -161,6 +189,14 @@ ImportPtr addImport(
   return ImportPtr(new ExchangeAPI_Import(aFeature, theFilePath));
 }
 
+ImportPtr addImportXAOMem(const std::shared_ptr<ModelAPI_Document> & thePart,
+                          PyObject* theBuffer)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ExchangeAPI_Import::ID());
+  std::string aString (PyBytes_AsString(theBuffer));
+  return ImportPtr(new ExchangeAPI_Import(aFeature, "", aString));
+}
+
 ImportPtr addImportSTEP(
     const std::shared_ptr<ModelAPI_Document> & thePart,
     const std::string & theFilePath,
index cd8d21b610cfb15aa3eaec80e697f80a3b473f4e..76262f8e346af7a8b5ae18abfeaa2f1160b754fb 100644 (file)
 #include <ModelHighAPI_Macro.h>
 #include <ModelHighAPI_Reference.h>
 #include <ModelHighAPI_Selection.h>
+
+#include <Python.h>
 //--------------------------------------------------------------------------------------
+
 /**\class ExchangeAPI_Import
  * \ingroup CPPHighAPI
  * \brief Interface for Import feature
@@ -42,11 +45,18 @@ public:
   /// Constructor without values
   EXCHANGEAPI_EXPORT
   explicit ExchangeAPI_Import(const std::shared_ptr<ModelAPI_Feature> & theFeature);
+
   /// Constructor with values
   EXCHANGEAPI_EXPORT
   ExchangeAPI_Import(const std::shared_ptr<ModelAPI_Feature> & theFeature,
                      const std::string & theFilePath);
 
+  /// Constructor with values for XAO import from memory buffer
+  EXCHANGEAPI_EXPORT
+  ExchangeAPI_Import(const std::shared_ptr<ModelAPI_Feature> & theFeature,
+                     const std::string & theFilePath,
+                     const std::string & theBuffer);
+
   /// Constructor with values for Step file
   EXCHANGEAPI_EXPORT
   ExchangeAPI_Import(const std::shared_ptr<ModelAPI_Feature> & theFeature,
@@ -58,7 +68,7 @@ public:
   EXCHANGEAPI_EXPORT
   virtual ~ExchangeAPI_Import();
 
-  INTERFACE_6(ExchangePlugin_ImportFeature::ID(),
+  INTERFACE_7(ExchangePlugin_ImportFeature::ID(),
               filePath, ExchangePlugin_ImportFeature::FILE_PATH_ID(),
               ModelAPI_AttributeString, /** File path */,
               importType, ExchangePlugin_ImportFeature::IMPORT_TYPE_ID(),
@@ -70,7 +80,9 @@ public:
               materials, ExchangePlugin_ImportFeature::STEP_MATERIALS_ID(),
               ModelAPI_AttributeBoolean, /** Materials */,
               colors, ExchangePlugin_ImportFeature::STEP_COLORS_ID(),
-              ModelAPI_AttributeBoolean, /** Colors */
+              ModelAPI_AttributeBoolean, /** Colors */,
+              memoryBuffer, ExchangePlugin_ImportFeature::MEMORY_BUFFER_ID(),
+              ModelAPI_AttributeString, /** Bytes */
   )
 
   /// Set point values
@@ -98,6 +110,13 @@ EXCHANGEAPI_EXPORT
 ImportPtr addImport(const std::shared_ptr<ModelAPI_Document> & thePart,
                     const std::string & theFilePath);
 
+/**\ingroup CPPHighAPI
+ * \brief Create Import feature to import XAO data from bytes buffer
+ */
+EXCHANGEAPI_EXPORT
+ImportPtr addImportXAOMem(const std::shared_ptr<ModelAPI_Document> & thePart,
+                          PyObject* theBuffer);
+
 /**\ingroup CPPHighAPI
  * \brief Create Import Step feature
  */
index b04aaaed547b7bac75ee375b919da9da53a45b79..ca1a2e4ddba94afc986940d977035c6a824ad269 100644 (file)
@@ -50,6 +50,7 @@
 #include <ModelAPI_AttributeIntArray.h>
 #include <ModelAPI_AttributeTables.h>
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeBoolean.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Object.h>
@@ -117,6 +118,10 @@ void ExchangePlugin_ExportFeature::initAttributes()
   data()->addAttribute(ExchangePlugin_ExportFeature::STL_FILE_TYPE(),
    ModelAPI_AttributeString::typeId());
 
+  // export to memory buffer (implemented for XAO format only)
+  data()->addAttribute(ExchangePlugin_ExportFeature::MEMORY_BUFFER_ID(),
+                       ModelAPI_AttributeString::typeId());
+
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
     ExchangePlugin_ExportFeature::XAO_FILE_PATH_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
@@ -127,11 +132,14 @@ void ExchangePlugin_ExportFeature::initAttributes()
     ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
     ExchangePlugin_ExportFeature::XAO_SELECTION_LIST_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
+    ExchangePlugin_ExportFeature::MEMORY_BUFFER_ID());
 
   // to support previous version of document, move the selection list
   // if the type of export operation is XAO
   AttributeStringPtr aTypeAttr = string(EXPORT_TYPE_ID());
-  if (aTypeAttr->isInitialized() && aTypeAttr->value() == "XAO") {
+  if (aTypeAttr->isInitialized() &&
+      (aTypeAttr->value() == "XAO" || aTypeAttr->value() == "XAOMem")) {
     bool aWasBlocked = data()->blockSendAttributeUpdated(true, false);
     AttributeSelectionListPtr aSelList = selectionList(SELECTION_LIST_ID());
     AttributeSelectionListPtr aXAOSelList = selectionList(XAO_SELECTION_LIST_ID());
@@ -163,21 +171,29 @@ void ExchangePlugin_ExportFeature::execute()
       this->string(ExchangePlugin_ExportFeature::FILE_FORMAT_ID());
   std::string aFormat = aFormatAttr->value();
 
+  bool isMemoryExport = false;
+  AttributeStringPtr aTypeAttr = string(EXPORT_TYPE_ID());
+  if (aTypeAttr->isInitialized() && aTypeAttr->value() == "XAOMem")
+    isMemoryExport = true;
+
   AttributeStringPtr aFilePathAttr =
       this->string(ExchangePlugin_ExportFeature::FILE_PATH_ID());
   std::string aFilePath = aFilePathAttr->value();
-  if (aFilePath.empty())
+  if (aFilePath.empty() && !isMemoryExport)
     return;
 
-  exportFile(aFilePath, aFormat);
+  exportFile(aFilePath, aFormat, isMemoryExport);
 }
 
 void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName,
-                                              const std::string& theFormat)
+                                              const std::string& theFormat,
+                                              const bool         isMemoryExport)
 {
   std::string aFormatName = theFormat;
 
   if (aFormatName.empty()) { // get default format for the extension
+    if (isMemoryExport) return;
+
     // ".brep" -> "BREP"
     std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(theFileName);
     if (anExtension == "BREP" || anExtension == "BRP") {
@@ -192,9 +208,9 @@ void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName,
   }
 
   if (aFormatName == "XAO") {
-    exportXAO(theFileName);
+    exportXAO(theFileName, isMemoryExport);
     return;
-  }else if (aFormatName == "STL") {
+  } else if (aFormatName == "STL") {
     exportSTL(theFileName);
     return;
   }
@@ -248,7 +264,8 @@ void ExchangePlugin_ExportFeature::exportFile(const std::string& theFileName,
 
 /// Returns XAO string by the value from the table
 static std::string valToString(const ModelAPI_AttributeTables::Value& theVal,
-  const ModelAPI_AttributeTables::ValueType& theType) {
+                               const ModelAPI_AttributeTables::ValueType& theType)
+{
   std::ostringstream aStr; // the resulting string value
   switch(theType) {
   case ModelAPI_AttributeTables::BOOLEAN:
@@ -309,7 +326,8 @@ void ExchangePlugin_ExportFeature::exportSTL(const std::string& theFileName)
 }
 
 
-void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName)
+void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName,
+                                             const bool         isMemoryExport)
 {
   try {
 
@@ -396,6 +414,12 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName)
     // get the name from the first result
     ResultPtr aResultBody = *aResults.begin();
     aGeometryName = Locale::Convert::toString(aResultBody->data()->name());
+    if (isMemoryExport) {
+      // for python dump
+      string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->setValue(aGeometryName);
+      // or
+      //data()->setName(Locale::Convert::toWString(aGeometryName));
+    }
   }
 
   aXao.getGeometry()->setName(aGeometryName);
@@ -563,7 +587,12 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName)
   }
 
   // exporting
-  XAOExport(theFileName, &aXao, anError);
+  if (isMemoryExport) {
+    string(ExchangePlugin_ExportFeature::MEMORY_BUFFER_ID())->setValue(XAOExportMem(&aXao, anError));
+  }
+  else {
+    XAOExport(theFileName, &aXao, anError);
+  }
 
   if (!anError.empty()) {
     setError("An error occurred while exporting " + theFileName + ": " + anError);
index 5331b39f4254671de10f55d59fcf138a86a0e92c..100a5e00c7da7a0a2dc1bae238645a9ac1a7ef4d 100644 (file)
@@ -150,6 +150,13 @@ public:
     static const std::string MY_XAO_GEOMETRY_NAME_ID("xao_geometry_name");
     return MY_XAO_GEOMETRY_NAME_ID;
   }
+  /// attribute string memory buffer
+  inline static const std::string& MEMORY_BUFFER_ID()
+  {
+    static const std::string MY_MEMORY_BUFFER_ID("memory_buffer");
+    return MY_MEMORY_BUFFER_ID;
+  }
+
   /// Default constructor
   EXCHANGEPLUGIN_EXPORT ExchangePlugin_ExportFeature();
   /// Default destructor
@@ -185,10 +192,12 @@ public:
 protected:
   /// Performs export of the file
   EXCHANGEPLUGIN_EXPORT void exportFile(const std::string& theFileName,
-                                        const std::string& theFormat);
+                                        const std::string& theFormat,
+                                        const bool         isMemoryExport);
 
   /// Performs export to XAO file
-  EXCHANGEPLUGIN_EXPORT void exportXAO(const std::string& theFileName);
+  EXCHANGEPLUGIN_EXPORT void exportXAO(const std::string& theFileName,
+                                       const bool         isMemoryExport);
 
   /// Performs export to STL file
   EXCHANGEPLUGIN_EXPORT void exportSTL(const std::string& theFileName);
index 7020326e769f10be1b5c87d852afa448f161ef58..a57986e3205fc90010827dd73fe561330efba796 100644 (file)
@@ -94,6 +94,7 @@ void ExchangePlugin_ImportFeature::initAttributes()
   data()->addAttribute(STEP_MATERIALS_ID(), ModelAPI_AttributeBoolean::typeId());
   data()->addAttribute(STEP_COLORS_ID(), ModelAPI_AttributeBoolean::typeId());
   data()->addAttribute(STEP_SCALE_INTER_UNITS_ID(), ModelAPI_AttributeBoolean::typeId());
+  data()->addAttribute(MEMORY_BUFFER_ID(), ModelAPI_AttributeString::typeId());
 
   ModelAPI_Session::get()->validators()->registerNotObligatory(
       getKind(), ExchangePlugin_ImportFeature::STEP_COLORS_ID());
@@ -105,7 +106,22 @@ void ExchangePlugin_ImportFeature::initAttributes()
       getKind(), ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(
       getKind(), ExchangePlugin_ImportFeature::FILE_PATH_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(
+      getKind(), ExchangePlugin_ImportFeature::MEMORY_BUFFER_ID());
+}
+
+bool ExchangePlugin_ImportFeature::isEditable()
+{
+  AttributeStringPtr aImportTypeAttr = string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID());
+  std::string aFormat = aImportTypeAttr->value();
+
+  if (aFormat == "XAOMem")
+    // If the shape is imported from memory buffer, do not allow to edit the feature
+    return false;
+
+  return true;
 }
+
 /*
  * Computes or recomputes the results
  */
@@ -113,20 +129,34 @@ void ExchangePlugin_ImportFeature::execute()
 {
   AttributeStringPtr aImportTypeAttr = string(ExchangePlugin_ImportFeature::IMPORT_TYPE_ID());
   std::string aFormat = aImportTypeAttr->value();
-  AttributeStringPtr aFilePathAttr;
-  if (aFormat == "STEP" || aFormat == "STP")
-  {
-    aFilePathAttr = string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID());
-  } else {
-    aFilePathAttr = string(ExchangePlugin_ImportFeature::FILE_PATH_ID());
+
+  if (aFormat == "XAOMem") {
+    // Import from memory buffer
+    AttributeStringPtr aMemoryBuffAttr =
+      string(ExchangePlugin_ImportFeature::MEMORY_BUFFER_ID());
+    std::string aMemoryBuff = aMemoryBuffAttr->value();
+    if (aMemoryBuff.empty()) {
+      setError("Memory buffer is empty.");
+      return;
+    }
+    importXAO("", aMemoryBuff, true);
   }
-  std::string aFilePath = aFilePathAttr->value();
-  if (aFilePath.empty()) {
-    setError("File path is empty.");
-    return;
+  else {
+    // Import from file
+    AttributeStringPtr aFilePathAttr;
+    if (aFormat == "STEP" || aFormat == "STP") {
+        aFilePathAttr = string(ExchangePlugin_ImportFeature::STEP_FILE_PATH_ID());
+    }
+    else {
+      aFilePathAttr = string(ExchangePlugin_ImportFeature::FILE_PATH_ID());
+    }
+    std::string aFilePath = aFilePathAttr->value();
+    if (aFilePath.empty()) {
+      setError("File path is empty.");
+      return;
+    }
+    importFile(aFilePath);
   }
-
-  importFile(aFilePath);
 }
 
 void ExchangePlugin_Import_ImageFeature::execute()
@@ -357,16 +387,26 @@ void ExchangePlugin_ImportFeature::setMaterielGroup(
   }
 }
 
-void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName)
+void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName,
+                                             const std::string& theMemoryBuff,
+                                             const bool         isMemoryImport)
 {
+  std::string aDataSource = theFileName;
+
   try {
   std::string anError;
 
   XAO::Xao aXao;
-  std::shared_ptr<GeomAPI_Shape> aGeomShape = XAOImport(theFileName, anError, &aXao);
+  std::shared_ptr<GeomAPI_Shape> aGeomShape;
+  if (isMemoryImport) {
+    aGeomShape = XAOImportMem(theMemoryBuff, anError, &aXao);
+    aDataSource = "memory buffer";
+  }
+  else
+    aGeomShape = XAOImport(theFileName, anError, &aXao);
 
   if (!anError.empty()) {
-    setError("An error occurred while importing " + theFileName + ": " + anError);
+    setError("An error occurred while importing " + aDataSource + ": " + anError);
     return;
   }
 
@@ -374,8 +414,12 @@ void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName)
 
   // use the geometry name or the file name for the feature
   std::string aBodyName = aXaoGeometry->getName();
-  if (aBodyName.empty())
-    aBodyName = GeomAlgoAPI_Tools::File_Tools::name(theFileName);
+  if (aBodyName.empty()) {
+    if (isMemoryImport)
+      aBodyName = "ImportXAOMem";
+    else
+      aBodyName = GeomAlgoAPI_Tools::File_Tools::name(theFileName);
+  }
   data()->setName(Locale::Convert::toWString(aBodyName));
 
   ResultBodyPtr aResultBody = createResultBody(aGeomShape);
@@ -549,7 +593,7 @@ void ExchangePlugin_ImportFeature::importXAO(const std::string& theFileName)
 // LCOV_EXCL_START
   } catch (XAO::XAO_Exception& e) {
     std::string anError = e.what();
-    setError("An error occurred while importing " + theFileName + ": " + anError);
+    setError("An error occurred while importing " + aDataSource + ": " + anError);
     return;
   }
 // LCOV_EXCL_STOP
index 2398b41890afa2f13e40535c6d84bd76f081a7b5..8a47253a3d95ccbc79a1b41e17aaf06d849fdfe8 100644 (file)
@@ -149,6 +149,12 @@ public:
     static const std::string MY_STEP_COLORS_ID("step_colors");
     return MY_STEP_COLORS_ID;
   }
+  /// attribute memory buffer
+  inline static const std::string& MEMORY_BUFFER_ID()
+  {
+    static const std::string MY_MEMORY_BUFFER_ID("memory_buffer");
+    return MY_MEMORY_BUFFER_ID;
+  }
   /// Returns the unique kind of a feature
   EXCHANGEPLUGIN_EXPORT virtual const std::string& getKind() override
   {
@@ -161,12 +167,17 @@ public:
   /// Request for initialization of data model of the feature: adding all attributes
   EXCHANGEPLUGIN_EXPORT virtual void initAttributes();
 
+  /// Return false in case of XAOMem import.
+  EXCHANGEPLUGIN_EXPORT virtual bool isEditable();
+
 protected:
   /// Performs the import of the file
   EXCHANGEPLUGIN_EXPORT void importFile(const std::string& theFileName) override;
 
   /// Performs the import of XAO file
-  EXCHANGEPLUGIN_EXPORT void importXAO(const std::string& theFileName);
+  EXCHANGEPLUGIN_EXPORT void importXAO(const std::string& theFileName,
+                                       const std::string& theMemoryBuff = std::string(),
+                                       const bool         isMemoryImport = false);
 
 private:
   /// Set groups of color
index 1773c9bf940c81c46bbe96d6c1d28eda0036eeb0..072c9495a5d719d167299cc956d2e013e1eea8a8 100644 (file)
@@ -119,6 +119,14 @@ Selection list in the property panel contains a list of exported objects which c
     :param string: The name of the author, empty by default
     :param string: The name for the shape processed in GEOMETRY module, empty by default
 
+.. py:function:: aBuffer = model.exportToXAOMem(Part_doc, Object, Author="", GeometryName="")
+
+    This function enables passing data in XAO format from SHAPER to GEOM through a memory buffer (bytes array), without creation of real file on disk.
+
+    :param object: The object to export
+    :param string: The name of the author, empty by default
+    :param string: The name for the shape processed in GEOMETRY module, empty by default
+
 Result
 """"""
 
index 817c5c1cb6d89e139f50b11732a26ce072bf95df..f035ea360cbefb185f3c07ec49e9a1e8b7852391 100644 (file)
@@ -47,10 +47,10 @@ The import will be performed within the active part. If no part is active, the p
 
 **TUI Command**:
 
-.. py:function:: model.importPart(Doc, FileNameString, [PrevFeature])
+.. py:function:: model.importPart(Part_doc, FileNameString, [PrevFeature])
 
-    :param part: The current part object
-    :param string: A file name string
+    :param Part_doc: The target part document, where to import the data
+    :param string: The file name string
     :param reference: The feature after which the imported entities should be inserted
 
 
@@ -88,9 +88,16 @@ In case of first choice the format of imported file will be defined according to
 
 .. py:function:: model.addImport(Part_doc, FileNameString)
 
-    :param part: The current part object
+    :param Part_doc: The target part document, where to import the data
     :param string: A file name string.
 
+.. py:function:: model.addImportXAOMem(Part_doc, aBuffer)
+
+    This function allows importing data in XAO format from GEOM through a memory buffer (bytes array), without creation of real file on disk.
+
+    :param Part_doc: The target part document, where to import the data
+    :param aBuffer: A byte array with data in XAO format.
+
 Result
 """"""
 
@@ -127,7 +134,7 @@ The **Import to** combobox provides the list of destinations (one of existing Pa
 
 .. py:function:: model.addImportSTEP(Part_doc, FileNameString,scalInterUnits,materials,colors)
 
-    :param part: The current part object
+    :param Part_doc: The target part document, where to import the data
     :param string: A file name string.
     :param boolean: True if scale to UIS
     :param boolean: True to create groups from materials
index 83b9aba4d627ce67e2b655512c2131e9fb49763e..9eff85040c008dc8ac8d89b2b552d6298d60dac1 100644 (file)
                    placeholder="Please input the geometry name">
       </stringvalue>
     </case>
+    <case id="XAOMem" title="XAOMem" internal="1">
+      <stringvalue id="xao_author"
+                   label="Author"
+                   placeholder="Please input the author">
+      </stringvalue>
+      <stringvalue id="xao_geometry_name"
+                   label="Geometry name"
+                   placeholder="Please input the geometry name">
+      </stringvalue>
+    </case>
     <case id="STL" title="STL">
       <export_file_selector id="stl_file_path"
                             type="save"
index b208717e4fee8d7d5bb54c2fab386dfe20a7460e..6637952ed7d8ea65e6bdb169db1373917cef9b09 100644 (file)
@@ -4,40 +4,43 @@
       <feature id="ImportMacro" title="Import" tooltip="Import a file" icon="icons/Exchange/import.png"
                helpfile="importFeature.html"
                internal="1">
-      <switch id="ImportType">
-        <case id="Regular" title="BREP, XAO, IGES, STL">
-          <file_selector id="file_path" title="Import file" path="">
+        <switch id="ImportType">
+          <case id="Regular" title="BREP, XAO, IGES, STL">
+            <file_selector id="file_path" title="Import file" path="">
               <validator id="ExchangePlugin_ImportFormat" parameters="BREP|BRP:BREP,IGES|IGS:IGES,XAO:XAO,STL:STL" />
-          </file_selector>
-        <choice id="target_part"
-                string_list_attribute="target_parts_list"
-                label="Import to"
-                tooltip="Select the part to import the document" />
-        </case>
-        <case id="STEP" title="STEP">
+            </file_selector>
+            <choice id="target_part"
+                    string_list_attribute="target_parts_list"
+                    label="Import to"
+                    tooltip="Select the part to import the document" />
+          </case>
+          <case id="STEP" title="STEP">
             <file_selector id="step_file_path" title="Import file" path="">
               <validator id="ExchangePlugin_ImportFormat" parameters="STEP|STP:STEP" />
             </file_selector>
             <choice id="step_target_part"
-                string_list_attribute="step_target_parts_list"
-                label="Import to"
-                tooltip="Select the part to import the document" />
+                    string_list_attribute="step_target_parts_list"
+                    label="Import to"
+                    tooltip="Select the part to import the document" />
             <groupbox title="STEP options">
               <boolvalue id="step_scale_inter_units"
-                        label="Scale to International System of Units"
-                        default="true"/>
+                         label="Scale to International System of Units"
+                         default="true"/>
               <groupbox title="Create groups from">
                 <boolvalue id="step_materials"
-                          label="Materials"
-                          default="false"/>
+                           label="Materials"
+                           default="false"/>
                 <boolvalue id="step_colors"
-                          label="Colors"
-                          default="false"/>
+                           label="Colors"
+                           default="false"/>
               </groupbox>
             </groupbox>
           </case>
+          <case id="XAOMem" title="XAOMem" internal="1">
+          </case>
         </switch>
-</feature>
+      </feature>
+
       <feature id="ImportImageMacro" title="Import" tooltip="Import a file" icon="icons/Exchange/import.png"
                helpfile="importFeature.html"
                internal="1">
@@ -49,6 +52,7 @@
                 label="Import to"
                 tooltip="Select the image to import the document" />
       </feature>
+
       <feature id="Import" title="Import" tooltip="Import a file" icon="icons/Exchange/import.png"
                helpfile="importFeature.html" internal="1">
         <switch id="ImportType">
             </file_selector>
             <groupbox title="STEP options">
               <boolvalue id="step_scale_inter_units"
-                        label="Scale to International System of Units"
-                        default="true"/>
+                         label="Scale to International System of Units"
+                         default="true"/>
               <groupbox title="Create groups from">
                 <boolvalue id="step_materials"
-                          label="Materials"
-                          default="false"/>
+                           label="Materials"
+                           default="false"/>
                 <boolvalue id="step_colors"
-                          label="Colors"
-                          default="false"/>
+                           label="Colors"
+                           default="false"/>
               </groupbox>
             </groupbox>
           </case>
+          <case id="XAOMem" title="XAOMem" internal="1">
+          </case>
         </switch>
       </feature>
       <feature id="ImportImage" title="Import" tooltip="Import a file" icon="icons/Exchange/import.png"
@@ -88,6 +94,7 @@
                helpfile="exportFeature.html" internal="1">
         <source path="export_widget.xml" />
       </feature>
+
       <feature id="Dump" title="Dump" tooltip="Dump Python script" icon="icons/Exchange/dump.png"
                helpfile="dumpFeature.html" abort_confirmation="false">
         <export_file_selector id="file_path"
                 label="Import to"
                 tooltip="Select the part to import the document" />
       </feature>
+
       <feature id="ExportPart" title="Export part" tooltip="Export structure of the Part to file" icon="icons/Exchange/export_part.png"
                helpfile="exportFeature.html"
                internal="1">
index af7a2b131a49852f08e77808af5f7e61b09db8a1..89f53c637349cd591d354d5399bfb39bfa48aa05 100644 (file)
@@ -81,3 +81,40 @@ bool XAOExport(const std::string& theFileName,
   }
   return true;
 }
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+const std::string XAOExportMem(XAO::Xao* theXao,
+                               std::string& theError)
+{
+  std::string aRetBuff ("");
+
+#ifdef _DEBUG
+  std::cout << "Export XAO into memory buffer " << std::endl;
+#endif
+
+  if (!theXao) {
+    theError = "An invalid argument.";
+    return aRetBuff;
+  }
+
+  try {
+    XAO::BrepGeometry* aGeometry = dynamic_cast<XAO::BrepGeometry*>(theXao->getGeometry());
+    TopoDS_Shape aShape = aGeometry->getTopoDS_Shape();
+    bool aWasFree = aShape.Free(); // make top level topology free, same as imported
+    if (!aWasFree)
+      aShape.Free(Standard_True);
+
+    aRetBuff = XAO::XaoExporter::saveToXml(theXao);
+
+    if (!aWasFree)
+      aShape.Free(Standard_False);
+  } catch (XAO::XAO_Exception& e) {
+    theError = e.what();
+    return aRetBuff;
+  }
+  return aRetBuff;
+}
index 2944b964518be39bb40fdbf0c5d2006a2c3bf3e6..3ae31de6bbf80dbd208bcef0c48d6ee80078295b 100644 (file)
@@ -42,4 +42,9 @@ bool XAOExport(const std::string& theFileName,
                XAO::Xao* theXao,
                std::string& theError);
 
+/// Implementation of the export XAO to memory buffer (std::string)
+GEOMALGOAPI_EXPORT
+const std::string XAOExportMem(XAO::Xao* theXao,
+                               std::string& theError);
+
 #endif /* GEOMALGOAPI_XAOEXPORT_H_ */
index 2d734e8815cac5de03fdc55573fc7b2a56e7250f..5b241497642e6d8c6a15fcbedf5aa8bbd50893e4 100644 (file)
@@ -66,3 +66,46 @@ std::shared_ptr<GeomAPI_Shape> XAOImport(const std::string& theFileName,
   aGeomShape->setImpl(new TopoDS_Shape(aShape));
   return aGeomShape;
 }
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+std::shared_ptr<GeomAPI_Shape> XAOImportMem(const std::string& theMemoryBuff,
+                                            std::string& theError,
+                                            XAO::Xao* theXao)
+{
+#ifdef _DEBUG
+  std::cout << "Import XAO from file " << theFileName << std::endl;
+#endif
+  if (theMemoryBuff.empty() || !theXao) {
+    theError = "An invalid argument.";
+    return std::shared_ptr<GeomAPI_Shape>();
+  }
+
+  TopoDS_Shape aShape;
+  try {
+    if (XAO::XaoExporter::setXML(theMemoryBuff, theXao)) {
+      XAO::Geometry* aGeometry = theXao->getGeometry();
+      XAO::Format aFormat = aGeometry->getFormat();
+      if (aFormat == XAO::BREP) {
+        if (XAO::BrepGeometry* aBrepGeometry = dynamic_cast<XAO::BrepGeometry*>(aGeometry))
+          aShape = aBrepGeometry->getTopoDS_Shape();
+      } else {
+        theError = "Unsupported XAO geometry format:" + XAO::XaoUtils::shapeFormatToString(aFormat);
+        aShape.Nullify();
+      }
+    } else {
+      theError = "XAO object was not read successful";
+      aShape.Nullify();
+    }
+  } catch (XAO::XAO_Exception& e) {
+    theError = e.what();
+    aShape.Nullify();
+  }
+
+  std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
+  aGeomShape->setImpl(new TopoDS_Shape(aShape));
+  return aGeomShape;
+}
index 5682dcf3122957eeeb9a13d5ca46757c86629333..986e03cef5aed729998ffdcb06028c16c1f3eab0 100644 (file)
@@ -36,4 +36,10 @@ std::shared_ptr<GeomAPI_Shape> XAOImport(const std::string& theFileName,
                                           std::string& theError,
                                           XAO::Xao* theXao);
 
+/// Implementation of the import XAO data from memory buffer
+GEOMALGOAPI_EXPORT
+std::shared_ptr<GeomAPI_Shape> XAOImportMem(const std::string& theMemoryBuff,
+                                            std::string& theError,
+                                            XAO::Xao* theXao);
+
 #endif /* GEOMALGOAPI_XAOIMPORT_H_ */
index 945a0efbd8908ded6d7e48e2ab3aaacd09d311e6..21370b2215537d52498d28a555c739969e3547ff 100644 (file)
@@ -253,6 +253,11 @@ bool ModelAPI_Feature::isStable()
   return myIsStable;
 }
 
+bool ModelAPI_Feature::isEditable()
+{
+  return true;
+}
+
 bool ModelAPI_Feature::customAction(const std::string& /*theActionId*/)
 {
   return false;
index c5705de11e5bb9493fdc10c638e378c07cbc472b..c973d4464ff3400c61f1ed637501d7054edb5df9 100644 (file)
@@ -41,7 +41,7 @@ class ModelAPI_Feature : public ModelAPI_Object
   std::list<std::shared_ptr<ModelAPI_Result> > myResults;
   ///< is feature disabled or not
   bool myIsDisabled;
-  ///< is feature is stable (not editing)
+  ///< is feature stable (not editing)
   bool myIsStable;
 
  public:
@@ -155,6 +155,9 @@ class ModelAPI_Feature : public ModelAPI_Object
   /// Returns the feature is stable or not.
   MODELAPI_EXPORT virtual bool isStable();
 
+  /// Returns the feature is editable or not. Most of features are editable.
+  MODELAPI_EXPORT virtual bool isEditable();
+
   /// Performs some custom feature specific functionality (normally called by some GUI button)
   /// \param theActionId an action key
   /// \return a boolean value about it is performed
index 4e1e51146dfe75b20b48cbd5f6b991e24200c60c..486b442507f3ede195aeca2fe79497c1b6d3ec0f 100644 (file)
@@ -133,6 +133,7 @@ void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage, bool a
         //it's pages recursively and setup into the widget.
         if (myWidgetApi->toChildWidget()) {
           do {
+            if (myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) continue;
             QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
             QString aTooltip = qs(myWidgetApi->getProperty(FEATURE_TOOLTIP));
             QString aCaseId = qs(myWidgetApi->getProperty(_ID));
index c4dc84c15c976b86d033e98574fd530843e7a47e..73113c0066ee5a3db32218dfd89d467381d73b2c 100644 (file)
@@ -1630,23 +1630,24 @@ void PartSet_Module::addObjectBrowserMenu(QMenu* theMenu) const
       } else if (aObject->document() == aMgr->activeDocument()) {
         if (hasParameter || hasFeature) {
 
-          // disable Edit menu for groups under ImportResult feature
           bool isEnabled = true;
-          if (aFeature.get() && aFeature->getKind() == "Group")
-          {
-            std::shared_ptr<ModelAPI_CompositeFeature> anOwner =
-              ModelAPI_Tools::compositeOwner (aFeature);
-
-            if (anOwner.get() && anOwner->getKind() == "ImportResult")
-            {
-              myMenuMgr->action("EDIT_CMD")->setEnabled(false);
-              isEnabled = false;
+          if (aFeature.get()) {
+            // disable Edit menu for not editable features
+            isEnabled = aFeature->isEditable();
+
+            // disable Edit menu for groups under ImportResult feature
+            if (aFeature->getKind() == "Group") {
+              std::shared_ptr<ModelAPI_CompositeFeature> anOwner =
+                ModelAPI_Tools::compositeOwner (aFeature);
+              if (anOwner.get() && anOwner->getKind() == "ImportResult") {
+                isEnabled = false;
+              }
             }
           }
 
-          if (isEnabled)
-          {
-            myMenuMgr->action("EDIT_CMD")->setEnabled(true);
+          myMenuMgr->action("EDIT_CMD")->setEnabled(isEnabled);
+
+          if (isEnabled) {
             theMenu->addAction(myMenuMgr->action("EDIT_CMD"));
             if (aCurrentOp && aFeature.get()) {
               if (aCurrentOp->id().toStdString() == aFeature->getKind())
index 2e43b1241ec636b1435d38b84d008dd29de762ef..188d4abf994e9cd5f513da21054eef746fccba26 100644 (file)
@@ -19,7 +19,8 @@
 """Package for Exchange plugin for the Parametric Geometry API of the Modeler.
 """
 
-from ExchangeAPI import addImport, addImportSTEP, exportToFile, exportToXAO, exportToSTL
+from ExchangeAPI import addImport, addImportXAOMem, addImportSTEP
+from ExchangeAPI import exportToFile, exportToXAO, exportToXAOMem, exportToSTL
 from ExchangeAPI import exportPart, importPart, addImportImage
 
 from .tools import *
index 4ba49c5f5beb7966303c933d524b53fd0f4fbef1..9816b43ae88bdd50f6ee89b6df2979801e1f2c53 100644 (file)
@@ -655,7 +655,9 @@ const std::string XaoExporter::saveToXml(Xao* xaoObject)
 
     xmlChar *xmlbuff;
     int buffersize;
-    xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1); // format = 1 for node indentation
+    //xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1); // format = 1 for node indentation
+    // save with encoding to correspond to "saveToFile" and provide the same file size
+    xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "UTF-8", 1); // format = 1 for node indentation
     xmlFreeDoc(doc);
     xmlCleanupGlobals();