为“绘制脚本工具”(Paint Scripts Tool)写入 MEL 脚本 
              
              
              注意
              本部分假定了解 MEL 脚本和编程的知识。有关 MEL 的详细信息,请参见手册的MEL 和表达式部分。 
“绘制脚本工具”(Paint Scripts Tool)的依据是在 NURBS 或多边形曲面上叠加的二维数值数组的概念。该数组由曲面的顶点位置定义或由均匀分布于曲面参数空间的任意 2D 栅格定义。将该数值数组想象成 2D 灰度图像,其中各像素对应一个数组位置,而灰度值对应与该数组位置相关联的数值。与“绘制脚本工具”(Paint Scripts Tool)相关联的脚本确定 Artisan 解释数值数组的方式。需要知道指定给如上所述其中之一数组位置的数值时,Artisan 调用脚本。更改指定给其中一个数组位置的数值时,Artisan 也可以调用脚本。
脚本绘制 MEL 程序
“绘制脚本工具”(Paint Scripts Tool)由一组 MEL 程序定义。MEL 程序的名称在“工具设置”(Tool Settings)编辑器的“设置”(Setup)区域显示。也可以使用 artUserPaintCtx MEL 命令设置 MEL 程序。本章介绍了以下 Artisan MEL 程序:
工具设置命令 (-tsc "ToolSetupCommand") 
              工具清理命令 (-tcc "ToolCleanupCommand") 
              获取数组属性命令 (-gac "GetArrayAttributeCommand") 
              初始化命令 (-ic "InitializeCommand") 
              完成命令 (-fc "FinalizeCommand") 
              设定值命令 (-svc "SetValueCommand") 
              获取值命令 (-gvc "GetValueCommand") 
              获取曲面命令 (-gsc "GetSurfaceCommand") 
              更改栅格大小 
              绘制圆锥体而不是球体 
              抖动栅格 
              在下列描述中,用于设定命令的 artUserPaintCtx 标志括在括号内。 
“工具设置命令”(Tool Setup Command) (-tsc "ToolSetupCommand")
如果已定义,一选定(通过使用“修改 > 绘制脚本工具(Modify > Paint Scripts Tool)”菜单项或从“工具箱”(Tool Box)或工具架中选择)“绘制脚本工具”(Paint Scripts Tool)之后,即调用 ToolSetupCommand。该程序常用于设置所有其他的 Artisan MEL 程序。该程序定义如下:
global proc ToolSetupCommand (
              string $toolContextName
              )
              {
              // This is an example artUserPaintCtx command that would setup
              // the following Artisan procedures. This is not a realistic
              // example because you would never have all the procedures
              // defined.
              //
              artUserPaintCtx -e
              -tcc "ToolCleanupCommand"
              -gac "GetArrayAttributeCommand"
              -ic "InitializeCommand" -fc "FinalizeCommand"
              -svc "SetValueCommand" -gvc "GetValueCommand"
              -gsc "GetSurfaceCommand"
              $toolContextName;
              }
              其中,$toolContextName 是选定工具上下文的名称。旨在将其用作 artUserPaintCtx 命令的最终参数。 
“工具清理命令”(Tool Cleanup Command) (-tcc "ToolCleanupCommand")
如果已定义,在即将退出“绘制脚本工具”(Paint Scripts Tool)之前,调用 ToolCleanupCommand。该程序定义如下:
global proc ToolCleanupCommand (
              string $toolContextName
              )
              {
              ...
              }
              其中,$toolContextName 是已退出工具上下文的名称。 
