add SMESH plugin MGCleaner

This commit is contained in:
cvw 2013-06-13 13:38:35 +00:00
parent 25008e4a96
commit 02df1b69aa
18 changed files with 2708 additions and 13 deletions

View File

@ -578,6 +578,9 @@ AC_OUTPUT([ \
src/Tools/YamsPlug/Makefile \ src/Tools/YamsPlug/Makefile \
src/Tools/YamsPlug/doc/Makefile \ src/Tools/YamsPlug/doc/Makefile \
src/Tools/YamsPlug/doc/conf.py \ src/Tools/YamsPlug/doc/conf.py \
src/Tools/MGCleanerPlug/Makefile \
src/Tools/MGCleanerPlug/doc/Makefile \
src/Tools/MGCleanerPlug/doc/conf.py \
src/Tools/padder/Makefile \ src/Tools/padder/Makefile \
src/Tools/padder/meshjob/Makefile \ src/Tools/padder/meshjob/Makefile \
src/Tools/padder/meshjob/idl/Makefile \ src/Tools/padder/meshjob/idl/Makefile \

View File

@ -156,7 +156,8 @@ dist_salomeres_DATA = \
mesh_sew_sideelements.png \ mesh_sew_sideelements.png \
mesh_merge_nodes.png \ mesh_merge_nodes.png \
mesh_merge_elements.png \ mesh_merge_elements.png \
select1.png \ select1.png \
open.png \
StdMeshers.xml \ StdMeshers.xml \
mesh_pattern.png \ mesh_pattern.png \
mesh_pentahedron.png \ mesh_pentahedron.png \
@ -193,10 +194,10 @@ dist_salomeres_DATA = \
mesh_tree_mesh_partial.png \ mesh_tree_mesh_partial.png \
mesh_extractGroup.png \ mesh_extractGroup.png \
mesh_precompute.png \ mesh_precompute.png \
mesh_2d_from_3d.png \ mesh_2d_from_3d.png \
mesh_free_faces.png \ mesh_free_faces.png \
scale.png \ scale.png \
scale_along_axes.png \ scale_along_axes.png \
split_into_tetra.png \ split_into_tetra.png \
mesh_duplicate_nodes.png \ mesh_duplicate_nodes.png \
mesh_duplicate_nodes_with_elem.png \ mesh_duplicate_nodes_with_elem.png \

View File

@ -113,6 +113,7 @@
<parameter name="sub_menu" value="%1 module"/> <parameter name="sub_menu" value="%1 module"/>
<parameter name="User's Guide" value="%SMESH_ROOT_DIR%/share/doc/salome/gui/SMESH/index.html"/> <parameter name="User's Guide" value="%SMESH_ROOT_DIR%/share/doc/salome/gui/SMESH/index.html"/>
<parameter name="Plug-ins/Yams plugin User's Guide" value="%SMESH_ROOT_DIR%/share/doc/salome/gui/SMESH/yams/index.html"/> <parameter name="Plug-ins/Yams plugin User's Guide" value="%SMESH_ROOT_DIR%/share/doc/salome/gui/SMESH/yams/index.html"/>
<parameter name="Plug-ins/MGCleaner plugin User's Guide" value="%SMESH_ROOT_DIR%/share/doc/salome/gui/SMESH/MGCleaner/index.html"/>
<parameter name="Developer's Guide" value="%SMESH_ROOT_DIR%/share/doc/salome/tui/SMESH/index.html"/> <parameter name="Developer's Guide" value="%SMESH_ROOT_DIR%/share/doc/salome/tui/SMESH/index.html"/>
</section> </section>
<section name="resources"> <section name="resources">

BIN
resources/open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -51,7 +51,7 @@
<source>ICON_CONNECTION_2D</source> <source>ICON_CONNECTION_2D</source>
<translation>mesh_multi_edges_2d.png</translation> <translation>mesh_multi_edges_2d.png</translation>
</message> </message>
<message> <message>
<source>ICON_CREATE_GROUP</source> <source>ICON_CREATE_GROUP</source>
<translation>mesh_group.png</translation> <translation>mesh_group.png</translation>
</message> </message>
@ -271,11 +271,11 @@
<source>ICON_FREE_EDGE</source> <source>ICON_FREE_EDGE</source>
<translation>mesh_free_edges.png</translation> <translation>mesh_free_edges.png</translation>
</message> </message>
<message> <message>
<source>ICON_FREE_EDGE_2D</source> <source>ICON_FREE_EDGE_2D</source>
<translation>mesh_free_edges_2d.png</translation> <translation>mesh_free_edges_2d.png</translation>
</message> </message>
<message> <message>
<source>ICON_FREE_NODE</source> <source>ICON_FREE_NODE</source>
<translation>mesh_free_nodes.png</translation> <translation>mesh_free_nodes.png</translation>
</message> </message>
@ -427,15 +427,15 @@
<source>ICON_REORIENT_2D</source> <source>ICON_REORIENT_2D</source>
<translation>reorient_faces_face.png</translation> <translation>reorient_faces_face.png</translation>
</message> </message>
<message> <message>
<source>ICON_SMESH_DUPLICATE_NODES</source> <source>ICON_SMESH_DUPLICATE_NODES</source>
<translation>mesh_duplicate_nodes.png</translation> <translation>mesh_duplicate_nodes.png</translation>
</message> </message>
<message> <message>
<source>ICON_SMESH_DUPLICATE_NODES_WITH_ELEM</source> <source>ICON_SMESH_DUPLICATE_NODES_WITH_ELEM</source>
<translation>mesh_duplicate_nodes_with_elem.png</translation> <translation>mesh_duplicate_nodes_with_elem.png</translation>
</message> </message>
<message> <message>
<source>ICON_SMESH_DUPLICATE_ELEM_ONLY</source> <source>ICON_SMESH_DUPLICATE_ELEM_ONLY</source>
<translation>mesh_duplicate_elem_only.png</translation> <translation>mesh_duplicate_elem_only.png</translation>
</message> </message>

View File

@ -0,0 +1,585 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2007-2013 EDF R&D
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
# Modules Python
# Modules Eficas
import os, subprocess
from MGCleanerPlugDialog import Ui_MGCleanerPlugDialog
from MGCleanerMonViewText import MGCleanerMonViewText
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget):
"""
"""
def __init__(self):
QWidget.__init__(self)
self.setupUi(self)
self.connecterSignaux()
self.fichierIn=""
self.fichierOut=""
self.MeshIn=""
self.commande=""
self.num=1
self.__selectedMesh=None
# complex whith QResources: not used
# The icon are supposed to be located in the $SMESH_ROOT_DIR/share/salome/resources/smesh folder,
# other solution could be in the same folder than this python module file:
# iconfolder=os.path.dirname(os.path.abspath(__file__))
self.iconfolder=os.environ["SMESH_ROOT_DIR"]+"/share/salome/resources/smesh"
#print "MGCleanerMonPlugDialog iconfolder",iconfolder
icon = QIcon()
icon.addFile(os.path.join(self.iconfolder,"select1.png"))
self.PB_LoadHyp.setIcon(icon)
self.PB_LoadHyp.setToolTip("hypothesis from Salome Object Browser")
self.PB_SaveHyp.setIcon(icon)
self.PB_SaveHyp.setToolTip("hypothesis to Salome Object Browser")
self.PB_MeshSmesh.setIcon(icon)
self.PB_MeshSmesh.setToolTip("source mesh from Salome Object Browser")
icon = QIcon()
icon.addFile(os.path.join(self.iconfolder,"open.png"))
self.PB_ParamsFileExplorer.setIcon(icon)
self.PB_Load.setIcon(icon)
self.PB_Load.setToolTip("hypothesis from file")
self.PB_Save.setIcon(icon)
self.PB_Save.setToolTip("hypothesis to file")
self.PB_MeshFile.setIcon(icon)
self.PB_MeshFile.setToolTip("source mesh from a file in disk")
#Ces parametres ne sont pas remis à rien par le clean
self.paramsFile= os.path.abspath(os.path.join(os.environ["HOME"],".MGCleaner.dat"))
self.LE_ParamsFile.setText(self.paramsFile)
self.LE_MeshFile.setText("")
self.LE_MeshSmesh.setText("")
v1=QDoubleValidator(self)
v1.setBottom(0.)
#v1.setTop(10000.)
v1.setDecimals(4)
self.SP_MinHoleSize.setValidator(v1)
v2=QDoubleValidator(self)
v2.setBottom(0.)
#v2.setTop(10000.)
v2.setDecimals(4)
self.SP_ToleranceDisplacement.setValidator(v2)
v3=QDoubleValidator(self)
v3.setBottom(0.)
#v3.setTop(10000.)
v3.setDecimals(4)
self.SP_ResolutionLength.setValidator(v3)
v4=QDoubleValidator(self)
v4.setBottom(0.)
#v4.setTop(10000.)
v4.setDecimals(4)
self.SP_OverlapDistance.setValidator(v4)
self.resize(800, 500)
self.clean()
def connecterSignaux(self) :
self.connect(self.PB_Cancel,SIGNAL("clicked()"),self.PBCancelPressed)
self.connect(self.PB_Default,SIGNAL("clicked()"),self.clean)
self.connect(self.PB_Help,SIGNAL("clicked()"),self.PBHelpPressed)
self.connect(self.PB_OK,SIGNAL("clicked()"),self.PBOKPressed)
self.connect(self.PB_Load,SIGNAL("clicked()"),self.PBLoadPressed)
self.connect(self.PB_Save,SIGNAL("clicked()"),self.PBSavePressed)
self.connect(self.PB_LoadHyp,SIGNAL("clicked()"),self.PBLoadHypPressed)
self.connect(self.PB_SaveHyp,SIGNAL("clicked()"),self.PBSaveHypPressed)
self.connect(self.PB_MeshFile,SIGNAL("clicked()"),self.PBMeshFilePressed)
self.connect(self.PB_MeshSmesh,SIGNAL("clicked()"),self.PBMeshSmeshPressed)
self.connect(self.LE_MeshSmesh,SIGNAL("returnPressed()"),self.meshSmeshNameChanged)
self.connect(self.PB_ParamsFileExplorer,SIGNAL("clicked()"),self.setParamsFileName)
self.connect(self.LE_MeshFile,SIGNAL("returnPressed()"),self.meshFileNameChanged)
self.connect(self.LE_ParamsFile,SIGNAL("returnPressed()"),self.paramsFileNameChanged)
#QtCore.QObject.connect(self.checkBox, QtCore.SIGNAL("stateChanged(int)"), self.change)
self.connect(self.CB_FillHoles,SIGNAL("stateChanged(int)"),self.SP_MinHoleSize.setEnabled)
self.connect(self.CB_ComputedToleranceDisplacement,SIGNAL("stateChanged(int)"),self.SP_ToleranceDisplacement.setDisabled)
self.connect(self.CB_ComputedResolutionLength,SIGNAL("stateChanged(int)"),self.SP_ResolutionLength.setDisabled)
self.connect(self.CB_ComputedOverlapDistance,SIGNAL("stateChanged(int)"),self.SP_OverlapDistance.setDisabled)
def PBHelpPressed(self):
try:
mydir=os.environ["SMESH_ROOT_DIR"]
except Exception:
QMessageBox.warning( self, "Help", "Help unavailable $SMESH_ROOT_DIR not found")
return
maDoc=mydir+"/share/doc/salome/gui/SMESH/MGCleaner/_downloads/mg-cleaner_user_manual.pdf"
command="xdg-open "+maDoc+";"
subprocess.call(command, shell=True)
def PBOKPressed(self):
if not(self.PrepareLigneCommande()):
#warning done yet
#QMessageBox.warning(self, "Compute", "Command not found")
return
maFenetre=MGCleanerMonViewText(self, self.commande)
def enregistreResultat(self):
import smesh
import SMESH
import salome
from salome.kernel import studyedit
if not os.path.isfile(self.fichierOut):
QMessageBox.warning(self, "Compute", "Result file "+self.fichierOut+" not found")
maStudy=studyedit.getActiveStudy()
smesh.SetCurrentStudy(maStudy)
(outputMesh, status) = smesh.CreateMeshesFromGMF(self.fichierOut)
name=str(self.LE_MeshSmesh.text())
initialMeshFile=None
initialMeshObject=None
if name=="":
a=str(self.fichierIn)
name=os.path.basename(os.path.splitext(a)[0])
initialMeshFile=a
else:
initialMeshObject=maStudy.FindObjectByName(name ,"SMESH")[0]
meshname = name+"_MGC_"+str(self.num)
smesh.SetName(outputMesh.GetMesh(), meshname)
outputMesh.Compute() #no algorithms message for "Mesh_x" has been computed with warnings: - global 1D algorithm is missing
self.editor = studyedit.getStudyEditor()
moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
HypReMeshEntry = self.editor.findOrCreateItem(
moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" )
monStudyBuilder=maStudy.NewBuilder()
monStudyBuilder.NewCommand()
newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num))
self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; "))
SOMesh=maStudy.FindObjectByName(meshname ,"SMESH")[0]
if initialMeshFile!=None:
newStudyFileName=monStudyBuilder.NewObject(SOMesh)
self.editor.setAttributeValue(newStudyFileName, "AttributeName", "meshFile")
self.editor.setAttributeValue(newStudyFileName, "AttributeExternalFileDef", initialMeshFile)
self.editor.setAttributeValue(newStudyFileName, "AttributeComment", initialMeshFile)
if initialMeshObject!=None:
newLink=monStudyBuilder.NewObject(SOMesh)
monStudyBuilder.Addreference(newLink, initialMeshObject)
newLink=monStudyBuilder.NewObject(SOMesh)
monStudyBuilder.Addreference(newLink, newStudyIter)
if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
self.num+=1
return True
def PBSavePressed(self):
from datetime import datetime
if not(self.PrepareLigneCommande()): return
text = "# MGCleaner hypothesis parameters\n"
text += "# Params for mesh : " + self.LE_MeshSmesh.text() +"\n"
text += datetime.now().strftime("# Date : %d/%m/%y %H:%M:%S\n")
text += "# Command : "+self.commande+"\n"
text += self.getResumeData(separator="\n")
text += "\n\n"
try:
f=open(self.paramsFile,"a")
except:
QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
return
try:
f.write(text)
except:
QMessageBox.warning(self, "File", "Unable to write "+self.paramsFile)
return
f.close()
def PBSaveHypPressed(self):
"""save hypothesis in Object Browser"""
#QMessageBox.warning(self, "save Object Browser MGCleaner Hypothesis", "TODO")
import smesh
import SMESH
import salome
from salome.kernel import studyedit
maStudy=studyedit.getActiveStudy()
smesh.SetCurrentStudy(maStudy)
self.editor = studyedit.getStudyEditor()
moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH")
HypReMeshEntry = self.editor.findOrCreateItem(
moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" )
monStudyBuilder=maStudy.NewBuilder()
monStudyBuilder.NewCommand()
newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry)
self.editor.setAttributeValue(newStudyIter, "AttributeName", "MGCleaner Parameters_"+str(self.num))
self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; "))
if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0)
self.num+=1
return True
"""
import salome_pluginsmanager
print "salome_pluginsmanager.plugins",salome_pluginsmanager.plugins
print "salome_pluginsmanager.current_plugins_manager",salome_pluginsmanager.current_plugins_manager
"""
def SP_toStr(self, widget):
#cr, pos=widget.validator().validate(res, 0) #n.b. "1,3" is acceptable !locale!
try:
return str(float(widget.text()))
except:
widget.setProperty("text", "0.0")
return "0.0"
def getResumeData(self, separator="\n"):
text=""
if self.RB_Fix1.isChecked():
CheckOrFix="fix1pass"
else:
if self.RB_Fix2.isChecked():
CheckOrFix="fix2pass"
else:
CheckOrFix="check"
text+="CheckOrFix="+CheckOrFix+separator
text+="PreserveTopology="+str(self.CB_PreserveTopology.isChecked())+separator
text+="FillHoles="+str(self.CB_FillHoles.isChecked())+separator
v=self.SP_toStr(self.SP_MinHoleSize)
text+="MinHoleSize="+v+separator
text+="ComputedToleranceDisplacement="+str(self.CB_ComputedToleranceDisplacement.isChecked())+separator
v=self.SP_toStr(self.SP_ToleranceDisplacement)
text+="ToleranceDisplacement="+v+separator
text+="ComputedResolutionLength="+str(self.CB_ComputedResolutionLength.isChecked())+separator
v=self.SP_toStr(self.SP_ResolutionLength)
text+="ResolutionLength="+v+separator
text+="FoldingAngle="+str(self.SP_FoldingAngle.value())+separator
text+="RemeshPlanes="+str(self.CB_RemeshPlanes.isChecked())+separator
text+="ComputedOverlapDistance="+str(self.CB_ComputedOverlapDistance.isChecked())+separator
v=self.SP_toStr(self.SP_OverlapDistance)
text+="OverlapDistance="+v+separator
text+="OverlapAngle="+str(self.SP_OverlapAngle.value())+separator
text+="Verbosity="+str(self.SP_Verbosity.value())+separator
return str(text)
def loadResumeData(self, hypothesis, separator="\n"):
text=str(hypothesis)
self.clean()
for slig in reversed(text.split(separator)):
lig=slig.strip()
#print "load ResumeData",lig
if lig=="": continue #skip blanck lines
if lig[0]=="#": break
try:
tit,value=lig.split("=")
if tit=="CheckOrFix":
self.RB_Fix1.setChecked(False)
self.RB_Fix2.setChecked(False)
self.RB_Check.setChecked(False)
if value=="fix1pass": self.RB_Fix1.setChecked(True)
if value=="fix2pass": self.RB_Fix2.setChecked(True)
if value=="check": self.RB_Check.setChecked(True)
if tit=="PreserveTopology": self.CB_PreserveTopology.setChecked(value=="True")
if tit=="FillHoles": self.CB_FillHoles.setChecked(value=="True")
if tit=="MinHoleSize": self.SP_MinHoleSize.setProperty("text", value)
if tit=="ComputedToleranceDisplacement": self.CB_ComputedToleranceDisplacement.setChecked(value=="True")
if tit=="ToleranceDisplacement": self.SP_ToleranceDisplacement.setProperty("text", value)
if tit=="ComputedResolutionLength": self.CB_ComputedResolutionLength.setChecked(value=="True")
if tit=="ResolutionLength": self.SP_ResolutionLength.setProperty("text", value)
if tit=="FoldingAngle": self.SP_FoldingAngle.setProperty("value", float(value))
if tit=="RemeshPlanes": self.CB_RemeshPlanes.setChecked(value=="True")
if tit=="ComputedOverlapDistance": self.CB_ComputedOverlapDistance.setChecked(value=="True")
if tit=="OverlapDistance": self.SP_OverlapDistance.setProperty("text", value)
if tit=="OverlapAngle": self.SP_OverlapAngle.setProperty("value", float(value))
if tit=="Verbosity": self.SP_Verbosity.setProperty("value", int(float(value)))
except:
QMessageBox.warning(self, "load MGCleaner Hypothesis", "Problem on '"+lig+"'")
def PBLoadPressed(self):
"""load last hypothesis saved in tail of file"""
try:
f=open(self.paramsFile,"r")
except :
QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile)
return
try:
text=f.read()
except :
QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile)
return
f.close()
self.loadResumeData(text, separator="\n")
def PBLoadHypPressed(self):
"""load hypothesis saved in Object Browser"""
#QMessageBox.warning(self, "load Object Browser MGCleaner hypothesis", "TODO")
import salome
from salome.kernel import studyedit
from salome.smesh.smeshstudytools import SMeshStudyTools
from salome.gui import helper as guihelper
from omniORB import CORBA
mySObject, myEntry = guihelper.getSObjectSelected()
if CORBA.is_nil(mySObject) or mySObject==None:
QMessageBox.critical(self, "Hypothese", "select an Object Browser MGCleaner hypothesis")
return
#for i in dir(mySObject): print "dir mySObject",i
#print "GetAllAttributes",mySObject.GetAllAttributes()
#print "GetComment",mySObject.GetComment()
#print "GetName",mySObject.GetName()
#could be renamed...
#if mySObject.GetFather().GetName()!="MGCleaner Hypotheses":
# QMessageBox.critical(self, "Hypothese", "not a child of MGCleaner Hypotheses")
# return
text=mySObject.GetComment()
#a verification
if "CheckOrFix=" not in text:
QMessageBox.critical(self, "Load Hypothese", "Object Browser selection not a MGCleaner Hypothesis")
return
self.loadResumeData(text, separator=" ; ")
return
def PBCancelPressed(self):
self.close()
def PBMeshFilePressed(self):
fd = QFileDialog(self, "select an existing Mesh file", self.LE_MeshFile.text(), "Mesh-Files (*.mesh);;All Files (*)")
if fd.exec_():
infile = fd.selectedFiles()[0]
self.LE_MeshFile.setText(infile)
self.fichierIn=infile.toLatin1()
self.MeshIn=""
self.LE_MeshSmesh.setText("")
def setParamsFileName(self):
fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)")
if fd.exec_():
infile = fd.selectedFiles()[0]
self.LE_ParamsFile.setText(infile)
self.paramsFile=infile.toLatin1()
def meshFileNameChanged(self):
self.fichierIn=str(self.LE_MeshFile.text())
#print "meshFileNameChanged", self.fichierIn
if os.path.exists(self.fichierIn):
self.__selectedMesh=None
self.MeshIn=""
self.LE_MeshSmesh.setText("")
return
QMessageBox.warning(self, "Mesh file", "File doesn't exist")
def meshSmeshNameChanged(self):
"""only change by GUI mouse selection, otherwise clear"""
#self.MeshIn=str(self.LE_MeshSmesh.text())
#print "meshSmeshNameChanged", self.MeshIn
self.__selectedMesh = None
self.MeshIn=""
self.LE_MeshSmesh.setText("")
self.fichierIn=""
return
def paramsFileNameChanged(self):
self.paramsFile=self.LE_ParamsFile.text()
def PBMeshSmeshPressed(self):
import salome
import smesh
from salome.kernel import studyedit
from salome.smesh.smeshstudytools import SMeshStudyTools
from salome.gui import helper as guihelper
from omniORB import CORBA
mySObject, myEntry = guihelper.getSObjectSelected()
if CORBA.is_nil(mySObject) or mySObject==None:
QMessageBox.critical(self, "Mesh", "select an input mesh")
return
self.smeshStudyTool = SMeshStudyTools()
try:
self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
except:
QMessageBox.critical(self, "Mesh", "select an input mesh")
return
if CORBA.is_nil(self.__selectedMesh):
QMessageBox.critical(self, "Mesh", "select an input mesh")
return
myName = mySObject.GetName()
#print "MeshSmeshNameChanged", myName
self.MeshIn=myName
self.LE_MeshSmesh.setText(myName)
self.LE_MeshFile.setText("")
self.fichierIn=""
def prepareFichier(self):
self.fichierIn="/tmp/ForMGCleaner_"+str(self.num)+".mesh"
#print "prepareFichier"
import SMESH
self.__selectedMesh.ExportGMF(self.__selectedMesh, self.fichierIn, True)
def PrepareLigneCommande(self):
"""
#use doc examples of mg-cleaner:
ls -al /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin
source /data/tmplgls/salome/prerequis/install/LICENSE/dlim8.var.sh
export PATH=/data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/bin/Linux_64:$PATH
cp -r /data/tmplgls/salome/prerequis/install/COMMON_64/MeshGems-1.0/examples .
cd examples
mg-cleaner.exe --help
mg-cleaner.exe --in case7.mesh --out case7-test.mesh --check
mg-cleaner.exe case7.mesh case7-fix.mesh --fix
mg-cleaner.exe --in Porsche.mesh --out Porsche-test.mesh --check
mg-cleaner.exe --in Porsche.mesh --out Porschefix.mesh --fix
mg-cleaner.exe --in Porsche.mesh --out PorscheNewfix.mesh --fix --resolution_length 0.03
"""
#self.commande="mg-cleaner.exe --in " + self.fichierIn + " --out " + self.fichierOut + " --fix2pass"
#return True
#print "PrepareLigneCommande '"+self.fichierIn+"' '"+self.MeshIn+"'",self.__selectedMesh
if self.fichierIn=="" and self.MeshIn=="":
QMessageBox.critical(self, "Mesh", "select an input mesh")
return False
if self.__selectedMesh!=None: self.prepareFichier()
if not (os.path.isfile(self.fichierIn)):
QMessageBox.critical(self, "File", "unable to read GMF Mesh in "+str(self.fichierIn))
return False
self.commande="mg-cleaner.exe"
verbosity=str(self.SP_Verbosity.value())
self.commande+=" --verbose " + verbosity
self.commande+=" --in " + self.fichierIn
#print "self.fichierIn",self.fichierIn,type(self.fichierIn)
deb=os.path.splitext(str(self.fichierIn))
self.fichierOut=deb[0] + "_fix.mesh"
self.commande+=" --out "+self.fichierOut
if self.RB_Fix1.isChecked():
self.commande+=" --fix1pass"
else:
if self.RB_Fix2.isChecked():
self.commande+=" --fix2pass"
else:
self.commande+=" --check"
if self.CB_PreserveTopology.isChecked():
self.commande+=" --topology respect"
else:
self.commande+=" --topology ignore"
if self.CB_FillHoles.isChecked(): #no fill holes default
self.commande+=" --min_hole_size " + self.SP_toStr(self.SP_MinHoleSize)
if not self.CB_ComputedToleranceDisplacement.isChecked(): #computed default
self.commande+=" --tolerance_displacement " + self.SP_toStr(self.SP_ToleranceDisplacement)
if not self.CB_ComputedResolutionLength.isChecked(): #computed default
self.commande+=" --resolution_length " + self.SP_toStr(self.SP_ResolutionLength)
self.commande+=" --folding_angle " + str(self.SP_FoldingAngle.value())
if self.CB_RemeshPlanes.isChecked(): #no remesh default
self.commande+=" --remesh_planes"
if not self.CB_ComputedOverlapDistance.isChecked(): #computed default
self.commande+=" --overlap_distance " + self.SP_toStr(self.SP_OverlapDistance)
self.commande+=" --overlap_angle " + str(self.SP_OverlapAngle.value())
return True
def clean(self):
self.RB_Check.setChecked(False)
self.RB_Fix1.setChecked(False)
self.RB_Fix2.setChecked(True)
self.CB_PreserveTopology.setChecked(False)
self.CB_FillHoles.setChecked(False)
self.CB_RemeshPlanes.setChecked(False)
self.SP_MinHoleSize.setProperty("text", 0)
self.SP_ToleranceDisplacement.setProperty("text", 0)
self.SP_ResolutionLength.setProperty("text", 0)
self.SP_FoldingAngle.setProperty("value", 15)
self.SP_OverlapDistance.setProperty("text", 0)
self.SP_OverlapAngle.setProperty("value", 15)
self.SP_Verbosity.setProperty("value", 3)
self.CB_ComputedToleranceDisplacement.setChecked(True)
self.CB_ComputedResolutionLength.setChecked(True)
self.CB_ComputedOverlapDistance.setChecked(True)
__dialog=None
def getDialog():
"""
This function returns a singleton instance of the plugin dialog.
c est obligatoire pour faire un show sans parent...
"""
global __dialog
if __dialog is None:
__dialog = MGCleanerMonPlugDialog()
#else :
# __dialog.clean()
return __dialog
#
# ==============================================================================
# For memory
# ==============================================================================
#
def TEST_standalone():
"""
works only if a salome is launched yet with a study loaded
to launch standalone python do:
/export/home/wambeke/2013/V6_main_MGC_CO6.4_64/APPLI/runSession
python
or (do not works)
python /export/home/wambeke/2013/V6_main_MGC_CO6.4_64/INSTALL/SMESH/share/salome/plugins/smesh/MGCleanerMonPlugDialog.py
"""
import salome
import smesh
import SMESH
from salome.kernel import studyedit
salome.salome_init()
maStudy=studyedit.getActiveStudy()
#etc...a mano...
#
# ==============================================================================
# Basic use cases and unit test functions
# ==============================================================================
#
def TEST_MGCleanerMonPlugDialog():
#print "TEST_MGCleanerMonPlugDialog"
import sys
from PyQt4.QtGui import QApplication
from PyQt4.QtCore import QObject, SIGNAL, SLOT
app = QApplication(sys.argv)
QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
dlg=MGCleanerMonPlugDialog()
dlg.show()
sys.exit(app.exec_())
if __name__ == "__main__":
TEST_MGCleanerMonPlugDialog()
#TEST_standalone()
pass

