// =========================================================================== // 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: March 5, 2001 // global proc renderCreateBarUIManage( string $renderCreateBarUI, int $manage) { // // Description: // This procedure is called to cause the render create bar UI to be shown // or hidden. // This procedure causes the formLayout which contains the render create // bar UI to be managed or unmanaged, according to the $manage argument. // formLayout -edit -manage $manage $renderCreateBarUI; } global proc int renderCreateBarUIIsManaged( string $renderCreateBarUI) { // // Description: // This procedure is called to determine whether or not the create bar UI // is being shown. // // Returns: // true if the render create bar UI is shown, false if not. // return (`formLayout -query -manage $renderCreateBarUI`); } global proc addToRenderNodeTreeLister( string $renderNodeTreeLister, string $postCommand, string $frame, string $classification, string $as, string $flag) { // // Description: // This procedure is called as the render create bar UI is // being built. // This procedure adds each node type that is classified according to // $classification to the nodeTreeLister. The item command is configured // create a node of that type using the $as and $flag arguments to // createRenderNodeCB(). // // some shaders are registered as both // rendernode/myrenderer/material and shaders/surface // For those nodes, this function is called twice : // once with $classification = shader/surface, // once with $classification = rendernode/myrenderer/material // We want to create buttons/menus in myrenderer section string $nodes[]; string $customClassificationArray[] = `callbacks -executeCallbacks -hook "renderNodeClassification"`; // fill in the nodes array based on the classification filters if (size($customClassificationArray)){ // does the classification string match any of the filters returned? // (this match should be unique) int $found = 0; string $currentCustomClassificationString; for ($currentCustomClassificationString in $customClassificationArray){ if (startsWith($classification, $currentCustomClassificationString)){ $found = 1; break; } } if ($found){ // if we have a match, then we can go ahead and return the node types without filtering // Give 3rd parties a chance to append to the exclusion string string $thirdPartiesClassificationExclusionStrings[] = `callbacks -executeCallbacks -hook "provideClassificationExclusionStrings" $classification`; $thirdPartiesClassificationExclusionStrings = stringArrayRemoveExact({""}, $thirdPartiesClassificationExclusionStrings); string $exclusionString = stringArrayToString($thirdPartiesClassificationExclusionStrings, ":"); $nodes = `listNodeTypes -ex $exclusionString $classification`; } else{ // if we don't have a match, we're probably looking at a basic type like shaders/surface, and // don't want to have the custom types like rendernode/myrenderer show up as well, so filter // them out string $filterCommand = "listNodeTypes -ex \""; string $filter; for ($filter in $customClassificationArray){ $filterCommand += $filter + ":"; } $filterCommand += "\" \"" +$classification + "\""; $nodes = eval($filterCommand); } } else{ $nodes = `listNodeTypes $classification`; } string $annotation = ""; string $encPostCommand = encodeString($postCommand); python("import maya.app.general.tlfavorites as _fav"); for ($type in $nodes) { // Check whether node should appear in this UI, based on // certain variables if (!shouldAppearInNodeCreateUI($type)) { continue; } string $command = ""; string $labelName; // cycle through the callback results to see if any handle this classification string $commands[] = `callbacks -executeCallbacks -hook "createRenderNodeCommand" $encPostCommand $type`; for ($command in $commands) { if (size($command)) break; } if( size($command) ) { // command has been defined by a callback $labelName = $type; } else { $command = ("createRenderNodeCB" + " " + $as + " \"" + $flag + "\" " + $type + " \"" + $encPostCommand + "\" "); $labelName = `nodeTypeNiceName $type`; } string $buffer[]; int $numTokens = `tokenize $labelName "/" $buffer`; if($numTokens > 1) { $labelName = stringArrayToString($buffer, "|"); } string $nodePath = $frame + "/" + $labelName; nodeTreeLister -e -add $nodePath ($type + ".svg") $command $renderNodeTreeLister; python(("_fav.addPath(\"" + encodeString($nodePath) + "\",\"" + encodeString($type) + "\")")); } python ("del _fav"); } global proc initializeMayaNodeTypeInfo () // // Description: This procedure creates an array storing Maya node // categories and the info needed to create a node of // each type. // { global string $gMayaNodeTypeInfo[]; if( size( $gMayaNodeTypeInfo ) == 0 ) { int $index = 0; // Materials. // $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Surface" ); $gMayaNodeTypeInfo[$index++] = "shader/surface"; $gMayaNodeTypeInfo[$index++] = "-asShader"; $gMayaNodeTypeInfo[$index++] = "surfaceShader"; $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Volumetric" ); $gMayaNodeTypeInfo[$index++] = "shader/volume"; $gMayaNodeTypeInfo[$index++] = "-asShader"; $gMayaNodeTypeInfo[$index++] = "volumeShader"; $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Displacement" ); $gMayaNodeTypeInfo[$index++] = "shader/displacement"; $gMayaNodeTypeInfo[$index++] = "-asShader"; $gMayaNodeTypeInfo[$index++] = "displacementShader"; // Textures. // $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "2D Textures" ); $gMayaNodeTypeInfo[$index++] = "texture/2d"; $gMayaNodeTypeInfo[$index++] = "-as2DTexture"; $gMayaNodeTypeInfo[$index++] = ""; $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "3D Textures" ); $gMayaNodeTypeInfo[$index++] = "texture/3d"; $gMayaNodeTypeInfo[$index++] = "-as3DTexture"; $gMayaNodeTypeInfo[$index++] = ""; $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Env Textures" ); $gMayaNodeTypeInfo[$index++] = "texture/environment"; $gMayaNodeTypeInfo[$index++] = "-asEnvTexture"; $gMayaNodeTypeInfo[$index++] = ""; $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Other Textures" ); $gMayaNodeTypeInfo[$index++] = "texture/other"; $gMayaNodeTypeInfo[$index++] = "-asTexture"; $gMayaNodeTypeInfo[$index++] = ""; // Lights. // $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Lights" ); $gMayaNodeTypeInfo[$index++] = "light"; $gMayaNodeTypeInfo[$index++] = "-asLight"; $gMayaNodeTypeInfo[$index++] = ""; // Utilities. // $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Utilities" ); $gMayaNodeTypeInfo[$index++] = "utility"; $gMayaNodeTypeInfo[$index++] = "-asUtility"; $gMayaNodeTypeInfo[$index++] = ""; $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Image Planes" ); $gMayaNodeTypeInfo[$index++] = "imageplane"; $gMayaNodeTypeInfo[$index++] = "-asUtility"; $gMayaNodeTypeInfo[$index++] = ""; $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Glow" ); $gMayaNodeTypeInfo[$index++] = "postprocess/opticalFX"; $gMayaNodeTypeInfo[$index++] = "-asPostProcess"; $gMayaNodeTypeInfo[$index++] = ""; $gMayaNodeTypeInfo[$index++] = "Maya/" + localizedNodeClassificationLabel( "Rendering" ); $gMayaNodeTypeInfo[$index++] = "rendering"; $gMayaNodeTypeInfo[$index++] = "-asRendering"; $gMayaNodeTypeInfo[$index++] = ""; } } global proc int mayaNumNodeCategories() // // Description: Returns the number of Maya node categories. // { // // Make sure all the Maya node categories are filled in before we use them. // initializeMayaNodeTypeInfo(); global string $gMayaNodeTypeInfo[]; return( size($gMayaNodeTypeInfo)/4 ); } global proc string[] mayaGetNodeCategory( int $whichCat ) // // Description: Retrieves information about the specified category. // // Arguments: $whichCat - the numeric identifier for the category. // // Returns: A 4-element string array containing the title string, // ui base name, static classification, and runtime classification // for the category. // { // // Make sure all the Maya node categories are filled in before we use them. // initializeMayaNodeTypeInfo(); global string $gMayaNodeTypeInfo[]; string $categoryName = $gMayaNodeTypeInfo[4*$whichCat]; string $categoryClassification = $gMayaNodeTypeInfo[4*$whichCat+1]; string $categoryAs = $gMayaNodeTypeInfo[4*$whichCat+2]; string $categoryFlag = $gMayaNodeTypeInfo[4*$whichCat+3]; return { $categoryName, $categoryClassification, $categoryAs, $categoryFlag }; } global proc createMayaNodesTreeLister_Content(string $renderNodeTreeLister, string $postCommand, string $filterClasses[]) // // Description: // This procedure contains code for adding Maya nodes // to the treeLister. { // use the shortname of the tree control for faster lookups // since we know it's under the current parent string $buff[]; int $num = `tokenize $renderNodeTreeLister "|" $buff`; if ($num > 0) { $renderNodeTreeLister = $buff[$num-1]; } if(size($filterClasses) == 0) { // Create all categories // int $numCategories = mayaNumNodeCategories(); int $i; for( $i = 0; $i < $numCategories; $i++ ) { string $categoryInfo[] = mayaGetNodeCategory( $i ); string $title = $categoryInfo[0]; string $classification = $categoryInfo[1]; string $as = $categoryInfo[2]; string $flag = $categoryInfo[3]; // add to the treeLister // addToRenderNodeTreeLister($renderNodeTreeLister, $postCommand, $title, $classification, $as, $flag); } } else { // Create only the categories in the filter array // for($filterClass in $filterClasses) { int $numCategories = mayaNumNodeCategories(); int $i; for( $i = 0; $i < $numCategories; $i++ ) { string $categoryInfo[] = mayaGetNodeCategory( $i ); string $title = $categoryInfo[0]; string $classification = $categoryInfo[1]; string $as = $categoryInfo[2]; string $flag = $categoryInfo[3]; if(startsWith($filterClass, $classification)) { // If the filter classification is a subclass of // a default, only add the subclass nodes to the // treeLister. // addToRenderNodeTreeLister($renderNodeTreeLister, $postCommand, $title, $filterClass, $as, $flag); break; } else if(startsWith($classification, $filterClass)) { // If the filter classification is a superclass of // a default, we can add all the default nodes to the // treeLister. // addToRenderNodeTreeLister($renderNodeTreeLister, $postCommand, $title, $classification, $as, $flag); break; } } } } } proc string renderCreateBarFavoritesFile() // Description: Returns the full path to the favorites file // { return (`internalVar -userPrefDir` + "renderNodeTypeFavorites"); } proc renderCreateBarInitDefaultFavorites(string $fname) // Description: Create the default favorites file // { // This default set is only created if the file doesn't already exist. string $defaultNodeTypes[] = {"blinn","lambert","layeredShader", "phong","phongE","rampShader","surfaceShader","useBackground"}; string $defaultFavs = "["; string $basePath = ("Maya/" + localizedNodeClassificationLabel( "Surface" )); string $nodeType; for ($nodeType in $defaultNodeTypes) { string $suffix = `nodeTypeNiceName($nodeType)`; string $fullPath = ($basePath + "/" + $suffix) ; string $tuple = ("(\"" + encodeString($fullPath) + "\",\"" + encodeString($nodeType) + "\")"); $defaultFavs += ($tuple + ","); } $defaultFavs += "]"; $fileId=`fopen $fname "w"`; if ($fileId != 0) { fprint $fileId $defaultFavs; fclose $fileId; } } global proc string[] renderCreateBarFavorites() // Description: This procedure returns the list of renderCreateBar favorites // as a list like: {"Maya/Surface/Blinn","blinn","Maya/Volume/... } // { string $fname = renderCreateBarFavoritesFile(); if (!`file -q -ex $fname`) { // No favorites. Create a default set renderCreateBarInitDefaultFavorites($fname); } string $fnameenc = `encodeString $fname`; string $favs[] = python("import maya.app.general.tlfavorites as _fav;_fav.readFavorites(\"" + $fnameenc + "\")"); python("del _fav"); return $favs; } proc renderCreateBarInitFavorites(string $lister) // Description: This procedure is called to hook up the treeLister to // a Favorites store. // { string $fname = renderCreateBarFavoritesFile(); if (!`file -q -ex $fname`) { // No favorites. Create a default set renderCreateBarInitDefaultFavorites($fname); } string $fnameenc = `encodeString $fname`; string $py = ( "import maya.app.general.tlfavorites as _fav;" + "_fav.attachStore('" + $lister + "',\"" + $fnameenc + "\");" + "del _fav"); python($py); } global proc renderCreateBarPopupCreate2DTexture(string $path, string $lister, string $texType) // Description: This procedure is called to create a 2D texture with a particular // type by temporarily changing create2DTextureType optionVar // { string $oldTexType = `optionVar -query create2dTextureType`; optionVar -stringValue create2dTextureType $texType; treeLister -e -executeItem $path $lister; optionVar -stringValue create2dTextureType $oldTexType; refreshCreateNodeUI(); } global proc renderCreateBarPopupMenuCB(string $lister, string $menu) // Description: This procedure is called to populate the treeLister // result items RMB menu. // { // delete our old items first string $items[] = `menu -q -ia $menu`; for ($itemToDelete in $items){ if(`menuItem -exists $itemToDelete`){ catchQuiet( `deleteUI -menuItem $itemToDelete` ); } } $path = `treeLister -q -resultsPathUnderCursor $lister`; if (0 == `size $path`) return; // query the lang and command string string $item[] = `treeLister -q -itemScript $path $lister`; // The way Maya formats all of it's scriptCommands is: // "createRenderNodeCB -as(NodeUsage) NodeClassification NodeType" // We extract the current node type from it. string $scripCommandTokens[]; string $currentNodeType = ""; $numberOfTokens = `tokenize $item[1] " " $scripCommandTokens`; if($numberOfTokens > 4){ $currentNodeType = $scripCommandTokens[3]; } // Give third parties a chance to add menuItems to the RMB menu of a treeLister node. string $oldParent = `setParent -menu -query`; setParent -menu $menu; int $mayaShouldAddItsOwnItemsToTheRMBMenu = 1; string $encodedScriptCommandOfTreeListerNode = encodeString($item[1]); int $requestsToRemoveMayasOwnItemsFromRMBMenu[] = `callbacks -executeCallbacks -hook "addItemsToRMBMenuOfTreeLister" $currentNodeType $encodedScriptCommandOfTreeListerNode`; // If third parties did add items, did they request Maya to add it's own items to the // RMB menu aswell? if(`size $requestsToRemoveMayasOwnItemsFromRMBMenu` > 0) { for ($requestToRemoveMayasOwnItemsFromRMBMenu in $requestsToRemoveMayasOwnItemsFromRMBMenu) { if($requestToRemoveMayasOwnItemsFromRMBMenu == 1) { // We have found at least one plugin that doesn't want Maya to add it's own items. We won't then. $mayaShouldAddItsOwnItemsToTheRMBMenu = 0; break; } } } if($mayaShouldAddItsOwnItemsToTheRMBMenu == 1) { string $itemsAddedByThirdParties[] = `menu -q -ia $menu`; // note: The 'Favorites' related menu item will always be there // so we need to account for it in the items listed in the menu. if(`size $itemsAddedByThirdParties` > 1){ // We separate third parties and Maya items using a divider menuItem -divider true; } // if -as2DTexture is in the command then populate the 2d texture options if (`gmatch $item[1] "*-as2DTexture*"`) { menuItem -label (uiRes("m_renderCreateBarUI.kCreateTexture")) -command ("renderCreateBarPopupCreate2DTexture \"" + $path + "\" " + $lister + " \"normal\"" ) normalItem2; menuItem -label (uiRes("m_renderCreateBarUI.kCreateAsProjection")) -command ("renderCreateBarPopupCreate2DTexture \"" + $path + "\" " + $lister + "\"projection\"" ) projectionItem2; menuItem -label (uiRes("m_renderCreateBarUI.kCreateAsStencil")) -command ("renderCreateBarPopupCreate2DTexture \"" + $path + "\" " + $lister + "\"stencil\"" ) stencilItem2; } } setParent -menu $oldParent; } proc renderCreateBarInitPopupMenu(string $lister) // Description: This procedure is called to create a popupMenu // on the treelister to handle creation options. // { string $menuName = "renderCreateBarPopupMenu"; popupMenu -parent $lister -pmc ("renderCreateBarPopupMenuCB \""+ $lister + "\" \"" + $menuName +"\"") $menuName; } global proc buildRenderNodeTreeListerContent(string $renderNodeTreeLister, string $postCommand, string $filterString) // // Description: This procedure is to populate the treeLister with render nodes. // { string $createContentProc; string $filterClassArray[]; $filterClassArray = stringToStringArray($filterString, " "); createMayaNodesTreeLister_Content($renderNodeTreeLister, $postCommand, $filterClassArray); // call custom UI callbacks string $encodedPostCommand = `encodeString($postCommand)`; callbacks -executeCallbacks -hook "buildRenderNodeTreeListerContent" $renderNodeTreeLister $encodedPostCommand $filterString; if(`adskAssetListUI -q -materialLoaded`) { $createContentProc = "adskAssetListUI -uiCommand \"nodeTreeLister -e -add\" -commandSuffix \"" + $renderNodeTreeLister + "\""; eval $createContentProc; } // If there is a user initialize procedure defined, then call it if (`optionVar -exists "renderNodeTypeTreeInitializeUserProc"`) { string $userInitProcedure = `optionVar -query "renderNodeTreeInitializeUserProc"`; string $fname = renderCreateBarFavoritesFile(); // User procedure is called as: fn(treeListerName, favoritesFileName); // The procedure should populate the treeLister with items, and update the // favorites pathToStoredKey dict, as in done by addToRenderNodeTreeLister() // eval(($userInitProcedure + " " + $renderNodeTreeLister + "\"" + $fname + "\"")); } // Init treeLister renderCreateBarInitPopupMenu($renderNodeTreeLister); catch( renderCreateBarInitFavorites($renderNodeTreeLister) ); treeLister -e -expandToDepth 0 $renderNodeTreeLister; } global proc string createRenderNodeTreeLister(string $postCommand, string $filterString) // // Description: This procedure is to create a new treeLister for render nodes. // { // Create the nodeTreeLister and set its node library type (Hypershade is the default). string $renderNodeTreeLister = `nodeTreeLister -nodeLibrary "Hypershade"`; buildRenderNodeTreeListerContent($renderNodeTreeLister, $postCommand, $filterString); return $renderNodeTreeLister; } global proc refreshRenderNodeTreeLister(string $renderNodeTreeLister, string $postCommand, string $filterString) // // Description: This procedure is to refresh a render node treeLister // by clearing its contents and repopulating it. // { treeLister -e -clearContents $renderNodeTreeLister; buildRenderNodeTreeListerContent($renderNodeTreeLister, $postCommand, $filterString); } global proc string renderCreateBarUI( string $parentForm) { // // Description: // This procedure is called to build the UI on the left of the Hypershade // panel which allows the user to create new render nodes. // // Returns: // The name of the renderCreateBarUI that has been created. This name // should be stored and used later as an argument to other procedures in // this file which require it. // setParent $parentForm; string $renderCreateBarUI = `formLayout -manage false`; string $renderNodeTreeLister = createRenderNodeTreeLister("", ""); formLayout -edit -af $renderNodeTreeLister top 0 -af $renderNodeTreeLister left 0 -af $renderNodeTreeLister bottom 0 -af $renderNodeTreeLister right 0 $renderCreateBarUI; setParent ..; // from $renderCreateBarUI formLayout -edit -af $renderCreateBarUI top 0 -af $renderCreateBarUI bottom 0 -af $renderCreateBarUI left 0 -af $renderCreateBarUI right 0 $parentForm; // Now the formLayouts are created, we can fill in the content. // Calling the content creation after specifying how things are // attached to the the formLayout // give us the option of speeding up the content building process // by unmanaging the layout, create the content, then manage the // layout. // formLayout -edit -manage true $renderCreateBarUI; return $renderCreateBarUI; }