Share

Creating a Compound

In this tutorial we will create a compound, an MCG graph that can be re-used in other MCG graphs. Compounds can help simplify graphs by "hiding" complexity in a single node. Compounds can be referenced by multiple graphs. When a compound is updated or changed, it affects all the graphs in which it is used. The concept is similar to functions or procedures in other programming paradigms.

We will start by creating a mesh modifier which constrains the mesh between two objects, and then simplify it by converting some of the graph logic into a compound.

  1. Open the MCG editor to create a new graph, using Scripting > New Max Creation Graph. Since we are controlling the position of two objects relative to a third, we need two inputs. The input for an object in the scene is Tool Input: SceneNode, which you can find under Inputs > Tools in the Operator Depot. Drag two Tool Input: SceneNode operators onto the graph, and name them "Object 1" and "Object 2".

    Note: Names on inputs are the labels on the user interface for the MCG tool. In this case, it will be the label displayed on the node picker buttons in the modifier.
  2. For this modifier, we need the world position of the two chosen objects. Press the X key to search for SceneNode World Position, or find it under 3ds Max > Scene Node > Transform in the Operator Depot. Once you've created one node, shift-drag it to make a copy, then wire the nodes:

  3. At this point we want to calculate the position between the two selected objects. We'll do this by adding the two object positions and dividing by 2, to get the "average" position. Add the Add operator to the graph (Math > Basic), and wire the two world positions to it. Wire the output of the Add node to the vector input of a Divide Vector (Math > Vector), and wire a Constant of 2.0 (Core > Constant) into the value input:

    Note: Constant nodes have specific parsing rules for their inputs. Add a ".0" to a number to treat it as a float. If no decimal is specified, the value is treated as a whole-number integer. Consult the Constant node's description in the Node Properties panel for its parsing rules.
  4. Now we need the object to apply the modifier to (the object at the bottom of the modifier stack). The input for this is the Modifier: Mesh node (Inputs > Tools). Add this to the graph.

  5. To apply any transform to a mesh (including transforming the position, as in this case), use the Transform Mesh operator (Geometry > Mesh). Wire the Mesh output from the Modifier: Mesh to the mesh input of this node.

    If you try to wire the Vector3 output of the Divide Vector node to the matrix input of the Transform Mesh node, you'll notice that the wire is red. This indicates an issue - in this case, the two types are incompatible. We need to convert the Vector3 output to a matrix value.

  6. Search for and add a Translation Matrix operator (Math > Matrix), and wire it between the Divide Vector and Transform Mesh.

  7. The last step of creating our graph is to add the output. Add an Output: Modifier operator (Outputs > Tools), and wire it to the Mesh output of the Transform Mesh node:

  8. Press CTRL+S to save the graph, set its Tool Name as "MCG_Position_Constraint", and set its Display Name as the same thing. Save this tool to your MCG user profile's Tools directory: C:\Users\username\Autodesk\3ds Max 2018\Max Creation Graph\Tools.

  9. Evaluate the graph, and test it in a scene: create three different geometry objects in a scene - we'll call them A, B, and C. Make sure object C is centered at [0,0,0] in the scene, and apply the MCG_Position_Constraint modifier to it from the modifier list. Set "Object 1" to A and "Object 2" to B, and confirm that changing the position of either A or B affects the position of the modified object C. In this example, the modifier is applied to a torus:

  10. We are now ready to convert the "logic" of the graph to a compound. In the MCG Editor, select the middle part of the graph: everything from the two SceneNode World Position nodes to the Transform Matrix node, and copy (Ctrl+C or Edit > Copy). Open a new graph via File > New in the node editor menu, and paste the content:

  11. Compounds require compound-specific inputs and outputs. Add an Output: Compound (Outputs > Compounds) to the output of the Translation Matrix. Right-click the two SceneNode World Position nodes and select Generate Compound Inputs. These should be re-named "Object 1" and "Object 2", and will become the inputs of our compound when used in another graph.

  12. Save the new graph as a .maxcompound, named "MCG_ConstrainBetweenTwoNodes" and make sure to save it in your MCG user profile's Compounds directory: C:\Users\username\Autodesk\3ds Max 2018\Max Creation Graph. Once it is saved, press Operators > Reload Operators to ensure it is loaded into the operator depot.

  13. You can now go back to the original graph (MCG_Position_Constraint.maxtool) and replace the copied operators with MCG_ConstrainBetweenTwoNodes. By default, new compounds appear under the Uncategorized entry in the Operator Depot. You may change this by modifying the compound's Category from its graph properties (Right-Click the Compound > Open Compound in New Tab > Edit > Edit Graph Properties...), and re-saving it. Wire the new node into the graph, and notice how the graph became much cleaner:

  14. You can test that the modifier continues to work by saving it (CTRL+S), evaluating it (CTRL+E), and manipulating objects A and B in the viewport.

  15. Let's make some improvements to our modifier. We can avoid the requirement of placing our modified object at the world origin [0,0,0] by converting the transformed mesh into Tool Space. We do this by adding a Modifier: Local to World Matrix operator (Inputs > Tools) to our graph, and feeding it into a Mesh in ToolSpace operator:

    Note This step uses the matrix from the modifier stack to transform a mesh defined in world coordinates into the tool's local coordinates.

  16. Save CTRL+S and evaluate CTRL+E the graph. To confirm our changes worked, move the modified object in the scene. The modified object should continue to remain constrained between both picked objects, regardless of its position in the scene.

  17. Finally, let's see how we can improve our compound. Keep in mind that editing a compound will update all the graphs that reference it. Open the compound graph (Right-Click the Compound > Open Compound in New Tab), and delete the Add, Divide Vector and Constant operators. We will replace them with a node that provides a linear interpolation between two vectors based on an input value, a Lerp operator. Add the Lerp operator (Math > Interpolation), and wire it to the SceneNode World Position operators. Add a Compound Input: Float (Inputs > Compounds) to provide the t input value. Name the input "Weight", and save CTRL+S the compound. Press CTRL+E on the compound or select Operators > Reload Operators to reload the operator depot with your new changes to the compound.

  18. Return to the MCG_Position_Constraint.maxtool graph. You'll see that the compound now has a new "Weight" input. Add a Tool Input: Float (Inputs > Tools) to this input, also named "Weight" (the label that will appear in the UI), with a min of 0.0, a max of 1.0, and a default of 0.5. Save CTRL+S, evaluate CTRL+E, and test the new "Weight" spinner to apply a weighting to the constrained object.

This tutorial has illustrated how you can create compounds to compartmentalize logic to re-use in other graphs.

Was this information helpful?