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
.obj
files - 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
- Contour rendering is experimental
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: