]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge branch 'occ/shaper2smesh'
authorvsr <vsr@opencascade.com>
Fri, 21 Feb 2020 12:22:23 +0000 (15:22 +0300)
committervsr <vsr@opencascade.com>
Fri, 21 Feb 2020 12:22:23 +0000 (15:22 +0300)
27 files changed:
CMakeLists.txt
build_Salome_deb.bat
env_Salome.bat
salomeRun_deb.bat
src/ConnectorAPI/Test/TestShaperStudy1.py [new file with mode: 0644]
src/ConnectorAPI/Test/TestShaperStudy2.py [new file with mode: 0644]
src/ConnectorAPI/Test/TestShaperStudy3.py [new file with mode: 0644]
src/ConnectorAPI/Test/tests.set
src/ConnectorPlugin/CMakeLists.txt
src/ConnectorPlugin/ConnectorPlugin.py
src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py [new file with mode: 0644]
src/ConnectorPlugin/plugin-Connector.xml
src/ExchangePlugin/ExchangePlugin_Dump.cpp
src/ExchangePlugin/ExchangePlugin_Dump.h
src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h
src/ModelHighAPI/ModelHighAPI_Dumper.cpp
src/ModelHighAPI/ModelHighAPI_Dumper.h
src/PythonAPI/model/dump/DumpAssistant.py
src/PythonAPI/model/services/__init__.py
src/SHAPERGUI/SHAPERGUI.cpp
src/SHAPERGUI/SHAPERGUI.h
src/SHAPERGUI/SHAPERGUI_DataModel.cpp
src/XAO/CMakeLists.txt

index c63a22307b8a5cfe57f62eec4202265d439c847a..e8cbbbfef7d77fc8a9c47225f4c343169e5a205e 100644 (file)
@@ -97,6 +97,7 @@ IF(${HAVE_SALOME})
     SET(SHAPER_INSTALL_BIN lib/salome CACHE INTERNAL "" FORCE)
     SET(SHAPER_INSTALL_PLUGIN_FILES lib/salome CACHE INTERNAL "" FORCE)
     SET(SHAPER_INSTALL_PYTHON_FILES bin/salome CACHE INTERNAL "" FORCE)
+    SET(SHAPER_INSTALL_HEADERS include/salome CACHE INTERNAL "" FORCE)
     SET(SHAPER_INSTALL_RESOURCES share/salome/resources/shaper CACHE INTERNAL "" FORCE)
     SET(SHAPER_INSTALL_QM_RESOURCES share/salome/resources/shaper CACHE INTERNAL "" FORCE)
     SET(SHAPER_INSTALL_XML_RESOURCES share/salome/resources/shaper CACHE INTERNAL "" FORCE)
index a65baa442e0369a644a66f8c65a4a0e23a1dd514..9ab127ec1e7cc685cd7fcb985e6fca501a35e8e1 100644 (file)
@@ -10,7 +10,7 @@ popd
 @SET SRC_DIR=%ROOT_DIR%\sources
 @SET OCC_LIB_PREFIX=d
 
-call %SRC_DIR%\env_Salome.bat d
+call %SRC_DIR%\env_Salome.bat d comp
 mkdir %ROOT_DIR%\build
 cd %ROOT_DIR%\build
 
