1 # -*- coding: utf-8 -*-
2 #_____________________________________
4 import sys, os, re,types
6 from PyQt4.QtGui import QMessageBox
8 from salome.kernel.logger import Logger
9 logger = Logger( "EFICAS_SRC.EFICASGUI.eficasSalome.py" )
12 # eficasConfig definit le EFICAS_ROOT
13 # lignes de path ajoutees pour acceder aux packages python du
14 # logiciel Eficas. Le package Aster est ajoute explicitement pour
15 # acceder au module prefs.py. A
16 # ajout de InterfaceQT4 pour permettre l acces a la fenetre Option
17 sys.path[:0]=[eficasConfig.eficasPath,
18 os.path.join( eficasConfig.eficasPath,'Editeur'),
19 os.path.join( eficasConfig.eficasPath,'UiQT4'),
20 os.path.join( eficasConfig.eficasPath,'InterfaceQT4'),
21 eficasConfig.eficasPath,
26 from InterfaceQT4 import qtEficas
32 from salome.kernel.studyedit import getStudyEditor
35 # couleur pour visualisation des geometries
37 COLORS = colors.ListeColors
38 LEN_COLORS = len( COLORS )
41 class MyEficas( qtEficas.Appli ):
43 Classe de lancement du logiciel EFICAS dans SALOME
44 Cette classe specialise le logiciel Eficas par l'ajout de:
45 a)la creation de groupes de mailles dans le composant SMESH de SALOME
46 b)la visualisation d'elements geometrique dans le coposant GEOM de SALOME par selection dans EFICAS
48 def __init__( self, parent, code = "ASTER", fichier = None, module = "EFICAS",
49 version = None, componentName = "Eficas",multi=False):
53 @param parent: widget Qt parent
55 @param code: catalogue a lancer ( ASTER, HOMARD OPENTURNS ). optionnel ( defaut = ASTER ).
57 @param fichier: chemin absolu du fichier eficas a ouvrir a das le lancement. optionnel
60 dictPathCode={'ASTER':'Aster','OPENTURNS_STUDY':'Openturns_Study','CARMEL3D':'Carmel3D',
61 'OPENTURNS_WRAPPER':'Openturns_Wrapper','MAP':'MAP','SEP':'Sep'}
62 if code in dictPathCode.keys():
63 pathCode=dictPathCode[code]
64 sys.path[:0]=[os.path.join(eficasConfig.eficasPath,pathCode)]
66 if Editeur.__dict__.has_key( 'session' ):
67 from Editeur import session
71 eficasArg += [ fichier ]
73 eficasArg += [ "-c", version ]
76 session.parse( eficasArg )
78 self.editor = getStudyEditor() # Editeur de l'arbre d'etude
80 qtEficas.Appli.__init__( self,code=code,salome=1,parent=parent,multi=multi)
82 #--------------- specialisation EFICAS dans SALOME -------------------
84 self.salome = True #active les parties de code specifique dans Salome( pour le logiciel Eficas )
85 self.module = module #indique sous quel module dans l'arbre d'etude ajouter le JDC.
86 self.componentName = componentName
88 # donnee pour la creation de groupe de maille
89 self.mainShapeNames = {} #dictionnaire pour gerer les multiples fichiers possibles ouverts par
90 #eficas ( cle = identifiant du JDC ), une mainshape par fichier ouvert.
91 #dictionnaire des sous-geometrie de la geometrie principale ( cle = entry, valeur = name )
92 #----------------------------------------------------------------------
94 self.icolor = 0 # compteur pour memoriser la couleur courante
98 def closeEvent(self,event):
103 if hasattr(self,'readercata') :
110 # ___________________________ Methodes de l ex Pal __________________________________
112 #----------------------------------------------------------------
113 def getCORBAObjectInComponent( self, entry, composant ):
114 #----------------------------------------------------------------
116 mySO = self.editor.study.FindObjectID(entry)
118 object = mySO.GetObject()
120 myComponent = salome.lcc.FindOrLoadComponent("FactoryServer", composant)
121 SCom = self.editor.study.FindComponent( composant )
122 print myComponent , SCom
123 self.editor.builder.LoadWith( SCom , myComponent )
124 object = mySO.GetObject()
126 logger.debug("selectedEntry: An error occurs")
130 #----------------------------------------------
131 def giveMeshGroups( self,entry,label1,typeMesh):
132 #----------------------------------------------
137 monMaillage =self.getCORBAObjectInComponent(entry,"SMESH")
138 if monMaillage != None : # selection d'un groupe de SMESH
139 if monMaillage._narrow(SMESH.SMESH_Mesh):
140 mailSO = self.editor.study.FindObjectID(entry)
141 if mailSO == None : return names, msg
144 subIt = self.editor.study.NewChildIterator(mailSO)
146 subSO = subIt.Value()
149 if (subSO.GetName()[0:9]!=label1) : continue
150 subSSMeshit=self.editor.study.NewChildIterator(subSO)
151 while subSSMeshit.More():
152 subSSMeshSO = subSSMeshit.Value()
154 if subSSMeshSO.GetObject()._narrow(typeMesh):
155 names.append(subSSMeshSO.GetName())
157 msg=entry + " n est pas un maillage"
159 logger.debug(' giveMeshGroups pb avec ( entry = %s ) ' %entry )
160 msg=' giveMeshGroup pb avec ( entry = %s ) '+ entry
163 #-------------------------------------
164 def isMeshGroup( self,entry):
165 #-------------------------------------
169 monObjet =self.getCORBAObjectInComponent(entry,"SMESH")
170 if monObjet != None : # selection d'un groupe de SMESH
171 if monObjet._narrow(SMESH.SMESH_GroupBase):
174 logger.debug(' isMeshGroup pb avec ( entry = %s ) ' %entry )
177 #-------------------------------------
178 def isShape( self,entry):
179 #-------------------------------------
183 monObjet =self.getCORBAObjectInComponent(entry,"GEOM")
184 if monObjet != None : # selection d'un objet GEOM
185 if monObjet._narrow(GEOM.GEOM_Object ):
188 logger.debug(' isShape pb avec ( entry = %s ) ' %entry )
191 #-----------------------------------------------------------------
192 def getMainShapeEntry(self,entry):
193 #-----------------------------------------------------------------
196 mainShapeEntry = entry.split(':')[:4]
197 if len(mainShapeEntry) == 4:
198 strMainShapeEntry = '%s:%s:%s:%s'%tuple(mainShapeEntry)
199 if self.isMainShape(strMainShapeEntry):
200 result = strMainShapeEntry
202 logger.debug( 'Erreur pour SalomeStudy.getMainShapeEntry( entry = %s ) ' %entry )
206 #-----------------------------------------------------------------
207 def isMainShape(self,entry):
208 #-----------------------------------------------------------------
211 monObjet =self.getCORBAObjectInComponent(entry,"GEOM")
213 shape = monObjet._narrow( GEOM.GEOM_Object )
214 if shape.IsMainShape():
217 logger.debug( 'Errreur pour SalomeStudy.isMainShape( entry = %s ) ' %entry )
222 #-----------------------------------------------------------------
223 def ChercheType( self, shape ):
224 #-----------------------------------------------------------------
225 tgeo = shape.GetShapeType()
226 geomEngine = salome.lcc.FindOrLoadComponent( "FactoryServer", "GEOM" )
227 #print dir(self.editor.study)
228 groupIMeasureOp = geomEngine.GetIMeasureOperations(self.editor.study._get_StudyId())
229 if tgeo != "COMPOUND" : return tgeo
231 strInfo = groupIMeasureOp.WhatIs( shape )
233 l = strInfo.split('\n')
236 nom, valeur = couple.split(':')
237 dictInfo[ nom.strip() ] = valeur.strip()
239 ordre = [ "COMPSOLID", "SOLID", "SHELL", "FACE", "WIRE", "EDGE", "VERTEX" ]
241 if dictInfo[ t ] != '0':
247 #-----------------------------------------------------------------
248 def selectShape( self, editor, entry, kwType = None ):
249 #-----------------------------------------------------------------
251 selection sous-geometrie dans Salome:
252 -test1) si c'est un element sous-geometrique .
253 -test2) si appartient a la geometrie principale.
255 name, msgError = '',''
256 mySO = self.editor.study.FindObjectID(entry)
258 return name, msgError
259 object = mySO.GetObject()
261 return name, msgError
264 shape = object._narrow( GEOM.GEOM_Object )
266 return name, msgError
268 tGeo=self.ChercheType(shape)
270 return name, msgError
271 #if kwType == "GROUP_NO" and str(tGeo) != "VERTEX":
272 # name,msgError = '',"la selection n est pas un Vertex"
273 # return name, msgError
274 if kwType == "GROUP_MA" and str(tGeo) == "VERTEX":
275 name, msgError = '', "la selection n est pas un groupe de maille"
276 return name, msgError
278 mainShapeEntry = self.getMainShapeEntry( entry )
279 if self.mainShapeNames.has_key( editor ):
280 #print "------------- self.mainShapeNames[editor]" , self.mainShapeNames[editor]
281 if self.mainShapeNames[editor] == mainShapeEntry:
284 msgError="Le groupe reference la geometrie " + mainShapeEntry + " et non " + self.mainShapeNames[editor]
286 self.mainShapeNames[editor] = mainShapeEntry
289 return name, msgError
292 #-----------------------------------------------------------------
293 def selectMeshGroup( self, editor, selectedEntry, kwType = None ):
294 #-----------------------------------------------------------------
296 selection groupe de maille dans Salome:
297 -test 1) si c'est un groupe de maille
298 -test 2) si le maillage fait reference a la geometrie principale
300 name, msgError = '',''
302 mySO=self.editor.study.FindObjectID(selectedEntry )
303 from salome.smesh.smeshstudytools import SMeshStudyTools
304 monSMeshStudyTools=SMeshStudyTools(self.editor)
305 meshSO = monSMeshStudyTools.getMeshFromGroup(mySO)
306 if meshSO == None : return name, msgError
308 # on verifie que l entree selectionnee a le bon type (NODE ou EDGE...)
310 groupObject = self.getCORBAObjectInComponent(selectedEntry,"SMESH")
312 logger.debug("selectedMeshEntry: An error occurs")
315 aGroup = groupObject._narrow( SMESH.SMESH_GroupBase )
316 if aGroup: tGroup = aGroup.GetType()
318 if kwType == "GROUP_NO" and tGroup != SMESH.NODE:
319 msgError = "GROUP_NO attend un groupe de noeud"
320 return name, msgError
321 elif kwType == "GROUP_MA" and tGroup == SMESH.NODE:
322 msgError = "GROUP_MA attend un point goupe de maille"
323 return name, msgError
325 # on cherche la shape associee
326 #PN PN mesh_Object est un SOject
327 meshObject = meshSO.GetObject()
328 mesh = meshObject._narrow( SMESH.SMESH_Mesh )
329 if mesh: #c'est bien un objet maillage
330 shape = mesh.GetShapeToMesh()
332 ior = salome.orb.object_to_string( shape )
334 sObject = self.editor.study.FindObjectIOR( ior )
335 mainShapeID = sObject.GetID()
339 return name, "Type d objet non permis"
341 # on cherche si la shape associee est la bonne
342 #print "------------- mainShapeID" , mainShapeID
343 if self.mainShapeNames.has_key( editor ):
344 #print "------------- self.mainShapeNames[editor]" , self.mainShapeNames[editor]
345 if self.mainShapeNames[editor] == mainShapeID:
348 msgError="Le groupe reference la geometrie " + mainShapeID + " et non " + self.mainShapeNames[editor]
350 self.mainShapeNames[editor] = mainShapeID
353 #print "------------------------------ name :", name
354 #print "------------------------------ name :", name
355 #print "------------------------------ name :", name
359 def displayMeshGroups(self, meshGroupName):
361 visualisation group de maille de nom meshGroupName dans salome
363 ok, msgError = False, ''
366 sg = salome.ImportComponentGUI('SMESH')
367 meshGroupEntries = []
369 selMeshGroupEntry = None
371 # liste des groupes de maille de nom meshGroupName
372 listSO = self.editor.study.FindObjectByName(meshGroupName, "SMESH")
374 #print "liste des groupes de maille de nom %s: "%(meshGroupName), listSO
377 return 0,'Plusieurs objets portent ce nom'
379 return 0,'Aucun objet ne porte ce nom'
381 groupEntry = SObjet.GetID()
382 myComponent = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
383 SCom = self.editor.study.FindComponent("SMESH")
384 myBuilder = self.editor.study.NewBuilder()
385 myBuilder.LoadWith( SCom , myComponent )
386 sg.CreateAndDisplayActor(groupEntry)
387 #color = COLORS[ self.icolor % LEN_COLORS ]
388 #self.icolor = self.icolor + 1
389 #sg.SetColor(groupEntry, color[0], color[1], color[2])
390 salome.sg.Display(groupEntry)
396 msgError = "Impossible d afficher "+shapeName
400 # ___________________________ Methodes appelees par EFICAS __________________________________
401 #----------------------------------------------------------------
402 def selectGroupFromSalome( self, kwType = None, editor=None):
403 #----------------------------------------------------------------
405 Selection d'element(s) d'une geometrie ( sub-shape ) ou d'element(s) de maillage ( groupe de maille) partir de l'arbre salome
406 retourne ( la liste des noms des groupes, message d'erreur )
408 Note: Appele par EFICAS lorsqu'on clique sur le bouton ajouter la liste du panel GROUPMA
412 atLeastOneStudy = self.editor.study
413 if not atLeastOneStudy:
416 # recupere toutes les selections de l'utilsateur dans l'arbre Salome
417 entries = salome.sg.getAllSelected()
418 nbEntries = len( entries )
420 for entry in entries:
421 if self.isMeshGroup(entry): # selection d 'un sous maillage
422 name, msg = self.selectMeshGroup( editor, entry, kwType )
423 elif self.isShape(entry): # selection d'une sous-geometrie
424 name, msg = self.selectShape( editor, entry, kwType )
426 name, msg = None, "Selection SALOME non autorisee."
431 logger.debug("selectGroupFromSalome: An error occurs")
432 #print "=================== selectGroupFromSalome ", names, msg
433 #print "=================== selectGroupFromSalome ", names, msg
434 #print "=================== selectGroupFromSalome ", names, msg
437 #---------------------------------------------
438 def addJdcInSalome( self, jdcPath ):
439 #---------------------------------------------
441 Ajoute le Jeu De Commande dans l'arbre d'etude Salome dans la rubrique EFICAS
444 msgError = "Erreur dans l'export du fichier de commande dans l'arbre d'etude Salome"
447 atLeastOneStudy = self.editor.study
448 if not atLeastOneStudy:
451 fileType = { 'ASTER' : "FICHIER_EFICAS_ASTER",
452 'SEP' : "FICHIER_EFICAS_SEP",
453 'MAP' : "FICHIER_EFICAS_MAP",
454 'OPENTURNS': "FICHIER_EFICAS_OPENTURNS",
455 'OPENTURNS_STUDY': "FICHIER_EFICAS_OPENTURNS_STUDY",
456 'OPENTURNS_WRAPPER': "FICHIER_EFICAS_OPENTURNS_WRAPPER",
457 'CARMEL3D': "FICHIER_EFICAS_CARMEL3D",
460 folderName = { 'ASTER' : 'AsterFiles',
462 'CARMEL3D' : 'CARMEL3DFiles' ,
464 'OPENTURNS_STUDY': 'OpenturnsFiles',
465 'OPENTURNS_WRAPPER': 'OpenturnsFiles'}
467 folderType = { 'ASTER': "ASTER_FILE_FOLDER",
468 'SEP': "SEP_FILE_FOLDER",
469 'MAP': "MAP_FILE_FOLDER",
470 'CARMEL3D': "CARMEL3D_FILE_FOLDER",
471 'OPENTURNS_STUDY':"OPENTURNS_FILE_FOLDER",
472 'OPENTURNS_WRAPPER': "OPENTURNS_FILE_FOLDER"}
475 moduleEntry = self.editor.findOrCreateComponent(self.module, self.componentName)
476 itemName = re.split("/",jdcPath)[-1]
478 if folderName.has_key(self.code) :
479 monFolderName=folderName[ self.code ]
481 monFolderName=str(self.code)+"Files"
483 if folderType.has_key(self.code) :
484 monFolderType=fileType[ self.code ]
486 monFolderType=str(self.code)+"_FILE_FOLDER"
488 if fileType.has_key(self.code) :
489 monFileType=fileType[ self.code ]
491 monFileType="FICHIER_EFICAS_"+str(self.code)
493 fatherEntry = self.editor.findOrCreateItem(
495 name = monFolderName,
496 #icon = "ICON_COMM_FOLDER",
497 fileType = monFolderType)
499 commEntry = self.editor.findOrCreateItem( fatherEntry ,
501 fileType = monFileType,
503 #icon = "ICON_COMM_FILE",
504 comment = str( jdcPath ))
506 salome.sg.updateObjBrowser(1)
508 #print 'addJdcInSalome commEntry->', commEntry
510 ok, msgError = True, ''
511 except Exception, exc:
512 msgError = "Can't add Eficas file to Salome study tree"
513 logger.debug(msgError, exc_info = True)
514 QMessageBox.warning(self, self.tr("Warning"),
515 self.tr("%s. Reason:\n%s\n\nSee logs for "
516 "more details." % (msgError, exc)))
520 #---------------------------------------
521 def displayShape( self, shapeName ):
522 #---------------------------------------
524 visualisation de nom shapeName dans salome
526 ok, msgError = False, ''
530 sgPyQt = SalomePyQt.SalomePyQt()
531 myActiveView=sgPyQt.getActiveView()
532 if myActiveView < 0 :
533 return ok, 'pas de vue courante'
535 currentViewType=sgPyQt.getViewType(myActiveView)
536 if str(currentViewType) != "OCCViewer" : # maillage
537 ok, msgError = self.displayMeshGroups(shapeName)
539 current_color = COLORS[ self.icolor % LEN_COLORS ]
540 from salome.geom.geomtools import GeomStudyTools
541 myGeomTools=GeomStudyTools(self.editor)
542 ok = myGeomTools.displayShapeByName( shapeName, current_color )
544 self.icolor = self.icolor + 1
546 msgError = "Impossible d afficher "+shapeName
552 #---------------------------------------
553 def ChercheGrpMeshInSalome(self):
554 print "je passe par la"
558 entries = salome.sg.getAllSelected()
559 nbEntries = len( entries )
560 names, msg = None, "Selection SALOME non autorisee."
562 for entry in entries:
564 names,msg=self.giveMeshGroups(entry,"SubMeshes",SMESH.SMESH_subMesh)
570 #---------------------------------------
571 def ChercheGrpMailleInSalome(self):
576 entries = salome.sg.getAllSelected()
577 nbEntries = len( entries )
578 names, msg = None, "Selection SALOME non autorisee."
580 for entry in entries:
582 names,msg=self.giveMeshGroups(entry,"Groups of",SMESH.SMESH_GroupBase)
590 #---------------------------------------
592 # def buildCabriGeom( self, name, **param ):
594 visualisation dans GEOM d'une geometrie CABRI
597 # qt.QApplication.setOverrideCursor( qt.QCursor.waitCursor )
598 # cabri.tetra( name, **param )
599 # qt.QApplication.restoreOverrideCursor()
603 #-------------------------------------------------------------------------------------------------------
604 # Pilotage de la Visu des elements de structures
608 def envoievisu(self,liste_commandes):
610 from salome.geom.structelem import StructuralElementManager, InvalidParameterError
612 QMessageBox.critical(self, self.tr("Error"),
613 self.tr("Cannot display structural elements: "
614 "module GEOM is not installed."))
617 atLeastOneStudy = self.editor.study
618 if not atLeastOneStudy:
620 logger.debug(10*'#'+":envoievisu: creating a StructuralElementManager instance")
621 structElemManager = StructuralElementManager()
622 elem = structElemManager.createElement(liste_commandes)
624 salome.sg.updateObjBrowser(True)
625 except InvalidParameterError, err:
626 trStr = self.tr("Invalid parameter for group %(group)s: %(expr)s must be "
627 "greater than %(minval)g (actual value is %(value)g)")
628 msg = str(trStr) % {"group": err.groupName, "expr": err.expression,
629 "minval": err.minValue, "value": err.value}
630 QMessageBox.warning(self, self.tr("Error"), msg)
632 traceback.print_exc()
633 logger.debug(10*'#'+":pb dans envoievisu")
636 #-------------------------------------------------------------------------------------------------------
637 # Point d'entree lancement EFICAS
639 def runEficas( code=None, fichier=None, module = "EFICAS", version=None, componentName = "Eficas",multi=False):
640 logger.debug(10*'#'+":runEficas: START")
642 logger.debug(10*'#'+":runEficas: code="+str(code))
643 logger.debug(10*'#'+":runEficas: fichier="+str(fichier))
644 logger.debug(10*'#'+":runEficas: module="+str(module))
645 logger.debug(10*'#'+":runEficas: version="+str(version))
647 #if not appli: #une seul instance possible!
648 appli = MyEficas( SalomePyQt.SalomePyQt().getDesktop(), code = code, fichier = fichier,
649 module = module, version = version, componentName = componentName,multi=multi )
650 #if not appli: #une seul instance possible!
651 # appli = MyEficas( SalomePyQt.SalomePyQt().getDesktop(), code = code, fichier = fichier,
652 # module = module, componentName = componentName, version=version )
653 logger.debug(10*'#'+":runEficas: END")