Pyvista Bodies#
Pyvista is a powerful open-source tool for the creation and visualization of meshes. Pyvista PolyData
objects can be directly transformed into Magpylib TriangularMesh
magnets via the classmethod from_pyvista
.
Note
The Pyvista library used in the following examples is not automatically installed with Magpylib. A Pyvista installation guide is found here.
Dodecahedron Magnet#
In this example a Magpylib magnet is generated directly from a Pyvista body.
import numpy as np
import pyvista as pv
import magpylib as magpy
# Create a simple pyvista PolyData object
dodec_mesh = pv.Dodecahedron(radius=.01)
dodec = magpy.magnet.TriangularMesh.from_pyvista(
polarization=(0, 0, .1),
polydata=dodec_mesh,
)
# Add a sensor with path
sens = magpy.Sensor(position=np.linspace((-2,0,1), (2,0,1), 100)/100)
# Show system and field
with magpy.show_context(dodec, sens, backend='plotly') as s:
s.show(col=1)
s.show(col=2, output=['Bx', 'Bz'])
Boolean operations with Pyvista#
With Pyvista it is possible to build complex shapes with boolean geometric operations. However, such operations often result in open and disconnected meshes that require some refinement to produce solid magnets. The following example demonstrates the problem, how to analyze and fix it.
import pyvista as pv
import magpylib as magpy
# Create a complex pyvista PolyData object using a boolean operation
sphere = pv.Sphere(radius=0.006)
cube = pv.Cube(x_length=.01, y_length=.01, z_length=.01).triangulate()
obj = cube.boolean_difference(sphere)
# Construct magnet from PolyData object and ignore check results
magnet = magpy.magnet.TriangularMesh.from_pyvista(
polarization=(0, 0, .1),
polydata=obj,
check_disconnected="ignore",
check_open="ignore",
reorient_faces="ignore",
style_label="magnet",
)
print(f'mesh status open: {magnet.status_open}')
print(f'mesh status disconnected: {magnet.status_disconnected}')
print(f"mesh status self-intersecting: {magnet.status_selfintersecting}")
print(f'mesh status reoriented: {magnet.status_reoriented}')
magnet.show(
backend="plotly",
style_mesh_open_show=True,
style_mesh_disconnected_show=True,
)
mesh status open: True
mesh status disconnected: True
mesh status self-intersecting: False
mesh status reoriented: True
The result cannot be used for magnetic field computation. Even if all faces were present, the reorient-faces algorithm would fail when these faces are disconnected. Such problems can be fixed by
giving Pyvista a finer mesh to work with from the start
Pyvista mesh cleaning (merge duplicate points, remove unused points, remove degenerate faces)
The following code produces a clean magnet .
import pyvista as pv
import magpylib as magpy
# Create a complex pyvista PolyData object using a boolean operation. Start with
# finer mesh and clean after operation
sphere = pv.Sphere(radius=0.6)
cube = pv.Cube().triangulate().subdivide(2)
obj = cube.boolean_difference(sphere)
obj = obj.clean()
obj = obj.scale([1e-2]*3)
# Construct magnet from PolyData object
magnet = magpy.magnet.TriangularMesh.from_pyvista(
polarization=(0, 0, .1),
polydata=obj,
style_label="magnet",
)
print(f'mesh status open: {magnet.status_open}')
print(f'mesh status disconnected: {magnet.status_disconnected}')
print(f"mesh status self-intersecting: {magnet.status_selfintersecting}")
print(f'mesh status reoriented: {magnet.status_reoriented}')
magnet.show(backend="plotly")
mesh status open: False
mesh status disconnected: False
mesh status self-intersecting: False
mesh status reoriented: True