// =========================================================================== // 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: December 7/2000 // // Description: // // This file contains the procedures which implement a portable (can be // used anywhere) user interface for viewing a shading network (with // swatches) in a graphical layout. This file also contains the // procedures used to manipulate that user interface once it has been // created. // // --------------------------------------------------------------------------- // Special names and things like that // // "graphForm": the name of the form which contains the graph // source containerOperations.mel; // --------------------------------------------------------------------------- // Local procedures // global string $gGraphUILookupTable[]; global int $gGraphUILookupTableCreated = false; proc createGraphUILookupTable() { // // Description: // This procedure is called every time the user creates a graphUI // component, but only has any effect the first time it is called. // This procedure initializes the string array $gGraphUILookupTable[] // for use as a lookup table. The lookup table will contain information // about all graphUI components which exist in the current Maya // session. // global string $gGraphUILookupTable[]; global int $gGraphUILookupTableCreated; if (!$gGraphUILookupTableCreated) { string $columns[]; $columns[0] = "graphUI"; $columns[1] = "hypershadeName"; $columns[2] = "popupMenuScript"; lookupTable($gGraphUILookupTable, $columns); $gGraphUILookupTableCreated = true; } } proc registerGraphUI( string $graphUI) { // // Description: // This procedure is used to register a graphUI component by entering // it as a row in the lookup table which contains information about all // graphUI components that currently exist in Maya. // The row created is initially blank except for the graphUI name. // Further information about the graphUI component must be // subsequently added to the lookup table. // global string $gGraphUILookupTable[]; string $row[]; $row[0] = $graphUI; $row[1] = ""; $row[2] = ""; lookupTableAddRow($gGraphUILookupTable, $row); } proc registerHypershadeName( string $graphUI, string $hypershadeName) { // // Description: // This procedure associates the hypershadeName with the graphUI in // the lookup table. // global string $gGraphUILookupTable[]; // ASSUMPTION: // We assume that a row already exists for this graphUI, as it should // have been created by a call to registerGraphUI() as the UI was being // created. // lookupTableEdit( $gGraphUILookupTable, "graphUI", $graphUI, "hypershadeName", $hypershadeName); } proc string lookupHypershadeName( string $graphUI) { // // Description: // This procedure looks up the hypershade name associated with the // specified graphUI name in the lookup table. // // Returns: // The hypershade name, if one is associated with the specified // graph UI name. // Otherwise: "". // global string $gGraphUILookupTable[]; return (lookupTableLookup( $gGraphUILookupTable, "graphUI", $graphUI, "hypershadeName")); } proc string generateUniqueHypershadeName() { // // Description: // This procedure is usually called just before creating a new hypershade // for a graphUI. // This procedure generates a unique name for a hypershade by // creating a string of the form graph#HyperShadeEd and incrementing the # // part until no hypershade by that name exists. // // Returns: // A unique name by which a hypershade can be created. // int $i = 1; while (`hyperGraph -exists ("graph" + $i + "HyperShadeEd")`) { $i++; } return ("graph" + $i + "HyperShadeEd"); } // --------------------------------------------------------------------------- // Global procedures // global proc int graphUIIsManaged( string $graphUI) { // // Description: // This procedure is used to query whether the overall layout of the // specified graphUI component is managed or not. // // Returns: // This procedure returns true if the overall layout is managed, false if // not. // return `formLayout -query -manage $graphUI`; } global proc graphUIManage( string $graphUI, int $manage) { // // Description: // This procedure lets the caller manage or unmanage the overall layout of // the specified graphUI component. // formLayout -edit -manage $manage $graphUI; } global proc string graphUIPopupMenuScript( string $graphUI) { // // Description: // This procedure looks up the name of the popup menu script associated // with the specified graphUI component. // // Returns: // The name of the popup menu script. // // Lookup the name of the popup menu script in the lookup table // global string $gGraphUILookupTable[]; return lookupTableLookup( $gGraphUILookupTable, "graphUI", $graphUI, "popupMenuScript"); } global proc graphUISetPopupMenuScript( string $graphUI, string $scriptName) { // // Description: // This procedure sets the popup menu script which is invoked when the // user RMB clicks in the hyperShade element of the specified graphUI // component. The script will be called with two arguments: the name of // the hyperShade editor from which the menu was invoked, and the name of // the popupMenu object to which the menu items are to be added. // // If $scriptName is "", no popup menu will be invoked when the user RMB // clicks in the hyperShade editor. // // Find the name of the control that the menu will be attached to // string $hypershadeName = lookupHypershadeName($graphUI); string $parent = `hyperGraph -query -control $hypershadeName`; string $popupMenuName = ($hypershadeName + "PopupMenu"); if ($scriptName == "") { if (`popupMenu -exists $popupMenuName`) { deleteUI $popupMenuName; } } else { // Create the popup menu // if (!`popupMenu -exists $popupMenuName`) { string $fullMenuName ; $fullMenuName = `popupMenu -parent $parent -aob 1 -mm 1 $popupMenuName`; popupMenu -edit -allowOptionBoxes 1 -postMenuCommand ($scriptName + " " + $hypershadeName + " " + $popupMenuName) $fullMenuName; } } // Store the name of the popup menu script in the lookup table // // ASSUMPTION: // We assume that a row already exists for this graphUI, as it should // have been created by a call to registerGraphUI() as the UI was being // created. // global string $gGraphUILookupTable[]; lookupTableEdit( $gGraphUILookupTable, "graphUI", $graphUI, "popupMenuScript", $scriptName); } global proc graphUIClearGraph( string $graphUI) { // // Description: // Calling this method causes the hyperShade editor associated with the // specified graphUI component to be cleared. // string $hypershadeName = lookupHypershadeName($graphUI); hyperShade -reset $hypershadeName; // Make this hypershade a work area so that newly created nodes will appear // in it. // hyperShade -setWorkArea "Default" -dependGraphArea true $hypershadeName; } global proc graphUIRearrangeGraph( string $graphUI) { // // Description: // Calling this method causes the hyperShade editor associated with the // specified graphUI component to have its contents rearranged (to a // tidier arrangement). // string $hypershadeName = lookupHypershadeName($graphUI); hyperGraph -edit -layout -frameGraph $hypershadeName; } global proc string graphUIGetDisplayFlags() // // Description: // Checks the option vars that are set by the // "Options->Display" menu on the HyperShade, and // returns the hyperShade command flags that will // implement the desired behaviour. // { string $showShapes = ""; // figure out what type of shape display the user has // enabled (0=no shapes, 1=non-SG shapes, 2=all shapes). // Default to all shapes if the option var is not present. // if( !`optionVar -exists hsShapeDisplay` ) { optionVar -intValue hsShapeDisplay 2; } int $shapeDisplay = `optionVar -query hsShapeDisplay`; if( $shapeDisplay == 0 ) { // no shapes, so specify the no shapes flag // $showShapes = " -ns "; } else if( $shapeDisplay == 1 ) { // no SG-connected shapes // $showShapes = " -nsg "; } else if( $shapeDisplay == 2 ) { // all shapes (the default for the command) // $showShapes = ""; } // check for transform display (defaults to on) // if( !`optionVar -exists hsTransformDisplay` ) { optionVar -intValue hsTransformDisplay 1; } string $showTransforms = ""; if( `optionVar -query hsTransformDisplay` == 0) { $showTransforms = " -nt "; } // return concatenated command flags to display the desired stuff // string $showFlags = $showShapes + $showTransforms; return $showFlags; } proc removeUnwantedNodes(string $hypershadeName) { string $graphNodes[] = `hyperGraph -q -gnl $hypershadeName`; global string $gSoloShaderName; if (`stringArrayContains $gSoloShaderName $graphNodes`) { hyperGraph -edit -removeNode $gSoloShaderName $hypershadeName; } } global proc graphUIGraphMaterials( string $graphUI) { // // Description: // Calling this method causes the current graph in the hyperShade editor // associated with the specified graphUI component to be replaced with a // graph of the shading network applied to the currently selected object. // string $hypershadeName = lookupHypershadeName($graphUI); string $displayFlags = graphUIGetDisplayFlags(); eval( "hyperShade -shaderNetworks " + $displayFlags + $hypershadeName ); removeUnwantedNodes($hypershadeName); hyperGraph -edit -frameGraph $hypershadeName; } global proc graphUIShowUpstream( string $graphUI) { // // Description: // Calling this method causes the current graph in the hyperShade editor // associated with the specified graphUI component to be replaced with a // graph of the shading network upstream from the currently selected node. // string $hypershadeName = lookupHypershadeName($graphUI); if (`optionVar -query hsClearBeforeGraphing` == 1) { hyperShade -clearWorkArea $hypershadeName; } string $displayFlags = graphUIGetDisplayFlags(); eval( "hyperShade -networks " + $displayFlags + "-upStream " + $hypershadeName ); removeUnwantedNodes($hypershadeName); hyperGraph -edit -frameGraph $hypershadeName; } global proc graphUIShowDownstream( string $graphUI) { // // Description: // Calling this method causes the current graph in the hyperShade editor // associated with the specified graphUI component to be replaced with a // graph of the shading network downstream from the currently selected // node. // string $hypershadeName = lookupHypershadeName($graphUI); if (`optionVar -query hsClearBeforeGraphing` == 1) { hyperShade -clearWorkArea $hypershadeName; } string $displayFlags = graphUIGetDisplayFlags(); eval( "hyperShade -networks " + $displayFlags + "-downStream " + $hypershadeName ); removeUnwantedNodes($hypershadeName); hyperGraph -edit -frameGraph $hypershadeName; } global proc graphUIShowUpAndDownstream( string $graphUI) { // // Description: // Calling this method causes the current graph in the hyperShade editor // associated with the specified graphUI component to be replaced with a // graph of the shading network both upstream and downstream from the // currently selected node. // string $hypershadeName = lookupHypershadeName($graphUI); if (`optionVar -query hsClearBeforeGraphing` == 1) { hyperShade -clearWorkArea $hypershadeName; } string $displayFlags = graphUIGetDisplayFlags(); eval( "hyperShade -networks " + $displayFlags + "-upStream -downStream " + $hypershadeName ); removeUnwantedNodes($hypershadeName); hyperGraph -edit -frameGraph $hypershadeName; } global proc graphUIShowPreviousGraph( string $graphUI) { // // Description: // Each hypergraph keeps a stack of graphs in memory. Every time the user // graphs a network, that new graph gets pushed onto the stack. // Calling this method causes the current graph to be replaced with the // graph which is below the current one in the stack of graphs in memory. // string $hypershadeName = lookupHypershadeName($graphUI); hyperGraph -edit -backward $hypershadeName; } global proc graphUIShowNextGraph( string $graphUI) { // // Description: // Each hypergraph keeps a stack of graphs in memory. Every time the user // graphs a network, that new graph gets pushed onto the stack. // Calling this method causes the current graph to be replaced with the // graph which is above the current one in the stack of graphs in memory. // string $hypershadeName = lookupHypershadeName($graphUI); hyperGraph -edit -forward $hypershadeName; } global proc graphUIAddSelected( string $graphUI) { // // Description: // Calling this method causes the currently selected nodes to be added to // the contents of the hyperShade editor associated with the specified // graphUI component. // string $hypershadeName = lookupHypershadeName($graphUI); string $nodeArray[] = `ls -dependencyNodes -selection`; int $i; for ($i = 0; $i < size($nodeArray); $i++) { hyperGraph -edit -addDependNode $nodeArray[$i] $hypershadeName; } } global proc graphUIRemoveSelected( string $graphUI) { // // Description: // Calling this method causes the currently selected nodes to be removed // from the contents of the hyperShade editor associated with the // specified graphUI component. // string $hypershadeName = lookupHypershadeName($graphUI); string $graphNodes[] = `hyperGraph -q -gnl $hypershadeName`; string $nodeArray[] = `ls -dependencyNodes -selection`; int $i; for ($i = 0; $i < size($nodeArray); $i++) { if (`stringArrayContains $nodeArray[$i] $graphNodes`) { hyperGraph -edit -removeNode $nodeArray[$i] $hypershadeName; } } } global proc graphUICreateContainer( string $graphUI ) { // Description: // Calling this method causes the currently selected gadgets to // be grouped into a container. // int $incShaders = `optionVar -q containerIncludeShaders`; optionVar -intValue containerIncludeShaders 1; CreateContainer; optionVar -intValue containerIncludeShaders $incShaders; } global proc graphUIRemoveContainer( string $graphUI ) { // Description: // Calling this method causes the currently selected containers // to be unpacked and removed from the scene // unpackAndRemoveContainer(`ls -sl -containers`); } global proc graphUICollapseContainer( string $graphUI ) { // Description: // Calling this method causes the currently selected // collapsable folder node gadgets to collapse if it is not // collapsed. // string $hypershadeName = lookupHypershadeName($graphUI); hyperGraph -edit -collapseContainer $hypershadeName; } global proc graphUIExpandContainer( string $graphUI ) { // Description: // Calling this method causes the currently selected // collapsed folder node gadgets to uncollapse if it is // collapsed. // string $hypershadeName = lookupHypershadeName($graphUI); hyperGraph -edit -expandContainer $hypershadeName; } global proc string graphUIHypershadeName( string $graphUI) { // // Description: // This procedure returns the name of the hyperShade editor associated // with the specified graphUI component. // return (lookupHypershadeName($graphUI)); } // --------------------------------------------------------------------------- // Procedures for creating and deleting a graph UI // global proc graphUIDelete( string $graphUI, int $alsoDeleteHypershade) { if (!$alsoDeleteHypershade) { // The caller has asked us not to delete the hypershade object along // with the UI, so we unparent it from the UI before we delete the UI. // string $hypershadeName = lookupHypershadeName($graphUI); hyperGraph -edit -unParent $hypershadeName; } deleteUI $graphUI; } global proc string graphUI( string $parentFormLayout, string $hypershadeName) { // // Description: // This procedure is called from any piece of UI which wants to create a // graph UI within itself. // This procedure creates the graph UI. // If the stateDescription is specified, this code will use it to create // a UI with the characteristics described therein. // In particular, this is designed to allow the graph UI to be moved from // layout to layout without dramatically changing its appearance. // Otherwise (if no stateDescription is provided), new UI is created with // the default configuration. // // Returns: // This method returns the name of the UI which should be stored by the // caller for later use in performing operations on the graph UI. // // Create the lookup table if it does not already exist. // createGraphUILookupTable(); int $newHypershadeCreated = false; if ($hypershadeName == "") { $hypershadeName = generateUniqueHypershadeName(); hyperGraph -unParent $hypershadeName; hyperUserInit($hypershadeName); $newHypershadeCreated = true; } string $graphUI; int $iconSize = 26; $graphUI = `formLayout graph`; // Register the graphUI in the lookup table // registerGraphUI($graphUI); registerHypershadeName($graphUI, $hypershadeName); setParent ..; // from $graphUI formLayout -edit -af $graphUI top 0 -af $graphUI bottom 0 -af $graphUI left 0 -af $graphUI right 0 $parentFormLayout; string $oldParent = `setParent -q`; setParent $graphUI; hyperGraph -edit -parent $graphUI $hypershadeName; formLayout -edit -af $hypershadeName top 0 -af $hypershadeName bottom 0 -af $hypershadeName left 0 -af $hypershadeName right 0 $graphUI; setParent $oldParent; if ($newHypershadeCreated) { // Make this hypershade a work area so that newly created nodes will // appear in it. // hyperShade -setWorkArea "Default" -dependGraphArea true $hypershadeName; } return $graphUI; }