“获取数组属性命令”(Get Array Attribute Command) (-gac "GetArrayAttributeCommand")
如果定义该命令,可忽略对初始化命令、完成命令、设定值命令以及获取值命令定义的任何命令。
如果已定义,一旦选定用于绘制的各个曲面,即调用 GetArrayAttributeCommand。该程序返回字符串,其解释为指称某些依存关系节点上双数组属性的名称列表。该程序定义如下:
global proc string GetArrayAttributeCommand (
              string $surfaceName
              )
              {
              string $arrayAttributes
              // determine array attributes that correspond to
              // $surfaceName
              ...
              return $arrayAttributes;
              }
              其中,$surfacename 是曲面的名称,其与返回的数组属性相关联。如果返回多个数组属性,Artisan 需要一个值时将读取第一个属性,但是 Artisan 会将所有属性都写入。 
“初始化命令”(Initialize Command) (-ic "InitializeCommand")
如果已定义,开始每个笔划前,各可绘制曲面调用一次 InitializeCommand。该程序定义如下:
global proc string InitializeCommand(
              int $surfaceName
              )
              {
              string $flags;
              // build up $flags
              //
              ...
              return $flags;
              }
              其中,$surfacename 是曲面名称。有关示例,请参见以下目录中的 spherePaint.mel 和 geometryPaint.mel: 
(Windows) Drive:\Program Files\Autodesk\Maya2012\scripts\others 
              (Linux) mayapath/scripts/others 
              (Mac OS X) /Applications/Autodesk/maya2012/Maya.app/Contents/scripts/others 
              该程序应: 
为该曲面确定唯一的整数 曲面 ID。该 ID 将被传递到与该曲面相关联的 SetValueCommand、GetValueCommand 和 FinalizeCommand 的未来调用。如果脚本保持每个曲面的信息,将该 ID 变成数组索引是极容易的,索引可用于轻松访问每个曲面的信息。 
              确定未来调用与该曲面相关联的 SetValueCommand 哪种类型的信息。 
              确定是在曲面顶点绘制,还是在曲面参数空间中等间距分布的栅格上绘制。 
              所有这类信息通过程序传递回的 $flags 变量传递回 Artisan。该字符串包含一系列标志和参数,这些标志和参数与能够传递到标准 MEL 程序中的标志和参数非常类似。下面介绍了“绘制脚本工具”(Paint Scripts Tool)能够识别的标志。每个标志都有一个短版本和一个长版本(按下面的方式即为:-短/长)以及一些参数: 
-id/identifier int
              该标志表示即将用于该曲面的整数曲面 ID。如果该标志未指定,该曲面的曲面 ID 为 -1。 
-uv/uvlong string
              该标志指示是否应该将 (U,V) 位置发送到 SetValueCommand。对于此,可能的值为无、曲面或规格化。默认值为无。 
-p/position string
              该标志指示是否应该将 (x,y,z) 位置发送到 SetValueCommand。对于这一点,可能的值为 none、local 或 world。默认值为无。 
-n/normal string
              该标志指示是否应该将 (nx,ny,nz) 法线发送到 SetValueCommand。对于这一点,可能的值为 none、local 或 world。默认值为无。 
-g/grid int1 int2
              该标志指示应在曲面 U 方向大小为 int1 且曲面 V 方向大小为 int2 的参数空间内等间距分布的栅格上进行绘制。如果未指定该标志,将在曲面顶点定义的数组上进行绘制。 
-j/jitter boolean
              该标志仅与 -grid 标志配合使用时才有效。如果为 true,那么在将其传递到 SetValueCommand 之前,栅格位置发生抖动。默认值为 false。 
-d/dither boolean
              该标志仅与 -grid 标志配合使用时才有效。如果为 true,Artisan 使用 16x16 抖动矩阵,以确定是否为其调用 SetValueCommand。 
-dt/directionType string 
              该标志指示 (U,V,W) 笔划方向是否应发送到 SetValueCommand。对于此,可能的值为无、screenV(屏幕空间中的向量)或 worldV(世界空间中的向量)。默认值为无。对于投影绘制,screenV 和 worldV 均返回屏幕空间中的向量。方向选项不支持反射绘制。如果请求的方向为屏幕向量,那么第三个值 (W) 将无效。 