index 57d9e32f6d3ad673c0ee8cf54677fee9d9556586..c10acdb0c2bd2de6df116e5a47c388fa8b6e0049 100644 (file)
@@ -40,7 +40,13 @@ if "%BOOST_ROOT_DIR%" == "" (
 
 cd /d %SALOME_ROOT_DIR%\WORK
 call set_env.bat %1
-call "%PDIR%\env_compile.bat"
+
+if %2 == run (
+  call "%PDIR%\env_launch.bat"
+) else (
+  call "%PDIR%\env_compile.bat"
+)
+
 cd /d %ROOT_DIR%
 
 @REM -------------------------
index 17e988d5561f14898566f99b13c4ea519d4ab4fa..5534c345ce059291fb2514d36701ddbd1658f51e 100644 (file)
@@ -8,7 +8,7 @@ pushd %PARENT_DIR%
 popd
 
 @SET OCC_LIB_PREFIX=d
-call env_Salome.bat d
+call env_Salome.bat d run
 
 rem Variable which is necessary for launching SALOME
 SET SALOME_PLEASE_SETUP_ENVIRONMENT_AS_BEFORE=1
diff --git a/src/ConnectorAPI/Test/TestShaperStudy1.py b/src/ConnectorAPI/Test/TestShaperStudy1.py
new file mode 100644 (file)
index 0000000..870278a
--- /dev/null
@@ -0,0 +1,161 @@
+# Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import sys
+import salome
+
+salome.salome_init()
+
+###
+### SHAPER component
+###
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "r", "15")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(25, 25, 15)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchCircle_1.center(), SketchAPI_Point(SketchPoint_1).coordinates(), 25)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchCircle_1.center(), SketchAPI_Point(SketchPoint_1).coordinates(), 25)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], "r")
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0)
+model.do()
+
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+Sketch_2 = model.addSketch(Part_2_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_2.addLine(-5.176380902051512, 19.31851652579896, 19.31851652579829, -5.176380902058602)
+SketchLine_2 = Sketch_2.addLine(19.31851652579829, -5.176380902058602, -14.14213562374638, -14.14213562374059)
+SketchConstraintCoincidence_1 = Sketch_2.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_2.addLine(-14.14213562374638, -14.14213562374059, -5.176380902051512, 19.31851652579896)
+SketchConstraintCoincidence_2 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint())
+SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintEqual_2 = Sketch_2.setEqual(SketchLine_1.result(), SketchLine_2.result())
+SketchProjection_2 = Sketch_2.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_2 = SketchProjection_2.createdFeature()
+SketchConstraintDistance_1 = Sketch_2.setDistance(SketchLine_2.startPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), 20, True)
+SketchConstraintDistance_2 = Sketch_2.setDistance(SketchLine_3.endPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), 20, True)
+SketchConstraintDistance_3 = Sketch_2.setDistance(SketchLine_3.startPoint(), SketchAPI_Point(SketchPoint_2).coordinates(), 20, True)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_4 = SketchProjection_3.createdFeature()
+SketchConstraintAngle_1 = Sketch_2.setAngle(SketchLine_3.result(), SketchLine_4.result(), 75)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_2_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3r-SketchLine_2r-SketchLine_1r")], model.selection(), 30, 0)
+Fillet_1 = model.addFillet(Part_2_doc, [model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_3][Extrusion_1_1/To_Face]")], 2)
+model.do()
+
+Part_3 = model.addPart(partSet)
+Part_3_doc = Part_3.document()
+Sketch_3 = model.addSketch(Part_3_doc, model.defaultPlane("XOZ"))
+SketchLine_5 = Sketch_3.addLine(52.5, 35, 22.5, 35)
+SketchLine_6 = Sketch_3.addLine(22.5, 35, 22.5, 15)
+SketchLine_7 = Sketch_3.addLine(22.5, 15, 52.5, 15)
+SketchLine_8 = Sketch_3.addLine(52.5, 15, 52.5, 35)
+SketchConstraintCoincidence_4 = Sketch_3.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_5 = Sketch_3.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_6 = Sketch_3.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_7 = Sketch_3.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_1 = Sketch_3.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_1 = Sketch_3.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_2 = Sketch_3.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_2 = Sketch_3.setVertical(SketchLine_8.result())
+SketchLine_9 = Sketch_3.addLine(0, 0, 52.5, 35)
+SketchLine_9.setAuxiliary(True)
+SketchProjection_4 = Sketch_3.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_3 = SketchProjection_4.createdFeature()
+SketchConstraintCoincidence_8 = Sketch_3.setCoincident(SketchLine_9.startPoint(), SketchPoint_3.result())
+SketchConstraintCoincidence_9 = Sketch_3.setCoincident(SketchLine_5.startPoint(), SketchLine_9.endPoint())
+SketchConstraintCoincidence_10 = Sketch_3.setCoincident(SketchLine_6.endPoint(), SketchLine_9.result())
+SketchConstraintLength_1 = Sketch_3.setLength(SketchLine_8.result(), 20)
+SketchConstraintLength_2 = Sketch_3.setLength(SketchLine_5.result(), 30)
+SketchConstraintDistanceVertical_2 = Sketch_3.setVerticalDistance(SketchLine_7.endPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 15)
+model.do()
+Revolution_1 = model.addRevolution(Part_3_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f")], model.selection("EDGE", "PartSet/OX"), 45, 0)
+model.end()
+
+###
+### SHAPERSTUDY component
+###
+
+if 'model' in globals():
+  model.publishToShaperStudy()
+import SHAPERSTUDY
+Extrusion_1_1, = SHAPERSTUDY.shape(model.featureStringId(Extrusion_1))
+Fillet_1_1, = SHAPERSTUDY.shape(model.featureStringId(Fillet_1))
+Revolution_1_1, = SHAPERSTUDY.shape(model.featureStringId(Revolution_1))
+###
+### SMESH component
+###
+
+import  SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New()
+#smesh.SetEnablePublish( False ) # Set to False to avoid publish in study if not needed or in some particular situations:
+                                 # multiples meshes built in parallel, complex and numerous mesh edition (performance)
+
+Mesh_1 = smesh.Mesh(Fillet_1_1)
+Regular_1D = Mesh_1.Segment()
+Number_of_Segments_1 = Regular_1D.NumberOfSegments(7,None,[])
+MEFISTO_2D = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO)
+Max_Element_Area_1 = MEFISTO_2D.MaxElementArea(20)
+isDone = Mesh_1.Compute()
+assert(isDone)
+Mesh_2 = smesh.Mesh(Extrusion_1_1)
+Cartesian_3D = Mesh_2.BodyFitted()
+Body_Fitting_Parameters_1 = Cartesian_3D.SetGrid([ [ '4.3589' ], [ 0, 1 ]],[ [ '4.3589' ], [ 0, 1 ]],[ [ '4.3589' ], [ 0, 1 ]],4,0)
+Body_Fitting_Parameters_1.SetFixedPoint( SMESH.PointStruct ( 0, 0, 0 ), 1 )
+Body_Fitting_Parameters_1.SetAxesDirs( SMESH.DirStruct( SMESH.PointStruct ( 1, 0, 0 )), SMESH.DirStruct( SMESH.PointStruct ( 0, 1, 0 )), SMESH.DirStruct( SMESH.PointStruct ( 0, 0, 1 )) )
+isDone = Mesh_2.Compute()
+assert(isDone)
+Mesh_3 = smesh.Mesh(Revolution_1_1)
+status = Mesh_3.AddHypothesis(Number_of_Segments_1)
+Regular_1D_1 = Mesh_3.Segment()
+isDone = Mesh_3.Compute()
+assert(isDone)
+
+## Set names of Mesh objects
+smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
+smesh.SetName(MEFISTO_2D.GetAlgorithm(), 'MEFISTO_2D')
+smesh.SetName(Cartesian_3D.GetAlgorithm(), 'Cartesian_3D')
+smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')
+smesh.SetName(Mesh_2.GetMesh(), 'Mesh_2')
+smesh.SetName(Mesh_3.GetMesh(), 'Mesh_3')
+smesh.SetName(Body_Fitting_Parameters_1, 'Body Fitting Parameters_1')
+smesh.SetName(Max_Element_Area_1, 'Max. Element Area_1')
+smesh.SetName(Number_of_Segments_1, 'Number of Segments_1')
+
+# check the SHAPER study objects generated names
+assert(Extrusion_1_1.GetName() == "Extrusion_1_1")
+assert(Fillet_1_1.GetName() == "Fillet_1_1")
+assert(Revolution_1_1.GetName() == "Revolution_1_1")
+# check the smesh mesh is computed correctly
+assert(Mesh_1.NbNodes() == 235)
+assert(Mesh_2.NbNodes() == 168)
+assert(Mesh_3.NbNodes() == 80)
diff --git a/src/ConnectorAPI/Test/TestShaperStudy2.py b/src/ConnectorAPI/Test/TestShaperStudy2.py
new file mode 100644 (file)
index 0000000..6b37049
--- /dev/null
@@ -0,0 +1,116 @@
+# Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import os
+import sys
+import salome
+
+salome.salome_init()
+
+#=========================================================================
+# A function to get the XAO file path
+#=========================================================================
+def getPath(path):
+    shapes_dir = os.path.join(os.getenv("DATA_DIR"), "Shapes")
+    return os.path.join(shapes_dir, path)
+
+###
+### SHAPER component
+###
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(147.3929660820667, 79.1580464539047, 58.09363834643254, 79.1580464539047)
+SketchLine_2 = Sketch_1.addLine(58.09363834643254, 79.1580464539047, 58.09363834643254, 8.969712804393431)
+SketchLine_3 = Sketch_1.addLine(58.09363834643254, 8.969712804393431, 147.3929660820667, 8.969712804393431)
+SketchLine_4 = Sketch_1.addLine(147.3929660820667, 8.969712804393431, 147.3929660820667, 79.1580464539047)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f")], model.selection(), 150, 0)
+Extrusion_1.setName("Box")
+Extrusion_1.result().setName("Box")
+Group_1 = model.addGroup(Part_1_doc, "Vertices", [model.selection("VERTEX", "[Box/Generated_Face&Sketch_1/SketchLine_1][Box/Generated_Face&Sketch_1/SketchLine_2][Box/To_Face]"), model.selection("VERTEX", "[Box/Generated_Face&Sketch_1/SketchLine_3][Box/Generated_Face&Sketch_1/SketchLine_4][Box/To_Face]")])
+Group_1.setName("VerticesGroup")
+Group_1.result().setName("VerticesGroup")
+Group_2 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Box/Generated_Face&Sketch_1/SketchLine_4"), model.selection("FACE", "Box/Generated_Face&Sketch_1/SketchLine_3")])
+Group_2.setName("FacesGroup")
+Group_2.result().setName("FacesGroup")
+Field_1 = model.addField(Part_1_doc, 1, "DOUBLE", 3, ["Comp 1", "Comp 2", "Comp 3"], [model.selection("EDGE", "[Box/Generated_Face&Sketch_1/SketchLine_2][Box/Generated_Face&Sketch_1/SketchLine_3]")])
+Field_1.setName("MyField")
+Field_1.result().setName("MyField")
+Field_1.addStep(0, 0, [[0, 0, 0], [1, 1.5, 37.2]])
+
+model.end()
+
+###
+### SHAPERSTUDY component
+###
+
+if 'model' in globals():
+  model.publishToShaperStudy()
+import SHAPERSTUDY
+Box, VerticesGroup, FacesGroup, MyField, = SHAPERSTUDY.shape(model.featureStringId(Extrusion_1))
+Box_1, VerticesGroup_1, FacesGroup_1, MyField_1, = SHAPERSTUDY.archive(Box, getPath("Xao/TestShaperStudy2.xao"))
+###
+### SMESH component
+###
+
+import  SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New()
+#smesh.SetEnablePublish( False ) # Set to False to avoid publish in study if not needed or in some particular situations:
+                                 # multiples meshes built in parallel, complex and numerous mesh edition (performance)
+
+Mesh_1 = smesh.Mesh(Box)
+Regular_1D = Mesh_1.Segment()
+Number_of_Segments_1 = Regular_1D.NumberOfSegments(4)
+MEFISTO_2D = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO)
+Length_From_Edges_1 = MEFISTO_2D.LengthFromEdges()
+MEFISTO_2D_1 = Mesh_1.Triangle(algo=smeshBuilder.MEFISTO,geom=FacesGroup)
+Max_Element_Area_1 = MEFISTO_2D_1.MaxElementArea(2)
+Mesh_1.Compute()
+Mesh_1.GetMesh().ReplaceShape( Box_1 )
+SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject(Mesh_1.GetMesh()), Box_1)
+Mesh_1.Clear()
+Sub_mesh_1 = MEFISTO_2D_1.GetSubMesh()
+
+
+## Set names of Mesh objects
+smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
+smesh.SetName(MEFISTO_2D.GetAlgorithm(), 'MEFISTO_2D')
+smesh.SetName(Number_of_Segments_1, 'Number of Segments_1')
+smesh.SetName(Max_Element_Area_1, 'Max. Element Area_1')
+smesh.SetName(Length_From_Edges_1, 'Length From Edges_1')
+smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')
+smesh.SetName(Sub_mesh_1, 'Sub-mesh_1')
+
+assert(Mesh_1.Compute())
diff --git a/src/ConnectorAPI/Test/TestShaperStudy3.py b/src/ConnectorAPI/Test/TestShaperStudy3.py
new file mode 100644 (file)
index 0000000..991c333
--- /dev/null
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+
+###
+### This file is generated automatically by SALOME v9.4.0 with dump python functionality
+###
+
+import os
+import sys
+import salome
+
+salome.salome_init()
+
+#=========================================================================
+# A function to get the XAO file path
+#=========================================================================
+def getPath(path):
+    shapes_dir = os.path.join(os.getenv("DATA_DIR"), "Shapes")
+    return os.path.join(shapes_dir, path)
+
+###
+### SHAPER component
+###
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Param_H = model.addParameter(Part_1_doc, "h", "20")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(75.09305815883349, 77.46634028730745, 23.30071943952229, 77.46634028730745)
+SketchLine_2 = Sketch_1.addLine(23.30071943952229, 77.46634028730745, 23.30071943952229, 23.93663846925804)
+SketchLine_3 = Sketch_1.addLine(23.30071943952229, 23.93663846925804, 75.09305815883349, 23.93663846925804)
+SketchLine_4 = Sketch_1.addLine(75.09305815883349, 23.93663846925804, 75.09305815883349, 77.46634028730745)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f")], model.selection(), "h", 0)
+
+model.end()
+
+###
+### SHAPERSTUDY component
+###
+
+if 'model' in globals():
+  model.publishToShaperStudy()
+import SHAPERSTUDY
+Extrusion_1_1, = SHAPERSTUDY.shape(model.featureStringId(Extrusion_1))
+Extrusion_1_1_1, = SHAPERSTUDY.archive(Extrusion_1_1, getPath("Xao/TestShaperStudy2.xao"))
+###
+### SMESH component
+###
+
+import  SMESH, SALOMEDS
+from salome.smesh import smeshBuilder
+
+smesh = smeshBuilder.New()
+#smesh.SetEnablePublish( False ) # Set to False to avoid publish in study if not needed or in some particular situations:
+                                 # multiples meshes built in parallel, complex and numerous mesh edition (performance)
+
+Mesh_1 = smesh.Mesh(Extrusion_1_1)
+Cartesian_3D = Mesh_1.BodyFitted()
+Body_Fitting_Parameters_1 = Cartesian_3D.SetGrid([ [ '7.71225' ], [ 0, 1 ]],[ [ '7.71225' ], [ 0, 1 ]],[ [ '7.71225' ], [ 0, 1 ]],4,0)
+Body_Fitting_Parameters_1.SetFixedPoint( SMESH.PointStruct ( 0, 0, 0 ), 1 )
+Body_Fitting_Parameters_1.SetAxesDirs( SMESH.DirStruct( SMESH.PointStruct ( 1, 0, 0 )), SMESH.DirStruct( SMESH.PointStruct ( 0, 1, 0 )), SMESH.DirStruct( SMESH.PointStruct ( 0, 0, 1 )) )
+isDone = Mesh_1.Compute()
+Mesh_2 = smesh.Mesh(Extrusion_1_1)
+Regular_1D = Mesh_2.Segment()
+Number_of_Segments_1 = Regular_1D.NumberOfSegments(7)
+MEFISTO_2D = Mesh_2.Triangle(algo=smeshBuilder.MEFISTO)
+Max_Element_Area_1 = MEFISTO_2D.MaxElementArea(20)
+SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject(Mesh_2.GetMesh()), Extrusion_1_1_1)
+Mesh_2.GetMesh().ReplaceShape( Extrusion_1_1_1 )
+isDone = Mesh_2.Compute()
+
+
+## Set names of Mesh objects
+smesh.SetName(Cartesian_3D.GetAlgorithm(), 'Cartesian_3D')
+smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
+smesh.SetName(MEFISTO_2D.GetAlgorithm(), 'MEFISTO_2D')
+smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')
+smesh.SetName(Mesh_2.GetMesh(), 'Mesh_2')
+smesh.SetName(Max_Element_Area_1, 'Max. Element Area_1')
+smesh.SetName(Body_Fitting_Parameters_1, 'Body Fitting Parameters_1')
+smesh.SetName(Number_of_Segments_1, 'Number of Segments_1')
+
+# check on update of the initial box Mesh_1 computed on it is changed, Mesh_2 on dead shape is unchanged
+aNb1 = Mesh_1.NbElements()
+aNb2 = Mesh_2.NbElements()
+model.begin()
+Param_H.setValue(50)
+model.end()
+model.publishToShaperStudy()
+assert(Mesh_1.Compute())
+assert(Mesh_1.NbElements() > aNb1)
+assert(Mesh_2.Compute())
+assert(Mesh_2.NbElements() == aNb2)
index be23a5a85583f459f3a2b2cac302b9692448f6a5..fcd2f7f1ca470c9eed9f0467de441e831a60e908 100644 (file)
@@ -25,4 +25,7 @@ SET(TEST_NAMES
   TestExportToGEOMWholeFeature
   Test2882
   Test17917
+  TestShaperStudy1
+  TestShaperStudy2
+  TestShaperStudy3
 )
