A Grasshopper plugin for Rhino 8 that generates volumetric labyrinth partitions from two editable curve networks. You draw two families of curves; BSSG computes the surface equidistant to both (the bisector of their distance fields) and splits the volume into two interpenetrating channel systems — the organization behind triply periodic minimal surfaces (TPMS), but driven by curves you can edit instead of a fixed equation.
Fourteen components in six tabs cover generation, diagnostics, curvature analysis, and export. Set A is always drawn red, set B cyan.
Requirements: Rhino 8 (Windows or macOS; the plugin relies on Rhino 8's built-in Python 3 runtime) and an internet connection for the first run.
- Locate the package file
BSSG-0.1.yak(shipped next to this README). - Install it in one of two ways:
- Drag and drop the
.yakfile onto an open Rhino window, or - run in a terminal:
"/Applications/Rhino 8.app/Contents/Resources/bin/yak" install BSSG-0.1.yak(Windows:"C:\Program Files\Rhino 8\System\Yak.exe" install BSSG-0.1.yak)
- Drag and drop the
- Restart Rhino. Grasshopper now shows a BSSG tab.
- The first time a BSSG component solves, Rhino provisions the Python packages it needs (numpy, scipy, scikit-image) — this one-time step can take a minute and needs internet. Everything after that is local.
The bssg geometry core ships inside the plugin; nothing else to install.
| Component | Role |
|---|---|
| BSSG Domain | Turns a bounding Brep + a resolution n into the sampling grid. n is the number of points along the longest edge (48 for drafts, 96+ for final geometry). |
| Component | Role |
|---|---|
| Skeleton Set | Wraps your curves as one skeleton family. Any Rhino curve works (sampled to a polyline). Label A (red) or B (cyan) — a dropdown appears automatically. |
| Skeleton Presets | Coded graph pairs for classic TPMS cells: Schwarz P and F-RD (the gyroid entry is a documented stub and reports why it is unavailable). Outputs both skeleton sets plus the matching bounding box. |
| Interpolate | Morphs between two skeleton states at parameter t (0..1). Curve counts must match; curves are paired by list order. Check Diagnostics near pinch events. |
| Component | Role |
|---|---|
| BSSG Field | Samples the difference field f = dA − dB on the grid. normalized = True gives f̂ = (dA−dB)/(dA+dB) in (−1, 1), useful for nested offset surfaces. |
| BSSG Extract | Marching-cubes iso-surface at tau (0 = the bisector wall). Welded, deterministic, no smoothing. Also emits a report. |
| BSSG Solve | The one-node wrapper: Brep + two skeleton sets + n + tau → mesh + report. Equivalent to Domain → Field → Extract. |
| Component | Role |
|---|---|
| Diagnostics | Topology of any mesh: connected components N, boundary loops L, genus G per component, plus warnings. A box-clipped wall is expected to be non-watertight. |
| Labyrinth Solids | The two void volumes as closed meshes, chosen by field sign (A or B, dropdown provided). Closed against the domain boundary. |
| Component | Role |
|---|---|
| Curvature | Jet-fitted per-vertex mean curvature H and principal curvatures K1 ≤ K2. Leave r unwired to use 3× the median edge length. I masks vertices at least k rings from the boundary rim. |
| Deviation Map | Colors the mesh by the curvature-deviation index ω — 0 (blue) means minimal-surface behavior, values at the cap saturate. Also reports ω statistics. |
| Compare | Hausdorff / mean / RMS distance and area excess against a reference mesh. |
| Report | Formats any upstream report JSONs into one readable panel text. |
| Export | Writes <path>.obj + <path>.json (report + settings echo). Nothing is written until you flip go to True. |
Single-component tab — see the Export row above.
- Drop Skeleton Presets and BSSG Solve.
- Wire
SA→SA,SB→SB,B→D; add slidersn = 48(integer) andtau = 0.0. - You get the Schwarz P cell wall. Panel on
Rshows the report.
Note: skeleton-set and field wires carry data objects with no viewport preview — only meshes draw. That is normal.
1 — Preset cell studies. With the quick-start definition: slide
tau to ±0.12 and watch volume shift between the two labyrinths; set
normalized = True and try tau = ±0.35 for relative-distance offset
surfaces; switch the T dropdown to F-RD for the second verified preset.
2 — Explicit chain. Replace Solve with Domain → Field → Extract to
expose every stage (identical result). Wire several R outputs into
Report for one combined panel.
3 — Your own curves. Draw two curve families in Rhino (start with
two skew lines in a box). Two Skeleton Set components (A and B),
box → D on BSSG Solve, n = 64. Move a curve — the wall follows.
If the sets touch, you get a near-tangency warning rather than a repair:
the curves are yours; BSSG only reports.
4 — Morph. Make a second state of set A (copy + move the curves),
wrap it in another Skeleton Set, and drive Interpolate (S0, S1,
slider t) into Solve's SA. The wall sweeps as t slides.
5 — Voids. Feed BSSG Field into Labyrinth Solids, side A
or B: closed solids of the two channel systems, ready for volume
takeoff or 3D printing checks (run them through Diagnostics —
watertight should be True).
6 — Minimality check. Curvature on an extracted wall (leave r
unwired, k = 2), then Deviation Map with its K1/K2 and
cap = 0.5. A Schwarz P cell renders mostly deep blue (ω near 0 —
quasi-minimal), with brighter bands only near the clipped boundary.
Compare two resolutions (n = 48 vs 96) to see discretization error
directly.
7 — Export. Export with M, R, a path, and a Boolean toggle
on go. Files are written only when go is True; the .json echoes
every setting so results can be regenerated.
- Units: world units of your Rhino document throughout; all radii and spacings are physical distances, never cell counts.
- Warnings, not repairs: degenerate inputs (touching sets, empty regions, non-watertight results) surface as component warnings; your inputs are never modified.
- Determinism: identical inputs give bitwise-identical meshes.
- Resolution: features smaller than the grid spacing can vanish, and a curve edit or iso-value change can pass through a topology change — re-check Diagnostics after big edits.
BSSG accompanies the paper "BSSG: Curve-guided design of volumetric
labyrinth partitions in Grasshopper" (M. Aghaei Meibodi, DART
Laboratory, University of Michigan). The geometry core is a pure-Python
library (bssg) included with the plugin and also usable standalone.