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