Genome v1.1.0.49116 November 8, 2012

Hello fellow Genome-rs, we’ve got a tasty new build of Genome ready for your consumption. This new build includes some fancy new loop-style nodes with exciting names like Loop, FaceLoopByEdge, ParticleSearch, and more. These new nodes let you define an operation that is applied multiple times like a for loop or a foreach loop in general programming.

Give it a whirl and let us know what you think. Also bug reports are helpful because we don’t like bugs. Not one bit.

Have Fun!

[size=85]Genome_1.1.0.49116_x64.msi (removed)
Genome MX 1.1.0.49116 64 bit for 3ds Max 2010, 2011, 2012, and 2013.
(8.85 MiB) Downloaded 8 times

Genome_1.1.0.49116_Win32.msi (removed)
Genome MX 1.1.0.49116 32 bit for 3ds Max 2010, 2011, 2012, and 2013.
(8.27 MiB) Not downloaded yet[/size]

[size=200]This post is Work In Progress…[/size]

[size=150]Modifier Changes[/size]

  • Added Iterations control - this lets you run the same modifier multiple times on the stack over itself. for example in order to grow a selection N times. Please see the preview video posted here
  • If the modifier stack is collapsed and there were exposed parameters in a Genome modifier, these will now be cleaned up when the object is selected again or when the scene is saved.

[size=150]New Magma Nodes And Node Features[/size]

  • Added a “Loops” Category - accessed via the P keyboard shortcut. It contains the various Loop nodes. Loop nodes are currently pale green.
  • Added a generic Loop operator. See further on this page for details.
  • Several “GeoLoops” are available as separate operators. They are meant to perform loops over vertices or faces based on a specified reference vertex or face. These operators do not have a condition since they have a finite implicit list of faces or vertices. See further on this page for details.
  • Added a “ParticleSearch” loop operator. It is a more general version of the ParticleSumRadius and PartucleSumCount operators and lets the user create various particle lookup operators using a search radius or count. See further on this page for details.
  • All loop nodes have a Max. Iterations value. It is to prevent a generic loop from running forever if the condition is not set correctly. If you are looping with the generic Loop node over all faces or vertices, be sure to set the Max. Iterations value to a number higher than the expected Max. number of faces or vertices!
  • Loop nodes allow Default values to be specified for each Input and Output-as-Input socket. Normally, when an Input is created, it will have no default value and will show up as red. You can click the Default>> button and select the desired value type (Float, Int, Vector or Quat) to be set as default. This will turn the socket green and the Default value will show up in the dynamic “Input Defaults” rollout. You can also remove a default by selecting the last option from the menu. This feature will be available at a later point in BLOPs too.
  • Implicit separators of 5 pixels will be inserted automatically between the hard-coded input sockets, the custom Input sockets and the Outputs’ Input sockets of a Loop node. NOTE that the explicit separators in BLOPs were also reduced from 10 to 5 pixels to save some vertical space.
  • Pressing the “Remove” button in BLOPs and Loops will now show a Yes/No prompt to avoid the accidental removal of sockets. In future builds, adding/removing sockets will be also handled by the Undo buffer (currently not implemented).
  • When an error is detected in a node inside a container (BLOP or LOOP), all parent nodes will be shown in red, and the error message will describe where the offending node is within the hierarchy. From the Debug menu, you can now select “Navigate to Error Node” to go directly to the level and select the node that caused the error!

[size=150]MagmaFlow Editor Improvements[/size]

  • Added a Welcome message which explains the basic steps to start using MagmaFlow or access the Help. It can be dismissed or turned off permanently. It only opens for empty modifiers.
  • The modifier’s own AutoReorder Toggle state and mode will be stored in the modifier itself and restored for each Editor individually after loading a Max scene containing Genome modifiers.
  • Dragging a wire from an unconnected “Geometry” input of Loop nodes will create a CurrentMesh input, dragging from other nodes like NearestPoint will create InputGeometry instead.
  • Fixed the loading of modifier settings when using the “Save As Max Version” option to bring scenes from 3ds Max 2013 to 2012,2011 or 2010 - Unicode was not handled correctly by 3ds Max when storing AppData.

[size=200]New Nodes In Detail[/size]
Here’s a brief description of the purpose of the new loop-style nodes in Genome 1.1.0. All of these nodes are containers, similar to BLOP nodes except the contained nodes are used to define an operation that is executed multiple times.

All loops have a user-specified number of constant-valued inputs and a user-specified number of outputs. For each output there is an associated input socket that provides an initial value. During each loop iteration the output sockets is assigned a new value and on the next iteration the associated input socket will reflect this. The output sockets of the Loop node produce the last value that was assigned inside the loop.

[size=150]Loop[/size]
The Loop node is a general-purpose looping construct most similar to a while loop in C/VB/C#/etc.

The loop operates until the “Condition” socket inside the loop is assigned a value of False. Typical uses of this node is to loop over all faces of a mesh, or loop until a bouncing RayIntersect does not hit geometry. There is an adjustable property that limits the number of times the loop can execute in order to avoid an infinite loop when a bad configuration is done.

[size=150]VertexLoopByEdge[/size]
This loop visits each vertex that neighbors the “current” vertex via a single edge. The node has 3 predefined input sockets that take the Geometry list, an index into the Geometry list (ie. which mesh), and a vertex index. This uniquely specifies a single vertex in the geometry which is called the “current vertex” while looping.

