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.