Groom Operator 

One or more Ornatrix operators can be boxed (combined) together into a single Groom operator. The operator will function the same way as the operators comprising it. The reason for boxing operators could include:
  • Organization: Making the stack cleaner by boxing various parts to create fewer overall operators
  • Graft grooms: Creating a special type of groom preset which can be grafted on top of any surface and reused
  • Exposing only selected parameters: Creating a groom where only a few parameters are exposed and can be used to control parameters of boxed operators.
  • A procedurally non-destructive way of baking hair or operators.

A Groom operator can be unboxed (expanded) at any time to replace itself with the contained operators.



Boxing is the process of replacing one or more Ornatrix operators with a single Groom operator such that the output of the stack is unchanged. The boxed operators, including their current parameter values and assets such as maps, are contained within the Groom operator.

To box:
  1. Select one or more operators in the operator stack
  2. Right click on one of the selected operators
  3. Select Box option



Unboxing is a process of replacing a Groom node with the operators comprising it such that the output of the overall hair stack is unchanged. Parameter values are restored, however, some assets such as maps may not be perfectly restored since they are replaced with previously rasterized values.

To unbox:

  1. Select and right click on a Groom node in the operator stack
  2. Select Unbox


Exposing Parameters 

By default a Groom node does not expose any parameters of its comprising operators. It uses the parameter values as they were at the time of boxing to evaluate the internal operators. You may expose any number of parameters which can be used to set the values of boxed operator parameters through scripting.

To expose parameters:
  1. Select the Groom node and open Maya's Attribute Editor
  2. Expand Groom Parameters Script group
  3. Click on Edit Parameters Script... button. Default text editor containing a Python script will be opened. The Python script contains an array of all parameters which can be exposed organized and commented in a friendly way.
  4. Uncomment one or more parameters (e.g. remove the "#" character at the beginning of a line)
  5. Save the file
  6. Press Update button in the Attribute Editor

The Groom Parameters group, previously empty, will now contain the exposed parameters. You can keep modifying the Python script file and pressing the Update button to further refine the parameters script. You can rename the parameters, adjust their default, minimum, and maximum values, and create parameters which use math or set values of multiple operator parameters at the same time. You can also set values of ramp curve knots and array parameters.


Parameter groups 

Parameters can be organized into UI groups. To create a parameter group the following definition is used:

('GroupUIName', 'Group', True )

All parameters following a group, before the next group definition, are placed under said group. Groups are auto-generated based on Ornatrix operator parameter groups in the default parameter script.


Parameter definition 

The basic, and most used, way to change a parameter is via the set_value function:

('ParameterUIName', 'type', lambda gm, v : gm.set_value( 'OperatorName', 'OperatorParameterName', v ), minValue, maxValue, defaultValue )

The above standard definition uses the following entries:
  • ParameterUIName: Name which will appear in the UI. Camel case is used and spaces will be inserted between words.
  • type: Type of the UI parameter. Can be int, float, bool, or string. This type must match the type of the parameter set by set_value later.
  • Setter function. We use a lambda in our example but you can also reference any function which accepts a "graph manager" gm and a value v.
  • Optional:
    • minValue, maxValue: Minimum and maximum UI values for the parameter. This is for convenience only, user can set values outside of this range through scripting.
    • defaultValue: Default value of the parameter. This value will be assigned if user resets everything.

Note how we use the gm member passed into our parameter function to set the actual value using set_value function. The following functions are available:

  • gm.set_value( 'OperatorName', 'OperatorParameterName', v )

    This is the function from above example. OperatorName and OperatorParameterName are the operator and its parameter for which the value will be set. v is the value. You can perform any mathematical/scripted operation on the value before setting it (e.g. v * 2 + 5)
  • gm.set_element_value( 'OperatorName', 'OperatorParameterName', elementIndex, v )

    In some cases parameters can be stored as arrays (e.g. Surface Comb's sink directions). This function allows setting values of specific elements within such a parameter array.
  • gm.set_ramp_knot( 'OperatorName', 'OperatorParameterName', knotIndex, position, value )

    For ramp parameters, allows setting individual knot values. position is the horizontal knot position (between 0 and 1) and value is the vertical knot position (between 0 and 1). Useful for adjusting operator effects at specific parts along strand length.
  • gm.set_ramp_knot_position( 'OperatorName', 'OperatorParameterName', knotIndex, position )

    Same as set_ramp_knot but allows only modifying knot positions.
  • gm.set_ramp_knot_value( 'OperatorName', 'OperatorParameterName', knotIndex, value )

    Same as set_ramp_knot but allows only modifying knot values.

Mirroring graft grooms 

If a Groom node is a graft groom you can mirror its output to one of the object-space axes.

To mirror a groom:
  1. In Attribute Editor, expand the Mirror Groom group
  2. Check the Enable option

The groom will be mirrored to the other side of object space, X-axis by default. You can change the axis through the Axis parameter.

Using the Randomize option (on by default), the mirrored groom's "Random Seed" parameter script value will be set to a value different than the base groom. This allows the mirrored groom to appear different from one side to another. Note that this requires a parameter with a name RandomSeed to be defined.

Missing Something? Let us know if this page needs more information about the topic.