一半君的总结纸

听话只听一半君

#123 如何自定义Attribute Editor Template?

用人话说就是假如你写了个.mll .so插件,新创建了某种类型的节点,那么他需要一个attribute editor, 具体有哪些属性可以改,以及他长什么样子,也是人写出来的

再简单点的例子比如,rigging的时候,某个node上你加了一堆dynamic attrs,但是你又不想他们出现在attribute editor的最底下,又比如一个string的attr,你想让他右侧有个按钮,按了以后出现个file browser让你选图片序列,这都需要自定义个template,不然默认就是一个textedit输入框而已

有两种方法可以做到,他们分别是写.mel和 Maya 2013之后的新的用.xml文件的方法

方法1,AETemplate.mel

这种方法只能对某种类型的node进行设置,一改就全改了,如果你写的plugin有注册新的节点类型,那可以用此方法

假设你新建一个scene,里面只有一个空group, 加了几个attr用于测试

createNode transform -n "ctrl_grp";
	addAttr -ci true -sn "imageName" -ln "imageName" -dt "string";
	addAttr -ci true -sn "frameExtension" -ln "frameExtension" -at "long";
	addAttr -ci true -sn "enumAttr" -ln "enumAttr" -min 0 -max 2 -en "Green:Blue:Red" 
		-at "enum";
	setAttr -k on ".imageName";
	setAttr -k on ".frameExtension";
	setAttr -k on ".enumAttr";

什么都不做的时候,默认是这效果
attribute_editor_1

如果在MAYA_SCRIPTS_PATH里有个叫做AEtransformTemplate.mel的文件,那么
attribute_editor_2

其内容可以是

global proc AEtransformTemplate( string $nodeName )
{
    editorTemplate -beginScrollLayout;

    // AEtransformMain $nodeName;
    // AEtransformNoScroll $nodeName;

    editorTemplate -beginLayout "Image Sequence Attributes" -collapse 0;
    //Add imageName attr - string
    editorTemplate -label "Image Path: " -addControl "imageName";
    // here the last argument "imageName" is optional
    editorTemplate -callCustom "AE_file_browse" "AE_file_browse_repeat" "imageName";
    editorTemplate -endLayout;


    editorTemplate -beginLayout "Offsets" -collapse 0;
    //Add the frameExtension attr - int
    editorTemplate -label "Frame: "-addControl "frameExtension";
    //Add the numAttr control
    // editorTemplate -addControl "enumAttr";
    editorTemplate -callCustom "UTrans_extraCtrlsBuild" "UTrans_extraCtrlsUpdate" "enumAttr";
    editorTemplate -endLayout;

    // add default transform attrs
    AEtransformMain $nodeName;
    AEtransformNoScroll $nodeName;
 
    editorTemplate -addExtraControls;

    editorTemplate -endScrollLayout;
}

// http://danostrov.com/2012/10/27/intro-to-aetemplates/
global proc UTrans_extraCtrlsBuild(string $enumAttrName)
{
    //Create an attrEnumOptionMenuGrp for the enumAttr
    attrEnumOptionMenuGrp
        -label "Enumerated: "
        -attribute $enumAttrName
        -enumeratedItem 0 "zero"
        -enumeratedItem 1 "one"
        -enumeratedItem 2 "two"
        -enumeratedItem 3 "three"
        UTransEnumAttrOptionGrp;
}

global proc UTrans_extraCtrlsUpdate(string $enumAttrName)
{
    //Update the attrEnumOptionMenuGrp for the enumAttr
    attrEnumOptionMenuGrp -e -attribute $enumAttrName UTransEnumAttrOptionGrp;
}


// http://antarcticoutpost31.blogspot.ca/2011/03/maya-ae-template-file-browser.html
// here "imageName" is passed as $attr, but it's optional
global proc AE_file_browse(string $attr){
 
 rowLayout -nc 3;
  text -label "Path Selector";
  textField  -fileName `getAttr $attr` LocationText;
  symbolButton -image "navButtonBrowse.xpm" -c ("loadPopup(\"" + $attr + "\")");
  setParent ..;
 
}

global proc AE_file_browse_repeat(string $attr){
 textField  -e -fileName `getAttr $attr` LocationText;
}


global proc loadPopup(string $attr){
 string $loc = `fileDialog -dm "*"`;
 
 if ($loc != ""){
  setAttr -type "string" $attr $loc;
  textField -e -fileName `getAttr $attr` LocationText;
 }
}

其中

// 定义一段可折叠的folder
editorTemplate -beginLayout "Image Sequence Attributes" -collapse 0;
...
editorTemplate -endLayout;

// 后面的前两个参数分别是 build时候运行的command update时候运行的command <参数1> <参数2> ...
editorTemplate -callCustom "AE_file_browse" "AE_file_browse_repeat" "imageName";

上面这段试了下按下Path Selector右侧按钮的时候,打开一个文件选择dialog,然后不但设置自身的textedit,他还能修改另一个attr,比如他上面的imagePath,此外,凡是被editorTemplate加到顶上去的attr,就不再出现在最底下的 extra attributes里了

