// =========================================================================== // 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. // =========================================================================== // // // Creation Date: Jul 30, 1998 // // Description: // This script sets up the skinCluster dialog box // // Input Arguments: // None. // // Return Value: // None. // proc int gridResolutionEnumToInt( int $enumVal ) { // Sanity check // if ( $enumVal < 1 || $enumVal > 11 ) error( (uiRes("m_performSkinCluster.kGridResAssert")) ); return pow( 2, 11 - $enumVal ); } proc setOptionVars (int $forceFactorySettings) { // bindTo // if ( $forceFactorySettings || !`optionVar -exists bindTo` ) { optionVar -intValue bindTo 1; } // bindMethod // if ( $forceFactorySettings || !`optionVar -exists bindMethod` ) { optionVar -intValue bindMethod 1; } if ( $forceFactorySettings || !`optionVar -exists skinMethod` ) { // skinMethod: classic linear optionVar -intValue skinMethod 1; } // normalization method // 1 == none // 2 == interactive // 3 == post if ($forceFactorySettings || !`optionVar -exists normalizeWeights`) { // interactive optionVar -intValue normalizeWeights 2; } // weight distribution // 1 == Distance // 2 == Neighbours if ($forceFactorySettings || !`optionVar -exists weightDistribution`) { optionVar -intValue weightDistribution 1; } // allowMultipleBindPoses // if ( $forceFactorySettings || !`optionVar -exists multipleBindPosesOpt` ) { optionVar -intValue multipleBindPosesOpt 1; } // maxInfluences // if ($forceFactorySettings || !`optionVar -exists maxInfl`) { optionVar -intValue maxInfl 5; } if ($forceFactorySettings || !`optionVar -exists obeyMaxInfl`) { optionVar -intValue obeyMaxInfl 1; } // dropoff power // if ($forceFactorySettings || !`optionVar -exists dropoff`) { optionVar -floatValue dropoff 4.0; } // remove unused influences after bind // if ($forceFactorySettings || !`optionVar -exists removeUnusedInfluences`) { optionVar -intValue removeUnusedInfluences 1; } // colorize skeleton after bind // if ($forceFactorySettings || !`optionVar -exists colorizeSkeleton`) { optionVar -intValue colorizeSkeleton 1; } // Include hidden objects during bind // if ($forceFactorySettings || !`optionVar -exists bindIncludeHiddenSelections`) { optionVar -intValue bindIncludeHiddenSelections 0; } // heatmapFalloff // if ($forceFactorySettings || !`optionVar -exists heatmapFalloff`) { optionVar -floatValue heatmapFalloff 0.68; } // Geodesic voxel bind options // if ($forceFactorySettings || !`optionVar -exists geodesicFalloff`) { optionVar -floatValue geodesicFalloff 0.2; } if ($forceFactorySettings || !`optionVar -exists geodesicRes`) { optionVar -intValue geodesicRes 3; } if ($forceFactorySettings || !`optionVar -exists geodesicPostVoxelCheck`){ optionVar -intValue geodesicPostVoxelCheck 1; } } // // Procedure Name: // skinClusterSetup // // Description: // Update the state of the option box UI to reflect the option values. // // Input Arguments: // parent - Top level parent layout of the option box UI. // Required so that UI object names can be // successfully resolved. // // forceFactorySettings - Whether the option values should be set to // default values. // // Return Value: // None. // global proc skinClusterSetup (string $parent, int $forceFactorySettings) { // Retrieve the option settings // setOptionVars( $forceFactorySettings ); setParent $parent; // Query the optionVar's and set the values into the controls // // bindTo = to selected joints or to selected skeleton // optionMenuGrp -e -sl `optionVar -query bindTo` bindTo; // bindMethod = closest joint or closest distance or heat map // optionMenuGrp -e -sl `optionVar -query bindMethod` bindMethod; // skinning method - classic linear, dual quaternion, weight blended optionMenuGrp -e -sl `optionVar -query skinMethod` skinMethod; // normalization mode optionMenuGrp -e -sl `optionVar -query normalizeWeights` normalizeWeightsDropDown; optionMenuGrp -e -sl `optionVar -query weightDistribution` -enable (`optionMenuGrp -q -sl normalizeWeightsDropDown` == 2) weightDistributionDropDown; // allowMultipleBindPoses // checkBoxGrp -e -v1 `optionVar -q multipleBindPosesOpt` multipleBindPoses; // maxInfluences // if (`intSliderGrp -exists maxInfl`) { intSliderGrp -edit -value `optionVar -query maxInfl` maxInfl; } if (`checkBoxGrp -exists obeyMaxInfl`) { checkBoxGrp -edit -value1 `optionVar -query obeyMaxInfl` obeyMaxInfl; } // Should we remove unused influences after a bind? // if (`checkBoxGrp -exists removeUnusedInfluences`) { checkBoxGrp -edit -value1 `optionVar -query removeUnusedInfluences` removeUnusedInfluences; } // check the colorize skeleton box if the corresponding variable is true. // if (`checkBoxGrp -exists colorizeSkeleton`) { checkBoxGrp -edit -value1 `optionVar -query colorizeSkeleton` colorizeSkeleton; } // Include hidden objects during bind // if (`checkBoxGrp -exists bindIncludeHiddenSelections`) { checkBoxGrp -edit -value1 `optionVar -query bindIncludeHiddenSelections` bindIncludeHiddenSelections; } skinClusterUpdateDistanceSetup; skinClusterUpdateHeatMapSetup; skinClusterUpdateGeomBindSetup; } global proc skinClusterCreateDistanceOptions(string $parent) { frameLayout -label (uiRes("m_performSkinCluster.kDistanceOptions")) -collapsable false distanceOpts; frameLayout -e -labelVisible 0 -borderVisible 0 distanceOpts; floatSliderGrp -label (uiRes("m_performSkinCluster.kDropoffRate")) -minValue 0.1 -maxValue 10.0 -fieldMaxValue 100.0 -pre 1 -sliderStep 0.1 -enable true -cc "skinClusterUpdateDistanceOptions;" dropoff; setParent ..; } global proc skinClusterUpdateDistanceOptions() { if (`floatSliderGrp -exists dropoff`) { optionVar -floatValue dropoff `floatSliderGrp -query -value dropoff`; } } global proc skinClusterUpdateDistanceSetup() { int $bindMethod = `optionVar -query bindMethod`; frameLayout -e -visible ($bindMethod == 1 || $bindMethod == 2) distanceOpts; if (`floatSliderGrp -exists dropoff`) { floatSliderGrp -e -value `optionVar -query dropoff` dropoff; } } global proc skinClusterCreateHeatMapOptions(string $parent) { frameLayout -label (uiRes("m_performSkinCluster.kHeatmapOptions")) -collapsable false heatmapOpts; frameLayout -e -labelVisible 0 -borderVisible 0 heatmapOpts; floatSliderGrp -label (uiRes("m_performSkinCluster.kHeatmapFalloff")) -annotation (uiRes("m_performSkinCluster.kHeatmapFalloffAnnot")) -minValue 0.0 -maxValue 1.0 -fieldMinValue 0.0 -fieldMaxValue 1.0 -pre 2 -step 0.01 -enable true -cc "skinClusterUpdateHeatMapOptions;" heatmapFalloff; setParent ..; } global proc skinClusterUpdateHeatMapOptions() { // heatmap falloff // if (`floatSliderGrp -exists heatmapFalloff`) { optionVar -floatValue heatmapFalloff `floatSliderGrp -query -value heatmapFalloff`; } } global proc skinClusterUpdateHeatMapSetup() { int $bindMethod = `optionVar -query bindMethod`; frameLayout -e -visible ($bindMethod == 3) heatmapOpts; // heatmap falloff // if (`floatSliderGrp -exists heatmapFalloff`) { floatSliderGrp -e -value `optionVar -query heatmapFalloff` heatmapFalloff; } } global proc skinClusterCreateGeomBindOptions(string $parent) { frameLayout -label (uiRes("m_performSkinCluster.kGeomBindOptions")) -collapsable false geodesicOpts; frameLayout -e -labelVisible 0 -borderVisible 0 geodesicOpts; floatSliderGrp -label (uiRes("m_performSkinCluster.kGeomBindFalloff")) -annotation (uiRes("m_performSkinCluster.kGeomBindFalloffAnnot")) -minValue 0.0 -maxValue 1.0 -fieldMinValue 0.0 -fieldMaxValue 1.0 -pre 2 -step 0.01 -enable 1.0 -cc "skinClusterUpdateGeomBindOptions;" geodesicFalloff; optionMenuGrp -label (uiRes("m_performSkinCluster.kGeodesicVoxelResolution")) -annotation (uiRes("m_performSkinCluster.kGeodesicVoxelResolutionAnnot")) -cc "skinClusterUpdateGeomBindOptions;" geodesicRes ; menuItem -label 1024 ; menuItem -label 512 ; menuItem -label 256 ; menuItem -label 128 ; menuItem -label 64 ; checkBoxGrp -ncb 1 -annotation (uiRes("m_performSkinCluster.kGeodesicVoxelPostCheckAnnot")) -label1 (uiRes("m_performSkinCluster.kGeodesicVoxelPostCheck")) -cc "skinClusterUpdateGeomBindOptions;" geodesicPostVoxelCheck ; setParent ..; } global proc skinClusterUpdateGeomBindOptions() { if (`floatSliderGrp -exists geodesicFalloff`) { optionVar -floatValue geodesicFalloff `floatSliderGrp -q -value geodesicFalloff`; } if (`optionMenuGrp -exists geodesicRes`) { optionVar -intValue geodesicRes `optionMenuGrp -q -sl geodesicRes`; } if (`checkBoxGrp -exists geodesicPostVoxelCheck`) { optionVar -intValue geodesicPostVoxelCheck `checkBoxGrp -q -value1 geodesicPostVoxelCheck`; } } global proc skinClusterUpdateGeomBindSetup() { int $bindMethod = `optionVar -query bindMethod`; frameLayout -e -visible ($bindMethod == 4) geodesicOpts; // Geodesic voxel binding options // if (`floatSliderGrp -exists geodesicFalloff`) { floatSliderGrp -e -value `optionVar -query geodesicFalloff` geodesicFalloff; } if (`optionMenuGrp -exists geodesicRes`) { optionMenuGrp -e -sl `optionVar -q geodesicRes` geodesicRes; } if (`checkBoxGrp -exists geodesicPostVoxelCheck`) { checkBoxGrp -e -value1 `optionVar -q geodesicPostVoxelCheck` geodesicPostVoxelCheck; } } // // Procedure Name: // skinClusterCallback // // Description: // Update the option values with the current state of the option box UI. // // Input Arguments: // parent - Top level parent layout of the option box UI. Required so // that UI object names can be successfully resolved. // // doIt - Whether the command should execute. // // Return Value: // None. // global proc skinClusterCallback (string $parent, int $doIt) { setParent $parent; // bindTo // optionVar -intValue bindTo `optionMenuGrp -q -sl bindTo`; int $defaultBindMethod = `optionMenuGrp -q -sl bindMethod`; int $defaultSkinMethod = `optionMenuGrp -q -sl skinMethod`; int $defaultNormalizeMethod = `optionMenuGrp -q -sl normalizeWeightsDropDown`; // Set default options optionVar -intValue bindMethod $defaultBindMethod; optionVar -intValue skinMethod $defaultSkinMethod; optionVar -intValue normalizeWeights $defaultNormalizeMethod; optionVar -intValue weightDistribution `optionMenuGrp -q -sl weightDistributionDropDown`; // allowMultipleBindPoses // optionVar -intValue multipleBindPosesOpt `checkBoxGrp -q -v1 multipleBindPoses`; // MaxInfluences // if (`intSliderGrp -exists maxInfl`) { optionVar -floatValue maxInfl `intSliderGrp -query -value maxInfl`; } if (`checkBoxGrp -exists obeyMaxInfl`) { optionVar -intValue obeyMaxInfl `checkBoxGrp -query -value1 obeyMaxInfl`; } // Set the value of the persistent variable "removeUnusedInfluences" to // that of the option box. if (`checkBoxGrp -exists removeUnusedInfluences`) { optionVar -intValue removeUnusedInfluences `checkBoxGrp -query -value1 removeUnusedInfluences`; } // Set the value of the persistent variable "colorizeSkeleton" to // that of the option box. if (`checkBoxGrp -exists colorizeSkeleton`) { optionVar -intValue colorizeSkeleton `checkBoxGrp -query -value1 colorizeSkeleton`; } // Set the value of the persistent variable "bindIncludeHiddenSelections" to // that of the option box. // if (`checkBoxGrp -exists bindIncludeHiddenSelections`) { optionVar -intValue bindIncludeHiddenSelections `checkBoxGrp -query -value1 bindIncludeHiddenSelections`; } skinClusterUpdateDistanceOptions; skinClusterUpdateHeatMapOptions; skinClusterUpdateGeomBindOptions; if ($doIt) { performSkinCluster false; addToRecentCommandQueue "performSkinCluster false" "Skin Cluster"; } } global proc string skinClusterBasic( string $tabLayout ) { setParent $tabLayout; string $tabForm = `columnLayout -adjustableColumn true`; optionMenuGrp -annotation (uiRes("m_performSkinCluster.kBindToAllAnnot")) -label (uiRes("m_performSkinCluster.kBindTo")) bindTo; menuItem -label (uiRes("m_performSkinCluster.kJointHierarchy")) ; menuItem -label (uiRes("m_performSkinCluster.kSelectedJoints")) ; menuItem -label (uiRes("m_performSkinCluster.kObjectHierarchy")) ; optionMenuGrp -label (uiRes("m_performSkinCluster.kBindMethod")) -annotation (uiRes("m_performSkinCluster.kBindonDistAnnot")) bindMethod; menuItem -label (uiRes("m_performSkinCluster.kClosestDistance")) ; menuItem -label (uiRes("m_performSkinCluster.kClosestHierarchy")) ; menuItem -label (uiRes("m_performSkinCluster.kHeatMap")) ; menuItem -label (uiRes("m_performSkinCluster.kGeodesicVoxel")); string $cc = ""; string $isDistanceBind = "(`optionMenuGrp -q -sl bindMethod` == 1 || `optionMenuGrp -q -sl bindMethod` == 2)"; $cc = $cc + "frameLayout -e -visible " + $isDistanceBind + "distanceOpts; " ; string $isHeatMapBind = "(`optionMenuGrp -q -sl bindMethod` == 3)"; $cc = $cc + "frameLayout -e -visible " + $isHeatMapBind + "heatmapOpts; " ; string $isGeodesicVoxelBind = "(`optionMenuGrp -q -sl bindMethod` == 4)"; $cc = $cc + "frameLayout -e -visible " + $isGeodesicVoxelBind + "geodesicOpts; "; optionMenuGrp -e -cc ($cc) bindMethod; optionMenuGrp -label (uiRes("m_performSkinCluster.kSkinMethod")) -annotation (uiRes("m_performSkinCluster.kSkinMethodAnnot")) skinMethod; menuItem -label (uiRes("m_performSkinCluster.kLinearMethod")) ; menuItem -label (uiRes("m_performSkinCluster.kDualQuaternionMethod")) ; menuItem -label (uiRes("m_performSkinCluster.kBlendedMethod")) ; optionMenuGrp -label (uiRes("m_performSkinCluster.kNormalizationWeights")) -annotation (uiRes("m_performSkinCluster.kNormalizeWeightsAnnot")) -changeCommand ("optionMenuGrp -e -enable (`optionMenuGrp -q -sl normalizeWeightsDropDown` == 2) weightDistributionDropDown;") normalizeWeightsDropDown; menuItem -label (uiRes("m_performSkinCluster.kNormalizeNone")) ; menuItem -label (uiRes("m_performSkinCluster.kNormalizeInteractive")) ; menuItem -label (uiRes("m_performSkinCluster.kNormalizePost")) ; optionMenuGrp -label (uiRes("m_performSkinCluster.kWeightDistribution")) -annotation (uiRes("m_performSkinCluster.kWeightDistributionAnnot")) weightDistributionDropDown; menuItem -label (uiRes("m_performSkinCluster.kDZWDistance")) ; menuItem -label (uiRes("m_performSkinCluster.kDZWNeighbors")) ; checkBoxGrp -label "" -label1 (uiRes("m_performSkinCluster.kAllowMultipleBindPoses")) -of1 "optionVar -intValue multipleBindPosesOpt 0" -on1 "optionVar -intValue multipleBindPosesOpt 1" multipleBindPoses; intSliderGrp -label (uiRes("m_performSkinCluster.kMaxInfluences")) -annotation (uiRes("m_performSkinCluster.kMaxInfluencesAnnot")) -fieldMinValue 1 -minValue 1 -maxValue 30 maxInfl; checkBoxGrp -ncb 1 -annotation (uiRes("m_performSkinCluster.kInfluencesEnforcedAnnot")) -label "" -label1 (uiRes("m_performSkinCluster.kMaintainInfluences")) obeyMaxInfl; checkBoxGrp -ncb 1 -annotation (uiRes("m_performSkinCluster.kPerformanceImproveAnnot")) -label1 (uiRes("m_performSkinCluster.kRemUnused")) removeUnusedInfluences; checkBoxGrp -ncb 1 -annotation (uiRes("m_performSkinCluster.kAssignColorAnnot")) -label1 (uiRes("m_performSkinCluster.kColorizeSkeleton")) colorizeSkeleton; checkBoxGrp -ncb 1 -annotation (uiRes("m_performSkinCluster.kIncludeHiddenSelAnnot")) -label1 (uiRes("m_performSkinCluster.kIncludeHiddenSelections")) bindIncludeHiddenSelections; skinClusterCreateDistanceOptions ""; skinClusterCreateHeatMapOptions ""; skinClusterCreateGeomBindOptions ""; setParent -m ..; optionMenuGrp -e -sl 1 bindTo; optionMenuGrp -e -sl 2 bindMethod; optionMenuGrp -e -sl 1 skinMethod; optionMenuGrp -e -sl 3 normalizeWeightsDropDown; optionMenuGrp -e -sl 1 weightDistributionDropDown; setParent ..; return $tabForm; } global proc skinClusterOptions () { // Name of the command for this option box // string $commandName = "skinCluster"; // Build the option box "methods" // string $callback = ($commandName + "Callback"); string $setup = ($commandName + "Setup"); // Get the option box. // // The value returned is the name of the layout to be used as // the parent for the option box UI. // string $layout = getOptionBox(); setParent $layout; setOptionBoxCommandName("skinCluster"); setUITemplate -pushTemplate DefaultTemplate; waitCursor -state 1; tabLayout -scr true -tv false; // To get the scroll bars string $parent = `columnLayout -adjustableColumn 1`; skinClusterBasic $parent; waitCursor -state 0; setUITemplate -popTemplate; // 'Apply' button. // string $applyBtn = getOptionBoxApplyBtn(); button -edit -label (uiRes("m_performSkinCluster.kBindSkin")) -command ($callback + " " + $parent + " " + 1) $applyBtn; // 'Save' button. // string $saveBtn = getOptionBoxSaveBtn(); button -edit -command ($callback + " " + $parent + " " + 0 + "; hideOptionBox") $saveBtn; // 'Reset' button. // string $resetBtn = getOptionBoxResetBtn(); button -edit -command ($setup + " " + $parent + " " + 1) $resetBtn; // Set the option box title. // setOptionBoxTitle (uiRes("m_performSkinCluster.kSmoothBindOptions")); // Customize the 'Help' menu item text. // setOptionBoxHelpTag( "SmoothBind" ); // Set the current values of the option box. // eval (($setup + " " + $parent + " " + 0)); // Show the option box. // showOptionBox(); } proc string assembleCmd () { setOptionVars( false ); string $cmd = ""; int $colorSkeleton = `optionVar -query colorizeSkeleton`; if ($colorSkeleton) { string $joints[] = `ls -sl -type joint`; string $rootJoint = $joints[0]; if($rootJoint != "") { $cmd = "colorizeSkeleton \"" + $rootJoint + "\" true;\n"; } } $cmd += "newSkinCluster \""; int $bindTo = `optionVar -q bindTo`; if ($bindTo == 2) { $cmd = ( $cmd + "-toSelectedBones " ); } else if ($bindTo == 3) { $cmd = ( $cmd + "-toSkeletonAndTransforms " ); } int $bindMethod = `optionVar -q bindMethod`; $cmd = ( $cmd + "-bindMethod " + ( $bindMethod - 1 ) + " " ); // If heatmap binding add specified falloff if ($bindMethod == 3) { $cmd = $cmd + "-heatmapFalloff " + ( `optionVar -q heatmapFalloff` ) + " "; } else if ($bindMethod == 4) { $cmd = $cmd + "-heatmapFalloff " + ( `optionVar -q geodesicFalloff` ) + " "; $cmd = $cmd + "-geodesicResolution " ; $cmd = $cmd + gridResolutionEnumToInt( `optionVar -q geodesicRes` ) + " "; $cmd = $cmd + "-geodesicPostVoxelCheck " + (`optionVar -q geodesicPostVoxelCheck`) + " "; } int $skinMethod = `optionVar -q skinMethod`; if ($skinMethod > 1) { $cmd = ( $cmd + "-skinMethod " + ($skinMethod -1) + " "); } int $normalizeWeights = `optionVar -q normalizeWeights`; $cmd = ( $cmd + "-normalizeWeights " + ($normalizeWeights -1) + " "); int $weightDistribution = `optionVar -q weightDistribution`; $cmd = ( $cmd + "-weightDistribution " + ($weightDistribution -1) + " "); $cmd += "-mi " + `optionVar -query maxInfl` + " "; if (`optionVar -query obeyMaxInfl`) { $cmd += "-omi true "; } $cmd += "-dr " + `optionVar -query dropoff`; int $cullUnusedInfluences = `optionVar -query removeUnusedInfluences`; if ($cullUnusedInfluences) { $cmd += " -rui true"; } else { $cmd += " -rui false"; } int $includeHiddenSelections = `optionVar -query bindIncludeHiddenSelections`; if ($includeHiddenSelections) $cmd += " -ihs"; $cmd += (",multipleBindPose,"+`optionVar -q multipleBindPosesOpt`+"\";"); return $cmd; } global proc string performSkinCluster (int $action) // The action variable means // 0 - do the command // 1 - show the option box // 2 - return the drag command { string $cmd = ""; switch ($action) { case 0: // Execute the command // Retrieve the option settings // setOptionVars (false); // Get the command and print it in the command window $cmd = `assembleCmd`; // Execute the command with the option settings eval($cmd); break; case 1: // Do the option box skinClusterOptions; break; case 2: // Return the drag string // Retrieve the option settings // setOptionVars (false); // Get the command $cmd = `assembleCmd`; break; } return $cmd; }