ACS - Manual

Contents

1. Overview

Welcome to the ACS manual. I am going to try to explain many, if not all, aspects of the acs script. The script has a rather abstract nature and therefore, I've written a Quick Start tutorial, which I hope clarifies the concept and makes it more "touchable".

I recommend to start with the quick start tutorial. When there is a reference to a chapter of this manual, take a look at it, until you roughly understand what it is about. This way, you get used to the workflow and understand the rather dry theory of the manual in a more human friendly way. After that, if something is not clear or you want to use the acs for more complicated setups, you can study the manual more thoroughly.

There are some advanced things that you don't need to understand in order to use the acs. However, these should be explained in this manual, as they are part of the system and might be important for some users who already know the system and want to go that extra mile. These paragraphs are shown in a box like this.

In these boxes, I've written tips for using certain functions. Their info usually speeds up working with the UI.

This is a warning box. It is used to emphasize the importance of a certain fact and shows possible pitfalls.

So what's ACS?

ACS stands for Attribute Combination System. The name is related to the BCS (BlendShape Combination System) and already shows that we deal with simple attributes, instead of blend shapes.

2. Basics

The acs connects any number of driving attributes with any number of driven attributes. Basically, that's it. Yet, it does it in a rather complex way, allowing for combination-sculpting of attribute values.

It can be used in any situation where an SDK does not provide the desired control, especially when you want to define context sensitive behavior, i.e., when several attributes are changed together. The applications range from hand rigs to being a part in a multi layered facial setup, and even more complicated systems. It can be useful in much simpler scenarios, too. For example, when you want to have two attributes drive one, etc..

As the basic concepts were created, it quickly became apparent that the system would need to store that much information that it could not simply be "planted" on top of any existing node in the Maya scene. At the end, 52 new attributes had to be added, 21 of which were multi attributes. This complexity made it inevitable to lean it on API structures and create a new node. The script doesn't use any API, though, at least not at the moment.

3. The User Interface

When you open the UI by executing DPK_attrCombinationSystemUI;, you should see the following window (initially with empty lists, of course):

The interface is divided into three parts: Inputs, Data Points, and Outputs. Every part has some view mode options and a list. The input part also has four buttons and an input field. The two buttons directly below the list ("<<" and ">>") are the layer buttons. The field is called position field and the two remaining buttons are the position buttons. Below these parts, there is a drop down list, a select, and a close button.

The three lists have two marking menus each:

Most of their menu items can also be reached through the main menu of the acs window. The only two functions that are not explained are Expand and Collapse in the input and data point list. They simply expand/collapse the selected inputs/data points. Expanding will be explained further below.

ACS Node Drop-Down Menu

The ACS node drop-down menu contains all acs nodes that exist in the scene. The node that is chosen in this menu will be edited in the UI and is considered the current acs node. You can select it in the scene using the Select button.

4. Inputs and Outputs

As explained above, the purpose of the acs is to connect any number of driving attributes with any number of driven attributes, similar to an SDK setup. It was also stated that there are so many things that need to be stored and taken care of that a dedicated node was the most flexible way to implement this system. The acs node works like an API node which takes input values, does its computation, and sets some output values. All input and output attributes are located on the acs node and the computation doesn't change any other attribute in the scene.

How do we now define which attributes are the driving, the controlling ones, and how do we get their value so that we can work with it? As with all nodes, the information has to be obtained by connecting the attributes.

Importing inputs means that the driving attributes are connected to the input attributes of the acs node. Importing outputs means that the attributes which hold the computed output values on the acs node are connected to the driven attributes.

Already imported inputs are shown in the left list. Imported outputs aren't shown directly. Only their agents, so called dummy attributes, are displayed in the right list. This is because outputs have to be shown together with a value and this can be done most effectively by using a channel box control. By the way, this is the reason why the displayed outputs may have slightly different names than the defined output names.

5. Data Points Part 1

Now, how do you connect the inputs with the outputs?

You define a set of keys, called data points. A key has a position and a value and so does a data point. Because you want to connect to any number of outputs, a data point needs to store not just one value, as keys do. Instead, the data point holds many values, one for each output. I've written that you also want to connect from any number of inputs. This means that a data point has a more complicated position than a keyframe because the position can include more than one input's value.

Again, when you create a single SDK key connecting one attribute with another, you define three things for this key: a position, a value, and the tangent type. Data points are very similar with two major differences:

  1. They don't hold one value but any number of values.

  2. They are not placed on a one-dimensional position based on one input value, like SDK keys, but at any position in an n-dimensional space (where n is the number of contributing inputs).

