Builtin Library
README.md
grid
A grid is space cut into cells: a geometry whose points are the centres of its cells, laid out x fastest, then y, then z, and whose point columns are its channels (a density, a distance, a height, a colour). A grid one cell thick along an axis is flat: the height over a ground, an image.
Because a grid is a geometry, everything that works on points works on its
cells. attribute.set writes a channel from any field, attribute.accumulate
totals one, attribute.promote folds one into a single value. These ops add
what knowing the layout gives:
grid.box: a grid of cells filling a box. Give it a cell count per axis, or a cell size.grid.cell_index: which cell each position falls in (-1 outside), as a field.grid.neighbor_index: the cell a fixed step away from each cell, held to the grid's edge, as a field.grid.sample: a channel read at every point of a geometry, blended between the eight cell centres around it.
procgen.searchNodes("", { pack = "grid" }) lists the family and procgen.describeNode("op.<id>")
describes any one of them.
Particles deposited into cells, then read back by the particles:
local sparks = g.op.attribute.set({ domain = g.op.points.sphere({ count = 200 }), name = "mass", value = 1 })
local air = g.op.grid.box({ size = { x = 4, y = 3, z = 4 }, cells = { x = 32, y = 24, z = 32 } })
local cell = g.op.grid.cell_index({ grid = air })
local dense = g.op.attribute.scatter({ geometry = air, source = sparks, index = cell, name = "mass", as = "density" })
local felt = g.op.grid.sample({ geometry = sparks, grid = dense, name = "density" })
A blur along x is two neighbours gathered and averaged:
local right = g.op.grid.neighbor_index({ grid = dense, offset = { x = 1, y = 0, z = 0 } })
local left = g.op.grid.neighbor_index({ grid = dense, offset = { x = -1, y = 0, z = 0 } })
local a = g.op.attribute.gather({ geometry = dense, index = right, name = "density", as = "r" })
local b = g.op.attribute.gather({ geometry = a, index = left, name = "density", as = "l" })