Salome HOME
Update copyrights
[modules/smesh.git] / src / Tools / MGCleanerPlug / MGCleanerMonPlugDialog.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2013-2019  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 verbose = True
31
32 class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget):
33   """
34   """
35   def __init__(self):
36     QWidget.__init__(self)
37     self.setupUi(self)
38     self.connecterSignaux()
39     self.fichierIn=""
40     self.fichierOut=""
41     self.MeshIn=""
42     self.commande=""
43     self.num=1
44     self.__selectedMesh=None
45
46     # complex with QResources: not used
47     # The icon are supposed to be located in the $SMESH_ROOT_DIR/share/salome/resources/smesh folder,
48     # other solution could be in the same folder than this python module file:
49     # iconfolder=os.path.dirname(os.path.abspath(__file__))
50
51     self.iconfolder=os.environ["SMESH_ROOT_DIR"]+"/share/salome/resources/smesh"
52     #print "MGCleanerMonPlugDialog iconfolder",iconfolder
53     icon = QIcon()
54     icon.addFile(os.path.join(self.iconfolder,"select1.png"))
55     self.PB_LoadHyp.setIcon(icon)
56     self.PB_LoadHyp.setToolTip("hypothesis from Salome Object Browser")
57     self.PB_SaveHyp.setIcon(icon)
58     self.PB_SaveHyp.setToolTip("hypothesis to Salome Object Browser")
59     self.PB_MeshSmesh.setIcon(icon)
60     self.PB_MeshSmesh.setToolTip("source mesh from Salome Object Browser")
61     icon = QIcon()
62     icon.addFile(os.path.join(self.iconfolder,"open.png"))
63     self.PB_ParamsFileExplorer.setIcon(icon)
64     self.PB_Load.setIcon(icon)
65     self.PB_Load.setToolTip("hypothesis from file")
66     self.PB_Save.setIcon(icon)
67     self.PB_Save.setToolTip("hypothesis to file")
68     self.PB_MeshFile.setIcon(icon)
69     self.PB_MeshFile.setToolTip("source mesh from a file in disk")
70
71     #Ces parametres ne sont pas remis a rien par le clean
72     self.paramsFile= os.path.abspath(os.path.join(os.environ["HOME"],".MGCleaner.dat"))
73     self.LE_ParamsFile.setText(self.paramsFile)
74     self.LE_MeshFile.setText("")
75     self.LE_MeshSmesh.setText("")
76
77     v1=QDoubleValidator(self)
78     v1.setBottom(0.)
79     #v1.setTop(10000.)
80     v1.setDecimals(4)
81     self.SP_MinHoleSize.setValidator(v1)
82     self.SP_MinHoleSize.titleForWarning="MinHoleSize"
83
84     v2=QDoubleValidator(self)
85     v2.setBottom(0.)
86     #v2.setTop(10000.)
87     v2.setDecimals(4)
88     self.SP_ToleranceDisplacement.setValidator(v2)
89     self.SP_ToleranceDisplacement.titleForWarning="ToleranceDisplacement"
90
91     v3=QDoubleValidator(self)
92     v3.setBottom(0.)
93     #v3.setTop(10000.)
94     v3.setDecimals(4)
95     self.SP_ResolutionLength.setValidator(v3)
96     self.SP_ResolutionLength.titleForWarning="ResolutionLength"
97     
98     v4=QDoubleValidator(self)
99     v4.setBottom(0.)
100     #v4.setTop(10000.)
101     v4.setDecimals(4)
102     self.SP_OverlapDistance.setValidator(v4)
103     self.SP_OverlapDistance.titleForWarning="OverlapDistance"
104     
105     self.resize(800, 500)
106     self.clean()
107
108   def connecterSignaux(self) :
109     self.PB_Cancel.clicked.connect(self.PBCancelPressed)
110     self.PB_Default.clicked.connect(self.clean)
111     self.PB_Help.clicked.connect(self.PBHelpPressed)
112     self.PB_OK.clicked.connect(self.PBOKPressed)
113     
114     self.PB_Load.clicked.connect(self.PBLoadPressed)
115     self.PB_Save.clicked.connect(self.PBSavePressed)
116     self.PB_LoadHyp.clicked.connect(self.PBLoadHypPressed)
117     self.PB_SaveHyp.clicked.connect(self.PBSaveHypPressed)
118     
119     self.PB_MeshFile.clicked.connect(self.PBMeshFilePressed)
120     self.PB_MeshSmesh.clicked.connect(self.PBMeshSmeshPressed)
121     self.LE_MeshSmesh.returnPressed.connect(self.meshSmeshNameChanged)
122     self.PB_ParamsFileExplorer.clicked.connect(self.setParamsFileName)
123     self.LE_MeshFile.returnPressed.connect(self.meshFileNameChanged)
124     self.LE_ParamsFile.returnPressed.connect(self.paramsFileNameChanged)
125
126     #QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL("stateChanged(int)"), self.change) 
127     self.CB_FillHoles.stateChanged[int].connect(self.SP_MinHoleSize.setEnabled)
128     self.CB_ComputedToleranceDisplacement.stateChanged[int].connect(self.SP_ToleranceDisplacement.setDisabled)
129     self.CB_ComputedResolutionLength.stateChanged[int].connect(self.SP_ResolutionLength.setDisabled)
130     self.CB_ComputedOverlapDistance.stateChanged[int].connect(self.SP_OverlapDistance.setDisabled)
131
132   def PBHelpPressed(self):
133     import SalomePyQt
134     sgPyQt = SalomePyQt.SalomePyQt()
135     try:
136       mydir=os.environ["SMESH_ROOT_DIR"]
137     except Exception:
138       QMessageBox.warning(self, "Help", "Help unavailable $SMESH_ROOT_DIR not found")
139       return
140
141     maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/index.html"
142     sgPyQt.helpContext(maDoc,"")
143     
144     #maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf"
145     #command="xdg-open "+maDoc+";"
146     #subprocess.call(command, shell=True)
147
148   def PBOKPressed(self):
149     if not(self.PrepareLigneCommande()):
150       #warning done yet
151       #QMessageBox.warning(self, "Compute", "Command not found")
152       return
153     maFenetre=MGCleanerMonViewText(self, self.commande)
154
155   def enregistreResultat(self):
156     import salome
157     import SMESH
158     from salome.kernel import studyedit
159     from salome.smesh import smeshBuilder
160     smesh = smeshBuilder.New()
161     
162     if not os.path.isfile(self.fichierOut):
163       QMessageBox.warning(self, "Compute", "Result file "+self.fichierOut+" not found")
164
165     maStudy=salome.myStudy
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()
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_risky(self):
234     """
235     save hypothesis in Object Browser outside GEOM ou MESH
236     WARNING: at root of Object Browser is not politically correct
237     """
238     import salome
239     
240     if verbose: print("save hypothesis in Object Browser")
241     
242     name = "MGCleaner"
243     #how ??? icon = "mesh_tree_hypo.png"
244     namei = "MGCleaner Parameters_%i" % self.num
245     datai = self.getResumeData(separator=" ; ")
246     
247     myStudy = salome.myStudy
248     myBuilder = myStudy.NewBuilder()
249     #myStudy.IsStudyLocked()
250     myComponent = myStudy.FindComponent(name)
251     if myComponent == None:
252       print("myComponent not found, create")
253       myComponent = myBuilder.NewComponent(name)
254     AName = myBuilder.FindOrCreateAttribute(myComponent, "AttributeName")
255     AName.SetValue(name)
256     ACmt = myBuilder.FindOrCreateAttribute(myComponent, "AttributeComment")
257     ACmt.SetValue(name)
258     
259     myObject = myBuilder.NewObject(myComponent)
260     AName = myBuilder.FindOrCreateAttribute(myObject, "AttributeName")
261     AName.SetValue(namei)
262     ACmt = myBuilder.FindOrCreateAttribute(myObject, "AttributeComment")
263     ACmt.SetValue(datai)
264
265     if salome.sg.hasDesktop(): salome.sg.updateObjBrowser()
266     self.num += 1
267     if verbose: print(("save %s in Object Browser done: %s\n%s" % (name, myObject.GetID(), datai)))
268     return True
269
270   def PBSaveHypPressed(self):
271     """
272     save hypothesis in Object Browser
273     bug: affichage ne marche pas si inclusion dans dans GEOM ou MESH depuis salome 730
274     """
275     import salome
276     import SMESH
277     from salome.kernel import studyedit
278     from salome.smesh import smeshBuilder
279     #[PAL issue tracker:issue1871] Les nouveaux objets ne s'affichent pas dans SMESH
280     QMessageBox.warning(self, "Save", "waiting for fix: Object Browser will not display hypothesis")
281     
282     if verbose: print("save hypothesis in Object Browser")
283     smesh = smeshBuilder.New()
284
285     maStudy=salome.myStudy
286
287     self.editor = studyedit.getStudyEditor()
288     moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
289     HypReMeshEntry = self.editor.findOrCreateItem(
290         moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png")
291     #, comment = "HypothesisForRemeshing" )
292
293     monStudyBuilder=maStudy.NewBuilder()
294     monStudyBuilder.NewCommand()
295     newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
296     name = "MGCleaner Parameters_%i" % self.num
297     self.editor.setAttributeValue(newStudyIter, "AttributeName", name)
298     data = self.getResumeData(separator=" ; ")
299     self.editor.setAttributeValue(newStudyIter, "AttributeComment", data)
300
301     """ 
302     # example storing in notebook
303     import salome_notebook
304     notebook = salome_notebook.notebook
305     notebook.set("MGCleaner_%i" % self.num, data)
306     """
307
308     if salome.sg.hasDesktop(): salome.sg.updateObjBrowser()
309     self.num += 1
310     if verbose: print(("save %s in Object Browser done:\n%s" % (name, data)))
311     return True
312
313   def SP_toStr(self, widget):
314     """only for a QLineEdit widget"""
315     #cr, pos=widget.validator().validate(res, 0) #n.b. "1,3" is acceptable !locale!
316     try:
317       val=float(widget.text())
318     except:
319       QMessageBox.warning(self, widget.titleForWarning, "float value is incorrect: '"+widget.text()+"'")
320       res=str(widget.validator().bottom())
321       widget.setProperty("text", res)
322       return res
323     valtest=widget.validator().bottom()
324     if valtest!=None:
325       if val<valtest:
326         QMessageBox.warning(self, widget.titleForWarning, "float value is under minimum: "+str(val)+" < "+str(valtest))
327         res=str(valtest)
328         widget.setProperty("text", res)
329         return res
330     valtest=widget.validator().top()
331     if valtest!=None:
332       if val>valtest:
333         QMessageBox.warning(self, widget.titleForWarning, "float value is over maximum: "+str(val)+" > "+str(valtest))
334         res=str(valtest)
335         widget.setProperty("text", res)
336         return res    
337     return str(val)
338
339   def getResumeData(self, separator="\n"):
340     text=""
341     if self.RB_Fix1.isChecked():
342       CheckOrFix="mode_fix"
343     else:
344       CheckOrFix="mode_check"
345     text+="CheckOrFix="+CheckOrFix+separator
346     text+="PreserveTopology="+str(self.CB_PreserveTopology.isChecked())+separator
347     text+="FillHoles="+str(self.CB_FillHoles.isChecked())+separator
348     v=self.SP_toStr(self.SP_MinHoleSize)
349     text+="MinHoleSize="+v+separator
350     text+="ComputedToleranceDisplacement="+str(self.CB_ComputedToleranceDisplacement.isChecked())+separator
351     v=self.SP_toStr(self.SP_ToleranceDisplacement)
352     text+="ToleranceDisplacement="+v+separator
353     text+="ComputedResolutionLength="+str(self.CB_ComputedResolutionLength.isChecked())+separator
354     v=self.SP_toStr(self.SP_ResolutionLength)
355     text+="ResolutionLength="+v+separator
356     text+="FoldingAngle="+str(self.SP_FoldingAngle.value())+separator
357     text+="RemeshPlanes="+str(self.CB_RemeshPlanes.isChecked())+separator
358     text+="ComputedOverlapDistance="+str(self.CB_ComputedOverlapDistance.isChecked())+separator
359     v=self.SP_toStr(self.SP_OverlapDistance)
360     text+="OverlapDistance="+v+separator
361     text+="OverlapAngle="+str(self.SP_OverlapAngle.value())+separator
362     text+="Verbosity="+str(self.SP_Verbosity.value())+separator
363     return str(text)
364
365   def loadResumeData(self, hypothesis, separator="\n"):
366     text=str(hypothesis)
367     self.clean()
368     for slig in reversed(text.split(separator)):
369       lig=slig.strip()
370       #print "load ResumeData",lig
371       if lig=="": continue #skip blanck lines
372       if lig[0]=="#": break
373       try:
374         tit,value=lig.split("=")
375         if tit=="CheckOrFix":
376           self.RB_Fix1.setChecked(False)
377           self.RB_Check.setChecked(False)
378           if value=="mode_fix": self.RB_Fix1.setChecked(True)
379           if value=="mode_check": self.RB_Check.setChecked(True)
380         if tit=="PreserveTopology": self.CB_PreserveTopology.setChecked(value=="True")
381         if tit=="FillHoles": self.CB_FillHoles.setChecked(value=="True")
382         if tit=="MinHoleSize": self.SP_MinHoleSize.setProperty("text", value)
383         if tit=="ComputedToleranceDisplacement": self.CB_ComputedToleranceDisplacement.setChecked(value=="True")
384         if tit=="ToleranceDisplacement": self.SP_ToleranceDisplacement.setProperty("text", value)
385         if tit=="ComputedResolutionLength": self.CB_ComputedResolutionLength.setChecked(value=="True")
386         if tit=="ResolutionLength": self.SP_ResolutionLength.setProperty("text", value)
387         if tit=="FoldingAngle": self.SP_FoldingAngle.setProperty("value", float(value))
388         if tit=="RemeshPlanes": self.CB_RemeshPlanes.setChecked(value=="True")
389         if tit=="ComputedOverlapDistance": self.CB_ComputedOverlapDistance.setChecked(value=="True")
390         if tit=="OverlapDistance": self.SP_OverlapDistance.setProperty("text", value)
391         if tit=="OverlapAngle": self.SP_OverlapAngle.setProperty("value", float(value))
392         if tit=="Verbosity": self.SP_Verbosity.setProperty("value", int(float(value)))
393       except:
394         QMessageBox.warning(self, "load MGCleaner Hypothesis", "Problem on '"+lig+"'")
395
396   def PBLoadPressed(self):
397     """load last hypothesis saved in tail of file"""
398     try:
399       f=open(self.paramsFile,"r")
400     except:
401       QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
402       return
403     try:
404       text=f.read()
405     except:
406       QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile)
407       return
408     f.close()
409     self.loadResumeData(text, separator="\n")
410
411   def PBLoadHypPressed(self):
412     """load hypothesis saved in Object Browser"""
413     #QMessageBox.warning(self, "load Object Browser MGCleaner hypothesis", "TODO")
414     import salome
415     from salome.kernel import studyedit
416     from salome.smesh.smeshstudytools import SMeshStudyTools
417     from salome.gui import helper as guihelper
418     from omniORB import CORBA
419
420     mySObject, myEntry = guihelper.getSObjectSelected()
421     if CORBA.is_nil(mySObject) or mySObject==None:
422       QMessageBox.critical(self, "Hypothese", "select an Object Browser MGCleaner hypothesis")
423       return
424     
425     #for i in dir(mySObject): print "dir mySObject",i
426     #print "GetAllAttributes",mySObject.GetAllAttributes()
427     #print "GetComment",mySObject.GetComment()
428     #print "GetName",mySObject.GetName()
429     
430     #could be renamed...
431     #if mySObject.GetFather().GetName()!="MGCleaner Hypotheses":
432     #  QMessageBox.critical(self, "Hypothese", "not a child of MGCleaner Hypotheses")
433     #  return
434     
435     text=mySObject.GetComment()
436     
437     #a verification
438     if "CheckOrFix=" not in text:
439       QMessageBox.critical(self, "Load Hypothese", "Object Browser selection not a MGCleaner Hypothesis")
440       return
441     self.loadResumeData(text, separator=" ; ")
442     return
443     
444   def PBCancelPressed(self):
445     self.close()
446
447   def PBMeshFilePressed(self):
448     fd = QFileDialog(self, "select an existing Mesh file", self.LE_MeshFile.text(), "Mesh-Files (*.mesh);;All Files (*)")
449     if fd.exec_():
450       infile = fd.selectedFiles()[0]
451       self.LE_MeshFile.setText(infile)
452       self.fichierIn=str(infile)
453       self.MeshIn=""
454       self.LE_MeshSmesh.setText("")
455       self.__selectedMesh=None
456
457   def setParamsFileName(self):
458     fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)")
459     if fd.exec_():
460       infile = fd.selectedFiles()[0]
461       self.LE_ParamsFile.setText(infile)
462       self.paramsFile=str(infile)
463
464   def meshFileNameChanged(self):
465     self.fichierIn=str(self.LE_MeshFile.text())
466     #print "meshFileNameChanged", self.fichierIn
467     if os.path.exists(self.fichierIn): 
468       self.__selectedMesh=None
469       self.MeshIn=""
470       self.LE_MeshSmesh.setText("")
471       return
472     QMessageBox.warning(self, "Mesh file", "File doesn't exist")
473
474   def meshSmeshNameChanged(self):
475     """only change by GUI mouse selection, otherwise clear"""
476     #self.MeshIn=str(self.LE_MeshSmesh.text())
477     #print "meshSmeshNameChanged", self.MeshIn
478     self.__selectedMesh = None
479     self.MeshIn=""
480     self.LE_MeshSmesh.setText("")
481     self.fichierIn=""
482     return
483
484   def paramsFileNameChanged(self):
485     self.paramsFile=self.LE_ParamsFile.text()
486
487   def PBMeshSmeshPressed(self):
488     from omniORB import CORBA
489     import salome
490     from salome.kernel import studyedit
491     from salome.smesh.smeshstudytools import SMeshStudyTools
492     from salome.gui import helper as guihelper
493     from salome.smesh import smeshBuilder
494     smesh = smeshBuilder.New()
495
496     mySObject, myEntry = guihelper.getSObjectSelected()
497     if CORBA.is_nil(mySObject) or mySObject==None:
498       QMessageBox.critical(self, "Mesh", "select an input mesh")
499       #self.LE_MeshSmesh.setText("")
500       #self.MeshIn=""
501       #self.LE_MeshFile.setText("")
502       #self.fichierIn=""
503       return
504     self.smeshStudyTool = SMeshStudyTools()
505     try:
506       self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
507     except:
508       QMessageBox.critical(self, "Mesh", "select an input mesh")
509       return
510     if CORBA.is_nil(self.__selectedMesh):
511       QMessageBox.critical(self, "Mesh", "select an input mesh")
512       return
513     myName = mySObject.GetName()
514     #print "MeshSmeshNameChanged", myName
515     self.MeshIn=myName
516     self.LE_MeshSmesh.setText(myName)
517     self.LE_MeshFile.setText("")
518     self.fichierIn=""
519
520   def prepareFichier(self):
521     self.fichierIn=tempfile.mktemp(suffix=".mesh",prefix="ForMGCleaner_")
522     if os.path.exists(self.fichierIn):
523         os.remove(self.fichierIn)
524     self.__selectedMesh.ExportGMF(self.__selectedMesh, self.fichierIn, True)
525
526   def PrepareLigneCommande(self):
527     """
528     #use doc examples of mg-cleaner:
529     ls -al /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin
530     source /data/tmplgls/salome/prerequis/install/LICENSE/dlim8.var.sh
531     export PATH=/data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin/Linux_64:$PATH
532     cp -r /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/examples .
533     cd examples
534     mg-cleaner.exe --help
535     mg-cleaner.exe --in case7.mesh --out case7-test.mesh --check
536     mg-cleaner.exe case7.mesh case7-fix.mesh --fix
537     mg-cleaner.exe --in Porsche.mesh --out Porsche-test.mesh --check
538     mg-cleaner.exe --in Porsche.mesh --out Porschefix.mesh --fix
539     mg-cleaner.exe --in Porsche.mesh --out PorscheNewfix.mesh --fix --resolution_length 0.03
540     """
541     
542     #self.commande="mg-cleaner.exe --in " + self.fichierIn + " --out " + self.fichierOut + " --fix2pass" 
543     #return True
544     #print "PrepareLigneCommande '"+self.fichierIn+"' '"+self.MeshIn+"'",self.__selectedMesh
545     if self.fichierIn=="" and self.MeshIn=="":
546       QMessageBox.critical(self, "Mesh", "select an input mesh")
547       return False
548     if self.__selectedMesh!=None: self.prepareFichier()
549     if not (os.path.isfile(self.fichierIn)):
550       QMessageBox.critical(self, "File", "unable to read GMF Mesh in "+str(self.fichierIn))
551       return False
552     
553     self.commande="mg-cleaner.exe"
554     verbosity=str(self.SP_Verbosity.value())
555     self.commande+=" --verbose " + verbosity
556     self.commande+=' --in "' + self.fichierIn+'"'
557     deb=os.path.splitext(str(self.fichierIn))
558     self.fichierOut=deb[0] + "_fix.mesh"
559     self.commande+=' --out "'+self.fichierOut+'"'
560     if self.RB_Fix1.isChecked():
561       self.commande+=" --mode fix"
562     else:
563       self.commande+=" --mode check"
564     if self.CB_PreserveTopology.isChecked():
565       self.commande+=" --topology respect"
566     else:
567       self.commande+=" --topology ignore"
568     if self.CB_FillHoles.isChecked(): #no fill holes default
569       self.commande+=" --min_hole_size " + self.SP_toStr(self.SP_MinHoleSize)
570     if not self.CB_ComputedToleranceDisplacement.isChecked(): #computed default
571       self.commande+=" --tolerance_displacement " + self.SP_toStr(self.SP_ToleranceDisplacement)
572     if not self.CB_ComputedResolutionLength.isChecked(): #computed default
573       self.commande+=" --resolution_length " + self.SP_toStr(self.SP_ResolutionLength)
574     self.commande+=" --folding_angle " + str(self.SP_FoldingAngle.value())
575     if self.CB_RemeshPlanes.isChecked(): #no remesh default
576       self.commande+=" --remesh_planes yes"
577     if not self.CB_ComputedOverlapDistance.isChecked(): #computed default
578       self.commande+=" --overlap_distance " + self.SP_toStr(self.SP_OverlapDistance)
579     self.commande+=" --overlap_angle " + str(self.SP_OverlapAngle.value())
580     if verbose: print(("INFO: MGCCleaner command:\n  %s" % self.commande))
581     return True
582
583   def clean(self):
584     self.RB_Check.setChecked(False)
585     self.RB_Fix1.setChecked(True)
586     self.CB_PreserveTopology.setChecked(False)
587     self.CB_FillHoles.setChecked(False)
588     self.CB_RemeshPlanes.setChecked(False)
589     
590     self.SP_MinHoleSize.setProperty("text", 0)
591     self.SP_ToleranceDisplacement.setProperty("text", 0)
592     self.SP_ResolutionLength.setProperty("text", 0)
593     self.SP_FoldingAngle.setProperty("value", 15)
594     self.SP_OverlapDistance.setProperty("text", 0)
595     self.SP_OverlapAngle.setProperty("value", 15)
596     self.SP_Verbosity.setProperty("value", 3)
597     
598     self.CB_ComputedToleranceDisplacement.setChecked(True)
599     self.CB_ComputedResolutionLength.setChecked(True)
600     self.CB_ComputedOverlapDistance.setChecked(True)
601
602 __dialog=None
603 def getDialog():
604   """
605   This function returns a singleton instance of the plugin dialog.
606   It is mandatory in order to call show without a parent ...
607   """
608   global __dialog
609   if __dialog is None:
610     __dialog = MGCleanerMonPlugDialog()
611   #else :
612   #   __dialog.clean()
613   return __dialog
614
615
616 #
617 # ==============================================================================
618 # For memory
619 # ==============================================================================
620 #
621 def TEST_standalone():
622   """
623   works only if a salome is launched yet with a study loaded
624   to launch standalone python do:
625   ./APPLI/runSession
626   python
627   or (do not works)
628   python ./INSTALL/SMESH/share/salome/plugins/smesh/MGCleanerMonPlugDialog.py
629   """
630   import salome
631   import SMESH
632   from salome.kernel import studyedit
633   salome.salome_init()
634   maStudy=salome.myStudy
635   #etc...a mano...
636
637 #
638 # ==============================================================================
639 # Basic use cases and unit test functions
640 # ==============================================================================
641 #
642 def TEST_MGCleanerMonPlugDialog():
643   import sys
644   from qtsalome import QApplication
645   app = QApplication(sys.argv)
646   app.lastWindowClosed.connect(app.quit)
647
648   dlg=MGCleanerMonPlugDialog()
649   dlg.show()
650   sys.exit(app.exec_())
651
652 if __name__ == "__main__":
653   TEST_MGCleanerMonPlugDialog()
654   #TEST_standalone()
655   pass
656