I think, the second statement still needs a bit more clarification: A keyframe's position is a certain value of time (for animation) or the value of an attribute (for SDKs). A data point's position can be the value of a certain input. It can also be the two values of two inputs. You could even place a data point at a position where 3 or, say, 200 inputs have a certain value, though the latter wouldn't be very common. The data point will only be "reached" when all these inputs have exactly this value.

6. Input Positions

As you now know, data points are positioned at certain values of one or more inputs. Data points have to be weighted so that they fade in when the value of the input approaches the position of the data point. They are faded out when the value of the input goes away from the data point's position.

We first have to define the positions that we want to use, before we can create any data point. These positions are then interpolated, instead of the data points themselves. Creating and managing positions is explained in chapter 11. The Position Field and Buttons.

You might wonder why you have to create and define positions. Let's take a simple example: We have one input and want to create a data point that has its full effect when the input has a value of 1. In this case, we would create an "input position" at the value 1 and a data point with this position. We can now set the values of the data point, i.e., the values of the outputs when the data point has its full effect. So far, it doesn't seem like input positions are needed.

Now, what do we do when we want to add a data point which is active at 0.5? We create a second input position at the value 0.5 and use it for our second data point. We now have two positions for the input. Let's increase the input's value slowly from 0 to 1 and take a look at the weights of the positions. When the input moves from 0 to 0.5, the weight of the position at 0.5 increases from 0 to 1. When the input now moves from 0.5 to 1, the weight of the position at 0.5 decreases from 1 to 0 and the weight of the position at 1 increases from 0 to 1. This results in the data points being faded in and out one after the other.

One big issue wasn't touched upon, yet: the interpolation of a position's weight. In a setup with only one position, the interpolation is linear. That means that as the value of the input approaches the position, the position's weight increases linearly and is 1 when the input has reached it. In the above example, the 0.5 position's weight was interpolated in a smooth fashion. It had a slope of 0 at its position. This results in a smooth blending of the different data points. In fact, the weight of the position at 1 moved slightly down below 0 when the input was between 0 and 0.5. This "anticipation" leads to even smoother movements between the data points.

Of course, you can change the interpolation of the input positions so that you get the behavior you want. See the descriptions of the interpolations in chapter 10. Menu Functions under Position Mode.

In the user interface, input positions are displayed in the input list. An input which has positions has a "+" as a prefix. Double click this input to "expand" it and see its positions. A position is displayed with its interpolation and its position. For example "sp 10". This means that the position is currently running with "spline" interpolation and is at the value 10 of its input.

7. Data Points Part 2

Every input has a value at which no position is active. Consequently, at this value, all data points, which use any of the positions, have to have a weight of 0, i.e., they don't have any influence on the outputs. This is called the input's "neutral" value and is typically at 0, but can be changed to any other value.

Now, which values do the outputs have when all inputs are at their neutral state? This is defined by the one data point which uses no input position, the neutral data point. This data point always has a weight of 1.

This fact leads to the conclusion that data points are constantly mixed together. Many data points can have weights greater 0 at the same time. The simplest case is when there is one regular data point (using one input position) and the neutral data point. When the position of the one data point is reached, so that it has a weight of 1, the neutral is still active.

Relative and Absolute

The concept of relative and absolute dataPoints is a little tricky to understand, at first. Since it isn't crucial to using the acs, it will be explained in an advanced box.

There are two ways a data point can store the values of the outputs: relative and absolute.

To explain these two modes, I'll use a simple example, which shows the concept. Let's say we have one output and one input. The neutral data point sets the output to 1. There is one data point for the input. It sets the output to 10. We now take a look at the pureMix of the data point.

The pureMix
The pureMix consists of the output values at the data point's position without its contribution. To get this pureMix, we simply set the inputs so that exactly the one data point is active we want to have to pureMix of. If we now disable this data point, other data points could still be active. At least the neutral data point is active. In this example, the neutral data point sets the output to 1, so this is the pureMix of the data point.

The relative values of a data point are the differences between its pureMix and the values, the outputs should have when the data point's position is reached. In this case, the relative value (for the one output) of the data point is 9.

The absolute values are the final values of the outputs when the data point's position is reached, including all other data points that could be active. So the absolute value of our example data point is 10.

If a data point is in relative mode, its relative values stay the same, no matter how its pureMix changes. This means, that the absolute values change when influencing data points (like the neutral data point) change their values. When we edit the neutral data point so that the output has a value of 5, the data point has an absolute value of 14. So when we set the input to 1 (to activate the data point), the output will be 14.

