// =========================================================================== // 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 int blendShapeCreateTargetGroup(string $targetsAndTargetGroups[]) // // Description: // Create a new target group containing all the items in // $targetsAndTargetGroups (blendshape1.1/blendshape1.-1...) // { if (size($targetsAndTargetGroups) == 0) return 0; // Nothing to group // 1. Gather child items for the new created group string $bsdName; string $groupItems[]; for ($i = 0; $i < size($targetsAndTargetGroups); $i++) { string $buffer[]; tokenize($targetsAndTargetGroups[$i], ".", $buffer); if (size($buffer) != 2) continue; if ($i == 0) $bsdName = $buffer[0]; else if ($bsdName != $buffer[0]) return 0; // Not the same blend shape node $groupItems[size($groupItems)] = $buffer[1]; } // 2. Set child items for the new created group int $directoryIndex = blendShapeUnusedTargetDirectoryIndex($bsdName); setTargetDirectoryChildren($bsdName, $directoryIndex, $groupItems); // 3. Update parents for the items of the new group int $groupItemParents[]; for ($item in $groupItems) { string $parentIndexAttr; if (startsWith($item, "-")) // target group $parentIndexAttr = $bsdName + ".targetDirectory[" + stringRemovePrefix($item, "-") + "].parentIndex"; else // target $parentIndexAttr = $bsdName + ".parentDirectory[" + $item + "]"; int $parentIndex = `getAttr $parentIndexAttr`; if ($parentIndex < 0) $parentIndex = 0; if (!intArrayContains($parentIndex, $groupItemParents)) $groupItemParents[size($groupItemParents)] = $parentIndex; setAttr $parentIndexAttr $directoryIndex; } setAttr ($bsdName + ".targetDirectory[" + $directoryIndex + "].parentIndex") $groupItemParents[0]; // 3. Insert the new group into the grand parent, and remove the group items from their old parent for ($i = 0; $i < size($groupItemParents); $i++) { int $childIndices[] = `getAttr ($bsdName + ".targetDirectory[" + $groupItemParents[$i] + "].childIndices")`; string $buffer[] = stringToStringArray(intArrayToString($childIndices, ","), ","); if ($i == 0) { int $indexToInsert = stringArrayFind($groupItems[0], 0, $buffer); stringArrayInsertAtIndex($indexToInsert, $buffer, stringAddPrefix($directoryIndex, "-")); } $buffer = stringArrayRemove($groupItems, $buffer); setTargetDirectoryChildren($bsdName, $groupItemParents[$i], $buffer); } // 4. Set the new group's name string $directoryName = unusedTargetDirectoryName($bsdName, $groupItemParents[0]); setAttr ($bsdName + ".targetDirectory[" + $directoryIndex + "].directoryName") -type "string" $directoryName; return 1; } global proc string unusedTargetDirectoryName(string $bsdName, string $parentIndex) { string $usedNames[]; int $childIndices[] = `getAttr ($bsdName + ".targetDirectory[" + $parentIndex + "].childIndices")`; for ($child in $childIndices) { if ($child < 0) $usedNames[size($usedNames)] = `getAttr ($bsdName + ".targetDirectory[" + (-$child) + "].directoryName")`; } for ($i = 1; ; $i++) { string $name = "Group " + $i; if (!stringArrayContains($name, $usedNames)) return $name; } } global proc setTargetDirectoryChildren(string $bsdName, string $directoryIndex, string $childItems[]) { string $setChildCmd = "setAttr " + $bsdName + ".targetDirectory[" + $directoryIndex + "].childIndices -type Int32Array " + size($childItems); for ($item in $childItems) { $setChildCmd += " " + $item; } $setChildCmd += ";"; eval($setChildCmd); }