Project 11.3: That s a Real Pane in My Window


A popular method for working with blend shape animation for facial animation is to link a camera to the face, often by constraining or parenting it underneath a joint representing the skull. This view then stays with the character, allowing a stable view for creating animation. In this project, we will create an interface optimized for animation of blend shape animation.

First, let s take a quick look at the standard Maya Blend Shape Editor, seen in Figure 11.20.

click to expand
Figure 11.20: The Maya Blend Shape Editor.

The Blend Shape Editor provides more control than an animator needs. While allowing an artist to add and remove blend shapes is great for a technical director, once it gets to the animation stage, all those issues should be resolved, and it would be awful if the animator were to accidentally deform the blend shapes . Therefore, we will remove those. Moreover, the huge scroll layout seems like an awful waste of space.

Design

Unfortunately, we cannot easily create a vertical slider as fully featured as that in the Blend Shape Editor. We want our sliders to possess the following attributes:

  • Horizontal or vertical orientation

  • Real-time updating of model (rather than on slider release)

  • Representation of animation data

Unfortunately, we cannot do all three. While MEL provides the facility to connect attributes directly, with the command connectControl , and we could build each individual element out of sliders and fields, they will not give the user feedback on whether a channel is animated. However, if we are simply willing to give up the vertical orientation, we get all this and more, in the form of automatic popup menus with the control attrFieldSliderGrp . This control sets up the two-way connection, gives us pre-made popup menus, and an interface with which animators are familiar.

Our first step is to design the window with all the layout breakdowns needed to create our window, seen in Figure 11.21.

click to expand
Figure 11.21: Blender window breakdown.

By this point, the process that we will use to find all our data to build our user interface should be readily familiar, so let s get to it.

Implementation

We begin, as always, by validating our script. See Example 11.17.

Example 11.17: Script validation.

 global proc blender ()     {     } 

Knowing that we have a valid script, we can begin adding functionality. Before we can build the window, we need to gather data from the scene. Specifically, we need to find the single object with a blendshape node we want to take control of. See Example 11.18.

Example 11.18: Finding the blendshape node of the selected object.

  // Find all the info on the blend node   // on current object   // Build Selection List  string $sel[] = `ls -selection`;  // Check to make sure the user has a single   // object selected  if (`size $sel` != 1)         error "Please select a blendshape object";  // Get the history listing for the object   // to find any blendshapes  string $hist[] = `listHistory`;     string $attribs[], $blendShapeNode;  // Find the blendshape  for ($each in $hist)         if (`nodeType $each` == "blendShape")             $blendShapeNode = $each;  // This finds the names of the attributes   // that drive the blend shape definition  string $contrib[] = `listAttr                         -multi ($blendShapeNode                                 + ".weight")`; 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_11/project_UI06/v01/blender.mel.

Now that we have our data gathered, we are ready to build the UI. Like any window, we first define the window, using an integer to define its width, aiding in window construction. See Example 11.19.

Example 11.19: The process begins with the creation of a window.

 if (`size $contrib` > 0)  //we build only if we qualify  {  // Build Window  int $windowWidth = 750;         if(`window -exists blenderUI` != 1)             {             window                 -maximizeButton false                 -resizeToFitChildren false                 -title "Blender"                 -iconName "Blender"                 -menuBar false                 -widthHeight $windowWidth 274                  blenderUI; 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_11/project_UI06/v02/blender.mel.

Next, we add the formLayout . While using the form layout makes the process of building a dynamic UI somewhat trickier, it is pretty much the only way to get the exact look we want. See Example 11.20.

Example 11.20: The addition of a form layout.

 // Form Layout     string $blenderForm = `formLayout                     -numberOfDivisions 100`; 

We will embed the modeling panel in a Pane Layout. Our modeling window will not have the menu bar, nor will it respond to key commands to turn on its shading status, so all that, along with camera assignment, must be done in code. After creating the paneLayout , we create the modelEditor panel. The Model Editor has many arguments that can influence its appearance. We have chosen to set the bare minimum to get a decent view with which to work. After creation, we assign the view to use the perspective camera. We could use a popupMenu or a optionMenu to control which camera to use or view settings. It would also be very easy, through a carefully constructed naming convention or by building artificial connections, to add the capability to switch between different characters . See Example 11.21.