In absolute mode, the absolute values of a data point are preserved, even when influencing data points change. Back to the example, when the data point had been absolute before we set the neutral's output value to 5, its absolute value would have stayed at 10. So when we had set the input to 1, the output would have been 10. Consequently, the relative value of the data point would have been 5, since this is the value we have to add to the pureMix to get a result of 10.

Data points can also be instances of other data points. Take a look at Create Instance With Selected Position(s) in chapter 10. Menu Functions if you want more information on instances.

Data Points in the UI

Data points are displayed in the center list. For less screen clutter, they are grouped together into data point groups. All data points that use the same inputs belong to the same group. Groups can be collapsed and expanded like inputs. To expand/collapse a group, simply double click it.

A data point is displayed with its mode (relative, absolute, or instance), the inputs it uses, and the positions of these inputs. E.g., "A: tx(0.5)*ty(1)" means that there is an absolute data point ("A:") that uses a position 0.5 of the input "tx" and a position 1 of the input "ty".

When you select a data point (or a group with only one data point), its values are shown in the output list. The view modes of the output list don't change the mode or values of the data point. For more information on these view modes, see chapter 12. View Modes.

More Theory about Data Points

Blend Shape targets could be called data points, as well as keys of an animation curve. These all hold some data which is then used to calculate some output values. They are applied based on some input values (weights, time, etc.) using different interpolation methods.

The data points of the acs are similar to blend shape targets in the way that they hold data for many attributes (targets store vertex positions). Furthermore, the way data points are computed is exactly as with blend shapes. Their weighted values are simply added together to calculate the resulting values. One difference is that blend shapes can just store geometric data, while data points store data of simple numeric attributes.

Apart from the data type, the biggest difference lies in how their weights are calculated. Blend shape targets get their weight from a dedicated attribute, their weight attribute. So there's a direct connection between the data point (the target) and exactly, and only, one attribute. The acs works quite different: weights of data points are calculated based on the specific value of one or more input attributes. You can say, e.g., that you want a certain data point to have a weight of 1 when a certain input has the value 4.33 and should fade to 0 when the input is at 2 and/or at 10. You could also create a data point that has a weight of 1 when input1 is at 1 and input2 is at 0.5.

If you imagine a space where every input attribute has its own dimension, you could think of data points to be placed at any position in this input space. With many data points, you can virtually lay out several "paths" through this space. One nice thing about the acs is how the empty places are defined, since data points are defined in a sub-space which uses just the input dimensions the data point needs to define its position. This way, one could walk a certain path, but offset it in totally different dimensions. When there are no data points at the exact position, the linear superposition of the sub-space data points is used. Taking the hand example of the quick start tutorial, there's no problem when you wiggle the pinky while the thumb is curled, even though these positions in the input space are not defined by any data point.

8. Input Position Layers

Position Layers are best explained using a simple example. Say we have one input with two positions, 0.5 and 1, and two data points, one for each. If both positions are in the main layer 0 (which is the default), the position at 1 is 0 until the input gets higher than 0.5. So they do kind of a cross-fade.

When we now move the position at 0.5 into a sub layer, it is invisible for the positions in the main layer (here the position at 1). The 0.5 position doesn't change its behavior, it fades in and out as the input moves from 0 to 1. The position at 1, however, moves linearly from 0 to 1 together with its input.

Without the layers, the two data points would fade in, one after the other. It would be difficult to create slight variations to the movement of the outputs.

With the layer setup, the data point at the position 1 will come into play right from the start of the input's movement. The 0.5 data point is added on top of this movement. It is faded in and out. This makes it possible to define variations to the movement of the main data point (at position 1) as offset. When we change the values of the data point at position 1, they are inherited by the 0.5 data point (if it's not absolute, of course).

Changing the Layer of an Input Position

You can change the layer of an input position by selecting it in the input list and clicking on the "<<" or ">>" button. The "<<" button will move it one layer up, until it is in the main layer 0. Press ">>" to move it into a deeper layer. You can move positions into any depth to create complex setups.

Conceptually, some positions can not be moved into a sub layer. These are the border positions. If they were moved into sub layers, the other positions wouldn't see them anymore. This could result in data points influencing each other in a cycle.

9. Input Position Groups

The concept of input position groups was included quite late in the development of the acs. It solves a complicated problem and thus, can not be explained in an easily understandable way.

As you may have noticed by now, I often use little example setups to explain the more complex ideas of the acs, and this is what I'm going to do again.