测试的时候运行以下命令可以刷新显示效果

source "AExxxTemplate.mel";
refreshEditorTemplates;
方法2,使用xml形式的template

要求maya 2013或更高,这个新增的功能不但可以设置特定节点类型的attribute editor要如何显示,他还能限定如果这个节点是某个特殊的名字的时候才生效(这就消除了以前template只能用在开发者写的插件带来的新节点类型上的局限性,现在带来了更多可能性,因为可以自定义显示哪些ui,用处比如动画师可以不仅仅操作channelbox了,当然各公司一般都有某个ui来选control,不会直接用channelbox,但是这里开创了一种新的可能性)

如果设置了MAYA_CUSTOM_TEMPLATE_PATH环境变量,而里面又有这样的一个名字的xml文件的话AETemplate.xml,那就和旧版本Maya一样,对所有这个类型的node生效,如果是AE.Template.xml的话,那只就是对名字叫做NodeName的节点生效

xml的template可以用bonus tools里带的 Attribute Editor Template Builder辅助生成,先出个大形再手改也可以
attribute_editor_xml_1

根据Maya帮助,template里的callback可以用mel也可以用python,现在一般都尽量用python了吧
还是使用上面的ctrl_grp做例子,不过又给他添加了一个dummy属性
假如我有这样一个xml文件,他的名字决定了他只对叫做ctrl_grp的transform node 生效

<?xml version='1.0' encoding='UTF-8'?>
<templates>
    <template name="AEtransform">

        <attribute name="frameExtension" type="maya.long">
            <label>Frame Extension</label>
        </attribute>
        <attribute name="enumAttr" type="maya.enum">
            <label>Enum Attr</label>
        </attribute>
        <attribute name="imageName" type="maya.string">
            <label>Image Name</label>
        </attribute>

        <attribute name="dummy" type="maya.float">
            <label>Anything you want</label>
            <description language="cb">py.AEaddFloatSlider.AEaddFloatSliderModule</description>
        </attribute>

    </template>

    <view name="Custom" template="AEtransform">
        <property name="frameExtension"/>
        <property name="enumAttr"/>
        <property name="imageName"/>
        <property name="dummy"/>
    </view>
    
</templates>

其中定义了一个view叫Custom, 其中dummy attr顾名思义,是为了加上label叫做Anything you want的滑条而随便起的名字(可以是其他任何ui,因为具体创建什么ui是由AEaddFloatSlider.py文件里的AEaddFloatSliderModule function决定的,利用这一点,可以在attribute editor里创建任何ui,dummy属性可以不存在,只要你在callback里完全不用他就行

import maya.cmds as cmds
def AEaddFloatSliderModule(	plug, sliderLabel, annot ):
	# create your ui here 
	cmds.rowLayout( nc=2 )
	# val = cmds.getAttr( plug )
	cmds.text( label=sliderLabel )
	slider = cmds.floatSlider( annotation=annot, v=100 )

	# update maya scene after slider updated
	def AEaddFloatSliderModuleCB( *args ):
		val = cmds.floatSlider( slider, q=1, v=1 )
		print 'in callback:',val
		# cmds.setAttr( plug, val )

	cmds.floatSlider( slider, e=1, cc=AEaddFloatSliderModuleCB )
	cmds.setParent( u=1 )

上面的代码是maya帮助里的,plug就是传来的attr的名字,在这里是’custom’, lz把getAttr / setAttr 去掉了,因为lz这里想表示的是,即使是个不存在的attr,照样可以创建ui

测试的时候,刷新attribute editor显示可以用

putenv MAYA_CUSTOM_TEMPLATE_PATH "/path/to/your/template"
refreshCustomTemplate;
ShowAttributeEditorOrChannelBox;
ShowAttributeEditorOrChannelBox;

python("import AEaddFloatSlider");
python("reload(AEaddFloatSlider)");

// set current view
setLocalView "Custom" "ctrl_grp" 1;

// hide view label
// toggleViewLabels(0)

在上面的例子里,callback的作用就是拖滑条,放手的时候执行,当然这里可以是任何操作

如上所述,既然可以加任意ui,那把modelpanel, grapheditor等乱搞的ui加进去也是可以的了?lz下面来试一下


上图的代码示例

lz又试了下graph editor嵌入,不过感觉意义不明显,而且如果不禁用attribute editor自动刷新,直接会造成maya跳出,似乎每次点到别的object,都会造成panelayout被删除,但是customGraphEditor这个scriptedPanel可以被保留,lz在加上customGraphEditor之后就把自动刷新attribute editor关了以避免crash,暂时没想到什么好办法利用这个嵌入的graph editor

上图的代码示例

此外试一下加个file browser按钮

上图的代码示例

待续…

参考:
Maya AE Template File Browser
Intro to AETemplates – Dan Ostrov
Custom Attribute Editor templates – maya 2015 Documentation
Autodesk Maya Bonus Tools 2014-2015-2016
Mixing PyQt4 and Maya UI objects
Workflow Scripts – Aaron Koressel

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 博主赞过: