// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // // Description: // This is an simple example script for the Artisan Script Paint // tool. It will paint spheres onto the selected NURBS 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 Script Paint Tool (Modify->Script Paint Tool) // and bring up the Tool Settings window // 3) Go to the Setup tab and enter "sphereArrayPaint" into the // "Tool Setup Cmd" field and hit enter // 4) Paint Spheres // // Tips: // Once you have the Sphere Paint Tool setup you may want to drag // it from the minibar to the shelf so that it is always accessible // // These are global variables used to keep track of multiple // surfaces and the name prefixes used for the spheres on each // surface // global string $gSphereNamePrefix[]; global int $gSpherePaintFreeSlot = 0; global int $gSpherePaintSlots = 0; // This procedure should be set as the "Tool Setup Cmd" in the // Setup tab of the Maya Artisan Script Paint tool's tool settings // window. The tool context is supplied as an argument. // global proc sphereArrayPaint( string $context ) { // initialize all the other commands in this scriptable // paint tool context. // artUserPaintCtx -e -ic "initSphereArrayPaint" -fc "finishSphereArrayPaint" -svc "" -sac "setSphereArrayPaintValue" -gvc "getSphereArrayPaintValue" -gsc "" -cc "" -tcc "" -gac "" $context; } // This is the "Initialize Cmd". This procedure is called once // for every selected surface when an intial 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 initSphereArrayPaint( string $name ) { global string $gSphereNamePrefix[]; global int $gSpherePaintFreeSlot; global int $gSpherePaintSlots; int $slot; // find a free slot for this surface in the global arrays // for ( $slot = $gSpherePaintFreeSlot; $slot < $gSpherePaintSlots; $slot++ ) { if ( $gSphereNamePrefix[$slot] == "" ) { break; } } if ( $slot == $gSpherePaintSlots ) { $gSpherePaintSlots++; $gSpherePaintFreeSlot = $gSpherePaintSlots; } if ( `nodeType $name` == "nurbsSurface" || `nodeType $name` == "mesh" || `nodeType $name` == "subdiv") { // 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`; $gSphereNamePrefix[$slot] = $parent[0] + "Sphere"; } // 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 finishSphereArrayPaint( int $slot ) { global string $gSphereNamePrefix[]; global int $gSpherePaintFreeSlot; // clear out the slot that was used for this surface // $gSphereNamePrefix[$slot] = ""; if ( $slot < $gSpherePaintFreeSlot ) { $gSpherePaintFreeSlot = $slot; } } proc spherePaintDebug( string $msg ) { print $msg ; } // 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 setSphereArrayPaintValue( int $slot, int $count, int $indices[], float $vals[], float $xyz[] ) { global string $gSphereNamePrefix[]; spherePaintDebug ( "setSphereArrayPaintValue (" + $count + ")\n") ; if ( $gSphereNamePrefix[$slot] != "" ) { int $i; for ( $i=0; $i<$count; $i++ ) { int $index = $indices[ $i ]; float $val = $vals[ $i ]; // determine the name of the sphere associated with this // grid location // string $objname = $gSphereNamePrefix[$slot] + $index; if ( `objExists $objname` ) { // 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; spherePaintDebug ( "Sphere scaling (" + $index + ")\n") ; } else { delete $objname; spherePaintDebug ( "Sphere deleting (" + $index + ")\n") ; } } else if ( $val > 0 ) { // 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 -r 1 -ch off -name $objname`; if ( $sname[0] != $objname ) { string $sphereNameError = (uiRes("m_sphereArrayPaint.kSphereNameFailed")); catch (error (`format -s $objname -s $sname[0] $sphereNameError`) ); } scale $val $val $val; float $x = $xyz[ 3*$i + 0 ]; float $y = $xyz[ 3*$i + 1 ]; float $z = $xyz[ 3*$i + 2 ]; move $x $y $z; spherePaintDebug ( "Sphere position (" + $index + ") : " + $x + " " + $y + " " + $z + "\n") ; } } } } // 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 getSphereArrayPaintValue( int $slot, int $index ) { global string $gSphereNamePrefix[]; if ( $gSphereNamePrefix[$slot] != "" ) { // if this slot is valid, generate the name for the // sphere at this grid index // string $objname = $gSphereNamePrefix[$slot] + $index; if ( `objExists $objname` ) { // if the sphere exists, return the X scale factor // as the value for this grid location // return `getAttr ($objname + ".sx")`; } else { // the sphere doesn't exist, therefore return 0 as // the value for this grid location // return 0.0; } } else { return 0.0; } }