View File

@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2007-2013 EDF R&D
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
# Modules Python
import string,types,os
import traceback
from PyQt4 import *
from PyQt4.QtGui import *
from PyQt4.QtCore import *
# Import des panels
from MGCleanerViewText import Ui_ViewExe
class MGCleanerMonViewText(Ui_ViewExe, QDialog):
"""
Classe permettant la visualisation de texte
"""
def __init__(self, parent, txt, ):
QDialog.__init__(self,parent)
self.setupUi(self)
self.resize( QSize(1000,600).expandedTo(self.minimumSizeHint()) )
#self.connect( self.PB_Ok,SIGNAL("clicked()"), self, SLOT("close()") )
self.connect( self.PB_Ok,SIGNAL("clicked()"), self.theClose )
self.connect( self.PB_Save,SIGNAL("clicked()"), self.saveFile )
self.PB_Save.setToolTip("Save trace in log file")
self.PB_Ok.setToolTip("Close view")
self.monExe=QProcess(self)
self.connect(self.monExe, SIGNAL("readyReadStandardOutput()"), self.readFromStdOut )
self.connect(self.monExe, SIGNAL("readyReadStandardError()"), self.readFromStdErr )
# Je n arrive pas a utiliser le setEnvironment du QProcess
# fonctionne hors Salome mais pas dans Salome ???
cmds=''
try :
LICENCE_FILE=os.environ["DISTENE_LICENCE_FILE_FOR_MGCLEANER"]
except:
LICENCE_FILE=''
try :
PATH=os.environ["DISTENE_PATH_FOR_MGCLEANER"]
except:
PATH=''
if LICENCE_FILE != '':
cmds+='source '+LICENCE_FILE+'\n'
else:
cmds+="# $DISTENE_LICENCE_FILE_FOR_MGCLEANER NOT SET\n"
if PATH != '':
cmds+='export PATH='+PATH+':$PATH\n'
else:
cmds+="# $DISTENE_PATH_FOR_MGCLEANER NOT SET\n"
#cmds+='env\n'
cmds+='rm -f '+self.parent().fichierOut+'\n'
cmds+=txt+'\n'
cmds+='echo END_OF_MGCleaner\n'
pid=self.monExe.pid()
nomFichier='/tmp/MGCleaner_'+str(pid)+'.sh'
f=open(nomFichier,'w')
f.write(cmds)
f.close()
maBidouille='sh ' + nomFichier
self.monExe.start(maBidouille)
self.monExe.closeWriteChannel()
self.enregistreResultatsDone=False
self.show()
def saveFile(self):
#recuperation du nom du fichier
savedir=os.environ['HOME']
fn = QFileDialog.getSaveFileName(None, self.trUtf8("Save File"),savedir)
if fn.isNull() : return
ulfile = os.path.abspath(unicode(fn))
try:
f = open(fn, 'wb')
f.write(str(self.TB_Exe.toPlainText()))
f.close()
except IOError, why:
QMessageBox.critical(self, self.trUtf8('Save File'),
self.trUtf8('The file <b>%1</b> could not be saved.<br>Reason: %2')
.arg(unicode(fn)).arg(str(why)))
def readFromStdErr(self):
a=self.monExe.readAllStandardError()
self.TB_Exe.append(QString.fromUtf8(a.data(),len(a)))
def readFromStdOut(self) :
a=self.monExe.readAllStandardOutput()
aa=QString.fromUtf8(a.data(),len(a))
self.TB_Exe.append(aa)
if "END_OF_MGCleaner" in aa:
self.parent().enregistreResultat()
self.enregistreResultatsDone=True
#self.theClose()
def theClose(self):
if not self.enregistreResultatsDone:
self.parent().enregistreResultat()
self.enregistreResultatsDone=True
self.close()

