// =========================================================================== // 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: // AEpsdFileTemplate // // Description Name; // Creates the attribute editor controls for the file Node // // Input Value: // nodeName // // Output Value: // None // global int $psdFileNameChangeJob = -1 ; global proc AEpsdTreeViewDblClick( string $label ) { // Disallow editing the layer names. The presence of this callback // disables the default renaming function. } global proc string AEpsdAddTreeViewItem( string $tree, string $item, string $itemParent ) { string $name = $item; int $id = 1; // treeView must have unique item names, while PSD files do not // enforce that restriction. To resolve, add a numeric ID to the // end of the name and store the original name in the annotation while( `treeView -q -itemExists $name $tree` ) { $name = $item + " " + $id; $id++; } treeView -e -addItem $name $itemParent $tree; treeView -e -itemAnnotation $name $item $tree; return $name; } global proc AEpsdAddLayerSetMenuItems( string $fileNode, string $linkLayerTree ) { string $layerSetNames[] = `getAttr ($fileNode + ".layerSets")` ; int $layerDepths[] = `getAttr ($fileNode + ".layerDepths")` ; string $layerName = `getAttr ($fileNode + ".layerSetName")` ; // Clear the tree view treeView -e -ra $linkLayerTree; AEpsdAddTreeViewItem( $linkLayerTree, (uiRes("m_AEpsdFileTexTemplate.kComposite")), "" ); treeView -e -selectItem (uiRes("m_AEpsdFileTexTemplate.kComposite")) 1 $linkLayerTree; string $currentLayerSet = "Composite" ; if( size( $layerSetNames ) == 0) { if ($currentLayerSet != $layerName) { // add a bogus item for data preservation purposes in the // case of a broken file reference. $currentLayerSet = $layerName; AEpsdAddTreeViewItem( $linkLayerTree, $layerName, "" ); treeView -e -selectItem $layerName 1 $linkLayerTree; } treeView -e -enable false $linkLayerTree; } else { //add new layer set name in tree view. string $currParent = ""; int $index, $parentCount = 0; // use a stack to record the current parent and use // the offset in depth to return a previous parent string $parentList[]; string $updatedName; for ( $index = size($layerSetNames)-1; $index >= 0; $index-- ) { string $layer = $layerSetNames[$index]; int $currDepth = $layerDepths[$index]; string $prevLayer = ""; int $prevDepth = 0; if( $index < size($layerSetNames)-1 ) { $prevLayer = $layerSetNames[$index+1]; $prevDepth = $layerDepths[$index+1]; } if( $currDepth > $prevDepth ) { // if current depth is more than previous depth, // add current parent onto the stack $currParent = $prevLayer; $parentList[$parentCount]=$currParent; $parentCount++; // record updated name, since if there are same names, a numericID will // be added behind the actual name in UI. $updatedName = AEpsdAddTreeViewItem( $linkLayerTree, $layer, $currParent ); } else if( $currDepth < $prevDepth ) { // if current depth is less than previous depth, // pop $offset off the stack and current parent will be the end of the stack int $offset = $prevDepth - $currDepth; $parentCount = $parentCount - $offset; string $tempParentList[]; int $ind; if ($parentCount == 0) { $currParent = ""; clear($parentList); } else { // Pop $offset off the parentList, current parent will be the end of the stack for ( $ind = $parentCount -1; $ind >= 0; $ind--) { $tempParentList[$ind] = $parentList[$ind]; } clear($parentList); $parentList = $tempParentList; $currParent = $parentList[$parentCount - 1]; } $updatedName = AEpsdAddTreeViewItem( $linkLayerTree, $layer, $currParent ); } else if( $currDepth == $prevDepth ) { // if curent depth is equal to previous depth, // do nothing other than updating the added item name $updatedName = AEpsdAddTreeViewItem( $linkLayerTree, $layer, $currParent ); } $layerSetNames[$index] = $updatedName; if( $layer == $layerName ) { treeView -e -cs $linkLayerTree; treeView -e -selectItem $layerName 1 $linkLayerTree; $currentLayerSet = $layerName; } } treeView -e -showItem $currentLayerSet $linkLayerTree; treeView -e -en 1 $linkLayerTree; } // set the layer set name, it can be "composite" or the current layer set name if found in the file setAttr -type "string" ($fileNode + ".layerSetName") $currentLayerSet ; } global proc AEpsdAddAlphaToUseMenuItems( string $fileNode, string $alphaToUseMenu ) { string $alphaList[] = `getAttr ($fileNode + ".alphaList")` ; string $alphaName = `getAttr ($fileNode + ".alpha")` ; if( ! `menuItem -exists ($alphaToUseMenu + "|alphaAEdefault")` ) menuItem -label (uiRes("m_AEpsdFileTexTemplate.kDefault")) -parent $alphaToUseMenu "alphaAEdefault" ; // select "Default" item optionMenu -e -select 1 $alphaToUseMenu ; string $currentAlpha = "Default" ; int $index = 0 ; //delete previous menu items. while ( `menuItem -exists ($alphaToUseMenu + "|alphaAE" + $index)` ) { deleteUI ("alphaAE" + $index) ; ++$index ; } optionMenu -e -select 1 $alphaToUseMenu ; if ( size( $alphaList ) == 0 ) { if ($currentAlpha != $alphaName) { // add a bogus item for data preservation purposes in the // case of a broken file reference. $currentAlpha = $alphaName; menuItem -label $alphaName -parent $alphaToUseMenu "alphaAE0" ; optionMenu -e -select 2 $alphaToUseMenu ; } //editorTemplate -dimControl $fileNode $alphaToUseMenu true ; optionMenu -e -enable false $alphaToUseMenu ; } else { //add new ones. for ( $index = 0 ; $index < size( $alphaList ) ; ++$index ) { string $alpha = $alphaList[ $index ] ; menuItem -l $alpha -parent $alphaToUseMenu ("alphaAE" + $index) ; if( $alpha == $alphaName ) { optionMenu -e -select ($index + 2) $alphaToUseMenu ; $currentAlpha = $alpha ; } } //editorTemplate -dimControl $fileNode $alphaToUseMenu false; optionMenu -e -enable true $alphaToUseMenu ; } // set the alpha name, it can be "Default" or the current alpha name if found in the file setAttr -type "string" ($fileNode + ".alpha") $currentAlpha ; } global proc AEpsdFileTextureNameChanged( string $fileNode) { // // Description: // This procedure is called from AEassignTextureCB. // If the newly chosen file has an alpha channel, this procedure hooks up // the outTransparency attribute of the file node to the transparency // attribute of materials which are using this file for color, where // appropriate. // if (`getAttr ($fileNode + ".fileHasAlpha")` == 1) { // // The newly chosen file has an alpha channel. // string $dstNodeArray[]; $dstNodeArray = `listConnections -source false -destination true ($fileNode + ".outColor")`; string $dstNode; for ($dstNode in $dstNodeArray) { if( $dstNode == "swatchShadingGroup" ) { // a temporary node/attribute connection used for swatch updation which // might have been deleted, hence do not re-connect it. // continue; } string $type = `nodeType $dstNode`; if ( (isClassified($dstNode, "shader")) && (size(`ls ($dstNode + ".transparency")`) != 0) && (size(`ls ($dstNode + ".color")`) != 0) && (`isConnected ($fileNode+".outColor") ($dstNode+".color")`) && (size(`listConnections -source true -destination false ($dstNode + ".transparency")`) == 0)) { // The dstNode is a material or projection utility, // and it has a transparency attribute, // and it has a color attribute, // and the file node outColor is connected to the material // color, // and that transparency attribute is not currently the // destination of any connection. // We want to connect this file node's outTransparency to // the dstNode's transparency. // connectAttr ($fileNode + ".outTransparency") ($dstNode + ".transparency"); } else if( (strcmp($type, "projection") == 0) && (size(`ls ($dstNode + ".transparency")`) != 0) && (size(`ls ($dstNode + ".image")`) != 0) && (`isConnected ($fileNode+".outColor") ($dstNode+".image")`) && (size(`listConnections -source true -destination false ($dstNode + ".transparency")`) == 0)) { connectAttr ($fileNode + ".outTransparency") ($dstNode + ".transparency"); string $projDstNodeArray[]; $projDstNodeArray = `listConnections -source false -destination true ($dstNode + ".outColor")`; string $projDstNode; for($projDstNode in $projDstNodeArray) { if ( (isClassified($projDstNode, "shader")) && (size(`ls ($projDstNode + ".transparency")`) != 0) && (size(`ls ($projDstNode + ".color")`) != 0) && (`isConnected ($dstNode+".outColor") ($projDstNode+".color")`) && (size(`listConnections -source true -destination false ($projDstNode + ".transparency")`) == 0)) { connectAttr ($dstNode + ".outTransparency") ($projDstNode + ".transparency"); } } } } } } // // Procedure Name: // AEassignTextureCB // global proc int AEassignTextureCB( string $fileAttribute, string $filename, string $fileType ) { // // Description: // This procedure is called when the user changes the file texture name in // the edit box in the file texture attribute editor (whether by manually // typing it in, or by using the file browser to choose a new file). // // This procedure updates the file texture node file name attribute and // calls AEpsdFileTextureNameChanged to do some special case handling for // files with alpha channels. // setAttr $fileAttribute -type "string" $filename; string $currentDir = `workspace -q -dir`; retainWorkingDirectory ($currentDir); // Extract the name of the node from the node.attribute name // string $tokenArray[]; tokenize($fileAttribute, ".", $tokenArray); string $fileNode = $tokenArray[0]; AEpsdFileTextureNameChanged($fileNode); return true; } // // Procedure Name: // AEpsdFileTextureBrowser // global proc AEpsdFileTextureBrowser( string $cmd ) { string $workspace = `workspace -q -fn`; setWorkingDirectory $workspace "image" "sourceImages"; fileBrowser ($cmd, (uiRes("m_AEpsdFileTexTemplate.kOpen")), "Photoshop", 0); } // // Procedure Name: // AEpsdFileTextureNameNew // global proc AEpsdFileTextureNameNew (string $fileAttribute) { setUITemplate -pst attributeEditorTemplate; rowLayout -nc 3 textureNameLayout; text -label (uiRes("m_AEpsdFileTexTemplate.kImageName")); textField textureNameField; symbolButton -image "navButtonBrowse.png" browser; setParent ..; setUITemplate -ppt; AEpsdFileTextureNameReplace $fileAttribute; } // // Procedure Name: // AEpsdFileTextureNameReplace // global proc AEpsdFileTextureNameReplace (string $fileAttribute) { global int $psdFileNameChangeJob ; string $parent = `setParent -q`; connectControl -fileName textureNameField $fileAttribute; string $command = "AEassignTextureCB "+" "+$fileAttribute; button -e -c ("AEpsdFileTextureBrowser \"" + $command + "\"" ) browser; string $tokenArray[]; tokenize($fileAttribute, ".", $tokenArray); string $fileNode = $tokenArray[0]; // kill the previous script job if one was created if( $psdFileNameChangeJob >= 0 && `scriptJob -exists $psdFileNameChangeJob` ) { scriptJob -kill $psdFileNameChangeJob ; } // these jobs are required to handle file names changes // by user typing the name of the file in the edit box. string $cmd = "AEpsdAddLayerSetMenuItems " + $fileNode + " linkLayerSetTree;" ; $cmd += "AEpsdAddAlphaToUseMenuItems " + $fileNode + " alphaToUseMenu;" ; $cmd += "AEpsdFileTextureNameChanged " + $fileNode + ";" ; $psdFileNameChangeJob = `scriptJob -attributeChange $fileAttribute $cmd`; } global proc AEpsdLinkLayerSetToTexture(string $layerSetAttr, string $linkLayerTree) { string $selected[] = `treeView -q -selectItem $linkLayerTree` ; string $layerSet = `treeView -q -item $selected[0] -ia $linkLayerTree`; string $tokenArray[]; tokenize($layerSetAttr, ".", $tokenArray); string $fileNode = $tokenArray[0]; //The "Composite" item label may be localized in the UI, but must not be //localized for the attribute value in order to ensure //scene file compatibility. if ($layerSet == (uiRes("m_AEpsdFileTexTemplate.kComposite"))) { $layerSet = "Composite"; } setAttr -type "string" $layerSetAttr $layerSet ; if (`getAttr ($fileNode + ".fileHasAlpha")` == 1) { // we can connect the outTransparency to shader // OR // connect outAlpha to the layered texture input. AEpsdFileTextureNameChanged( $fileNode ); } } global proc AEpsdAlphaToUse(string $alphaList, string $alphaToUseMenu) { string $alpha = `optionMenu -q -value $alphaToUseMenu` ; string $tokenArray[]; tokenize($alphaList, ".", $tokenArray); string $fileNode = $tokenArray[0]; //The "Default" item label may be localized in the UI, but must not be //localized for the attribute value in order to ensure //scene file compatibility. if ($alpha == (uiRes("m_AEpsdFileTexTemplate.kDefault"))) { $alpha = "Default"; } setAttr -type "string" $alphaList $alpha ; } global proc AEpsdFileTextureLayerSets(string $layerSets) { setUITemplate -pst attributeEditorTemplate; string $parent = `setParent -q`; string $linkLayerSetForm = $parent + "|linkLayerSetLayout|linkLayerSetTreeForm"; string $linkLayerSetTree = $linkLayerSetForm + "|linkLayerSetTree"; rowLayout -nc 2 linkLayerSetLayout; text -label (uiRes("m_AEpsdFileTexTemplate.kLinkToLayer")) linkLayerLabel; formLayout -h 240 -w 100 linkLayerSetTreeForm; treeView -numberOfButtons 0 -ams false -abr false -adr false -arp false -scc ("AEpsdLinkLayerSetToTexture " + $layerSets + " " + $linkLayerSetTree) -idc ("AEpsdTreeViewDblClick") linkLayerSetTree; setParent ..; setParent ..; formLayout -e -attachForm $linkLayerSetTree "top" 0 -attachForm $linkLayerSetTree "bottom" 0 -attachForm $linkLayerSetTree "left" 0 -attachForm $linkLayerSetTree "right" 0 $linkLayerSetForm; setUITemplate -ppt; AEpsdFileTextureLayerSetsReplace $layerSets ; } global proc AEpsdFileTextureAlphaList(string $alphaList) { setUITemplate -pst attributeEditorTemplate; string $parent = `setParent -q`; string $alphaToUseMenu = $parent + "|alphaToUseLayout|alphaToUseMenu"; rowLayout -nc 2 alphaToUseLayout; text -label (uiRes("m_AEpsdFileTexTemplate.kAlphaToUse")); optionMenu -label "" -cc ("AEpsdAlphaToUse " + $alphaList + " " + $alphaToUseMenu) alphaToUseMenu; setParent ..; setUITemplate -ppt; AEpsdFileTextureAlphaListReplace $alphaList ; } global proc AEpsdFileTextureLayerSetsReplace(string $layerSetNameAttr) { string $tokenArray[]; tokenize($layerSetNameAttr, ".", $tokenArray); string $fileNode = $tokenArray[0]; string $parent = `setParent -q`; string $layerSetTree = $parent + "|linkLayerSetLayout|linkLayerSetTreeForm|linkLayerSetTree"; treeView -e -en 1 -scc ("AEpsdLinkLayerSetToTexture " + $layerSetNameAttr + " " + $layerSetTree) $layerSetTree; AEpsdAddLayerSetMenuItems( $fileNode, $layerSetTree ) ; } global proc AEpsdFileTextureAlphaListReplace(string $alphaList) { string $tokenArray[]; tokenize($alphaList, ".", $tokenArray); string $fileNode = $tokenArray[0]; string $parent = `setParent -q`; string $alphaToUseMenu = $parent + "|alphaToUseLayout|alphaToUseMenu"; editorTemplate -dimControl $fileNode $alphaToUseMenu true ; optionMenu -e -cc ("AEpsdAlphaToUse " + $alphaList + " " + $alphaToUseMenu) $alphaToUseMenu; AEpsdAddAlphaToUseMenuItems( $fileNode, $alphaToUseMenu ) ; } global proc AEpsdCheckUseHardwareTextureCycling ( string $nodeName ) { string $nodeAttr = $nodeName + ".useHardwareTextureCycling"; int $value = `getAttr $nodeAttr`; if ( $value == 1 ) { editorTemplate -dimControl $nodeName "startCycleExtension" false; editorTemplate -dimControl $nodeName "endCycleExtension" false; editorTemplate -dimControl $nodeName "byCycleIncrement" false; } else { editorTemplate -dimControl $nodeName "startCycleExtension" true; editorTemplate -dimControl $nodeName "endCycleExtension" true; editorTemplate -dimControl $nodeName "byCycleIncrement" true; } } // // Procedure Name: // checkFilterType // global proc checkFilterType ( string $nodeName ) { string $nodeAttr = $nodeName + ".filterType"; int $filter = `getAttr $nodeAttr`; if ($filter == 0) { editorTemplate -dimControl $nodeName "filter" true; editorTemplate -dimControl $nodeName "filterOffset" true; } else { editorTemplate -dimControl $nodeName "filter" false; editorTemplate -dimControl $nodeName "filterOffset" false; } // if ($filter == 1) // editorTemplate -dimControl $nodeName "useMaximumRes" false; // else // editorTemplate -dimControl $nodeName "useMaximumRes" true; } // // File Texture Reload functions // global proc AEpsdFileTextureReload (string $ftn) { setUITemplate -pst attributeEditorTemplate; rowLayout -nc 5 -cl5 "center" "center" "center" "center" "center"; text -label ""; button -label (uiRes("m_AEpsdFileTexTemplate.kReload")) psdFileReloadBtn; button -label (uiRes("m_AEpsdFileTexTemplate.kEdit")) psdFileEditBtn; button -label (uiRes("m_AEpsdFileTexTemplate.kView")) psdFileViewBtn; text -label ""; setParent ..; setUITemplate -ppt; AEpsdFileTextureReloadReplace($ftn); } global proc AEpsdFileTextureReloadReplace (string $ftn) { button -e -c ("AEpsdFileTextureReloadCmd " + $ftn) psdFileReloadBtn; button -e -c ("AEpsdFileTextureEditCmd " + $ftn) psdFileEditBtn; button -e -c ("AEpsdFileTextureViewCmd " + $ftn) psdFileViewBtn; } global proc AEpsdFileTextureReloadCmd (string $ftn) { string $currFile = `getAttr $ftn`; if ($currFile != "") { int $i; string $allTextures[] = `ls -typ file`; // this loop is needed to guarantee all texture nodes who // reference this file gets updated. for ($i = 0; $i < size($allTextures); $i++) { string $ithFile = `getAttr ($allTextures[$i] + ".ftn")`; if ($ithFile == $currFile) setAttr ($allTextures[$i] + ".ftn") -type "string" $currFile; } } } global proc AEpsdFileTextureEditCmd (string $ftn) { string $currFile = `getAttr $ftn`; if (`filetest -f $currFile`) { launchImageEditor -eif $currFile; } } global proc AEpsdFileTextureViewCmd (string $ftn) { string $currFile = `getAttr $ftn`; if (`filetest -f $currFile`) { launchImageEditor -vif $currFile; } } // // Prefilter settings // global proc checkPreFilter ( string $nodeName ) { string $nodeAttr = $nodeName + ".preFilter"; int $value = `getAttr $nodeAttr`; if ( $value == 1 ) { editorTemplate -dimControl $nodeName "preFilterRadius" false; } else { editorTemplate -dimControl $nodeName "preFilterRadius" true; } } // // Procedure Name: // AEpsdFileTemplate // global proc AEpsdFileTexTemplate ( string $nodeName ) { AEswatchDisplay $nodeName; editorTemplate -beginScrollLayout; editorTemplate -beginLayout (uiRes("m_AEpsdFileTexTemplate.kFileAttr")) -collapse 0; editorTemplate -addControl "filterType" "checkFilterType"; editorTemplate -addControl "preFilter" "checkPreFilter"; editorTemplate -addControl "preFilterRadius"; editorTemplate -addSeparator; editorTemplate -callCustom "AEpsdFileTextureNameNew" "AEpsdFileTextureNameReplace" "fileTextureName"; editorTemplate -callCustom "AEpsdFileTextureReload" "AEpsdFileTextureReloadReplace" "fileTextureName"; editorTemplate -addSeparator; editorTemplate -callCustom "AEpsdFileTextureLayerSets" "AEpsdFileTextureLayerSetsReplace" "layerSetName" ; editorTemplate -callCustom "AEpsdFileTextureAlphaList" "AEpsdFileTextureAlphaListReplace" "alpha" ; editorTemplate -suppress "layerSets" ; editorTemplate -suppress "layerDepths" ; editorTemplate -suppress "alphaList" ; editorTemplate -suppress "filterWidth"; editorTemplate -beginNoOptimize; editorTemplate -suppress "useMaximumRes"; editorTemplate -addControl "useCache"; editorTemplate -addControl "disableFileLoad"; editorTemplate -label (uiRes("m_AEpsdFileTexTemplate.kUseImageSequence")) -addControl "useFrameExtension" "checkUseFrameExtension"; editorTemplate -endNoOptimize; editorTemplate -label (uiRes("m_AEpsdFileTexTemplate.kImageNumber")) -addControl "frameExtension"; editorTemplate -addControl "frameOffset"; editorTemplate -endLayout; editorTemplate -beginLayout (uiRes("m_AEpsdFileTexTemplate.kHardwareTextureCyclingOptions")); editorTemplate -addControl "useHardwareTextureCycling" "AEpsdCheckUseHardwareTextureCycling"; editorTemplate -addControl "startCycleExtension"; editorTemplate -addControl "endCycleExtension"; editorTemplate -addControl "byCycleIncrement"; editorTemplate -endLayout; // suppressed attributes editorTemplate -suppress "noiseUV"; // ADSK_CLR_MGT_BEGIN editorTemplate -suppress "exposure"; // ADSK_CLR_MGT_END editorTemplate -suppress "uvTilingMode"; editorTemplate -suppress "explicitUvTiles"; editorTemplate -suppress "baseExplicitUvTilePosition"; editorTemplate -suppress "uvTileProxyQuality"; editorTemplate -suppress "ptexFilterType"; editorTemplate -suppress "ptexFilterWidth"; editorTemplate -suppress "ptexFilterBlur"; editorTemplate -suppress "ptexFilterSharpness"; editorTemplate -suppress "ptexFilterInterpolateLevels"; editorTemplate -suppress "colorProfile"; // include/call base class/node attributes AEtexture2dCommon $nodeName; editorTemplate -addExtraControls; editorTemplate -endScrollLayout; }