Overview 概述
Normally, Houdini processes the nodes in a geometry network from top to bottom, feeding the output of each node into the input of the next node, down to the node with the display or render flag. However, there are times when it’s useful to do looping: running the same chain of nodes multiple times.
There are three main uses for looping:
有三种主要的循环方式:
You want to process the input geometry over and over again.
For example, you might want to add multiple layers of noise, or create complex procedural geometry by extruding all faces multiple times.
第一种,反复对输入几何执行运算。例如,你想添加多个nosie层,或多次挤压表面创建复杂的程序化几何。
You want to process each piece of the input geometry.
For example, you might want to apply the same edits to each rock in some rubble.
第二种,对输入几何体的每个部分都执行运算。例如,你可能想应用同样的操作在每一块岩石上。
You want to process one geometry using each piece of another geometry.
The classic example of this is the “Swiss cheese problem”: you want to loop over each sphere in the set of air bubbles and subtract it from a block of cheese.
第三种,使用一个几何体的每一部件对另一几何体执行相同运算。经典案例“瑞士奶酪问题”:你想循环执行空气泡泡中的每一个球体从奶酪中去除。
The “For Loop” and “For Each Loop” tools in the network editor tab menu set up Block Begin and Block End nodes, where the nodes between the begin and end are looped. These tools are meant to be easier to use than previous looping solutions in Houdini, the For Each subnet and Solver SOP.
在网络编辑器面板中的“For Loop”与“For Each Loop”工具设置Block Begin与Block End 节点,位于其间的节点会被循环操作。这些工具比之前Houdini版本中的循环解决方案ForEach子网络与Solver SOP简单些。
1.In the network editor, open the Tab menu and choose “For loop”.
1.在网络编辑器中,按Tab,选择“For loop”。
The tool will create a Block Begin and Block End node wired together. The Block Begin has the Method parameter set to “Fetch feedback”, meaning it will start each loop after the first with the output of the previous loop.
这个工具会创建一个将Block Begin 与 Block End连接在一起的节点。在Block Begin节点中有Method 参数设置“Fetch feedback”,意为着它将循环第一次之后的每一次输出结果。
2.Select the Block End node and set the Iterations parameter to the number of times you want the loop to run.
2.选择Block End节点设置Iterations参数指定你想要循环的次数。
Warning
You should probably start with just 1 or 2 iterations at first until you know the loop is working they way you want. It’s possible to unintentionally create a loop that operates on all geometry andcreates new geometry in each loop, exponentially increasing the geometry size and cooking time. Note that if Houdini gets stuck in a long cook you can press Esc to cancel the cook.
在初次循环时,迭代次数建议设置为1或2直到你确定循环流程是你想要的。不小心循环所有几何体并且每次循环都创建新的几何体,几何体的数据量以及烘焙时间呈指数型增长,这也是有可能的。注意如果Houdini被困在一个很长的烘焙操作中,按Esc可以停止烘焙。
Wire the geometry you want to process into the Block Begin.
将你想要执行的几何连上Block Begin。
Wire the nodes to process the geometry between the Block Begin and Block End.
在Block Begin与Block End之间连入你想要对几何操作的节点。
In this example, we simply do two iterations of extruding and scaling every face of a box.
在这个节点,我们简单的对一个Box的表面迭代两次执行挤出并缩放操作。
Note
The point of this type of loop is that the output of one loop becomes the input for the next loops, so any geometry you create in the loop will accumulate. If all you want is to apply the same nodes once to multiple copies, you want the Copy node.
这种类型的循环重点是这次循环的输出变成下一次循环的输入。如果你想将同一个节点一次应用到多份,你要使用Copy节点。
A “piece” is usually defined as the primitives that have the same value of the piece or name attribute. Several tool such as Shatter create this type of partition attribute for you. You can specify an attribute name other than piece using the Template attribute parameter on the Block End node (this parameter is only available when the Block Begin’s input is connected).
一个“块”通常指的是基元中包含相同值的块或属性名。一些工具如Shatter为你创建这种类型的属性。
If no template attribute exists, block will loop over each point or primitive.
如果不存在模板属性,block将会循环执行每一个点或者基元。
In the network editor, open the Tab menu and choose “For Each Loop”.
在Network Editor,按Tab,选择“For Each Loop”。
The tool will create a Block Begin and Block End node wired together. The Block Begin has the Method parameter set to “Fetch piece”, meaning it will start each loop with a different piece of the input.
这个工具创建将Block Begin与Block End节点连接在一起。Block Begin有Method参数设置为“Fetch piece”,意味着它会将每次循环执行输入几何中的不同块。
Select the Block End node and set the Template class to the type of pieces you are iterating over (points or primitives/faces). This will usually be primitives.
选择Block End节点,设置块类型的参数 Template class(points或/faces)。它通常是primitives。
Note that you don’t set the number of iterations… the loop will simply loop over each piece in the input.
注意,如果你不设置迭代次数,循环操作将会遍历每一块。
In this example, we loop over the pieces of a shattered torus and apply Mountain to each one individually.
这个案例,我们遍历圆环的每一块,分别执行Mountain。
A loop can have more than Block Begin node. So, for example, one branch of the network will get its input piecewise and another branch will be simple repetition accumulating the result of using the pieces.
一个循环可以有多个Block Begin节点。所以,例如,网络的一个分支用来得到它的输入分段,另一个分支用来简单的重复累积计算结果。
The classic example of this type of loop is making Swiss cheese: use simple repetition to accumulate the results of processing one input geometry (the cheese block) by looping over pieces from a second input geometry (the air bubbles).
这个类型循环的案例是瑞士奶酪:单一的重复累积输出结果(奶酪块)作为下次循环的输入。
In the network editor, open the Tab menu and choose “For loop”.
在Network Editor,按Tab,选择 “For loop”。
This loop branch will do the work of accumulating the changes to the cheese block.
这个循环分支用来改变奶酪块。
Create another Block Begin node.
创建另一个Block Begin节点。
Set the Method parameter to “Fetch piece”.
设置Method 参数为“Fetch piece”。
Set the Block path parameter to the Block End of the existing loop. You can use the node chooser button next to the parameter, or drag the Block End from the network editor onto the parameter in the parameter editor.
设置 Block path参数为已经存在的Block End。你可以使用节点选择按钮从中指定,也可以从Network Editor拖拽Block End到此参数编辑器上。
This loop branch will do the work of fetching each bubble from the bubble geometry.
这个循环分支将会从泡泡几何体遍历每一个泡泡。
The following shows an example network for making Swiss cheese using the two loop branches:
下面的图片展示使用双分支循环创建瑞士奶酪。
How to get information about the current loop 如果得到当前循环的信息
Sometimes you need the current loop, or the current piece number, in an expression on one of the nodes in the loop. You can get this information with a “Fetch metadata” Block Begin node.
有时你需要在循环中使用表达式得到当前循环,或当前块编号。你可以通过“Fetch metadata”Block Begin节点得到这些信息。
Set up a looping block using the instructions above.
使用上面的说明设置一个循环块。
Create a new Block Begin node.
创建一个新的Block Begin节点。
Set the Method parameter to “Fetch metadata”.
设置Method 参数为“Fetch metadata”。
Set the Block path parameter to the Block End of your existing loop. You can use the node chooser button next to the parameter, or drag the Block End from the network editor onto the parameter in the parameter editor.
设置Block path 参数为已经存在的Block End。你可以使用节点选择按钮从中指定,也可以从Network Editor拖拽Block End到此参数编辑器上。
This node creates an empty geometry with some detail attributes.
这个节点创建一个包含Detail属性的空几何体。
numiterations The expected total number of iterations, taking into account the Max Iterations and Single Pass parameters on the Block End.
迭代总数的期望值,这要考虑Block End节点中Max Iterations 与Single Pass 参数的设置。
iteration The current iteration number, always starting at 0 and increasing by 1 each loop.
当前迭代索引,通常从0开始,每次让递增1。
value In piece-wise loops, this is the current value of the attribute, for example the piece integer or name string (or the current point or primitive number if there is no attribute).
在分段循环,这是属性的当前值。例如块整数或名称字符串(如果没属性,则是当前点与基元编号)
In simple repetition loops, this is a floating point value starting at the Block End’s Start value and increasing by Increment each loop.
在单一重复循环,这是在Block End节点中的Start value 参数的起始值,并每次循环以Increment 参数递增。
ivalue In simple repetition, this is an integer version of value. This can be useful if the value is naturally integer (for example, start at 1 and increment by 2) and/or if values may be over 24 million (where floating point numbers lose precision).
在单一重复循环,这是一个整数版本号。它用来确定数值是否是整数时是非常有用的(例如,以1为起始,每次增加2)并且/或 如果值超过2400万(浮点数将会丢失精度)。
To grab the value of these attributes in a node inside the loop…
在循环中抓取这些属性值:
In a Houdini expression, use the detail expression function.
在Houdini表达式中,使用detail表达式。
For example:
detail("../block_begin2", "iteration", 0)
In an Attribute wrangle, use the detail VEX function.
In Python, use hou.Geometry.attribValue
node(“../block_begin2”).geometry().attribValue(“iteration”)
If the Stop condition parameter on the Block End node evaluates to 1 before an iteration, looping stops. This lets you write an expression that tests certain conditions. For example, you could stop looping if the number of polygons in a feedback loop passes a certain threshold.
如果Block End节点中的Stop condition 参数在一个迭代之前变成1,则停止循环。这允许你编写表达式测试某些条件。例如,在超过多边形的数量超过临界点时停止循环。
You can step through the iterations of the loop by setting the Max iterations parameter on the Block End node. For example, start it at 1 and increase to see the results of each loop.
你可以设置Max iterations 参数跟踪循环。例如,起始设置为1,逐步增加观察循环结果。
In piecewise loops, you can see the output of an individual piece/iteration using the Single pass parameter on the Block End node.
在分段循环,在Block End节点你可以使用Single pass 参数指定输出。
This node does not allow specifying pieces using groups. Because groups are not necessarily disjoint, it is very slow to translate them into pieces. If your geometry uses groups to specify the pieces, you can create an attribute from the groups using the Name node’s “Name from Groups” function, then split by the created attribute.
这个节点不允许使用groups指定块。因为是不是disjoint的,所以把它们转换为块是非常慢的。如果你的几何体使用组指定块,你可以使用Name节点的“Name from Groups”方法创建一个由组而来属性,然后通创建的属性进行分割。
The color of the blob surrounding the nodes in a loop comes from the color of the Block Begin and Block End nodes. Change the color of one of these nodes to change the color of the blob.
blob的颜色取决于Block Begin与Block End节点的颜色,改变这些节点的颜色将改变周围的颜色。
To hide or show the blob, right-click the Block Begin node and choose Flags > Descriptive parameter.
隐藏与显示blob,在Block End(这里应该是End节点)节点上点击右键选择Flags > Descriptive parameter。
Currently only nodes between Block Begin and Block End nodes are included in the blob. Unfortunately the blob does wrap around nodes that are included in the loop because of channel reference dependencies. This is a limitation of the current implementation.
目前只有在Block Begin与Block End节点之间的节点被包含在blob中。不幸的是因为通道引用的依赖关系,blob周围的节点也会被包含进去,这是目前的限制。