Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commite8beb5604c

README.md

core.concat (procNode)

Join several geometries into one: points, vertices and primitives end to end, links renumbered, every column any geometry holds.

One op, geometry.join, over the list of parts: the plan holds one node for the join however many parts and columns it has. The op reads what each part holds (its columns, their types and widths, its counts, its marks and labels) without moving any element, and the concat module in this node's folder decides every column of a class in one call: the type it takes (the type the first part with elements holds it as; a part that holds it at another width is refused by name, one that holds it as another type of the same width is cast by value), its description words, and what the elements of a part that holds no such column stand at: the value an element without the attribute has, the rest of the component field it feeds or the identity points.pose reads an instance attribute as (proc.translate.absentValue: orient and rot unrotated, scale and pscale 1, up +Y), else zero. A part laid among others reads its pose as it did alone. The link columns shift by what comes before: vertex.pt by the points of earlier parts, primitive.vstart by their vertices.

A numeric column some part holds on the device is joined by one dispatch of the concat kernel over every part, with one description run for every column of the join; a part's column on the CPU is written into that dispatch's table, and a part's run on the device is read where it stands. A numeric column every part holds on the CPU is joined there, and so is a column of a type the device cannot hold (text, a record), as a column of values; a part that holds no such column leaves its elements without a value. The counts are summed on the CPU, and nothing is read back. A part whose run is live on the device (rewritten as time moves) makes the join live: the rewrite that moves the part dispatches the join again.

Ids

The point id of each part moves past the ids of the parts before it, so every id of the result is unique. A part spans the larger of its next id and its point count. A part without an id column is numbered in order after them.

A point column that holds the id of another point is marked as one: attribute.set with ids = true marks it, and elements.link marks the parent it writes. Where some part holds ids, each part's values of a marked column move by the amount its ids move, a negative value (no point) stays, and a part without the column names nothing (-1). Where no part holds ids, the marked values refer to nothing the join renumbers and join as they are. A hierarchy built in two parts, each numbered from 0, keeps its parenting through the join.

Parts that count their elements on the device, when no part holds a column marked as holding point ids, are laid end to end on the device (proc.substrate.Geometry.merge), so the join reads no count: one dispatch writes where every part starts from the counts, and one dispatch of the concat kernel lays down each column. There a point's id becomes its id times the number of parts plus its part's place (from 0), and a part without an id column uses each point's number: a 9-point grid with no id joined before a 4-point line numbered 0 to 3 gives the grid the ids 0, 2, ..., 16 and the line 1, 3, 5, 7. Every id stays unique.

Labels

A detail labels names, per attribute, a list of values the elements' values of that attribute index (a population's labels.Mesh, the pieces its copies' Mesh numbers). The join lays every part's labels end to end per attribute, and each part's values of that attribute move past the labels of the parts before it, so every element keeps naming the label it named; a part without the attribute names none (-1).

Inputs

  • geometries (List<Geometry>). The geometries joined, in order.

Outputs

  • geometry: the joined geometry.

Example

local grid = g.mesh.grid({ size = { x = 2, z = 2 }, cells = { x = 2, z = 2 } })
local points = g.points.grid({ countX = 4, countZ = 1, spacing = 1 })
local joined = g.core.concat({ geometries = { grid, points } })

joined holds the grid's nine points followed by the line's four, and every point id is unique.