TPMS and lattice catalog#
pyvcad_metamaterials supplies seven periodic implicit cells and six graph cells. This guide compares those cells on the same rectangular maps, then uses ordinary CSG to fill more familiar part geometries.
Build a finite rectangular map#
Every catalog builder receives a CellMap first:
import pyvcad as pv
import pyvcad_metamaterials as mm
cell_map = mm.rectangular_cell_map(
(pv.Vec3(-15.0, -15.0, -15.0), pv.Vec3(15.0, 15.0, 15.0)),
cells=(3, 3, 3),
)
Use cells=(nu, nv, nw) when exact repetition count and phase matter. Use cell_size=... when approximate world spacing is more convenient. cell_size is converted to integer counts by rounding upward, so the requested world bounds remain exact and the realized spacing adjusts slightly to fit them.
TPMS catalog#
The names in mm.TPMS_NAMES can be passed to mm.tpms(...), and each also has a named helper such as mm.gyroid(...) or mm.schwarz_p(...).
The complete interactive gallery is 02_tpms_gallery.py.
Sheet and solid modes#
sheet = mm.gyroid(cell_map, mode="sheet", wall_thickness=1.6)
solid = mm.gyroid(cell_map, mode="solid", level=0.0)
In sheet mode, wall_thickness is the requested wall thickness in millimetres. In solid mode, level shifts the dividing surface and changes the retained labyrinth. Standard TPMS cells use the local map metric so those controls remain world-unit quantities when the cells are deformed.
See 01_tpms_gyroid.py for the side-by-side interactive example.
Graph lattice catalog#
Graph lattices use normalized vertices and edges, then map each repeated segment into world space. mm.LATTICE_NAMES lists the built-in catalog.
lattice = mm.octet(
cell_map,
beam_radius=0.8,
node_radius=0.9,
curve_tolerance=0.05,
)
beam_radius controls strut radius in millimetres. node_radius optionally overrides the joint radius; if omitted, joints follow the beam field. curve_tolerance controls subdivision of beams that become curved under a non-linear map.
See 03_strut_lattices.py for the complete interactive catalog.
Fill ordinary geometry#
Mapped structures are ordinary nodes, so lattice filling is an Intersection. Build a map over the target’s bounds, build the architected material, and clip it with the target geometry.
sphere = pv.Sphere(pv.Vec3(0.0, 0.0, 0.0), 16.0)
cell_map = mm.rectangular_cell_map(
(pv.Vec3(-17.0, -17.0, -17.0), pv.Vec3(17.0, 17.0, 17.0)),
cells=(4, 4, 4),
)
root = pv.Intersection(sphere, mm.gyroid(cell_map, wall_thickness=1.4))
For imported meshes, call prepare(...) before querying bounding_box(), then construct the rectangular map from the returned bounds. The complete examples are 04_lattice_in_shape.py, 10_benchy_gyroid_infill.py, and 11_teapot_lattice_infill.py.
Parameter summary#
Structure |
Topology |
Primary geometric controls |
|---|---|---|
TPMS sheet |
|
|
TPMS solid |
|
|
Graph lattice |
|
|
All of these scalar controls can also change across a design. Continue with Attribute-driven metamaterials to grade geometry, cell spacing, and material distribution.

















