Shape Collections¶
The ShapeCollection is a utility that lets you build complex 2D or 3D geometry by combining predefined shapes, custom meshes, and transformed objects. These collections are typically used with app.mesh() to create a mesh visual.
Overview¶
- Add basic geometric shapes: squares, cubes, spheres, etc.
- Transform each shape independently (offset, scale, 4×4 matrix)
- Load shapes from
.objfiles - Generate surfaces from height maps or triangulated polygons
- Use in a mesh visual with lighting, textures, contours, or isolines
Usage¶
sc = dvz.ShapeCollection()
sc.add_cube(offset=(0, 0, 0), scale=1.0)
visual = app.mesh(sc, lighting=True)
After use, destroy the shape collection to free resources:
sc.destroy()
Supported Shapes¶
| Shape | Method | Notes |
|---|---|---|
| Square | add_square() |
2D quad in XY plane |
| Disc | add_disc() |
Circular disc with resolution |
| Sector | add_sector() |
Arc segment between two angles (2D disc slice) |
| Cube | add_cube() |
Axis-aligned 3D cube |
| Sphere | add_sphere() |
Specify rows, cols for resolution |
| Tetrahedron | add_tetrahedron() |
Platonic solid |
| Hexahedron | add_hexahedron() |
Cube variant |
| Octahedron | add_octahedron() |
Platonic solid |
| Dodecahedron | add_dodecahedron() |
Platonic solid |
| Icosahedron | add_icosahedron() |
Platonic solid |
| Cone | add_cone() |
Cone with cap |
| Cylinder | add_cylinder() |
Cylinder with caps |
| Arrow | add_arrow() |
Cylinder + cone composite |
| Torus | add_torus() |
Donut shape with tubular cross-section |
Custom Geometry¶
Polygon¶
sc.add_polygon(points, contour='full')
points: Nx2 array of polygon vertices- Uses earcut triangulation internally
Warning
There may be visual artifacts along the contours of highly irregular polygons, such as those derived from geographical data. These can be addressed with a more robust triangulation algorithm. Improvements are planned for a future release.
Surface¶
sc.add_surface(heights, colors)
- Heights: 2D array of Z-values
- Colors: 2D RGBA array (same shape)
- Generates a triangulated surface patch
OBJ Import¶
Load external 3D geometry from a Wavefront OBJ file:
sc.add_obj("models/teapot.obj", scale=0.5)
This loads all vertices and faces into the shape collection.
Transformations¶
Each shape can be transformed individually:
offset: a 3D translation(x, y, z)scale: a uniform scalartransform: a 4×4 transformation matrix (overrides offset/scale)
Colors¶
Each basic shape accepts a uniform color argument for the shape.
Finalizing¶
After building your collection, use:
visual = app.mesh(sc, lighting=True, contour=True)
And after you're done using it:
sc.destroy() # Frees memory
Example¶
import numpy as np
import datoviz as dvz
rows = 12
cols = 16
N = rows * cols
t = np.linspace(0, 1, N)
x, y = np.meshgrid(np.linspace(-1, 1, rows), np.linspace(-1, 1, cols))
z = np.zeros_like(x)
offsets = np.c_[x.flat, y.flat, z.flat]
scales = 1.0 / rows * (1 + 0.25 * np.sin(5 * 2 * np.pi * t))
colors = dvz.cmap('hsv', np.mod(t, 1))
sc = dvz.ShapeCollection()
for offset, scale, color in zip(offsets, scales, colors):
sc.add_cube(offset=offset, scale=scale, color=color)
app = dvz.App()
figure = app.figure()
panel = figure.panel(background=True)
arcball = panel.arcball(initial=(-1, -0.1, -0.25))
visual = app.mesh(sc, lighting=True)
panel.add(visual)
app.run()
app.destroy()
sc.destroy()
Summary¶
The ShapeCollection system is a powerful way to build reusable geometry for the mesh visual.
- ✔️ Add and transform 2D/3D primitives
- ✔️ Generate and combine triangulated surfaces
See also: