On this page | |
Since | 17.0 |
Overview ¶
The For Each LOP repeats a set of operations multiple times, offering options to alter parameters during each iteration. This node forms a block with a Begin Context Options Block node connected through its third input, and the nodes in between the start node and this node’s third input are the operations that will be repeated. Setting the Iteration method determines whether this node re-cooks the loop over a range of numbers or a list of primitive paths.
The start node is a context options node because the for-each block uses context option variables to hold the iteration counters. Unlike the For Each SOP nodes, this node does not intrinsically isolate the affected prims within the loop. It just the context option values, with the number or primitive path for each loop, and cooks the nodes.
This has several uses:
-
Generating a certain number of prims, attributes, edits, or whatever you need, automatically.
-
Applying a series of changes to a bunch of primitives.
-
Applying a series of changes to all variant sets on a bunch of primitives, or to all variants.
Note
The context option generated by a for-each block leaks through to the target of a Fetch LOP. Even though the hull does not encompass the fetched nodes, they should be considered within the block and are able to use the context options accordingly. This may or may not be expected behavior.
How to ¶
-
In the LOP network, press ⇥ Tab and choose For Each.
This puts down a block starting with a Begin Context Options Block node and ending with this node.
-
Wire the incoming node chain into the
foreach_end
node’s first input.If you are only adding to the stage (for example, creating new prims), you don’t need to wire anything into the
foreach_begin
. However, if you are modifying existing prims, you should also wire the incoming node chain into theforeach_begin
node’s input, so it’s available in the loop. -
Select For Each node at the end of the block (
foreach_end
). -
In the node’s parameters, choose the Iteration method.
-
In between the
foreach_begin
node and theforeach_end
node’s third input, wire in the LOP nodes you want to loop over.The For Each node cooks the block zero or more times (according to the Iteration method). The results are flattened and added as a sublayer over the incoming stage from the first input.
Loop variables ¶
On the nodes inside the block, you can access context options containing the current iteration number (ITERATION
) and the total number of iterations (NUMITERATIONS
).
Some iteration methods also set an ITERATIONVALUE
variable. The contents of the variable depends on the iteration method. For example, when iterating over primitives, the ITERATIONVALUE
contains the scene graph path of the current prim. See the help for the Iteration method parameter below.
Tip
You can rename the looping variables using parameters on the For Each node (see below). If you are nesting for-each loops, you should rename the variables so each loop level has different variable names, so you can tell them apart.
For example, if you had a “for each variant set” loop and inside that loop a “for each variant” loop, you might rename the outer variables to VARSET_ITERATION
and NUM_VARSETS
, and the inner variables to VARIANT_ITERATION
and NUM_VARIANTS
.
In expressions ¶
To get the value of a context option in an expression inside the loop, use @‹name›
, for example:
@ITERATION
or use the contextoption expression function:
contextoption("ITERATION")
For example, if you want to create 100 lights inside the /lights
prim, named /lights/light_0
to /lights/light_99
, you would put a Light node in the loop block and set its Primitive path to the following expression:
/lights/light_`@ITERATION`
(Remember in string parameters, you must surround expression code with backticks.)
In Python ¶
To get the value of a context option in Python inside the loop, use the hou.contextOption() function.
loopnum = hou.contextOption("ITERATION")
You may find it useful to use Python’s extensive library of string and path manipulation functions to pull information out of the ITERATIONVALUE
.
Do not use hou.setContextOption() in a loop. Context options propagate up the network chain, not down. If you want to define variables for use in expressions within the loop, use an Edit Context Options LOP at the end of looping part of the network (usually connected directly to the third input of the For Each LOP).
Tips ¶
-
Leave the Perform layer break parameter on in the Begin Context Options Block node at the start of the loop block.
Without this option enabled, any nodes above the Begin Context Options Block node would be included in each loop and uselessly combined with every other iteration (uselessly because the data will be the same on each cook).
-
Because this block uses context options to hold the iteration variables, it works quite differently from For-Each loops in other network types.
-
To edit every variant in a certain variant set on selected prims:
-
Make an outer “for each prim” loop over the prims. Set the Primitives parameter to select the prims you want to edit. Change the name of the
ITERATIONVALUE
variable in this loop toPRIMPATH
. -
Make an inner “for each variant” loop. Change the name of the
ITERATIONVALUE
variable in this loop toVARIANTNAME
. -
Now in the inner loop you can supply both the current primitive’s scene graph path as
@PRIMPATH
and the current variant’s name as@VARIANTNAME
in nodes to edit the variant.
-
Inputs ¶
First input
Connect the incoming stage to this input. The node flattens the results of looping over the nodes connected to the third input, and then overlays it as a new layer on this stage in the output.
Second input
The Iteration method has options to loop over prims/variant sets/variants from this input instead of from the first input. This lets you drive the iteration using a separate stage other than the stage being modified.
The data in this input is never included in this node’s output. It may be used as to drive iteration, depending on the Iteration method setting.
Third input
This input is re-cooked for each iteration. The node flattens together the layers generated on each iteration, and composes the flattened result onto the stage from to the first input.
Parameters ¶
Iteration Method
How this node loops/what it loops over.
For Number of Iterations
Loops a set number of times. Note that you can drive the number of iterations dynamically with an expression in the Iterations parameter.
This method sets ITERATIONVALUE
to the same value as ITERATION
(the current loop count, starting from 0).
For Each Primitive in First Input
Loops over each primitive selected by the primitive pattern in Primitives (from the first input).
This method sets ITERATIONVALUE
to the full path of the current prim.
This option is useful for performing edits on a set of primitives.
For Each Variant Set in First Input
Loops over each variant set on a certain prim (or prims). The primitive pattern in Primitives selects the prim(s) holding the variant sets (from the first input).
This method sets ITERATIONVALUE
to the name of the current variant set.
You can use this add variants to or remove variants from variant sets. You could also nest another For-Each loop inside using “For each variant in first input” to loop over each variant in each variant set.
For Each Variant in First Input
Loops over each variant in a named variant set on a certain prim (or prims). The primitive pattern in Primitives selects the prim(s) holding the variant sets (from the first input).
This method sets ITERATIONVALUE
to the name of the current variant.
This method does not change the variant selection.
For Each String in Parameter
Loops over each string provided in the Iterate Over Strings parameter. The number of iterations will be defined by the number of separate strings specified in the parameter.
This method sets ITERATIONVALUE
to the current string from the parameter.
You can also choose to drive iteration using data from the second input instead of the first input. If for some reason the things you want to loop over are in another node chain, you can connect it to the second input and use these options. Note that data from the second input is never included in this node’s output. It is only used to drive the iterations, if you choose one of the “in second input” options.
Iterations
When Iteration method is “For Number of Iterations”, this is the number of loops. (You can use an expression in this parameter to drive the number of loops based on something else.)
Primitives
When Iteration method is “For each primitive”, “For each variant set”, or “For each variant”, the prims to look at. You can drag primitives from the scene graph tree pane into this textbox to add their paths, or click the select button beside the text box to select the primitives in the viewer. You can also use primitive patterns for advanced matching, including matching all prims in a collection (using /path/to/prim.collection:‹name›
).
Variant Set
When Iteration method is “For each variant”, the name of the variant set to loop over.
Iterate Over Strings
When Iteration method is “For each string in parameter”, the list of strings to loop over. Individual strings are separated by white space. Quotes can be used around a string to incorporate white space into that value.
Combine Iterations
Separate Layers
Each iteration from the third input is added into a new sublayer stack in the output, sorted by strongest to weakest from the strongest (last) iteration, then strongest to weakest from the next strongest (second-to-last) iteration, and so on.
This includes layers from above a Layer Break node, which allows such layers to continue to provide context for all subsequent layers.
Separate Layers, File Layers Weakest
Like “Separate Layers” (above), except that any sublayers that refer to existing layer files on disk are ordered to be weaker than any layers authored purely in the LOP network.
This is useful when combining several LOP node streams where each stream begins with one of more file layers, then applies modifications to a new layer on top of that layer. After merging these streams, all the LOP-authored modification layers will be adjacent to each other in the sublayer list for the stage. This allows all these new layers to be flattened into a single layer by the USD ROP without also flattening the layers from disk. (In the regular Separate Layers mode, layers from disk would alternate with layers authored in LOPs, and each LOP layer would have to be saved to a separate new layer on disk.)
Note
This option can change the result of composing the stage if the opinions from layers on disk were intended to be stronger than opinions authored in the LOP network.
Separate Layers, File and SOP Layers Weakest
Like “Separate Layers, File Layers Weakest” (above), except that sublayers imported from SOP nodes are also sorted with files loaded from disk, appearing before any layers authored purely in the LOP network.
This is useful when you want the layers authored from SOPs to be saved to separate layers rather than flattened together with the layers authored in the LOP Network.
Flatten Layers
All layers from all iterations are flattened together into a single output layer.
Layers from above Layer Break nodes are removed prior to flattening and so do not contribute to the output.
Flatten Into First Input’s Active Layer
The layers from all the iterations are flattened into the active layer of the first input.
Layers from above Layer Break nodes other than on the first input are removed prior to flattening and so do not contribute to the output.
Flatten Each Input
For each iteration its layers are flattened, and then the flattened iterations are added to a new sublayer stack in the output.
Layers from above Layer Break nodes are removed prior to flattening and so do not contribute to the output.
Strip Layers Above Layer Breaks
Enable this option to remove all layers created above Layer Break nodes on every input to this node. This is the default option since usually a layer break operation is used to separate data generated by the For Each iterations from data authored prior to the For Each Begin node, and thus prevent duplicate copies of the data outside the loop from being added to the stage. However in some cases, such as when different iterations follow different cook paths, it may be useful to preserve the layers from above layer breaks. As noted in the Combine iterations description, some values of that parameter may cause layers from above layer breaks to be stripped in spite of this option being turned off.
Set Last Modified Primitives from Iteration input
Iteration Option Name
The name of the context option variable this node will create holding the current loop number (starting from 0). You can rename this for convenience or to make nested loops use unique names.
Iteration Count Option Name
The name of the context option variable this node will create holding the total number of loops. You can rename this for convenience or to make nested loops use unique names.
Value Option Name
The name of the context option variable this node will create holding Iteration method-specific information (the current iteration for “Number of iterations”, the current prim path for “For each primitive”, the variant set name for “For each variant set”, or the variant name for “For each variant”). You can rename this for convenience or to make nested loops use unique names.
Iteration Range
This lets you optionally restrict the number of iterations the node would normally perform to start and end within a certain range. This can be useful for debugging, to observe the effect of just a “slice” of the overall result.
All Iterations
Run all available iterations (the default, normal operation).
Single Iteration
Only run one iteration, specified in the First iteration parameter. The loop numbers start at 0
.
Range of Iterations
Only run a range of iterations, from the First iteration until the Last iteration (inclusive). For example, if you set Iteration method to “For number of iterations” and set the number to 5, you would get iterations 0, 1, 2, 3, and 4. If you then set Iteration range to “Range”, First iteration to 1, and Last iteration to 3, you would only get iterations 1, 2, and 3.
First iteration
When Iteration range is “Single”, only run this iteration number. When Iteration range is “Range”, only run a subset of iterations starting at this number. The first iteration is numbered 0.
Last iteration
When Iteration range is “Range”, only run a subset of iterations including but ending at this number. The first iteration is numbered 0.