-
Notifications
You must be signed in to change notification settings - Fork 95
PoC / Paraview integration for mesh_doctor
#2790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from paraview.util.vtkAlgorithm import * | ||
from paraview.selection import * | ||
|
||
|
||
@smproxy.filter(name="Mesh Doctor(GEOS)") | ||
@smproperty.input(name="Input") | ||
@smdomain.datatype(dataTypes=["vtkUnstructuredGrid"], composite_data_supported=False) | ||
class ElementVolumesFilter(VTKPythonAlgorithmBase): | ||
""" | ||
Example portage meshDoctor in PV Python plugins | ||
""" | ||
def __init__(self): | ||
super().__init__(outputType='vtkUnstructuredGrid') | ||
from checks import element_volumes | ||
self.opt = element_volumes.Options(0) | ||
|
||
def RequestData(self, request, inInfo, outInfo): | ||
inData = self.GetInputData(inInfo, 0, 0) | ||
outData = self.GetOutputData(outInfo, 0) | ||
assert inData is not None | ||
if outData is None or (not outData.IsA(inData.GetClassName())): | ||
outData = inData.NewInstance() | ||
extracted = self._Process(inData) | ||
outData.DeepCopy( extracted.GetOutput() ) | ||
outInfo.GetInformationObject(0).Set(outData.DATA_OBJECT(), extracted.GetOutput()) | ||
|
||
print("1> There are {} cells under {} m3 vol".format(outData.GetNumberOfCells(), self.opt)) | ||
return 1 | ||
|
||
def _Process(self,mesh): | ||
from checks import element_volumes | ||
from paraview.vtk import vtkIdTypeArray, vtkSelectionNode, vtkSelection, vtkCollection | ||
from vtk import vtkExtractSelection | ||
res = element_volumes.check(mesh, self.opt) | ||
ids = vtkIdTypeArray() | ||
ids.SetNumberOfComponents(1) | ||
for val in res.element_volumes: | ||
ids.InsertNextValue(val[0]) | ||
|
||
|
||
selectionNode = vtkSelectionNode() | ||
selectionNode.SetFieldType(vtkSelectionNode.CELL) | ||
selectionNode.SetContentType(vtkSelectionNode.INDICES) | ||
selectionNode.SetSelectionList(ids) | ||
selection = vtkSelection() | ||
selection.AddNode(selectionNode) | ||
|
||
extracted = vtkExtractSelection() | ||
extracted.SetInputDataObject(0, mesh) | ||
extracted.SetInputData(1, selection) | ||
extracted.Update() | ||
print("There are {} cells under {} m3 vol".format(extracted.GetOutput().GetNumberOfCells(), self.opt)) | ||
print("There are {} arrays of cell data".format(extracted.GetOutput().GetCellData().GetNumberOfArrays(), self.opt)) | ||
|
||
return extracted | ||
|
||
@smproperty.doublevector(name="Vol Threshold", default_values=["0.0"]) | ||
def SetValue(self, val): | ||
from checks import element_volumes | ||
self.opt = element_volumes.Options(val) | ||
# print("settings value:", self.opt) | ||
self.Modified() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -122,3 +122,75 @@ It will also verify that the ``VTK_POLYHEDRON`` cells can effectively get conver | |
|
||
.. command-output:: python mesh_doctor.py supported_elements --help | ||
:cwd: ../../../coreComponents/python/modules/geosx_mesh_doctor | ||
|
||
``Using mesh_doctor in paraview`` | ||
"""""""""""""""""""""""""""""""""" | ||
|
||
Using mesh_doctor as a programmable filter | ||
____________________________________________ | ||
|
||
To use ``mesh_doctor`` in Paraview as a python programmable filter, a python package install is required first in Paraview python resolved | ||
path. Paraview is storing its python ressources under its *lib/pythonX.X* depending on the paraview version, *e.g* Paraview 5.11 is working | ||
with python 3.9. As a results the following command will install ``mesh_doctor`` package into Paraview resolved path. | ||
|
||
.. command-output:: python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps --upgrade --target /path/to/Paraview/lib/python3.9/ mesh_doctor | ||
|
||
.. note:: | ||
``pip`` is installing the ``mesh_doctor`` package from the test.pypi repo, which is intended to test package deployment. | ||
Once stabilized and ``mesh_doctor`` uploaded onto the main package repo, this should be dropped out. | ||
|
||
Once the installation done, the */path/to/Paraview/lib/pythonX.X* should holds ``mesh_doctor`` package content, *i.e.* ``checks`` and ``parsing``. | ||
Then launching ``Paraview`` and loading our *mesh.vtu*, as an example, we will design a *Programmable python filter* relying on *element_volumes* from | ||
``mesh_doctor``. Add such a filter pipelined after the mesh reader, in the script section paste the following, | ||
|
||
.. code-block:: python | ||
:linenos: | ||
|
||
mesh = inputs[0].VTKObject | ||
tol = 1.2e-6 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you know how to define There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That I think would remain to be set from the script. This would maybe possible via Plugin to have a |
||
|
||
from checks import element_volumes | ||
import vtk | ||
|
||
res = element_volumes.__check(mesh, element_volumes.Options(tol)) | ||
#print(res) | ||
ids = vtk.vtkIdTypeArray() | ||
ids.SetNumberOfComponents(1) | ||
for cell_index, volume in res.element_volumes: | ||
ids.InsertNextValue(cell_index) | ||
|
||
selectionNode = vtk.vtkSelectionNode() | ||
selectionNode.SetFieldType(vtk.vtkSelectionNode.CELL) | ||
selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES) | ||
selectionNode.SetSelectionList(ids) | ||
selection = vtk.vtkSelection() | ||
selection.AddNode(selectionNode) | ||
extracted = vtk.vtkExtractSelection() | ||
extracted.SetInputDataObject(0, mesh) | ||
extracted.SetInputData(1, selection) | ||
extracted.Update() | ||
print("There are {} cells under {} m3 vol".format(extracted.GetOutput().GetNumberOfCells(), tol)) | ||
output.ShallowCopy(extracted.GetOutput()) | ||
|
||
Here we rely on ``pyvtk`` interface more than on Paraview adaptation, for legacy and reusability reasons. This is the reason | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean that we cannot access There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is exactly that. As I tried to launched it having |
||
for the full ``import vtk`` instead of ``from paraview import vtk``, the `vtkSelectionNode` being fully wrapped in paraview | ||
and not accessible otherwise. | ||
|
||
On line 7, we leverage ``mesh_doctor`` package to provide us with pairs of `(index,volumes)` of cells with volumes lower | ||
than tolerance `tol`. As input of *Programmable Python Filter* is wrapped in a `dataset_adapter.UnstructuredGrid`, we rely on | ||
the copy of the inital VTKObject `inputs[0].VTKObject` to ensure consistency with our ``pyvtk`` workflow. | ||
|
||
What follows is ``pyvtk`` steps in oder to convert into input struct and extract from the original mesh this list of cells. | ||
Eventually, the `extracted` selection is shallow-copied to the output and then accessible in ``Paraview``. An helper print | ||
is left and should be reported in *Output Message* of ``Paraview`` (and in launching terminal if exist). | ||
|
||
Using mesh_doctor as a paraview plugins | ||
____________________________________________ | ||
|
||
Another way of leveraging ``mesh_doctor`` in ``Paraview`` is to wrap it in a python plugin that would be loadable through the | ||
``Paraview`` interface under **Tools | Manage Plugins/Extensions** and **Load New** looking for ``mesh_doctor-pvplugin.py``. | ||
(see `Paraview How To <https://www.paraview.org/Wiki/ParaView/Plugin_HowTo#Using_Plugins>`_ for more details). | ||
|
||
The file ``mesh_doctor-pvplugin.py`` is located under the ``geosx_mesh_doctor`` module in GEOS. Once the plugin loaded and a mesh opened, | ||
it should appear in filter list as *Mesh Doctor(GEOS)*. It displays a parameter value box allowing the user to enter the volume he wants as | ||
threshold to select cells based on ``element_volumes`` capability. Once applied, it extracts selected set of cells as a new unstructured grid. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hacky I said 😝
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is installing it like this working for you? When I tried it seemed to me that there were some issue in the setup.py that did not allow for this to work. Basically I could not find the modules when trying to import them.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got this output
and I can checked afterwards that
checks
is in `/path/to/Paraview/lib/PythonX.X' but this need refactor/cleanup obv.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a workaround you can try while being in
mesh_doctor
directory conatining the.toml
which should produce de
dist/
directory with.whl
and.tar.gz
.The install command on the
.tar.gz
might also work, as