There will be a webinar on pyGIMLi hosted by SEG on March 19, 2024 at 4 pm CET. Register for free here.

Source code for pygimli.viewer.pv.utils

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pygimli as pg

pv = pg.optImport('pyvista', requiredFor="properly visualize 3D data")


pgVTKCELLTypes = {
    pg.core.MESH_EDGE_CELL_RTTI:     3,
    pg.core.MESH_EDGE_RTTI:          3,
    pg.core.MESH_EDGE3_RTTI:         21,
    pg.core.MESH_EDGE3_CELL_RTTI:    21 ,
    pg.core.MESH_TRIANGLE_RTTI:      5  ,
    pg.core.MESH_TRIANGLE6_RTTI:     22 ,
    pg.core.MESH_QUADRANGLE_RTTI:    9  ,
    pg.core.MESH_QUADRANGLE8_RTTI:   23 ,
    pg.core.MESH_TETRAHEDRON_RTTI:   10 ,
    pg.core.MESH_TETRAHEDRON10_RTTI: 24 ,
    pg.core.MESH_TRIPRISM_RTTI:      13 ,
    pg.core.MESH_TRIPRISM15_RTTI:    13 ,
    pg.core.MESH_PYRAMID_RTTI:       14 ,
    pg.core.MESH_PYRAMID13_RTTI:     14 ,
    pg.core.MESH_HEXAHEDRON_RTTI:    12 ,
    pg.core.MESH_HEXAHEDRON20_RTTI:  25 ,
}

[docs] def pgMesh2pvMesh(mesh, data=None, label=None, boundaries=False): """ pyGIMLi's mesh format is different from pyvista's needs, some preparation is necessary. Parameters ---------- mesh: pg.Mesh Structure generated by pyGIMLi to display. data: iterable Parameter to distribute to cells/nodes. """ if boundaries: mesh.createNeighbourInfos() if mesh.cellCount() == 0: ### mesh is already a boundary mesh return pgMesh2pvMesh(mesh, data, label) b = mesh.createSubMesh(mesh.boundaries([b.id() for b in mesh.boundaries() if b.outside() or b.marker() != 0])) return pgMesh2pvMesh(b, data, label) if mesh.cellCount() > 0: ids = [] for c in mesh.cells(): if c.rtti() == pg.core.MESH_TETRAHEDRON10_RTTI: # gimli still work with old zienk. counting ids.extend([len(c.ids()), *(c.ids()[[0,1,2,3,4,7,5,6,9,8]])]) else: ids.extend([len(c.ids()), *c.ids()]) grid = pv.UnstructuredGrid( np.asarray(ids), np.asarray([pgVTKCELLTypes[c.rtti()] for c in mesh.cells()]).flatten(), np.asarray(mesh.positions())) grid.cell_data['Cell Marker'] = np.asarray(mesh.cellMarkers()) elif mesh.boundaryCount() > 0: grid = pv.PolyData(np.asarray(mesh.positions()), faces=np.hstack([[len(b.ids()), *b.ids()] for b in mesh.boundaries()])) grid.cell_data['Boundary Marker'] = np.asarray(mesh.boundaryMarkers()) else: grid = pv.PolyData(np.asarray(mesh.positions())) # check for parameters inside the pg.Mesh for key, values in mesh.dataMap(): if len(values) == mesh.cellCount(): grid.cell_data[key] = np.asarray(values) elif len(values) == mesh.nodeCount(): grid.point_data[key] = np.asarray(values) # check the given data as well try: if data is not None: if len(data) == mesh.cellCount(): if label is None: label = 'Cell data' grid.cell_data[label] = np.asarray(data) elif len(data) == mesh.boundaryCount(): if label is None: label = 'Boundary data' grid.cell_data[label] = np.asarray(data) elif len(data) == mesh.nodeCount(): if label is None: label = 'Node data' grid.point_data[label] = np.asarray(data) else: pg.warn("Given data fits neither cell count nor node count:") pg.warn("{} vs. {} vs. {}".format(len(data), mesh.cellCount(), mesh.nodeCount())) except Exception as e: print(label) print(e) pg.error("fix pyvista mesh conversion") # print(grid.cell_data) # print(grid.point_data) if label is None: # last data that was added label = grid.array_names[-1] elif label not in grid.array_names: pg.warn("Given label '{}' was not found.".format(label)) label = grid.array_names[-1] grid.set_active_scalars(label) return grid