1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2013-2016 EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
26 from MGCleanerPlugDialog_ui import Ui_MGCleanerPlugDialog
27 from MGCleanerMonViewText import MGCleanerMonViewText
28 from qtsalome import *
31 class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget):
35 QWidget.__init__(self)
37 self.connecterSignaux()
43 self.__selectedMesh=None
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__))
50 self.iconfolder=os.environ["SMESH_ROOT_DIR"]+"/share/salome/resources/smesh"
51 #print "MGCleanerMonPlugDialog iconfolder",iconfolder
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")
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")
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("")
76 v1=QDoubleValidator(self)
80 self.SP_MinHoleSize.setValidator(v1)
81 self.SP_MinHoleSize.titleForWarning="MinHoleSize"
83 v2=QDoubleValidator(self)
87 self.SP_ToleranceDisplacement.setValidator(v2)
88 self.SP_ToleranceDisplacement.titleForWarning="ToleranceDisplacement"
90 v3=QDoubleValidator(self)
94 self.SP_ResolutionLength.setValidator(v3)
95 self.SP_ResolutionLength.titleForWarning="ResolutionLength"
97 v4=QDoubleValidator(self)
101 self.SP_OverlapDistance.setValidator(v4)
102 self.SP_OverlapDistance.titleForWarning="OverlapDistance"
104 self.resize(800, 500)
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)
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)
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)
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)
131 def PBHelpPressed(self):
133 sgPyQt = SalomePyQt.SalomePyQt()
135 mydir=os.environ["SMESH_ROOT_DIR"]
137 QMessageBox.warning( self, "Help", "Help unavailable $SMESH_ROOT_DIR not found")
140 maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/index.html"
141 sgPyQt.helpContext(maDoc,"")
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)
147 def PBOKPressed(self):
148 if not(self.PrepareLigneCommande()):
150 #QMessageBox.warning(self, "Compute", "Command not found")
152 maFenetre=MGCleanerMonViewText(self, self.commande)
154 def enregistreResultat(self):
157 from salome.kernel import studyedit
158 from salome.smesh import smeshBuilder
159 smesh = smeshBuilder.New(salome.myStudy)
161 if not os.path.isfile(self.fichierOut):
162 QMessageBox.warning(self, "Compute", "Result file "+self.fichierOut+" not found")
164 maStudy=studyedit.getActiveStudy()
165 smesh.SetCurrentStudy(maStudy)
166 (outputMesh, status) = smesh.CreateMeshesFromGMF(self.fichierOut)
167 name=str(self.LE_MeshSmesh.text())
169 initialMeshObject=None
171 a=str(self.fichierIn)
172 name=os.path.basename(os.path.splitext(a)[0])
175 initialMeshObject=maStudy.FindObjectByName(name ,"SMESH")[0]
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
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" )
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=" ; "))
192 SOMesh=maStudy.FindObjectByName(meshname ,"SMESH")[0]
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)
200 if initialMeshObject!=None:
201 newLink=monStudyBuilder.NewObject(SOMesh)
202 monStudyBuilder.Addreference(newLink, initialMeshObject)
204 newLink=monStudyBuilder.NewObject(SOMesh)
205 monStudyBuilder.Addreference(newLink, newStudyIter)
207 if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
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")
222 f=open(self.paramsFile,"a")
224 QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
229 QMessageBox.warning(self, "File", "Unable to write "+self.paramsFile)
233 def PBSaveHypPressed(self):
234 """save hypothesis in Object Browser"""
237 from salome.kernel import studyedit
238 from salome.smesh import smeshBuilder
239 smesh = smeshBuilder.New(salome.myStudy)
241 maStudy=studyedit.getActiveStudy()
242 smesh.SetCurrentStudy(maStudy)
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" )
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=" ; "))
255 if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
260 import salome_pluginsmanager
261 print "salome_pluginsmanager.plugins",salome_pluginsmanager.plugins
262 print "salome_pluginsmanager.current_plugins_manager",salome_pluginsmanager.current_plugins_manager
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!
269 val=float(widget.text())
271 QMessageBox.warning(self, widget.titleForWarning, "float value is incorrect: '"+widget.text()+"'")
272 res=str(widget.validator().bottom())
273 widget.setProperty("text", res)
275 valtest=widget.validator().bottom()
278 QMessageBox.warning(self, widget.titleForWarning, "float value is under minimum: "+str(val)+" < "+str(valtest))
280 widget.setProperty("text", res)
282 valtest=widget.validator().top()
285 QMessageBox.warning(self, widget.titleForWarning, "float value is over maximum: "+str(val)+" > "+str(valtest))
287 widget.setProperty("text", res)
291 def getResumeData(self, separator="\n"):
293 if self.RB_Fix1.isChecked():
294 CheckOrFix="fix1pass"
296 if self.RB_Fix2.isChecked():
297 CheckOrFix="fix2pass"
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
320 def loadResumeData(self, hypothesis, separator="\n"):
323 for slig in reversed(text.split(separator)):
325 #print "load ResumeData",lig
326 if lig=="": continue #skip blanck lines
327 if lig[0]=="#": break
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)))
351 QMessageBox.warning(self, "load MGCleaner Hypothesis", "Problem on '"+lig+"'")
353 def PBLoadPressed(self):
354 """load last hypothesis saved in tail of file"""
356 f=open(self.paramsFile,"r")
358 QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
363 QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile)
366 self.loadResumeData(text, separator="\n")
368 def PBLoadHypPressed(self):
369 """load hypothesis saved in Object Browser"""
370 #QMessageBox.warning(self, "load Object Browser MGCleaner hypothesis", "TODO")
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
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")
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()
388 #if mySObject.GetFather().GetName()!="MGCleaner Hypotheses":
389 # QMessageBox.critical(self, "Hypothese", "not a child of MGCleaner Hypotheses")
392 text=mySObject.GetComment()
395 if "CheckOrFix=" not in text:
396 QMessageBox.critical(self, "Load Hypothese", "Object Browser selection not a MGCleaner Hypothesis")
398 self.loadResumeData(text, separator=" ; ")
401 def PBCancelPressed(self):
404 def PBMeshFilePressed(self):
405 fd = QFileDialog(self, "select an existing Mesh file", self.LE_MeshFile.text(), "Mesh-Files (*.mesh);;All Files (*)")
407 infile = fd.selectedFiles()[0]
408 self.LE_MeshFile.setText(infile)
409 self.fichierIn=unicode(infile).encode("latin-1")
411 self.LE_MeshSmesh.setText("")
413 def setParamsFileName(self):
414 fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)")
416 infile = fd.selectedFiles()[0]
417 self.LE_ParamsFile.setText(infile)
418 self.paramsFile=unicode(infile).encode("latin-1")
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
426 self.LE_MeshSmesh.setText("")
428 QMessageBox.warning(self, "Mesh file", "File doesn't exist")
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
436 self.LE_MeshSmesh.setText("")
440 def paramsFileNameChanged(self):
441 self.paramsFile=self.LE_ParamsFile.text()
443 def PBMeshSmeshPressed(self):
444 from omniORB import CORBA
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)
452 mySObject, myEntry = guihelper.getSObjectSelected()
453 if CORBA.is_nil(mySObject) or mySObject==None:
454 QMessageBox.critical(self, "Mesh", "select an input mesh")
456 self.smeshStudyTool = SMeshStudyTools()
458 self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
460 QMessageBox.critical(self, "Mesh", "select an input mesh")
462 if CORBA.is_nil(self.__selectedMesh):
463 QMessageBox.critical(self, "Mesh", "select an input mesh")
465 myName = mySObject.GetName()
466 #print "MeshSmeshNameChanged", myName
468 self.LE_MeshSmesh.setText(myName)
469 self.LE_MeshFile.setText("")
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)
478 def PrepareLigneCommande(self):
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 .
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
494 #self.commande="mg-cleaner.exe --in " + self.fichierIn + " --out " + self.fichierOut + " --fix2pass"
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")
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))
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"
516 if self.RB_Fix2.isChecked():
517 self.commande+=" --fix2pass"
519 self.commande+=" --check"
520 if self.CB_PreserveTopology.isChecked():
521 self.commande+=" --topology respect"
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())
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)
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)
554 self.CB_ComputedToleranceDisplacement.setChecked(True)
555 self.CB_ComputedResolutionLength.setChecked(True)
556 self.CB_ComputedOverlapDistance.setChecked(True)
561 This function returns a singleton instance of the plugin dialog.
562 c est obligatoire pour faire un show sans parent...
566 __dialog = MGCleanerMonPlugDialog()
573 # ==============================================================================
575 # ==============================================================================
577 def TEST_standalone():
579 works only if a salome is launched yet with a study loaded
580 to launch standalone python do:
584 python ./INSTALL/SMESH/share/salome/plugins/smesh/MGCleanerMonPlugDialog.py
588 from salome.kernel import studyedit
590 maStudy=studyedit.getActiveStudy()
594 # ==============================================================================
595 # Basic use cases and unit test functions
596 # ==============================================================================
598 def TEST_MGCleanerMonPlugDialog():
600 from qtsalome import QApplication
601 app = QApplication(sys.argv)
602 app.lastWindowClosed.connect(app.quit)
604 dlg=MGCleanerMonPlugDialog()
606 sys.exit(app.exec_())
608 if __name__ == "__main__":
609 TEST_MGCleanerMonPlugDialog()