3D models and CAD#

Custom 3D models#

Each Magpylib object has a default 3D representation that is displayed with show. Users can add a custom 3D model to any Magpylib object with help of the style.model3d.add_trace method. The new trace is stored in style.model3d.data. User-defined traces move with the object just like the default models do. The default trace can be hidden with the command obj.model3d.showdefault=False. When using the 'generic' backend, custom traces are automatically translated into any other backend. If a specific backend is used, it will only show when called with the corresponding backend.

The input trace is a dictionary which includes all necessary information for plotting or a magpylib.graphics.Trace3d object. A trace dictionary has the following keys:

  1. 'backend': 'generic', 'matplotlib' or 'plotly'

  2. 'constructor': name of the plotting constructor from the respective backend, e.g. plotly 'Mesh3d' or matplotlib 'plot_surface'

  3. 'args': default None, positional arguments handed to constructor

  4. 'kwargs': default None, keyword arguments handed to constructor

  5. 'coordsargs': tells magpylib which input corresponds to which coordinate direction, so that geometric representation becomes possible. By default {'x': 'x', 'y': 'y', 'z': 'z'} for the 'generic' backend and Plotly backend, and {'x': 'args[0]', 'y': 'args[1]', 'z': 'args[2]'} for the Matplotlib backend.

  6. 'show': default True, toggle if this trace should be displayed

  7. 'scale': default 1, object geometric scaling factor

  8. 'updatefunc': default None, updates the trace parameters when show is called. Used to generate dynamic traces.

The following example shows how a generic trace is constructed with Mesh3d and Scatter3d and is displayed with three different backends:

import numpy as np
import magpylib as magpy
import pyvista as pv

pv.set_jupyter_backend('panel') # improve rendering in a jupyter notebook

# Mesh3d trace #########################

trace_mesh3d = {
    'backend': 'generic',
    'constructor': 'Mesh3d',
    'kwargs': {
        'x': (1, 0, -1, 0),
        'y': (-.5, 1.2, -.5, 0),
        'z': (-.5, -.5, -.5, 1),
        'i': (0, 0, 0, 1),
        'j': (1, 1, 2, 2),
        'k': (2, 3, 3, 3),
        #'opacity': 0.5,
    },
}
coll = magpy.Collection(position=(0,-3,0), style_label="'Mesh3d' trace")
coll.style.model3d.add_trace(trace_mesh3d)

# Scatter3d trace ######################

ts = np.linspace(0, 2*np.pi, 30)
trace_scatter3d = {
    'backend': 'generic',
    'constructor': 'Scatter3d',
    'kwargs': {
        'x': np.cos(ts),
        'y': np.zeros(30),
        'z': np.sin(ts),
        'mode': 'lines',
    }
}
dipole = magpy.misc.Dipole(moment=(0,0,1), style_label="'Scatter3d' trace", style_size=6)
dipole.style.model3d.add_trace(trace_scatter3d)

magpy.show(coll, dipole, backend='matplotlib')
magpy.show(coll, dipole, backend='plotly')
magpy.show(coll, dipole, backend='pyvista')
../_images/506bcf3941f78ccedc0d1e92c4053d8797265061edc02d66095b055998962f62.png