1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 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.
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
25 from MGCleanerPlugDialog import Ui_MGCleanerPlugDialog
26 from MGCleanerMonViewText import MGCleanerMonViewText
27 from PyQt4.QtGui import *
28 from PyQt4.QtCore 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.connect(self.PB_Cancel,SIGNAL("clicked()"),self.PBCancelPressed)
109 self.connect(self.PB_Default,SIGNAL("clicked()"),self.clean)
110 self.connect(self.PB_Help,SIGNAL("clicked()"),self.PBHelpPressed)
111 self.connect(self.PB_OK,SIGNAL("clicked()"),self.PBOKPressed)
113 self.connect(self.PB_Load,SIGNAL("clicked()"),self.PBLoadPressed)
114 self.connect(self.PB_Save,SIGNAL("clicked()"),self.PBSavePressed)
115 self.connect(self.PB_LoadHyp,SIGNAL("clicked()"),self.PBLoadHypPressed)
116 self.connect(self.PB_SaveHyp,SIGNAL("clicked()"),self.PBSaveHypPressed)
118 self.connect(self.PB_MeshFile,SIGNAL("clicked()"),self.PBMeshFilePressed)
119 self.connect(self.PB_MeshSmesh,SIGNAL("clicked()"),self.PBMeshSmeshPressed)
120 self.connect(self.LE_MeshSmesh,SIGNAL("returnPressed()"),self.meshSmeshNameChanged)
121 self.connect(self.PB_ParamsFileExplorer,SIGNAL("clicked()"),self.setParamsFileName)
122 self.connect(self.LE_MeshFile,SIGNAL("returnPressed()"),self.meshFileNameChanged)
123 self.connect(self.LE_ParamsFile,SIGNAL("returnPressed()"),self.paramsFileNameChanged)
125 #QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL("stateChanged(int)"), self.change)
126 self.connect(self.CB_FillHoles,SIGNAL("stateChanged(int)"),self.SP_MinHoleSize.setEnabled)
127 self.connect(self.CB_ComputedToleranceDisplacement,SIGNAL("stateChanged(int)"),self.SP_ToleranceDisplacement.setDisabled)
128 self.connect(self.CB_ComputedResolutionLength,SIGNAL("stateChanged(int)"),self.SP_ResolutionLength.setDisabled)
129 self.connect(self.CB_ComputedOverlapDistance,SIGNAL("stateChanged(int)"),self.SP_OverlapDistance.setDisabled)
131 def PBHelpPressed(self):
133 mydir=os.environ["SMESH_ROOT_DIR"]
135 QMessageBox.warning( self, "Help", "Help unavailable $SMESH_ROOT_DIR not found")
137 maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf"
138 command="xdg-open "+maDoc+";"
139 subprocess.call(command, shell=True)
141 def PBOKPressed(self):
142 if not(self.PrepareLigneCommande()):
144 #QMessageBox.warning(self, "Compute", "Command not found")
146 maFenetre=MGCleanerMonViewText(self, self.commande)
148 def enregistreResultat(self):
151 from salome.kernel import studyedit
152 from salome.smesh import smeshBuilder
153 smesh = smeshBuilder.New(salome.myStudy)
155 if not os.path.isfile(self.fichierOut):
156 QMessageBox.warning(self, "Compute", "Result file "+self.fichierOut+" not found")
158 maStudy=studyedit.getActiveStudy()
159 smesh.SetCurrentStudy(maStudy)
160 (outputMesh, status) = smesh.CreateMeshesFromGMF(self.fichierOut)
161 name=str(self.LE_MeshSmesh.text())
163 initialMeshObject=None
165 a=str(self.fichierIn)
166 name=os.path.basename(os.path.splitext(a)[0])
169 initialMeshObject=maStudy.FindObjectByName(name ,"SMESH")[0]
171 meshname = name+"_MGC_"+str(self.num)
172 smesh.SetName(outputMesh.GetMesh(), meshname)
173 outputMesh.Compute() #no algorithms message for "Mesh_x" has been computed with warnings: - global 1D algorithm is missing
175 self.editor = studyedit.getStudyEditor()
176 moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
177 HypReMeshEntry = self.editor.findOrCreateItem(
178 moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" )
180 monStudyBuilder=maStudy.NewBuilder()
181 monStudyBuilder.NewCommand()
182 newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
183 self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num))
184 self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; "))
186 SOMesh=maStudy.FindObjectByName(meshname ,"SMESH")[0]
188 if initialMeshFile!=None:
189 newStudyFileName=monStudyBuilder.NewObject(SOMesh)
190 self.editor.setAttributeValue(newStudyFileName, "AttributeName", "meshFile")
191 self.editor.setAttributeValue(newStudyFileName, "AttributeExternalFileDef", initialMeshFile)
192 self.editor.setAttributeValue(newStudyFileName, "AttributeComment", initialMeshFile)
194 if initialMeshObject!=None:
195 newLink=monStudyBuilder.NewObject(SOMesh)
196 monStudyBuilder.Addreference(newLink, initialMeshObject)
198 newLink=monStudyBuilder.NewObject(SOMesh)
199 monStudyBuilder.Addreference(newLink, newStudyIter)
201 if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
205 def PBSavePressed(self):
206 from datetime import datetime
207 if not(self.PrepareLigneCommande()): return
208 text = "# MGCleaner hypothesis parameters\n"
209 text += "# Params for mesh : " + self.LE_MeshSmesh.text() +"\n"
210 text += datetime.now().strftime("# Date : %d/%m/%y %H:%M:%S\n")
211 text += "# Command : "+self.commande+"\n"
212 text += self.getResumeData(separator="\n")
216 f=open(self.paramsFile,"a")
218 QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
223 QMessageBox.warning(self, "File", "Unable to write "+self.paramsFile)
227 def PBSaveHypPressed(self):
228 """save hypothesis in Object Browser"""
231 from salome.kernel import studyedit
232 from salome.smesh import smeshBuilder
233 smesh = smeshBuilder.New(salome.myStudy)
235 maStudy=studyedit.getActiveStudy()
236 smesh.SetCurrentStudy(maStudy)
238 self.editor = studyedit.getStudyEditor()
239 moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
240 HypReMeshEntry = self.editor.findOrCreateItem(
241 moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" )
243 monStudyBuilder=maStudy.NewBuilder()
244 monStudyBuilder.NewCommand()
245 newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
246 self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num))
247 self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; "))
249 if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
254 import salome_pluginsmanager
255 print "salome_pluginsmanager.plugins",salome_pluginsmanager.plugins
256 print "salome_pluginsmanager.current_plugins_manager",salome_pluginsmanager.current_plugins_manager
259 def SP_toStr(self, widget):
260 """only for a QLineEdit widget"""
261 #cr, pos=widget.validator().validate(res, 0) #n.b. "1,3" is acceptable !locale!
263 val=float(widget.text())
265 QMessageBox.warning(self, widget.titleForWarning, "float value is incorrect: '"+widget.text()+"'")
266 res=str(widget.validator().bottom())
267 widget.setProperty("text", res)
269 valtest=widget.validator().bottom()
272 QMessageBox.warning(self, widget.titleForWarning, "float value is under minimum: "+str(val)+" < "+str(valtest))
274 widget.setProperty("text", res)
276 valtest=widget.validator().top()
279 QMessageBox.warning(self, widget.titleForWarning, "float value is over maximum: "+str(val)+" > "+str(valtest))
281 widget.setProperty("text", res)
285 def getResumeData(self, separator="\n"):
287 if self.RB_Fix1.isChecked():
288 CheckOrFix="fix1pass"
290 if self.RB_Fix2.isChecked():
291 CheckOrFix="fix2pass"
294 text+="CheckOrFix="+CheckOrFix+separator
295 text+="PreserveTopology="+str(self.CB_PreserveTopology.isChecked())+separator
296 text+="FillHoles="+str(self.CB_FillHoles.isChecked())+separator
297 v=self.SP_toStr(self.SP_MinHoleSize)
298 text+="MinHoleSize="+v+separator
299 text+="ComputedToleranceDisplacement="+str(self.CB_ComputedToleranceDisplacement.isChecked())+separator
300 v=self.SP_toStr(self.SP_ToleranceDisplacement)
301 text+="ToleranceDisplacement="+v+separator
302 text+="ComputedResolutionLength="+str(self.CB_ComputedResolutionLength.isChecked())+separator
303 v=self.SP_toStr(self.SP_ResolutionLength)
304 text+="ResolutionLength="+v+separator
305 text+="FoldingAngle="+str(self.SP_FoldingAngle.value())+separator
306 text+="RemeshPlanes="+str(self.CB_RemeshPlanes.isChecked())+separator
307 text+="ComputedOverlapDistance="+str(self.CB_ComputedOverlapDistance.isChecked())+separator
308 v=self.SP_toStr(self.SP_OverlapDistance)
309 text+="OverlapDistance="+v+separator
310 text+="OverlapAngle="+str(self.SP_OverlapAngle.value())+separator
311 text+="Verbosity="+str(self.SP_Verbosity.value())+separator
314 def loadResumeData(self, hypothesis, separator="\n"):
317 for slig in reversed(text.split(separator)):
319 #print "load ResumeData",lig
320 if lig=="": continue #skip blanck lines
321 if lig[0]=="#": break
323 tit,value=lig.split("=")
324 if tit=="CheckOrFix":
325 self.RB_Fix1.setChecked(False)
326 self.RB_Fix2.setChecked(False)
327 self.RB_Check.setChecked(False)
328 if value=="fix1pass": self.RB_Fix1.setChecked(True)
329 if value=="fix2pass": self.RB_Fix2.setChecked(True)
330 if value=="check": self.RB_Check.setChecked(True)
331 if tit=="PreserveTopology": self.CB_PreserveTopology.setChecked(value=="True")
332 if tit=="FillHoles": self.CB_FillHoles.setChecked(value=="True")
333 if tit=="MinHoleSize": self.SP_MinHoleSize.setProperty("text", value)
334 if tit=="ComputedToleranceDisplacement": self.CB_ComputedToleranceDisplacement.setChecked(value=="True")
335 if tit=="ToleranceDisplacement": self.SP_ToleranceDisplacement.setProperty("text", value)
336 if tit=="ComputedResolutionLength": self.CB_ComputedResolutionLength.setChecked(value=="True")
337 if tit=="ResolutionLength": self.SP_ResolutionLength.setProperty("text", value)
338 if tit=="FoldingAngle": self.SP_FoldingAngle.setProperty("value", float(value))
339 if tit=="RemeshPlanes": self.CB_RemeshPlanes.setChecked(value=="True")
340 if tit=="ComputedOverlapDistance": self.CB_ComputedOverlapDistance.setChecked(value=="True")
341 if tit=="OverlapDistance": self.SP_OverlapDistance.setProperty("text", value)
342 if tit=="OverlapAngle": self.SP_OverlapAngle.setProperty("value", float(value))
343 if tit=="Verbosity": self.SP_Verbosity.setProperty("value", int(float(value)))
345 QMessageBox.warning(self, "load MGCleaner Hypothesis", "Problem on '"+lig+"'")
347 def PBLoadPressed(self):
348 """load last hypothesis saved in tail of file"""
350 f=open(self.paramsFile,"r")
352 QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
357 QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile)
360 self.loadResumeData(text, separator="\n")
362 def PBLoadHypPressed(self):
363 """load hypothesis saved in Object Browser"""
364 #QMessageBox.warning(self, "load Object Browser MGCleaner hypothesis", "TODO")
366 from salome.kernel import studyedit
367 from salome.smesh.smeshstudytools import SMeshStudyTools
368 from salome.gui import helper as guihelper
369 from omniORB import CORBA
371 mySObject, myEntry = guihelper.getSObjectSelected()
372 if CORBA.is_nil(mySObject) or mySObject==None:
373 QMessageBox.critical(self, "Hypothese", "select an Object Browser MGCleaner hypothesis")
376 #for i in dir(mySObject): print "dir mySObject",i
377 #print "GetAllAttributes",mySObject.GetAllAttributes()
378 #print "GetComment",mySObject.GetComment()
379 #print "GetName",mySObject.GetName()
382 #if mySObject.GetFather().GetName()!="MGCleaner Hypotheses":
383 # QMessageBox.critical(self, "Hypothese", "not a child of MGCleaner Hypotheses")
386 text=mySObject.GetComment()
389 if "CheckOrFix=" not in text:
390 QMessageBox.critical(self, "Load Hypothese", "Object Browser selection not a MGCleaner Hypothesis")
392 self.loadResumeData(text, separator=" ; ")
395 def PBCancelPressed(self):
398 def PBMeshFilePressed(self):
399 fd = QFileDialog(self, "select an existing Mesh file", self.LE_MeshFile.text(), "Mesh-Files (*.mesh);;All Files (*)")
401 infile = fd.selectedFiles()[0]
402 self.LE_MeshFile.setText(infile)
403 self.fichierIn=infile.toLatin1()
405 self.LE_MeshSmesh.setText("")
407 def setParamsFileName(self):
408 fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)")
410 infile = fd.selectedFiles()[0]
411 self.LE_ParamsFile.setText(infile)
412 self.paramsFile=infile.toLatin1()
414 def meshFileNameChanged(self):
415 self.fichierIn=str(self.LE_MeshFile.text())
416 #print "meshFileNameChanged", self.fichierIn
417 if os.path.exists(self.fichierIn):
418 self.__selectedMesh=None
420 self.LE_MeshSmesh.setText("")
422 QMessageBox.warning(self, "Mesh file", "File doesn't exist")
424 def meshSmeshNameChanged(self):
425 """only change by GUI mouse selection, otherwise clear"""
426 #self.MeshIn=str(self.LE_MeshSmesh.text())
427 #print "meshSmeshNameChanged", self.MeshIn
428 self.__selectedMesh = None
430 self.LE_MeshSmesh.setText("")
434 def paramsFileNameChanged(self):
435 self.paramsFile=self.LE_ParamsFile.text()
437 def PBMeshSmeshPressed(self):
438 from omniORB import CORBA
440 from salome.kernel import studyedit
441 from salome.smesh.smeshstudytools import SMeshStudyTools
442 from salome.gui import helper as guihelper
443 from salome.smesh import smeshBuilder
444 smesh = smeshBuilder.New(salome.myStudy)
446 mySObject, myEntry = guihelper.getSObjectSelected()
447 if CORBA.is_nil(mySObject) or mySObject==None:
448 QMessageBox.critical(self, "Mesh", "select an input mesh")
450 self.smeshStudyTool = SMeshStudyTools()
452 self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
454 QMessageBox.critical(self, "Mesh", "select an input mesh")
456 if CORBA.is_nil(self.__selectedMesh):
457 QMessageBox.critical(self, "Mesh", "select an input mesh")
459 myName = mySObject.GetName()
460 #print "MeshSmeshNameChanged", myName
462 self.LE_MeshSmesh.setText(myName)
463 self.LE_MeshFile.setText("")
466 def prepareFichier(self):
467 self.fichierIn="/tmp/ForMGCleaner_"+str(self.num)+".mesh"
468 self.__selectedMesh.ExportGMF(self.__selectedMesh, self.fichierIn, True)
470 def PrepareLigneCommande(self):
472 #use doc examples of mg-cleaner:
473 ls -al /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin
474 source /data/tmplgls/salome/prerequis/install/LICENSE/dlim8.var.sh
475 export PATH=/data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin/Linux_64:$PATH
476 cp -r /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/examples .
478 mg-cleaner.exe --help
479 mg-cleaner.exe --in case7.mesh --out case7-test.mesh --check
480 mg-cleaner.exe case7.mesh case7-fix.mesh --fix
481 mg-cleaner.exe --in Porsche.mesh --out Porsche-test.mesh --check
482 mg-cleaner.exe --in Porsche.mesh --out Porschefix.mesh --fix
483 mg-cleaner.exe --in Porsche.mesh --out PorscheNewfix.mesh --fix --resolution_length 0.03
486 #self.commande="mg-cleaner.exe --in " + self.fichierIn + " --out " + self.fichierOut + " --fix2pass"
488 #print "PrepareLigneCommande '"+self.fichierIn+"' '"+self.MeshIn+"'",self.__selectedMesh
489 if self.fichierIn=="" and self.MeshIn=="":
490 QMessageBox.critical(self, "Mesh", "select an input mesh")
492 if self.__selectedMesh!=None: self.prepareFichier()
493 if not (os.path.isfile(self.fichierIn)):
494 QMessageBox.critical(self, "File", "unable to read GMF Mesh in "+str(self.fichierIn))
497 self.commande="mg-cleaner.exe"
498 verbosity=str(self.SP_Verbosity.value())
499 self.commande+=" --verbose " + verbosity
500 self.commande+=" --in " + self.fichierIn
501 #print "self.fichierIn",self.fichierIn,type(self.fichierIn)
502 deb=os.path.splitext(str(self.fichierIn))
503 self.fichierOut=deb[0] + "_fix.mesh"
504 self.commande+=" --out "+self.fichierOut
505 if self.RB_Fix1.isChecked():
506 self.commande+=" --fix1pass"
508 if self.RB_Fix2.isChecked():
509 self.commande+=" --fix2pass"
511 self.commande+=" --check"
512 if self.CB_PreserveTopology.isChecked():
513 self.commande+=" --topology respect"
515 self.commande+=" --topology ignore"
516 if self.CB_FillHoles.isChecked(): #no fill holes default
517 self.commande+=" --min_hole_size " + self.SP_toStr(self.SP_MinHoleSize)
518 if not self.CB_ComputedToleranceDisplacement.isChecked(): #computed default
519 self.commande+=" --tolerance_displacement " + self.SP_toStr(self.SP_ToleranceDisplacement)
520 if not self.CB_ComputedResolutionLength.isChecked(): #computed default
521 self.commande+=" --resolution_length " + self.SP_toStr(self.SP_ResolutionLength)
522 self.commande+=" --folding_angle " + str(self.SP_FoldingAngle.value())
523 if self.CB_RemeshPlanes.isChecked(): #no remesh default
524 self.commande+=" --remesh_planes"
525 if not self.CB_ComputedOverlapDistance.isChecked(): #computed default
526 self.commande+=" --overlap_distance " + self.SP_toStr(self.SP_OverlapDistance)
527 self.commande+=" --overlap_angle " + str(self.SP_OverlapAngle.value())
531 self.RB_Check.setChecked(False)
532 self.RB_Fix1.setChecked(False)
533 self.RB_Fix2.setChecked(True)
534 self.CB_PreserveTopology.setChecked(False)
535 self.CB_FillHoles.setChecked(False)
536 self.CB_RemeshPlanes.setChecked(False)
538 self.SP_MinHoleSize.setProperty("text", 0)
539 self.SP_ToleranceDisplacement.setProperty("text", 0)
540 self.SP_ResolutionLength.setProperty("text", 0)
541 self.SP_FoldingAngle.setProperty("value", 15)
542 self.SP_OverlapDistance.setProperty("text", 0)
543 self.SP_OverlapAngle.setProperty("value", 15)
544 self.SP_Verbosity.setProperty("value", 3)
546 self.CB_ComputedToleranceDisplacement.setChecked(True)
547 self.CB_ComputedResolutionLength.setChecked(True)
548 self.CB_ComputedOverlapDistance.setChecked(True)
553 This function returns a singleton instance of the plugin dialog.
554 c est obligatoire pour faire un show sans parent...
558 __dialog = MGCleanerMonPlugDialog()
565 # ==============================================================================
567 # ==============================================================================
569 def TEST_standalone():
571 works only if a salome is launched yet with a study loaded
572 to launch standalone python do:
576 python ./INSTALL/SMESH/share/salome/plugins/smesh/MGCleanerMonPlugDialog.py
580 from salome.kernel import studyedit
582 maStudy=studyedit.getActiveStudy()
586 # ==============================================================================
587 # Basic use cases and unit test functions
588 # ==============================================================================
590 def TEST_MGCleanerMonPlugDialog():
592 from PyQt4.QtGui import QApplication
593 from PyQt4.QtCore import QObject, SIGNAL, SLOT
594 app = QApplication(sys.argv)
595 QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
597 dlg=MGCleanerMonPlugDialog()
599 sys.exit(app.exec_())
601 if __name__ == "__main__":
602 TEST_MGCleanerMonPlugDialog()