-sp/stampPosition string 
              该标志指示 (spX,spY,spZ) 图章位置是否应发送到 SetValueCommand。对于这一点,可能的值为 none、local 或 world。默认值为无。 
“完成命令”(Finalize Command) (-fc "FinalizeCommand")
如果已定义,每个笔划完成后,各可绘制曲面调用一次 FinalizeCommand。该程序定义如下:
global proc FinalizeCommand(
              int $surfaceID
              )
              {
              ...
              }
              其中,$surfaceID 是由该曲面相应的 InitializeCommand 指定给曲面的曲面标识符。 
“设定值命令”(Set Value Command) (-svc "SetValueCommand")
如果已定义,Artisan 设定了与曲面的特定“位置”相关联的值后,调用 SetValueCommand。每个位置调用该程序一次。因此,如果某个 Artisan 绘制操作在曲面上的 10 处位置更改值,那么调用 SetArrayAttributeCommand 10 次。该程序定义如下:
global proc SetValueCommand(
              int $surfaceID,
              int $index,
              float $value,
              //
              // The following arguments are only passed if requested by
              // InitializeCommand. However this is the order that they
              // will be passed in.
              //
              float $u,			// ($u,$v) is UV location on surface
              float $v, 
              float $px,			// ($px,$py,$pz) is position on surface
              float $py,
              float $pz,
              float $nx,			// ($nx,$ny,$nz) is surface normal
              float $ny,
              float $nz
              )
              {
              ...
              }
              其中: 
$surfaceID 是由该曲面相应的 InitializeCommand 指定给曲面的曲面标识符 
              $index 是顶点或栅格索引 
              $value 是即将指定给传递索引的值 
              传递到该程序的附加参数取决于曲面 InitializeCommand 的返回。 
“获取值命令”(Get Value Command) (-gvc "GetValueCommand")
如果已定义,Artisan 想要与曲面的特定“位置”相关联的值时,调用 GetValueCommand。该程序定义如下:
global proc float GetValueCommand(
              int $surfaceID,
              int $valueIndex
              )
              {
              float $value
              // determine the value associated with $valueIndex location
              // on surface $surfaceID
              //
              ...
              return $value;
              }
              其中: 
$surfaceID 是由该曲面相应的 InitializeCommand 指定给曲面的曲面标识符 
              $valueIndex 是 Artisan 请求其值的某“位置”的索引 
              “获取曲面命令”(Get Surface Command) (-gsc "GetSurfaceCommand") 
很少对该命令进行定义。如果已定义,Artisan 每次处理选择列表时,选择列表上各依存关系节点调用一次 GetSurfaceCommand。任何时候选定“绘制脚本工具”(Paint Scripts Tool),通常都会出现这种情况。该程序定义如下:
global proc string GetSurfaceCommand (
              string $selectedDependencyNode
              )
              {
              string $surface;
              // Set $surface based on $selectedDependencyNode.
              // Set $surface to NULL string (""), if no surface 
              // is to be painted because of $selectedDependencyNode.
              //
              ...
  
              return $surface;
              }
              该程序覆盖 Artisan 对选择列表的默认处理。 
示例脚本绘制脚本
本部分介绍总体脚本布局并给出注释脚本示例。
总体脚本布局
用于“绘制脚本工具”(Paint Scripts Tool)的脚本可以以多种方式排列。该示例脚本布局用于采样 Artisan 脚本,可见于:
(Windows) Drive:\Program Files\Autodesk\Maya2012\scripts\others 
              (Linux) mayapath/scripts/others 
              (Mac OS X) /Applications/Autodesk/maya2012/Maya.app/Contents/scripts/others 
              布局在一个文件中保留所有 MEL 程序,所有的脚本,并仅允许填充“工具设置”(Tool Settings)窗口“设置”(Setup)区域中的“工具设置命令”(Tool Setup Cmd)框的方式定义所有脚本。该程序通过使用 artUserPaintCtx 命令设置所有其他 MEL 程序。对此的详细介绍如下: 
