Note
Go to the end to download the full example code.
Visualizing geometries¶
Now that you can build a geometry (Your first B-spline), this tutorial
shows how to see it. PaNTr’s pantr.viz module turns B-spline, Bézier, and
THB-spline geometries into PyVista meshes backed by
native VTK Bézier cells that store the exact polynomial geometry. The interactive
viewer below subdivides those cells for display, and a .vtu opened in ParaView
(>= 5.10) renders them as exact Bézier cells, tessellated at ParaView’s chosen
Nonlinear Subdivision Level. The toolkit is reused throughout the rest of the
tutorials:
plot()– one-call interactive viewing,Scene– compose several geometries with per-geometry options,control polygons and knot lines overlaid on the geometry,
scalar fields drawn as a colour map or an elevation surface,
save()– export to a.vtufile for ParaView.
Requires the viz extra: pip install "pantr[viz]". The Visualization
guide covers every rendering option in depth.
import tempfile
from pathlib import Path
import numpy as np
from pantr import viz
from pantr.bspline import Bspline, BsplineSpace, BsplineSpace1D, get_greville_abscissae
from pantr.cad import create_circle, create_disk
A curve with its control polygon and knot lines¶
create_circle() builds an exact circle as a rational quadratic
(NURBS) curve. show_control_polygon draws the control net; show_knot_lines
marks the images of the interior knots.
arc = create_circle(radius=1.0, angle=(0.0, 1.5 * np.pi))
viz.plot(arc, show_control_polygon=True, show_knot_lines=True)

<pyvista.plotting.plotter.Plotter object at 0x71ecbb6cd280>
A surface, knot lines on the geometry¶
For a surface the knot lines become iso-parametric curves lying on the surface.
disk = create_disk(radius_outer=1.0)
viz.plot(disk, color="lightsteelblue", show_knot_lines=True)

<pyvista.plotting.plotter.Plotter object at 0x71ecb7b4aab0>
Scalar fields: colour map vs. elevation¶
A rank-1 geometry is a scalar field f(u, v). By default it is drawn as a flat
colour map; elevation=True lifts the value into the third coordinate. Here we
build a biquadratic field whose coefficients sample sin(pi u) sin(pi v).
space = BsplineSpace([BsplineSpace1D([0, 0, 0, 0.5, 1, 1, 1], 2) for _ in range(2)])
greville = get_greville_abscissae(space.spaces[0])
gu, gv = np.meshgrid(greville, greville, indexing="ij")
coeffs = (np.sin(np.pi * gu) * np.sin(np.pi * gv))[..., np.newaxis]
field = Bspline(space, coeffs)
viz.plot(field, elevation=True, show_knot_lines=True)

<pyvista.plotting.plotter.Plotter object at 0x71ecb7b4aae0>
Composing a scene¶
Scene overlays several geometries, each with its own options.
scene = viz.Scene()
scene.add(disk, color="wheat", opacity=0.5)
scene.add(arc, color="crimson", show_control_polygon=True)
scene.show()

<pyvista.plotting.plotter.Plotter object at 0x71ecc41c9880>
Exporting to VTK¶
save() writes a .vtu file that ParaView (>= 5.10) renders with
exact Bézier geometry – handy for publication figures. In ParaView, switch the
representation to Surface With Edges to see the knot lines: it draws the cells’
curved edges, dynamically tessellated at the chosen Nonlinear Subdivision Level.
out_file = Path(tempfile.gettempdir()) / "pantr_disk.vtu"
viz.save(disk, out_file)
print(f"wrote {out_file}")
wrote /tmp/pantr_disk.vtu
Total running time of the script: (0 minutes 1.160 seconds)