index 17a885057e9dfb3f69597e62025ea52b74b426b0..ddf16fa67fa71de1c6e103337e4e0721596db723 100644 (file)
@@ -22,6 +22,7 @@ INCLUDE(Common)
 SET(PYTHON_FILES
     ConnectorPlugin.py
     ConnectorPlugin_ExportFeature.py
+    ConnectorPlugin_PublishToStudyFeature.py
 )
 
 SET(XML_RESOURCES
index f16adee55871b3ad29316e9a96c67ca254acbae3..3886c20e2240480dcaf114acadd4b2e92319e4d7 100644 (file)
@@ -23,6 +23,7 @@
 import ModelAPI
 
 from ConnectorPlugin_ExportFeature import ExportFeature
+from ConnectorPlugin_PublishToStudyFeature import PublishToStudyFeature
 
 ## @ingroup Plugins
 #  The main class for management the construction features as plugin.
@@ -37,6 +38,8 @@ class ConnectorPlugin(ModelAPI.ModelAPI_Plugin):
     def createFeature(self, theFeatureID):
         if theFeatureID == ExportFeature.ID():
             return ExportFeature().__disown__()
+        elif theFeatureID == PublishToStudyFeature.ID():
+            return PublishToStudyFeature().__disown__()
         else:
             print("ConnectorPlugin: No such feature %s" % theFeatureID)
 
diff --git a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py
new file mode 100644 (file)
index 0000000..509b9a3
--- /dev/null
@@ -0,0 +1,245 @@
+# Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+## @package Plugins
+#  ExportFeature class definition
+
+import ModelAPI
+import ExchangeAPI
+import EventsAPI
+from GeomAPI import *
+import GeomAlgoAPI
+
+import salome
+from salome.shaper import model
+
+import SHAPERSTUDY_ORB
+import SHAPERSTUDY_utils
+
+## @ingroup Plugins
+#  Feature to export all shapes and groups into the GEOM module
+class PublishToStudyFeature(ModelAPI.ModelAPI_Feature):
+
+    ## The constructor.
+    def __init__(self):
+        ModelAPI.ModelAPI_Feature.__init__(self)
+        pass
+
+    @staticmethod
+    ## Export kind. Static.
+    def ID():
+        return "PublishToStudy"
+
+    ## Returns the kind of a feature.
+    def getKind(self):
+        return PublishToStudyFeature.ID()
+
+    ## This feature is action: has no property panel and executes immediately.
+    def isAction(self):
+        return True
+
+    ## This feature has no attributes, as it is action.
+    def initAttributes(self):
+        pass
+
+    ## Exports all shapes and groups into the GEOM module.
+    def execute(self):
+        aSession = ModelAPI.ModelAPI_Session.get()
+        aPartSet = aSession.moduleDocument()
+        # check that the PartSet document current feature is the last to avoid problems with all
+        # features update
+        if aPartSet.size(model.ModelAPI_Feature_group()) > 0:
+          aLastFeature = ModelAPI.objectToFeature(aPartSet.object(model.ModelAPI_Feature_group(), aPartSet.size(model.ModelAPI_Feature_group()) - 1))
+          aCurrentFeature = aPartSet.currentFeature(True)
+          if aLastFeature.data().featureId() != aCurrentFeature.data().featureId():
+            EventsAPI.Events_InfoMessage("PublishToStudy", "Not all PartSet parts are up-to-date, nothing is published. Please, make the last PartSet feature as current.", self).send()
+            return
+        # find a shaper-study component
+        salome.salome_init(1)
+        aComponent = SHAPERSTUDY_utils.findOrCreateComponent()
+        anEngine = SHAPERSTUDY_utils.getEngine()
+        # collect all processed internal entries to break the link of unprocessed later
+        allProcessed = []
+
+        # iterate all parts and all results to publish them in SHAPER_STUDY
+        for aPartId in range(aPartSet.size(model.ModelAPI_ResultPart_group())):
+          aPartObject = aPartSet.object(model.ModelAPI_ResultPart_group(), aPartId)
+          aPartRes = ModelAPI.modelAPI_ResultPart(ModelAPI.modelAPI_Result(aPartObject))
+          aPartDoc = aPartRes.partDoc()
+          if aPartDoc is None and aPartObject is not None:
+            EventsAPI.Events_InfoMessage("PublishToStudy", "For publish to SHAPER-STUDY some Part is not activated", self).send()
+            break
+          aPartFeatureId = aPartSet.feature(aPartRes).data().featureId()
+          for aResId in range(aPartDoc.size(model.ModelAPI_ResultBody_group())):
+            aResObject = aPartDoc.object(model.ModelAPI_ResultBody_group(), aResId)
+            aRes = model.objectToResult(aResObject)
+            aResFeatureId = aPartDoc.feature(aRes).data().featureId()
+            aSSEntry = str(aPartFeatureId) + ":" + str(aResFeatureId)
+            aSShape = anEngine.FindOrCreateShape(aSSEntry)
+            aSShape.SetShapeByStream(aRes.shape().getShapeStream(False))
+            if not aSShape.GetSO(): # publish in case it is a new shape
+              anEngine.AddInStudy(aSShape, aRes.data().name(), None)
+            else: # restore a red reference if it was deleted
+              aDone, aSO2 = aSShape.GetSO().FindSubObject(1)
+              if aDone:
+                aDone, aRef = aSO2.ReferencedObject()
+                if not aDone:
+                  aBuilder = SHAPERSTUDY_utils.getStudy().NewBuilder()
+                  aBuilder.Addreference(aSO2, aSShape.GetSO())
+            allProcessed.append(aSSEntry)
+            # Groups
+            self.processGroups(aRes, anEngine, aPartFeatureId, aSShape, False)
+            # Fields
+            self.processGroups(aRes, anEngine, aPartFeatureId, aSShape, True)
+
+        # process all SHAPER-STUDY shapes to find dead
+        aSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(aComponent)
+        while aSOIter.More():
+          aSO = aSOIter.Value()
+          aSOIter.Next() ### here because there is continue inside the loop!
+          anIOR = aSO.GetIOR()
+          if len(anIOR):
+            anObj = salome.orb.string_to_object(anIOR)
+            if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
+              anEntry = anObj.GetEntry()
+              if len(anEntry) == 0:
+                continue;
+              elif anEntry not in allProcessed: # found a removed shape: make it dead for the moment
+                # remove the reference - red node
+                aRes, aSO2 = aSO.FindSubObject(1)
+                if aRes:
+                  aRes, aRef = aSO2.ReferencedObject()
+                  if aRes:
+                    aBuilder = SHAPERSTUDY_utils.getStudy().NewBuilder()
+                    aBuilder.RemoveReference(aSO2)
+
+    # Part of the "execute" method: processes the Groups of theRes result publication.
+    # If theFields is true, the same is performed for Fields.
+    def processGroups(self, theRes, theEngine, thePartFeatureId, theStudyShape, theFields):
+      allGroupsProcessed = []
+      if theFields:
+        aRefGroups = ModelAPI.referencedFeatures(theRes, "Field", True)
+      else:
+        aRefGroups = ModelAPI.referencedFeatures(theRes, "Group", True)
+      for aRef in aRefGroups:
+        aGroupIndices = []
+        aGroupHasIndex = {}
+        aResShape = theRes.shape()
+        if theFields:
+          aSelList = aRef.selectionList("selected")
+        else:
+          aSelList = aRef.selectionList("group_list")
+        aSelType = GeomAPI_Shape.shapeTypeByStr(aSelList.selectionType())
+        for aSelIndex in range(aSelList.size()):
+          aSelection = aSelList.value(aSelIndex)
+          if aSelection.contextObject():
+            aShape = aSelection.value()
+            if aShape:
+              allShapesList = [] # collect all sub-shapes selected in the group
+              if aShape.shapeType() == 0: # compound
+                anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType)
+                while anExplorer.more():
+                  allShapesList.append(anExplorer.current())
+                  anExplorer.next()
+              else:
+                allShapesList.append(aShape)
+              # get index of each selected shape: if 0, this sub-shape is not in our result
+              for aSelected in allShapesList:
+                anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, aSelected)
+                if anId > 0 and not anId in aGroupHasIndex:
+                  aGroupIndices.append(anId)
+                  aGroupHasIndex[anId] = 0
+        if len(aGroupIndices): # create group
+          aGroupFeatureId = aRef.data().featureId()
+          if theFields:
+            aFieldOp = theEngine.GetIFieldOperations()
+            aGroupEntry = "field" + str(thePartFeatureId) + ":" + str(aGroupFeatureId)
+            aGroup = aFieldOp.FindField(theStudyShape, aGroupEntry)
+          else:
+            aGroupOp = theEngine.GetIGroupOperations()
+            aGroupEntry = "group" + str(thePartFeatureId) + ":" + str(aGroupFeatureId)
+            aGroup = aGroupOp.FindGroup(theStudyShape, aGroupEntry)
+          if not aGroup: # create a new
+            if theFields:
+              aGroup = aFieldOp.CreateFieldByType(theStudyShape, aSelType)
+            else:
+              aGroup = aGroupOp.CreateGroup(theStudyShape, aSelType)
+            aGroup.SetEntry(aGroupEntry)
+            theEngine.AddInStudy(aGroup, aRef.firstResult().data().name(), theStudyShape)
+          aGroup.SetSelection(aGroupIndices)
+          if theFields:
+            self.fillField(aGroup, aRef, theEngine, aGroupIndices)
+          # a group takes shape from the main result
+          #aGroup.SetShapeByStream(aRef.firstResult().shape().getShapeStream(False)) # group shape
+          allGroupsProcessed.append(aGroupEntry)
+      # check all existing groups: if some does not processed, remove it from the tree
+      aSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(theStudyShape.GetSO())
+      while aSOIter.More():
+        aSO = aSOIter.Value()
+        anIOR = aSO.GetIOR()
+        if len(anIOR):
+          anObj = salome.orb.string_to_object(anIOR)
+          if (theFields and isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Field)) or \
+             (not theFields and type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Group):
+            anEntry = anObj.GetEntry()
+            if anEntry not in allGroupsProcessed: # found a removed group => remove
+              aBuilder = SHAPERSTUDY_utils.getStudy().NewBuilder()
+              aBuilder.RemoveObject(anObj.GetSO())
+        aSOIter.Next()
+
+    # Part of the "execute" method: theFiled fields filling.
+    def fillField(self, theField, theFeature, theEngine, theSelectionIndices):
+      aTables = theFeature.tables("values")
+      aValType = aTables.type() # type of the values
+      theField.SetValuesType(aValType)
+      aNumSteps = aTables.tables() # number of steps is number of tables
+      aSteps = []
+      for aVal in range(aNumSteps):
+        aSteps.append(aVal + 1)
+      theField.SetSteps(aSteps)
+      aCompNames = []
+      aCompNamesAttr = theFeature.stringArray("components_names")
+      for anIndex in range(aCompNamesAttr.size()):
+        aCompNames.append(aCompNamesAttr.value(anIndex))
+      theField.SetComponents(aCompNames)
+      # prepare the sub-shapes indices: all values for all sub-shapes must be defined
+      aShapeOp = theEngine.GetIShapesOperations()
+      allIndices = aShapeOp.GetAllSubShapesIDs(theField.GetShape(), theField.GetSelectionType(), False)
+      # define steps
+      theField.ClearFieldSteps()
+      for aVal in range(aNumSteps):
+        aVals = []
+        for aCol in range(aTables.columns()):
+          #for aRow in range(aTables.rows()):
+          for anIndex in allIndices:
+            if anIndex in theSelectionIndices:
+              aRow = theSelectionIndices.index(anIndex) + 1 # starting from the first line
+            else:
+              aRow = 0 # default value
+            aStrVal = aTables.valueStr(aRow, aCol, aVal)
+            if aValType == 0: # boolean
+              if aStrVal == "True":
+                aVals.append(1)
+              else:
+                aVals.append(0)
+            elif aValType == 1: # int
+              aVals.append(int(aStrVal))
+            elif aValType == 2: # double
+              aVals.append(float(aStrVal))
+        theField.AddFieldStep(theFeature.intArray("stamps").value(aVal), aVal + 1, aVals)
index d0eb76878874fbf3892dbfc29e1db9a65084dba7..0d30be9b41990a9b73efc0347b04b40122403995 100644 (file)
@@ -7,6 +7,10 @@
         tooltip="Export all results and groups into GEOM module"
         icon="icons/Connector/geom_export.png"
         helpfile="ConnectorPlugin/ConnectorPlugin.html"/>
