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
34 from salome.kernel.studyedit import getStudyEditor
37 # couleur pour visualisation des geometries
39 COLORS = colors.ListeColors
40 LEN_COLORS = len( COLORS )
42 from Extensions import localisation
43 localisation.localise(None,"en")
47 class MyEficas( qtEficas.Appli ):
49 Classe de lancement du logiciel EFICAS dans SALOME
50 Cette classe specialise le logiciel Eficas par l'ajout de:
51 a)la creation de groupes de mailles dans le composant SMESH de SALOME
52 b)la visualisation d'elements geometrique dans le coposant GEOM de SALOME par selection dans EFICAS
54 def __init__( self, parent, code = "ASTER", fichier = None, module = "EFICAS",
55 version = None, componentName = "Eficas",multi=False):
59 @param parent: widget Qt parent
61 @param code: catalogue a lancer ( ASTER, HOMARD OPENTURNS ). optionnel ( defaut = ASTER ).
63 @param fichier: chemin absolu du fichier eficas a ouvrir a das le lancement. optionnel
66 dictPathCode={'ASTER':'Aster','OPENTURNS_STUDY':'Openturns_Study','CARMEL3D':'Carmel3D',
67 'OPENTURNS_WRAPPER':'Openturns_Wrapper','MAP':'MAP','SEP':'Sep'}
68 if code in dictPathCode.keys():
69 pathCode=dictPathCode[code]
70 sys.path[:0]=[os.path.join(eficasConfig.eficasPath,pathCode)]
72 if Editeur.__dict__.has_key( 'session' ):
73 from Editeur import session
77 eficasArg += [ fichier ]
79 eficasArg += [ "-c", version ]
82 session.parse( eficasArg )
84 self.editor = getStudyEditor() # Editeur de l'arbre d'etude
86 qtEficas.Appli.__init__( self,code=code,salome=1,parent=parent,multi=multi)
88 #--------------- specialisation EFICAS dans SALOME -------------------
90 self.salome = True #active les parties de code specifique dans Salome( pour le logiciel Eficas )
91 self.module = module #indique sous quel module dans l'arbre d'etude ajouter le JDC.
92 self.componentName = componentName
94 # donnee pour la creation de groupe de maille
95 self.mainShapeNames = {} #dictionnaire pour gerer les multiples fichiers possibles ouverts par
96 #eficas ( cle = identifiant du JDC ), une mainshape par fichier ouvert.
97 #dictionnaire des sous-geometrie de la geometrie principale ( cle = entry, valeur = name )
98 #----------------------------------------------------------------------
100 self.icolor = 0 # compteur pour memoriser la couleur courante
104 def closeEvent(self,event):
109 if hasattr(self,'readercata') :
116 # ___________________________ Methodes de l ex Pal __________________________________
118 #----------------------------------------------------------------
119 def getCORBAObjectInComponent( self, entry, composant ):
120 #----------------------------------------------------------------
122 mySO = self.editor.study.FindObjectID(entry)
124 object = mySO.GetObject()
126 myComponent = salome.lcc.FindOrLoadComponent("FactoryServer", composant)
127 SCom = self.editor.study.FindComponent( composant )
128 print myComponent , SCom
129 self.editor.builder.LoadWith( SCom , myComponent )
130 object = mySO.GetObject()
132 logger.debug("selectedEntry: An error occurs")
136 #----------------------------------------------
137 def giveMeshGroups( self,entry,label1,typeMesh):
138 #----------------------------------------------
143 monMaillage =self.getCORBAObjectInComponent(entry,"SMESH")
144 if monMaillage != None : # selection d'un groupe de SMESH
145 if monMaillage._narrow(SMESH.SMESH_Mesh):
146 mailSO = self.editor.study.FindObjectID(entry)
147 if mailSO == None : return names, msg
150 subIt = self.editor.study.NewChildIterator(mailSO)
152 subSO = subIt.Value()
155 if (subSO.GetName()[0:9]!=label1) : continue
156 subSSMeshit=self.editor.study.NewChildIterator(subSO)
157 while subSSMeshit.More():
158 subSSMeshSO = subSSMeshit.Value()
160 if subSSMeshSO.GetObject()._narrow(typeMesh):
161 names.append(subSSMeshSO.GetName())
163 msg=entry + " n est pas un maillage"
165 logger.debug(' giveMeshGroups pb avec ( entry = %s ) ' %entry )
166 msg=' giveMeshGroup pb avec ( entry = %s ) '+ entry
169 #-------------------------------------
170 def isMeshGroup( self,entry):
171 #-------------------------------------
175 monObjet =self.getCORBAObjectInComponent(entry,"SMESH")
176 if monObjet != None : # selection d'un groupe de SMESH
177 if monObjet._narrow(SMESH.SMESH_GroupBase):
180 logger.debug(' isMeshGroup pb avec ( entry = %s ) ' %entry )
183 #-------------------------------------
184 def isShape( self,entry):
185 #-------------------------------------
189 monObjet =self.getCORBAObjectInComponent(entry,"GEOM")
190 if monObjet != None : # selection d'un objet GEOM
191 if monObjet._narrow(GEOM.GEOM_Object ):
194 logger.debug(' isShape pb avec ( entry = %s ) ' %entry )
197 #-----------------------------------------------------------------
198 def getMainShapeEntry(self,entry):
199 #-----------------------------------------------------------------
202 mainShapeEntry = entry.split(':')[:4]
203 if len(mainShapeEntry) == 4:
204 strMainShapeEntry = '%s:%s:%s:%s'%tuple(mainShapeEntry)
205 if self.isMainShape(strMainShapeEntry):
206 result = strMainShapeEntry
208 logger.debug( 'Erreur pour SalomeStudy.getMainShapeEntry( entry = %s ) ' %entry )
212 #-----------------------------------------------------------------
213 def isMainShape(self,entry):
214 #-----------------------------------------------------------------
217 monObjet =self.getCORBAObjectInComponent(entry,"GEOM")
219 shape = monObjet._narrow( GEOM.GEOM_Object )
220 if shape.IsMainShape():
223 logger.debug( 'Errreur pour SalomeStudy.isMainShape( entry = %s ) ' %entry )
228 #-----------------------------------------------------------------
229 def ChercheType( self, shape ):
230 #-----------------------------------------------------------------
231 tgeo = shape.GetShapeType()
232 geomEngine = salome.lcc.FindOrLoadComponent( "FactoryServer", "GEOM" )
233 #print dir(self.editor.study)
234 groupIMeasureOp = geomEngine.GetIMeasureOperations(self.editor.study._get_StudyId())
235 if tgeo != "COMPOUND" : return tgeo
237 strInfo = groupIMeasureOp.WhatIs( shape )
239 l = strInfo.split('\n')
242 nom, valeur = couple.split(':')
243 dictInfo[ nom.strip() ] = valeur.strip()
245 ordre = [ "COMPSOLID", "SOLID", "SHELL", "FACE", "WIRE", "EDGE", "VERTEX" ]
247 if dictInfo[ t ] != '0':
253 #-----------------------------------------------------------------
254 def selectShape( self, editor, entry, kwType = None ):
255 #-----------------------------------------------------------------
257 selection sous-geometrie dans Salome:
258 -test1) si c'est un element sous-geometrique .
259 -test2) si appartient a la geometrie principale.
261 name, msgError = '',''
262 mySO = self.editor.study.FindObjectID(entry)
264 return name, msgError
265 object = mySO.GetObject()
267 return name, msgError
270 shape = object._narrow( GEOM.GEOM_Object )
272 return name, msgError
274 tGeo=self.ChercheType(shape)
276 return name, msgError
277 #if kwType == "GROUP_NO" and str(tGeo) != "VERTEX":
278 # name,msgError = '',"la selection n est pas un Vertex"
279 # return name, msgError
280 if kwType == "GROUP_MA" and str(tGeo) == "VERTEX":
281 name, msgError = '', "la selection n est pas un groupe de maille"
282 return name, msgError
284 mainShapeEntry = self.getMainShapeEntry( entry )
285 if self.mainShapeNames.has_key( editor ):
286 #print "------------- self.mainShapeNames[editor]" , self.mainShapeNames[editor]
287 if self.mainShapeNames[editor] == mainShapeEntry:
290 msgError="Le groupe reference la geometrie " + mainShapeEntry + " et non " + self.mainShapeNames[editor]
292 self.mainShapeNames[editor] = mainShapeEntry
295 return name, msgError
298 #-----------------------------------------------------------------
299 def selectMeshGroup( self, editor, selectedEntry, kwType = None ):
300 #-----------------------------------------------------------------
302 selection groupe de maille dans Salome:
303 -test 1) si c'est un groupe de maille
304 -test 2) si le maillage fait reference a la geometrie principale
306 name, msgError = '',''
308 mySO=self.editor.study.FindObjectID(selectedEntry )
309 from salome.smesh.smeshstudytools import SMeshStudyTools
310 monSMeshStudyTools=SMeshStudyTools(self.editor)
311 meshSO = monSMeshStudyTools.getMeshFromGroup(mySO)
312 if meshSO == None : return name, msgError
314 # on verifie que l entree selectionnee a le bon type (NODE ou EDGE...)
316 groupObject = self.getCORBAObjectInComponent(selectedEntry,"SMESH")
318 logger.debug("selectedMeshEntry: An error occurs")
321 aGroup = groupObject._narrow( SMESH.SMESH_GroupBase )
322 if aGroup: tGroup = aGroup.GetType()
324 if kwType == "GROUP_NO" and tGroup != SMESH.NODE:
325 msgError = "GROUP_NO attend un groupe de noeud"
326 return name, msgError
327 elif kwType == "GROUP_MA" and tGroup == SMESH.NODE:
328 msgError = "GROUP_MA attend un point goupe de maille"
329 return name, msgError
331 # on cherche la shape associee
332 #PN PN mesh_Object est un SOject
333 meshObject = meshSO.GetObject()
334 mesh = meshObject._narrow( SMESH.SMESH_Mesh )
335 if mesh: #c'est bien un objet maillage
336 shape = mesh.GetShapeToMesh()
338 ior = salome.orb.object_to_string( shape )
340 sObject = self.editor.study.FindObjectIOR( ior )
341 mainShapeID = sObject.GetID()
345 return name, "Type d objet non permis"
347 # on cherche si la shape associee est la bonne
348 #print "------------- mainShapeID" , mainShapeID
349 if self.mainShapeNames.has_key( editor ):
350 #print "------------- self.mainShapeNames[editor]" , self.mainShapeNames[editor]
351 if self.mainShapeNames[editor] == mainShapeID:
354 msgError="Le groupe reference la geometrie " + mainShapeID + " et non " + self.mainShapeNames[editor]
356 self.mainShapeNames[editor] = mainShapeID
359 #print "------------------------------ name :", name
360 #print "------------------------------ name :", name
361 #print "------------------------------ name :", name
365 def displayMeshGroups(self, meshGroupName):
367 visualisation group de maille de nom meshGroupName dans salome
369 ok, msgError = False, ''
372 sg = salome.ImportComponentGUI('SMESH')
373 meshGroupEntries = []
375 selMeshGroupEntry = None
377 # liste des groupes de maille de nom meshGroupName
378 listSO = self.editor.study.FindObjectByName(meshGroupName, "SMESH")
380 #print "liste des groupes de maille de nom %s: "%(meshGroupName), listSO
383 return 0,'Plusieurs objets portent ce nom'
385 return 0,'Aucun objet ne porte ce nom'
387 groupEntry = SObjet.GetID()
388 myComponent = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
389 SCom = self.editor.study.FindComponent("SMESH")
390 myBuilder = self.editor.study.NewBuilder()
391 myBuilder.LoadWith( SCom , myComponent )
392 sg.CreateAndDisplayActor(groupEntry)
393 #color = COLORS[ self.icolor % LEN_COLORS ]
394 #self.icolor = self.icolor + 1
395 #sg.SetColor(groupEntry, color[0], color[1], color[2])
396 salome.sg.Display(groupEntry)
402 msgError = "Impossible d afficher "+shapeName
406 # ___________________________ Methodes appelees par EFICAS __________________________________
407 #----------------------------------------------------------------
408 def selectGroupFromSalome( self, kwType = None, editor=None):
409 #----------------------------------------------------------------
411 Selection d'element(s) d'une geometrie ( sub-shape ) ou d'element(s) de maillage ( groupe de maille) partir de l'arbre salome
412 retourne ( la liste des noms des groupes, message d'erreur )
414 Note: Appele par EFICAS lorsqu'on clique sur le bouton ajouter la liste du panel GROUPMA
418 atLeastOneStudy = self.editor.study
419 if not atLeastOneStudy:
422 # recupere toutes les selections de l'utilsateur dans l'arbre Salome
423 entries = salome.sg.getAllSelected()
424 nbEntries = len( entries )
426 for entry in entries:
427 if self.isMeshGroup(entry): # selection d 'un sous maillage
428 name, msg = self.selectMeshGroup( editor, entry, kwType )
429 elif self.isShape(entry): # selection d'une sous-geometrie
430 name, msg = self.selectShape( editor, entry, kwType )
432 name, msg = None, "Selection SALOME non autorisee."
437 logger.debug("selectGroupFromSalome: An error occurs")
438 #print "=================== selectGroupFromSalome ", names, msg
439 #print "=================== selectGroupFromSalome ", names, msg
440 #print "=================== selectGroupFromSalome ", names, msg
443 #---------------------------------------------
444 def addJdcInSalome( self, jdcPath ):
445 #---------------------------------------------
447 Ajoute le Jeu De Commande dans l'arbre d'etude Salome dans la rubrique EFICAS
450 msgError = "Erreur dans l'export du fichier de commande dans l'arbre d'etude Salome"
453 atLeastOneStudy = self.editor.study
454 if not atLeastOneStudy:
457 fileType = { 'ASTER' : "FICHIER_EFICAS_ASTER",
458 'SEP' : "FICHIER_EFICAS_SEP",
459 'MAP' : "FICHIER_EFICAS_MAP",
460 'OPENTURNS': "FICHIER_EFICAS_OPENTURNS",
461 'OPENTURNS_STUDY': "FICHIER_EFICAS_OPENTURNS_STUDY",
462 'OPENTURNS_WRAPPER': "FICHIER_EFICAS_OPENTURNS_WRAPPER",
463 'CARMEL3D': "FICHIER_EFICAS_CARMEL3D",
466 folderName = { 'ASTER' : 'AsterFiles',
468 'CARMEL3D' : 'CARMEL3DFiles' ,
470 'OPENTURNS_STUDY': 'OpenturnsFiles',
471 'OPENTURNS_WRAPPER': 'OpenturnsFiles'}
473 folderType = { 'ASTER': "ASTER_FILE_FOLDER",
474 'SEP': "SEP_FILE_FOLDER",
475 'MAP': "MAP_FILE_FOLDER",
476 'CARMEL3D': "CARMEL3D_FILE_FOLDER",
477 'OPENTURNS_STUDY':"OPENTURNS_FILE_FOLDER",
478 'OPENTURNS_WRAPPER': "OPENTURNS_FILE_FOLDER"}
481 moduleEntry = self.editor.findOrCreateComponent(self.module, self.componentName)
482 itemName = re.split("/",jdcPath)[-1]
484 if folderName.has_key(self.code) :
485 monFolderName=folderName[ self.code ]
487 monFolderName=str(self.code)+"Files"
489 if folderType.has_key(self.code) :
490 monFolderType=fileType[ self.code ]
492 monFolderType=str(self.code)+"_FILE_FOLDER"
494 if fileType.has_key(self.code) :
495 monFileType=fileType[ self.code ]
497 monFileType="FICHIER_EFICAS_"+str(self.code)
499 fatherEntry = self.editor.findOrCreateItem(
501 name = monFolderName,
502 #icon = "ICON_COMM_FOLDER",
503 fileType = monFolderType)
505 commEntry = self.editor.findOrCreateItem( fatherEntry ,
507 fileType = monFileType,
509 #icon = "ICON_COMM_FILE",
510 comment = str( jdcPath ))
512 salome.sg.updateObjBrowser(1)
514 #print 'addJdcInSalome commEntry->', commEntry
516 ok, msgError = True, ''
517 except Exception, exc:
518 msgError = "Can't add Eficas file to Salome study tree"
519 logger.debug(msgError, exc_info = True)
520 QMessageBox.warning(self, self.tr("Warning"),
521 self.tr("%s. Reason:\n%s\n\nSee logs for "
522 "more details." % (msgError, exc)))
526 #---------------------------------------
527 def displayShape( self, shapeName ):
528 #---------------------------------------
530 visualisation de nom shapeName dans salome
532 ok, msgError = False, ''
536 sgPyQt = SalomePyQt.SalomePyQt()
537 myActiveView=sgPyQt.getActiveView()
538 if myActiveView < 0 :
539 return ok, 'pas de vue courante'
541 currentViewType=sgPyQt.getViewType(myActiveView)
542 if str(currentViewType) != "OCCViewer" : # maillage
543 ok, msgError = self.displayMeshGroups(shapeName)
545 current_color = COLORS[ self.icolor % LEN_COLORS ]
546 from salome.geom.geomtools import GeomStudyTools
547 myGeomTools=GeomStudyTools(self.editor)
548 ok = myGeomTools.displayShapeByName( shapeName, current_color )
550 self.icolor = self.icolor + 1
552 msgError = "Impossible d afficher "+shapeName
558 #---------------------------------------
559 def ChercheGrpMeshInSalome(self):
560 print "je passe par la"
564 entries = salome.sg.getAllSelected()
565 nbEntries = len( entries )
566 names, msg = None, "Selection SALOME non autorisee."
568 for entry in entries:
570 names,msg=self.giveMeshGroups(entry,"SubMeshes",SMESH.SMESH_subMesh)
576 #---------------------------------------
577 def ChercheGrpMailleInSalome(self):
582 entries = salome.sg.getAllSelected()
583 nbEntries = len( entries )
584 names, msg = None, "Selection SALOME non autorisee."
586 for entry in entries:
588 names,msg=self.giveMeshGroups(entry,"Groups of",SMESH.SMESH_GroupBase)
599 #-------------------------------------------------------------------------------------------------------
600 # Pilotage de la Visu des elements de structures
604 def envoievisu(self,liste_commandes):
606 from salome.geom.structelem import StructuralElementManager, InvalidParameterError
608 QMessageBox.critical(self, self.tr("Error"),
609 self.tr("Cannot display structural elements: "
610 "module GEOM is not installed."))
613 atLeastOneStudy = self.editor.study
614 if not atLeastOneStudy:
616 logger.debug(10*'#'+":envoievisu: creating a StructuralElementManager instance")
617 structElemManager = StructuralElementManager()
618 elem = structElemManager.createElement(liste_commandes)
620 salome.sg.updateObjBrowser(True)
621 except InvalidParameterError, err:
622 trStr = self.tr("Invalid parameter for group %(group)s: %(expr)s must be "
623 "greater than %(minval)g (actual value is %(value)g)")
624 msg = str(trStr) % {"group": err.groupName, "expr": err.expression,
625 "minval": err.minValue, "value": err.value}
626 QMessageBox.warning(self, self.tr("Error"), msg)
628 traceback.print_exc()
629 logger.debug(10*'#'+":pb dans envoievisu")
632 #-------------------------------------------------------------------------------------------------------
633 # Point d'entree lancement EFICAS
635 def runEficas( code=None, fichier=None, module = "EFICAS", version=None, componentName = "Eficas",multi=False):
636 logger.debug(10*'#'+":runEficas: START")
638 logger.debug(10*'#'+":runEficas: code="+str(code))
639 logger.debug(10*'#'+":runEficas: fichier="+str(fichier))
640 logger.debug(10*'#'+":runEficas: module="+str(module))
641 logger.debug(10*'#'+":runEficas: version="+str(version))
643 #if not appli: #une seul instance possible!
644 appli = MyEficas( SalomePyQt.SalomePyQt().getDesktop(), code = code, fichier = fichier,
645 module = module, version = version, componentName = componentName,multi=multi )
646 #if not appli: #une seul instance possible!
647 # appli = MyEficas( SalomePyQt.SalomePyQt().getDesktop(), code = code, fichier = fichier,
648 # module = module, componentName = componentName, version=version )
649 logger.debug(10*'#'+":runEficas: END")