1 # -*- coding: utf-8 -*-
2 #_____________________________________
4 import sys, os, re,types
6 from PyQt4.QtGui import QMessageBox
7 from PyQt4.QtGui import QApplication
9 from salome.kernel.logger import Logger
10 logger = Logger( "EFICAS_SRC.EFICASGUI.eficasSalome.py" )
13 # eficasConfig definit le EFICAS_ROOT
14 # lignes de path ajoutees pour acceder aux packages python du
15 # logiciel Eficas. Le package Aster est ajoute explicitement pour
16 # acceder au module prefs.py. A
17 # ajout de InterfaceQT4 pour permettre l acces a la fenetre Option
18 sys.path[:0]=[eficasConfig.eficasPath,
19 os.path.join( eficasConfig.eficasPath,'Editeur'),
20 os.path.join( eficasConfig.eficasPath,'UiQT4'),
21 os.path.join( eficasConfig.eficasPath,'InterfaceQT4'),
22 os.path.join( eficasConfig.eficasPath,'Extensions'),
23 eficasConfig.eficasPath,
28 from InterfaceQT4 import qtEficas
32 sgPyQt = SalomePyQt.SalomePyQt()
33 langue=str(sgPyQt.stringSetting("language","language"))
36 from salome.kernel.studyedit import getStudyEditor
39 # couleur pour visualisation des geometries
41 COLORS = colors.ListeColors
42 LEN_COLORS = len( COLORS )
44 from Extensions import localisation
45 localisation.localise(None,langue)
49 class MyEficas( qtEficas.Appli ):
51 Classe de lancement du logiciel EFICAS dans SALOME
52 Cette classe specialise le logiciel Eficas par l'ajout de:
53 a)la creation de groupes de mailles dans le composant SMESH de SALOME
54 b)la visualisation d'elements geometrique dans le coposant GEOM de SALOME par selection dans EFICAS
56 def __init__( self, parent, code = "ASTER", fichier = None, module = "EFICAS",
57 version = None, componentName = "Eficas",multi=False):
61 @param parent: widget Qt parent
63 @param code: catalogue a lancer ( ASTER, HOMARD OPENTURNS ). optionnel ( defaut = ASTER ).
65 @param fichier: chemin absolu du fichier eficas a ouvrir a das le lancement. optionnel
68 dictPathCode={'ASTER':'Aster','OPENTURNS_STUDY':'Openturns_Study','CARMEL3D':'Carmel3D',
69 'OPENTURNS_WRAPPER':'Openturns_Wrapper','MAP':'MAP','SEP':'Sep'}
70 if code in dictPathCode.keys():
71 pathCode=dictPathCode[code]
72 sys.path[:0]=[os.path.join(eficasConfig.eficasPath,pathCode)]
74 if Editeur.__dict__.has_key( 'session' ):
75 from Editeur import session
79 eficasArg += [ fichier ]
81 eficasArg += [ "-c", version ]
84 session.parse( eficasArg )
86 self.editor = getStudyEditor() # Editeur de l'arbre d'etude
88 qtEficas.Appli.__init__( self,code=code,salome=1,parent=parent,multi=multi,langue=langue)
90 #--------------- specialisation EFICAS dans SALOME -------------------
92 self.salome = True #active les parties de code specifique dans Salome( pour le logiciel Eficas )
93 self.module = module #indique sous quel module dans l'arbre d'etude ajouter le JDC.
94 self.componentName = componentName
96 # donnee pour la creation de groupe de maille
97 self.mainShapeNames = {} #dictionnaire pour gerer les multiples fichiers possibles ouverts par
98 #eficas ( cle = identifiant du JDC ), une mainshape par fichier ouvert.
99 #dictionnaire des sous-geometrie de la geometrie principale ( cle = entry, valeur = name )
100 #----------------------------------------------------------------------
102 self.icolor = 0 # compteur pour memoriser la couleur courante
106 def closeEvent(self,event):
111 if hasattr(self,'readercata') :
118 # ___________________________ Methodes de l ex Pal __________________________________
120 #----------------------------------------------------------------
121 def getCORBAObjectInComponent( self, entry, composant ):
122 #----------------------------------------------------------------
124 mySO = self.editor.study.FindObjectID(entry)
126 object = mySO.GetObject()
128 myComponent = salome.lcc.FindOrLoadComponent("FactoryServer", composant)
129 SCom = self.editor.study.FindComponent( composant )
130 print myComponent , SCom
131 self.editor.builder.LoadWith( SCom , myComponent )
132 object = mySO.GetObject()
134 logger.debug("selectedEntry: An error occurs")
138 #----------------------------------------------
139 def giveMeshGroups( self,entry,label1,typeMesh):
140 #----------------------------------------------
145 monMaillage =self.getCORBAObjectInComponent(entry,"SMESH")
146 if monMaillage != None : # selection d'un groupe de SMESH
147 if monMaillage._narrow(SMESH.SMESH_Mesh):
148 mailSO = self.editor.study.FindObjectID(entry)
149 if mailSO == None : return names, msg
152 subIt = self.editor.study.NewChildIterator(mailSO)
154 subSO = subIt.Value()
157 if (subSO.GetName()[0:9]!=label1) : continue
158 subSSMeshit=self.editor.study.NewChildIterator(subSO)
159 while subSSMeshit.More():
160 subSSMeshSO = subSSMeshit.Value()
162 if subSSMeshSO.GetObject()._narrow(typeMesh):
163 names.append(subSSMeshSO.GetName())
165 msg=entry + self.tr(" n est pas un maillage")
167 logger.debug(' giveMeshGroups pb avec ( entry = %s ) ' %entry )
168 msg=' giveMeshGroup pb avec ( entry = %s ) '+ entry
171 #-------------------------------------
172 def isMeshGroup( self,entry):
173 #-------------------------------------
177 monObjet =self.getCORBAObjectInComponent(entry,"SMESH")
178 if monObjet != None : # selection d'un groupe de SMESH
179 if monObjet._narrow(SMESH.SMESH_GroupBase):
182 logger.debug(' isMeshGroup pb avec ( entry = %s ) ' %entry )
185 #-------------------------------------
186 def isShape( self,entry):
187 #-------------------------------------
191 monObjet =self.getCORBAObjectInComponent(entry,"GEOM")
192 if monObjet != None : # selection d'un objet GEOM
193 if monObjet._narrow(GEOM.GEOM_Object ):
196 logger.debug(' isShape pb avec ( entry = %s ) ' %entry )
199 #-----------------------------------------------------------------
200 def getMainShapeEntry(self,entry):
201 #-----------------------------------------------------------------
204 mainShapeEntry = entry.split(':')[:4]
205 if len(mainShapeEntry) == 4:
206 strMainShapeEntry = '%s:%s:%s:%s'%tuple(mainShapeEntry)
207 if self.isMainShape(strMainShapeEntry):
208 result = strMainShapeEntry
210 logger.debug( 'Erreur pour SalomeStudy.getMainShapeEntry( entry = %s ) ' %entry )
214 #-----------------------------------------------------------------
215 def isMainShape(self,entry):
216 #-----------------------------------------------------------------
219 monObjet =self.getCORBAObjectInComponent(entry,"GEOM")
221 shape = monObjet._narrow( GEOM.GEOM_Object )
222 if shape.IsMainShape():
225 logger.debug( 'Errreur pour SalomeStudy.isMainShape( entry = %s ) ' %entry )
230 #-----------------------------------------------------------------
231 def ChercheType( self, shape ):
232 #-----------------------------------------------------------------
233 tgeo = shape.GetShapeType()
234 geomEngine = salome.lcc.FindOrLoadComponent( "FactoryServer", "GEOM" )
235 #print dir(self.editor.study)
236 groupIMeasureOp = geomEngine.GetIMeasureOperations(self.editor.study._get_StudyId())
237 if tgeo != "COMPOUND" : return tgeo
239 strInfo = groupIMeasureOp.WhatIs( shape )
241 l = strInfo.split('\n')
244 nom, valeur = couple.split(':')
245 dictInfo[ nom.strip() ] = valeur.strip()
247 ordre = [ "COMPSOLID", "SOLID", "SHELL", "FACE", "WIRE", "EDGE", "VERTEX" ]
249 if dictInfo[ t ] != '0':
255 #-----------------------------------------------------------------
256 def selectShape( self, editor, entry, kwType = None ):
257 #-----------------------------------------------------------------
259 selection sous-geometrie dans Salome:
260 -test1) si c'est un element sous-geometrique .
261 -test2) si appartient a la geometrie principale.
263 name, msgError = '',''
264 mySO = self.editor.study.FindObjectID(entry)
266 return name, msgError
267 object = mySO.GetObject()
269 return name, msgError
272 shape = object._narrow( GEOM.GEOM_Object )
274 return name, msgError
276 tGeo=self.ChercheType(shape)
278 return name, msgError
279 #if kwType == "GROUP_NO" and str(tGeo) != "VERTEX":
280 # name,msgError = '',"la selection n est pas un Vertex"
281 # return name, msgError
282 if kwType == "GROUP_MA" and str(tGeo) == "VERTEX":
283 name, msgError = '', "la selection n est pas un groupe de maille"
284 return name, msgError
286 mainShapeEntry = self.getMainShapeEntry( entry )
287 if self.mainShapeNames.has_key( editor ):
288 #print "------------- self.mainShapeNames[editor]" , self.mainShapeNames[editor]
289 if self.mainShapeNames[editor] == mainShapeEntry:
292 msgError="Le groupe reference la geometrie " + mainShapeEntry + " et non " + self.mainShapeNames[editor]
294 self.mainShapeNames[editor] = mainShapeEntry
297 return name, msgError
300 #-----------------------------------------------------------------
301 def selectMeshGroup( self, editor, selectedEntry, kwType = None ):
302 #-----------------------------------------------------------------
304 selection groupe de maille dans Salome:
305 -test 1) si c'est un groupe de maille
306 -test 2) si le maillage fait reference a la geometrie principale
308 name, msgError = '',''
310 mySO=self.editor.study.FindObjectID(selectedEntry )
311 from salome.smesh.smeshstudytools import SMeshStudyTools
312 monSMeshStudyTools=SMeshStudyTools(self.editor)
313 meshSO = monSMeshStudyTools.getMeshFromGroup(mySO)
314 if meshSO == None : return name, msgError
316 # on verifie que l entree selectionnee a le bon type (NODE ou EDGE...)
318 groupObject = self.getCORBAObjectInComponent(selectedEntry,"SMESH")
320 logger.debug("selectedMeshEntry: An error occurs")
323 aGroup = groupObject._narrow( SMESH.SMESH_GroupBase )
324 if aGroup: tGroup = aGroup.GetType()
326 if kwType == "GROUP_NO" and tGroup != SMESH.NODE:
327 msgError = self.tr("GROUP_NO attend un groupe de noeud")
328 return name, msgError
329 elif kwType == "GROUP_MA" and tGroup == SMESH.NODE:
330 msgError = self.tr("GROUP_MA attend un point goupe de maille")
331 return name, msgError
333 # on cherche la shape associee
334 #PN PN mesh_Object est un SOject
335 meshObject = meshSO.GetObject()
336 mesh = meshObject._narrow( SMESH.SMESH_Mesh )
337 if mesh: #c'est bien un objet maillage
338 shape = mesh.GetShapeToMesh()
340 ior = salome.orb.object_to_string( shape )
342 sObject = self.editor.study.FindObjectIOR( ior )
343 mainShapeID = sObject.GetID()
347 return name, self.tr("Type d objet non permis")
349 # on cherche si la shape associee est la bonne
350 #print "------------- mainShapeID" , mainShapeID
351 if self.mainShapeNames.has_key( editor ):
352 #print "------------- self.mainShapeNames[editor]" , self.mainShapeNames[editor]
353 if self.mainShapeNames[editor] == mainShapeID:
356 msgError=self.tr("Le groupe reference la geometrie ") + mainShapeID + self.tr(" et non ") + self.mainShapeNames[editor]
358 self.mainShapeNames[editor] = mainShapeID
361 #print "------------------------------ name :", name
362 #print "------------------------------ name :", name
363 #print "------------------------------ name :", name
367 def displayMeshGroups(self, meshGroupName):
369 visualisation group de maille de nom meshGroupName dans salome
371 ok, msgError = False, ''
374 sg = salome.ImportComponentGUI('SMESH')
375 meshGroupEntries = []
377 selMeshGroupEntry = None
379 # liste des groupes de maille de nom meshGroupName
380 listSO = self.editor.study.FindObjectByName(meshGroupName, "SMESH")
382 #print "liste des groupes de maille de nom %s: "%(meshGroupName), listSO
385 return 0,self.tr('Plusieurs objets portent ce nom')
387 return 0,self.tr('Aucun objet ne porte ce nom')
389 groupEntry = SObjet.GetID()
390 myComponent = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
391 SCom = self.editor.study.FindComponent("SMESH")
392 myBuilder = self.editor.study.NewBuilder()
393 myBuilder.LoadWith( SCom , myComponent )
394 sg.CreateAndDisplayActor(groupEntry)
395 #color = COLORS[ self.icolor % LEN_COLORS ]
396 #self.icolor = self.icolor + 1
397 #sg.SetColor(groupEntry, color[0], color[1], color[2])
398 salome.sg.Display(groupEntry)
404 msgError = self.tr("Impossible d afficher ")+shapeName
408 # ___________________________ Methodes appelees par EFICAS __________________________________
409 #----------------------------------------------------------------
410 def selectGroupFromSalome( self, kwType = None, editor=None):
411 #----------------------------------------------------------------
413 Selection d'element(s) d'une geometrie ( sub-shape ) ou d'element(s) de maillage ( groupe de maille) partir de l'arbre salome
414 retourne ( la liste des noms des groupes, message d'erreur )
416 Note: Appele par EFICAS lorsqu'on clique sur le bouton ajouter la liste du panel GROUPMA
420 atLeastOneStudy = self.editor.study
421 if not atLeastOneStudy:
424 # recupere toutes les selections de l'utilsateur dans l'arbre Salome
425 entries = salome.sg.getAllSelected()
426 nbEntries = len( entries )
428 for entry in entries:
429 if self.isMeshGroup(entry): # selection d 'un sous maillage
430 name, msg = self.selectMeshGroup( editor, entry, kwType )
431 elif self.isShape(entry): # selection d'une sous-geometrie
432 name, msg = self.selectShape( editor, entry, kwType )
434 name, msg = None,self.tr("Selection SALOME non autorisee.")
439 logger.debug("selectGroupFromSalome: An error occurs")
440 #print "=================== selectGroupFromSalome ", names, msg
441 #print "=================== selectGroupFromSalome ", names, msg
442 #print "=================== selectGroupFromSalome ", names, msg
445 #----------------------------------------------------------------
446 def selectEntryFromSalome( self, kwType = None, editor=None):
447 #----------------------------------------------------------------
449 Selection d'element a partir de l'arbre salome
450 Ne verifie que l unicite de la selection
451 retourne ( la liste avec le nom du groupe, message d'erreur )
453 retourne une liste pour etre coherent avec selectGroupFromSalome
454 Note: Appele par EFICAS lorsqu'on clique sur le bouton ajouter la liste du panel SalomeEntry
458 atLeastOneStudy = self.editor.study
459 if not atLeastOneStudy:
461 entries = salome.sg.getAllSelected()
462 nbEntries = len( entries )
464 msg = self.tr(u"Veuillez selectionner une entree de l'arbre d'etude de Salome")
465 QMessageBox.information(self, self.tr(u"Selection depuis Salome"), msg)
468 msg = self.tr(u"Une seule entrée doit être sélectionnée dans l'arbre d'étude de Salome")
469 QMessageBox.information(self, self.tr(u"Sélection depuis Salome"),msg)
472 value = salome.sg.getSelected(0)
474 msg = self.tr(u"L'entrée de l'arbre d'étude de Salome a été sélectionnée")
477 QMessageBox.information(self, self.tr(u"Sélection depuis Salome"), unicode(e))
478 return [], unicode(e)
481 #---------------------------------------------
482 def addJdcInSalome( self, jdcPath ):
483 #---------------------------------------------
485 Ajoute le Jeu De Commande dans l'arbre d'etude Salome dans la rubrique EFICAS
488 msgError = "Erreur dans l'export du fichier de commande dans l'arbre d'etude Salome"
491 atLeastOneStudy = self.editor.study
492 if not atLeastOneStudy:
495 fileType = { 'ASTER' : "FICHIER_EFICAS_ASTER",
496 'SEP' : "FICHIER_EFICAS_SEP",
497 'MAP' : "FICHIER_EFICAS_MAP",
498 'OPENTURNS': "FICHIER_EFICAS_OPENTURNS",
499 'OPENTURNS_STUDY': "FICHIER_EFICAS_OPENTURNS_STUDY",
500 'OPENTURNS_WRAPPER': "FICHIER_EFICAS_OPENTURNS_WRAPPER",
501 'CARMEL3D': "FICHIER_EFICAS_CARMEL3D",
504 folderName = { 'ASTER' : 'AsterFiles',
506 'CARMEL3D' : 'CARMEL3DFiles' ,
508 'OPENTURNS_STUDY': 'OpenturnsFiles',
509 'OPENTURNS_WRAPPER': 'OpenturnsFiles'}
511 folderType = { 'ASTER': "ASTER_FILE_FOLDER",
512 'SEP': "SEP_FILE_FOLDER",
513 'MAP': "MAP_FILE_FOLDER",
514 'CARMEL3D': "CARMEL3D_FILE_FOLDER",
515 'OPENTURNS_STUDY':"OPENTURNS_FILE_FOLDER",
516 'OPENTURNS_WRAPPER': "OPENTURNS_FILE_FOLDER"}
519 moduleEntry = self.editor.findOrCreateComponent(self.module, self.componentName)
520 itemName = re.split("/",jdcPath)[-1]
522 if folderName.has_key(self.code) :
523 monFolderName=folderName[ self.code ]
525 monFolderName=str(self.code)+"Files"
527 if folderType.has_key(self.code) :
528 monFolderType=fileType[ self.code ]
530 monFolderType=str(self.code)+"_FILE_FOLDER"
532 if fileType.has_key(self.code) :
533 monFileType=fileType[ self.code ]
535 monFileType="FICHIER_EFICAS_"+str(self.code)
537 fatherEntry = self.editor.findOrCreateItem(
539 name = monFolderName,
540 #icon = "ICON_COMM_FOLDER",
541 fileType = monFolderType)
543 commEntry = self.editor.findOrCreateItem( fatherEntry ,
545 fileType = monFileType,
547 #icon = "ICON_COMM_FILE",
548 comment = str( jdcPath ))
550 salome.sg.updateObjBrowser(1)
552 #print 'addJdcInSalome commEntry->', commEntry
554 ok, msgError = True, ''
555 except Exception, exc:
556 msgError = "Can't add Eficas file to Salome study tree"
557 logger.debug(msgError, exc_info = True)
558 QMessageBox.warning(self, self.tr("Warning"),
559 self.tr("%s. Raison:\n%s\n\n Voir la log pour plus de détails " % (msgError, exc)))
563 #---------------------------------------
564 def displayShape( self, shapeName ):
565 #---------------------------------------
567 visualisation de nom shapeName dans salome
569 ok, msgError = False, ''
573 sgPyQt = SalomePyQt.SalomePyQt()
574 myActiveView=sgPyQt.getActiveView()
575 if myActiveView < 0 :
576 return ok, 'pas de vue courante'
578 currentViewType=sgPyQt.getViewType(myActiveView)
579 if str(currentViewType) != "OCCViewer" : # maillage
580 ok, msgError = self.displayMeshGroups(shapeName)
582 current_color = COLORS[ self.icolor % LEN_COLORS ]
583 from salome.geom.geomtools import GeomStudyTools
584 myGeomTools=GeomStudyTools(self.editor)
585 ok = myGeomTools.displayShapeByName( shapeName, current_color )
587 self.icolor = self.icolor + 1
589 msgError =self.tr("Impossible d afficher ")+shapeName
595 #---------------------------------------
596 def ChercheGrpMeshInSalome(self):
597 #---------------------------------------
598 #print "je passe par la"
602 entries = salome.sg.getAllSelected()
603 nbEntries = len( entries )
604 names, msg = None, self.tr("Selection SALOME non autorisee.")
606 for entry in entries:
607 names,msg=self.giveMeshGroups(entry,"SubMeshes",SMESH.SMESH_subMesh)
612 #---------------------------------------
613 def ChercheGrpMailleInSalome(self):
614 #---------------------------------------
619 entries = salome.sg.getAllSelected()
620 nbEntries = len( entries )
621 names, msg = None, self.tr("Selection SALOME non autorisee.")
623 for entry in entries:
625 names,msg=self.giveMeshGroups(entry,"Groups of",SMESH.SMESH_GroupBase)
636 #-------------------------------------------------------------------------------------------------------
637 # Pilotage de la Visu des elements de structures
641 def envoievisu(self,liste_commandes):
643 from salome.geom.structelem import StructuralElementManager, InvalidParameterError
645 QMessageBox.critical(self, self.tr("Error"),
646 self.tr("Impossible d'afficher les elements de structure: "
647 "module GEOM n est pas installe."))
650 atLeastOneStudy = self.editor.study
651 if not atLeastOneStudy:
653 logger.debug(10*'#'+":envoievisu: creating a StructuralElementManager instance")
654 structElemManager = StructuralElementManager()
655 elem = structElemManager.createElement(liste_commandes)
657 salome.sg.updateObjBrowser(True)
658 except InvalidParameterError, err:
659 trStr = self.tr("Invalid parameter for group %(group)s: %(expr)s must be "
660 "greater than %(minval)g (actual value is %(value)g)")
661 msg = str(trStr) % {"group": err.groupName, "expr": err.expression,
662 "minval": err.minValue, "value": err.value}
663 QMessageBox.warning(self, self.tr("Error"), msg)
665 traceback.print_exc()
666 logger.debug(10*'#'+":pb dans envoievisu")
669 #-------------------------------------------------------------------------------------------------------
670 # Point d'entree lancement EFICAS
672 def runEficas( code=None, fichier=None, module = "EFICAS", version=None, componentName = "Eficas",multi=False):
673 logger.debug(10*'#'+":runEficas: START")
675 logger.debug(10*'#'+":runEficas: code="+str(code))
676 logger.debug(10*'#'+":runEficas: fichier="+str(fichier))
677 logger.debug(10*'#'+":runEficas: module="+str(module))
678 logger.debug(10*'#'+":runEficas: version="+str(version))
680 #if not appli: #une seul instance possible!
681 appli = MyEficas( SalomePyQt.SalomePyQt().getDesktop(), code = code, fichier = fichier,
682 module = module, version = version, componentName = componentName,multi=multi )
683 #if not appli: #une seul instance possible!
684 # appli = MyEficas( SalomePyQt.SalomePyQt().getDesktop(), code = code, fichier = fichier,
685 # module = module, componentName = componentName, version=version )
686 logger.debug(10*'#'+":runEficas: END")