+      <feature
+        id="PublishToStudy"
+        title="Pyblish to study"
+        internal="1"/>
     </group>
   </workbench>
 </plugin>
\ No newline at end of file
index 097042a286c29427aa9dd52a64d2d1b56ed4b8f9..e955db6548ec522c169b2aac63f24b1785da8c86 100644 (file)
@@ -65,10 +65,13 @@ void ExchangePlugin_Dump::initAttributes()
   data()->addAttribute(GEOMETRIC_DUMP_ID(), ModelAPI_AttributeBoolean::typeId());
   data()->addAttribute(WEAK_NAMING_DUMP_ID(), ModelAPI_AttributeBoolean::typeId());
 
+  data()->addAttribute(EXPORT_VARIABLES_ID(), ModelAPI_AttributeBoolean::typeId());
+
   // default values
   boolean(TOPOLOGICAL_NAMING_DUMP_ID())->setValue(THE_DUMP_NAMING);
   boolean(GEOMETRIC_DUMP_ID())->setValue(THE_DUMP_GEO);
   boolean(WEAK_NAMING_DUMP_ID())->setValue(THE_DUMP_WEAK);
+  boolean(EXPORT_VARIABLES_ID())->setValue(false);
 }
 
 void ExchangePlugin_Dump::execute()