View File

@ -0,0 +1,839 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MGCleanerPlugDialog</class>
<widget class="QWidget" name="MGCleanerPlugDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>500</height>
</rect>
</property>
<property name="windowTitle">
<string>MGCleaner : Remeshing tool</string>
</property>
<property name="sizeGripEnabled" stdset="0">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_xx">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="PB_OK">
<property name="text">
<string>Compute</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PB_Cancel">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="PB_SaveHyp">
<property name="text">
<string>Save</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PB_LoadHyp">
<property name="text">
<string>Load</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PB_Default">
<property name="text">
<string>Default</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="PB_Help">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Help</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_xx">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QTabWidget" name="TWOptions">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="simple">
<attribute name="title">
<string>Simple Remeshing Options</string>
</attribute>
<widget class="QGroupBox" name="GBOptim">
<property name="geometry">
<rect>
<x>10</x>
<y>140</y>
<width>750</width>
<height>270</height>
</rect>
</property>
<property name="title">
<string>Options</string>
</property>
<layout class="QHBoxLayout" name="RBLayoutopt">
<item>
<spacer name="horizontalSpacer_xx">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="RBLayout1">
<item>
<widget class="QRadioButton" name="RB_Check">
<property name="toolTip">
<string>Performs checks only (no fixing).
Writes diagnostics into the output file.
Default is to fix with two passes.</string>
</property>
<property name="text">
<string>Only checking</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="RB_Fix1">
<property name="toolTip">
<string>Analyses and fixes mesh with only the first stage of the cleaning procedure.
Does not write diagnostics into the output file.
Default is to fix with two passes.</string>
</property>
<property name="text">
<string>Fix problems with one pass</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="RB_Fix2">
<property name="toolTip">
<string>Analyses and fixes mesh with the two stage cleaning procedure.
Does not write diagnostics into the output file.
Default is to fix with two passes.</string>
</property>
<property name="text">
<string>Fix problems with two passes</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="CB_PreserveTopology">
<property name="toolTip">
<string>Disables fixing operations which induce topology modifications.
Default is enable topology modifications.
(argument --topology)</string>
</property>
<property name="text">
<string>Preserve topology</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="CB_FillHoles">
<property name="toolTip">
<string>Default is not to fill holes.
if set: see 'surface size threshold of holes' in 'Advanced remeshing options'.</string>
</property>
<property name="text">
<string>Fill holes</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="CB_RemeshPlanes">
<property name="toolTip">
<string>Inserts vertices on planes to improve mesh quality .
May be useful for poor quality triangulations (eg .STL or .DXF triangulations).
Default is not to mesh planes.</string>
</property>
<property name="text">
<string>Remesh planes</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>750</width>
<height>120</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="title">
<string>Original Mesh</string>
</property>
<widget class="QPushButton" name="PB_MeshFile">
<property name="geometry">
<rect>
<x>40</x>
<y>70</y>
<width>190</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Mesh File GMF format</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
<widget class="QLineEdit" name="LE_MeshFile">
<property name="geometry">
<rect>
<x>240</x>
<y>70</y>
<width>481</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
</widget>
<widget class="QPushButton" name="PB_MeshSmesh">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>190</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Mesh Object Browser</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
<widget class="QLineEdit" name="LE_MeshSmesh">
<property name="geometry">
<rect>
<x>240</x>
<y>30</y>
<width>481</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
</widget>
<widget class="QLabel" name="label_8">
<property name="geometry">
<rect>
<x>10</x>
<y>80</y>
<width>31</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>or</string>
</property>
</widget>
</widget>
<zorder>groupBox</zorder>
<zorder>GBOptim</zorder>
</widget>
<widget class="QWidget" name="advanced">
<attribute name="title">
<string>Advanced Remeshing Options</string>
</attribute>
<widget class="QGroupBox" name="groupBox_5">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>750</width>
<height>400</height>
</rect>
</property>
<property name="title">
<string>You can control</string>
</property>
#1
<widget class="QLineEdit" name="SP_MinHoleSize">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>100</width>
<height>25</height>
</rect>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<widget class="QLabel" name="LA_minHoleSize">
<property name="geometry">
<rect>
<x>130</x>
<y>30</y>
<width>600</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>sets the surface size threshold below which holes are filled.
Set 'Fill holes' in 'Simple Remeshing Options'.</string>
</property>
<property name="text">
<string>Surface size threshold of holes to fill (--min_hole_size)</string>
</property>
</widget>
#2
<widget class="QLineEdit" name="SP_ToleranceDisplacement">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>100</width>
<height>25</height>
</rect>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<widget class="QLabel" name="LA_toleranceDisplacement">
<property name="geometry">
<rect>
<x>130</x>
<y>70</y>
<width>600</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>Sets the displacement threshold below which modification is allowed.
Unused in collision resolution .
'Tolerance displacement' is set to resolution_length if it is lower.</string>
</property>
<property name="text">
<string>Tolerance displacement threshold of points for modification
(--tolerance_displacement)</string>
</property>
</widget>
<widget class="QCheckBox" name="CB_ComputedToleranceDisplacement">
<property name="geometry">
<rect>
<x>650</x>
<y>70</y>
<width>100</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>If set default value is computed from model.</string>
</property>
<property name="text">
<string>Computed</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
#3
<widget class="QLineEdit" name="SP_ResolutionLength">
<property name="geometry">
<rect>
<x>20</x>
<y>110</y>
<width>100</width>
<height>25</height>
</rect>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<widget class="QLabel" name="LA_resolutionLength">
<property name="geometry">
<rect>
<x>130</x>
<y>110</y>
<width>600</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>sets the distance threshold above which 2 points are considered distinct.
Sets the tolerance displacement to 1/5 of this size.
Default is computed from model.</string>
</property>
<property name="text">
<string>Distance threshold for two points distinct (--resolution_length)</string>
</property>
</widget>
<widget class="QCheckBox" name="CB_ComputedResolutionLength">
<property name="geometry">
<rect>
<x>650</x>
<y>110</y>
<width>100</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>If set default value is computed from model.</string>
</property>
<property name="text">
<string>Computed</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
#4
<widget class="QDoubleSpinBox" name="SP_FoldingAngle">
<property name="geometry">
<rect>
<x>20</x>
<y>150</y>
<width>100</width>
<height>25</height>
</rect>
</property>
<property name="maximum">
<double>360</double>
</property>
<property name="minimum">
<double>0</double>
</property>
<property name="singleStep">
<double>0.01</double>
</property>
<property name="value">
<double>15</double>
</property>
</widget>
<widget class="QLabel" name="LA_foldingAngle">
<property name="geometry">
<rect>
<x>130</x>
<y>150</y>
<width>600</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>Sets the threshold angle below which 2 connected triangles are considered overlapping .
Reduce this value if model contains sharp angles below this threshold that must be kept.
Overlap_angle is set to this angle if it is higher.
Default is 15 degrees.</string>
</property>
<property name="text">
<string>Angle threshold for two connected triangles overlapping (--folding_angle)</string>
</property>
</widget>
#5
<widget class="QLineEdit" name="SP_OverlapDistance">
<property name="geometry">
<rect>
<x>20</x>
<y>190</y>
<width>100</width>
<height>25</height>
</rect>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<widget class="QLabel" name="LA_overlapDistance">
<property name="geometry">
<rect>
<x>130</x>
<y>190</y>
<width>600</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>sets the distance below which 2 unconnected triangles are considered overlapping.
Reduce this value if too many overlaps are detected.
Default is computed from model.</string>
</property>
<property name="text">
<string>Distance threshold for two unconnected triangles overlapping
(--overlap_distance)</string>
</property>
</widget>
<widget class="QCheckBox" name="CB_ComputedOverlapDistance">
<property name="geometry">
<rect>
<x>650</x>
<y>190</y>
<width>100</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>If set default value is computed from model.</string>
</property>
<property name="text">
<string>Computed</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
#6
<widget class="QDoubleSpinBox" name="SP_OverlapAngle">
<property name="geometry">
<rect>
<x>20</x>
<y>230</y>
<width>100</width>
<height>25</height>
</rect>
</property>
<property name="maximum">
<double>360</double>
</property>
<property name="minimum">
<double>0</double>
</property>
<property name="singleStep">
<double>1</double>
</property>
<property name="value">
<double>15</double>
</property>
</widget>
<widget class="QLabel" name="LA_overlapAngle">
<property name="geometry">
<rect>
<x>130</x>
<y>230</y>
<width>600</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>Sets the angle below which 2 unconnected triangles are considered overlapping.
'Folding angle' is set to this angle if it is lower.
Default is 15 degrees.</string>
</property>
<property name="text">
<string>Angle threshold for two unconnected triangles overlapping (--overlap_angle)</string>
</property>
</widget>
</widget>
</widget>
<widget class="QWidget" name="generic">
<attribute name="title">
<string>Generic Options</string>
</attribute>
<widget class="QGroupBox" name="groupBox_4">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>750</width>
<height>130</height>
</rect>
</property>
<property name="title">
<string>MGCleaner Generic Options</string>
</property>
<widget class="QSpinBox" name="SP_Verbosity">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>100</width>
<height>25</height>
</rect>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="value">
<number>3</number>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>130</x>
<y>30</y>
<width>600</width>
<height>30</height>
</rect>
</property>
<property name="toolTip">
<string>sets the verbosity level.
From 0 (no detail) to 10 (very detailed).
Default is 3.</string>
</property>
<property name="text">
<string>Verbosity level</string>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_6">
<property name="geometry">
<rect>
<x>10</x>
<y>150</y>
<width>750</width>
<height>170</height>
</rect>
</property>
<property name="title">
<string>Plug-in Generic Options</string>
</property>
<widget class="QLabel" name="label_10">
<property name="geometry">
<rect>
<x>20</x>
<y>40</y>
<width>391</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>File used to save MGCleaner hypothesis parameters :</string>
</property>
</widget>
<widget class="QPushButton" name="PB_ParamsFileExplorer">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>30</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLineEdit" name="LE_ParamsFile">
<property name="geometry">
<rect>
<x>60</x>
<y>70</y>
<width>661</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="PB_Save">
<property name="geometry">
<rect>
<x>20</x>
<y>110</y>
<width>70</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
<widget class="QPushButton" name="PB_Load">
<property name="geometry">
<rect>
<x>120</x>
<y>110</y>
<width>70</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Load</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ViewExe</class>
<widget class="QDialog" name="ViewExe">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>469</width>
<height>489</height>
</rect>
</property>
<property name="windowTitle">
<string>Run MGCleaner</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QTextBrowser" name="TB_Exe"/>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="PB_Ok">
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="PB_Save">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2006-2013 EDF R&D
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
# if you already have plugins defined in a salome_plugins.py file, add this file at the end.
# if not, copy this file as ${HOME}/Plugins/smesh_plugins.py or ${APPLI}/Plugins/smesh_plugins.py
def MGCleanerLct(context):
# get context study, studyId, salomeGui
study = context.study
studyId = context.studyId
sg = context.sg
import os
import subprocess
import tempfile
from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4.QtGui import QFileDialog
from PyQt4.QtGui import QMessageBox
#prior test to avoid unnecessary user GUI work with ending crash
try :
os.environ['DISTENE_LICENCE_FILE_FOR_MGCLEANER']
except:
QMessageBox.warning(None,"Products","Distene's product MeshGem Cleaner is not installed.\nrequired environment variable:\nDISTENE_LICENCE_FILE_FOR_MGCLEANER='/.../dlim8.var.sh'")
return
import MGCleanerMonPlugDialog
window=MGCleanerMonPlugDialog.getDialog()
window.show()

