1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 ## \defgroup geomtools geomtools - Tools to access GEOM engine and objects
25 # This module provides tools to facilitate the use of geom engine and geom
30 This module provides tools to facilitate the use of geom engine and geom
35 GEOM = None # GEOM module is loaded only when needed
37 from salome.kernel.logger import Logger
38 from salome.kernel import termcolor
39 logger = Logger("salome.geom.geomtools", color = termcolor.RED)
41 from salome.kernel.studyedit import getActiveStudyId, getStudyEditor
42 from salome.kernel.services import IDToObject, IDToSObject
43 from salome.kernel.deprecation import is_called_by_sphinx
46 if not is_called_by_sphinx():
47 from salome.gui import helper as guihelper
55 ## Return an object behaving exactly like geompy module, except that it is
56 # associated with the study \em studyId. If \em studyId is \b None, return
57 # a pseudo geompy object for the current study.
59 def getGeompy(studyId = None):
61 Return an object behaving exactly like geompy module, except that it is
62 associated with the study `studyId`. If `studyId` is :const:`None`, return
63 a pseudo geompy object for the current study.
65 # We can't use geompy module because it initializes GEOM with
66 # salome.myStudy, which may not exist. So we use this trick to create
67 # a pseudo geompy module.
70 studyId = getActiveStudyId()
71 if not _geompys.has_key(studyId):
72 from salome.geom import geomBuilder
73 study = salome.myStudyManager.GetStudyByID(studyId)
74 _geompys[studyId] = geomBuilder.New(study)
75 return _geompys[studyId]
80 DisplayMode=ModeShading
81 PreviewColor=[236,163,255]
83 ## This class provides several methods to manipulate geom objects in Salome study.
84 # The parameter <em>studyEditor</em> defines a \b StudyEditor
85 # object used to access the study. If \b None, the method returns a
86 # \b StudyEditor object on the current study.
90 # This instance attribute contains the underlying \b StudyEditor object.
91 # It can be used to access the study but the attribute itself should not be modified.
95 This class provides several methods to manipulate geom objects in Salome
96 study. The parameter `studyEditor` defines a
97 :class:`~salome.kernel.studyedit.StudyEditor` object used to access the study. If
98 :const:`None`, the method returns a :class:`~salome.kernel.studyedit.StudyEditor`
99 object on the current study.
101 .. attribute:: editor
103 This instance attribute contains the underlying
104 :class:`~salome.kernel.studyedit.StudyEditor` object. It can be used to access
105 the study but the attribute itself should not be modified.
109 def __init__(self, studyEditor = None):
112 GEOM = __import__("GEOM")
113 if studyEditor is None:
114 studyEditor = getStudyEditor()
115 self.editor = studyEditor
117 # ======================================================================
118 # Helper functions to add/remove a geometrical shape in/from the study
119 # ======================================================================
120 ## Add a GEOM shape in the study. It returns the associated entry
121 # that corresponds to the identifier of the entry in the study. This
122 # entry can be used to retrieve an object in the study. A folderName
123 # can be specified. In this case, a folder with this name is first
124 # created in the Geometry part of the study, and the shape study
125 # object is stored in this folder of the study.
127 # \param shape (GEOM object) the GEOM object defining the shape
128 # \param shapeName (string) the name for this shape in the study
129 # \param folderName (string) the name of a folder in the GEOM part of the study
130 def addShapeToStudy(self, shape,shapeName,folderName=None):
132 Add a GEOM shape in the study. It returns the associated entry
133 that corresponds to the identifier of the entry in the study. This
134 entry can be used to retrieve an object in the study. A folderName
135 can be specified. In this case, a folder with this name is first
136 created in the Geometry part of the study, and the shape study
137 object is stored in this folder of the study.
139 :type shape: GEOM object
140 :param shape: the GEOM object defining the shape
142 :type shapeName: string
143 :param shapeName: the name for this shape in the study
145 :type folderName: string
146 :param folderName: the name of a folder in the GEOM part of the study
148 study = self.editor.study
149 studyId = study._get_StudyId()
150 geompy = getGeompy(studyId)
152 if folderName is None:
153 # Insert the shape in the study by the standard way
154 entry = geompy.addToStudy( shape, shapeName )
156 # A folder name has been specified to embed this shape. Find
157 # or create a folder with this name in the Geometry study, and
158 # then store the shape in this folder.
159 geomStudyFolder = self.editor.findOrCreateComponent("GEOM")
160 shapeStudyFolder = self.editor.findOrCreateItem(geomStudyFolder,folderName)
162 shapeIor = salome.orb.object_to_string(shape)
163 geomgui = salome.ImportComponentGUI("GEOM")
164 shapeIcon = geomgui.getShapeTypeIcon(shapeIor)
166 shapeStudyObject = self.editor.createItem(shapeStudyFolder,
170 entry = shapeStudyObject.GetID()
174 ## This removes the specified entry from the study. Note that this
175 # operation does not destroy the underlying GEOM object, neither
176 # erase the drawing in the viewer.
177 # The underlying GEOM object is returned (so that it can be destroyed)
178 def removeFromStudy(self, shapeStudyEntry):
180 This removes the specified entry from the study. Note that this
181 operation does not destroy the underlying GEOM object, neither
182 erase the drawing in the viewer.
183 The underlying GEOM object is returned (so that it can be destroyed)
185 study = self.editor.study
186 studyId = study._get_StudyId()
187 shape = self.getGeomObjectFromEntry(shapeStudyEntry)
188 studyObject = IDToSObject(shapeStudyEntry)
189 self.editor.removeItem(studyObject,True)
192 # ======================================================================
193 # Helper functions to display/erase a shape in/from the viewer. The
194 # shape must be previously put in the study and the study entry must
195 # be known. Note also that these function works implicitly on the
196 # active study (WARN: it does not ensure consistency with the
197 # study associated to the studyEditor used to initiate this
198 # object. It's up to you to be self-consistent (or to improve this
199 # python source code).
200 # ======================================================================
202 ## Display the geometrical shape whose name in the study is <em>shapeName</em>.
204 # \param shapeName (string) name of the geometrical shape
205 # \param color (tuple) RGB components of the color of the shape
206 # \return True if the shape was found, False otherwise
207 def displayShapeByName(self, shapeName, color = None, fit=True):
209 Display the geometrical shape whose name in the study is `shapeName`.
211 :type shapeName: string
212 :param shapeName: name of the geometrical shape
214 :type color: tuple (triplet)
215 :param color: RGB components of the color of the shape
217 :return: True if the shape was found, False otherwise
219 logger.debug("displayShapeByName in PAL: %s with color %s" %
221 listSO = self.editor.study.FindObjectByName(shapeName, "GEOM")
224 geomObj = self.editor.getOrLoadObject(sObj)
226 shape = geomObj._narrow(GEOM.GEOM_Object)
228 return self.displayShapeByEntry(entry,color,fit)
231 ## Display the geometrical shape whose entry is given by \em entry.
232 # You should prefer use this function instead of the
233 # displayShapeByName() which can have an unpredictible behavior in
234 # the case where several objects exist with the same name in the study.
235 def displayShapeByEntry(self, shapeStudyEntry, color = None, fit=True):
237 Display the geometrical shape whose entry is given by
238 `entry`. You should prefer use this function instead of the
239 displayShapeByName which can have an unpredictible behavior in
240 the case where several objects exist with the same name in the
243 geomgui = salome.ImportComponentGUI("GEOM")
245 geomgui.createAndDisplayFitAllGO(shapeStudyEntry)
247 geomgui.createAndDisplayGO(shapeStudyEntry)
248 geomgui.setDisplayMode(shapeStudyEntry, DisplayMode)
249 if color is not None:
250 geomgui.setColor(shapeStudyEntry, color[0], color[1], color[2])
253 ## Erase the geometrical shape whose entry is given by \em entry.
254 # Please note that the shape is just erased from the
255 # viewer. The associated study object still exists in the study,
256 # and the geom object still exists in the GEOM engine.
257 def eraseShapeByEntry(self, shapeStudyEntry):
259 Erase the geometrical shape whose entry is given by
260 `entry`. Please note that the shape is just erased from the
261 viewer. The associated study object still exists in the study,
262 and the geom object still exists in the GEOM engine.
264 geomgui = salome.ImportComponentGUI("GEOM")
265 eraseFromAllWindows=True
266 geomgui.eraseGO(shapeStudyEntry,eraseFromAllWindows)
270 # ======================================================================
271 # Helper functions for a complete suppression of a shape from the
273 # ======================================================================
274 ## This completly deletes a geom shape.
275 # \warning Please be aware that to delete a geom object,
276 # you have three operations to perform:
278 # 1. erase the shape from the viewers
279 # 2. remove the entry from the study
280 # 3. destroy the underlying geom object
281 def deleteShape(self,shapeStudyEntry):
283 This completly deletes a geom shape.
285 WARNING: please be aware that to delete a geom object, you have
286 three operations to perform:
288 1. erase the shape from the viewers
289 2. remove the entry from the study
290 3. destroy the underlying geom object
292 self.eraseShapeByEntry(shapeStudyEntry)
293 shape = self.removeFromStudy(shapeStudyEntry)
296 # ======================================================================
297 # Helper functions for interactivity with the object browser
298 # ======================================================================
299 ## Returns the GEOM object currently selected in the objects browser.
300 def getGeomObjectSelected(self):
302 Returns the GEOM object currently selected in the objects browser.
304 sobject, entry = guihelper.getSObjectSelected()
305 geomObject = self.getGeomObjectFromEntry(entry)
308 ## Returns the GEOM object associated to the specified entry,
309 # (the entry is the identifier of an item in the active study)
310 def getGeomObjectFromEntry(self,entry):
312 Returns the GEOM object associated to the specified entry,
313 (the entry is the identifier of an item in the active study)
317 geomObject=IDToObject(entry, self.editor.study)
318 return geomObject._narrow(GEOM.GEOM_Object)
321 # ==================================================================
322 # Use cases and demo functions
323 # ==================================================================
327 # 1. Run a SALOME application including GEOM, and create a new study
328 # 2. In the console, enter:
329 # >>> from salome.geom import geomtools
330 # >>> geomtools.TEST_createBox()
331 # 3. Select the object named "box" in the browser
332 # 4. In the console, enter:
333 # >>> geomtools.TEST_getGeomObjectSelected()
335 def TEST_createBox():
337 box = geompy.MakeBoxDXDYDZ(200, 200, 200)
338 geompy.addToStudy( box, 'box' )
339 if salome.sg.hasDesktop():
340 salome.sg.updateObjBrowser(1)
343 def TEST_getGeomObjectSelected():
344 tool = GeomStudyTools()
345 myGeomObject = tool.getGeomObjectSelected()
348 ## This test is a simple use case that illustrates how to create a
349 # GEOM shape in a SALOME session (create the GEOM object, put in in
350 # the study, and display the shape in a viewer) and delete a shape
351 # from a SALOME session (erase the shape from the viewer, delete the
352 # entry from the study, and finally destroy the underlying GEOM
355 def TEST_createAndDeleteShape():
357 This test is a simple use case that illustrates how to create a
358 GEOM shape in a SALOME session (create the GEOM object, put in in
359 the study, and display the shape in a viewer) and delete a shape
360 from a SALOME session (erase the shape from the viewer, delete the
361 entry from the study, and finally destroy the underlying GEOM
366 study = salome.myStudy
367 studyId = salome.myStudyId
369 from salome.geom import geomtools
370 geompy = geomtools.getGeompy(studyId)
372 from salome.kernel.studyedit import getStudyEditor
373 studyEditor = getStudyEditor(studyId)
375 gst = geomtools.GeomStudyTools(studyEditor)
377 # --------------------------------------------------
378 # Create a first shape (GEOM object)
381 cylinder = geompy.MakeCylinderRH(radius, length)
383 # Register the shape in the study, at the root of the GEOM
384 # folder. A name must be specified. The register operation
385 # (addShapeToStudy) returns an identifier of the entry in the study.
386 cylinderName = "cyl.r%s.l%s"%(radius,length)
387 cylinderStudyEntry = gst.addShapeToStudy(cylinder, cylinderName)
389 # Display the registered shape in a viewer
390 gst.displayShapeByEntry(cylinderStudyEntry)
392 # --------------------------------------------------
395 sphere = geompy.MakeSphereR(radius)
396 sphereName = "sph.r%s"%radius
397 sphereStudyEntry = gst.addShapeToStudy(sphere, sphereName)
398 gst.displayShapeByEntry(sphereStudyEntry)
400 # --------------------------------------------------
401 # This new shape is stored in the study, but in a specific
402 # sub-folder, and is displayed in the viewer with a specific
405 box = geompy.MakeBoxDXDYDZ(length,length,length)
406 boxName = "box.l%s"%length
407 folderName = "boxset"
408 boxStudyEntry = gst.addShapeToStudy(box, boxName, folderName)
409 gst.displayShapeByEntry(boxStudyEntry,PreviewColor)
411 # --------------------------------------------------
412 # In this example, we illustrate how to erase a shape (the sphere)
413 # from the viewer. After this operation, the sphere is no longer
414 # displayed but still exists in the study. You can then redisplay
415 # it using the context menu of the SALOME object browser.
416 gst.eraseShapeByEntry(sphereStudyEntry)
418 # --------------------------------------------------
419 # In this last example, we completly delete an object from the
420 # SALOME session (erase from viewer, remove from study and finnaly
421 # destroy the object). This is done by a simple call to
423 gst.deleteShape(cylinderStudyEntry)
425 # --------------------------------------------------
426 # At the end of the executioon of this test, you should have in
427 # the SALOME session:
428 # - the box, in a dedicated folder of the study, and displayed in the viewer
429 # - the sphere, in the standard place of the study, and not displayed
431 # If you comment the deleteShape line, you should see the cylinder
432 # in the study and displayed in the viewer.
434 if __name__ == "__main__":
435 #TEST_getGeomObjectSelected()
436 TEST_createAndDeleteShape()