Inside the VertexLoopByEdge node you can use a LoopChannel node to access the vertex properties of the vertex the loop is currently visiting. This is exactly like using an InputChannel node, except it reads from the vertices we are looping over inside the VertexLoopByEdge node.

You can recreate the Relax modifier using VertexLoopByEdge to collect the average position of the neighbor vertices and blending between that average position and the original vertex position.

[size=150]FaceLoopByEdge[/size]
This loop visits each face that neighbors the “current” face via an edge. The node has 3 predefined input sockets that take the Geometry list, an index into the Geometry list (ie. which mesh), and a face index. This uniquely specifies a single face in the geometry which is called the “current face” while looping.

Inside the FaceLoopByEdge node you can use a LoopChannel node to access the face properties of the face the loop is currently visiting. This is exactly like using an InputChannel node, except it reads from the faces we are looping over inside the FaceLoopByEdge node.

You can diffuse a face selection using FaceLoopByEdge to determine if any neighbor faces are selected. If they are select the “current face” too by writing True to the FaceSelection channel outside of the loop.

[size=150]FaceLoopByVertex[/size]
This loop visits each face that contains the “current vertex”. The node has 3 predefined input sockets that take the Geometry list, an index into the Geometry list (ie. which mesh), and a vertex index. This uniquely specifies a single vertex in the geometry which is called the “current vertex” while looping.

Inside the FaceLoopByVertex node you can use a LoopChannel node to access the face properties of the face the loop is currently visiting. This is exactly like using an InputChannel node, except it reads from the faces we are looping over inside the FaceLoopByVertex node.

You can convert a face selection to a vertex selection by counting how many faces using a vertex are selected and how many are not selected. You could consider the vertex selected if at least 1 face is selected, or if all faces are selected. You could generate a soft selection by dividing the number of selected faces by the total number of faces visited.

[size=150]VertexLoopByFace[/size]
This loop visits each vertex contained in the “current face”. The node has 3 predefined input sockets that take the Geometry list, an index into the Geometry list (ie. which mesh), and a face index. This uniquely specifies a single face in the geometry which is called the “current face” while looping.

Inside the VertexLoopByFace you can use a LoopChannel node to access the vertex and face-vertex properties of the face-vertex the loop is currently visiting. This is exactly like using an InputChannel node, except it reads from the face-vertex we are looping over inside the VertexLoopByFace node.

This node could be used for calculating the centroid of the face (ie. a weighted sum if the face’s vertex positions). This is primarily intended for working with polygon meshes once we add support for them.

[size=150]ParticleSearch[/size]
This loop has two modes, controlled by the searchMode property. In ‘Radius’ mode it visits all particles within a sphere specified by a position and radius passed in input sockets 2 and 3 respectively. In ‘Count’ mode it visits the closest N particles to the specified position.

Inside the ParticleSearch you can use a LoopChannel node to access the properties of the particle the loop is currently visiting. This is exactly like using an InputChannel node, except it reads from the particle we are looping over inside the ParticleSearch node.

This node could be used to find the average density of nearby particles by accumulating the Density of each particle visited, then dividing by the volume of the sphere searched.

[size=200]KNOWN BUGS[/size]

  • After posting the build, we discovered a memory leak when using the Iterations spinner to run the Genome modifier multiple times… This is being looked at.
  • Copying a Genome modifier with Loop nodes can cause some Output sockets in the Loop body to be reconnected incorrectly to their respective [Inputs]. This will break the flow silently without showing an error. This should be fixed in the near future.

[size=200]SAMPLE SCENES: MAX 2010+, GENOME 1.1.0.49116+[/size]

[size=150]Surface Curvature[/size]
In this example, each vertex’ normal is passed into a VertexLoopByEdge operator where the DotProduct of this Normal with the Normals of all neighbor vertices is accumulated in the first Output. The second output counts the number of neighbors. Then the sum of the DotProducts is divided by the Count, boosted by an Exponent and subtracted from 1.0 (because parallel normals produce Dot Product of 1.0, but we want the selection to be 0.0) and the result is set to the Selection Channel. The result is no selection of flat areas and more selection where the normals diverge. In the scene, a vertex on a 100x100 segs plane is animated with Soft Selection over 100 frames. The resulting curvature is converted to a new soft-selection by Genome. Try enabling the Push to see a wrinkle at the base where the curvature is high…
GNM_VertexSoftSelection_ByCurvature_Max2010_v003.zip (155 KB)

[size=150]Select Element By Face Selection[/size]
In this example, for each face in the mesh, its Element ID is compared to the Element IDs of all other faces and if they match, the number of selected faces within the Element as well as the total number of faces in the Element are collected by a Loop operator. The result is then used to compare to a threshold and the face is selected if more than the specified percentage of faces in the element are also selected. An animated Vol.Select is selecting faces of the teapot over time. When the percentage of selected faces is greater or equal to 60%, the whole element is selected. By changing the threshold, you can set the element selection to happen earlier (when less faces are selected) or later (when more faces are selected).
WARNING: This implementation is VERY SLOW and does not scale well because for each face, all other faces are re-visited. So with 1000 faces you get 1M iterations, but with 10,000 faces you get 100 million iterations! We plan to provide better internal channels to perform this kind of operation without an explicit loop.
GNM_SelectElementByFaceSelection_Max2010_v004.zip (20 KB)