When we have two inputs with each having two input positions, all of which have one data point (so we have two inputs, four input positions, and four data points):

- Input1
   sp 0.4   --> dp1
   sp 1     --> dp2
- Input2
   sp 0.5   --> dp3
   sp 1     --> dp4

We now create a combination data point (dp5) using Input1 position 1 and Input2 position 1.

- Input1
   sp 0.4   --> dp1
   sp 1     --> dp2   --
- Input2                \
   sp 0.5   --> dp3      dp5
   sp 1     --> dp4   --/

What do we do when we want a second combination data point at Input1 position 0.7 and Input2 position 0.5? We could not move the position from 0.4 to 0.7, since we need data point dp1 to be at the position 0.4. We also can't create a new position at 0.7, because this would change the way, position 0.4 and position 1 are interpolated. Even a sub layer is no option, because a sub position at 0.7 would start fading in from 0.4, but we want it to start at 0.

As you can see, there seems to be no way to solve this problem. This is where input position groups come into play.

Take the following input scenario:

- Input1
   sp 0.4     # Main input position group
   sp 1
  - Grp 1     # First input position group
     sp 0.7
     sp 1
- Input2
   sp 0.5     # Main input position group
   sp 1

We now change the setup so that the simple data points, which use just one position, use the two main input groups (the positions directly below the inputs) and the combination data points use the first position group of Input1 and the main group of Input2.

- Input1
   sp 0.4   --> dp1
   sp 1     --> dp2
  - Grp 1
     sp 0.7           --
     sp 1   ----------- \ -------
- Input2                 dp6     \
   sp 0.5   --> dp3   --/         dp5
   sp 1     --> dp4   -----------/

Input position groups of the same input don't see each other. They have no knowledge about their existence and are totally independent. Also, the main group isn't handled any differently then the other groups. This allows for a great flexibility in the creation of combination data points.

There is one limitation: Data points of the same data point group have to use positions of the same input position groups.

As I've written in 7. Data Points Part 2, data points that use positions of the same inputs, belong to the same data point group.

This limitation ensures that there will be no cycle when the data points are evaluated. If there would be a data point using just the 0.7 position, it would change the pureMix of data point dp1 at position 0.4. On the other hand, data point dp1 would change the pureMix at 0.7. If both data points were set to be absolute, the cycle would be perfect and could not be resolved.

As you can see in the above example, input position groups belong to their input, just like the positions. Also, they contain positions themselves. You can expand/collapse them by double clicking on them.

See chapter 11. The Position Field and Buttons for information on how to create new input positions.

10. Menu Functions

This chapter describes all the functions of the menus of the acs UI. These descriptions are often short and you need to know a bit about the acs to understand some of them.

Click on a menu item to jump to its description.

Initialize

Create New ACS Node...

This will create a new ACS node. You need such a node for every acs setup.

Plug Into Existing Connection...

This will automate the process of importing inputs, outputs, and creating data points to connect these. You have to select an object that has keyable numeric attributes which are connected to any other numeric attribute. A window will show all the found connections. When you select them and press the Plug button, the connections are removed, the sources are imported as inputs, and the destinations are imported as outputs. Furthermore, a data point is created for each input. Their values are set in a way that will build a linear connection between the original sources and the destinations. Thus, the behavior should not change and the connection is replaced by the acs.

Import Inputs...

Use this function to define the attributes that should drive the system. In SDK terminology, this will define the drivers. Since they are connected to the input attributes of the acs node, I simply call them inputs. Select the object that has the keyable, numeric attributes and click on this menu item. A window will show all attributes that could be imported. Select the ones you want to be driving the system and click on the Import button.

Import Outputs...

Use this function to define the attributes that should be controlled by the acs. In SDK terminology, this will define the driven attributes. Since they are connected to the output attributes of the acs node, I call them outputs. As with the inputs, select the object that has the keyable, numeric attributes and click on this menu item. A window will show all attributes that could be imported. Select the ones you want to be driven by the system and click on the Import button.

Quick Connection

This creates data points and sets their values so that the inputs are connected with the outputs in a linear way. You have to select at least one input in the input list, and the same number of outputs. Outputs are selected in the output list by clicking on their name (as in the channel box). You can select more than one output by clicking and dragging or by ctrl-clicking on the name.

Edit

Position Mode

