一半君的总结纸

听话只听一半君

#37 如何在Attribute Editor里添加自定义属性的下拉菜单?

如果你在Maya里随便选一个transform node , Attribute Editor 里Rotate Order属性是有一个下拉菜单的,本篇 How-To 将演示如何给自己加的属性添加一个类似的菜单.

首先你必须知道Maya是如何生成这些菜单的. 我去看了下AEtemplate scripts, 希望能在里面找到定义这种custom controls的地方. 但是没找到,似乎这效果是在内部定义的,而不是通过 MEL template定义的:

global proc AEtransformMain ( string $nodeName )
{
  // ...
  editorTemplate -beginLayout "Transform Attributes" -collapse 0;

  // ...
    editorTemplate -addControl "rotateOrder";
}

虽然我们没办法改变Maya的内部默认行为. 但我们 可以 通过使用 AEtemplate system 达到同样的效果 — 在 template里修改/添加相应的节点类型. 在下面的例子中我用过的是 locator , 然后我为.locatorOption属性创建了一个 attrEnumOptionMenuGrp .

注意: 在为某个自定义属性定义这种菜单的时候,如果在节点类型里没有这个自定义属性,就会出问题。比如如果你的第一个locator没有这个属性,就会出错。除非你重启Maya,你才能让你修改过的 AEtemplate 发挥效果.

这里我使用了一个弱智方法来保证locator上的这个属性始终存在; 显然我肯定这不是最好的方法. 可能还有更好的方法, 但唯一能彻底避免这个问题的方法是通过API定义一个 custom node class , 这样你的locator-derived node才能一出来就带有你的自定义属性.

下面是我的临时解决方法:

//  Procedure Name:
//  AElocatorTemplate (modified)
//
//  Description:
//  Creates the attribute editor controls for the locator node
//  and creates an attrEnumOptionMenuGrp for a '.locatorOption' attr

// This function adds the given attribute if it doesn't already exist.
proc assertAttribute( string $attrName )
{
  string $nodeName[];
  tokenize($attrName, ".", $nodeName);

  if ( !`attributeQuery -node $nodeName[0] -exists $nodeName[1]` )
    addAttr -at "short" -ln $nodeName[1] -dv 0 -min 0 $nodeName[0];
}

// This function is called when the Attribute Editor page is
// first created for a locator node
global proc AElocatorOptionNew( string $attrName )
{
  string $nodeName[];
  tokenize($attrName, ".", $nodeName);

  // This hack ensures that the standard locator has the
  // extra attribute; else, this enhancement will not work!
  assertAttribute( $attrName );

  // Push the Attribute Editor UITemplate
  setUITemplate -pst attributeEditorPresetsTemplate;

  // Add the optionMenu enumeration group.
  // This will be connected to the our specified attribute.
  attrEnumOptionMenuGrp
    -l "Option"
    -columnAlign 1 "right"
    -at $attrName
    -ei 0 "Default"
    -ei 1 "Option #1"
    -ei 2 "Option #2"
    -ei 3 "Option #3"
    -ei 4 "(etc)"
      locatorEnumOptionMenu;

  // Pop to restore the UITemplate
  setUITemplate -ppt;
}

// This function is called for subsequent selections
// of a locator node
global proc AElocatorOptionReplace( string $attrName )
{
  string $nodeName[];
  tokenize($attrName, ".", $nodeName);

  // Disable the drop-down menu if the attribute does not exist
  if ( `attributeQuery -node $nodeName[0] -exists "locatorOption"` )
    attrEnumOptionMenuGrp -e
       -enable true
       -attribute $attrName
          locatorEnumOptionMenu;
  else
    attrEnumOptionMenuGrp -e -enable false locatorEnumOptionMenu;

}

// The editor template for the locator
global proc AElocatorTemplate( string $nodeName )
{
  editorTemplate -beginScrollLayout;

    editorTemplate -beginLayout "Locator Attributes" -collapse 0;
      AElocatorCommon $nodeName;

      // Define custom control for locatorOption attribute
      editorTemplate -callCustom
        "AElocatorOptionNew"
        "AElocatorOptionReplace"
        "locatorOption";

      // Suppress the numerical attribute in Extra Attributes
      editorTemplate -suppress "locatorOption";

    editorTemplate -endLayout;

    AElocatorInclude $nodeName;

  editorTemplate -addExtraControls;
  editorTemplate -endScrollLayout;
}

(修改 AEtemplates 时候最麻烦的就是他们是被缓存了的,如果你改了某处,你只能重启Maya才能看到修改过后的效果.)

下一个问题是: 我在 Channel Box里如何达到同样效果.

不幸的是, 我还不知道如何 (或者是是否可行) 达到.

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: