1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2013 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.
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 This module provides tools to facilitate the use of geom engine and geom
27 GEOM = None # GEOM module is loaded only when needed
29 from salome.kernel.logger import Logger
30 from salome.kernel import termcolor
31 logger = Logger("salome.geom.geomtools", color = termcolor.RED)
33 from salome.kernel.studyedit import getActiveStudyId, getStudyEditor
34 from salome.kernel.services import IDToObject, IDToSObject
36 from salome.gui import helper as guihelper
42 def getGeompy(studyId = None):
44 Return an object behaving exactly like geompy module, except that it is
45 associated with the study `studyId`. If `studyId` is :const:`None`, return
46 a pseudo geompy object for the current study.
48 # We can't use geompy module because it initializes GEOM with
49 # salome.myStudy, which may not exist. So we use this trick to create
50 # a pseudo geompy module.
53 studyId = getActiveStudyId()
54 if not _geompys.has_key(studyId):
55 from salome.geom import geomBuilder
56 study = salome.myStudyManager.GetStudyByID(studyId)
57 _geompys[studyId] = geomBuilder.New(study)
58 return _geompys[studyId]
63 DisplayMode=ModeShading
64 PreviewColor=[236,163,255]
68 This class provides several methods to manipulate geom objects in Salome
69 study. The parameter `studyEditor` defines a
70 :class:`~salome.kernel.studyedit.StudyEditor` object used to access the study. If
71 :const:`None`, the method returns a :class:`~salome.kernel.studyedit.StudyEditor`
72 object on the current study.
76 This instance attribute contains the underlying
77 :class:`~salome.kernel.studyedit.StudyEditor` object. It can be used to access
78 the study but the attribute itself should not be modified.
82 def __init__(self, studyEditor = None):
85 GEOM = __import__("GEOM")
86 if studyEditor is None:
87 studyEditor = getStudyEditor()
88 self.editor = studyEditor
90 # ======================================================================
91 # Helper functions to add/remove a geometrical shape in/from the study
92 # ======================================================================
93 def addShapeToStudy(self, shape,shapeName,folderName=None):
95 Add a GEOM shape in the study. It returns the associated entry
96 that corresponds to the identifier of the entry in the study. This
97 entry can be used to retrieve an object in the study. A folderName
98 can be specified. In this case, a folder with this name is first
99 created in the Geometry part of the study, and the shape study
100 object is stored in this folder of the study.
102 :type shape: GEOM object
103 :param shape: the GEOM object defining the shape
105 :type shapeName: string
106 :param shapeName: the name for this shape in the study
108 :type folderName: string
109 :param folderName: the name of a folder in the GEOM part of the study
111 study = self.editor.study
112 studyId = study._get_StudyId()
113 geompy = getGeompy(studyId)
115 if folderName is None:
116 # Insert the shape in the study by the standard way
117 entry = geompy.addToStudy( shape, shapeName )
119 # A folder name has been specified to embed this shape. Find
120 # or create a folder with this name in the Geometry study, and
121 # then store the shape in this folder.
122 geomStudyFolder = self.editor.findOrCreateComponent("GEOM")
123 shapeStudyFolder = self.editor.findOrCreateItem(geomStudyFolder,folderName)
125 shapeIor = salome.orb.object_to_string(shape)
126 geomgui = salome.ImportComponentGUI("GEOM")
127 shapeIcon = geomgui.getShapeTypeIcon(shapeIor)
129 shapeStudyObject = self.editor.createItem(shapeStudyFolder,
133 entry = shapeStudyObject.GetID()
137 def removeFromStudy(self, shapeStudyEntry):
139 This removes the specified entry from the study. Note that this
140 operation does not destroy the underlying GEOM object, neither
141 erase the drawing in the viewer.
142 The underlying GEOM object is returned (so that it can be destroyed)
144 study = self.editor.study
145 studyId = study._get_StudyId()
146 shape = self.getGeomObjectFromEntry(shapeStudyEntry)
147 studyObject = IDToSObject(shapeStudyEntry)
148 self.editor.removeItem(studyObject,True)
151 # ======================================================================
152 # Helper functions to display/erase a shape in/from the viewer. The
153 # shape must be previously put in the study and the study entry must
154 # be known. Note also that these function works implicitly on the
155 # active study (WARN: it does not ensure consistency with the
156 # study associated to the studyEditor used to initiate this
157 # object. It's up to you to be self-consistent (or to improve this
158 # python source code).
159 # ======================================================================
161 def displayShapeByName(self, shapeName, color = None, fit=True):
163 Display the geometrical shape whose name in the study is `shapeName`.
165 :type shapeName: string
166 :param shapeName: name of the geometrical shape
168 :type color: tuple (triplet)
169 :param color: RGB components of the color of the shape
171 :return: True if the shape was found, False otherwise
173 logger.debug("displayShapeByName in PAL: %s with color %s" %
175 listSO = self.editor.study.FindObjectByName(shapeName, "GEOM")
178 geomObj = self.editor.getOrLoadObject(sObj)
180 shape = geomObj._narrow(GEOM.GEOM_Object)
182 return self.displayShapeByEntry(entry,color,fit)
185 def displayShapeByEntry(self, shapeStudyEntry, color = None, fit=True):
187 Display the geometrical shape whose entry is given by
188 `entry`. You should prefer use this function instead of the
189 displayShapeByName which can have an unpredictible behavior in
190 the case where several objects exist with the same name in the
193 geomgui = salome.ImportComponentGUI("GEOM")
195 geomgui.createAndDisplayFitAllGO(shapeStudyEntry)
197 geomgui.createAndDisplayGO(shapeStudyEntry)
198 geomgui.setDisplayMode(shapeStudyEntry, DisplayMode)
199 if color is not None:
200 geomgui.setColor(shapeStudyEntry, color[0], color[1], color[2])
203 def eraseShapeByEntry(self, shapeStudyEntry):
205 Erase the geometrical shape whose entry is given by
206 `entry`. Please note that the shape is just erased from the
207 viewer. The associated study object still exists in the study,
208 and the geom object still exists in the GEOM engine.
210 geomgui = salome.ImportComponentGUI("GEOM")
211 eraseFromAllWindows=True
212 geomgui.eraseGO(shapeStudyEntry,eraseFromAllWindows)
216 # ======================================================================
217 # Helper functions for a complete suppression of a shape from the
219 # ======================================================================
220 def deleteShape(self,shapeStudyEntry):
222 This completly deletes a geom shape.
224 WARNING: please be aware that to delete a geom object, you have
225 three operations to perform:
227 1. erase the shape from the viewers
228 2. remove the entry from the study
229 3. destroy the underlying geom object
231 self.eraseShapeByEntry(shapeStudyEntry)
232 shape = self.removeFromStudy(shapeStudyEntry)
235 # ======================================================================
236 # Helper functions for interactivity with the object browser
237 # ======================================================================
238 def getGeomObjectSelected(self):
240 Returns the GEOM object currently selected in the objects browser.
242 sobject, entry = guihelper.getSObjectSelected()
243 geomObject = self.getGeomObjectFromEntry(entry)
246 def getGeomObjectFromEntry(self,entry):
248 Returns the GEOM object associated to the specified entry,
249 (the entry is the identifier of an item in the active study)
253 geomObject=IDToObject(entry, self.editor.study)
254 return geomObject._narrow(GEOM.GEOM_Object)
257 # ==================================================================
258 # Use cases and demo functions
259 # ==================================================================
263 # 1. Run a SALOME application including GEOM, and create a new study
264 # 2. In the console, enter:
265 # >>> from salome.geom import geomtools
266 # >>> geomtools.TEST_createBox()
267 # 3. Select the object named "box" in the browser
268 # 4. In the console, enter:
269 # >>> geomtools.TEST_getGeomObjectSelected()
271 def TEST_createBox():
273 box = geompy.MakeBoxDXDYDZ(200, 200, 200)
274 geompy.addToStudy( box, 'box' )
275 if salome.sg.hasDesktop():
276 salome.sg.updateObjBrowser(1)
279 def TEST_getGeomObjectSelected():
280 tool = GeomStudyTools()
281 myGeomObject = tool.getGeomObjectSelected()
284 def TEST_createAndDeleteShape():
286 This test is a simple use case that illustrates how to create a
287 GEOM shape in a SALOME session (create the GEOM object, put in in
288 the study, and display the shape in a viewer) and delete a shape
289 from a SALOME session (erase the shape from the viewer, delete the
290 entry from the study, and finally destroy the underlying GEOM
295 study = salome.myStudy
296 studyId = salome.myStudyId
298 from salome.geom import geomtools
299 geompy = geomtools.getGeompy(studyId)
301 from salome.kernel.studyedit import getStudyEditor
302 studyEditor = getStudyEditor(studyId)
304 gst = geomtools.GeomStudyTools(studyEditor)
306 # --------------------------------------------------
307 # Create a first shape (GEOM object)
310 cylinder = geompy.MakeCylinderRH(radius, length)
312 # Register the shape in the study, at the root of the GEOM
313 # folder. A name must be specified. The register operation
314 # (addShapeToStudy) returns an identifier of the entry in the study.
315 cylinderName = "cyl.r%s.l%s"%(radius,length)
316 cylinderStudyEntry = gst.addShapeToStudy(cylinder, cylinderName)
318 # Display the registered shape in a viewer
319 gst.displayShapeByEntry(cylinderStudyEntry)
321 # --------------------------------------------------
324 sphere = geompy.MakeSphereR(radius)
325 sphereName = "sph.r%s"%radius
326 sphereStudyEntry = gst.addShapeToStudy(sphere, sphereName)
327 gst.displayShapeByEntry(sphereStudyEntry)
329 # --------------------------------------------------
330 # This new shape is stored in the study, but in a specific
331 # sub-folder, and is displayed in the viewer with a specific
334 box = geompy.MakeBoxDXDYDZ(length,length,length)
335 boxName = "box.l%s"%length
336 folderName = "boxset"
337 boxStudyEntry = gst.addShapeToStudy(box, boxName, folderName)
338 gst.displayShapeByEntry(boxStudyEntry,PreviewColor)
340 # --------------------------------------------------
341 # In this example, we illustrate how to erase a shape (the sphere)
342 # from the viewer. After this operation, the sphere is no longer
343 # displayed but still exists in the study. You can then redisplay
344 # it using the context menu of the SALOME object browser.
345 gst.eraseShapeByEntry(sphereStudyEntry)
347 # --------------------------------------------------
348 # In this last example, we completly delete an object from the
349 # SALOME session (erase from viewer, remove from study and finnaly
350 # destroy the object). This is done by a simple call to
352 gst.deleteShape(cylinderStudyEntry)
354 # --------------------------------------------------
355 # At the end of the executioon of this test, you should have in
356 # the SALOME session:
357 # - the box, in a dedicated folder of the study, and displayed in the viewer
358 # - the sphere, in the standard place of the study, and not displayed
360 # If you comment the deleteShape line, you should see the cylinder
361 # in the study and displayed in the viewer.
363 if __name__ == "__main__":
364 #TEST_getGeomObjectSelected()
365 TEST_createAndDeleteShape()