@@ -242,6 +242,75 @@ def from_vtk(path, **kwargs):
242242 ** kwargs
243243 )
244244
245+ def from_pyvista (obj , ** kwargs ):
246+ """Import a mesh from ``pyvista`` or ``vtk``.
247+
248+ Parameters
249+ ----------
250+ obj : pyvista compatible object
251+ Any object compatible with pyvista. Includes most ``vtk``
252+ objects.
253+
254+ Returns
255+ -------
256+ PolyMesh
257+ ``ipygany.PolyMesh`` object
258+
259+ Examples
260+ --------
261+
262+ Convert a pyvista mesh to a PolyMesh
263+
264+ >>> import pyvista as pv
265+ >>> from ipygany import PolyMesh
266+ >>> pv_mesh = pv.Sphere()
267+ >>> mesh = PolyMesh.from_pyvista(pv_mesh)
268+ >>> mesh
269+ PolyMesh(data=[Data(components=[Component(array=array([-6.1232343e-17,
270+ 6.1232343e-17, -1.0811902e-01, -2.1497…
271+
272+ """
273+ try :
274+ import pyvista as pv
275+ except ImportError :
276+ raise ImportError ('Please install ``pyvista`` to use this feature' )
277+
278+ from .vtk_loader import get_ugrid_data
279+
280+ # attempt to wrap non-pyvista objects
281+ if not pv .is_pyvista_dataset (obj ):
282+ mesh = pv .wrap (obj )
283+ if not pv .is_pyvista_dataset (mesh ):
284+ raise TypeError (f'Object type ({ type (mesh )} ) cannot be converted to '
285+ 'a pyvista dataset' )
286+ else :
287+ mesh = obj
288+
289+ # PolyMesh requires vertices and triangles, so we need to
290+ # convert the mesh to an all triangle polydata
291+ if not isinstance (obj , pv .PolyData ):
292+ # unlikely case that mesh does not have extract_surface
293+ if not hasattr (mesh , 'extract_surface' ):
294+ mesh = mesh .cast_to_unstructured_grid ()
295+ surf = mesh .extract_surface ()
296+ else :
297+ surf = mesh
298+
299+ # convert to an all-triangular surface
300+ if surf .is_all_triangles ():
301+ trimesh = surf
302+ else :
303+ trimesh = surf .triangulate ()
304+
305+ # finally, pass the triangle vertices to PolyMesh
306+ triangle_indices = trimesh .faces .reshape (- 1 , 4 )[:, 1 :]
307+
308+ return PolyMesh (
309+ vertices = trimesh .points ,
310+ triangle_indices = triangle_indices ,
311+ data = _grid_data_to_data_widget (get_ugrid_data (trimesh ))
312+ )
313+
245314 def reload (self , path , reload_vertices = False , reload_triangles = False , reload_data = True ):
246315 """Reload a vtk file, entirely or partially."""
247316 from .vtk_loader import (
0 commit comments