This is a sub menu which has functions to change the way the input positions are calculated. As explained above, positions get their value based on the distance between their position and the value of their input. They are also influenced by the other positions of their group and in which layer they are. There are many ways one could calculate the value of a position. Yet, three things are common to all (excluding "Disabled"):

  1. They have a value of 1 when the value of their input is exactly the value of their position.

  2. They have a value of 0 when the value of their input is at the neutral value.

  3. They have a value of 0 when the value of their input is at the position of any other input position that is on their layer or on a higher layer.

Most of the interpolation types have equal behavior when there's only one input position (except "Flat", "Arc" and "Inverse Arc").

Linear
Linear input positions get their value using a linear falloff.

Smooth: Flat
Flat means that the positions have kind of an "ease in - ease out" behavior.

Smooth: Precise
This is the same as "Spline" when there are one or two positions. With three or more positions, precise will prevent the anticipation of the spline interpolation. In contrast to "Flat", the first and last positions don't have this ease behavior.

Smooth: Spline
Spline is the default interpolation. It results in the most natural movement in most cases. With only one position, it behaves the same as linear. With two or more positions, spline results in anticipation of the positions. This leads to the most fluent movements.

Smooth: Enhanced
This is a slightly tweaked version of the spline interpolation. With three or more positions, it results in even more anticipation to preserve the behavior around the actual position.

Smooth: Arc
This interpolation was specifically designed for inbetween position that need to make arced movements. It works best if the position is on layer 1 and is the only inbetween position.

Smooth: Inverse Arc
Use this interpolation for creating arcs around the zero position of an input. It works best on layer 0 (main layer) positions at equal distance to the zero position, e.g. on -1 and 1.

Disabled
Disabled positions are always 0.

Rename Input...

Changes the name of the selected input. You will be prompted for the new name.

Rename Output...

Changes the name of the selected output. You will be prompted for the new name.

Reorder Inputs...

With this, you can change the order of the inputs. A new window will open and display all inputs. Select the ones you want to move and do a "Right Click->Up" or "Right Click->Down".

To move an input far down at once, select some inputs below it and move them up.

Reorder Data Point Groups...

This changes the order of the data point groups. The procedure is the same as with reordering inputs.

Reorder Outputs...

This changes the order of the outputs. The procedure is the same as with reordering inputs.

Delete Inputs/Positions

This will remove all selected positions from the acs. You can also delete position groups or whole inputs. Note that data points which use any of the deleted positions will also be deleted.

Delete Data Points

Removes the selected data points or data point groups from the acs.

Delete Outputs

Removes the selected outputs from the acs.

Update Expression

Use this when you have changed the acs expression with the expression editor and want to reset it.

Data Points

Create With Selected Position(s)

