- Geometry
- Render
Populate
Purpose
Section titled “Purpose”Populate places a network you built once as many members. Each member runs its own copy of that network with its own state and clock. Binding rows decide what each member’s controls read, so a handful of rows can vary fifty members.
Reach for Populate when the copies have to keep their own state and behaviour. Copies that only differ in their controls need no Populate: Place builds those variants for you. The Populations guide walks through the whole workflow.
- Build one member as a normal network of Voro operators inside a COMP. Test it on its own first.
- Place Populate from the Geometry view of the Voro menu, under Render. Its Status reads “Select a member source”.
- Set Member Source to that COMP. Status moves through compiling and admission, then reports the member count.
- Set Count. Add Binding rows for the controls that should differ between members, and Publication rows for the outputs you want to use outside the population.
- To couple members to each other or to the world, add a Relation.
After you edit the member network in place, press Refresh Member. Changing Member Source to another network admits the population again.
Inputs and outputs
Section titled “Inputs and outputs”Populate has no wires of its own. A member’s inputs come from its Binding rows, and its outputs leave through Publication rows under the public names you give them. Other operators pick those names from their menus, and a Relation reads and writes them.
A Publication row set to Member gives one publication per member. Shared gives one packed publication with a member axis.
Populate presents its members through a Geometry operator that the host creates when the population is admitted. Presentation Geometry shows which one, and Locate Presentation Geometry selects it in the network.
Controls
Section titled “Controls”Reset Population and Run. Reset Population returns every live member to its initial state and restarts every relation grouped with it, so a member and the relation correcting it start from the same moment. It does not add or remove members. Run off holds the population and everything grouped with it. Work already under way finishes, members keep their state, and Emit, Retire and Reset still queue up for when you turn Run back on.
Count, Capacity and Seed. Count is how many members the population starts with. Capacity is how many member rows the Engine allocates. Leave it at 0 to allocate exactly Count, or set it higher if you plan to emit members while it runs. Seed makes seeded bindings repeat the same values run to run.
Changing membership while it runs. Emit Members creates Emit Count new members inside Capacity. Retire Member and Reset One Member act on the member whose handle you type into Member Handle. Inspect Member lists the handles. Lifecycle Packets does the same job from the network: pick an operator whose published points are read as birth, retire and reset commands, one per row.
Bindings. Each row binds one control or input of the member network. The mode decides where the value comes from:
- constant gives every member the same value.
- sequence gives member
ithe value ati % length, so a short list repeats. - seeded draws a value per member between a minimum and a maximum, from Seed and the member index.
- resource reads another operator’s output, such as a static mesh, a field or another population’s publication. Input Semantics chooses whether every member reads the whole publication or each member gets its own row.
Write the Value field as JSON. A constant is a single value such as 0.5. A sequence is a list such as [0.2, 0.5, 0.9], and seeded takes [min, max].
Binding rows repeat too. With ten rows and fifty members, member i uses row i % 10. That is on purpose. If you need fifty different values, give one row a sequence of fifty values.
Relations. Relation Assignments lists the relations this population takes part in. Expose Relations brings them onto the network as operators you can see and edit.
Status on the Voro page is the number to trust. It reports the Count you asked for, the rows the Engine admitted and the members alive right now, then births, retirements, refusals and the last refusal reason. If Count says 50 and Status says 10 rows admitted, read the refusal text.
An Emit that would go past Capacity is refused as a whole and changes nothing. Handles are never reused. A retired member’s row goes to the next birth under a new handle, so an old handle is refused instead of acting on a different member.
Reset One Member restarts only that member. Its siblings and its relations keep running, and it picks up their output from where they are now. Use Reset Population when the member and its relations should restart together.
A population does not step until at least one of its members’ inputs has published something. A population whose only input is its own feedback from a Relation cannot start. Give the member one input that publishes from the first pass, such as a static mesh.
Bypass takes the population out of the network’s plan. It keeps its identity and settings, and Status reads “Bypassed; excluded from the plan”.
Declarations, per-member spans and the relation packet contract are in the Lab’s Populations guide, lab/AUTHORING_GUIDE/POPULATIONS.md in the Voro package.
Parameters
Section titled “Parameters”Populate
op('populate').par.Reset Restart this population and every owner grouped with it in one interaction scope: each live member returns to its initial state and its relations restart with it, so a member and the contact that corrects it agree about time again. Membership is unchanged -- no member is born or retired. The Voro page Reset State currently reaches the same engine call from the module side; this is the one to use, because it is the one that names what it resets.
- Default:
None
op('populate').par.Run Off holds this population and everything grouped with it at the next scheduler pass; work already dispatched finishes. Emit, Retire and Reset are still accepted while held and take effect on release. Hold is not Bypass: the members keep their state.
- Default:
On- Options:
- Off, On
op('populate').par.Membersource Path to the member network this population places, once per member. Every operator inside it becomes part of one member. Changing this re-admits the population; use Refresh Member for an edit inside the same network.
- Default:
None
op('populate').par.Refreshmember Re-read the member network and its parameters after editing it in place. This is a template refresh, not a reset: member state and membership are untouched.
- Default:
None
op('populate').par.Count How many members this population starts with. Count seeds membership at admission; afterwards Emit and Retire move live membership within Capacity without re-admitting the graph. Status reports what was actually admitted, which is the number to trust.
- Default:
8
op('populate').par.Capacity The number of member rows the Engine allocates. Births past Capacity are refused rather than reallocating under a running simulation. 0 allocates exactly Count, so leave room here if you intend to Emit.
- Default:
0
op('populate').par.Seed Base value for seeded bindings, so a population is reproducible run to run. Each member derives its own value from this and its member index.
- Default:
0
op('populate').par.Emitcount How many members one Emit Members pulse tries to create. A request past Capacity is refused as a whole and changes nothing.
- Default:
1
op('populate').par.Emit Create Emit Count new members now, inside Capacity, without re-admitting the graph. Each gets a new Engine handle; a reused storage row is never a reused identity. Status reports how many were admitted or refused.
- Default:
None
op('populate').par.Memberhandle The Engine handle of one live member, which Retire Member and Reset One Member act on. Handles are shown by Inspect Member; a handle is session-unique and is never reissued, so a stale one is refused rather than hitting someone else.
- Default:
"" (Empty String)
op('populate').par.Retire Retire the member named by Member Handle. Its siblings keep their own state and clocks; its storage row is reused by a later birth under a new handle.
- Default:
None
op('populate').par.Resetmember Return the member named by Member Handle to its initial state and advance its reset epoch. Only that member: its siblings are untouched, and relations grouped with this population keep running, so the member re-reads their packets from wherever they are now. Use Reset Population to restart them together.
- Default:
None
op('populate').par.Relationowners Which relations this population participates in. A relation is what couples members to each other or to the world; a data wire alone does not group them for Run, Hold and Reset.
- Default:
None
op('populate').par.Exposerelations Bring the relations this population participates in onto the network as operators you can see and edit.
- Default:
None
op('populate').par.Inspectmember Open the runtime view of this population: live membership, each member handle and reset epoch, per-member bindings, and the last refusal with its reason.
- Default:
None
op('populate').par.Migrationtarget The Geometry operator this population publishes its members through. Written by the host when the population is admitted; read-only here.
- Default:
None
op('populate').par.Navigatemigration Select and show the Presentation Geometry above in the network.
- Default:
None
Bindings
op('populate').par.BindingLabel The name this binding is published under, so a host or another operator can address it.
- Default:
"" (Empty String)
op('populate').par.BindingValue A constant, a comma-separated sequence, or Min, Max for random. A sequence shorter than Count repeats; it does not refuse.
- Default:
0
Publications
op('populate').par.PublicationPublicname The name this population publishes that output under.
- Default:
"" (Empty String)