@@ -159,6 +162,14 @@ void ExchangePlugin_Dump::dump(const std::string& theFileName)
     aDumper->addCustomStorage(aWeakNamingStorage);
   }
 
-  if (!aDumper->process(aDoc, theFileName))
-    setError("An error occured while dumping to " + theFileName);
+  if (!aDumper->process(aDoc, theFileName)) {
+    setError("An error occurred while dumping to " + theFileName);
+  } else {
+    if (boolean(EXPORT_VARIABLES_ID())->value()) {
+      aDumper->exportVariables();
+    }
+  }
+  // clear cashed data after export variables was performed
+  aDumper->clearCustomStorage();
+
 }
index 5ee0f004b89e02e75912d3688a8ca3569b1f00f1..1d7127b0b5926c8ddf2e83447f131afd0d3bc419 100644 (file)
@@ -71,6 +71,13 @@ public:
     return MY_WEAK_NAMING_DUMP_ID;
   }
 
+  /// attribute name for boolean flag to export variable names correspondence to another module
+  inline static const std::string& EXPORT_VARIABLES_ID()
+  {
+    static const std::string MY_EXPORT_VARIABLES_ID("export_variables");
+    return MY_EXPORT_VARIABLES_ID;
+  }
+
   /// Default constructor
   EXCHANGEPLUGIN_EXPORT ExchangePlugin_Dump();
   /// Default destructor
