GridGroup

A GridGroup arranges objects in regular patterns — rows, 2D grids, rectangular borders, and curved arcs. It is anchorless: there is no central object, just a pattern laid out around the group’s own center. This is the tool for repeated furniture: classroom desks, auditorium seating, a row of lockers.

GridGroup patterns: row, grid, rectilinear, arc
The four patterns, laid out around the group's own center — no anchor: rows and grids share one orientation, border slots face inward, arc slots tilt along the curve.

with scene.GridGroup(sparsity=0.5) as classroom:
    chair = scene.AddAsset("a dark wooden dining chair")
    classroom.place_grid(6 * chair, cols=3)

place_row(objects)

Lays objects out in a single row along the X axis, evenly spaced.

grid row top-down grid row perspective

place_grid(objects, cols)

Fills a 2D grid row-major: objects are placed left-to-right, wrapping to a new row every cols objects.

Parameter Type Description
objects list Objects to arrange.
cols int Number of columns; rows are added as needed.

grid 2D top-down grid 2D perspective

place_rectilinear(width1, width2, depth1, depth2)

Arranges objects along the four sides of a rectangular border, leaving the middle open — a ring of seats around a meeting space, or chairs lining the walls.

Parameter Type Description
width1 list Top row (runs along X).
width2 list Bottom row (runs along X).
depth1 list Left column (runs along Z).
depth2 list Right column (runs along Z).

grid rectilinear top-down grid rectilinear perspective

place_arc(objects, towards=None)

Lays objects out in one or more curved rows, like theatre seating. With towards set, the arc curves around that target: rows are measured outward from the target’s boundary, and every object turns to face it — chairs gathered at a fireplace, an audience facing a lectern. Without a target, objects face the group’s own center.

Parameter Type Default Description
objects list required Objects to arrange.
towards object None If set, the arc wraps this target and each object faces it.
fireplace = scene.AddAsset("a brick fireplace with a glowing fire")
fireplace.set_location(0, -fireplace.get_aabb()[0, 1], -2.4)   # rest on the floor
with scene.GridGroup(sparsity=0.4) as seating:
    chair = scene.AddAsset("a dark wooden dining chair")
    seating.place_arc(8 * chair, towards=fireplace)
scene.bind(fireplace)
scene.bind(seating)

grid arc top-down grid arc perspective

The rows work like a theatre’s seating bank. The block is wide and shallow — few rows, long ones — with the front row the shortest and each row behind it holding more (the eight chairs above split 3 + 5). Seats across the whole bank share one linear pitch, so they fall on exact lateral columns, with alternate rows offset by half a pitch — a brick pattern that lets sightlines pass between the seats in front. Rows are gently bowed lines rather than circles around the target: each row’s curvature center sits well behind the focal point, so the wings pull toward it without ever wrapping around it, and the bank stands far enough back that no seat turns more than ~40° off the central axis. Every seat still faces the focal point individually. sparsity widens the seat-to-seat gap and the row-to-row gap.

One subtlety worth knowing: the arc’s geometry is computed when the group compiles. If a RoomGroup later repositions the group or the target, the room re-aims every arc object at the target’s final position automatically — positions stay frozen with the group, but the facing always ends up correct.

Parameters: sparsity and randomness

GridGroup(sparsity=..., randomness=...) accepts two layout controls, both in [0, 1], both deterministic under the scene seed.

sparsity — the gap between objects, as a fraction of their size. 0 packs them edge-to-edge; higher values open up space between them:

grid sparsity sweep

randomness — jitters the spacing and the facing so the arrangement looks organic instead of mechanical. 0 gives perfectly uniform gaps and exact formation facings; higher values introduce controlled variation. It works at any sparsity (positions wander and each object turns slightly off its row or arc facing, even in a tightly packed grid):

grid randomness sweep

with scene.GridGroup(sparsity=0.5, randomness=0.9) as g:
    chair = scene.AddAsset("a dark wooden dining chair")
    g.place_grid(9 * chair, cols=3)

grid randomness top-down grid randomness perspective

Rotational variation here is deliberately tame (up to about ±14° at randomness=1.0, versus ±30° for the anchored groups’ jitter dial, AroundGroup) — a grid should loosen, not dissolve; rows still read as rows.

Compilation

A GridGroup is deterministic: its layout is fully determined by the pattern (plus the seeded dials above), so compilation skips overlap and proportion optimization entirely, and the group freezes immediately.


Next: every arrangement so far still floats in empty space — RoomGroup gives it walls, doors, windows, and a floor plan to land on.


This site uses Just the Docs, a documentation theme for Jekyll.