Triply Periodic Minimal Surfaces (TPMS)

Gyroid

from microgen import Tpms
from microgen.shape.surface_functions import gyroid

geometry = Tpms(
    surface_function=gyroid,
    density=0.30,
    resolution=30,
)
shape = geometry.generate_surface_mesh(type_part="sheet")
shape.save("gyroid.stl")
../_images/gyroid.png

TPMS available

from pathlib import Path

import numpy as np
import pyvista as pv

from microgen import Tpms
from microgen.shape import surface_functions

surfaces = [
    surface_functions.neovius,
    surface_functions.gyroid,
    surface_functions.schwarz_d,
    surface_functions.schwarz_p,
    surface_functions.honeycomb,
    surface_functions.schoen_iwp,
    surface_functions.schoen_frd,
    surface_functions.fischer_koch_s,
    surface_functions.pmy,
]

meshes = []

i = 0
n_col = 3
n_row = np.ceil(len(surfaces) / n_col)
for i, surface in enumerate(surfaces):
    i_x = i % n_col
    i_y = i // n_col

    elem = Tpms(
        surface_function=surface,
        offset=0.3,
        resolution=50,
    )

    # center = (1.2 * (i_x - 0.5 * (n_col - 1)), -1.2 * (i_y - 0.5 * (n_row - 1)), 0)
    mesh = elem.sheet
    mesh.translate(
        [1.2 * (i_x - 0.5 * (n_col - 1)), -1.2 * (i_y - 0.5 * (n_row - 1)), 0],
        inplace=True,
    )
    meshes.append(mesh)

vtm_file = Path(__file__).parent / "surfaces.vtm"
pv.MultiBlock(meshes).save(vtm_file)
# pv.MultiBlock(meshes).plot(color="w")
../_images/tpms.png

Spherical gyroid

from pathlib import Path

import pyvista as pv

from microgen import Tpms, surface_functions

geometry = Tpms(
    surface_function=surface_functions.gyroid,
    offset=0.3,
    repeat_cell=3,
    resolution=30,
)
shape = geometry.generate_surface_mesh(type_part="sheet")
shape = shape.flip_faces()

sphere = pv.Sphere(radius=1.45)

result = shape.boolean_intersection(sphere)
vtk_file = Path(__file__).parent / "tpmsSphere.vtk"
result.save(vtk_file)
# result.plot(color='w')
../_images/tpms_sphere.png

Shell

from pathlib import Path

from microgen import Tpms, surface_functions
from microgen.cad import make_box, make_compound

# Outer 3x3x3 box, hollowed by subtracting an inner 2.8x2.8x2.8 cavity —
# replaces the CadQuery ``Workplane.shell`` API.  The face-selective version
# ("open on +Z, -X, +X") could be reproduced with ``BRepOffsetAPI_MakeThickSolid``
# via OCP, but a plain symmetric shell is enough for this demo.
outer = make_box((3.0, 3.0, 3.0), (0.0, 0.0, 0.0))
inner = make_box((2.8, 2.8, 2.8), (0.0, 0.0, 0.0))
shell = outer.cut(inner)

geometry = Tpms(
    surface_function=surface_functions.gyroid,
    offset=0.5,
    repeat_cell=3,
    resolution=15,
)
shape = geometry.generate_cad(type_part="sheet", smoothing=0)

compound = make_compound([shell, shape])
stl_file = str(Path(__file__).parent / "tpms_shell.stl")
compound.export_stl(stl_file)
../_images/tpms_shell.png