index 81a78f0d8cc3ad574baa4497d7133584ac9af7ce..93500cc5e7660a345a7aa6e851878269123e23fe 100644 (file)
@@ -592,7 +592,7 @@ bool ExchangePlugin_ExportFeature::isMacro() const
     }
   }
 
-  if (aFormat == "XAO") { // on export to GEOm the selection attribute is filled - this is
+  if (aFormat == "XAO") { // on export to GEOM the selection attribute is filled - this is
                           // an exceptional case where export to XAO feature must be kept
     AttributeSelectionListPtr aList = aThis->selectionList(XAO_SELECTION_LIST_ID());
     return !aList->isInitialized() || aList->size() == 0;
index ce7788b54eacc00f2339011271663f62e27b0435..78a10ac3c5ffb0bb6940a29828e1a07dca6c034d 100644 (file)
@@ -32,6 +32,7 @@
 #include <BRepAlgoAPI_Section.hxx>
 #include <BRepBndLib.hxx>
 #include <BRepBuilderAPI_FindPlane.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepTools.hxx>
 #include <Bnd_Box.hxx>
@@ -638,11 +639,17 @@ GeomPointPtr GeomAPI_Shape::middlePoint() const
 }
 
 // LCOV_EXCL_START
-std::string GeomAPI_Shape::getShapeStream() const
+std::string GeomAPI_Shape::getShapeStream(const bool theWithTriangulation) const
 {
   std::ostringstream aStream;
   const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
-  BRepTools::Write(aShape, aStream);
+  if (!theWithTriangulation) { // make a copy of shape without triangulation
+    BRepBuilderAPI_Copy aCopy(aShape, Standard_False, Standard_False);
+    const TopoDS_Shape& aCopyShape = aCopy.Shape();
+    BRepTools::Write(aCopyShape, aStream);
+  } else {
+    BRepTools::Write(aShape, aStream);
+  }
   return aStream.str();
 }
 // LCOV_EXCL_STOP
index ec6e5737475df793f1c9dc9c5814a9f27b47b778..61fd4f5bc36372462ed275eaed21fa02e3edb47d 100644 (file)
@@ -192,7 +192,7 @@ public:
 
   /// Returns the shape as BRep stream
   GEOMAPI_EXPORT
-  std::string getShapeStream() const;
+  std::string getShapeStream(const bool theWithTriangulation = true) const;
 
   /// Returns intersection of shapes
   GEOMAPI_EXPORT
index 8714aca6204a3e9ef71c1e3597c48f03498ca9df..280281161658dff410af88e17ccdbc3f5677f53d 100644 (file)
@@ -866,4 +866,53 @@ void copyVisualizationAttrs(
   }
 }
 