Example 11.21: Adding a modeling panel to our UI.

  //Pane Layout  string $modPane = `paneLayout                             -configuration single`;  //Modeling Pane  string $modEdit = `modelEditor                 -displayAppearance smoothShaded                 -grid 0`                 ;  // CHANGE CAMERA USED HERE  modelEditor                 -edit                 -camera perspShape                 $modEdit;             setParent..;  //up to form  showWindow blenderUI; 
On the CD  

The text for this script is found on the CD-ROM as Chapter_11/project_UI06/v03/blender.mel

If we execute the script, we see something resembling Figure 11.22.

click to expand
Figure 11.22: The first build of the UI.

formLayout The collapsed panel is due to not using the power of the formLayout. We add the form layout edit before the window is drawn. We will have the modeling panel take up 45% of the form layout. See Example 11.22.

Example 11.22: Sizing the modeling panel element.

 formLayout -edit         -attachForm $modPane "top" 2         -attachForm $modPane "left" 2         -attachForm $modPane "bottom" 2         -attachPosition $modPane "right" 0 45         $blenderForm;     showWindow blenderUI; 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_11/project_UI06/v04/blender.mel.

After adding this edit statement, our UI appears somewhat similar to Figure 11.23.

click to expand
Figure 11.23: The properly sized modeling panel.

Now that we have the first half of the user interface finished, we can move into the dynamically built area.

The first objective will be to place a column layout to which we will add our sliders. Using a column layout is the best way to add an unknown number of controls to a UI and still have some control over its appearance. We capture the name of the column, which is a child of the formLayout , for later alignment. See Example 11.23.

Example 11.23: Adding a column layout to hold future additions to the UI.

 string $blenderColumn = `columnLayout                                  -adjustableColumn true                                  -rowSpacing 5`; 

To dynamically build the slider controls, we use a for loop to add a rowLayout , attrFieldSliderGroup , and button for each of the shapes that contribute to the blendshape node. Note that while some people like to overcrank the values of the blendshapes, we have limited the slider to between 0 and 1. This is the generally expected behavior, and the values that will be used by most artists most of the time. Should the need arise to go outside the expected range, it is a simple matter to go into the script and alter the limits. See Example 11.24.

