// =========================================================================== // 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: // // performLODGenerateMeshes (UI interface to the automatic generation of // lower resolution meshes, via calls to polyReduce) // // Input Arguments: // Returns: // Reduce command // // Description: // // Perform a generation of reduced levels, for LOD purposes. // // ////////////////////////////////////////////////////////////////////// proc int LODMaxLevels() // // Description: // // Maximum number of LOD levels that can be generated. // { return 9; } proc setOptionVars (int $forceFactorySettings) // // Description: // Set user definable options // // Arguments: // forceFactorySettings : use defaults // { if( !`exists pr_setOptionVars` ){ eval("source \"polyReduceUtils.mel\""); } pr_setOptionVars( $forceFactorySettings, "LODGenerateMeshes" ); // Set option vars specific to performLODGenerateMeshes // // Copy the skin weights, if possible // if ($forceFactorySettings || !`optionVar -exists LODGenerateMeshesCopySkinWeights`){ optionVar -intValue LODGenerateMeshesCopySkinWeights 1; } // Number of LOD levels that can be generated // if ($forceFactorySettings || !`optionVar -exists LODGenerateMeshesNumLevels`){ optionVar -intValue LODGenerateMeshesNumLevels 1; } int $maxLevels = LODMaxLevels(); // Specify which LOD levels to generate // if ($forceFactorySettings || !`optionVar -exists LODGenerateLevelArray`){ // By default, only generate first level. // optionVar -clearArray LODGenerateLevelArray; optionVar -intValueAppend LODGenerateLevelArray 1; int $level = 2; while( $level <= $maxLevels ){ optionVar -intValueAppend LODGenerateLevelArray 0; $level++; } } // Percentage of vertices to remove for each LOD level if ($forceFactorySettings || !`optionVar -exists LODPercentArray`){ optionVar -clearArray LODPercentArray; int $level = 1; float $fVal = 100.0/3.0; // Remove 33% of vertices for level 1 while( $level <= $maxLevels ){ optionVar -floatValueAppend LODPercentArray $fVal; // Gradually move towards removing 100% // $fVal = (100.0+2*$fVal)/3.0; $level++; } } // Number of vertices to keep if ($forceFactorySettings || !`optionVar -exists LODVertexCountArray`){ optionVar -clearArray LODVertexCountArray; int $level = 1; while( $level <= $maxLevels ){ optionVar -intValueAppend LODVertexCountArray 0; $level++; } } // Number of triangles to keep if ($forceFactorySettings || !`optionVar -exists LODTriangleCountArray`){ optionVar -clearArray LODTriangleCountArray; int $level = 1; while( $level <= $maxLevels ){ optionVar -intValueAppend LODTriangleCountArray 0; $level++; } } } global proc performLODGenerateMeshesSetup( string $parent, int $forceFactorySettings ) // // Description: // Do the setup of widget states // // Arguments: // parent : parent widget; if NULL, only set the option vars. // forceFactorySettings : set to defaults // // Note: This is used by pr_performOptions in polyReduceUtils.mel // { setOptionVars($forceFactorySettings); if( $parent == "" ){ return; } // Perform the setup on the part that is common to both polyReduce and // LODGenerateMeshes. // pr_performSetup( $parent, $forceFactorySettings, "LODGenerateMeshes" ); checkBox -e -value (`optionVar -q LODGenerateMeshesCopySkinWeights`) copySkinWeights; optionMenuGrp -e -select (`optionVar -q LODGenerateMeshesNumLevels`) LODGenerateMeshesNumLevels; setParent ..; updateLODGenerateMeshesNumLevels( 1, $parent ); } global proc performLODGenerateMeshesCallback (string $parent, int $doIt) // // Description: // Save option variables before application or save. // // Arguments: // parent : parent widget // doIt : perform action // // Note: This is used by pr_performOptions in polyReduceUtils.mel // { string $oldParent = `setParent -q`; setParent $parent; // Perform the callbak on the part that is common to both polyReduce and // LODGenerateMeshes. // pr_performCallback( "LODGenerateMeshes" ); setParent terminationConditions; int $copySkinWeights = `checkBox -q -value copySkinWeights`; optionVar -intValue LODGenerateMeshesCopySkinWeights $copySkinWeights; int $numLevels = `optionMenuGrp -q -sl LODGenerateMeshesNumLevels`; optionVar -intValue LODGenerateMeshesNumLevels $numLevels; int $maxLevels = LODMaxLevels(); int $level = 1; optionVar -clearArray LODGenerateLevelArray; optionVar -clearArray LODPercentArray; optionVar -clearArray LODVertexCountArray; optionVar -clearArray LODTriangleCountArray; while( $level <= $maxLevels ){ int $iVal = `checkBox -q -value ("LODGenerateLevel" + $level)`; optionVar -intValueAppend LODGenerateLevelArray $iVal; float $fVal = `floatSliderGrp -q -value ("LODReducePercent" + $level)`; optionVar -floatValueAppend LODPercentArray $fVal; $iVal = `intFieldGrp -q -v1 ("LODReduceVertexCount" + $level)`; optionVar -intValueAppend LODVertexCountArray $iVal; $iVal = `intFieldGrp -q -v1 ("LODReduceTriangleCount" + $level)`; optionVar -intValueAppend LODTriangleCountArray $iVal; $level++; } setParent ..; setParent $oldParent; if ($doIt) { performLODGenerateMeshes 0; addToRecentCommandQueue "performLODGenerateMeshes 0" "LODGenerateMeshes"; } } global proc updateLODGenerateLevel( int $levelEnabled, int $level, string $parent ) // // Description: // This is called when the check box for an LOD level is toggled. // // Arguments: // levelEnabled : true iff this level is being enabled // level : index of LOD level being toggle // parent : parent widget // { setParent $parent; floatSliderGrp -e -enable $levelEnabled ("LODReducePercent" + $level); intFieldGrp -e -enable $levelEnabled ("LODReduceVertexCount" + $level); intFieldGrp -e -enable $levelEnabled ("LODReduceTriangleCount" + $level); } global proc updateLODGenerateMeshesNumLevels( int $syncToOptVars, string $parent ) // // Description: // This is called when the number of LOD levels being converted is // changed, or when the LOD visibility states need to be enabled. // // Arguments: // syncToOptVars : true iff we should first sync to optionVar values // parent : parent widget // { setParent $parent; int $numLevels = `optionMenuGrp -q -sl LODGenerateMeshesNumLevels`; optionVar -intValue LODGenerateMeshesNumLevels $numLevels; int $maxLevels = LODMaxLevels(); int $termType = (`optionMenuGrp -q -sl polyReduceTermination`-1); int $percentVisible = ($termType == 0); int $vertexCountVisible = ($termType == 1); int $triangleCountVisible = ($termType == 2); int $levelVisible = true; // First level is always visible // Query the state of the optionVar values // int $generateLevels[] = `optionVar -query LODGenerateLevelArray`; float $percentages[] = `optionVar -query LODPercentArray`; int $vertexCounts[] = `optionVar -query LODVertexCountArray`; int $triangleCounts[] = `optionVar -query LODTriangleCountArray`; int $level = 1; while( $level <= $maxLevels ){ if( $level > $numLevels ){ // Subsequent levels are hidden $levelVisible = false; } if( $syncToOptVars ){ // Sync to optionVar values before updating controls // checkBox -e -value ($generateLevels[$level-1]) ("LODGenerateLevel" + $level); floatSliderGrp -e -value ($percentages[$level-1]) ("LODReducePercent" + $level); intFieldGrp -e -v1 ($vertexCounts[$level-1]) ("LODReduceVertexCount" + $level); intFieldGrp -e -v1 ($triangleCounts[$level-1]) ("LODReduceTriangleCount" + $level); } // Update controls /// int $levelEnabled = `checkBox -q -value ("LODGenerateLevel" + $level)`; checkBox -e -vis ($levelVisible) ("LODGenerateLevel" + $level); floatSliderGrp -e -enable $levelEnabled -vis ($levelVisible && $percentVisible) ("LODReducePercent" + $level); intFieldGrp -e -enable $levelEnabled -vis ($levelVisible && $vertexCountVisible) ("LODReduceVertexCount" + $level); intFieldGrp -e -enable $levelEnabled -vis ($levelVisible && $triangleCountVisible) ("LODReduceTriangleCount" + $level); $level++; } } global proc buildLODGenerateMeshesSettingsSection() // // Description: // This is called by pr_performOptions to build the Settings Section (and // the LOD section). // { // Build the frame layout for the Settings Method // frameLayout -l (uiRes("m_performLODGenerateMeshes.kConstructionOptions")) -collapsable 1 -collapse 0 constructionOptions; checkBox -label (uiRes("m_performLODGenerateMeshes.kCopySkinWeights")) -ann (uiRes("m_performLODGenerateMeshes.kCopySkinWeightsAnn")) -onCommand ("optionVar -intValue LODGenerateMeshesCopySkinWeights 1") -offCommand ("optionVar -intValue LODGenerateMeshesCopySkinWeights 0") copySkinWeights; setParent ..; } global proc buildLODGenerateMeshesReductionSection( string $parent ) // // Description: // This is called by pr_performOptions to build the Reduction Section (and // the LOD section). // // Arguments: // parent : parent widget // { string $percentageLbl = (uiRes("m_performLODGenerateMeshes.kPercentage")); string $vertexLimitLbl = (uiRes("m_performLODGenerateMeshes.kVertexLimit")); string $triangleLimitLbl = (uiRes("m_performLODGenerateMeshes.kTriangleLimit")); // Build the frame layout for the Reduction Method // frameLayout -l (uiRes("m_performLODGenerateMeshes.kTerminationConditions")) -ann (uiRes("m_performLODGenerateMeshes.kTerminationToolAnn")) -collapsable 1 -collapse 0 terminationConditions; optionMenuGrp -label (uiRes("m_performLODGenerateMeshes.kTermination")) -cc ("updateLODGenerateMeshesNumLevels 0 " + $parent) polyReduceTermination; menuItem -label $percentageLbl; menuItem -label $vertexLimitLbl; menuItem -label $triangleLimitLbl; setParent ..; // Build the frame layout for the LOD Levels // frameLayout -l (uiRes("m_performLODGenerateMeshes.kLODLevels")) -ann (uiRes("m_performLODGenerateMeshes.kLODLevelsAnn")) -collapsable 1 -collapse 0 lodLevels; optionMenuGrp -label (uiRes("m_performLODGenerateMeshes.kLODNumLevels")) -ann (uiRes("m_performLODGenerateMeshes.kLODNumLevelsAnn")) -cc ("updateLODGenerateMeshesNumLevels 0 " + $parent) LODGenerateMeshesNumLevels; int $level = 1; int $maxLevels = LODMaxLevels(); while( $level <= $maxLevels ){ menuItem -label $level; $level++; } // Setup each level, making it invisible until we enable it // if( !`exists lodRoot`){ eval("source \"lodUtils.mel\""); } $level = 1; while( $level <= $maxLevels ){ string $formLayout = `formLayout -nd 100`; string $lodRoot = lodRoot(); string $cb = `checkBox -label ($lodRoot + $level) -ann (uiRes("m_performLODGenerateMeshes.kCheckBoxAnn")) -vis false -onCommand ("updateLODGenerateLevel 1 " + $level + " " + $parent ) -offCommand ("updateLODGenerateLevel 0 " + $level + " " + $parent ) ("LODGenerateLevel" + $level)`; string $sliders[]; $sliders[0] = `floatSliderGrp -label $percentageLbl -ann (uiRes("m_performLODGenerateMeshes.kPercentAnn")) -cw 1 80 -vis false -minValue 0.0 -maxValue 100.0 -fieldMinValue 0.0 -fieldMaxValue 100.0 ("LODReducePercent" + $level)`; $sliders[1] = `intFieldGrp -l $vertexLimitLbl -ann (uiRes("m_performLODGenerateMeshes.kTargetVertexCountAnn")) -cw 1 80 -vis false ("LODReduceVertexCount" + $level)`; $sliders[2] = `intFieldGrp -l $triangleLimitLbl -ann (uiRes("m_performLODGenerateMeshes.kTargetTriangleCountAnn")) -cw 1 80 -vis false ("LODReduceTriangleCount" + $level)`; setParent ..; formLayout -e -af $cb "left" 60 -ac $sliders[0] "left" 0 $cb -an $sliders[0] "right" -ac $sliders[1] "left" 0 $cb -an $sliders[1] "right" -ac $sliders[2] "left" 0 $cb -an $sliders[2] "right" $formLayout; $level++; } setParent ..; } global proc buildLODGenerateMeshesButtonTitleHelp( string $applyBtn ) { button -edit -label (uiRes("m_performLODGenerateMeshes.kGenerateButton")) $applyBtn; setOptionBoxTitle( (uiRes("m_performLODGenerateMeshes.kLODGenerateMeshOptions")) ); setOptionBoxHelpTag( "LODGenerateMeshes" ); } proc performLODGenerateMeshesOptions() // // Description: // Options for LOD Generate Meshes // { if( !`exists pr_performOptions` ){ eval("source \"polyReduceUtils.mel\""); } pr_performOptions( "LODGenerateMeshes" ); } proc string assembleCmd() // // Description: // Build a command based on the current option variables. // // Returns: // string command // { if( !`exists pr_assembleCmd` ){ eval("source \"polyReduceUtils.mel\""); } int $level = 0; int $lastLevel = `optionVar -q LODGenerateMeshesNumLevels`; string $commonOptions = pr_assembleCmd("LODGenerateMeshes"); string $cmd; int $generateLevels[] = `optionVar -query LODGenerateLevelArray`; float $percentages[] = `optionVar -query LODPercentArray`; int $vertexCounts[] = `optionVar -query LODVertexCountArray`; int $triangleCounts[] = `optionVar -query LODTriangleCountArray`; // Calculate the max LOD threshold we'll need to compute. // int $maxThreshold = 1; while( $level < $lastLevel ){ if( $generateLevels[$level] ){ $maxThreshold = $level+1; } $level++; } // Reset level counter to zero. // $level = 0; while( $level < $lastLevel ){ int $levelEnabled = $generateLevels[$level]; if( $levelEnabled ){ $cmd += "doPerformPolyReduceArgList 3 {" + $commonOptions + ",\"" + ($percentages[$level]) + "\"" + ",\"" + ($vertexCounts[$level]) + "\"" + ",\"" + ($triangleCounts[$level]) + "\"" + // -replaceOriginal // ",\"0\"" + // -preserveLocation // ",\"1\"" + // Specify level // ",\"" + ($level+1) + "\"" + // Specify if we copy skin weights // ",\"" + `optionVar -q LODGenerateMeshesCopySkinWeights` + "\"" + // Specify the max LOD thresholds we want to compute // ",\"" + $maxThreshold + "\"};"; } $level++; } return $cmd; } global proc string performLODGenerateMeshes(int $option) // // Description: // LOD Generate Meshes (UI wrapper) // // Arguments: // option: 0=execute, 1=option box, 2=drag to shelf // // Returns: // command // // { string $cmd = ""; switch ($option) { case 0: // Retrieve the option settings // setOptionVars( false ); // Get the command. // $cmd = `assembleCmd`; // Execute the command with the option settings. // evalEcho($cmd); break; case 1: // Just show the option box performLODGenerateMeshesOptions(); break; case 2: // Retrieve the option settings. // setOptionVars( false ); // Get the command. // $cmd = `assembleCmd`; break; } return $cmd; }