+std::list<FeaturePtr> referencedFeatures(
+  std::shared_ptr<ModelAPI_Result> theTarget, const std::string& theFeatureKind,
+  const bool theSortResults)
+{
+  std::set<FeaturePtr> aResSet; // collect in the set initially to avoid duplicates
+  std::list<ResultPtr> allSubRes;
+  allSubRes.push_back(theTarget);
+  ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theTarget);
+  if (aBody.get())
+    allSubs(aBody, allSubRes);
+  std::list<ResultPtr>::iterator aSub = allSubRes.begin();
+  for(; aSub != allSubRes.end(); aSub++) {
+    const std::set<AttributePtr>& aRefs = (*aSub)->data()->refsToMe();
+    std::set<AttributePtr>::const_iterator aRef = aRefs.cbegin();
+    for(; aRef != aRefs.cend(); aRef++) {
+      FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+      if (aFeat.get() && (theFeatureKind.empty() || aFeat->getKind() == theFeatureKind))
+        aResSet.insert(aFeat);
+    }
+  }
+  // add also feature of the target that may be referenced as a whole
+  FeaturePtr aTargetFeature = theTarget->document()->feature(theTarget);
+  const std::set<AttributePtr>& aRefs = aTargetFeature->data()->refsToMe();
+  std::set<AttributePtr>::const_iterator aRef = aRefs.cbegin();
+  for(; aRef != aRefs.cend(); aRef++) {
+    FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+    if (aFeat.get() && (theFeatureKind.empty() || aFeat->getKind() == theFeatureKind))
+      aResSet.insert(aFeat);
+  }
+
+  std::list<FeaturePtr> aResList;
+  std::set<FeaturePtr>::iterator aResIter = aResSet.begin();
+  for(; aResIter != aResSet.end(); aResIter++) {
+    if (theSortResults) { // sort results by creation-order
+      std::list<FeaturePtr>::iterator aListIter = aResList.begin();
+      for(; aListIter != aResList.end(); aListIter++) {
+        if ((*aResIter)->document()->isLater(*aListIter, *aResIter))
+          break;
+      }
+      if (aListIter == aResList.end()) // goes to the end
+        aResList.push_back(*aResIter);
+      else
+        aResList.insert(aListIter, *aResIter);
+    } else //just push to the end unsorted
+      aResList.push_back(*aResIter);
+  }
+  return aResList;
+}
+
 } // namespace ModelAPI_Tools
index b0af5520bae730e1b3a1252f24df5a358bb42e70..a91e6250962e2a6feb5536760b643528850402c3 100644 (file)
@@ -236,6 +236,15 @@ MODELAPI_EXPORT double getTransparency(const std::shared_ptr<ModelAPI_Result>& t
 MODELAPI_EXPORT void copyVisualizationAttrs(std::shared_ptr<ModelAPI_Result> theSource,
                                             std::shared_ptr<ModelAPI_Result> theDest);
 
+/*! Produces list of features that reference to the given target (directly or through sub-results)
+* \param theTarget the referenced result
+* \param theFeatureKind the resulting features filter: the feature kind or all for the empty string
+* \param theSortResults to sort the resulting list of features by the features creation order
+*/
+MODELAPI_EXPORT std::list<std::shared_ptr<ModelAPI_Feature> > referencedFeatures(
+  std::shared_ptr<ModelAPI_Result> theTarget, const std::string& theFeatureKind,
+  const bool theSortResults);
+
 }
 
 #endif
index 1d655bbdfc93010dd1527512ef33200f9c9e50df..778b1c94c7c4573a139af74896bc2a929ea577f8 100644 (file)
@@ -648,7 +648,6 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theD
 
   // dump subfeatures and store result to file
   bool isOk = process(theDoc) && myDumpStorage->exportTo(theFileName, myModules);
-  clearCustomStorage();
   return isOk;
 }
 
@@ -1551,3 +1550,24 @@ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper,
 
   return theDumper;
 }
+
+
+void ModelHighAPI_Dumper::exportVariables() const
+{
+  DocumentPtr aRoot = ModelAPI_Session::get()->moduleDocument();
+  EntityNameMap::const_iterator aNameIter = myNames.cbegin();
+  for(; aNameIter != myNames.end(); aNameIter++) {
+    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aNameIter->first);
+    if (aFeature.get() && aFeature->document() != aRoot) {
+      FeaturePtr aPartFeat = ModelAPI_Tools::findPartFeature(aRoot, aFeature->document());
+      if (aPartFeat.get()) {
+        int aFeatureId = aFeature->data()->featureId();
+        int aPartId = aPartFeat->data()->featureId();
+        std::ostringstream anEntryStr;
+        anEntryStr<<aPartId<<":"<<aFeatureId;
+        std::string anEntry = anEntryStr.str();
+        exportVariable(anEntry, aNameIter->second.myCurrentName);
+      }
+    }
+  }
+}
index 90242c3aac90f0a2fd0a2f86b9ff6a1d05d13af5..ef81ae2128e2466bce9df2205cb8b6f1fa408930 100644 (file)
@@ -162,7 +162,6 @@ public:
   /// Clear custom storages list
   MODELHIGHAPI_EXPORT
   void clearCustomStorage();
-
   /// Dump given document into the file
   /// \return \c true, if succeed
   MODELHIGHAPI_EXPORT
@@ -347,6 +346,13 @@ public:
   MODELHIGHAPI_EXPORT
   bool isDumped(const std::shared_ptr<ModelAPI_AttributeRefList>& theRefList) const;
 
