Salome HOME
PR: plugin for MeshCut
authorprascle <prascle>
Tue, 3 May 2011 15:37:17 +0000 (15:37 +0000)
committerprascle <prascle>
Tue, 3 May 2011 15:37:17 +0000 (15:37 +0000)
src/Tools/MeshCut/Makefile.am
src/Tools/MeshCut/MeshCutDialog.ui [new file with mode: 0644]
src/Tools/MeshCut/README
src/Tools/MeshCut/meshcut_plugin.py [new file with mode: 0644]

index 38adf91950b8c052bc0b61af61348722ddf6e584..a32f4454c596fc974575ea283e7cc7fcd3d5d2be 100644 (file)
@@ -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 $@
diff --git a/src/Tools/MeshCut/MeshCutDialog.ui b/src/Tools/MeshCut/MeshCutDialog.ui
new file mode 100644 (file)
index 0000000..1ec5422
--- /dev/null
@@ -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 &lt; T &lt;= 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>
index 6dbff87f2c3b7ac3cb0bb86354a04fbcacf7ba3a..599806b183fb125209fd67f26235dd0d256780a4 100644 (file)
@@ -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
diff --git a/src/Tools/MeshCut/meshcut_plugin.py b/src/Tools/MeshCut/meshcut_plugin.py
new file mode 100644 (file)
index 0000000..578d3fa
--- /dev/null
@@ -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)
+