Skip to content
Voro
  1. Geometry
  2. Render

Place

Place draws one shape many times. Give it a module, say how many variants of that module to build, and Place lays the copies out and renders them as one operator. A shelf of props in six colourways, a field of rocks in four sizes or a word spelled from its own letters, with the letters from Font, each take one Place.

Every copy is a row. A row carries a position, and it can also carry a rotation, a size, a colour tint and the number of the variant it draws. With nothing wired in, Place makes the rows itself from its Layout. Wire in points from a simulation, a POP network or another Voro operator and each point becomes a copy.

Place Place from the Geometry view of the Voro menu, under Render. It is a Geometry COMP, so it sits in a scene the same way a Geometry does.

  1. On the Place page, set Module to a module file, such as a prop’s main.py, or to its folder. Set Variants to how many versions you want.
  2. Add a Vary row for each module control that should differ between variants. Pick the control, then choose List and type values separated by spaces or commas, or choose Random and type a minimum and a maximum. List values cycle over the variants. Random draws one value per variant from Variant Seed, and the same seed gives the same variants.
  3. Choose a Layout and a Count. Each item is a row, and Variant Pick decides which variant it draws: Cycle takes them in order, Random picks one per item by Seed.
  4. In your Scene, add the Place to the Geometry selection. Keep the Place COMP’s render flag on. Any renderer that selects that Scene draws it.

Once the module is built, its own controls appear on Place’s Module page. Edits there reach every variant live, without a rebuild. A control that a Vary row drives greys out on the Module page, because Vary sets it per variant.

Move, turn or scale the whole Place on its Xform page, like any Geometry COMP. Give it a look with Material on the Look page. That page is the same as Geometry’s, Matched Materials rows included, and one material binding serves every variant.

In TouchDesigner, Place has three POP inputs. A wire always beats the matching control.

  • geometry replaces the Module. Each topology run of the mesh is one variant. A plain TouchDesigner mesh is one variant. Font gives one variant per distinct glyph on glyphs and one row per character on rows, so wiring both into Place spells the text. A Populate mesh gives one variant per member.
  • proxy gives each variant its pivot: one point per variant, with an optional rot quaternion. Leave it empty and the Pivot menu decides.
  • rows replaces the Layout. Each point is one copy. Place reads P and, when the POP has them, orient as a quaternion in x, y, z, w order, scale as one or three values, Cd as a tint and variant as the variant number.

The variant number rounds to the nearest whole number and counts from 0. A negative variant hides that copy, which is how you switch copies off without changing the row count.

Two more inputs come from other Voro operators, not TouchDesigner wires. Select them on Place’s Bindings page. variant is a list with one variant number per row and beats the rows’ variant attribute. attributes is a colour and material list, one line per row, and beats the rows’ Cd. Its format is in the Lab guide.

The scene output carries every copy to the Scene as scene objects, with their materials.

The Place page’s Module, Variants, Variant Seed and Vary controls build the variants, as described in Use. The rest of the page makes and shapes the rows.

  • Layout, Count, Spacing and Jitter only apply when nothing is wired into rows. Spacing is the distance between neighbours in every layout, so a Circle grows as Count rises.
  • Variant Pick only applies when neither the variant binding nor a variant attribute on the rows names a variant.
  • Pivot sets which point of each variant sits on its row. Bottom puts the centre of each variant’s underside on the row, so things stand on the floor. Auto uses the proxy when there is one and the origin otherwise.
  • Item Scale, Scale Random and Rotate Random apply to every row, wired or not. Each copy turns about its pivot.
  • Seed drives every random choice on the page. Change it to reshuffle the scatter, the jitter, the picks, the sizes and the turns together.

The Rays page decides how light treats the copies in Realtime Trace: whether the camera sees them, whether they cast shadows, whether they show up in indirect light and whether they emit light. The other renderers ignore it.

  • Each variant that has at least one row becomes one scene object, and a scene holds at most 256 objects in total. Place refuses a shape with more variants than that. Leave room for the rest of the scene.
  • A row that names a variant past the last one is an error, and the message names that row. Use a negative number to hide a copy.
  • Moving rows is cheap and happens every frame. When the number of rows or the variant list changes, Place regroups the rows once.
  • Place’s viewer shows the rows as points, not the meshes.
  • Place shows “waiting” while its module builds for the first time. That is not a failure.
  • A tint colours the whole copy. It cannot give different faces of one variant different colours.
  • For one mesh copied from TouchDesigner CHOP, DAT, SOP, POP or TOP instancing data, use Geometry’s native instancing instead. For copies that each keep their own state and behaviour, use Populate.

The Lab’s instancing guide in the Voro package, lab/AUTHORING_GUIDE/INSTANCING.md, covers the rest: writing Place into a graph file, matrix rows and the colour and material list format.

Inputs

  • geometry points
  • proxy points
  • rows points
  • variant image
    1
  • attributes image
    1 x 8
  • material scene
  • transform row
  • material0..14 scene
    15 slots

Outputs

  • scene scene required

Place

Layout (Layout) Menu op('place').par.Layout

Where items go when nothing is wired into rows: a Grid, a Line along x, a Circle facing out, or Scattered over the ground the Grid would cover.

Default:
0
Options:
Grid, Line, Circle, Scatter
Count (Count) Int op('place').par.Count

How many items the Layout makes.

Default:
16
Range:
1 to 10000
Spacing (Spacing) Float op('place').par.Spacing

The distance between neighbouring items, in every Layout.

Default:
1
Range:
0 to 10
Jitter (Jitter) Float op('place').par.Jitter

Nudges each item off its Grid, Line or Circle spot, up to this fraction of Spacing.

Default:
0
Range:
0 to 1
Variant Pick (Pick) Menu op('place').par.Pick

Which variant each item draws when nothing names one: Cycle takes them in order (0, 1, 2, ... then again), Random draws one per item by Seed.

Default:
0
Options:
Cycle, Random
Pivot (Pivot) Menu op('place').par.Pivot

The point of each variant that sits on its spot: Auto uses the module's proxy when it has one, Origin its origin, Bottom the centre of its underside.

Default:
0
Options:
Auto, Origin, Bottom
Item Scale (Scale) Float op('place').par.Scale

Every item's size.

Default:
1
Range:
0 to 10
Scale Random (Scalerandom) Float op('place').par.Scalerandom

How much each item's size varies by Seed: 0.5 is anywhere from half to one and a half.

Default:
0
Range:
0 to 1
Rotate Random (Rotaterandomx) Float op('place').par.Rotaterandomx

Turns each item by up to this many degrees either way about this axis, by Seed.

Default:
0
Range:
0 to 180
Rotate Random (Rotaterandomy) Float op('place').par.Rotaterandomy

Turns each item by up to this many degrees either way about this axis, by Seed.

Default:
0
Range:
0 to 180
Rotate Random (Rotaterandomz) Float op('place').par.Rotaterandomz

Turns each item by up to this many degrees either way about this axis, by Seed.

Default:
0
Range:
0 to 180
Seed (Seed) Int op('place').par.Seed

The seed of every random choice on this page: Random pick, Scatter, Jitter, Scale Random and Rotate Random.

Default:
0
Range:
0 to 1000

Rays

Camera (Raycamera) Toggle op('place').par.Raycamera
Default:
On
Options:
Off, On
Shadows (Rayshadows) Toggle op('place').par.Rayshadows
Default:
On
Options:
Off, On
Indirect (Rayindirect) Toggle op('place').par.Rayindirect
Default:
On
Options:
Off, On
Emits Light (Rayemit) Toggle op('place').par.Rayemit
Default:
On
Options:
Off, On