// =========================================================================== // 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. // =========================================================================== global proc blendShapeEditorMergeTarget() // // Description: // Callback function for merging selected targets in Shape Editor. // { if (!isMergeTargetEnabled()) return; // to get all the selected items at the Shape Editor. string $bsn = ""; int $targetIndices[]; int $groupIndices[]; string $selectedGroups[]; $selectedGroups = stringArrayCatenate($selectedGroups, getShapeEditorTreeviewSelection(3)); for ($item in $selectedGroups) { string $buffer[]; tokenize($item, ".", $buffer); if (size($buffer) != 2) continue; $bsn = $buffer[0]; string $grpIdxStr = $buffer[1]; int $grpIdx = (int)$grpIdxStr; if ( !intArrayContains($grpIdx, $groupIndices) ) $groupIndices[size($groupIndices)] = $grpIdx; } for ($item in $groupIndices) { int $tmpTargetIndices[] = blendShapeTargetFromDirectory($bsn, $item, 0); for ($item2 in $tmpTargetIndices) { if (!intArrayContains($item2, $targetIndices)) $targetIndices[size($targetIndices)] = $item2; } } string $selectedTargets[]; $selectedTargets = stringArrayCatenate($selectedTargets, getShapeEditorTreeviewSelection(24)); for ($item in $selectedTargets) { string $buffer[]; tokenize($item, ".", $buffer); if (size($buffer) != 2) continue; // in-between or others $bsn = $buffer[0]; string $tgtIndexStr = $buffer[1]; int $tgtIndex = (int)$tgtIndexStr; if (!intArrayContains($tgtIndex, $targetIndices)) $targetIndices[size($targetIndices)] = $tgtIndex; } if ($bsn == "" || size($targetIndices) < 2) return; string $firstSelected[] = getShapeEditorTreeviewSelection(31); string $firstSelectedTargetName = "target_merged"; string $firstSelectionTargetSourcePlugs[]; string $firstSelectionTargetDestinationPlugs[]; string $firstSelectionTargetCombinationDrivers[]; int $firstSelectionTargetCombinationMethod; for ($item in $firstSelected) { string $buffer[]; tokenize($item, ".", $buffer); if (size($buffer) != 2) continue; int $idx = (int)$buffer[1]; if ($idx >= 0) { $firstSelectedTargetName = blendShapeTargetNameFromIndex($bsn, $idx); $targetPlug = $bsn + "." + $firstSelectedTargetName; //Save source, for combination target, save driver indexes and combination method if(`combinationShape -q -ex -bs $bsn -ctn $firstSelectedTargetName`) { $firstSelectionTargetCombinationDrivers = `combinationShape -q -ald -bs $bsn -ctn $firstSelectedTargetName`; $firstSelectionTargetCombinationMethod = `combinationShape -q -cm -bs $bsn -ctn $firstSelectedTargetName`; } else $firstSelectionTargetSourcePlugs = `listConnections -p on -d off $targetPlug`; //Save destinations $firstSelectionTargetDestinationPlugs = `listConnections -p on -s off $targetPlug`; } else { $firstSelectedTargetName = blendShapeTargetDirectoryNameFromIndex($bsn, -$idx); } $firstSelectedTargetName = substituteAllString($firstSelectedTargetName, " ", "_"); } $lastSelectedItem = getShapeEditorTreeviewSelection(20); // merge targets into a new one //blendShapeMergeTarget($bsn, $targetIndices) $tempAttr = $bsn + ".inputTarget[" + 0 + "].inputTargetGroup[" + $targetIndices[0] + "].postDeformersMode"; int $targetPDM = `getAttr $tempAttr`; for ($item in $targetIndices) { $tempAttr = $bsn + ".inputTarget[" + 0 + "].inputTargetGroup[" + $item + "].postDeformersMode"; int $tempTargetPDM = `getAttr $tempAttr`; if ($tempTargetPDM != $targetPDM) { error ((uiRes("m_blendShapeEditorMergeTarget.kDifferentPDM"))); return; } } string $transformName = ""; if ($targetPDM == 2) { // transform space for ($item in $targetIndices) { $tempAttr = $bsn + ".inputTarget[" + 0 + "].inputTargetGroup[" + $item + "].tmx"; $connections = `listConnections $tempAttr`; $tempTransformName = $connections[0]; if ($transformName == "") $transformName = $tempTransformName; else { if ($transformName != $tempTransformName) { error ((uiRes("m_blendShapeEditorMergeTarget.kDifferentJoints"))); return; } } } } int $checkTopology = 1; int $targetType = $targetPDM + 2; // object/tangent/transform space. int $editOn = 0; int $resetWeight = 0; string $duplicateTargets[]; // this procedure will add targets for every base. int $newTargetIndexes[] = doBlendShapeAddTarget( $bsn, $checkTopology, $targetType, $transformName, $editOn, $resetWeight, $duplicateTargets ); if (size($newTargetIndexes) == 0) return; $cmdMergeSource = ""; for ($item in $targetIndices) { if (blendShapeTargetIsVisible($bsn, $item)) $cmdMergeSource += "-mergeSource " + $item + " "; } if ($cmdMergeSource != "") { $cmd = "blendShape -edit "; $cmd += $cmdMergeSource; $cmd += "-mergeTarget " + $newTargetIndexes[0] + " " + $bsn; evalEcho($cmd); } if (size($lastSelectedItem)) { string $buffer[]; tokenize($lastSelectedItem[0], ".", $buffer); if (size($buffer) == 2) { int $idx = (int)$buffer[1]; if ($idx >= 0) { $tempAttr = $bsn + ".parentDirectory[" + $idx + "]"; int $toParent = `getAttr $tempAttr`; $cmd = "blendShapeTargetMove " + $bsn + " " + $newTargetIndexes[0] + " " + $toParent + " " + $idx + " " + 1; evalEcho($cmd); } else { $cmd = "blendShapeTargetMove " + $bsn + " " + $newTargetIndexes[0] + " " + -$idx + " " + 0 + " " + 2; evalEcho($cmd); } } } // delete the selected items for ($item in $targetIndices) blendShapeDeleteTargetGroup($bsn, $item); // rename the new targe to the first selected one. blendShapeRenameTargetAlias($bsn, $newTargetIndexes[0], $firstSelectedTargetName); // Restore source if(size($firstSelectionTargetCombinationDrivers) > 0) { //Create a new combination shape since the old one is removed by target deleting $cmd = "combinationShape -bs " + $bsn + " -cti " + $newTargetIndexes[0] + " -cm " + $firstSelectionTargetCombinationMethod; int $hasDriver = false; for($driverTargetName in $firstSelectionTargetCombinationDrivers) { if(`objExists $driverTargetName`) { string $subStrings[] = stringToStringArray($driverTargetName, "."); if(size($subStrings) == 2) { $cmd += " -dtn "; $cmd += $subStrings[1]; $hasDriver = true; } } } if($hasDriver) eval($cmd); } else if(size($firstSelectionTargetSourcePlugs) == 1) { if(`objExists $firstSelectionTargetSourcePlugs[0]`) { $cmd = "connectAttr " + $firstSelectionTargetSourcePlugs[0] + " " + $bsn + ".w[" + $newTargetIndexes[0] + "]"; eval($cmd); } } // Restore destinations for($dest in $firstSelectionTargetDestinationPlugs) { if(`objExists $dest`) { $cmd = "connectAttr " + $bsn + ".w[" + $newTargetIndexes[0] + "] " + $dest; eval($cmd); } } return; }