mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-02-19 08:53:08 +05:00
PR: plugin for MeshCut
This commit is contained in:
parent
e145b0e8b3
commit
07a37cb49f
@ -43,3 +43,14 @@ MeshCut_CPPFLAGS = $(MED2_INCLUDES)
|
||||
|
||||
MeshCut_LDFLAGS = $(MED2_LIBS) $(HDF5_LIBS)
|
||||
|
||||
|
||||
|
||||
UIPY_FILES = MeshCutDialog.py
|
||||
BUILT_SOURCES = $(UIPY_FILES)
|
||||
bin_SCRIPTS = $(UIPY_FILES) meshcut_plugin.py
|
||||
clean-local:
|
||||
rm -f $(UIPY_FILES)
|
||||
EXTRA_DIST += MeshCutDialog.ui meshcut_plugin.py
|
||||
|
||||
%.py : %.ui
|
||||
pyuic4 $< -o $@
|
||||
|
270
src/Tools/MeshCut/MeshCutDialog.ui
Normal file
270
src/Tools/MeshCut/MeshCutDialog.ui
Normal file
@ -0,0 +1,270 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>416</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>cut a mesh by a plane</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="pb_origMeshFile">
|
||||
<property name="text">
|
||||
<string>original mesh file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="le_origMeshFile"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>output mesh name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="le_outMeshName">
|
||||
<property name="text">
|
||||
<string>meshCut</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>name of group above cut</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="le_groupAbove">
|
||||
<property name="text">
|
||||
<string>above</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>name of group below cut</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="le_groupBelow">
|
||||
<property name="text">
|
||||
<string>below</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>cut plane</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>normal vector</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>vertex in plane</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDoubleSpinBox" name="dsb_normX">
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QDoubleSpinBox" name="dsb_normY">
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsb_vertY">
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QDoubleSpinBox" name="dsb_normZ">
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsb_vertZ">
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsb_vertX">
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Tolerance 0 < T <= 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QDoubleSpinBox" name="dsb_tolerance">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>396</width>
|
||||
<height>90</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QPushButton" name="pb_help">
|
||||
<property name="text">
|
||||
<string>Help</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QDialogButtonBox" name="pb_okCancel">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="le_cutMeshFile"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pb_cutMeshFile">
|
||||
<property name="text">
|
||||
<string>cut mesh file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>pb_okCancel</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>pb_okCancel</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -21,6 +21,6 @@ where:
|
||||
belowGroups = name of the group of volumes below the cut plane
|
||||
nx ny nz = vector normal to the cut plane
|
||||
px py pz = a point of the cut plane
|
||||
T = 0 < T < 1 : vertices of a tetrahedron are considered as belonging
|
||||
T = 0 < T < 1 : vertices of a tetrahedron are considered as belonging to
|
||||
the cut plane if their distance to the plane is inferior to L*T
|
||||
where L is the mean edge size of the tetrahedron
|
||||
|
126
src/Tools/MeshCut/meshcut_plugin.py
Normal file
126
src/Tools/MeshCut/meshcut_plugin.py
Normal file
@ -0,0 +1,126 @@
|
||||
# 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/salome_plugins.py or ${APPLI}/Plugins/salome_plugins.py
|
||||
|
||||
import salome_pluginsmanager
|
||||
|
||||
def MeshCut(context):
|
||||
# get context study, studyId, salomeGui
|
||||
study = context.study
|
||||
studyId = context.studyId
|
||||
sg = context.sg
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
from PyQt4 import QtGui
|
||||
from PyQt4.QtGui import QFileDialog
|
||||
from PyQt4.QtGui import QMessageBox
|
||||
from MeshCutDialog import Ui_Dialog
|
||||
|
||||
class CutDialog(QtGui.QDialog):
|
||||
|
||||
def __init__(self):
|
||||
QtGui.QDialog.__init__(self)
|
||||
# Set up the user interface from Designer.
|
||||
self.ui = Ui_Dialog()
|
||||
self.ui.setupUi(self)
|
||||
# Connect up the buttons.
|
||||
self.connect(self.ui.pb_origMeshFile, QtCore.SIGNAL("clicked()"),
|
||||
self.setInputFile)
|
||||
self.connect(self.ui.pb_cutMeshFile, QtCore.SIGNAL("clicked()"),
|
||||
self.setOutputFile)
|
||||
self.connect(self.ui.pb_help, QtCore.SIGNAL("clicked()"),
|
||||
self.helpMessage)
|
||||
pass
|
||||
|
||||
def setInputFile(self):
|
||||
fd = QFileDialog(self, "select an existing Med file", self.ui.le_origMeshFile.text(), "MED-Files (*.med);;All Files (*)")
|
||||
if fd.exec_():
|
||||
infile = fd.selectedFiles()[0]
|
||||
self.ui.le_origMeshFile.setText(infile)
|
||||
insplit = os.path.splitext(infile.toLocal8Bit().data())
|
||||
outfile = insplit[0] + '_cut' + insplit[1]
|
||||
self.ui.le_cutMeshFile.setText(outfile)
|
||||
pass
|
||||
|
||||
def setOutputFile(self):
|
||||
fd = QFileDialog(self, "select an output Med file", self.ui.le_cutMeshFile.text(), "MED-Files (*.med);;All Files (*)")
|
||||
if fd.exec_():
|
||||
self.ui.le_cutMeshFile.setText(fd.selectedFiles()[0])
|
||||
pass
|
||||
|
||||
def helpMessage(self):
|
||||
QMessageBox.about(None, "About MeshCut",
|
||||
"""
|
||||
Cut a tetrahedron mesh by a plane
|
||||
---------------------------------
|
||||
|
||||
MeshCut allows to cut a mesh constituted of linear
|
||||
tetrahedrons by a plane. The tetrahedrons intersected
|
||||
by the plane are cut and replaced by elements of
|
||||
various types (tetrahedron, pyramid, pentahedron).
|
||||
|
||||
MeshCut is a standalone program, reading and
|
||||
producing med files. The cutting plane is defined
|
||||
by a vector normal to the plane and a vertex
|
||||
belonging to the plane.
|
||||
|
||||
Vertices of a tetrahedron are considered as belonging to
|
||||
the cut plane if their distance to the plane is inferior
|
||||
to L*T where L is the mean edge size of the tetrahedron
|
||||
and T the tolerance.
|
||||
""")
|
||||
pass
|
||||
pass
|
||||
|
||||
|
||||
|
||||
window = CutDialog()
|
||||
window.ui.dsb_tolerance.setValue(0.01)
|
||||
retry = True
|
||||
while(retry):
|
||||
retry = False
|
||||
window.exec_()
|
||||
result = window.result()
|
||||
if result:
|
||||
# dialog accepted
|
||||
args = ['MeshCut']
|
||||
args += [window.ui.le_origMeshFile.text().toLocal8Bit().data()]
|
||||
args += [window.ui.le_cutMeshFile.text().toLocal8Bit().data()]
|
||||
args += [window.ui.le_outMeshName.text().toLocal8Bit().data()]
|
||||
args += [window.ui.le_groupAbove.text().toLocal8Bit().data()]
|
||||
args += [window.ui.le_groupBelow.text().toLocal8Bit().data()]
|
||||
args += [str(window.ui.dsb_normX.value())]
|
||||
args += [str(window.ui.dsb_normY.value())]
|
||||
args += [str(window.ui.dsb_normZ.value())]
|
||||
args += [str(window.ui.dsb_vertX.value())]
|
||||
args += [str(window.ui.dsb_vertY.value())]
|
||||
args += [str(window.ui.dsb_vertZ.value())]
|
||||
args += [str(window.ui.dsb_tolerance.value())]
|
||||
f= tempfile.NamedTemporaryFile(delete=False)
|
||||
fname = f.name
|
||||
p = subprocess.Popen(args, stdout=f, stderr=f)
|
||||
err = p.wait()
|
||||
f.close()
|
||||
if err==0:
|
||||
os.remove(fname)
|
||||
else:
|
||||
f = open(fname, 'r')
|
||||
m = f.read()
|
||||
msgBox = QMessageBox()
|
||||
msgBox.setText("Parameters are not OK")
|
||||
msgBox.setInformativeText("Do you want to retry ?")
|
||||
msgBox.setDetailedText(m)
|
||||
msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Cancel)
|
||||
msgBox.setDefaultButton(QMessageBox.Retry)
|
||||
ret = msgBox.exec_()
|
||||
if ret == QMessageBox.Retry:
|
||||
retry = True
|
||||
pass
|
||||
pass
|
||||
pass
|
||||
pass
|
||||
|
||||
# register the function in the plugin manager
|
||||
salome_pluginsmanager.AddFunction('MeshCut', 'Cut a tetrahedron mesh by a plane', MeshCut)
|
||||
|
Loading…
Reference in New Issue
Block a user