Creates a new data point using the selected input positions. The data point will have no relative values (thus, it doesn't change anything) and can then be edited. If a data point with these positions exists, it is selected in the data point list. If there are inputs selected, their highest positions in the main input position group are used for the data point. If an input that is selected doesn't have any positions, a new position is created for it.

Create Using Current Input Values

Uses the current values of the input attributes to find out, which positions have to be used for the data point. If a new input combination is used for the data point, new input positions will be created in new groups. Use this with care, since it may do things to your acs that you don't want or understand.

Create Instance With Selected Position(s)

Same as Create With Selected Position(s), but the new data point will be an instance of the one selected data point. The (absolute) values of this instance will always be the same as the (absolute) values of the instance target. Note that the instance target has to use less positions than the new data point.

This is because when it uses the same number or more, it may be possible that the instance changes the pureMix at the position of the target data point. But the instance always has to have the same absolute values, right? You can see that a cycle would occur and every time the values are updated, they may shift around, which can not be allowed. This is the reason for the limitation that the instance has to use more positions than its target.

Select Instance Target

When you have selected an instance data point, this will select its direct target (which could also be an instance).

Separate Position Groups

Two data points of the same data point group also have to use input positions of the same position groups. It may happen, however, that two data point groups use positions of the same position group. When you now want to create a new input position that is used by only one of the data point groups, you might want to duplicate the input position group and transfer the data points of one of the data point groups to the position of the new position group. This is what this function does. Select the data point group you want to have exclusive position groups for and click this menu item.

Sort based on Number of Inputs / First Input

These two items will sort the dataPoint groups in the Data Point list. The first, Sort based on Number of Inputs, will result in the plain dataPoints (with only one input in their position) to be listed first. The dataPoints with the highest number of inputs and thus the most complex position will be the last ones. This is recommended for building a setup.

The second item, Sort based on First Input, will show all dataPoints of the first input first, no matter whether it has a simple or complex position. Following are the remaining dataPoints of the second input, then the third, etc...

Note that these two items only change the way the list shows the dataPoints and does not affect the behavior of the system in any way.

Copy Values...

With two or more data points selected, this will open a new window with two lists. Select the data point from which you want to copy in the left list and the data point(s) you want to copy the values to in the right list. Choose whether you want the relative or absolute values to be copied (this is not dependent on the modes of the data points) and click on the Copy button.

Delete

Same as Delete Data Points.

Make Relative

Converts the selected data points to relative data points. When you convert an instance into a relative data point, the instance will not be an instance anymore. You can not convert any data point into an instance.

Make Absolute

Converts the selected data points to absolute data points. Instances are converted to absolute data points and can not be converted back to instances.

Edit

Enters the edit mode for the selected data point. This is the same as double clicking the data point (which is much faster).

View

Expand/Collapse All Inputs

Expands or collapses all inputs and all their position groups. When expanded, you can see all positions of all inputs. When collapsed, only the inputs are visible givin you a better overview.

Expand/Collapse All Data Point Groups

Expands or collapses all data point groups.

Positions: Select Data Points

When you have selected a position (or an input or position group), this will select all data points that use any of them. This is useful to find data points in complex systems.

Data Points: Select Inputs

Selects the inputs that contain the positions the selected data points use.

Data Points: Select Position Groups

Same as above, but selects the position groups. If the positions are in the main group, the input is selected.

Data Points: Select Positions

Selects the input positions that the selected data points use.

Outputs: Select Inputs

Selects the inputs that have any effect on the selected outputs. An input affects an output when any data point that uses the input, has a value for the output.

Outputs: Select Positions

Similar to "Outputs: Select Inputs", but this selects the actual positions which have an influence on the selected outputs.

Outputs: Select Data Points

Selects the data points which influence the selected outputs.

Refresh

Updates the whole UI. This is useful when you have changed the acs using the scripting interface and the UI doesn't show the changes.

Options...

A new window will show some options for the script. They are now explained, one by one.

Create new Data Point as Absolute
If checked, new data points will be created as absolute data points. The default is off so that new data points are relative.

Prompt before deletion
Specifies, whether to ask before finally deleting a position, input, output, or data point. If unchecked, the deletion is done immediately. The default is on.

Prompt before indirect deletion
It is highly recommended that this is checked. If unchecked, when deleting input positions, you are not notified when data points have to be deleted.

List Spacing
Defines how many items should be visible around selected inputs or data points. This has an effect when the lists have to be rebuild, e.g., when you expand an input or you choose any of the selection functions. The default is 5.

Separation Character
Defines the character(s) that are put between the inputs for the names of combination data points and data point groups.

Default Interpolation
Specifies which interpolation new input positions should use when they are created.

11. The Position Field and Buttons

The position field, as well as the two buttons Edit and Create below the input list, have context sensitive functions. You can use them to create new positions for an input (either in the main group, or in a sub group). You also define an input's neutral value and move input positions to different values. Finally, you create new input position groups with them.

Here are the different functions and how they are applied:

Setting an input's neutral value

Select the input(s) you want to change and enter the new neutral value into the position field. Press Edit to change the neutral values for the selected inputs. Limitations of the layers of input positions may prohibit a certain change. In this case, the input is not changed.

Creating a new position

Select any position of the group(s) you want to add a position to. If the input has no positions yet, you can select the input. Enter the new position into the position field and press Create.

Moving a position

Select the position(s) you want to move and enter the new position into the position field. Press Edit to apply the changes. The limitations of layered input positions could make the change invalid. In this case, it is simply not done.

Creating a new input position group

Select the input for which you want to add an input position group. Enter the position of one of the input positions that should be part of the group and press the Create button.

12. View Modes

When you work with bigger acs setups, you often need to see only a small portion of the system. The three view modes of the input and data point list enable you to hide parts of the system in a dynamic, context sensitive way.

View Modes of the Input List

View Modes of the Data Point List

View Modes of the Output List

The view modes of the output list display the data of the selected data point in two different ways. In absolute mode, the final values at the position of the data point are shown. In relative mode, only the difference between the pureMix of the data point and the final values is displayed. The view modes of the output list work with absolute, relative, and instance data points. Changing the view mode has no effect on the selected data point. It is just a viewing option.

13. Scripting Interface

What is the Scripting Interface?

It consists of a set of procedures that can be used to create, set up, and modify an acs setup via MEL.

What is it for?

It serves two purposes: It can be used to automate the rigging (e.g. of a character) by scripting it. Furthermore, it can be used to implement additional features.

There are two types of procedures. The ones that work with and the ones that work without the UI. The UI ones can't be used for scripting rigs, of course. You are free to use the non UI procedures in any situation, including Maya's batch mode, since these don't do prompting or anything that works with windows.

To find a list of the procedures, take a look at "PART 8: Scripting Interface" of the acs script. There are all procedures with a short description of what they do and how to use them.

Here is a little example, demonstrating how to shorten the input names of the tutorial setup. You could place this or similar code into a shelf button and use it as a part of the acs script. Load acsTut2.ma or higher (from the example scenes of the Quick Start), make sure the acs UI is displayed, and run the following code.

// Source the acs script.
source "DPK_attrCombinationSystemUI.mel";

// We put our code into curly braces ("{}"), so that the variables stay local.
{
    // Retrieve the current acs node.
    string $acs = `DPK_acs_getACSnode`;

    // Get all inputs.
    int $inputs[] = `DPK_acs_getAllInputs $acs`;

    // It is much faster to rename all inputs at once than to rename them one
    // by one. Therefore, we collect the new names in the $names array.
    string $names[];

    // Iterate through the inputs, get their current name, and shorten it.
    int $x;
    for ($x = 0; $x < size($inputs); ++$x)
    {
        // Get the current name of the input.
        $names[$x] = `DPK_acs_getInputName $acs $inputs[$x]`;

        // At first, we will remove the "handCtrl_" prefix.
        $names[$x] = `substitute "^handCtrl_" $names[$x] ""`;

        // We don't need the "Curl" suffix.
        $names[$x] = `substitute "Curl$" $names[$x] ""`;

        // Shorten "spread" and "natural".
        $names[$x] = `substitute "spread"  $names[$x] "spr"`;
        $names[$x] = `substitute "natural" $names[$x] "nat"`;

        // Substitute the long with the short finger names.
        $names[$x] = `substitute "pointer" $names[$x] "pnt"`;
        $names[$x] = `substitute "middle"  $names[$x] "mid"`;
        $names[$x] = `substitute "ring"    $names[$x] "rng"`;
        $names[$x] = `substitute "pinky"   $names[$x] "pnk"`;
        $names[$x] = `substitute "thumb"   $names[$x] "tmb"`;
    }

    // The $names array now contains the new, shortened names. Assign these
    // names to the inputs.
    DPK_acs_renameInputs $acs $inputs $names;

    // The UI still shows the old names. This will lead to problems when they
    // are selected, since they don't exist anymore. To prevent this, we
    // update the UI.
    DPK_acs_refreshUI;
}

And now a little example of how to use these procedures for rigging. You have to open the acsTut1.ma scene (from the example scenes) and run the following code.

// Source the acs script.
source "DPK_attrCombinationSystemUI.mel";

// We put our code into curly braces ("{}"), so that the variables stay local.
{
    // Create a new acs node.
    string $acs = `DPK_acs_createACS "myACS"`;

    // Import the inputs and store them in local variables.
    int $pnt = `DPK_acs_importInput $acs "handCtrl.pointerCurl"`;
    int $mid = `DPK_acs_importInput $acs "handCtrl.middleCurl"`;
    int $rng = `DPK_acs_importInput $acs "handCtrl.ringCurl"`;
    int $pnk = `DPK_acs_importInput $acs "handCtrl.pinkyCurl"`;

    // Import the joints as outputs.
    int $pntJ1_x = `DPK_acs_importOutput $acs "pointer_1.rx"`;
    int $pntJ2_x = `DPK_acs_importOutput $acs "pointer_2.rx"`;
    int $pntJ3_x = `DPK_acs_importOutput $acs "pointer_3.rx"`;
    int $pntJ4_x = `DPK_acs_importOutput $acs "pointer_4.rx"`;
    int $midJ1_x = `DPK_acs_importOutput $acs "middle_1.rx"`;
    int $midJ2_x = `DPK_acs_importOutput $acs "middle_2.rx"`;
    int $midJ3_x = `DPK_acs_importOutput $acs "middle_3.rx"`;
    int $midJ4_x = `DPK_acs_importOutput $acs "middle_4.rx"`;
    int $rngJ1_x = `DPK_acs_importOutput $acs "ring_1.rx"`;
    int $rngJ2_x = `DPK_acs_importOutput $acs "ring_2.rx"`;
    int $rngJ3_x = `DPK_acs_importOutput $acs "ring_3.rx"`;
    int $rngJ4_x = `DPK_acs_importOutput $acs "ring_4.rx"`;
    int $pnkJ1_x = `DPK_acs_importOutput $acs "pinky_1.rx"`;
    int $pnkJ2_x = `DPK_acs_importOutput $acs "pinky_2.rx"`;
    int $pnkJ3_x = `DPK_acs_importOutput $acs "pinky_3.rx"`;
    int $pnkJ4_x = `DPK_acs_importOutput $acs "pinky_4.rx"`;

    // In case the outputs have had any value other then 0, we remove their
    // data from the neutral data point.
    DPK_acs_setDataPointValues $acs 0 0 int{} float{};

    // Create the input positions at 10 for every input.
    DPK_acs_createPosAttr $acs $pnt 0  10 "";
    DPK_acs_createPosAttr $acs $mid 0  10 "";
    DPK_acs_createPosAttr $acs $rng 0  10 "";
    DPK_acs_createPosAttr $acs $pnk 0  10 "";


    // Create a data point at position 10 of the pointerCurl input. <
    // To do this, we first build the position for the new dataPoint and store
    // it in the $posAttrs array.
    int $posAttrs[];

    // This dataPoint only has one posAttr in its position (i.e. it is 1D).
    $posAttrs[0] = DPK_acs_getPosAttr( $acs, $pnt, 0, 10 );

    // Create the dataPoint (and reset the $posAttrs array for further usage).
    int $dataPoint = `DPK_acs_createDataPoint $acs $posAttrs 0`;
    clear $posAttrs;

    // Set the values of the data point, so that the pointer curls.
    DPK_acs_setDataPointValues $acs $dataPoint 0
        { $pntJ1_x, $pntJ2_x, $pntJ3_x, $pntJ4_x }
        {   -1,       -95,      -95,      -95    };


    // Do the same with the other fingers. <
    $posAttrs[0] = DPK_acs_getPosAttr( $acs, $mid, 0, 10 );
    $dataPoint   = DPK_acs_createDataPoint( $acs, $posAttrs, 0 );
    clear $posAttrs;
    DPK_acs_setDataPointValues $acs $dataPoint 0
        { $midJ1_x, $midJ2_x, $midJ3_x, $midJ4_x }
        {   1,        -90,      -90,      -95    };

    $posAttrs[0] = DPK_acs_getPosAttr( $acs, $rng, 0, 10 );
    $dataPoint   = DPK_acs_createDataPoint( $acs, $posAttrs, 0 );
    clear $posAttrs;
    DPK_acs_setDataPointValues $acs $dataPoint 0
        { $rngJ1_x, $rngJ2_x, $rngJ3_x, $rngJ4_x }
        {   -1,       -95,      -90,      -100   };

    $posAttrs[0] = DPK_acs_getPosAttr( $acs, $pnk, 0, 10 );
    $dataPoint   = DPK_acs_createDataPoint( $acs, $posAttrs, 0 );
    clear $posAttrs;
    DPK_acs_setDataPointValues $acs $dataPoint 0
        { $pnkJ1_x, $pnkJ2_x, $pnkJ3_x, $pnkJ4_x }
        {   -4,       -95,      -70,      -90    };


    // Now, create a combination dataPoint. <
    // Add the natural attribute to the setup.
    int $nat = `DPK_acs_importInput $acs "handCtrl.natural"`;

    // Create the posAttr at 10.
    DPK_acs_createPosAttr $acs $nat 0  10 "";

    // Build the position for the combination dataPoint.
    $posAttrs[0] = DPK_acs_getPosAttr( $acs, $pnt, 0, 10 );
    $posAttrs[1] = DPK_acs_getPosAttr( $acs, $nat, 0, 10 );

    // Create the dataPoint.
    $dataPoint   = DPK_acs_createDataPoint( $acs, $posAttrs, 0 );
    clear $posAttrs;

    // Set the values.
    DPK_acs_setDataPointValues $acs $dataPoint 0
        { $midJ4_x, $midJ3_x, $midJ2_x, $rngJ4_x, $rngJ3_x, $rngJ2_x }
        {   -8,       -33,      -19,      -11,      -21,      3      };
}

This code will create a new acs node, import some inputs and outputs, and create a few data points. This is just an example and does not demonstrate the full power of the scripting interface, of course.

 

If anything is unclear or if you have any ideas or suggestions, feel free to email me at:
daniel@dpk.stargrav.com

Menus View Modes View Modes View Modes Input List DataPoint List Output List Decrease WPos Layer Increase WPos Layer Position Field Position Buttons Position Buttons Current ACS node Select current ACS node

Copyright © 2008, Daniel Pook-Kolb