Example 11.24: Using a loop to dynamically add controls to our layout.

 for ($each in $contrib)         {         rowLayout             -numberOfColumns 2             -columnWidth2 $windowWidth 50             -adjustableColumn 1             -columnAlign 1 center             -columnAlign 2 center             -columnAttach 1 both 0             -columnAttach 2 both 0             ;         attrFieldSliderGrp             -min 0.0             -max 1.0             -at ($blendShapeNode + "." + $each)             -label $each             -adjustableColumn 3             -columnAlign 1 right             -columnWidth 1 90             -columnWidth 4 1             ;         button             -label "Key"             -align center             -command ("setKeyframe " + $blendShapeNode +                         "." + $each);  setParent..;  //back to Column         } 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_11/project_UI06/v05/blender.mel.

We now want to modify the formLayout edit statement to account for and place the columnLayout in the formLayout . We will attach the left side of the columnLayout to the right side of the paneLayout that contains the modelPanel . See Example 11.25.

Example 11.25: Using the formLayout command with the edit flag to control the appearance of our UI.

 formLayout -edit         -attachForm $modPane "top" 2         -attachForm $modPane "left" 2         -attachForm $modPane "bottom" 2         -attachPosition $modPane "right" 0 45         -attachForm $blenderColumn "top" 2         -attachControl $blenderColumn left 5 $modPane         -attachForm $blenderColumn "bottom" 2         -attachForm $blenderColumn right 2         $blenderForm; 
On the CD  

The text for this script is found on the companion CD-ROM as Chapter_11/project_UI06/v06/blender.mel.

Right now, the UI works, and works as planned, seen in Figure 11.24. Because we used the formLayout , the user is free to resize the UI to his liking, and the 3D viewport and the sliders scale with the window.

click to expand
Figure 11.24: th2:Project Conclusion and Review

Because it is possible for the user to have enough blendshapes to more than fill the UI, in the script review we have incorporated conditional statements to implement in a scroll layout when needed. Note that when the scrollLayout is active, we have to add conditional setParent and formLayout “edit statements.

On the CD  

The text for the final script is found on the companion CD-ROM as Chapter_11/project_UI06/final/blender.mel.

We have seen how the flexibility and power of user-created UIs can be greatly enhanced by incorporating appropriate panel elements. Next, we will cover scripted panels, which take almost the antithesis approach, incorporating controls and layouts into panels.

Project Script Review

 global proc blender ()     {  // Find All the info on the blend node   // on current object  string $sel[] = `ls -sl`;     if (`size $sel` == 0)         error "Please select a blendshape object";     string $hist[] = `listHistory -il 2`;     string $attribs[], $blendShapeNode;     for ($each in $hist)         if (`nodeType $each` == "blendShape")             $blendShapeNode = $each;     string $contrib[] = `listAttr                         -multi ($blendShapeNode                                 + ".weight")`;     float $conWts[] = `getAttr ($blendShapeNode                                 + ".weight")`;     if (`size $contrib` > 0)         {  // Build Window  int $windowWidth = 750;         if(`window -exists blenderUI` != 1)             {             window                 -maximizeButton false                 -resizeToFitChildren false                 -title "Blender"                 -iconName "Blender"                 -menuBar false                 -wh $windowWidth 274                  blenderUI;  // Form Layout  string $blenderForm = `formLayout                     -numberOfDivisions 100`;  // Pane Layout  string $modPane = `paneLayout                             -configuration single`;  // Modeling Pane  string $modEdit = `modelEditor             -displayAppearance smoothShaded             -grid 0`             ;  // CHANGE CAMERA USED HERE  modelEditor                 -edit                 -camera perspShape                 $modEdit;  setParent..;  //up to form             string $scrollLay;             if (`size $conWts` > 10)                 $scrollLay = `scrollLayout                          -horizontalScrollBarThickness 0                          -verticalScrollBarThickness 5`;             string $blenderColumn = `columnLayout                                  -adjustableColumn true                                  -rowSpacing 5`;             for ($i = 0; $i < `size $conWts`; $i++)                 {                 rowLayout                     -numberOfColumns 2                     -columnWidth2 ($windowWidth) 50                     -adjustableColumn 1                     -columnAlign 1 "center"                     -columnAlign 2 "center"                     -columnAttach 1 "both" 0                     -columnAttach 2 "both" 0                     ;                         attrFieldSliderGrp                             -min 0.0                             -max 1.0                             -at ($blendShapeNode                                     + "."                                     + $contrib[$i])                             -label $contrib[$i]                             -adjustableColumn 3                             -columnAlign 1 right                             -columnWidth 1 90                             -columnWidth 4 1                             ;                         button                             -label "Key"                             -align center                             -command ("setKeyframe "                                         + $blendShapeNode                                         + "."                                         + $contrib[$i]);  setParent..;  //back to Column                 }         if (`size $scrollLay` > 0)  setParent ..;  //  up to scroll if needed   setParent ..;  //  up to form  if (`size $scrollLay` == 0)         {         formLayout             -edit             -attachForm $modPane "top" 2             -attachForm $modPane "left" 2             -attachForm $modPane "bottom" 2             -attachPosition $modPane "right" 0 45             -attachForm $blenderColumn "top" 2             -attachControl $blenderColumn left 5 $modPane             -attachForm $blenderColumn "bottom" 2             -attachForm $blenderColumn right 2             $blenderForm;         }     else         {         formLayout             -edit             -attachForm $modPane "top" 2             -attachForm $modPane "left" 2             -attachForm $modPane "bottom" 2             -attachPosition $modPane "right" 0 45             -attachForm $scrollLay "top" 2             -attachControl $scrollLay left 5 $modPane             -attachForm $scrollLay "bottom" 2             -attachForm $scrollLay right 2             $blenderForm;         }     showWindow blenderUI;     }     }     } 



The MEL Companion
The MEL Companion: Maya Scripting for 3D Artists (Charles River Media Graphics)
ISBN: 1584502754
EAN: 2147483647
Year: 2003
Pages: 101

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net