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(...).

Gyroid TPMS
Gyroid
I-WP TPMS
I-WP
Lidinoid TPMS
Lidinoid
Neovius TPMS
Neovius
Schwarz-D TPMS
Schwarz-D
Schwarz-P TPMS
Schwarz-P
Split-P TPMS
Split-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)
Gyroid sheet mode
Sheet mode: a wall around the level surface
Gyroid solid mode
Solid mode: one labyrinth side of the level surface

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.

Cubic graph lattice
Cubic
BCC graph lattice
BCC
FCC graph lattice
FCC
Kelvin graph lattice
Kelvin
Octet graph lattice
Octet
Diamond graph lattice
Diamond
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))
Sphere filled with a gyroid
Gyroid clipped to a sphere
3DBenchy filled with a gyroid
3DBenchy with gyroid infill
Utah teapot filled with an octet lattice
Utah teapot with octet infill

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

ImplicitUnitCell

wall_thickness, level, map cell count/spacing

TPMS solid

ImplicitUnitCell

level, map cell count/spacing

Graph lattice

GraphUnitCell

beam_radius, node_radius, curve_tolerance, map cell count/spacing

All of these scalar controls can also change across a design. Continue with Attribute-driven metamaterials to grade geometry, cell spacing, and material distribution.