]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOM_PY/structelem/__init__.py
Salome HOME
Merge remote-tracking branch 'origin/V8_3_BR' into ngr/python3_dev
[modules/geom.git] / src / GEOM_PY / structelem / __init__.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
4 #
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.
9 #
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.
14 #
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
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21
22 ## \defgroup structelem structelem - Structural elements package
23 #  \{ 
24 #  \details
25 #  This package is used to create and visualize structural elements. 
26 #  It contains three modules:
27 #  - This module \ref structelem "salome.geom.structelem" defines the main classes
28 #  StructuralElement and StructuralElementManager that can be
29 #  directly used to build structural elements.
30 #  - The module \ref parts "salome.geom.structelem.parts" defines 
31 #  the classes corresponding to the different parts (beams, grids, etc.) that make up 
32 #  a structural element. It is used to build the geometric shapes in the structural element.
33 #  - The module \ref orientation "salome.geom.structelem.orientation" defines 
34 #  the classes that are used to compute the orientation of the structural element parts 
35 #  and to build the corresponding markers.
36 #
37 #  A structural element is a set of geometric shapes (beams, grids, etc.) that
38 #  are built semi-automatically along a set of geometric primitives (edges for
39 #  instance). They are visualized with the same color as their base primitives in
40 #  the geom viewer.
41 #  \n Structural elements are generally created by the StructuralElementManager class, 
42 #  from a list of commands describing the element to create.
43 #
44 #  Example:
45 #  \code
46 #  commandList = [('VisuPoutreGenerale', {'Group_Maille': 'Edge_1'}),
47 #                 ('VisuBarreCercle', {'R': 30, 'Group_Maille': 'Edge_1', 'EP': 15}),
48 #                ]
49 #
50 #  structElemManager = StructuralElementManager()
51 #  elem = structElemManager.createElement(commandList)
52 #  elem.display()
53 #  salome.sg.updateObjBrowser(True)
54 #  \endcode
55 #
56 #  \defgroup orientation
57 #  \defgroup parts
58 #  \}
59
60 """
61 This package is used to create and visualize structural elements. It contains
62 three modules:
63
64 * This module :mod:`salome.geom.structelem` defines the main classes
65   :class:`StructuralElement` and :class:`StructuralElementManager` that can be
66   directly used to build structural elements.
67 * The module :mod:`salome.geom.structelem.parts` defines the classes corresponding to
68   the different parts (beams, grids, etc.) that make up a structural element.
69   It is used to build the geometric shapes in the structural element.
70 * The module :mod:`salome.geom.structelem.orientation` defines the classes that are
71   used to compute the orientation of the structural element parts and to build
72   the corresponding markers.
73
74 A structural element is a set of geometric shapes (beams, grids, etc.) that
75 are built semi-automatically along a set of geometric primitives (edges for
76 instance). They are visualized with the same color as their base primitives in
77 the geom viewer.
78
79 Structural elements are generally created by the
80 :class:`StructuralElementManager` class, from a list of commands describing
81 the element to create.
82
83 Example::
84
85     commandList = [('VisuPoutreGenerale', {'Group_Maille': 'Edge_1'}),
86                    ('VisuBarreCercle',
87                     {'R': 30, 'Group_Maille': 'Edge_1', 'EP': 15}),
88                   ]
89
90     structElemManager = StructuralElementManager()
91     elem = structElemManager.createElement(commandList)
92     elem.display()
93     salome.sg.updateObjBrowser(True)
94
95 """
96
97 import types
98
99 import salome
100
101 from salome.kernel.logger import Logger
102 from salome.kernel import termcolor
103 logger = Logger("salome.geom.structelem", color = termcolor.RED)
104 from salome.kernel.studyedit import getStudyEditor
105
106 __all__ = ["parts", "orientation"]
107
108 from salome.geom.geomtools import getGeompy
109 from salome.geom.structelem import parts
110 from salome.geom.structelem.parts import InvalidParameterError
111
112 import GEOM
113
114 ## This class manages the structural elements in the study. It is used to
115 #  create a new structural element from a list of commands. The parameter
116 #  \em studyId defines the ID of the study in which the manager will create
117 #  structural elements. If it is \b None or not specified, it will use
118 #  the ID of the current study as defined by 
119 #  \b salome.kernel.studyedit.getActiveStudyId() function.
120 #  \ingroup structelem
121 class StructuralElementManager:
122     """
123     This class manages the structural elements in the study. It is used to
124     create a new structural element from a list of commands. The parameter
125     `studyId` defines the ID of the study in which the manager will create
126     structural elements. If it is :const:`None` or not specified, it will use
127     the ID of the current study as defined by
128     :func:`salome.kernel.studyedit.getActiveStudyId` function.
129     """
130     def __init__(self, studyId = None):
131         self._studyEditor = getStudyEditor(studyId)
132
133     ## Create a structural element from the list of commands \em commandList.
134     #  Each command in this list represent a part of the structural element,
135     #  that is a specific kind of shape (circular beam, grid, etc.)
136     #  associated with one or several geometrical primitives. A command must
137     #  be a tuple. The first element is the structural element part class
138     #  name or alias name. The second element is a dictionary containing the
139     #  parameters describing the part. Valid class names are all the classes
140     #  defined in the module salome.geom.structelem.parts and inheriting
141     #  parts.StructuralElementPart. There are also several
142     #  aliases for backward compatibility. Here is the complete list:        
143     #  - parts.GeneralBeam
144     #  - parts.CircularBeam
145     #  - parts.RectangularBeam
146     #  - parts.ThickShell
147     #  - parts.Grid
148     #  - parts.VisuPoutreGenerale() (alias for parts.GeneralBeam)
149     #  - parts.VisuPoutreCercle() (alias for parts.CircularBeam)
150     #  - parts.VisuPoutreRectangle() (alias for parts.RectangularBeam)
151     #  - parts.VisuBarreGenerale() (alias for parts.GeneralBeam)
152     #  - parts.VisuBarreRectangle() (alias for parts.RectangularBeam)
153     #  - parts.VisuBarreCercle() (alias for parts.CircularBeam)
154     #  - parts.VisuCable() (alias for parts.CircularBeam)
155     #  - parts.VisuCoque() (alias for parts.ThickShell)
156     #  - parts.VisuGrille() (alias for parts.Grid)
157     #  - \b Orientation: This identifier is used to specify the orientation
158     #  of one or several 1D structural element parts (i.e. beams). The
159     #  parameters are described in class orientation.Orientation1D.
160     #
161     #  The valid parameters in the dictionary depend on the type of the
162     #  structural element part, and are detailed in the documentation of
163     #  the corresponding class. The only parameter that is common to all the
164     #  classes is "MeshGroups" (that can also be named "Group_Maille"). It
165     #  defines the name of the geometrical object(s) in the study that will
166     #  be used as primitives to build the structural element part. This
167     #  parameter can be either a list of strings or a single string with
168     #  comma separated names.
169     def createElement(self, commandList):
170         """
171         Create a structural element from the list of commands `commandList`.
172         Each command in this list represent a part of the structural element,
173         that is a specific kind of shape (circular beam, grid, etc.)
174         associated with one or several geometrical primitives. A command must
175         be a tuple. The first element is the structural element part class
176         name or alias name. The second element is a dictionary containing the
177         parameters describing the part. Valid class names are all the classes
178         defined in the module :mod:`~salome.geom.structelem.parts` and inheriting
179         class :class:`~parts.StructuralElementPart`. There are also several
180         aliases for backward compatibility. Here is the complete list:
181         
182         * :class:`~parts.GeneralBeam`
183         * :class:`~parts.CircularBeam`
184         * :class:`~parts.RectangularBeam`
185         * :class:`~parts.ThickShell`
186         * :class:`~parts.Grid`
187
188         * :func:`~parts.VisuPoutreGenerale` (alias for
189           :class:`~parts.GeneralBeam`)
190         * :func:`~parts.VisuPoutreCercle` (alias for
191           :class:`~parts.CircularBeam`)
192         * :func:`~parts.VisuPoutreRectangle` (alias for
193           :class:`~parts.RectangularBeam`)
194         * :func:`~parts.VisuBarreGenerale` (alias for
195           :class:`~parts.GeneralBeam`)
196         * :func:`~parts.VisuBarreRectangle` (alias for
197           :class:`~parts.RectangularBeam`)
198         * :func:`~parts.VisuBarreCercle` (alias for
199           :class:`~parts.CircularBeam`)
200         * :func:`~parts.VisuCable` (alias for :class:`~parts.CircularBeam`)
201         * :func:`~parts.VisuCoque` (alias for :class:`~parts.ThickShell`)
202         * :func:`~parts.VisuGrille` (alias for :class:`~parts.Grid`)
203         
204         * ``Orientation``: This identifier is used to specify the orientation
205           of one or several 1D structural element parts (i.e. beams). The
206           parameters are described in class
207           :class:`~orientation.Orientation1D`.
208
209         The valid parameters in the dictionary depend on the type of the
210         structural element part, and are detailed in the documentation of
211         the corresponding class. The only parameter that is common to all the
212         classes is "MeshGroups" (that can also be named "Group_Maille"). It
213         defines the name of the geometrical object(s) in the study that will
214         be used as primitives to build the structural element part. This
215         parameter can be either a list of strings or a single string with
216         comma separated names.
217         """
218         logger.debug("StructuralElementManager.createElement: START")
219         logger.debug("Command list: %s" % commandList)
220
221         element = StructuralElement(self._studyEditor.studyId)
222         orientationCmdList = []
223         for command in commandList:
224             (parttype, parameters) = command
225             if parttype == "Orientation":
226                 orientationCmdList += [command]
227             elif parttype not in dir(parts):
228                 logger.warning('Invalid structural element part name "%s"'
229                                ' in command %s, this command will be '
230                                'ignored.' % (parttype, command))
231             else:
232                 (meshGroupList, newparams) = self._extractMeshGroups(command)
233                 for meshGroup in meshGroupList:
234                     # Get the geometrical primitive object
235                     if meshGroup.startswith('/'):
236                         groupSObj = self._studyEditor.study.FindObjectByPath(meshGroup)
237                         meshGroup = meshGroup.split('/')[-1]
238                         pass
239                     else:
240                         groupSObj = self._studyEditor.study.FindObject(meshGroup)
241                         pass
242                     groupGeomObj = None
243                     if groupSObj is not None:
244                         groupGeomObj = \
245                                 self._studyEditor.getOrLoadObject(groupSObj)
246                     if groupGeomObj is None:
247                         logger.error("Can't get geom object corresponding to "
248                                      'mesh group "%s", structural element '
249                                      "part %s will not be built." %
250                                      (meshGroup, command))
251                         continue
252                     
253                     # Create the part
254                     try:
255                         part = parts.__dict__[parttype](
256                                         self._studyEditor.studyId, meshGroup,
257                                         groupGeomObj, newparams)
258                         element.addPart(part)
259                     except InvalidParameterError as e:
260                         logger.error("Invalid parameter error: %s" % e)
261                         raise
262                     except:
263                         logger.exception("Can't create structural element"
264                                          " part with command %s." %
265                                          str(command))
266
267         # Orientations are parsed after the parts because they must be
268         # associated with existing parts.
269         for command in orientationCmdList:
270             (parttype, parameters) = command
271             (meshGroupList, orientParams) = self._extractMeshGroups(command)
272             for meshGroup in meshGroupList:
273                 element.addOrientation(meshGroup, orientParams)
274
275         element.build()
276         logger.debug("StructuralElementManager.createElement: END")
277         return element
278    
279     ## This method extracts the names of the mesh groups (i.e. the
280     #  geometrical objects used to build the structural element part) in the
281     #  command in parameter. It returns a tuple containing the mesh groups as
282     #  a list of strings and the other parameters of the command as a new
283     #  dictionary. 
284     def _extractMeshGroups(self, command):
285         """
286         This method extracts the names of the mesh groups (i.e. the
287         geometrical objects used to build the structural element part) in the
288         command in parameter. It returns a tuple containing the mesh groups as
289         a list of strings and the other parameters of the command as a new
290         dictionary.
291         """
292         (parttype, parameters) = command
293         newparams = parameters.copy()
294         groupMailleParam = newparams.pop("Group_Maille", None)
295         meshGroupParam = newparams.pop("MeshGroups", None)
296         if groupMailleParam is None and meshGroupParam is None:
297             logger.warning("No mesh group specified in command %s, this "
298                            "command will be ignored." % command)
299             return ([], newparams)
300         elif groupMailleParam is not None and meshGroupParam is not None:
301             logger.warning('Both "MeshGroups" and "Group_Maille" specified in'
302                            ' command %s, only "MeshGroups" will be used.' %
303                            command)
304         elif groupMailleParam is not None and meshGroupParam is None:
305             meshGroupParam = groupMailleParam
306         
307         if isinstance(meshGroupParam, str):
308             meshGroupList = [meshGroupParam]
309         else:
310             meshGroupList = meshGroupParam
311         
312         if len(meshGroupList) == 0:
313             logger.warning("Mesh group list is empty in command %s, this "
314                            "command will be ignored." % command)
315
316         return (meshGroupList, newparams)
317
318
319 ## This class represents a structural element, i.e. a set of geometrical
320 #  objects built along geometrical primitives. The parameter \em studyId
321 #  defines the ID of the study that will contain the structural element. If
322 #  it is \b None or not specified, the constructor will use the ID of
323 #  the active study as defined by \b salome.kernel.studyedit.getActiveStudyId
324 #  function. Structural elements are normally created by the class
325 #  StructuralElementManager, so this class should not be
326 #  instantiated directly in the general case.
327 #  \ingroup structelem
328 class StructuralElement:
329     """
330     This class represents a structural element, i.e. a set of geometrical
331     objects built along geometrical primitives. The parameter `studyId`
332     defines the ID of the study that will contain the structural element. If
333     it is :const:`None` or not specified, the constructor will use the ID of
334     the active study as defined by :func:`salome.kernel.studyedit.getActiveStudyId`
335     function. Structural elements are normally created by the class
336     :class:`StructuralElementManager`, so this class should not be
337     instantiated directly in the general case.
338     """
339     _counter = 1
340
341     MAIN_FOLDER_NAME = "Structural Elements"
342
343     def __init__(self, studyId = None):
344         # _parts is the dictionary mapping group name to structural element
345         # part. _shapeDict is the dictionary mapping SubShapeID objects to
346         # structural element parts. Both are used to avoid duplicate shapes
347         # in structural elements.
348         self._parts = {}
349         self._shapeDict = {}
350         self._id = StructuralElement._counter
351         StructuralElement._counter += 1
352         self._studyEditor = getStudyEditor(studyId)
353         logger.debug("Creating structural element in study %s" %
354                      self._studyEditor.studyId)
355         self._SObject = None
356
357     ## Find or create the study object corresponding to the structural
358     #  element. This object is a Geom Folder named "SE_N" where N is a
359     #  numerical ID. 
360     def _getSObject(self):
361         """
362         Find or create the study object corresponding to the structural
363         element. This object is a Geom Folder named "SE_N" where N is a
364         numerical ID. 
365         """
366         if self._SObject is None:
367             geompy = getGeompy(self._studyEditor.studyId)
368             geomComponent = self._studyEditor.study.FindComponent("GEOM")
369             mainFolder = self._studyEditor.findItem(geomComponent,
370                                                     name = StructuralElement.MAIN_FOLDER_NAME,
371                                                     typeId=999)
372             if mainFolder is None:
373                 mainFolder = geompy.NewFolder(StructuralElement.MAIN_FOLDER_NAME)
374             self._SObject = geompy.NewFolder("SE_" + str(self._id), mainFolder)
375         return self._SObject
376
377     ## Add a part to the structural element.
378     #
379     #  \param newpart (StructuralElementPart) the part to add to the structural element.
380     def addPart(self, newpart):
381         """
382         Add a part to the structural element.
383
384         :type  newpart: :class:`~parts.StructuralElementPart`
385         :param newpart: the part to add to the structural element.
386
387         """
388         newshapes = newpart.baseShapesSet
389
390         # Check duplicate groups
391         if newpart.groupName in self._parts:
392             logger.warning('Mesh group "%s" is used several times in the '
393                            'structural element. Only the last definition '
394                            'will be used.' % newpart.groupName)
395         else:
396             # Check duplicate shapes
397             intersect = newshapes.intersection(list(self._shapeDict.keys()))
398             while len(intersect) > 0:
399                 shape, = intersect
400                 oldpartwithshape = self._shapeDict[shape]
401                 oldpartshapes = oldpartwithshape.baseShapesSet
402                 intersectwitholdpart = intersect.intersection(oldpartshapes)
403                 logger.warning('Some shapes are common to groups "%s" and '
404                                '"%s". For those, the parameters defined for '
405                                '"%s" will be used.' %
406                                (oldpartwithshape.groupName, newpart.groupName,
407                                 newpart.groupName))
408                 oldpartwithshape.baseShapesSet = \
409                                 oldpartshapes.difference(intersectwitholdpart)
410                 intersect = intersect.difference(intersectwitholdpart)
411
412         # Finally add the new part in the structural element
413         self._parts[newpart.groupName] = newpart
414         for shape in newshapes:
415             self._shapeDict[shape] = newpart
416
417     ## Add orientation information to a part in the structural element. This
418     #  information will be used to build the corresponding markers.
419     #
420     #  \param meshGroup (string) the name of a geometrical primitive. The orientation
421     #  information will apply to the structural element part built along this primitive.
422     #  \param orientParams (dictionary) parameters defining the orientation of the
423     #  structural element part. Those parameters are detailed in class orientation.Orientation1D.
424     def addOrientation(self, meshGroup, orientParams):
425         """
426         Add orientation information to a part in the structural element. This
427         information will be used to build the corresponding markers.
428
429         :type  meshGroup: string
430         :param meshGroup: the name of a geometrical primitive. The orientation
431                           information will apply to the structural element
432                           part built along this primitive.
433
434         :type  orientParams: dictionary
435         :param orientParams: parameters defining the orientation of the
436                              structural element part. Those parameters are
437                              detailed in class
438                              :class:`~orientation.Orientation1D`.
439
440         """
441         if meshGroup in self._parts:
442             self._parts[meshGroup].addOrientation(orientParams)
443         else:
444             logger.warning('Mesh group "%s" not found in structural element, '
445                            'cannot set orientation.' % meshGroup)
446
447     ## Build the geometric shapes and the markers corresponding to the
448     #  different parts of the structural element, and add them to the study.
449     def build(self):
450         """
451         Build the geometric shapes and the markers corresponding to the
452         different parts of the structural element, and add them to the study.
453         """
454         gg = salome.ImportComponentGUI("GEOM")
455         geompy = getGeompy(self._studyEditor.studyId)
456         for part in self._parts.values():
457             # Build the structural element part
458             logger.debug("Building %s" % part)
459             try:
460                 (shape, markers) = part.build()
461                 if shape is None:
462                     logger.error("Part %s has not been built" % part)
463                     continue
464             except:
465                 logger.exception("Couldn't build part %s" % part)
466                 continue
467             
468             # Add the new objects to the study
469             shapeSObjName = part.name + "_" + part.groupName
470             geompy.addToStudy(shape, shapeSObjName)
471             geompy.PutToFolder(shape, self._getSObject())
472
473             if markers is not None and len(markers) > 0:
474                 for i, marker in enumerate(markers, start = 1):
475                     markerSObjName = "Orient_" + shapeSObjName
476                     if len(markers) > 1:
477                         markerSObjName += "_%d" % i
478                     geompy.addToStudy(marker, markerSObjName)
479                     geompy.PutToFolder(marker, self._getSObject())
480
481     ## Display the structural element in the geom view.
482     def display(self):
483         """
484         Display the structural element in the geom view.
485         """
486         StructuralElement.showElement(self._SObject)
487
488     @staticmethod
489     ## Display the structural element corresponding to the study object \b theSObject
490     def showElement(theSObject):
491         """
492         Display the structural element corresponding to the study object
493         `theSObject`
494         """
495         if theSObject is not None:
496             gg = salome.ImportComponentGUI("GEOM")
497             aStudy = theSObject.GetStudy()
498             useCaseBuilder = aStudy.GetUseCaseBuilder()
499             editor = getStudyEditor(aStudy._get_StudyId())
500             aIterator = useCaseBuilder.GetUseCaseIterator(theSObject)
501             aIterator.Init(False)
502             while aIterator.More():
503                 sobj = aIterator.Value()
504                 icon = editor.getIcon(sobj)
505                 if icon != "ICON_OBJBROWSER_LCS":
506                     entry = aIterator.Value().GetID()
507                     gg.createAndDisplayGO(entry)
508                     gg.setDisplayMode(entry, 2) # Shading + edges
509                 aIterator.Next()
510
511
512 def TEST_CreateGeometry():
513     import salome
514     salome.salome_init()
515     import GEOM
516     from salome.geom import geomBuilder
517     geompy = geomBuilder.New(salome.myStudy)
518     import SALOMEDS
519     geompy.init_geom(salome.myStudy)
520     Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
521     edges = geompy.SubShapeAllSorted(Box_1, geompy.ShapeType["EDGE"])
522     geompy.addToStudy(Box_1, "Box_1")
523     for i in range(len(edges)):
524         geompy.addToStudyInFather(Box_1, edges[i], "Edge_%d" % i)
525     faces = geompy.SubShapeAllSorted(Box_1, geompy.ShapeType["FACE"])
526     faces[3].SetColor(SALOMEDS.Color(1.0,0.5,0.0))
527     faces[4].SetColor(SALOMEDS.Color(0.0,1.0,0.5))
528     for i in range(len(faces)):
529         geompy.addToStudyInFather(Box_1, faces[i], "Face_%d" % i)
530     Cylinder_1 = geompy.MakeCylinderRH(50, 200)
531     geompy.TranslateDXDYDZ(Cylinder_1, 300, 300, 0)
532     cyl_faces = geompy.SubShapeAllSorted(Cylinder_1, geompy.ShapeType["FACE"])
533     geompy.addToStudy(Cylinder_1, "Cylinder_1")
534     for i in range(len(cyl_faces)):
535         geompy.addToStudyInFather(Cylinder_1, cyl_faces[i], "CylFace_%d" % i)
536     Cylinder_2 = geompy.MakeTranslation(Cylinder_1, 100, 100, 0)
537     cyl_faces2 = geompy.SubShapeAllSorted(Cylinder_2,
538                                           geompy.ShapeType["FACE"])
539     geompy.addToStudy(Cylinder_2, "Cylinder_2")
540     for i in range(len(cyl_faces2)):
541         geompy.addToStudyInFather(Cylinder_2, cyl_faces2[i],
542                                   "CylFace2_%d" % i)
543
544
545 def TEST_StructuralElement():
546     salome.salome_init()
547     TEST_CreateGeometry()
548     liste_commandes = [('Orientation', {'MeshGroups': 'Edge_4',
549                                         'VECT_Y': (1.0, 0.0, 1.0)}),
550                        ('Orientation', {'MeshGroups': 'Edge_5',
551                                         'ANGL_VRIL': 45.0}),
552                        ('GeneralBeam', {'MeshGroups': ['Edge_1', 'Edge_7'],
553                                         'A': 1, 'IY1': 20, 'IY2': 40,
554                                         'IZ1': 60, 'IZ2': 30}),
555                        ('VisuPoutreCercle', {'MeshGroups': ['Edge_6'],
556                                              'R1': 30, 'R2': 20}),
557                        ('CircularBeam', {'MeshGroups': ['Edge_2', 'Edge_3'],
558                                          'R': 40, 'EP': 20}),
559                        ('RectangularBeam', {'MeshGroups': ['Edge_4', 'Edge_5'],
560                                             'HZ1': 60, 'HY1': 40,
561                                             'EPZ1': 15, 'EPY1': 10,
562                                             'HZ2': 40, 'HY2': 60,
563                                             'EPZ2': 10, 'EPY2': 15}),
564                        ('VisuCable', {'MeshGroups': 'Edge_7', 'R': 5}),
565                        ('VisuCoque', {'MeshGroups': 'Face_4',
566                                       'Epais': 10, 'Excentre': 5,
567                                       'angleAlpha': 45, 'angleBeta': 60}),
568                        ('VisuCoque', {'MeshGroups': 'CylFace_2', 'Epais': 5}),
569                        ('VisuGrille', {'MeshGroups': 'Face_5', 'Excentre': 5,
570                                        'angleAlpha': 45, 'angleBeta': 60}),
571                        ('VisuGrille', {'MeshGroups': 'CylFace2_2',
572                                        'Excentre': 5, 'origAxeX': 400,
573                                        'origAxeY': 400, 'origAxeZ': 0,
574                                        'axeX': 0, 'axeY': 0, 'axeZ': 100}),
575                       ]
576
577     structElemManager = StructuralElementManager()
578     elem = structElemManager.createElement(liste_commandes)
579     if salome.hasDesktop():
580         elem.display()
581         salome.sg.updateObjBrowser(True)
582
583
584 # Main function only used to test the module
585 if __name__ == "__main__":
586     TEST_StructuralElement()