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