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