Viewer

The isoext.viewer module shows extraction results without leaving Python. It is built on viser, which installs together with isoext, and has two modes: a live server for interactive work, and serialized scenes for notebooks and static web pages, which is how the examples in this documentation are rendered.

Controls

Every view, embedded in a page or served live, uses the same controls: drag with the left mouse button to orbit, drag with the right button to pan, and scroll to zoom. On a touch screen, one finger orbits and two fingers pan and zoom. Click a view to give it keyboard focus, then W, A, S and D move the camera forward, left, back and right, Q moves it down and E moves it up. Embedded views start framed on their content; reload the page to reset the camera.

import isoext
from isoext import viewer
from isoext.sdf import TorusSDF

grid = isoext.UniformGrid([96] * 3)
torus = TorusSDF(R=0.6, r=0.25)
grid.set_values(torus(grid.get_points()))

v, f = isoext.marching_cubes(grid)
print(f"{v.shape[0]:,} vertices")
19,416 vertices

Live Viewing

show starts a local server and prints its URL; open it in any browser. The server keeps running until you stop it, so you can keep working while the mesh stays up.

server = viewer.show(v, f, port=8080)
server.stop()

To put several meshes in one scene, call add_mesh on the running server with different scene names:

server = viewer.show(v, f, name="/torus")
viewer.add_mesh(server, v2, f2, name="/sphere", color="seagreen")

Styling

Each mesh is drawn in one solid color, set by the color argument: either an RGB tuple with components in [0, 1] or a color name, like "coral" or "goldenrod". Names are resolved by matplotlib, so anything from its named colors list works. What you see on screen is that color under the scene’s lighting, so faces brighten and darken with their orientation. The default is a light blue.

The remaining options change how the triangles are drawn: flat_shading uses one normal per triangle instead of smoothing across vertices, which makes the tessellation visible; wireframe draws only the triangle edges; and side selects which triangle sides to render – use side="double" for open surfaces, which disappear from behind under the default backface culling.

viewer.embed(v, f, color="goldenrod", flat_shading=True, height=360)

Grid Overlay

For small demonstration grids, the viewer can draw the grid itself: pass grid= to show or embed, or call add_grid on a server. Gray lines are the cell edges; red dots mark corners inside the surface, blue dots corners outside. grid_level= sets the iso-value the colors compare against. See Working with Grids for a sparse grid example.

small = isoext.UniformGrid([12] * 3)
small.set_values(torus(small.get_points()))

v_small, f_small = isoext.marching_cubes(small)
viewer.embed(v_small, f_small, grid=small, wireframe=True, height=360)

Static Scenes

embed returns an IPython IFrame for notebooks. It writes the serialized scene and viser’s self-contained client under _static/ next to the notebook and references them with relative URLs, so executed notebooks stay interactive when rendered to HTML and hosted statically – every example in this documentation works this way.

Outside notebooks, save_scene writes a .viser scene file and copy_client provides the player page. Putting both in one directory gives a self-contained scene you can host anywhere:

viewer.copy_client("scene/")   # writes scene/index.html
viewer.save_scene("scene/torus.viser", v, f, color="goldenrod")
# serve scene/ and open index.html?playbackPath=torus.viser

The full argument list for every function is in the viewer section of the API reference.