// Define global variables used throughout the script
              //
              global ...;
              // Define the Tool Setup Cmd procedure. This procedure will
              // setup all the other MEL procedures used by the Paint //Scripts tool.
              //
              // "spherePaint" would be entered into the Tool Setup Cmd field in
              // the Setup section of the tool settings window.
              //
              global proc spherePaint( string $context )
              {
              artUserPaintCtx -e
              -ic "initSpherePaint"
              -fc "finishSpherePaint"
              -svc "setSpherePaintValue"
              -gvc "getSpherePaintValue"
              -gsc ""
              -gac ""
              -tcc ""
              $context;
              }
              // Define various procedures that were mentioned in the Tool
              //Setup Cmd procedure above. All the procedures defined by
              //the artUserPaintCtx command have to be global.
              //
              global proc string initSpherePaint( string $surfaceName )
              {
              ...
              }
              ...
              spherePaint.mel 
这是一个注释版本的 spherePaint.mel 文件,提供位置如下:
(Windows) Drive:\Program Files\Autodesk\Maya2012\scripts\others 
              (Linux) mayapath/scripts/others 
              (Mac OS X) /Applications/Autodesk/maya2012/Maya.app/Contents/scripts/others 
              该脚本仅适用于 NURBS 曲面。 
//
              // This is a simple example script for the Artisan Paint 
              //Scripts tool. It will paint spheres onto the selected
              //surfaces. The size of the spheres are controlled by the
              //painted values.
              //
              // Usage:
              // 1) Place this script into your scripts directory (usually
              //the maya/scripts directory in your home directory
              // 2) Select the Paint Scripts Tool (Modify > Paint Scripts
              // Tool) and bring up the Tool Settings window
              // 3) Go to the Setup section and enter "spherePaint" into 
              // the "Tool Setup Cmd" field and hit enter
              // 4) Paint Geometry
              //
              // Tips:
              // Once you have the Geometry Paint Tool setup you may want
              // to it from the toolbar to the shelf so that it is always
              // accessible
              //
              这些全局变量用于确定正在绘制的曲面数量并确定曲面 ID。$sphereNamePrefix 是一个字符串数组,每个活动曲面一个字符串。如果条目为空字符串,则表示可获取其数组索引,并将其用作曲面 ID。如果该条目非空,那么创建球体时将该字符串用作前缀。$spherePaintFreeSlot 是 $sphereNamePrefix 的第一个可用条目,$spherePaintSlots 是 $sphereNamePrefix 的当前大小。曲面 ID 使用数组索引来存储每个曲面信息,这种方法经常在一些其他的采样 Artisan 脚本中频繁使用。 
// These are global variables used to keep track of multiple
              // surfaces and the name prefixes used for the spheres on each
              // surface
              //
              global string $sphereNamePrefix[];
              global int $spherePaintFreeSlot = 0;
              global int $spherePaintSlots = 0;
              spherePaint 是初始化“绘制脚本工具”(Paint Scripts Tool)的程序,方法是告知其在各种情况下应调用哪些程序。 
