Salome HOME
6511268a8243fafc594de24c204aee4ed261e953
[modules/smesh.git] / src / Tools / MGCleanerPlug / MGCleanerMonPlugDialog.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013  EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 # Modules Python
22 # Modules Eficas
23
24 import os, subprocess
25 from MGCleanerPlugDialog import Ui_MGCleanerPlugDialog
26 from MGCleanerMonViewText import MGCleanerMonViewText
27 from PyQt4.QtGui import *
28 from PyQt4.QtCore import *
29
30
31 class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget):
32   """
33   """
34   def __init__(self):
35     QWidget.__init__(self)
36     self.setupUi(self)
37     self.connecterSignaux()
38     self.fichierIn=""
39     self.fichierOut=""
40     self.MeshIn=""
41     self.commande=""
42     self.num=1
43     self.__selectedMesh=None
44     
45     # complex whith QResources: not used
46     # The icon are supposed to be located in the $SMESH_ROOT_DIR/share/salome/resources/smesh folder,
47     # other solution could be in the same folder than this python module file:
48     # iconfolder=os.path.dirname(os.path.abspath(__file__))
49
50     self.iconfolder=os.environ["SMESH_ROOT_DIR"]+"/share/salome/resources/smesh"
51     #print "MGCleanerMonPlugDialog iconfolder",iconfolder
52     icon = QIcon()
53     icon.addFile(os.path.join(self.iconfolder,"select1.png"))
54     self.PB_LoadHyp.setIcon(icon)
55     self.PB_LoadHyp.setToolTip("hypothesis from Salome Object Browser")
56     self.PB_SaveHyp.setIcon(icon)
57     self.PB_SaveHyp.setToolTip("hypothesis to Salome Object Browser")
58     self.PB_MeshSmesh.setIcon(icon)
59     self.PB_MeshSmesh.setToolTip("source mesh from Salome Object Browser")
60     icon = QIcon()
61     icon.addFile(os.path.join(self.iconfolder,"open.png"))
62     self.PB_ParamsFileExplorer.setIcon(icon)
63     self.PB_Load.setIcon(icon)
64     self.PB_Load.setToolTip("hypothesis from file")
65     self.PB_Save.setIcon(icon)
66     self.PB_Save.setToolTip("hypothesis to file")
67     self.PB_MeshFile.setIcon(icon)
68     self.PB_MeshFile.setToolTip("source mesh from a file in disk")
69     
70     #Ces parametres ne sont pas remis à rien par le clean
71     self.paramsFile= os.path.abspath(os.path.join(os.environ["HOME"],".MGCleaner.dat"))
72     self.LE_ParamsFile.setText(self.paramsFile)
73     self.LE_MeshFile.setText("")
74     self.LE_MeshSmesh.setText("")
75
76     v1=QDoubleValidator(self)
77     v1.setBottom(0.)
78     #v1.setTop(10000.)
79     v1.setDecimals(4)
80     self.SP_MinHoleSize.setValidator(v1)
81     self.SP_MinHoleSize.titleForWarning="MinHoleSize"
82
83     v2=QDoubleValidator(self)
84     v2.setBottom(0.)
85     #v2.setTop(10000.)
86     v2.setDecimals(4)
87     self.SP_ToleranceDisplacement.setValidator(v2)
88     self.SP_ToleranceDisplacement.titleForWarning="ToleranceDisplacement"
89
90     v3=QDoubleValidator(self)
91     v3.setBottom(0.)
92     #v3.setTop(10000.)
93     v3.setDecimals(4)
94     self.SP_ResolutionLength.setValidator(v3)
95     self.SP_ResolutionLength.titleForWarning="ResolutionLength"
96     
97     v4=QDoubleValidator(self)
98     v4.setBottom(0.)
99     #v4.setTop(10000.)
100     v4.setDecimals(4)
101     self.SP_OverlapDistance.setValidator(v4)
102     self.SP_OverlapDistance.titleForWarning="OverlapDistance"
103     
104     self.resize(800, 500)
105     self.clean()
106
107   def connecterSignaux(self) :
108     self.connect(self.PB_Cancel,SIGNAL("clicked()"),self.PBCancelPressed)
109     self.connect(self.PB_Default,SIGNAL("clicked()"),self.clean)
110     self.connect(self.PB_Help,SIGNAL("clicked()"),self.PBHelpPressed)
111     self.connect(self.PB_OK,SIGNAL("clicked()"),self.PBOKPressed)
112     
113     self.connect(self.PB_Load,SIGNAL("clicked()"),self.PBLoadPressed)
114     self.connect(self.PB_Save,SIGNAL("clicked()"),self.PBSavePressed)
115     self.connect(self.PB_LoadHyp,SIGNAL("clicked()"),self.PBLoadHypPressed)
116     self.connect(self.PB_SaveHyp,SIGNAL("clicked()"),self.PBSaveHypPressed)
117     
118     self.connect(self.PB_MeshFile,SIGNAL("clicked()"),self.PBMeshFilePressed)
119     self.connect(self.PB_MeshSmesh,SIGNAL("clicked()"),self.PBMeshSmeshPressed)
120     self.connect(self.LE_MeshSmesh,SIGNAL("returnPressed()"),self.meshSmeshNameChanged)
121     self.connect(self.PB_ParamsFileExplorer,SIGNAL("clicked()"),self.setParamsFileName)
122     self.connect(self.LE_MeshFile,SIGNAL("returnPressed()"),self.meshFileNameChanged)
123     self.connect(self.LE_ParamsFile,SIGNAL("returnPressed()"),self.paramsFileNameChanged)
124
125     #QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL("stateChanged(int)"), self.change) 
126     self.connect(self.CB_FillHoles,SIGNAL("stateChanged(int)"),self.SP_MinHoleSize.setEnabled)
127     self.connect(self.CB_ComputedToleranceDisplacement,SIGNAL("stateChanged(int)"),self.SP_ToleranceDisplacement.setDisabled)
128     self.connect(self.CB_ComputedResolutionLength,SIGNAL("stateChanged(int)"),self.SP_ResolutionLength.setDisabled)
129     self.connect(self.CB_ComputedOverlapDistance,SIGNAL("stateChanged(int)"),self.SP_OverlapDistance.setDisabled)
130
131   def PBHelpPressed(self):
132     try:
133       mydir=os.environ["SMESH_ROOT_DIR"]
134     except Exception:
135       QMessageBox.warning( self, "Help", "Help unavailable $SMESH_ROOT_DIR not found")
136       return
137     maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf"
138     command="xdg-open "+maDoc+";"
139     subprocess.call(command, shell=True)
140
141   def PBOKPressed(self):
142     if not(self.PrepareLigneCommande()):
143       #warning done yet
144       #QMessageBox.warning(self, "Compute", "Command not found")
145       return
146     maFenetre=MGCleanerMonViewText(self, self.commande)
147
148   def enregistreResultat(self):
149     import salome
150     import SMESH
151     from salome.kernel import studyedit
152     from salome.smesh import smeshBuilder
153     smesh = smeshBuilder.New(salome.myStudy)
154     
155     if not os.path.isfile(self.fichierOut):
156       QMessageBox.warning(self, "Compute", "Result file "+self.fichierOut+" not found")
157
158     maStudy=studyedit.getActiveStudy()
159     smesh.SetCurrentStudy(maStudy)
160     (outputMesh, status) = smesh.CreateMeshesFromGMF(self.fichierOut)
161     name=str(self.LE_MeshSmesh.text())
162     initialMeshFile=None
163     initialMeshObject=None
164     if name=="":
165       a=str(self.fichierIn)
166       name=os.path.basename(os.path.splitext(a)[0])
167       initialMeshFile=a
168     else:
169       initialMeshObject=maStudy.FindObjectByName(name ,"SMESH")[0]
170
171     meshname = name+"_MGC_"+str(self.num)
172     smesh.SetName(outputMesh.GetMesh(), meshname)
173     outputMesh.Compute() #no algorithms message for "Mesh_x" has been computed with warnings: -  global 1D algorithm is missing
174
175     self.editor = studyedit.getStudyEditor()
176     moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
177     HypReMeshEntry = self.editor.findOrCreateItem(
178         moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" )
179     
180     monStudyBuilder=maStudy.NewBuilder()
181     monStudyBuilder.NewCommand()
182     newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
183     self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num))
184     self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; "))
185     
186     SOMesh=maStudy.FindObjectByName(meshname ,"SMESH")[0]
187     
188     if initialMeshFile!=None:
189       newStudyFileName=monStudyBuilder.NewObject(SOMesh)
190       self.editor.setAttributeValue(newStudyFileName, "AttributeName", "meshFile")
191       self.editor.setAttributeValue(newStudyFileName, "AttributeExternalFileDef", initialMeshFile)
192       self.editor.setAttributeValue(newStudyFileName, "AttributeComment", initialMeshFile)
193
194     if initialMeshObject!=None:
195       newLink=monStudyBuilder.NewObject(SOMesh)
196       monStudyBuilder.Addreference(newLink, initialMeshObject)
197
198     newLink=monStudyBuilder.NewObject(SOMesh)
199     monStudyBuilder.Addreference(newLink, newStudyIter)
200
201     if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
202     self.num+=1
203     return True
204
205   def PBSavePressed(self):
206     from datetime import datetime
207     if not(self.PrepareLigneCommande()): return
208     text = "# MGCleaner hypothesis parameters\n"
209     text += "# Params for mesh : " +  self.LE_MeshSmesh.text() +"\n"
210     text += datetime.now().strftime("# Date : %d/%m/%y %H:%M:%S\n")
211     text += "# Command : "+self.commande+"\n"
212     text += self.getResumeData(separator="\n")
213     text += "\n\n"
214
215     try:
216       f=open(self.paramsFile,"a")
217     except:
218       QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
219       return
220     try:
221       f.write(text)
222     except:
223       QMessageBox.warning(self, "File", "Unable to write "+self.paramsFile)
224       return
225     f.close()
226
227   def PBSaveHypPressed(self):
228     """save hypothesis in Object Browser"""
229     import salome
230     import SMESH
231     from salome.kernel import studyedit
232     from salome.smesh import smeshBuilder
233     smesh = smeshBuilder.New(salome.myStudy)
234
235     maStudy=studyedit.getActiveStudy()
236     smesh.SetCurrentStudy(maStudy)
237     
238     self.editor = studyedit.getStudyEditor()
239     moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
240     HypReMeshEntry = self.editor.findOrCreateItem(
241         moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" )
242     
243     monStudyBuilder=maStudy.NewBuilder()
244     monStudyBuilder.NewCommand()
245     newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
246     self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num))
247     self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; "))
248     
249     if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
250     self.num+=1
251     return True
252
253     """
254     import salome_pluginsmanager
255     print "salome_pluginsmanager.plugins",salome_pluginsmanager.plugins
256     print "salome_pluginsmanager.current_plugins_manager",salome_pluginsmanager.current_plugins_manager
257     """
258   
259   def SP_toStr(self, widget):
260     """only for a QLineEdit widget"""
261     #cr, pos=widget.validator().validate(res, 0) #n.b. "1,3" is acceptable !locale!
262     try:
263       val=float(widget.text())
264     except:
265       QMessageBox.warning(self, widget.titleForWarning, "float value is incorrect: '"+widget.text()+"'")
266       res=str(widget.validator().bottom())
267       widget.setProperty("text", res)
268       return res
269     valtest=widget.validator().bottom()
270     if valtest!=None:
271       if val<valtest:
272         QMessageBox.warning(self, widget.titleForWarning, "float value is under minimum: "+str(val)+" < "+str(valtest))
273         res=str(valtest)
274         widget.setProperty("text", res)
275         return res
276     valtest=widget.validator().top()
277     if valtest!=None:
278       if val>valtest:
279         QMessageBox.warning(self, widget.titleForWarning, "float value is over maximum: "+str(val)+" > "+str(valtest))
280         res=str(valtest)
281         widget.setProperty("text", res)
282         return res    
283     return str(val)
284
285   def getResumeData(self, separator="\n"):
286     text=""
287     if self.RB_Fix1.isChecked():
288       CheckOrFix="fix1pass"
289     else:
290       if self.RB_Fix2.isChecked():
291         CheckOrFix="fix2pass"
292       else:
293         CheckOrFix="check"
294     text+="CheckOrFix="+CheckOrFix+separator
295     text+="PreserveTopology="+str(self.CB_PreserveTopology.isChecked())+separator
296     text+="FillHoles="+str(self.CB_FillHoles.isChecked())+separator
297     v=self.SP_toStr(self.SP_MinHoleSize)
298     text+="MinHoleSize="+v+separator
299     text+="ComputedToleranceDisplacement="+str(self.CB_ComputedToleranceDisplacement.isChecked())+separator
300     v=self.SP_toStr(self.SP_ToleranceDisplacement)
301     text+="ToleranceDisplacement="+v+separator
302     text+="ComputedResolutionLength="+str(self.CB_ComputedResolutionLength.isChecked())+separator
303     v=self.SP_toStr(self.SP_ResolutionLength)
304     text+="ResolutionLength="+v+separator
305     text+="FoldingAngle="+str(self.SP_FoldingAngle.value())+separator
306     text+="RemeshPlanes="+str(self.CB_RemeshPlanes.isChecked())+separator
307     text+="ComputedOverlapDistance="+str(self.CB_ComputedOverlapDistance.isChecked())+separator
308     v=self.SP_toStr(self.SP_OverlapDistance)
309     text+="OverlapDistance="+v+separator
310     text+="OverlapAngle="+str(self.SP_OverlapAngle.value())+separator
311     text+="Verbosity="+str(self.SP_Verbosity.value())+separator
312     return str(text)
313
314   def loadResumeData(self, hypothesis, separator="\n"):
315     text=str(hypothesis)
316     self.clean()
317     for slig in reversed(text.split(separator)):
318       lig=slig.strip()
319       #print "load ResumeData",lig
320       if lig=="": continue #skip blanck lines
321       if lig[0]=="#": break
322       try:
323         tit,value=lig.split("=")
324         if tit=="CheckOrFix":
325           self.RB_Fix1.setChecked(False)
326           self.RB_Fix2.setChecked(False)
327           self.RB_Check.setChecked(False)
328           if value=="fix1pass": self.RB_Fix1.setChecked(True)
329           if value=="fix2pass": self.RB_Fix2.setChecked(True)
330           if value=="check": self.RB_Check.setChecked(True)
331         if tit=="PreserveTopology": self.CB_PreserveTopology.setChecked(value=="True")
332         if tit=="FillHoles": self.CB_FillHoles.setChecked(value=="True")
333         if tit=="MinHoleSize": self.SP_MinHoleSize.setProperty("text", value)
334         if tit=="ComputedToleranceDisplacement": self.CB_ComputedToleranceDisplacement.setChecked(value=="True")
335         if tit=="ToleranceDisplacement": self.SP_ToleranceDisplacement.setProperty("text", value)
336         if tit=="ComputedResolutionLength": self.CB_ComputedResolutionLength.setChecked(value=="True")
337         if tit=="ResolutionLength": self.SP_ResolutionLength.setProperty("text", value)
338         if tit=="FoldingAngle": self.SP_FoldingAngle.setProperty("value", float(value))
339         if tit=="RemeshPlanes": self.CB_RemeshPlanes.setChecked(value=="True")
340         if tit=="ComputedOverlapDistance": self.CB_ComputedOverlapDistance.setChecked(value=="True")
341         if tit=="OverlapDistance": self.SP_OverlapDistance.setProperty("text", value)
342         if tit=="OverlapAngle": self.SP_OverlapAngle.setProperty("value", float(value))
343         if tit=="Verbosity": self.SP_Verbosity.setProperty("value", int(float(value)))
344       except:
345         QMessageBox.warning(self, "load MGCleaner Hypothesis", "Problem on '"+lig+"'")
346
347   def PBLoadPressed(self):
348     """load last hypothesis saved in tail of file"""
349     try:
350         f=open(self.paramsFile,"r")
351     except :
352         QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
353         return
354     try:
355         text=f.read()
356     except :
357         QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile)
358         return
359     f.close()
360     self.loadResumeData(text, separator="\n")
361
362   def PBLoadHypPressed(self):
363     """load hypothesis saved in Object Browser"""
364     #QMessageBox.warning(self, "load Object Browser MGCleaner hypothesis", "TODO")
365     import salome
366     from salome.kernel import studyedit
367     from salome.smesh.smeshstudytools import SMeshStudyTools
368     from salome.gui import helper as guihelper
369     from omniORB import CORBA
370
371     mySObject, myEntry = guihelper.getSObjectSelected()
372     if CORBA.is_nil(mySObject) or mySObject==None:
373       QMessageBox.critical(self, "Hypothese", "select an Object Browser MGCleaner hypothesis")
374       return
375     
376     #for i in dir(mySObject): print "dir mySObject",i
377     #print "GetAllAttributes",mySObject.GetAllAttributes()
378     #print "GetComment",mySObject.GetComment()
379     #print "GetName",mySObject.GetName()
380     
381     #could be renamed...
382     #if mySObject.GetFather().GetName()!="MGCleaner Hypotheses":
383     #  QMessageBox.critical(self, "Hypothese", "not a child of MGCleaner Hypotheses")
384     #  return
385     
386     text=mySObject.GetComment()
387     
388     #a verification
389     if "CheckOrFix=" not in text:
390       QMessageBox.critical(self, "Load Hypothese", "Object Browser selection not a MGCleaner Hypothesis")
391       return
392     self.loadResumeData(text, separator=" ; ")
393     return
394     
395   def PBCancelPressed(self):
396     self.close()
397
398   def PBMeshFilePressed(self):
399     fd = QFileDialog(self, "select an existing Mesh file", self.LE_MeshFile.text(), "Mesh-Files (*.mesh);;All Files (*)")
400     if fd.exec_():
401       infile = fd.selectedFiles()[0]
402       self.LE_MeshFile.setText(infile)
403       self.fichierIn=infile.toLatin1()
404       self.MeshIn=""
405       self.LE_MeshSmesh.setText("")
406
407   def setParamsFileName(self):
408     fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)")
409     if fd.exec_():
410       infile = fd.selectedFiles()[0]
411       self.LE_ParamsFile.setText(infile)
412       self.paramsFile=infile.toLatin1()
413
414   def meshFileNameChanged(self):
415     self.fichierIn=str(self.LE_MeshFile.text())
416     #print "meshFileNameChanged", self.fichierIn
417     if os.path.exists(self.fichierIn): 
418       self.__selectedMesh=None
419       self.MeshIn=""
420       self.LE_MeshSmesh.setText("")
421       return
422     QMessageBox.warning(self, "Mesh file", "File doesn't exist")
423
424   def meshSmeshNameChanged(self):
425     """only change by GUI mouse selection, otherwise clear"""
426     #self.MeshIn=str(self.LE_MeshSmesh.text())
427     #print "meshSmeshNameChanged", self.MeshIn
428     self.__selectedMesh = None
429     self.MeshIn=""
430     self.LE_MeshSmesh.setText("")
431     self.fichierIn=""
432     return
433
434   def paramsFileNameChanged(self):
435     self.paramsFile=self.LE_ParamsFile.text()
436
437   def PBMeshSmeshPressed(self):
438     from omniORB import CORBA
439     import salome
440     from salome.kernel import studyedit
441     from salome.smesh.smeshstudytools import SMeshStudyTools
442     from salome.gui import helper as guihelper
443     from salome.smesh import smeshBuilder
444     smesh = smeshBuilder.New(salome.myStudy)
445
446     mySObject, myEntry = guihelper.getSObjectSelected()
447     if CORBA.is_nil(mySObject) or mySObject==None:
448       QMessageBox.critical(self, "Mesh", "select an input mesh")
449       return
450     self.smeshStudyTool = SMeshStudyTools()
451     try:
452       self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
453     except:
454       QMessageBox.critical(self, "Mesh", "select an input mesh")
455       return
456     if CORBA.is_nil(self.__selectedMesh):
457       QMessageBox.critical(self, "Mesh", "select an input mesh")
458       return
459     myName = mySObject.GetName()
460     #print "MeshSmeshNameChanged", myName
461     self.MeshIn=myName
462     self.LE_MeshSmesh.setText(myName)
463     self.LE_MeshFile.setText("")
464     self.fichierIn=""
465
466   def prepareFichier(self):
467     self.fichierIn="/tmp/ForMGCleaner_"+str(self.num)+".mesh"
468     self.__selectedMesh.ExportGMF(self.__selectedMesh, self.fichierIn, True)
469
470   def PrepareLigneCommande(self):
471     """
472     #use doc examples of mg-cleaner:
473     ls -al /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin
474     source /data/tmplgls/salome/prerequis/install/LICENSE/dlim8.var.sh
475     export PATH=/data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin/Linux_64:$PATH
476     cp -r /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/examples .
477     cd examples
478     mg-cleaner.exe --help
479     mg-cleaner.exe --in case7.mesh --out case7-test.mesh --check
480     mg-cleaner.exe case7.mesh case7-fix.mesh --fix
481     mg-cleaner.exe --in Porsche.mesh --out Porsche-test.mesh --check
482     mg-cleaner.exe --in Porsche.mesh --out Porschefix.mesh --fix
483     mg-cleaner.exe --in Porsche.mesh --out PorscheNewfix.mesh --fix --resolution_length 0.03
484     """
485     
486     #self.commande="mg-cleaner.exe --in " + self.fichierIn + " --out " + self.fichierOut + " --fix2pass" 
487     #return True
488     #print "PrepareLigneCommande '"+self.fichierIn+"' '"+self.MeshIn+"'",self.__selectedMesh
489     if self.fichierIn=="" and self.MeshIn=="":
490       QMessageBox.critical(self, "Mesh", "select an input mesh")
491       return False
492     if self.__selectedMesh!=None: self.prepareFichier()
493     if not (os.path.isfile(self.fichierIn)):
494       QMessageBox.critical(self, "File", "unable to read GMF Mesh in "+str(self.fichierIn))
495       return False
496     
497     self.commande="mg-cleaner.exe"
498     verbosity=str(self.SP_Verbosity.value())
499     self.commande+=" --verbose " + verbosity
500     self.commande+=" --in " + self.fichierIn
501     #print "self.fichierIn",self.fichierIn,type(self.fichierIn)
502     deb=os.path.splitext(str(self.fichierIn))
503     self.fichierOut=deb[0] + "_fix.mesh"
504     self.commande+=" --out "+self.fichierOut
505     if self.RB_Fix1.isChecked():
506       self.commande+=" --fix1pass"
507     else:
508       if self.RB_Fix2.isChecked():
509         self.commande+=" --fix2pass"
510       else:
511         self.commande+=" --check"
512     if self.CB_PreserveTopology.isChecked():
513       self.commande+=" --topology respect"
514     else:
515       self.commande+=" --topology ignore"
516     if self.CB_FillHoles.isChecked(): #no fill holes default
517       self.commande+=" --min_hole_size " + self.SP_toStr(self.SP_MinHoleSize)
518     if not self.CB_ComputedToleranceDisplacement.isChecked(): #computed default
519       self.commande+=" --tolerance_displacement " + self.SP_toStr(self.SP_ToleranceDisplacement)
520     if not self.CB_ComputedResolutionLength.isChecked(): #computed default
521       self.commande+=" --resolution_length " + self.SP_toStr(self.SP_ResolutionLength)
522     self.commande+=" --folding_angle " + str(self.SP_FoldingAngle.value())
523     if self.CB_RemeshPlanes.isChecked(): #no remesh default
524       self.commande+=" --remesh_planes"
525     if not self.CB_ComputedOverlapDistance.isChecked(): #computed default
526       self.commande+=" --overlap_distance " + self.SP_toStr(self.SP_OverlapDistance)
527     self.commande+=" --overlap_angle " + str(self.SP_OverlapAngle.value())
528     return True
529     
530   def clean(self):
531     self.RB_Check.setChecked(False)
532     self.RB_Fix1.setChecked(False)
533     self.RB_Fix2.setChecked(True)
534     self.CB_PreserveTopology.setChecked(False)
535     self.CB_FillHoles.setChecked(False)
536     self.CB_RemeshPlanes.setChecked(False)
537     
538     self.SP_MinHoleSize.setProperty("text", 0)
539     self.SP_ToleranceDisplacement.setProperty("text", 0)
540     self.SP_ResolutionLength.setProperty("text", 0)
541     self.SP_FoldingAngle.setProperty("value", 15)
542     self.SP_OverlapDistance.setProperty("text", 0)
543     self.SP_OverlapAngle.setProperty("value", 15)
544     self.SP_Verbosity.setProperty("value", 3)
545     
546     self.CB_ComputedToleranceDisplacement.setChecked(True)
547     self.CB_ComputedResolutionLength.setChecked(True)
548     self.CB_ComputedOverlapDistance.setChecked(True)
549
550 __dialog=None
551 def getDialog():
552   """
553   This function returns a singleton instance of the plugin dialog.
554   c est obligatoire pour faire un show sans parent...
555   """
556   global __dialog
557   if __dialog is None:
558       __dialog = MGCleanerMonPlugDialog()
559   #else :
560   #   __dialog.clean()
561   return __dialog
562
563
564 #
565 # ==============================================================================
566 # For memory
567 # ==============================================================================
568 #
569 def TEST_standalone():
570   """
571   works only if a salome is launched yet with a study loaded
572   to launch standalone python do:
573   /export/home/wambeke/2013/V6_main_MGC_CO6.4_64/APPLI/runSession
574   python
575   or (do not works)
576   python /export/home/wambeke/2013/V6_main_MGC_CO6.4_64/INSTALL/SMESH/share/salome/plugins/smesh/MGCleanerMonPlugDialog.py
577   """
578   import salome
579   import SMESH
580   from salome.kernel import studyedit
581   salome.salome_init()
582   maStudy=studyedit.getActiveStudy()
583   #etc...a mano...
584
585 #
586 # ==============================================================================
587 # Basic use cases and unit test functions
588 # ==============================================================================
589 #
590 def TEST_MGCleanerMonPlugDialog():
591   #print "TEST_MGCleanerMonPlugDialog"
592   import sys
593   from PyQt4.QtGui import QApplication
594   from PyQt4.QtCore import QObject, SIGNAL, SLOT
595   app = QApplication(sys.argv)
596   QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
597
598   dlg=MGCleanerMonPlugDialog()
599   dlg.show()
600   sys.exit(app.exec_())
601
602 if __name__ == "__main__":
603   TEST_MGCleanerMonPlugDialog()
604   #TEST_standalone()
605   pass