// =========================================================================== // 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. // =========================================================================== // // Procedure Name: // AEsculptTemplate // // Description Name; // Creates the attribute editor controls for the sculpt node // // Input Value: // nodeName // // Output Value: // None // //=========== BEGIN Textured Sculpt Deformer Code ====================== // // The following code presents the UI for the textured sculpt deformer // feature, which allows users to assign a texture map that will // modulate the strength of the deformation over the surface of the // deformer object. // // This functionality is a little tough to implement, since the painted // values are on the surface of the sculpt sphere, not the surface being // deformed. Since the sculpt sphere is an implicity sphere object, it // is not paintable. Therefore, we have to do a little work behind the // scenes to create a NURBS sphere in the exact position as the sculpt // sphere, and let the user paint that. The sequence of events is // something like this: // // - user hits the Paint Sculpt Map button // - we create a NURBS sphere (the "visualizer") under the sculpt sphere // transform, so that it has exactly the same shape as the sculpt sphere, // even when the sculpt sphere is transformed // - we assign a new shader to the NURBS sphere, and use the // 3d paint tool to paint the color channel on that object // - we take the texture that is being painted on the color // channel of the NURBS sphere, and hook it up to the sculpt // texture on the sculpt deformer // // So, the end result is that it looks to the user like they're painting // on the sculpt sphere, but in fact they're painting on an intermediate // visualizer object. The visualizer object is deleted when the user // exits the paint tool. // // Since the sculpt sphere typically lies inside the object being deformed, // we need a way for the user to see what they're painting. The // "Visualize Texture" mode will just set the display overrides for // the deforming object, allowing the user to see through to the sculpt // sphere. // // The "Visualize Texture" option also works outside the context of painting // the sculpt map, in which case we must create the visualizer when the // option is enabled. When it is disabled, we delete the visualizer. So // the behaviour of Visualize Texture is: // // Enable Visualize Texture: // // - if we are in paint mode, it just sets the deforming object's draw // overrides to Wireframe. If the object is in a layer, we cannot // control the object's overrides, so we issue a warning and hide the // object. Since the visualizer has already been created for // painting, we just see right through to it. // // - if we are not in paint mode, we first create the visualizer object, // then do the above step // // Disable Visualize Texture: // // - if we are in paint mode, we just disable the draw override for the // deforming object (or unhide it if it is in a layer) The visualizer // is not deleted, so that users can continue to paint. It is sometimes // useful to watch the resulting deformation as you are painting. // // - if we are not in paint mode, we disable the draw override (or unhide // the object), and delete the visualizer. //------------ // // Here is a summary of the procedures related to textured sculpting: // // isTexturedSculptEnabled(): // - there is an environment variable MAYA_TEXTURED_SCULPT that can be // used to completely disable the UI for textured sculpting. By // default, it is true, so the UI is visible. // // paintSculptMap($node): // - creates the sculpt visualizer, enables the Visualize Texture // option, and puts the user into the 3d paint to to paint the // sculpt map. A script job is initialized that will delete // the visualizer and turn off the Visualize Texture mode when // the user exits the tool // // getSculptVisualizerShape() // getSculptVisualizerShader() // getObjectBeingPainted() // isSculptBeingPainted() // sculptToolChangedCallback(): // - routines for figuring out when the user has left the // sculpt paint tool, and removing all the sculpt visualization // stuff when they do // // updateSculptTexture() // - makes sure that the sculpt paint texture is actually hooked up // to the shader on the visualizer sphere // // getSculptVisualizer() // deleteSculptVisualizerByName() // deleteSculptVisualizer(): // - tools for creating and deleting the visualizer sphere for // a sculpt deformer // // recordSculptScriptJobs() // killSculptScriptJobs() // initSculptScriptJobs(): // - routines for managing some script jobs that ensure that // the sculpt visualizer stays in sync with the texture connected // to the sculpt deformer. // // sculptTextureSetVisualize() // sculptTextureGetVisualize() // visMode(): // - implement the Visualize Texture mode, and the different // behaviours that it needs to exhibit based on whether or not // the user is painting the map // // sculptDeformerAdvancedControls() // addAdvancedSculptAttrs(): // - for adding the dynamic attributes that control the sculpt deformer // to the node // // AEadvancedSculptAddAttrNew() // AEadvancedSculptAddAttrReplace(): // - manage the "Add Advanced Sculpt Attributes" button in the AE // // AEadvancedSculptVisualizeNew() // AEadvancedSculptVisualizeReplace(): // - manage the "Visualize Texture" checkbox in the AE // // AEadvancedSculptPaintNew() // AEadvancedSculptPaintReplace(): // - manage the "Paint Sculpt Map" button in the AE // //----------------------------------------------------------------------------- global int $gTexturedSculptDebug = 0; global proc sculptDebug( string $str ) { global int $gTexturedSculptDebug; if( $gTexturedSculptDebug ) { print ("Textured sculpt: " + $str ); } } global proc int isTexturedSculptEnabled() // // Description: // // The MAYA_TEXTURED_SCULPT environment variable // is used to turn on/off the texture sculpt deformer // controls. They are off by default. // { int $default = 1; int $returnVal; string $envVar = `getenv "MAYA_TEXTURED_SCULPT"`; if( size($envVar) ) { $returnVal = $envVar; } else { $returnVal = $default; } return $returnVal; } global proc paintSculptMap( string $node ) // // Description: // // Creates a NURBS sphere exactly aligned with the // sculpt deformer, and sets up the 3d paint tool // to paint on it. The texture being painted is connected // to the sculpt deformer. // { source art3dPaintCallback.mel; sculptDebug( "paintSculptMap " + $node ); if( `currentCtx` == "art3dPaintContext" ) { setToolTo selectSuperContext; } if( sculptDeformerAdvancedControls( $node, "query" ) ) { int $advancedEnabled = `getAttr ($node+".enableAdvanced")`; if( !$advancedEnabled ) { error( (uiRes("m_AEsculptTemplate.kTurnOnAdvanced"))); } else { string $oldSel[] = `ls -sl`; // create the visualizer sphere, if necessary // string $paintObj = getSculptVisualizer( $node, 1 ); // enable Visualize Texture mode // visMode( $node, 1 ); checkBoxGrp -e -v1 1 sculptVisualizeCheckBox; select $paintObj; string $conn[] = `listConnections -p on ($node+".texture")`; // find the surface shader on the sculpt object, and disconnect // any texture that may be already attached to it. If a file // texture is attached, leave it alone, since we can paint // on it. // string $SGs[] = `listSets -ets -o $paintObj -type 1`; string $shaders[] = `listConnections ($SGs[0]+".surfaceShader")`; string $textures[] = `listConnections ($shaders[0]+".color")`; int $alreadyTextured = 0; if( size($conn) ) { if( `nodeType ($conn[0])` == "file" ) { $alreadyTextured = 1; } else { disconnectAttr ($conn[0]) ($node+".texture"); } } // make sure that the visualizer has the sculpt texture attached // to it. // updateSculptTexture( $node ); // enter the 3d paint tool and assign file textures to // the color channel of the shader. // Art3dPaintTool; art3dPaintAssignFileTextures( "color" ); art3dPaintAssignFileTextureNow; // find the texture being painted, and hook it up to the // sculpt deformer if necessary (ie if we are starting to // paint the deformation map for the first time). // $textures = `listConnections ($shaders[0]+".color")`; if( !$alreadyTextured && (size($textures) > 0) ) { connectAttr ($textures[0]+".outColor") ($node+".texture"); } // make sure we restore the old selection // select $oldSel; // set up a script job that will destroy the visualizer object // when the user leaves the tool. // string $cmd = ("sculptToolChangedCallback " + $node); scriptJob -ro on -e ToolChanged $cmd; } } } global proc string getSculptVisualizerShape( string $node ) // // Finds the NURBS sphere shape that the deformation map is being painted // on. // { sculptDebug( "getSculptVisualizerShape " + $node + " \n" ); string $sculptVis = getSculptVisualizer( $node, 0 ); if( $sculptVis != "" ) { string $c[] = `listRelatives -children -type nurbsSurface $sculptVis`; if( size($c) == 1 ) { $sculptVis = $c[0]; } else { $sculptVis = ""; } } return $sculptVis; } global proc string getSculptVisualizerShader( string $node ) // // Finds the surface shader on the sculpt visualizer, if there is one // { sculptDebug( "getSculptVisualizerShader " + $node + " \n" ); string $shape = getSculptVisualizerShape( $node ); if( $shape != "" ) { string $SGs[] = `listSets -ets -o $shape -type 1`; if( size($SGs) > 0 ) { string $shaders[] = `listConnections ($SGs[0]+".surfaceShader")`; if( size($shaders) > 0 ) { return $shaders[0]; } } } return ""; } global proc string getObjectBeingPainted( string $paintContext ) // // Figures out which object is being painted in the given paint context. // Only returns the first object being painted. Only one sculpt map // can be painted at a time, so this is all we care about. // { sculptDebug( "getObjectBeingPainted " + $paintContext + " \n" ); string $shapesStr = `art3dPaintCtx -query -shapenames $paintContext`; string $shapes[]; tokenize( $shapesStr, " ", $shapes ); if( size($shapes) > 0 ) { return $shapes[0]; } else { return ""; } } global proc int isSculptBeingPainted( string $node ) // // Figures out if the given sculpt deformer is currently in the process of // having its sculpt map painted. This information is necessary for // determining how the Visualize Texture // { sculptDebug( "isSculptBeingPainted " + $node + "\n" ); string $currentContext = `currentCtx`; if( `art3dPaintCtx -query -exists $currentContext` ) { string $sculptVisShape = getSculptVisualizerShape( $node ); string $shapeBeingPainted = getObjectBeingPainted( $currentContext ); if( ($sculptVisShape != "") && ($sculptVisShape == $shapeBeingPainted) ) { return 1; } } return 0; } global proc sculptToolChangedCallback( string $node ) { sculptDebug( "sculptToolChangedCallback " + $node + "\n" ); // make sure the node exists - sometimes the tool changes // because the user did a File->New // if( !`objExists $node` ) { return; } if( !isSculptBeingPainted( $node ) ) { sculptTextureSetVisualize( $node, 0 ); } } global proc updateSculptTexture( string $sculpt ) // // Description: // // Ensures that the texture that is driving the given sculpt // deformer is attached to the color channel of the given // shader. This shader is assigned to the NURBS sphere that // is aligned with the sculpt deformer, thereby allowing users // to visualize the sculpt texture. // { sculptDebug( "updateSculptTexture " + $sculpt + "\n" ); if( !`objExists $sculpt` ) { return; } string $s; string $sl[] = `ls -sl`; string $shader = getSculptVisualizerShader( $sculpt ); if( $shader == "" ) { // there is no sculpt visualizer, so nothing to update // return; } if( `objExists $sculpt` && `objExists $shader` ) { string $tex[] = `listConnections ($sculpt + ".texture")`; if( size($tex) ) { // first, disconnect whatever may be connected to the // shader's color channel // string $shaderConn[] = `listConnections ($shader+".color")`; int $shouldConnect = 0; if( size($shaderConn) ) { if( $shaderConn[0] != $tex[0] ) { disconnectAttr ($shaderConn[0]+".outColor") ($shader+".color"); $shouldConnect = true; } } else { $shouldConnect = true; } // connect the given texture // if( $shouldConnect ) { connectAttr -f ($tex[0] + ".outColor") ($shader + ".color"); } } else { // if there is no sculpt texture, make sure that there is no // texture feeding the visualizer either. // string $shaderConn[] = `listConnections -p on ($shader+".color")`; if( size($shaderConn) ) { disconnectAttr $shaderConn[0] ($shader+".color"); } } } } global proc safeDelete( string $node ) // // Delete object if it exists. // { if( `objExists $node` ) { delete $node; } } global proc deleteSculptVisualizerByName( string $visualizer ) // // Deletes the sculpt visualizer, which consists of: // // - a transform that is a child of the sculpt sphere // - a NURBS visualizer sphere shape under that // - a shading group that should contain only the // visualizer sphere // - a shader that should be attached only to that // shading group // // This routine works based on the name of the visualizer object, // not the name of the sculpt deformer. This is so that we can // call this routine even when the sculpt deformer has been // deleted (provided we remembered the name of the visualizer). // { sculptDebug( "deleteSculptVisualizerByName " + $visualizer + "\n" ); // find the visualizer (returns the transform) // if( ($visualizer != "") && (`objExists $visualizer`) ) { string $shape = ""; string $shadingGroup = ""; string $shader = ""; // find the shape // string $shapes[] = `listRelatives -c $visualizer`; if( size($shapes) > 0 ) { // find its shading group // $shape = $shapes[0]; string $sets[] = `listSets -o $shape`; if( size($sets) > 0 ) { // find the surface shader // $shadingGroup = $sets[0]; string $shaders[] = `listConnections ($shadingGroup+".surfaceShader")`; if( size($shaders) > 0 ) { $shader = $shaders[0]; } } } // delete the shape and transform // if( $shape != "" ) { delete $shape; } delete $visualizer; // delete the shading group if it is empty now that the // visualizer sphere is gone // if( $shadingGroup != "" ) { string $shadingGroupMembers[] = `sets -q $shadingGroup`; if( size($shadingGroupMembers) == 0 ) { delete $shadingGroup; } } // delete the shader, if it is not connected to any shading groups // now that the visualizer group is gone // if( $shader != "" ) { string $otherShadingGroups[] = `listConnections ($shader+".outColor")`; if( size($otherShadingGroups) == 0 ) { delete $shader; } } } // kill the script jobs for this visualizer // killSculptScriptJobs( $visualizer ); } global proc deleteSculptVisualizer( string $sculpt ) // // Same as above, but works based on the sculpt deformer name // { sculptDebug( "deleteSculptVisualizer " + $sculpt + "\n" ); // find the visualizer (returns the transform) // string $visualizer = getSculptVisualizer( $sculpt, 0 ); deleteSculptVisualizerByName( $visualizer ); } // // The sculpt visualizers need two script jobs running: // // - A job that watches the sculpt deformer's .texture attribute. // When a new texture is connected there, we must also connect // it to the visualizer's shader to ensure that it is properly // shown. // // - A job that will delete the visualizer in case the sculpt // deformer is deleted while in "Visualize Texture" mode. // Ordinarily, the visualizer is deleted when the user leaves // Visualize Texture mode, but it would be possible for them // to blow away the deformer before exiting this mode. // // Furthermore, we want these script jobs to disappear once the // visualizer is gone. Knowing that there can be more than one // visualizer active in the scene at a time, we keep a global // array of visualizers, with their associated script job // numbers. When the deleteSculptVisualizer() function runs, // the last thing it does is search find the script jobs for the // visualizer that is being deleted and kill them. // // global string $gSculptVisualizerJobs[]; global proc recordSculptScriptJobs( string $visualizer, int $job1, int $job2 ) // // Stores the script jobs for the given visualizer in the global // array. // { sculptDebug( "recordSculptScriptJobs " + $visualizer + " " + $job1 + " " + $job2 + "\n" ); global string $gSculptVisualizerJobs[]; int $numSculpts = size($gSculptVisualizerJobs)/3; int $index = $numSculpts; int $s; for( $s = 0; $s < $numSculpts; $s++ ) { if( $gSculptVisualizerJobs[3*$s] == $visualizer ) { $index = $s; break; } } $gSculptVisualizerJobs[3*$index] = $visualizer; $gSculptVisualizerJobs[3*$index+1] = $job1; $gSculptVisualizerJobs[3*$index+2] = $job2; } global proc killSculptScriptJobs( string $visualizer ) // // Find the script jobs associated with the given visualizer and kill // them. Keep in mind that we might actually have been called from one // of those jobs, so do an evalDeferred() to make sure we can delete them. // We also remove the entries for this visualizer's jobs from the // global array. // { sculptDebug( "killSculptScriptJobs " + $visualizer + "\n" ); global string $gSculptVisualizerJobs[]; // new array, with this visualizer subtracted from it string $newArray[] = {}; int $numSculpts = size($gSculptVisualizerJobs)/3; int $s; for( $s = 0; $s < $numSculpts; $s++ ) { if( $gSculptVisualizerJobs[3*$s] == $visualizer ) { // make sure the jobs get killed // int $job1 = $gSculptVisualizerJobs[3*$s+1]; int $job2 = $gSculptVisualizerJobs[3*$s+2]; evalDeferred( "scriptJob -kill " + $job1 ); evalDeferred( "scriptJob -kill " + $job2 ); } else { // that visualizer is not being deleted, so just // tack it on to the new array. // $newArray[3*$s] = $gSculptVisualizerJobs[3*$s]; $newArray[3*$s+1] = $gSculptVisualizerJobs[3*$s+1]; $newArray[3*$s+2] = $gSculptVisualizerJobs[3*$s+2]; } } // set the global array to the one minus the deleted visualizer // $gSculptVisualizerJobs = $newArray; } global proc initSculptScriptJobs( string $sculpt, string $visualizer ) { sculptDebug( "initSculptScriptJobs " + $sculpt + " " + $visualizer + "\n" ); // when the texture changes, we need to update the // texture being displayed. // int $job1 = `scriptJob -killWithScene -connectionChange ($sculpt+".texture") ("updateSculptTexture " + $sculpt)`; // if the user kills the sculpt deformer before exiting Visualize // Texture mode, we need to make sure that the visualizer gets // deleted. // int $job2 = `scriptJob -killWithScene -attributeDeleted ($sculpt+".texture") ("deleteSculptVisualizerByName " + $visualizer)`; // store the jobs in the global array // recordSculptScriptJobs( $visualizer, $job1, $job2 ); } global proc string getSculptVisualizer( string $sculpt, int $create ) // // Description: // // Adds a NURBS sphere to the scene that is aligned with the // given sculpt deformer. Assigns the sculpt texture to that // sphere to allow users to visualize the texture, and gives them // an object to paint on. We connect this visualizer sphere to // the "visSphere" attribute on the sculpt node so we can find it. // { sculptDebug( "getSculptVisualizer " + $sculpt + " " + $create + "\n" ); if( `attributeQuery -ex -n $sculpt "visSphere"` ) { string $texture[] = `listConnections ($sculpt + ".texture")`; string $vs[] = `listConnections ($sculpt + ".visSphere")`; if( size($vs) == 0 ) { if( $create ) { // find the sculpt sphere // string $sl[] = `ls -sl`; string $sculptObjects[] = `listConnections ($sculpt + ".sculptObjectMatrix")`; string $sculptSphere = $sculptObjects[0]; // create the visualizer sphere, and make sure it is going // to display in shaded mode // string $res[] = `sphere -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 4 -ch 0`; string $visSphere = $res[0]; setAttr ($visSphere + ".overrideEnabled") 1; setAttr ($visSphere + ".overrideDisplayType") 2; // put it under the sculpt sphere, so that it takes on the // same shape // string $parentResult[] = `parent -r $visSphere $sculptSphere`; string $newSphere = $parentResult[0]; // hook it up to the sculpt deformer's visSphere attr so we // can find it easily // connectAttr ($newSphere + ".message") ($sculpt + ".visSphere"); // create a new shader+shading group to shade the visualizer // sphere. Set the incandescence to 1 and texture the diffuse // channel so the result is that the object's color is the // same as the texture's color. // string $newSE = `sets -r true -em`; sets -fe $newSE $newSphere; string $shader = `shadingNode -asShader lambert`; connectAttr -f ($shader + ".outColor") ($newSE + ".surfaceShader"); setAttr ($shader + ".incandescence") 1.0 1.0 1.0; // make sure the shader gets textured by the sculpt deformer's // texture updateSculptTexture( $sculpt ); initSculptScriptJobs( $sculpt, $newSphere ); // set the sphere to display nice and smoothly // displaySmoothness -divisionsU 3 -divisionsV 3 -pointsWire 16 -pointsShaded 4 $newSphere $visSphere; select $sl; return $parentResult[0]; } else { return ""; } } else { // just return the existing visualizer // return $vs[0]; } } else { return ""; } } global proc visMode( string $sculpt, int $enable ) // // Description: // // Enables/disables wireframe mode on the objects // being deformed by the given sculpt. This allows // us to see through the objects to visualize the // texture on the sculpt deformer beneath. // { sculptDebug( "visMode " + $sculpt + " " + $enable + "\n" ); string $objs[] = `sculpt -q -g $sculpt`; string $o; for( $o in $objs ) { // if the object is in a layer, we cannot override its draw, so // let's just hide it. Warn the user to let them know what's // going on. // if( size(`listConnections ($o+".drawOverride")`) > 0 ) { if( $enable ) { string $formatStr = (uiRes("m_AEsculptTemplate.kCannotSetToWireframe")); string $warnStr = `format -stringArg $o $formatStr`; hide $o; } else { showHidden $o; } } else { if( $enable ) { // draw override to wireframe // setAttr ($o + ".overrideEnabled") 1; setAttr ($o + ".overrideShading") 0; } else { // remove draw override // setAttr ($o + ".overrideEnabled") 0; setAttr ($o + ".overrideShading") 1; } } } } global proc sculptTextureSetVisualize( string $node, int $enable ) // // Description: // // Enables/disables "visualize texture" mode, in which the // deforming objects become wireframe, and the sculpt sphere // displays in textured mode. This allows users to easily see // the texture on the deformer, and is convenient for painting the // deformation map. // { sculptDebug( "sculptTextureSetVisualize " + $node + " " + $enable + "\n" ); // if we're not in paint mode, the Visualize Texture checkbox will // cause a visualizer to be created or deleted // if( !isSculptBeingPainted( $node ) ) { if( $enable ) { getSculptVisualizer( $node, 1 ); } else { deleteSculptVisualizer( $node ); } } if( $enable ) { DisplayShadedAndTextured; } checkBoxGrp -e -v1 $enable sculptVisualizeCheckBox; visMode $node $enable; } global proc int sculptTextureGetVisualize( string $node ) // // Description: // // Decides whether or not the specified sculpt deformer // is in "visualize texture" mode. Used to sync the UI // for that deformer. // { sculptDebug( "sculptTextureGetVisualize " + $node + "\n" ); string $sl[] = `ls -sl`; string $vis = getSculptVisualizer( $node, 0 ); if( $vis != "" ) { string $res[] = `ls -v $vis`; if( size($res) > 0 ) { return 1; } else { return 0; } } else { return 0; } } global proc int sculptDeformerAdvancedControls( string $node, string $action ) // // Description: // // Adds or queries existence of dynamic attributes on sculpt deformer // that control the textured sculpt behaviour. // { if( $action == "query" ) { return `attributeQuery -ex -n $node "enableAdvanced"`; } else if( $action == "add" ) { if( !`attributeQuery -ex -n $node "enableAdvanced"` ) { addAttr -at bool -ln "enableAdvanced" -dv false $node; } if( !`attributeQuery -ex -n $node "texture"` ) { addAttr -at float3 -ln "texture" -uac $node; } if( !`attributeQuery -ex -n $node "textureR"` ) { addAttr -at "float" -ln "textureR" -p texture $node; } if( !`attributeQuery -ex -n $node "textureG"` ) { addAttr -at "float" -ln "textureG" -p texture $node; } if( !`attributeQuery -ex -n $node "textureB"` ) { addAttr -at "float" -ln "textureB" -p texture $node; } if( !`attributeQuery -ex -n $node "textureMultiplier"` ) { addAttr -at "float" -ln "textureMultiplier" -dv 1.0 $node; } if( !`attributeQuery -ex -n $node "nonUniform"` ) { addAttr -at bool -ln "nonUniform" -dv false $node; } if( !`attributeQuery -ex -n $node "visSphere"` ) { addAttr -at message -ln "visSphere" $node; } return 1; } } global proc addAdvancedSculptAttrs( string $nodeName ) { sculptDeformerAdvancedControls( $nodeName, "add" ); checkBoxGrp -e -m 1 sculptVisualizeCheckBox; button -e -m 1 paintSculptButton; setAttr ($nodeName+".enableAdvanced") 1; } // // Methods that implement the "Add Advanced Sculpt Attrs" button // in the sculpt deformer AE. // global proc AEadvancedSculptAddAttrNew ( string $attr ) { global int $gTextColumnWidthIndex; string $nodeName[]; tokenize($attr, ".", $nodeName); setUITemplate -pst attributeEditorPresetsTemplate; rowLayout -nc 2 -columnWidth 1 $gTextColumnWidthIndex -columnWidth 2 200 -columnAttach 2 both 0 -columnAttach 1 right 5; text -label (uiRes("m_AEsculptTemplate.kAddAttributesFor")) -vis 0; button -label (uiRes("m_AEsculptTemplate.kAddAdvancedSculptAttributes")) -c ("addAdvancedSculptAttrs " + $nodeName[0] ) addAdvancedSculptAttrButton; setParent ..; setUITemplate -ppt; } global proc AEadvancedSculptAddAttrReplace ( string $attr ) { string $nodeName[]; tokenize($attr, ".", $nodeName); button -e -c ("addAdvancedSculptAttrs " + $nodeName[0] ) addAdvancedSculptAttrButton; advancedSculptDimUI( $nodeName[0] ); } // // Methods that implement the "Visualize Texture" button in the // sculpt deformer AE. // global proc AEadvancedSculptVisualizeNew( string $attr ) { string $nodeName[]; tokenize($attr, ".", $nodeName); string $onCommand = ("sculptTextureSetVisualize " + $nodeName[0] + " 1"); string $offCommand = ("sculptTextureSetVisualize " + $nodeName[0] + " 0"); checkBoxGrp -label (uiRes("m_AEsculptTemplate.kVisualizeTexture")) -onc $onCommand -ofc $offCommand sculptVisualizeCheckBox; int $curState = sculptTextureGetVisualize( $nodeName[0] ); checkBoxGrp -e -v1 $curState sculptVisualizeCheckBox; if( sculptDeformerAdvancedControls($nodeName[0],"query") ) { checkBoxGrp -e -m 1 sculptVisualizeCheckBox; } else { checkBoxGrp -e -m 0 sculptVisualizeCheckBox; } } global proc AEadvancedSculptVisualizeReplace( string $attr ) { string $nodeName[]; tokenize($attr, ".", $nodeName); string $onCommand = ("sculptTextureSetVisualize " + $nodeName[0] + " 1"); string $offCommand = ("sculptTextureSetVisualize " + $nodeName[0] + " 0"); checkBoxGrp -e -onc $onCommand -ofc $offCommand sculptVisualizeCheckBox; int $curState = sculptTextureGetVisualize( $nodeName[0] ); checkBoxGrp -e -v1 $curState sculptVisualizeCheckBox; if( sculptDeformerAdvancedControls($nodeName[0],"query") ) { checkBoxGrp -e -m 1 sculptVisualizeCheckBox; } else { checkBoxGrp -e -m 0 sculptVisualizeCheckBox; } } // // Methods that implement the "Paint Texture" button in the // sculpt deformer AE. // global proc AEadvancedSculptPaintNew ( string $attr ) { global int $gTextColumnWidthIndex; string $nodeName[]; tokenize($attr, ".", $nodeName); setUITemplate -pst attributeEditorPresetsTemplate; rowLayout -nc 2 -columnWidth 1 $gTextColumnWidthIndex -columnWidth 2 200 -columnAttach 2 both 0 -columnAttach 1 right 5; text -label (uiRes("m_AEsculptTemplate.kAddAttributesFor2")) -vis 0; button -label (uiRes("m_AEsculptTemplate.kPaintSculptMap")) -c ("paintSculptMap " + $nodeName[0] ) paintSculptButton; setParent ..; setUITemplate -ppt; if( sculptDeformerAdvancedControls($nodeName[0],"query") ) { button -e -m 1 paintSculptButton; } else { button -e -m 0 paintSculptButton; } } global proc AEadvancedSculptPaintReplace ( string $attr ) { string $nodeName[]; tokenize($attr, ".", $nodeName); button -e -c ("paintSculptMap " + $nodeName[0] ) paintSculptButton; if( sculptDeformerAdvancedControls($nodeName[0],"query") ) { button -e -m 1 paintSculptButton; } else { button -e -m 0 paintSculptButton; } } // // Responsible for dimming the advanced sculpt attr UI when the // "enable advanced" button is unchecked. // global proc advancedSculptDimUI( string $nodeName ) { if( `attributeQuery -ex -n $nodeName "enableAdvanced"` ) { int $enable = `getAttr ($nodeName + ".enableAdvanced")`; if( $enable ) { editorTemplate -dimControl $nodeName "texture" false; editorTemplate -dimControl $nodeName "textureMultiplier" false; editorTemplate -dimControl $nodeName "nonUniform" false; button -e -en 1 paintSculptButton; checkBoxGrp -e -en 1 sculptVisualizeCheckBox; } else { editorTemplate -dimControl $nodeName "texture" true; editorTemplate -dimControl $nodeName "textureMultiplier" true; editorTemplate -dimControl $nodeName "nonUniform" true; button -e -en 0 paintSculptButton; checkBoxGrp -e -en 0 sculptVisualizeCheckBox; } } } // //=========== END Textured Sculpt Deformer Code ====================== global proc checkSculptMode ( string $node ) { string $nodeAttr = $node + ".mode"; int $value = `getAttr $nodeAttr`; if ( $value == 2 /* stretch mode */ ) { string $conns[]; $conns = `listConnections -d false ($node+".startPosition")`; if (0 == size($conns)) { // call the sculpt edit command so that a locator can // get added if necessary // string $cmd = "sculpt -e -mode stretch "+ $node; evalDeferred $cmd; } } } global proc checkInsideMode ( string $node ) { string $nodeAttr = $node + ".insideMode"; int $value = `getAttr $nodeAttr`; if ( $value == 1 /* even mode */ ) { string $conns[]; $conns = `listConnections -d false ($node+".startPosition")`; if (0 == size($conns)) { // call the sculpt edit command so that a locator can // get added if necessary // string $cmd = "sculpt -e -insideMode even "+ $node; evalDeferred $cmd; } } } global proc AEmaximumDisplacementNew( string $attrName ) { setUITemplate -pst attributeEditorTemplate; attrFieldSliderGrp -attribute $attrName -label (uiRes("m_AEsculptTemplate.kMaxDisplacement")) maxDisplacementSlider; setUITemplate -ppt; } global proc AEmaximumDisplacementReplace( string $attrName ) { attrFieldSliderGrp -e -attribute $attrName -label (uiRes( "m_AEsculptTemplate.kMaxDisplacement" )) maxDisplacementSlider; } global proc AEsculptTemplate( string $nodeName ) { editorTemplate -beginScrollLayout; editorTemplate -beginLayout (uiRes("m_AEsculptTemplate.kSculptHistory")) -collapse false; editorTemplate -addControl "mode" "checkSculptMode"; editorTemplate -addControl "insideMode" "checkInsideMode"; editorTemplate -callCustom "AEmaximumDisplacementNew" "AEmaximumDisplacementReplace" "maximumDisplacement"; editorTemplate -addControl "dropoffType"; editorTemplate -addControl "dropoffDistance"; //================== BEGIN Textured Sculpt Deformer Code ============== // if( isTexturedSculptEnabled() ) { editorTemplate -addSeparator; editorTemplate -callCustom "AEadvancedSculptAddAttrNew" "AEadvancedSculptAddAttrReplace" ""; editorTemplate -addDynamicControl enableAdvanced "advancedSculptDimUI"; editorTemplate -addDynamicControl texture; editorTemplate -addDynamicControl textureMultiplier; editorTemplate -addDynamicControl nonUniform; editorTemplate -callCustom "AEadvancedSculptVisualizeNew" "AEadvancedSculptVisualizeReplace" ""; editorTemplate -callCustom "AEadvancedSculptPaintNew" "AEadvancedSculptPaintReplace" ""; } // //================== END Textured Sculpt Deformer Code ================ editorTemplate -endLayout; // include/call base class/node attributes AEgeometryFilterCommon $nodeName; AEgeometryFilterInclude $nodeName; editorTemplate -addExtraControls; editorTemplate -endScrollLayout; editorTemplate -suppress "startPosition"; editorTemplate -suppress "extendedEnd"; }