From a77c8750d49dfac5eaf357630c35141ca5be6251 Mon Sep 17 00:00:00 2001 From: boulant Date: Mon, 13 Feb 2012 12:53:09 +0000 Subject: [PATCH] IMP: geomtools, integration of helper functions to add/remove shape to/from study and to display/erase shape to/from a viewer. --- doc/docutils/overview.rst | 65 +++++++++--- src/GEOM_PY/geomtools.py | 212 +++++++++++++++++++++++++++++++++++--- 2 files changed, 248 insertions(+), 29 deletions(-) diff --git a/doc/docutils/overview.rst b/doc/docutils/overview.rst index 78a47b50b..c74a0aaed 100644 --- a/doc/docutils/overview.rst +++ b/doc/docutils/overview.rst @@ -5,17 +5,36 @@ General presentation of the GEOM python package The GEOM python package essentially contains: -* Utility functions to handle GEOM items in Salome study. -* Wrapping functions to help the usage of existing tools: +* Utility functions to handle GEOM items in Salome study (see ``geomtools.py``). - - a sketcher module to create sketches from the python API + - add a shape to a study, remove from the study + - display a shape in a viewer, erase the shape from the viewers + - completly delete a shape (undisplay, unpublish, and destroy the shape) + - helper functions to manage the selection in the object browser +* Wrapping functions to help the usage of GEOM tools: + + - a sketcher module to create sketches from the python API (see + ``sketcher.py``) * The visualization of structural elements: a function to create geometrical 3D representations of mechanical models called - "structural elements". + "structural elements" (see package ``structelem``) The functions are distributed in the python package -``salome.geom``. For example, the usage of the visualization of -structural elements can be appreciated with this set of instructions: +``salome.geom``. The specification of the programming interface of +this package is detailled in the part :doc:`Documentation of the +programming interface (API)` of this documentation. + +.. note:: + The main package ``salome`` contains other sub-packages that are + distributed with the other SALOME modules. For example, the KERNEL + module provides the python package ``salome.kernel`` and SMESH the + package ``salome.smesh``. + +Visualization of structural elements (package ``structelem``) +------------------------------------------------------------- + +The usage of the visualization of structural elements can be +appreciated with this set of instructions: .. code-block:: python @@ -27,12 +46,30 @@ This creates the geometrical objects displayed in the study below: .. image:: /images/salome-geom-structuralelements.png :align: center -The specification of the programming interface of this package is -detailled in the part :doc:`Documentation of the programming interface -(API)` of this documentation. +Manipulate GEOM object in the study (module ``geomtools``) +---------------------------------------------------------- -.. note:: - The main package ``salome`` contains other sub-packages that are - distributed with the other SALOME modules. For example, the KERNEL - module provides the python package ``salome.kernel`` and SMESH the - package ``salome.smesh``. +The usage of the ``geomtools`` module can be appreciated with this set +of instructions: + +.. code-block:: python + + from salome.geom.geomtools import TEST_createAndDeleteShape + TEST_createAndDeleteShape() + +This test executes the following procedure: + +* Create, publish, and display a cylinder +* Create, publish, and display a sphere +* Create a box, publish it in a folder "boxset", and display it with a + "pink" color. +* Erase the sphere from the viewer (the sphere still exists in the study) +* Delete the cylinder (the cylinder is no longer displayed and does + not exist any more, neither in the study nor the GEOM componet. + +At the end of the execution of this test, you should have in the +SALOME session: + +* the box, in a dedicated folder of the study, and displayed in the + viewer +* the sphere, in the standard place of the study, and not displayed diff --git a/src/GEOM_PY/geomtools.py b/src/GEOM_PY/geomtools.py index 890959cfb..3b37982f3 100644 --- a/src/GEOM_PY/geomtools.py +++ b/src/GEOM_PY/geomtools.py @@ -31,9 +31,9 @@ from salome.kernel import termcolor logger = Logger("salome.geom.geomtools", color = termcolor.RED) from salome.kernel.studyedit import getActiveStudyId, getStudyEditor -from salome.kernel.services import IDToObject +from salome.kernel.services import IDToObject, IDToSObject try: - from salome.gui import helper + from salome.gui import helper as guihelper except: pass @@ -69,6 +69,7 @@ def getGeompy(studyId = None): ModeWireFrame = 0 ModeShading = 1 DisplayMode=ModeShading +PreviewColor=[236,163,255] class GeomStudyTools: """ @@ -94,7 +95,78 @@ class GeomStudyTools: studyEditor = getStudyEditor() self.editor = studyEditor - def displayShapeByName(self, shapeName, color = None): + # ====================================================================== + # Helper functions to add/remove a geometrical shape in/from the study + # ====================================================================== + def addShapeToStudy(self, shape,shapeName,folderName=None): + """ + Add a GEOM shape in the study. It returns the associated entry + that corresponds to the identifier of the entry in the study. This + entry can be used to retrieve an object in the study. A folderName + can be specified. In this case, a folder with this name is first + created in the Geometry part of the study, and the shape study + object is stored in this folder of the study. + + :type shape: GEOM object + :param shape: the GEOM object defining the shape + + :type shapeName: string + :param shapeName: the name for this shape in the study + + :type folderName: string + :param folderName: the name of a folder in the GEOM part of the study + """ + study = self.editor.study + studyId = study._get_StudyId() + geompy = getGeompy(studyId) + + if folderName is None: + # Insert the shape in the study by the standard way + entry = geompy.addToStudy( shape, shapeName ) + else: + # A folder name has been specified to embed this shape. Find + # or create a folder with this name in the Geometry study, and + # then store the shape in this folder. + geomStudyFolder = self.editor.findOrCreateComponent("GEOM") + shapeStudyFolder = self.editor.findOrCreateItem(geomStudyFolder,folderName) + + shapeIor = salome.orb.object_to_string(shape) + geomgui = salome.ImportComponentGUI("GEOM") + shapeIcon = geomgui.getShapeTypeIcon(shapeIor) + + shapeStudyObject = self.editor.createItem(shapeStudyFolder, + name=shapeName, + IOR=shapeIor, + icon=shapeIcon) + entry = shapeStudyObject.GetID() + + return entry + + def removeFromStudy(self, shapeStudyEntry): + """ + This removes the specified entry from the study. Note that this + operation does not destroy the underlying GEOM object, neither + erase the drawing in the viewer. + The underlying GEOM object is returned (so that it can be destroyed) + """ + study = self.editor.study + studyId = study._get_StudyId() + shape = self.getGeomObjectFromEntry(shapeStudyEntry) + studyObject = IDToSObject(shapeStudyEntry) + self.editor.removeItem(studyObject,True) + return shape + + # ====================================================================== + # Helper functions to display/erase a shape in/from the viewer. The + # shape must be previously put in the study and the study entry must + # be known. Note also that these function works implicitly on the + # active study (WARN: it does not ensure consistency with the + # study associated to the studyEditor used to initiate this + # object. It's up to you to be self-consistent (or to improve this + # python source code). + # ====================================================================== + + def displayShapeByName(self, shapeName, color = None, fit=True): """ Display the geometrical shape whose name in the study is `shapeName`. @@ -115,21 +187,28 @@ class GeomStudyTools: if geomObj: shape = geomObj._narrow(GEOM.GEOM_Object) if shape: - return self.displayShapeByEntry(entry,color) + return self.displayShapeByEntry(entry,color,fit) return False - def displayShapeByEntry(self, entry, color = None): + def displayShapeByEntry(self, shapeStudyEntry, color = None, fit=True): """ - Display the geometrical shape whose entry is given by `entry`. + Display the geometrical shape whose entry is given by + `entry`. You should prefer use this function instead of the + displayShapeByName which can have an unpredictible behavior in + the case where several objects exist with the same name in the + study. """ - geomgui = salome.ImportComponentGUI("GEOM") - geomgui.createAndDisplayGO(entry) - geomgui.setDisplayMode(entry, DisplayMode) + geomgui = salome.ImportComponentGUI("GEOM") + if fit: + geomgui.createAndDisplayFitAllGO(shapeStudyEntry) + else: + geomgui.createAndDisplayGO(shapeStudyEntry) + geomgui.setDisplayMode(shapeStudyEntry, DisplayMode) if color is not None: - geomgui.setColor(entry, color[0], color[1], color[2]) + geomgui.setColor(shapeStudyEntry, color[0], color[1], color[2]) return True - def eraseShapeByEntry(self, entry): + def eraseShapeByEntry(self, shapeStudyEntry): """ Erase the geometrical shape whose entry is given by `entry`. Please note that the shape is just erased from the @@ -138,14 +217,37 @@ class GeomStudyTools: """ geomgui = salome.ImportComponentGUI("GEOM") eraseFromAllWindows=True - geomgui.eraseGO(entry,eraseFromAllWindows) + geomgui.eraseGO(shapeStudyEntry,eraseFromAllWindows) return True - + + + # ====================================================================== + # Helper functions for a complete suppression of a shape from the + # SALOME session. + # ====================================================================== + def deleteShape(self,shapeStudyEntry): + """ + This completly deletes a geom shape. + + WARNING: please be aware that to delete a geom object, you have + three operations to perform: + + 1. erase the shape from the viewers + 2. remove the entry from the study + 3. destroy the underlying geom object + """ + self.eraseShapeByEntry(shapeStudyEntry) + shape = self.removeFromStudy(shapeStudyEntry) + shape.Destroy() + + # ====================================================================== + # Helper functions for interactivity with the object browser + # ====================================================================== def getGeomObjectSelected(self): ''' Returns the GEOM object currently selected in the objects browser. ''' - sobject, entry = helper.getSObjectSelected() + sobject, entry = guihelper.getSObjectSelected() geomObject = self.getGeomObjectFromEntry(entry) return geomObject @@ -187,8 +289,88 @@ def TEST_getGeomObjectSelected(): myGeomObject = tool.getGeomObjectSelected() print myGeomObject +def TEST_createAndDeleteShape(): + """ + This test is a simple use case that illustrates how to create a + GEOM shape in a SALOME session (create the GEOM object, put in in + the study, and display the shape in a viewer) and delete a shape + from a SALOME session (erase the shape from the viewer, delete the + entry from the study, and finally destroy the underlying GEOM + object). + """ + import salome + salome.salome_init() + study = salome.myStudy + studyId = salome.myStudyId + + from salome.geom import geomtools + geompy = geomtools.getGeompy(studyId) + + from salome.kernel.studyedit import getStudyEditor + studyEditor = getStudyEditor(studyId) + + gst = geomtools.GeomStudyTools(studyEditor) + + # -------------------------------------------------- + # Create a first shape (GEOM object) + radius = 5 + length = 100 + cylinder = geompy.MakeCylinderRH(radius, length) + + # Register the shape in the study, at the root of the GEOM + # folder. A name must be specified. The register operation + # (addShapeToStudy) returns an identifier of the entry in the study. + cylinderName = "cyl.r%s.l%s"%(radius,length) + cylinderStudyEntry = gst.addShapeToStudy(cylinder, cylinderName) + + # Display the registered shape in a viewer + gst.displayShapeByEntry(cylinderStudyEntry) + + # -------------------------------------------------- + # A second shape + radius = 10 + sphere = geompy.MakeSphereR(radius) + sphereName = "sph.r%s"%radius + sphereStudyEntry = gst.addShapeToStudy(sphere, sphereName) + gst.displayShapeByEntry(sphereStudyEntry) + + # -------------------------------------------------- + # This new shape is stored in the study, but in a specific + # sub-folder, and is displayed in the viewer with a specific + # color. + length = 20 + box = geompy.MakeBoxDXDYDZ(length,length,length) + boxName = "box.l%s"%length + folderName = "boxset" + boxStudyEntry = gst.addShapeToStudy(box, boxName, folderName) + gst.displayShapeByEntry(boxStudyEntry,PreviewColor) + + # -------------------------------------------------- + # In this example, we illustrate how to erase a shape (the sphere) + # from the viewer. After this operation, the sphere is no longer + # displayed but still exists in the study. You can then redisplay + # it using the context menu of the SALOME object browser. + gst.eraseShapeByEntry(sphereStudyEntry) + + # -------------------------------------------------- + # In this last example, we completly delete an object from the + # SALOME session (erase from viewer, remove from study and finnaly + # destroy the object). This is done by a simple call to + # deleteShape(). + gst.deleteShape(cylinderStudyEntry) + + # -------------------------------------------------- + # At the end of the executioon of this test, you should have in + # the SALOME session: + # - the box, in a dedicated folder of the study, and displayed in the viewer + # - the sphere, in the standard place of the study, and not displayed + + # If you comment the deleteShape line, you should see the cylinder + # in the study and displayed in the viewer. + if __name__ == "__main__": - TEST_getGeomObjectSelected() + #TEST_getGeomObjectSelected() + TEST_createAndDeleteShape()