// =========================================================================== // 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. // =========================================================================== // // hikCustomRigOperations.mel // // Description: // Contains methods that perform custom rig operations. // These methods could trigger UI updates in any part of the // unified character context. // /////////////////////////////////////////////////////////////////// // Local Methods... /////////////////////////////////////////////////////////////////// proc int isReferenced( string $character ) { if ( size( $character ) == false || objExists( $character ) == false ) return false; return ( `referenceQuery -isNodeReferenced $character` ) ? true : false ; } proc string getFilters() { string $xml = (uiRes("m_hikCustomRigOperations.kXml")); string $all = (uiRes("m_hikCustomRigOperations.kAll")); return ( $xml + " (*.xml);;" + $all + " (*.*)" ); } /////////////////////////////////////////////////////////////////// // Global Methods... /////////////////////////////////////////////////////////////////// global proc hikCreateCustomRig( string $character ) { if( hikHasCustomRig($character) ) { warning( (uiRes("m_hikCustomRigOperations.kAlreadyHaveCustomRig"))); return; } //if we don't have a definition, prompt user to create one if( !hikHasDefinition($character) ) { string $define = ( uiRes( "m_hikGlobalUtils.kDefine" ) ); string $cancel = ( uiRes( "m_hikGlobalUtils.kCancel" ) ); string $result = `confirmDialog -title ( uiRes( "m_hikGlobalUtils.kCustomRig" ) ) -message (uiRes("m_hikCustomRigOperations.kNoDefinitionCreateOrDefine")) -button $define -button $cancel -defaultButton $define -cancelButton $cancel -dismissString $cancel`; if( $result == $define ) { hikCreateDefinition(); hikSelectControlRigTab(); } return; } // Attempt to lock the definition automatically. If we could not, // lower level method will raise confirmDialog if( !hikCheckDefinitionLocked($character) ) { hikSelectControlRigTab(); return; } // If no valid characterization exists, tell the user to create one if ( hikIsCharacterizationInValidOrWarningState() == false ) { confirmDialog -title (uiRes("m_hikCustomRigOperations.kConfirmDialogTitle")) -message (uiRes("m_hikCustomRigOperations.kConfirmDialogMessage")) -button ( uiRes( "m_hikGlobalUtils.kCancel" ) ) -cancelButton ( uiRes( "m_hikGlobalUtils.kCancel" ) ) -dismissString ( uiRes( "m_hikGlobalUtils.kCancel" ) ) ; return; } // Turn on the wait cursor. waitCursor -state 1; string $retargeter = RetargeterCreate( $character ); select -cl; hikUpdateCustomRigUI; hikSelectCustomRigTab; hikUpdateSourceList; hikUpdateCharacterList; // Turn off the wait cursor. waitCursor -state 0; } global proc hikDeleteCustomRig( string $character ) { if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceDeleteRigWarning")); return; } string $ok = ( uiRes( "m_hikGlobalUtils.kOK" ) ); string $cancel = ( uiRes( "m_hikGlobalUtils.kCancel" ) ); string $result = `confirmDialog -title (uiRes("m_hikCustomRigOperations.kDeleteHikSkeleton")) -message (uiRes("m_hikCustomRigOperations.kAreYouSureMsg")) -button $ok -button $cancel -defaultButton $ok -cancelButton $cancel -dismissString $cancel`; if ( $result != $ok ) return; string $retargeter = RetargeterGetName( $character ); if ( RetargeterExists( $retargeter ) ) hikCustomRigRemoveRetargeter( $retargeter ); // Remove the node that is created and connected with the CustomRigRetargeterNode string $lGlobal2SkNode = hikGetStateToGlobalSk( $character, 0 ); if( $lGlobal2SkNode != "" ) { delete $lGlobal2SkNode; } hikSetCurrentSource ""; hikUpdateSourceList; hikSelectControlRigTab; hikUpdateCharacterList; // we are also changing the current tab hikOnSwitchContextualTabs( ); } global proc hikImportCustomRigMapping( string $character ) { if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceImportRigWarning")); return; } string $filters = getFilters(); string $filename[] = `fileDialog2 -fileMode 1 -dialogStyle 2 -fileFilter $filters -caption (uiRes("m_hikCustomRigOperations.kImportCustomRigFile"))`; if ( size($filename) != 1 ) return; string $retargeter = RetargeterGetName( $character ); if( RetargeterReadFromFile( $retargeter, $filename[0] ) == false ) return; int $index, $indices[] = RetargeterAssignedElementIndices( $retargeter ); string $bodies[]; for( $index in $indices ) $bodies[$index] = hikCustomRigElementNameFromId( $character, $index ); RetargeterRemoveInvalidMappings( $retargeter, $bodies ); hikUpdateCustomRigUI; } global proc hikExportCustomRigMapping( string $character ) { string $filters = getFilters(); string $filename[] = `fileDialog2 -fileMode 0 -dialogStyle 2 -fileFilter $filters -caption (uiRes("m_hikCustomRigOperations.kExportCustomRigFile"))`; if ( size($filename) != 1 ) return; string $retargeter = RetargeterGetName( $character ); RetargeterWriteToFile( $retargeter, $filename[0] ); } global proc hikCustomRigAddRemoveMapping( string $type, int $state ) { // If no HIK Custom Rig widget is shown bail if ( `workspaceControl -exists hikCharacterControlsDock` == false ) return; string $character = hikGetCurrentCharacter(); if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceAddRemoveRigWarning")); return; } // If there is nothing selected in the CustomRigToolWidget bail int $inx = `hikCustomRigToolWidget -q -sl`; if ( $inx == -1 ) return; // If the selected id does not corresponds to a valid name bail string $body = hikCustomRigElementNameFromId( $character, $inx ); if ( size( $body ) == 0 ) { print (uiRes( "m_hikCustomRigOperations.kInvalidIndex" )); return; } hikSetCustomRigMapMode( $type, $state ); hikEnableCustomRigSliders( $type, $state ); string $retargeter = RetargeterGetName( $character ); // If state = 1, create the mapping of the specified type if ( $state ) RetargeterAddMapping( $retargeter, $body, $type, "", $inx ); else { // otherwise, remove it. RetargeterDeleteMapping( $retargeter, $body, $type ); // If there are no mappings left after the removal, this needs to be reflected in the UI if ( RetargeterHasMapping( $retargeter, $body ) == false ) { hikCustomRigClearMapping( $inx ); hikCustomRigToolWidget -e -sl -1; } } // Update the UI to reflect changes hikUpdateCustomRigUI; } global proc hikCustomRigAssignEffector( int $inx ) { string $selections[] = `ls -selection`; if ( size($selections) != 1 ) { warning (uiRes("m_hikCustomRigOperations.kNothingSelected")); return; } string $dest = $selections[0]; string $body = hikCustomRigElementNameFromId( hikGetCurrentCharacter(), $inx ); if ( size( $body ) == 0 ) { print (uiRes("m_hikCustomRigOperations.kInvalidIndex")); return; } string $character = hikGetCurrentCharacter(); if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceAssignRigWarning")); return; } string $retargeter = RetargeterGetName( $character ); int $success = 0; // Depending on the type of element selected at the UI, enable different mappings // Validation checks whether the setting attribute(s) is a valid operation and returns // 0 for none, 1 for rotation valid, 2 for translation valid, 3 for both valid string $type = hikCustomRigElementTypeFromId( $inx ); switch( $type ) { case "button": $success = RetargeterValidateMapping( $retargeter, $body, "TR", $dest ); if( $success == 0 ) return; if( $success == 1 || $success == 3 ) RetargeterAddMapping( $retargeter, $body, "R", $dest, $inx ); if( $success == 2 || $success == 3 ) RetargeterAddMapping( $retargeter, $body, "T", $dest, $inx ); break; case "fk": $success = RetargeterValidateMapping( $retargeter, $body, "R", $dest ); if( $success != 1 && $success != 3 ) return; RetargeterAddMapping( $retargeter, $body, "R", $dest, $inx ); break; default: $success = RetargeterValidateMapping( $retargeter, $body, "T", $dest ); if( $success != 2 && $success != 3 ) return; RetargeterAddMapping( $retargeter, $body, "T", $dest, $inx ); break; } hikUpdateCustomRigAssignedMappings $character; hikCustomRigToolWidget -e -sl $inx; hikUpdateCustomRigUI; } global proc hikCustomRigClearMapping( int $inx ) { string $character = hikGetCurrentCharacter(); if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceClearRigWarning")); return; } string $retargeter = RetargeterGetName( $character ); if ( $inx < 0 || RetargeterExists( $retargeter ) == false ) return; string $body = hikCustomRigElementNameFromId( $character, $inx ); if ( size( $body ) == 0 ) { print ( uiRes( "m_hikCustomRigOperations.kInvalidIndex" ) ); return; } RetargeterDeleteMapping( $retargeter, $body, "T" ); RetargeterDeleteMapping( $retargeter, $body, "R" ); // Query the widget for the set of assigned elements and // build a new list of assigned elements without $inx int $assigned[] = intArrayRemove( { $inx }, `hikCustomRigToolWidget -q -as` ); // If some assigned elements remain ... if ( size( $assigned ) > 0 ) { // ... set the new list of assigned effectors accordingly string $cmd = intArrayToString( $assigned, " -assigned " ); eval( `format -s $cmd "hikCustomRigToolWidget -e -assigned ^1s"` ); } else { // Otherwise, clear the list of assigned elements hikCustomRigToolWidget -e -as -1; } } global proc hikCustomRigClearAllMappings( int $inx ) { string $character = hikGetCurrentCharacter(); if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceClearAllRigWarning")); return; } RetargeterDeleteAllMappings( RetargeterGetName( $character ) ); // To ensure that the UI and retargeter don't fall out of synch // we make sure to remove any assigned effectors from the UI hikCustomRigToolWidget -e -as -1 -sl -1; } global proc hikCustomRigClearAllMappingsinView( int $inx ) { string $character = hikGetCurrentCharacter(); if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceClearAllinViewWarning")); return; } string $retargeter = RetargeterGetName( $character ); // Get the ids of all elements in the current view int $ids[] = `hikCustomRigToolWidget -q -ids`; // Get the ids of all assigned elements int $assigned[] = RetargeterAssignedElementIndices( $retargeter ); for ( $a in $assigned ) { // if the assigned element if shown in the current view if ( intArrayFind( $a, 0, $ids ) != -1 ) hikCustomRigClearMapping $a; // Remove the associated mapping } } global proc hikLoadCustomRigUIConfiguration() { string $filters = getFilters(); string $filename[]; if( `optionVar -exists hikCustomRigUIPath` ) { string $dir = `optionVar -q hikCustomRigUIPath`; $filename = `fileDialog2 -dir $dir -fileMode 1 -dialogStyle 2 -fileFilter $filters -caption (uiRes("m_hikCustomRigOperations.kImportUIConfiguration"))`; } else $filename = `fileDialog2 -fileMode 1 -dialogStyle 2 -fileFilter $filters -caption (uiRes("m_hikCustomRigOperations.kImportUIConfiguration"))`; if ( size($filename) != 1 ) return; optionVar -stringValue hikCustomRigUIPath $filename[0]; hikUpdateCustomRigConfigFromFile( $filename[0] ); } global proc hikUpdateCustomRigConfig() { string $configFile = `optionVar -q hikCustomRigUIPath`; if ( $configFile == "" ) return; hikUpdateCustomRigConfigFromFile( $configFile ); } global proc hikCustomRigRemoveRetargeter( string $retargeter ) { RetargeterDelete $retargeter; hikCustomRigClearAllMappings -1; hikSetCurrentSource ""; } global proc hikCustomRigReplaceEffector( int $inx ) { string $character = hikGetCurrentCharacter(); if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceReplaceMappingWarning")); return; } string $selections[] = `ls -selection`; if ( size($selections) != 1 ) { warning ( uiRes( "m_hikCustomRigOperations.kNothingSelected" ) ); return; } string $dest = $selections[0]; hikCustomRigClearMapping $inx; select -r $dest; hikCustomRigAssignEffector $inx; } global proc hikCustomRigSetOffset( string $type ) { string $character = hikGetCurrentCharacter(); if ( isReferenced( $character ) ) { warning (uiRes("m_hikCustomRigOperations.kReferenceSetOffsetRigWarning")); return; } string $retargeter = RetargeterGetName( $character ); if ( RetargeterExists( $retargeter ) == false ) return; int $inx = `hikCustomRigToolWidget -q -sl`; if ( $inx == -1 ) return; string $body = hikCustomRigElementNameFromId( $character, $inx ); if ( size( $body ) == 0 ) { print ( uiRes( "m_hikCustomRigOperations.kInvalidIndex" ) ); return; } string $x, $y, $z; if ( $type == "T" ) { $x = `floatSliderGrp -q -v hikCustomRigSliderTransX`; $y = `floatSliderGrp -q -v hikCustomRigSliderTransY`; $z = `floatSliderGrp -q -v hikCustomRigSliderTransZ`; } else if ( $type == "R" ) { $x = `floatSliderGrp -q -v hikCustomRigSliderRotX`; $y = `floatSliderGrp -q -v hikCustomRigSliderRotY`; $z = `floatSliderGrp -q -v hikCustomRigSliderRotZ`; } RetargeterSetMappingOffsets( $retargeter, $body, $type, $x, $y, $z ); } global proc hikNavigationPostCustomRig() { hikSchematicWidgetNavigationPost; hikUpdateCustomRigUI; } // These helper functions are called by the live connection UI to make sure the source drop down is // synchronized with the live connection check box. global proc hikCustomRigSetSourceToRemote() { hikUpdateSourceList; string $remote = ( hikGetCurrentCharacter() + "(remote)" ); if ( stringArrayContains( $remote, hikGetRemoteCharacters() ) ) { optionMenuGrp -e -v (" " + $remote) hikSourceList; hikSetCurrentSource( $remote ); } hikUpdateCustomRigUI; } global proc hikCustomRigSetSourceToNone() { hikUpdateSourceList; hikSetCurrentSource( hikNoneString() ); optionMenuGrp -e -v (" " + hikNoneString() ) hikSourceList; hikUpdateCustomRigUI; }