+  /// Export variables names to another module (calls exportVariable implemented in python)
+  MODELHIGHAPI_EXPORT virtual void exportVariables() const;
+
+  /// Export one variable name to another module (implemented in python)
+  MODELHIGHAPI_EXPORT virtual void exportVariable(
+    const std::string& theEntry, const std::string& theVarName) const {}
+
 protected:
   /// Dump "setName" command if last entity had user-defined name
   MODELHIGHAPI_EXPORT void dumpEntitySetName();
index 0b3eeb16745ef1f9f940a79467f389833bae1ce7..3170cc8570794ee6d7be7beeb43b2d38fb071a4e 100644 (file)
@@ -44,6 +44,7 @@ class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper):
         ModelHighAPI.ModelHighAPI_Dumper.__init__(self)
         ModelHighAPI.ModelHighAPI_Dumper.setInstance(self)
         self.collectFeatures()
+        self.myEngine = None
 
     ## Collect feature wrappers, which allow dumping (have method dump)
     def collectFeatures(self):
@@ -97,5 +98,18 @@ class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper):
             return self.myWrapperNames[aFeatureKind]
         return std_string()
 
+    ## Exports the dumped variables names to the SHAPERSTUDY
+    def exportVariable(self, theEntry, theVarName):
+        try:
+          if self.myEngine == None:
+            import SHAPERSTUDY_utils
+            aComponent = SHAPERSTUDY_utils.findOrCreateComponent()
+            self.myEngine = SHAPERSTUDY_utils.getEngine()
+          if self.myEngine != 1:
+            self.myEngine.StoreVariableName(theEntry, theVarName)
+        except:
+          self.myEngine = 1 # invalid access
+        pass
+
 # Instance of dumper
 dumper = DumpAssistant
index d585c1891f9f763f7c72b283abf3af3268d7c1f0..a8bd057618b390629cf6d69983c5173f11af4493 100644 (file)
@@ -29,3 +29,18 @@ from ModelHighAPI import reset
 from ModelHighAPI import addFolder, removeFolder
 from ModelHighAPI import ModelHighAPI_Selection as selection
 from ModelHighAPI import checkPythonDump as checkPythonDump
+from ModelAPI import findPartFeature
+
+# a method used for the python dump of the SHAPER STUDY
+def publishToShaperStudy():
+  begin()
+  activeDocument().addFeature("PublishToStudy")
+  end()
+
+# returns unique identifier of the feature : id of part it belongs to + ":" + id of feature
+def featureStringId(theFeature):
+  aRoot = moduleDocument()
+  aCurrent = theFeature.feature().document()
+  if aRoot and aCurrent:
+    return str(findPartFeature(aRoot, aCurrent).data().featureId()) + ":" + str(theFeature.feature().data().featureId())
+  return ""
index e9e7c0c0fddcea68b262c31c391c3977330e9f70..1ac461065e957c789673cdf65b4cd0e760221c6e 100644 (file)
@@ -452,6 +452,8 @@ bool SHAPERGUI::deactivateModule(SUIT_Study* theStudy)
   connect(getApp()->action(LightApp_Application::FileSaveAsId), SIGNAL(triggered(bool)),
           getApp(), SLOT(onSaveAsDoc()));
 
+  publishToStudy();
+
   return LightApp_Module::deactivateModule(theStudy);
 }
 
@@ -1186,3 +1188,9 @@ void SHAPERGUI::resetToolbars()
   SUIT_ResourceMgr* aResMgr = application()->resourceMgr();
   aResMgr->remove(ToolbarsSection);
 }
+
+void SHAPERGUI::publishToStudy()
+{
+  if (isActiveModule())
+    myWorkshop->module()->launchOperation("PublishToStudy", false);
+}
index 1c52678385d50ea1ab3a12f52032bbd8579d5f45..8db934c1683e27f19b922bd1929c3c46954c0e9e 100644 (file)
@@ -170,6 +170,8 @@ Q_OBJECT
 
   void resetToolbars();
 
+  void publishToStudy();
+
  public slots:
   /// \brief The method is redefined to connect to the study viewer before the data
   /// model is filled by opened file. This file open will flush redisplay signals for,
index efb30f936765a43c170cefea155ee697679e16a2..5a2effdc7fa16695843f6e1806feadc4aac9dffe 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <ModelAPI_Session.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeBoolean.h>
 #include <ExchangePlugin_Dump.h>
 
 #include <LightApp_Study.h>
@@ -85,6 +86,9 @@ bool SHAPERGUI_DataModel::open(const QString& thePath, CAM_Study* theStudy, QStr
 
 bool SHAPERGUI_DataModel::save(QStringList& theFiles)
 {
+  // Publish to study before saving of the data model
+  myModule->publishToStudy();
+
   LightApp_DataModel::save( theFiles );
   XGUI_Workshop* aWorkShop = myModule->workshop();
   std::list<std::string> aFileNames;
@@ -175,6 +179,8 @@ bool SHAPERGUI_DataModel::dumpPython(const QString& thePath, CAM_Study* theStudy
   if (!aStudy)
     return false;
 
+  myModule->publishToStudy();
+
   std::shared_ptr<ModelAPI_Document> aDoc = ModelAPI_Session::get()->activeDocument();
   ModelAPI_Session::get()->startOperation(ExchangePlugin_Dump::ID());
   FeaturePtr aFeature = aDoc->addFeature(ExchangePlugin_Dump::ID());
@@ -194,6 +200,10 @@ bool SHAPERGUI_DataModel::dumpPython(const QString& thePath, CAM_Study* theStudy
     if (aAttr.get())
       aAttr->setValue(".py");
 
+#ifdef HAVE_SALOME
+    aFeature->boolean(ExchangePlugin_Dump::EXPORT_VARIABLES_ID())->setValue(true);
+#endif
+
     ModelAPI_Session::get()->finishOperation();
 
     if (QFile::exists(aFileName.c_str())) {
@@ -232,4 +242,3 @@ bool SHAPERGUI_DataModel::dumpPython(const QString& thePath, CAM_Study* theStudy
   }
   return false;
 }
-
index a4fa551c1f874e057706104d9d912e682b838cbf..0ea99e989ae8ba17a7df24bf9929c72d3402126d 100644 (file)
@@ -90,3 +90,4 @@ SET(XAO_SOURCES
 ADD_LIBRARY(XAOShaper SHARED ${XAO_SOURCES} ${XAO_HEADERS})
 TARGET_LINK_LIBRARIES(XAOShaper ${PROJECT_LIBRARIES})
 INSTALL(TARGETS XAOShaper DESTINATION ${SHAPER_INSTALL_BIN})
+INSTALL(FILES ${XAO_HEADERS} DESTINATION ${SHAPER_INSTALL_HEADERS})