From dae7f73a8848b6acae0a45315286f7f89d8203aa Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 5 Feb 2020 18:07:53 +0300 Subject: [PATCH] Implementation of python dump of SHAPER STUDY for results and groups using XAO file format. --- CMakeLists.txt | 11 +++ src/PY/SHAPERSTUDY.py | 115 ++++++++++++++++++++++++---- src/SWIG/StudyData_Swig.i | 2 + src/StudyData/CMakeLists.txt | 7 +- src/StudyData/StudyData_XAO.cpp | 128 ++++++++++++++++++++++++++++++++ src/StudyData/StudyData_XAO.h | 67 +++++++++++++++++ 6 files changed, 311 insertions(+), 19 deletions(-) create mode 100644 src/StudyData/StudyData_XAO.cpp create mode 100644 src/StudyData/StudyData_XAO.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 87b80c4..f6ab31e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,17 @@ ELSE(EXISTS ${GEOM_ROOT_DIR}) MESSAGE(FATAL_ERROR "We absolutely need a Salome GEOM, please define GEOM_ROOT_DIR") ENDIF(EXISTS ${GEOM_ROOT_DIR}) +# Find SHAPER +# =========== +SET(SHAPER_ROOT_DIR $ENV{SHAPER_ROOT_DIR} CACHE PATH "Path to the Salome SHAPER") +IF(EXISTS ${SHAPER_ROOT_DIR}) + SET_AND_CHECK(SHAPER_INCLUDE_DIRS "${SHAPER_ROOT_DIR}/include/salome") + INCLUDE_DIRECTORIES(${SHAPER_INCLUDE_DIRS}) + find_library(LIB_XAOShaper NAMES XAOShaper PATHS ${SHAPER_ROOT_DIR}/lib/salome) +ELSE(EXISTS ${SHAPER_ROOT_DIR}) + MESSAGE(FATAL_ERROR "We absolutely need a Salome SHAPER, please define SHAPER_ROOT_DIR") +ENDIF(EXISTS ${SHAPER_ROOT_DIR}) + # Detection summary: SALOME_PACKAGE_REPORT_AND_CHECK() diff --git a/src/PY/SHAPERSTUDY.py b/src/PY/SHAPERSTUDY.py index 8aa739f..93789f5 100644 --- a/src/PY/SHAPERSTUDY.py +++ b/src/PY/SHAPERSTUDY.py @@ -32,6 +32,8 @@ import SHAPERSTUDY_IOperations import GEOM import SMESH +import StudyData_Swig + __entry2IOR__ = {} __entry2DumpName__ = {} @@ -342,6 +344,23 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, salome.orb.string_to_object(aRes).SetSO(getStudy().FindObjectID(sobject.GetID())) return aRes return "" + + def UniqueDumpName( self, theBaseName, theID ): + """ + Returns a unique name from the theBaseName. Keeps theBaseName if it was not used yet. + Stores the newly generated name into the global map __entry2DumpName__. + """ + global __entry2DumpName__ + aPrefix = 1 + # to avoid spaces and parenthesis in the variable name + aBaseName = theBaseName.replace(" ", "_").replace("(", "").replace(")", "") + aName = aBaseName + while aName in __entry2DumpName__: + aName = aBaseName + "_" + str(aPrefix) + aPrefix = aPrefix + 1 + __entry2DumpName__[theID] = aName + return aName + def DumpPython( self, isPublished, isMultiFile ): """ @@ -349,6 +368,7 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, """ global __entry2DumpName__ __entry2DumpName__.clear() + anArchiveNum = 1 # collect all shape-objects in the SHAPERSTUDY tree aShapeObjects = [] aStudy = getStudy() @@ -367,12 +387,6 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, script.append("\tmodel.publishToShaperStudy()") script.append("import SHAPERSTUDY") for aShapeObj in aShapeObjects: - aVarName = anObj.GetName() - aPrefix = 1 - while aVarName in __entry2DumpName__: - aVarName = anObj.GetName() + "_" + str(aPrefix) - aPrefix = aPrefix + 1 - __entry2DumpName__[aSO.GetID()] = aVarName # check this shape also has sub-groups and fields aGroupVarNames = [] aSOIter = aStudy.NewChildIterator(anObj.GetSO()) @@ -383,19 +397,46 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, aGroup = salome.orb.string_to_object(anIOR) if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group) or \ isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field): - aGroupVarName = aGroup.GetName() - aPrefix = 1 - while aGroupVarName in __entry2DumpName__: - aGroupVarName = aGroup.GetName() + "_" + str(aPrefix) - aPrefix = aPrefix + 1 - __entry2DumpName__[aGroupSO.GetID()] = aGroupVarName + aGroupVarName = self.UniqueDumpName(aGroup.GetName(), aGroupSO.GetID()) aGroupVarNames.append(aGroupVarName) aSOIter.Next() - aShapeStr = aVarName + aShapeVar = self.UniqueDumpName(anObj.GetName(), anObj.GetSO().GetID()) + aShapeStr = aShapeVar + ", " for aGName in aGroupVarNames: - aShapeStr = aShapeStr + ", " + aGName - aShapeStr = aShapeStr + " = SHAPERSTUDY.shape(\"" + anObj.GetEntry() +"\")" + aShapeStr = aShapeStr + aGName + ", " + aShapeStr = aShapeStr + "= SHAPERSTUDY.shape(\"" + anObj.GetEntry() +"\")" script.append(aShapeStr) + # dump also dead-shapes with groups and fields in the XAO format + aRes, aHistSO = aShapeObj.GetSO().FindSubObject(2) # the History folder + if aRes: + aDeads = aStudy.NewChildIterator(aHistSO) + while aDeads.More(): + aDSO = aDeads.Value() + aDIOR = aDSO.GetIOR() + if len(aDIOR): + aDeadShape = salome.orb.string_to_object(aDIOR) + if aDeadShape and type(aDeadShape) == SHAPERSTUDY_ORB._objref_SHAPER_Object: + aDeadString = "" + aXAO = StudyData_Swig.StudyData_XAO() + aXAO.SetShape(aDeadShape.getShape()) + anArchiveName = "archive_" + str(anArchiveNum) + ".xao" + anArchiveNum = anArchiveNum + 1 + aDeadVarName = self.UniqueDumpName(aDeadShape.GetName(), aDSO.GetID()) + aDeadString = aDeadString + aDeadVarName + ", " + aDGroupIter = aStudy.NewChildIterator(aDSO) + while aDGroupIter.More(): + aDeadGroup = aDGroupIter.Value().GetObject() + if isinstance(aDeadGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group): + aDGroupVarName = self.UniqueDumpName(aDeadGroup.GetName(), aDGroupIter.Value().GetID()) + aDeadString = aDeadString + aDGroupVarName + ", " + aGroupID = aXAO.AddGroup(aDeadGroup.GetSelectionType(), aDGroupVarName) + for aSel in aDeadGroup.GetSelection(): + aXAO.AddGroupSelection(aGroupID, aSel) + aDGroupIter.Next() + aXAO.Export(anArchiveName) + aDeadString = aDeadString + " = SHAPERSTUDY.archive(" + aShapeVar + ", \"" + anArchiveName + "\")" + script.append(aDeadString) + aDeads.Next() pass script.append("") # to have an end-line in the end @@ -540,3 +581,47 @@ def shape(theEntry): aSOIter.Next() return aRes return None # not found + +def archive(theShape, theXAOFile): + """ + Creates a dead shapes under the theShape and restores these dead objects state basing on theXAOFile + """ + theShape.MakeDead() + aStudy = getStudy() + # searching for the last dead + aDeads = aStudy.NewChildIterator(theShape.GetSO().FindSubObject(2)[1]) + aLastDeadSO = aDeads.Value() + while aDeads.More(): + aLastDeadSO = aDeads.Value() + aDeads.Next() + + aDShape = aLastDeadSO.GetObject() + if aDShape: + aXAO = StudyData_Swig.StudyData_XAO() + anError = aXAO.Import(theXAOFile) + if (len(anError)): + print("Error of XAO file import: " + anError) + return None + aDShape.SetShapeByPointer(aXAO.GetShape()) + aRes = (aDShape,) + # add groups and fields to the result + aGroupIndex = 0 + aSOIter = aStudy.NewChildIterator(aLastDeadSO) + while aSOIter.More(): + aGroupSO = aSOIter.Value() + anIOR = aGroupSO.GetIOR() + if len(anIOR): + aGroup = salome.orb.string_to_object(anIOR) + if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group): + aRes = aRes + (aGroup,) + aGroup.SetSelectionType(aXAO.GetGroupDimension(aGroupIndex)) + aSelection = [] + for aSel in aXAO.GetGroupSelection(aGroupIndex): + aSelection.append(aSel) + aGroup.SetSelection(aSelection) + aGroupIndex = aGroupIndex + 1 + elif isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field): + aRes = aRes + (aGroup,) + aSOIter.Next() + return aRes + return None # not found diff --git a/src/SWIG/StudyData_Swig.i b/src/SWIG/StudyData_Swig.i index 48b0445..2903bf8 100644 --- a/src/SWIG/StudyData_Swig.i +++ b/src/SWIG/StudyData_Swig.i @@ -5,6 +5,7 @@ %{ #include "StudyData_Object.h" #include "StudyData_Operation.h" +#include "StudyData_XAO.h" #include #include @@ -45,6 +46,7 @@ static PyObject* setOCCException(Standard_Failure& ex) %include "StudyData_Object.h" %include "StudyData_Operation.h" +%include "StudyData_XAO.h" %template(LongList) std::list; %template(PtrsList) std::list; diff --git a/src/StudyData/CMakeLists.txt b/src/StudyData/CMakeLists.txt index c3a4fa9..6189d6d 100644 --- a/src/StudyData/CMakeLists.txt +++ b/src/StudyData/CMakeLists.txt @@ -37,10 +37,7 @@ ADD_DEFINITIONS( SET(_link_LIBRARIES SalomeIDLGEOM ${OpenCASCADE_ModelingAlgorithms_LIBRARIES} - # ${OpenCASCADE_ModelingData_LIBRARIES} - # ${OpenCASCADE_ApplicationFramework_LIBRARIES} - # ${GEOM_NMTTools} - # ${GEOM_GEOMUtils} + ${LIB_XAOShaper} ) # --- headers --- @@ -50,6 +47,7 @@ SET(STUDYDATA_HEADERS StudyData.h StudyData_Object.h StudyData_Operation.h + StudyData_XAO.h ) # --- sources --- @@ -58,6 +56,7 @@ SET(STUDYDATA_HEADERS SET(STUDYDATA_SOURCES StudyData_Object.cpp StudyData_Operation.cpp + StudyData_XAO.cpp ) # --- rules --- diff --git a/src/StudyData/StudyData_XAO.cpp b/src/StudyData/StudyData_XAO.cpp new file mode 100644 index 0000000..c48da3b --- /dev/null +++ b/src/StudyData/StudyData_XAO.cpp @@ -0,0 +1,128 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "StudyData_XAO.h" + +#include +#include +#include +#include +#include + + +StudyData_XAO::StudyData_XAO() : myExport(NULL), myImport(NULL) +{} + +void StudyData_XAO::SetShape(const long long theShapePtr) +{ + myShape = (TopoDS_Shape*)(theShapePtr); + if (!myExport) + myExport = new XAO::Xao(); + XAO::BrepGeometry* aGeometry = new XAO::BrepGeometry; + myExport->setGeometry(aGeometry); + aGeometry->setTopoDS_Shape(*myShape); +} + +int StudyData_XAO::AddGroup(const int theSelType, const std::string theGroupName) +{ + if (!myExport) + myExport = new XAO::Xao(); + XAO::Dimension aDimension; + switch(theSelType) { + case 7: aDimension = XAO::VERTEX; break; + case 6: aDimension = XAO::EDGE; break; + case 4: aDimension = XAO::FACE; break; + case 2: aDimension = XAO::SOLID; break; + default: aDimension = XAO::WHOLE; + }; + XAO::Group* aNewGroup = myExport->addGroup(aDimension, theGroupName); + int anID = (int)myGroups.size(); + myGroups[anID] = aNewGroup; + return anID; +} + +void StudyData_XAO::AddGroupSelection(const int theGroupID, const int theSelection) +{ + XAO::Group* aGroup = myGroups[theGroupID]; + aGroup->add(theSelection); +} + +void StudyData_XAO::Export(const std::string theFileName) +{ + if (!myExport) + myExport = new XAO::Xao(); + myExport->setAuthor("ShaperStudy"); + + XAO::XaoExporter::saveToFile(myExport, theFileName, ""); +} + +std::string StudyData_XAO::Import(const std::string theFileName) +{ + std::string anError; + myImport = new XAO::Xao(); + try { + if (XAO::XaoExporter::readFromFile(theFileName, myImport)) { + XAO::Geometry* aGeometry = myImport->getGeometry(); + XAO::Format aFormat = aGeometry->getFormat(); + if (aFormat == XAO::BREP) { + if (XAO::BrepGeometry* aBrepGeometry = dynamic_cast(aGeometry)) + myShape = new TopoDS_Shape(aBrepGeometry->getTopoDS_Shape()); + } else { + anError = "Unsupported XAO geometry format:" + XAO::XaoUtils::shapeFormatToString(aFormat); + } + } else { + anError = "XAO object was not read successful"; + } + } catch (XAO::XAO_Exception& e) { + anError = e.what(); + } + + return anError; +} + +long long StudyData_XAO::GetShape() +{ + return (long long)(myShape); +} + +int StudyData_XAO::GetGroupDimension(const int theGroupID) +{ + XAO::Group* aXaoGroup = myImport->getGroup(theGroupID); + switch(aXaoGroup->getDimension()) { + case XAO::VERTEX: return 7; + case XAO::EDGE: return 6; + case XAO::FACE: return 4; + case XAO::SOLID: return 2; + default: return -1; + } + return -1; +} + +std::list StudyData_XAO::GetGroupSelection(const int theGroupID) +{ + XAO::Group* aXaoGroup = myImport->getGroup(theGroupID); + std::list aResult; + for (int anElementIndex = 0; anElementIndex < aXaoGroup->count(); ++anElementIndex) { + aResult.push_back(aXaoGroup->get(anElementIndex)); + } + return aResult; +} diff --git a/src/StudyData/StudyData_XAO.h b/src/StudyData/StudyData_XAO.h new file mode 100644 index 0000000..bc96381 --- /dev/null +++ b/src/StudyData/StudyData_XAO.h @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef StudyData_Object_H + +#include "StudyData.h" +#include + +#include +#include + +class TopoDS_Shape; + +class StudyData_XAO +{ + TopoDS_Shape* myShape; ///< the shape, part of XAO + XAO::Xao* myExport; ///< the XAO instance for export + XAO::Xao* myImport; ///< the XAO instance for export + std::map myGroups; ///< id of group to the group structure + +public: + StudyData_EXPORT StudyData_XAO(); + + // defines the shape for XAO export + StudyData_EXPORT void SetShape(const long long theShapePtr); + + // add a new group for export to XAO; returns id of this group + StudyData_EXPORT int AddGroup(const int theSelType, const std::string theGroupName); + // sets the selection for an already added group + StudyData_EXPORT void AddGroupSelection(const int theGroupID, const int theSelection); + + // performs the export to XAO + StudyData_EXPORT void Export(const std::string theFileName); + + // Imports the XAO data, returns the error string or empty one if it is ok. + StudyData_EXPORT std::string Import(const std::string theFileName); + + // Returns a pointer to the shape from XAO after import + StudyData_EXPORT long long GetShape(); + + // Returns a selection type of the group + StudyData_EXPORT int GetGroupDimension(const int theGroupID); + + // Returns a selection list of indices of the group + StudyData_EXPORT std::list GetGroupSelection(const int theGroupID); +}; + +#endif // !StudyData_XAO_H -- 2.30.2