X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FTools%2FMGCleanerPlug%2FMGCleanerMonPlugDialog.py;h=ec87a6f82a00921f1ca228721a0f6f58f90f0bf5;hp=05d2fd260b78c8bb561ab2de0ca1e663187f0267;hb=ab46000ce37681e966a28f5e9276420d01df78bd;hpb=02df1b69aa4a8f3bb6b4784cdcf40596dd5cd171 diff --git a/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py b/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py index 05d2fd260..ec87a6f82 100644 --- a/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py +++ b/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -# Copyright (C) 2007-2013 EDF R&D +# Copyright (C) 2013-2020 EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either -# version 2.1 of the License. +# version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -22,11 +22,12 @@ # Modules Eficas import os, subprocess -from MGCleanerPlugDialog import Ui_MGCleanerPlugDialog +import tempfile +from MGCleanerPlugDialog_ui import Ui_MGCleanerPlugDialog from MGCleanerMonViewText import MGCleanerMonViewText -from PyQt4.QtGui import * -from PyQt4.QtCore import * +from qtsalome import * +verbose = True class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): """ @@ -41,8 +42,8 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): self.commande="" self.num=1 self.__selectedMesh=None - - # complex whith QResources: not used + + # complex with QResources: not used # The icon are supposed to be located in the $SMESH_ROOT_DIR/share/salome/resources/smesh folder, # other solution could be in the same folder than this python module file: # iconfolder=os.path.dirname(os.path.abspath(__file__)) @@ -66,9 +67,9 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): self.PB_Save.setToolTip("hypothesis to file") self.PB_MeshFile.setIcon(icon) self.PB_MeshFile.setToolTip("source mesh from a file in disk") - - #Ces parametres ne sont pas remis à rien par le clean - self.paramsFile= os.path.abspath(os.path.join(os.environ["HOME"],".MGCleaner.dat")) + + #Ces parametres ne sont pas remis a rien par le clean + self.paramsFile= os.path.abspath(os.path.join(os.path.expanduser("~"),".MGCleaner.dat")) self.LE_ParamsFile.setText(self.paramsFile) self.LE_MeshFile.setText("") self.LE_MeshSmesh.setText("") @@ -78,61 +79,71 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): #v1.setTop(10000.) v1.setDecimals(4) self.SP_MinHoleSize.setValidator(v1) + self.SP_MinHoleSize.titleForWarning="MinHoleSize" v2=QDoubleValidator(self) v2.setBottom(0.) #v2.setTop(10000.) v2.setDecimals(4) self.SP_ToleranceDisplacement.setValidator(v2) + self.SP_ToleranceDisplacement.titleForWarning="ToleranceDisplacement" v3=QDoubleValidator(self) v3.setBottom(0.) #v3.setTop(10000.) v3.setDecimals(4) self.SP_ResolutionLength.setValidator(v3) + self.SP_ResolutionLength.titleForWarning="ResolutionLength" v4=QDoubleValidator(self) v4.setBottom(0.) #v4.setTop(10000.) v4.setDecimals(4) self.SP_OverlapDistance.setValidator(v4) + self.SP_OverlapDistance.titleForWarning="OverlapDistance" self.resize(800, 500) self.clean() def connecterSignaux(self) : - self.connect(self.PB_Cancel,SIGNAL("clicked()"),self.PBCancelPressed) - self.connect(self.PB_Default,SIGNAL("clicked()"),self.clean) - self.connect(self.PB_Help,SIGNAL("clicked()"),self.PBHelpPressed) - self.connect(self.PB_OK,SIGNAL("clicked()"),self.PBOKPressed) + self.PB_Cancel.clicked.connect(self.PBCancelPressed) + self.PB_Default.clicked.connect(self.clean) + self.PB_Help.clicked.connect(self.PBHelpPressed) + self.PB_OK.clicked.connect(self.PBOKPressed) - self.connect(self.PB_Load,SIGNAL("clicked()"),self.PBLoadPressed) - self.connect(self.PB_Save,SIGNAL("clicked()"),self.PBSavePressed) - self.connect(self.PB_LoadHyp,SIGNAL("clicked()"),self.PBLoadHypPressed) - self.connect(self.PB_SaveHyp,SIGNAL("clicked()"),self.PBSaveHypPressed) + self.PB_Load.clicked.connect(self.PBLoadPressed) + self.PB_Save.clicked.connect(self.PBSavePressed) + self.PB_LoadHyp.clicked.connect(self.PBLoadHypPressed) + self.PB_SaveHyp.clicked.connect(self.PBSaveHypPressed) - self.connect(self.PB_MeshFile,SIGNAL("clicked()"),self.PBMeshFilePressed) - self.connect(self.PB_MeshSmesh,SIGNAL("clicked()"),self.PBMeshSmeshPressed) - self.connect(self.LE_MeshSmesh,SIGNAL("returnPressed()"),self.meshSmeshNameChanged) - self.connect(self.PB_ParamsFileExplorer,SIGNAL("clicked()"),self.setParamsFileName) - self.connect(self.LE_MeshFile,SIGNAL("returnPressed()"),self.meshFileNameChanged) - self.connect(self.LE_ParamsFile,SIGNAL("returnPressed()"),self.paramsFileNameChanged) + self.PB_MeshFile.clicked.connect(self.PBMeshFilePressed) + self.PB_MeshSmesh.clicked.connect(self.PBMeshSmeshPressed) + self.LE_MeshSmesh.returnPressed.connect(self.meshSmeshNameChanged) + self.PB_ParamsFileExplorer.clicked.connect(self.setParamsFileName) + self.LE_MeshFile.returnPressed.connect(self.meshFileNameChanged) + self.LE_ParamsFile.returnPressed.connect(self.paramsFileNameChanged) #QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL("stateChanged(int)"), self.change) - self.connect(self.CB_FillHoles,SIGNAL("stateChanged(int)"),self.SP_MinHoleSize.setEnabled) - self.connect(self.CB_ComputedToleranceDisplacement,SIGNAL("stateChanged(int)"),self.SP_ToleranceDisplacement.setDisabled) - self.connect(self.CB_ComputedResolutionLength,SIGNAL("stateChanged(int)"),self.SP_ResolutionLength.setDisabled) - self.connect(self.CB_ComputedOverlapDistance,SIGNAL("stateChanged(int)"),self.SP_OverlapDistance.setDisabled) + self.CB_FillHoles.stateChanged[int].connect(self.SP_MinHoleSize.setEnabled) + self.CB_ComputedToleranceDisplacement.stateChanged[int].connect(self.SP_ToleranceDisplacement.setDisabled) + self.CB_ComputedResolutionLength.stateChanged[int].connect(self.SP_ResolutionLength.setDisabled) + self.CB_ComputedOverlapDistance.stateChanged[int].connect(self.SP_OverlapDistance.setDisabled) def PBHelpPressed(self): + import SalomePyQt + sgPyQt = SalomePyQt.SalomePyQt() try: mydir=os.environ["SMESH_ROOT_DIR"] except Exception: - QMessageBox.warning( self, "Help", "Help unavailable $SMESH_ROOT_DIR not found") + QMessageBox.warning(self, "Help", "Help unavailable $SMESH_ROOT_DIR not found") return - maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf" - command="xdg-open "+maDoc+";" - subprocess.call(command, shell=True) + + maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/index.html" + sgPyQt.helpContext(maDoc,"") + + #maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf" + #command="xdg-open "+maDoc+";" + #subprocess.call(command, shell=True) def PBOKPressed(self): if not(self.PrepareLigneCommande()): @@ -142,16 +153,16 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): maFenetre=MGCleanerMonViewText(self, self.commande) def enregistreResultat(self): - import smesh - import SMESH import salome + import SMESH from salome.kernel import studyedit - + from salome.smesh import smeshBuilder + smesh = smeshBuilder.New() + if not os.path.isfile(self.fichierOut): QMessageBox.warning(self, "Compute", "Result file "+self.fichierOut+" not found") - maStudy=studyedit.getActiveStudy() - smesh.SetCurrentStudy(maStudy) + maStudy=salome.myStudy (outputMesh, status) = smesh.CreateMeshesFromGMF(self.fichierOut) name=str(self.LE_MeshSmesh.text()) initialMeshFile=None @@ -193,7 +204,7 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): newLink=monStudyBuilder.NewObject(SOMesh) monStudyBuilder.Addreference(newLink, newStudyIter) - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser() self.num+=1 return True @@ -219,56 +230,118 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): return f.close() - def PBSaveHypPressed(self): - """save hypothesis in Object Browser""" - #QMessageBox.warning(self, "save Object Browser MGCleaner Hypothesis", "TODO") + def PBSaveHypPressed_risky(self): + """ + save hypothesis in Object Browser outside GEOM ou MESH + WARNING: at root of Object Browser is not politically correct + """ + import salome - import smesh - import SMESH + if verbose: print("save hypothesis in Object Browser") + + name = "MGCleaner" + #how ??? icon = "mesh_tree_hypo.png" + namei = "MGCleaner Parameters_%i" % self.num + datai = self.getResumeData(separator=" ; ") + + myStudy = salome.myStudy + myBuilder = myStudy.NewBuilder() + #myStudy.IsStudyLocked() + myComponent = myStudy.FindComponent(name) + if myComponent == None: + print("myComponent not found, create") + myComponent = myBuilder.NewComponent(name) + AName = myBuilder.FindOrCreateAttribute(myComponent, "AttributeName") + AName.SetValue(name) + ACmt = myBuilder.FindOrCreateAttribute(myComponent, "AttributeComment") + ACmt.SetValue(name) + + myObject = myBuilder.NewObject(myComponent) + AName = myBuilder.FindOrCreateAttribute(myObject, "AttributeName") + AName.SetValue(namei) + ACmt = myBuilder.FindOrCreateAttribute(myObject, "AttributeComment") + ACmt.SetValue(datai) + + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser() + self.num += 1 + if verbose: print(("save %s in Object Browser done: %s\n%s" % (name, myObject.GetID(), datai))) + return True + + def PBSaveHypPressed(self): + """ + save hypothesis in Object Browser + bug: affichage ne marche pas si inclusion dans dans GEOM ou MESH depuis salome 730 + """ import salome + import SMESH from salome.kernel import studyedit - - maStudy=studyedit.getActiveStudy() - smesh.SetCurrentStudy(maStudy) + from salome.smesh import smeshBuilder + #[PAL issue tracker:issue1871] Les nouveaux objets ne s'affichent pas dans SMESH + QMessageBox.warning(self, "Save", "waiting for fix: Object Browser will not display hypothesis") + if verbose: print("save hypothesis in Object Browser") + smesh = smeshBuilder.New() + + maStudy=salome.myStudy + self.editor = studyedit.getStudyEditor() moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH") HypReMeshEntry = self.editor.findOrCreateItem( - moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" ) - + moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") + #, comment = "HypothesisForRemeshing" ) + monStudyBuilder=maStudy.NewBuilder() monStudyBuilder.NewCommand() newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry) - self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num)) - self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; ")) - - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) - self.num+=1 + name = "MGCleaner Parameters_%i" % self.num + self.editor.setAttributeValue(newStudyIter, "AttributeName", name) + data = self.getResumeData(separator=" ; ") + self.editor.setAttributeValue(newStudyIter, "AttributeComment", data) + + """ + # example storing in notebook + import salome_notebook + notebook = salome_notebook.notebook + notebook.set("MGCleaner_%i" % self.num, data) + """ + + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser() + self.num += 1 + if verbose: print(("save %s in Object Browser done:\n%s" % (name, data))) return True - """ - import salome_pluginsmanager - print "salome_pluginsmanager.plugins",salome_pluginsmanager.plugins - print "salome_pluginsmanager.current_plugins_manager",salome_pluginsmanager.current_plugins_manager - """ - def SP_toStr(self, widget): + """only for a QLineEdit widget""" #cr, pos=widget.validator().validate(res, 0) #n.b. "1,3" is acceptable !locale! try: - return str(float(widget.text())) + val=float(widget.text()) except: - widget.setProperty("text", "0.0") - return "0.0" + QMessageBox.warning(self, widget.titleForWarning, "float value is incorrect: '"+widget.text()+"'") + res=str(widget.validator().bottom()) + widget.setProperty("text", res) + return res + valtest=widget.validator().bottom() + if valtest!=None: + if valvaltest: + QMessageBox.warning(self, widget.titleForWarning, "float value is over maximum: "+str(val)+" > "+str(valtest)) + res=str(valtest) + widget.setProperty("text", res) + return res + return str(val) def getResumeData(self, separator="\n"): text="" if self.RB_Fix1.isChecked(): - CheckOrFix="fix1pass" + CheckOrFix="mode_fix" else: - if self.RB_Fix2.isChecked(): - CheckOrFix="fix2pass" - else: - CheckOrFix="check" + CheckOrFix="mode_check" text+="CheckOrFix="+CheckOrFix+separator text+="PreserveTopology="+str(self.CB_PreserveTopology.isChecked())+separator text+="FillHoles="+str(self.CB_FillHoles.isChecked())+separator @@ -301,11 +374,9 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): tit,value=lig.split("=") if tit=="CheckOrFix": self.RB_Fix1.setChecked(False) - self.RB_Fix2.setChecked(False) self.RB_Check.setChecked(False) - if value=="fix1pass": self.RB_Fix1.setChecked(True) - if value=="fix2pass": self.RB_Fix2.setChecked(True) - if value=="check": self.RB_Check.setChecked(True) + if value=="mode_fix": self.RB_Fix1.setChecked(True) + if value=="mode_check": self.RB_Check.setChecked(True) if tit=="PreserveTopology": self.CB_PreserveTopology.setChecked(value=="True") if tit=="FillHoles": self.CB_FillHoles.setChecked(value=="True") if tit=="MinHoleSize": self.SP_MinHoleSize.setProperty("text", value) @@ -325,15 +396,15 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): def PBLoadPressed(self): """load last hypothesis saved in tail of file""" try: - f=open(self.paramsFile,"r") - except : - QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile) - return + f=open(self.paramsFile,"r") + except: + QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile) + return try: - text=f.read() - except : - QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile) - return + text=f.read() + except: + QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile) + return f.close() self.loadResumeData(text, separator="\n") @@ -378,16 +449,17 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): if fd.exec_(): infile = fd.selectedFiles()[0] self.LE_MeshFile.setText(infile) - self.fichierIn=infile.toLatin1() + self.fichierIn=str(infile) self.MeshIn="" self.LE_MeshSmesh.setText("") + self.__selectedMesh=None def setParamsFileName(self): fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)") if fd.exec_(): infile = fd.selectedFiles()[0] self.LE_ParamsFile.setText(infile) - self.paramsFile=infile.toLatin1() + self.paramsFile=str(infile) def meshFileNameChanged(self): self.fichierIn=str(self.LE_MeshFile.text()) @@ -413,16 +485,21 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): self.paramsFile=self.LE_ParamsFile.text() def PBMeshSmeshPressed(self): + from omniORB import CORBA import salome - import smesh from salome.kernel import studyedit from salome.smesh.smeshstudytools import SMeshStudyTools from salome.gui import helper as guihelper - from omniORB import CORBA + from salome.smesh import smeshBuilder + smesh = smeshBuilder.New() mySObject, myEntry = guihelper.getSObjectSelected() if CORBA.is_nil(mySObject) or mySObject==None: QMessageBox.critical(self, "Mesh", "select an input mesh") + #self.LE_MeshSmesh.setText("") + #self.MeshIn="" + #self.LE_MeshFile.setText("") + #self.fichierIn="" return self.smeshStudyTool = SMeshStudyTools() try: @@ -441,9 +518,9 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): self.fichierIn="" def prepareFichier(self): - self.fichierIn="/tmp/ForMGCleaner_"+str(self.num)+".mesh" - #print "prepareFichier" - import SMESH + self.fichierIn=tempfile.mktemp(suffix=".mesh",prefix="ForMGCleaner_") + if os.path.exists(self.fichierIn): + os.remove(self.fichierIn) self.__selectedMesh.ExportGMF(self.__selectedMesh, self.fichierIn, True) def PrepareLigneCommande(self): @@ -476,18 +553,14 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): self.commande="mg-cleaner.exe" verbosity=str(self.SP_Verbosity.value()) self.commande+=" --verbose " + verbosity - self.commande+=" --in " + self.fichierIn - #print "self.fichierIn",self.fichierIn,type(self.fichierIn) + self.commande+=' --in "' + self.fichierIn+'"' deb=os.path.splitext(str(self.fichierIn)) self.fichierOut=deb[0] + "_fix.mesh" - self.commande+=" --out "+self.fichierOut + self.commande+=' --out "'+self.fichierOut+'"' if self.RB_Fix1.isChecked(): - self.commande+=" --fix1pass" + self.commande+=" --mode fix" else: - if self.RB_Fix2.isChecked(): - self.commande+=" --fix2pass" - else: - self.commande+=" --check" + self.commande+=" --mode check" if self.CB_PreserveTopology.isChecked(): self.commande+=" --topology respect" else: @@ -500,16 +573,16 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): self.commande+=" --resolution_length " + self.SP_toStr(self.SP_ResolutionLength) self.commande+=" --folding_angle " + str(self.SP_FoldingAngle.value()) if self.CB_RemeshPlanes.isChecked(): #no remesh default - self.commande+=" --remesh_planes" + self.commande+=" --remesh_planes yes" if not self.CB_ComputedOverlapDistance.isChecked(): #computed default self.commande+=" --overlap_distance " + self.SP_toStr(self.SP_OverlapDistance) self.commande+=" --overlap_angle " + str(self.SP_OverlapAngle.value()) + if verbose: print(("INFO: MGCCleaner command:\n %s" % self.commande)) return True - + def clean(self): self.RB_Check.setChecked(False) - self.RB_Fix1.setChecked(False) - self.RB_Fix2.setChecked(True) + self.RB_Fix1.setChecked(True) self.CB_PreserveTopology.setChecked(False) self.CB_FillHoles.setChecked(False) self.CB_RemeshPlanes.setChecked(False) @@ -530,11 +603,11 @@ __dialog=None def getDialog(): """ This function returns a singleton instance of the plugin dialog. - c est obligatoire pour faire un show sans parent... + It is mandatory in order to call show without a parent ... """ global __dialog if __dialog is None: - __dialog = MGCleanerMonPlugDialog() + __dialog = MGCleanerMonPlugDialog() #else : # __dialog.clean() return __dialog @@ -549,17 +622,16 @@ def TEST_standalone(): """ works only if a salome is launched yet with a study loaded to launch standalone python do: - /export/home/wambeke/2013/V6_main_MGC_CO6.4_64/APPLI/runSession + ./APPLI/runSession python or (do not works) - python /export/home/wambeke/2013/V6_main_MGC_CO6.4_64/INSTALL/SMESH/share/salome/plugins/smesh/MGCleanerMonPlugDialog.py + python ./INSTALL/SMESH/share/salome/plugins/smesh/MGCleanerMonPlugDialog.py """ import salome - import smesh import SMESH from salome.kernel import studyedit salome.salome_init() - maStudy=studyedit.getActiveStudy() + maStudy=salome.myStudy #etc...a mano... # @@ -568,12 +640,10 @@ def TEST_standalone(): # ============================================================================== # def TEST_MGCleanerMonPlugDialog(): - #print "TEST_MGCleanerMonPlugDialog" import sys - from PyQt4.QtGui import QApplication - from PyQt4.QtCore import QObject, SIGNAL, SLOT + from qtsalome import QApplication app = QApplication(sys.argv) - QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) + app.lastWindowClosed.connect(app.quit) dlg=MGCleanerMonPlugDialog() dlg.show() @@ -583,3 +653,4 @@ if __name__ == "__main__": TEST_MGCleanerMonPlugDialog() #TEST_standalone() pass +