// This procedure should be set as the "Tool Setup Cmd" in the 
              // Setup section of the Maya Artisan Paint Scripts Tool’s tool settings
              // window. The tool context is supplied as an argument.
              //
              global proc spherePaint( string $context )
              {
              // initialize all the other commands in this scriptable 
              // paint tool context.
              // 
              artUserPaintCtx -e
              -ic "initSpherePaint"
              -fc "finishSpherePaint"
              -svc "setSpherePaintValue"
              -gvc "getSpherePaintValue"
              -gsc ""
              -cc ""
              -tcc ""
              -gac ""
              $context;
              }
              // This is the "Initialize Cmd". This procedure is called once
              // for every selected surface when an initial click is received
              // on any surface. The argument is the name of the surface. This
              // procedure returns a string which indicates to the scriptable
              // tool how to behave for the duration of the stroke. 
              //
              global proc string initSpherePaint( string $name )
              {
              global string $sphereNamePrefix[];
              global int $spherePaintFreeSlot;
              global int $spherePaintSlots;
              int $slot;
              首先要确定与该曲面相关联的曲面 ID。这可以通过查阅 $sphereNamePrefix 数组,查找第一个可用条目完成。一旦找到条目,该条目索引将被用作曲面 ID ($slot)。 
 // find a free slot for this surface in the global arrays
              //
              for ( $slot = $spherePaintFreeSlot; $slot < $spherePaintSlots; $slot++ )
              {
              if ( $sphereNamePrefix[$slot] == "" ) {
              break;
              }
              } 
              if ( $slot == $spherePaintSlots ) {
              $spherePaintSlots++;
              $spherePaintFreeSlot = $spherePaintSlots;
              }
              下一步是确定传入的 $name 是否对应于 NURBS 曲面。如果对应,那么生成已绘制球体的前缀,并将其存储到 $sphereNamePrefix 数组中相应的条目。 
 if ( ‘nodeType $name‘ == "nurbsSurface" ) {
              // save the name of the parent of this shape as well
              // as a prefix to use when creating the spheres
              //
              string $parent[] = `listRelatives -p $name`;
              $sphereNamePrefix[$slot] = $parent[0] + "Sphere";
              }
              初始化程序的最终功能是返回一个字符串,该字符串指示 Artisan 如何处理该曲面。该字符串是特殊标志及其参数组成的一个序列,上文已有描述。在本例中,字符串包含的标志可指示 Artisan: 
应为该曲面使用哪个曲面 ID 
              绘制应在曲面的参数空间上均匀分布的 20x20 栅格上进行 
              任何时候一旦调用,即将世界空间的位置传递到 setSpherePaintValue。 
              // Return an argument string which:
              // - tells the tool what surface ID to use for this surface
              // - indicates that values should be distributed on a 20x20
              // grid on the surface
              // - indicate that the associated world space position
              // should also be passed to the "Set Value Cmd".
              //
              return ( "-id " + $slot
              + " -grid 20 20"
              + " -position world");
              }
              // This is the "Finalize Cmd". This procedure is called at the
              // end of the stroke. It is passed the surface ID, that was
              // generated by the "Initialize Cmd".
              //
              global proc finishSpherePaint( int $slot )
              {
              在笔划结束时调用。使用 $slot 清除该曲面在 $sphereNamePrefix 中的相应条目。如果数组中已有 $slot,也可以用 $slot 更新 $spherePaintFreeSlot。 
 
              global string $sphereNamePrefix[];
              global int $spherePaintFreeSlot;
              // clear out the slot that was used for this surface
              //
              $sphereNamePrefix[$slot] = "";
              if ( $slot < $spherePaintFreeSlot ) {
              $spherePaintFreeSlot = $slot;
              }
              }
              // This is the "Set Value Cmd". It is called everytime a value
              // on the surface is changed. A surface ID, a grid index
              // on the surface and the value associated with that grid index
              // is passed. There can be additional arguments depending on the
              // options generated by the return value of the "Initialize Cmd".
              // In this case the (x,y,z) surface position for this grid point
              // is also passed.
              // 
              global proc setSpherePaintValue(
              int $slot,
              int $index,
              float $val,
              float $x,
              float $y,
              float $z
              )
              {
              global string $sphereNamePrefix[];
              确定 $slot 是否是有效的曲面 ID,方法是检查 $sphereNamePrefix 中的相应条目是否并非空字符串。 
 if ( $sphereNamePrefix[$slot] != "" ) {
              已绘制的所有球体都具有唯一的名称,该名称是曲面的 $sphereNamePrefix 和栅格索引的组合。这正是该脚本确定在此位置是否已进行绘制的方式。该方法的一个缺点是它对 initSpherePaint 中指定的栅格大小较为敏感。例如,索引 44 将对应于 10x10 栅格上的栅格位置 (4,4)。但是,如果栅格大小已更改为 20x20,索引 44 现在将对应于栅格位置 (2,4)。 
 // determine the name of the sphere associated with this
              // grid location 
              //
              string $objname = $sphereNamePrefix[$slot] + $index;
              if ( ‘objExists $objname‘ ) {
              在本例中,球体已经存在。因此,传递的值 $val 将用作球体的总体比例因子。作为一种特殊情况,如果值小于或等于 0,应移除对应的球体。 
 // if the sphere already exists, use the value to
              // adjust the size of the sphere. If the value is
              // 0, the sphere is deleted
              //
              if ( $val > 0 ) {
              scale $val $val $val $objname;
              } else {
              delete $objname;
              }
              } else if ( $val > 0 ) {
              在本例中,对应于该栅格位置没有已绘制的球体。使用球体 MEL 命令创建一个球体,并使用 -name 选项为新创建的球体给出所需名称。球体创建之后,均匀地更改球体的比例因子,直至达到传入的值 ($val)。此时球体也将定位,通过将球体从原点(默认情况下在此处创建球体)移动到传入该程序的世界空间位置 ($x,$y,$z),可以使球体出现在正确的位置。 
 
              // the sphere doesn’t exist
              //
              string $sname[];
              // create a sphere with the proper name, scale it by
              // the passed value and parent the sphere to the same
              // parent as the surface we are painting on
              //
              $sname=‘sphere -ch off -name $objname‘;
              if ( $sname[0] != $objname ) {
              print ("SPHERE NAME FAILED: wanted "
              + $objname + " got " + $sname[0] + "\n");
              }
              scale $val $val $val;
              move $x $y $z;
              }
              }
              }
              // This is the "Get Value Cmd". It is called everytime a value
              // on the surface is needed by the scriptable paint tool. A
              // surface ID and a grid index is passed in. This procedure should
              // return the value for this grid location on the specified surface.
              // 
              global proc float getSpherePaintValue( int $slot, int $index )
              {
              global string $sphereNamePrefix[];
              if ( $sphereNamePrefix[$slot] != "" ) {
              // if this slot is valid, generate the name for the
              // sphere at this grid index
              //
              string $objname = $sphereNamePrefix[$slot] + $index;
              任何时候 Artisan 需要一个对应于特定栅格位置的值时,便会调用该程序。在该脚本中,值是球体的比例因子。 
 
              if ( ‘objExists $objname‘ ) {
              如果在 $index 引用的位置上绘制了球体,将返回球体的 X 轴比例因子。X 轴比例因子也没有什么神奇奥妙之处。可能很容易拥有 Y 轴或 Z 轴比例因子,或者是所有与此相关的比例因子的平均值。这完全取决于脚本。 
 
              // if the sphere exists, return the X scale factor
              // as the value for this grid location
              //
              return ‘getAttr ($objname + ".sx")‘;
              } else {
              如果在该位置没有球体,那么仅返回 0.0 作为该位置的值。 
 // the sphere doesn’t exist, therefore return 0 as
              // the value for this grid location
              //
              return 0.0;
              }
              } else {
              return 0.0;
              }
              }
              以下是几个试验,可以尝试使用该脚本,以便要了解其工作方式。 
更改“栅格大小”(Grid Size)
更改第 89 行自:
 + " -grid 20 20"
              为: 
 + " -grid 40 30"
              
              绘制圆锥体而不是球体 
更改第 154 行自:
 $sname=‘sphere -ch off -name $objname‘;
              为: 
 $sname=‘cone -ch off -name $objname‘;
              抖动栅格 
添加行:
 + " -jitter true"
              于第 90 行之前。 
请将您关于此页内容的评论发送给我们