Back to index

salome-geom  6.5.0
geomtools.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 #
00003 # Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00004 #
00005 # This library is free software; you can redistribute it and/or
00006 # modify it under the terms of the GNU Lesser General Public
00007 # License as published by the Free Software Foundation; either
00008 # version 2.1 of the License.
00009 #
00010 # This library is distributed in the hope that it will be useful,
00011 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 # Lesser General Public License for more details.
00014 #
00015 # You should have received a copy of the GNU Lesser General Public
00016 # License along with this library; if not, write to the Free Software
00017 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 #
00019 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00020 #
00021 """
00022 This module provides tools to facilitate the use of geom engine and geom
00023 objects in Salome.
00024 """
00025 
00026 import salome
00027 GEOM = None    # GEOM module is loaded only when needed
00028 
00029 from salome.kernel.logger import Logger
00030 from salome.kernel import termcolor
00031 logger = Logger("salome.geom.geomtools", color = termcolor.RED)
00032 
00033 from salome.kernel.studyedit import getActiveStudyId, getStudyEditor
00034 from salome.kernel.services import IDToObject, IDToSObject
00035 try:
00036     from salome.gui import helper as guihelper
00037 except:
00038     pass
00039 
00040 _geompys = {}
00041 
00042 def getGeompy(studyId = None):
00043     """
00044     Return an object behaving exactly like geompy module, except that it is
00045     associated with the study `studyId`. If `studyId` is :const:`None`, return
00046     a pseudo geompy object for the current study.
00047     """
00048     # We can't use geompy module because it initializes GEOM with
00049     # salome.myStudy, which may not exist. So we use this trick to create
00050     # a pseudo geompy module. 
00051     salome.salome_init()
00052     if studyId is None:
00053         studyId = getActiveStudyId()
00054     if not _geompys.has_key(studyId):
00055         import geompyDC
00056         _geompys[studyId] = salome.lcc.FindOrLoadComponent("FactoryServer",
00057                                                            "GEOM")
00058         _geompys[studyId].ShapeType = geompyDC.ShapeType
00059         _geompys[studyId].GEOM = geompyDC.GEOM
00060         _geompys[studyId].kind = geompyDC.kind
00061         _geompys[studyId].info = geompyDC.info
00062         _geompys[studyId].PackData = geompyDC.PackData
00063         _geompys[studyId].ReadTexture = geompyDC.ReadTexture
00064         study = salome.myStudyManager.GetStudyByID(studyId)
00065         _geompys[studyId].init_geom(study)
00066     return _geompys[studyId]
00067 
00068 
00069 ModeWireFrame = 0
00070 ModeShading = 1
00071 DisplayMode=ModeShading
00072 PreviewColor=[236,163,255]
00073 
00074 class GeomStudyTools:
00075     """
00076     This class provides several methods to manipulate geom objects in Salome
00077     study. The parameter `studyEditor` defines a
00078     :class:`~salome.kernel.studyedit.StudyEditor` object used to access the study. If
00079     :const:`None`, the method returns a :class:`~salome.kernel.studyedit.StudyEditor`
00080     object on the current study.
00081 
00082     .. attribute:: editor
00083     
00084        This instance attribute contains the underlying
00085        :class:`~salome.kernel.studyedit.StudyEditor` object. It can be used to access
00086        the study but the attribute itself should not be modified.
00087 
00088     """
00089 
00090     def __init__(self, studyEditor = None):
00091         global GEOM
00092         if GEOM is None:
00093             GEOM = __import__("GEOM")
00094         if studyEditor is None:
00095             studyEditor = getStudyEditor()
00096         self.editor = studyEditor
00097 
00098     # ======================================================================
00099     # Helper functions to add/remove a geometrical shape in/from the study
00100     # ======================================================================
00101     def addShapeToStudy(self, shape,shapeName,folderName=None):
00102         """
00103         Add a GEOM shape in the study. It returns the associated entry
00104         that corresponds to the identifier of the entry in the study. This
00105         entry can be used to retrieve an object in the study. A folderName
00106         can be specified. In this case, a folder with this name is first
00107         created in the Geometry part of the study, and the shape study
00108         object is stored in this folder of the study. 
00109 
00110         :type   shape: GEOM object
00111         :param  shape: the GEOM object defining the shape
00112 
00113         :type   shapeName: string
00114         :param  shapeName: the name for this shape in the study 
00115 
00116         :type   folderName: string
00117         :param  folderName: the name of a folder in the GEOM part of the study
00118         """
00119         study   = self.editor.study
00120         studyId = study._get_StudyId()
00121         geompy  = getGeompy(studyId)
00122 
00123         if folderName is None:
00124             # Insert the shape in the study by the standard way
00125             entry = geompy.addToStudy( shape, shapeName )
00126         else:
00127             # A folder name has been specified to embed this shape. Find
00128             # or create a folder with this name in the Geometry study, and
00129             # then store the shape in this folder.
00130             geomStudyFolder = self.editor.findOrCreateComponent("GEOM")
00131             shapeStudyFolder = self.editor.findOrCreateItem(geomStudyFolder,folderName)
00132             
00133             shapeIor = salome.orb.object_to_string(shape)
00134             geomgui = salome.ImportComponentGUI("GEOM")
00135             shapeIcon = geomgui.getShapeTypeIcon(shapeIor)
00136             
00137             shapeStudyObject = self.editor.createItem(shapeStudyFolder,
00138                                                       name=shapeName,
00139                                                       IOR=shapeIor,
00140                                                       icon=shapeIcon)
00141             entry = shapeStudyObject.GetID()
00142 
00143         return entry
00144 
00145     def removeFromStudy(self, shapeStudyEntry):
00146         """
00147         This removes the specified entry from the study. Note that this
00148         operation does not destroy the underlying GEOM object, neither
00149         erase the drawing in the viewer.
00150         The underlying GEOM object is returned (so that it can be destroyed)
00151         """
00152         study = self.editor.study
00153         studyId = study._get_StudyId()
00154         shape = self.getGeomObjectFromEntry(shapeStudyEntry)    
00155         studyObject = IDToSObject(shapeStudyEntry)
00156         self.editor.removeItem(studyObject,True)
00157         return shape
00158 
00159     # ======================================================================
00160     # Helper functions to display/erase a shape in/from the viewer. The
00161     # shape must be previously put in the study and the study entry must
00162     # be known. Note also that these function works implicitly on the
00163     # active study (WARN: it does not ensure consistency with the
00164     # study associated to the studyEditor used to initiate this
00165     # object. It's up to you to be self-consistent (or to improve this
00166     # python source code). 
00167     # ======================================================================
00168 
00169     def displayShapeByName(self, shapeName, color = None, fit=True):
00170         """
00171         Display the geometrical shape whose name in the study is `shapeName`.
00172         
00173         :type   shapeName: string
00174         :param  shapeName: name of the geometrical shape
00175         
00176         :type   color: tuple (triplet)
00177         :param  color: RGB components of the color of the shape
00178         
00179         :return: True if the shape was found, False otherwise
00180         """
00181         logger.debug("displayShapeByName in PAL: %s with color %s" %
00182                      (shapeName, color))
00183         listSO = self.editor.study.FindObjectByName(shapeName, "GEOM")
00184         for sObj in listSO:
00185             entry = sObj.GetID()
00186             geomObj = self.editor.getOrLoadObject(sObj)
00187             if geomObj:
00188                 shape = geomObj._narrow(GEOM.GEOM_Object)
00189                 if shape:
00190                     return self.displayShapeByEntry(entry,color,fit)
00191         return False
00192 
00193     def displayShapeByEntry(self, shapeStudyEntry, color = None, fit=True):
00194         """
00195         Display the geometrical shape whose entry is given by
00196         `entry`. You should prefer use this function instead of the
00197         displayShapeByName which can have an unpredictible behavior in
00198         the case where several objects exist with the same name in the
00199         study.
00200         """
00201         geomgui = salome.ImportComponentGUI("GEOM")
00202         if fit:
00203             geomgui.createAndDisplayFitAllGO(shapeStudyEntry)
00204         else:
00205             geomgui.createAndDisplayGO(shapeStudyEntry)
00206         geomgui.setDisplayMode(shapeStudyEntry, DisplayMode)
00207         if color is not None:
00208             geomgui.setColor(shapeStudyEntry, color[0], color[1], color[2])
00209         return True
00210 
00211     def eraseShapeByEntry(self, shapeStudyEntry):
00212         """
00213         Erase the geometrical shape whose entry is given by
00214         `entry`. Please note that the shape is just erased from the
00215         viewer. The associated study object still exists in the study,
00216         and the geom object still exists in the GEOM engine.
00217         """
00218         geomgui = salome.ImportComponentGUI("GEOM")
00219         eraseFromAllWindows=True
00220         geomgui.eraseGO(shapeStudyEntry,eraseFromAllWindows)
00221         return True
00222 
00223 
00224     # ======================================================================
00225     # Helper functions for a complete suppression of a shape from the
00226     # SALOME session.
00227     # ======================================================================
00228     def deleteShape(self,shapeStudyEntry):
00229         """
00230         This completly deletes a geom shape.
00231         
00232         WARNING: please be aware that to delete a geom object, you have
00233         three operations to perform:
00234         
00235         1. erase the shape from the viewers
00236         2. remove the entry from the study
00237         3. destroy the underlying geom object
00238         """
00239         self.eraseShapeByEntry(shapeStudyEntry)
00240         shape = self.removeFromStudy(shapeStudyEntry)
00241         shape.Destroy()
00242 
00243     # ======================================================================
00244     # Helper functions for interactivity with the object browser
00245     # ======================================================================
00246     def getGeomObjectSelected(self):
00247         '''
00248         Returns the GEOM object currently selected in the objects browser.
00249         '''
00250         sobject, entry = guihelper.getSObjectSelected()
00251         geomObject = self.getGeomObjectFromEntry(entry)
00252         return geomObject
00253 
00254     def getGeomObjectFromEntry(self,entry):
00255         '''
00256         Returns the GEOM object associated to the specified entry,
00257         (the entry is the identifier of an item in the active study)
00258         '''
00259         if entry is None:
00260             return None
00261         geomObject=IDToObject(entry, self.editor.study)
00262         return geomObject._narrow(GEOM.GEOM_Object)
00263 
00264 #
00265 # ==================================================================
00266 # Use cases and demo functions
00267 # ==================================================================
00268 #
00269 
00270 # How to test?
00271 # 1. Run a SALOME application including GEOM, and create a new study
00272 # 2. In the console, enter:
00273 #    >>> from salome.geom import geomtools
00274 #    >>> geomtools.TEST_createBox()
00275 # 3. Select the object named "box" in the browser
00276 # 4. In the console, enter:
00277 #    >>> geomtools.TEST_getGeomObjectSelected()
00278 
00279 def TEST_createBox():
00280     geompy = getGeompy()
00281     box = geompy.MakeBoxDXDYDZ(200, 200, 200)
00282     geompy.addToStudy( box, 'box' )    
00283     if salome.sg.hasDesktop():
00284         salome.sg.updateObjBrowser(1)
00285 
00286 
00287 def TEST_getGeomObjectSelected():
00288     tool = GeomStudyTools()
00289     myGeomObject = tool.getGeomObjectSelected()
00290     print myGeomObject
00291 
00292 def TEST_createAndDeleteShape():
00293     """
00294     This test is a simple use case that illustrates how to create a
00295     GEOM shape in a SALOME session (create the GEOM object, put in in
00296     the study, and display the shape in a viewer) and delete a shape
00297     from a SALOME session (erase the shape from the viewer, delete the
00298     entry from the study, and finally destroy the underlying GEOM
00299     object).
00300     """
00301     import salome
00302     salome.salome_init()
00303     study   = salome.myStudy
00304     studyId = salome.myStudyId
00305 
00306     from salome.geom import geomtools
00307     geompy = geomtools.getGeompy(studyId)
00308     
00309     from salome.kernel.studyedit import getStudyEditor
00310     studyEditor = getStudyEditor(studyId)
00311 
00312     gst = geomtools.GeomStudyTools(studyEditor)
00313 
00314     # --------------------------------------------------
00315     # Create a first shape (GEOM object)
00316     radius = 5
00317     length = 100
00318     cylinder = geompy.MakeCylinderRH(radius, length)
00319 
00320     # Register the shape in the study, at the root of the GEOM
00321     # folder. A name must be specified. The register operation
00322     # (addShapeToStudy) returns an identifier of the entry in the study.
00323     cylinderName = "cyl.r%s.l%s"%(radius,length)
00324     cylinderStudyEntry = gst.addShapeToStudy(cylinder, cylinderName)
00325 
00326     # Display the registered shape in a viewer
00327     gst.displayShapeByEntry(cylinderStudyEntry)
00328 
00329     # --------------------------------------------------
00330     # A second shape
00331     radius = 10
00332     sphere = geompy.MakeSphereR(radius)
00333     sphereName = "sph.r%s"%radius
00334     sphereStudyEntry = gst.addShapeToStudy(sphere, sphereName)
00335     gst.displayShapeByEntry(sphereStudyEntry)
00336 
00337     # --------------------------------------------------
00338     # This new shape is stored in the study, but in a specific
00339     # sub-folder, and is displayed in the viewer with a specific
00340     # color.
00341     length = 20
00342     box = geompy.MakeBoxDXDYDZ(length,length,length)
00343     boxName = "box.l%s"%length
00344     folderName = "boxset" 
00345     boxStudyEntry = gst.addShapeToStudy(box, boxName, folderName)
00346     gst.displayShapeByEntry(boxStudyEntry,PreviewColor)
00347 
00348     # --------------------------------------------------
00349     # In this example, we illustrate how to erase a shape (the sphere)
00350     # from the viewer. After this operation, the sphere is no longer
00351     # displayed but still exists in the study. You can then redisplay
00352     # it using the context menu of the SALOME object browser.
00353     gst.eraseShapeByEntry(sphereStudyEntry)
00354 
00355     # --------------------------------------------------
00356     # In this last example, we completly delete an object from the
00357     # SALOME session (erase from viewer, remove from study and finnaly
00358     # destroy the object). This is done by a simple call to
00359     # deleteShape().
00360     gst.deleteShape(cylinderStudyEntry)
00361 
00362     # --------------------------------------------------
00363     # At the end of the executioon of this test, you should have in
00364     # the SALOME session:
00365     # - the box, in a dedicated folder of the study, and displayed in the viewer
00366     # - the sphere, in the standard place of the study, and not displayed 
00367 
00368     # If you comment the deleteShape line, you should see the cylinder
00369     # in the study and displayed in the viewer. 
00370 
00371 if __name__ == "__main__":
00372     #TEST_getGeomObjectSelected()
00373     TEST_createAndDeleteShape()
00374 
00375 
00376