View File

@ -0,0 +1,38 @@
# Copyright (C) 2007-2013 EDF R&D
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
SUBDIRS = doc
include $(top_srcdir)/adm_local/unix/make_common_starter.am
UIPY_FILES = MGCleanerPlugDialog.py MGCleanerViewText.py
salomeplugins_PYTHON = \
MGCleanerMonPlugDialog.py\
MGCleanerMonViewText.py\
MGCleanerplug_plugin.py
nodist_salomeplugins_PYTHON = $(UIPY_FILES)
CLEANFILES = $(UIPY_FILES)
EXTRA_DIST += $(UIPY_FILES:%.py=%.ui)
%.py : %.ui
$(PYUIC) $< -o $@

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -28,10 +28,10 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
SUBDIRS = MeshCut padder SUBDIRS = MeshCut padder
if SMESH_ENABLE_GUI if SMESH_ENABLE_GUI
SUBDIRS += YamsPlug SUBDIRS += YamsPlug MGCleanerPlug
endif endif
salomeplugins_PYTHON = \ salomeplugins_PYTHON = \
smesh_plugins.py smesh_plugins.py
DIST_SUBDIRS = MeshCut padder YamsPlug DIST_SUBDIRS = MeshCut padder YamsPlug MGCleanerPlug

BIN
src/Tools/YamsPlug/open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -24,6 +24,7 @@ import salome_pluginsmanager
from spadderPlugin import runSpadderPlugin from spadderPlugin import runSpadderPlugin
from meshcut_plugin import MeshCut from meshcut_plugin import MeshCut
from yamsplug_plugin import YamsLct from yamsplug_plugin import YamsLct
from MGCleanerplug_plugin import MGCleanerLct
salome_pluginsmanager.AddFunction('PADDER mesher', salome_pluginsmanager.AddFunction('PADDER mesher',
'Create a mesh with PADDER', 'Create a mesh with PADDER',
@ -36,3 +37,8 @@ salome_pluginsmanager.AddFunction('MeshCut',
salome_pluginsmanager.AddFunction('ReMesh with Yams', salome_pluginsmanager.AddFunction('ReMesh with Yams',
'Run Yams', 'Run Yams',
YamsLct) YamsLct)
salome_pluginsmanager.AddFunction('ReMesh with MGCleaner',
'Run MGCleaner',
MGCleanerLct)