From ff960fc7d0add1a550cfbe16f2f569ee0170eb95 Mon Sep 17 00:00:00 2001 From: jfa Date: Wed, 21 Jun 2023 12:12:34 +0100 Subject: [PATCH] [bos #35140] [EDF] (2023-T1) Memory communication between SHAPER and GEOM --- .../Test/CTestTestfileInstall.cmake | 6 + src/ConnectorAPI/Test/TestExportXAOMem.py | 108 ++++++++++++++++ src/ConnectorAPI/Test/TestImportXAOMem.py | 117 ++++++++++++++++++ src/ConnectorAPI/Test/tests.set | 5 + src/ExchangeAPI/CMakeLists.txt | 2 + src/ExchangeAPI/ExchangeAPI_Export.cpp | 95 ++++++++++++-- src/ExchangeAPI/ExchangeAPI_Export.h | 115 ++++++++++------- src/ExchangeAPI/ExchangeAPI_Import.cpp | 74 ++++++++--- src/ExchangeAPI/ExchangeAPI_Import.h | 23 +++- .../ExchangePlugin_ExportFeature.cpp | 47 +++++-- .../ExchangePlugin_ExportFeature.h | 13 +- .../ExchangePlugin_ImportFeature.cpp | 61 ++++++--- .../ExchangePlugin_ImportFeature.h | 10 +- src/ExchangePlugin/doc/exportFeature.rst | 8 ++ src/ExchangePlugin/doc/importFeature.rst | 7 ++ src/ExchangePlugin/export_widget.xml | 10 ++ src/ExchangePlugin/plugin-Exchange.xml | 60 +++++---- src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.cpp | 37 ++++++ src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.h | 5 + src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.cpp | 43 +++++++ src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.h | 6 + src/ModuleBase/ModuleBase_WidgetFactory.cpp | 1 + src/PythonAPI/model/exchange/__init__.py | 3 +- src/XAO/XAO_XaoExporter.cxx | 4 +- 24 files changed, 724 insertions(+), 136 deletions(-) create mode 100644 src/ConnectorAPI/Test/TestExportXAOMem.py create mode 100644 src/ConnectorAPI/Test/TestImportXAOMem.py diff --git a/src/ConnectorAPI/Test/CTestTestfileInstall.cmake b/src/ConnectorAPI/Test/CTestTestfileInstall.cmake index 798d8a908..d0a5b6188 100644 --- a/src/ConnectorAPI/Test/CTestTestfileInstall.cmake +++ b/src/ConnectorAPI/Test/CTestTestfileInstall.cmake @@ -29,3 +29,9 @@ FOREACH(tfile ${TEST_NAMES}) 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 index 000000000..5d67a7452 --- /dev/null +++ b/src/ConnectorAPI/Test/TestExportXAOMem.py @@ -0,0 +1,108 @@ +# Copyright (C) 2014-2022 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 +# + +""" + 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 index 000000000..ea79eadce --- /dev/null +++ b/src/ConnectorAPI/Test/TestImportXAOMem.py @@ -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 + #========================================================================= diff --git a/src/ConnectorAPI/Test/tests.set b/src/ConnectorAPI/Test/tests.set index 3551d9f42..18052ebcc 100755 --- a/src/ConnectorAPI/Test/tests.set +++ b/src/ConnectorAPI/Test/tests.set @@ -31,3 +31,8 @@ SET(TEST_NAMES TestImportSTL TestImportSTEP ) + +SET(TEST_NAMES_ADV + TestExportXAOMem + TestImportXAOMem +) diff --git a/src/ExchangeAPI/CMakeLists.txt b/src/ExchangeAPI/CMakeLists.txt index 848f9d5c1..b61b7834f 100644 --- a/src/ExchangeAPI/CMakeLists.txt +++ b/src/ExchangeAPI/CMakeLists.txt @@ -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 diff --git a/src/ExchangeAPI/ExchangeAPI_Export.cpp b/src/ExchangeAPI/ExchangeAPI_Export.cpp index cd3837642..d2d09ef20 100644 --- a/src/ExchangeAPI/ExchangeAPI_Export.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Export.cpp @@ -21,6 +21,8 @@ //-------------------------------------------------------------------------------------- #include //-------------------------------------------------------------------------------------- +#include +//-------------------------------------------------------------------------------------- #include #include #include @@ -28,6 +30,8 @@ #include #include //-------------------------------------------------------------------------------------- +#include +//-------------------------------------------------------------------------------------- ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr& theFeature) : ModelHighAPI_Interface(theFeature) @@ -97,11 +101,12 @@ ExchangeAPI_Export::ExchangeAPI_Export(const std::shared_ptr& 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& 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& 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& 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 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& 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 & thePart, } ExportPtr exportToXAO(const std::shared_ptr & 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 aFeature = @@ -286,6 +345,20 @@ ExportPtr exportToXAO(const std::shared_ptr & thePart, return ExportPtr(new ExchangeAPI_Export(aFeature, theFilePath, theSelectedShape, "XAO")); } +PyObject* exportToXAOMem(const std::shared_ptr & 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 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 & thePart, const std::string & theFilePath, const std::list & theSelected) diff --git a/src/ExchangeAPI/ExchangeAPI_Export.h b/src/ExchangeAPI/ExchangeAPI_Export.h index 42b16d12b..942d2473a 100644 --- a/src/ExchangeAPI/ExchangeAPI_Export.h +++ b/src/ExchangeAPI/ExchangeAPI_Export.h @@ -30,6 +30,9 @@ #include #include + +#include + //-------------------------------------------------------------------------------------- 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& 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& 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& 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& 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& 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 & thePart, */ EXCHANGEAPI_EXPORT ExportPtr exportToXAO(const std::shared_ptr & 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 & thePart, + const ModelHighAPI_Selection& theSelectedShape, + const std::string & theAuthor = std::string(), + const std::string & theGeometryName = std::string()); /** \ingroup CPPHighAPI diff --git a/src/ExchangeAPI/ExchangeAPI_Import.cpp b/src/ExchangeAPI/ExchangeAPI_Import.cpp index 195a1af80..e204bfd2d 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Import.cpp @@ -21,6 +21,8 @@ //-------------------------------------------------------------------------------------- #include //-------------------------------------------------------------------------------------- +#include +//-------------------------------------------------------------------------------------- #include #include #include @@ -54,6 +56,19 @@ ExchangeAPI_Import::ExchangeAPI_Import( setFilePath(theFilePath); } +ExchangeAPI_Import::ExchangeAPI_Import( + const std::shared_ptr & 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 & 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 & thePart, + PyObject* theBuffer) +{ + std::shared_ptr 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 & thePart, const std::string & theFilePath, diff --git a/src/ExchangeAPI/ExchangeAPI_Import.h b/src/ExchangeAPI/ExchangeAPI_Import.h index 9618bd73a..517d70c72 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.h +++ b/src/ExchangeAPI/ExchangeAPI_Import.h @@ -31,7 +31,10 @@ #include #include #include + +#include //-------------------------------------------------------------------------------------- + /**\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 & theFeature); + /// Constructor with values EXCHANGEAPI_EXPORT ExchangeAPI_Import(const std::shared_ptr & theFeature, const std::string & theFilePath); + /// Constructor with values for XAO import from memory buffer + EXCHANGEAPI_EXPORT + ExchangeAPI_Import(const std::shared_ptr & theFeature, + const std::string & theFilePath, + const std::string & theBuffer); + /// Constructor with values for Step file EXCHANGEAPI_EXPORT ExchangeAPI_Import(const std::shared_ptr & 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 & 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 & thePart, + PyObject* theBuffer); + /**\ingroup CPPHighAPI * \brief Create Import Step feature */ diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp index 54400c686..f5bb969f6 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.h b/src/ExchangePlugin/ExchangePlugin_ExportFeature.h index 7752d3da2..34cf47d97 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.h +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.h @@ -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); diff --git a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp index e73ccfbe3..491c87290 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ImportFeature.cpp @@ -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,6 +106,8 @@ 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()); } /* * Computes or recomputes the results @@ -113,20 +116,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 +374,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 aGeomShape = XAOImport(theFileName, anError, &aXao); + std::shared_ptr 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,7 +401,7 @@ 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()) + if (aBodyName.empty() && !isMemoryImport) aBodyName = GeomAlgoAPI_Tools::File_Tools::name(theFileName); data()->setName(Locale::Convert::toWString(aBodyName)); @@ -549,7 +576,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 diff --git a/src/ExchangePlugin/ExchangePlugin_ImportFeature.h b/src/ExchangePlugin/ExchangePlugin_ImportFeature.h index 54a60230d..53f25c342 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportFeature.h +++ b/src/ExchangePlugin/ExchangePlugin_ImportFeature.h @@ -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 { @@ -166,7 +172,9 @@ protected: 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 diff --git a/src/ExchangePlugin/doc/exportFeature.rst b/src/ExchangePlugin/doc/exportFeature.rst index 1773c9bf9..6d22c83d1 100644 --- a/src/ExchangePlugin/doc/exportFeature.rst +++ b/src/ExchangePlugin/doc/exportFeature.rst @@ -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: A being exported object + :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 """""" diff --git a/src/ExchangePlugin/doc/importFeature.rst b/src/ExchangePlugin/doc/importFeature.rst index 817c5c1cb..5daac002f 100644 --- a/src/ExchangePlugin/doc/importFeature.rst +++ b/src/ExchangePlugin/doc/importFeature.rst @@ -91,6 +91,13 @@ In case of first choice the format of imported file will be defined according to :param part: The current part object :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: The current part object + :param aBuffer: A byte array with data in XAO format. + Result """""" diff --git a/src/ExchangePlugin/export_widget.xml b/src/ExchangePlugin/export_widget.xml index 83b9aba4d..9eff85040 100644 --- a/src/ExchangePlugin/export_widget.xml +++ b/src/ExchangePlugin/export_widget.xml @@ -31,6 +31,16 @@ placeholder="Please input the geometry name"> + + + + + + - - - + + + - - - - + + + + + string_list_attribute="step_target_parts_list" + label="Import to" + tooltip="Select the part to import the document" /> + label="Scale to International System of Units" + default="true"/> + label="Materials" + default="false"/> + label="Colors" + default="false"/> + + - + + @@ -49,6 +52,7 @@ label="Import to" tooltip="Select the image to import the document" /> + @@ -63,18 +67,20 @@ + label="Scale to International System of Units" + default="true"/> + label="Materials" + default="false"/> + label="Colors" + default="false"/> + + + + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.cpp index 2efa08173..7575d8630 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.cpp @@ -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(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; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.h b/src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.h index bc312aeb5..ebe72b5b6 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_XAOExport.h @@ -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_ */ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.cpp index 864e42b9b..5d4941bef 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.cpp @@ -66,3 +66,46 @@ std::shared_ptr XAOImport(const std::string& theFileName, aGeomShape->setImpl(new TopoDS_Shape(aShape)); return aGeomShape; } + +//============================================================================= +/*! + * + */ +//============================================================================= +std::shared_ptr 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(); + } + + 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(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 aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aShape)); + return aGeomShape; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.h b/src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.h index 7c9faf02f..b8fb4b84a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_XAOImport.h @@ -36,4 +36,10 @@ std::shared_ptr 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 XAOImportMem(const std::string& theMemoryBuff, + std::string& theError, + XAO::Xao* theXao); + #endif /* GEOMALGOAPI_XAOIMPORT_H_ */ diff --git a/src/ModuleBase/ModuleBase_WidgetFactory.cpp b/src/ModuleBase/ModuleBase_WidgetFactory.cpp index a5824c6f2..3db9ade98 100644 --- a/src/ModuleBase/ModuleBase_WidgetFactory.cpp +++ b/src/ModuleBase/ModuleBase_WidgetFactory.cpp @@ -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)); diff --git a/src/PythonAPI/model/exchange/__init__.py b/src/PythonAPI/model/exchange/__init__.py index 4ca8d345a..42aa23f69 100644 --- a/src/PythonAPI/model/exchange/__init__.py +++ b/src/PythonAPI/model/exchange/__init__.py @@ -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 * diff --git a/src/XAO/XAO_XaoExporter.cxx b/src/XAO/XAO_XaoExporter.cxx index 8fabe338b..b07c333b9 100644 --- a/src/XAO/XAO_XaoExporter.cxx +++ b/src/XAO/XAO_XaoExporter.cxx @@ -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(); -- 2.39.2