// =========================================================================== // 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: Nov, 1999 // // Procedure Name: // doSplitClipArgList // // Description: // Split a clip // // Input Arguments: // $version: The version of this option box. Used to know how to // interpret the $args array. // // $args // Version 1 // [0] $timeMethod : method to set time // "currTimeMethod" = use current time // "specifyMethod" = use $time // [1] $time : time to split clip // [2] $editor : editor containing the clip // Version 2 // [3] $sourceMethod : method to treat original source clip // "deleteSourceMethod" = delete source clip of original // "keepSourceMethod" = do not delete source clip of original // Version 3 // [4] $clip : specific clip to enable // proc int blendIdForClip( int $clipIndex, string $sch, /* scheduler */ int $start /* at start or end */) // // If there is a blendNode for the specified clip, return its index. // If start is true, look for the blend at the start of the clip. // If start is false, look for the blend at the end of the clip. // If no blend is found, returns -1. // { string $blendInfo[] = `clipSchedule -q -blend $sch`; for ($blend in $blendInfo) { string $buff[4]; tokenize($blend,",",$buff); int $b_si = $buff[2]; int $b_ei = $buff[3]; float $start1 = `clipSchedule -ci $b_si -q -s $sch`; float $start2 = `clipSchedule -ci $b_ei -q -s $sch`; if ($start2 < $start1) { int $tmp = $b_si; $b_si = $b_ei; $b_ei = $tmp; } if ($start && $b_ei == $clipIndex) { return $b_si; } if ((0 == $start) && $b_si == $clipIndex) { return $b_ei; } } return -1; /* found nothing */ } proc int maxClipIndex(string $sch) // // Return the maxClipIndex of the scheduler // { string $schedInfo[] = `clipSchedule -q -ci $sch`; int $schedSize = size($schedInfo); if ($schedSize == 0) { return 0; } string $buff[7]; tokenize($schedInfo[$schedSize-1],",",$buff); int $ci = $buff[1]; return $ci; } proc copyClipAttrsToNewClip(string $origClip, string $newClip, string $sch) { // Get the original clip's absolute, enabled, track and weight. // We'll transfer this to the new clips. // float $wt = `getAttr ($origClip+".weight")`; float $scale = `getAttr ($origClip+".scale")`; int $enabled = `getAttr ($origClip+".enable")`; int $weightStyle = `getAttr ($origClip+".weightStyle")`; float $hold = `getAttr ($origClip+".hold")`; setAttr ($newClip+".weight") $wt; setAttr ($newClip+".scale") $scale; setAttr ($newClip+".enable") $enabled; setAttr ($newClip+".weightStyle") $weightStyle; setAttr ($newClip+".hold") $hold; copyAbsoluteChannelsClipData($newClip, $origClip); } proc string[] createTwoClips(float $origSplitTime, int $clipIndex, string $sch, string $character) // // Create two new clips: One to represent the start and one for the end { string $sourceClipName = `clipSchedule -ci $clipIndex -q -scn $sch`; // Temporarily transfer the source start and end from the instance clip // to the source clip so that the resulting split clips match the // values for the instance clip. // float $instSourceStart = `clipSchedule -ci $clipIndex -q -sourceStart $sch`; float $instSourceEnd = `clipSchedule -ci $clipIndex -q -sourceEnd $sch`; float $srcSourceStart = `getAttr ($sourceClipName+".sourceStart")`; float $srcSourceEnd = `getAttr ($sourceClipName+".sourceEnd")`; setAttr ($sourceClipName+".sourceStart") $instSourceStart; setAttr ($sourceClipName+".sourceEnd") $instSourceEnd; string $result[] = `clip -split $origSplitTime -name $sourceClipName $character`; setAttr ($sourceClipName+".sourceStart") $srcSourceStart; setAttr ($sourceClipName+".sourceEnd") $srcSourceEnd; return $result; } proc string[] splitClip(float $origSplitTime, float $splitTime, int $clipIndex, string $sch, string $character) { string $result[] = createTwoClips($origSplitTime, $clipIndex, $sch, $character); string $newClip1, $newClip2; $newClip1 = $result[0]; $newClip2 = $result[1]; string $clipName = `clipSchedule -ci $clipIndex -q -name $sch`; float $clipStart = `getAttr ($clipName+".startFrame")`; int $track = `clipSchedule -ci $clipIndex -q -track $sch`; // Does the clip have a blendNode at the start or end? // int $bn_start = blendIdForClip($clipIndex,$sch,1); int $bn_end = blendIdForClip($clipIndex,$sch,0); // Duplicate any existing blends // string $new_bn_start = ""; string $new_bn_end = ""; if (-1 != $bn_start) { string $blendName[] = `clipSchedule -bn $bn_start $clipIndex -q $sch`; if (size($blendName)) { string $dup[] = `duplicate -ic $blendName[0]`; if (size($dup)) { $new_bn_start = $dup[0]; } } } if (-1 != $bn_end) { string $blendName[] = `clipSchedule -bn $clipIndex $bn_end -q $sch`; if (size($blendName)) { string $dup[] = `duplicate -ic $blendName[0]`; if (size($dup)) { $new_bn_end = $dup[0]; } } } string $group = `clipSchedule -clipIndex $clipIndex -query -groupName $sch`; string $part1 = `clipSchedule -instance $newClip1 -start $clipStart -name ($clipName+"Start") $sch`; string $part2 = `clipSchedule -instance $newClip2 -start $splitTime -name ($clipName+"End") $sch`; copyClipAttrsToNewClip($clipName, $part1, $sch); copyClipAttrsToNewClip($clipName, $part2, $sch); setAttr ($part1+".hold") 0; // Remove the first clip // int $part1Index = getClipIndex ($part1, $sch); int $part2Index = getClipIndex ($part2, $sch); clipSchedule -rm -ci $clipIndex $sch; clipSchedule -ci $part1Index -track $track $sch; clipSchedule -ci $part2Index -track $track $sch; if ($group != "") { clipSchedule -group true -groupIndex $part1Index -groupIndex $part2Index -track $track -groupName $group $sch; } int $newIndex = maxClipIndex($sch); if ("" != $new_bn_start) { int $newStartIndex = $newIndex - 1; clipSchedule -b $bn_start $newStartIndex -bun $new_bn_start $sch; } if ("" != $new_bn_end) { clipSchedule -b $newIndex $bn_end -bun $new_bn_end $sch; } return $result; } proc string[] splitClipReuse(float $origSplitTime, float $splitTime, int $clipIndex, string $sch) // // This splits the clip without creating any new source clips by instancing // the original clip. The original clip is used as the start half of the split // clip, and the newly instanced clip is used as the end half of the split clip. // { string $origClip = `clipSchedule -ci $clipIndex -q -name $sch`; // Instance the original clip, making its source start be the origSplitTime // string $newClip = `clipSchedule -instance $origClip -start $splitTime -sourceStart $origSplitTime $sch`; // Make the source end of the original clip be the origSplitTime // clipSchedule -ci $clipIndex -sourceEnd $origSplitTime $sch; // Does the orig clip have a blendNode at the end? Any blend at the start is // still ok since we keep the start clip. // int $bn_end = blendIdForClip($clipIndex,$sch,0); // Duplicate the existing blend // string $new_bn_end = ""; string $old_bn; if (-1 != $bn_end) { string $blendName[] = `clipSchedule -bn $clipIndex $bn_end -q $sch`; if (size($blendName)) { string $dup[] = `duplicate -ic $blendName[0]`; if (size($dup)) { $new_bn_end = $dup[0]; $old_bn = $blendName[0]; } } } copyClipAttrsToNewClip($origClip, $newClip, $sch); setAttr ($origClip+".hold") 0; // If there was a blend, add it to the new end clip // int $part2Index = getClipIndex ($newClip, $sch); if ("" != $new_bn_end) { clipSchedule -b $part2Index $bn_end -bun $new_bn_end $sch; delete $old_bn; } // rename and set the track for the new clips // string $newOrigName = `rename $origClip ($origClip+"Start")`; $newClip = `rename $newClip ($origClip+"End")`; int $track = `clipSchedule -ci $clipIndex -q -track $sch`; clipSchedule -ci $part2Index -track $track $sch; string $group = `clipSchedule -clipIndex $clipIndex -query -groupName $sch`; if ($group != "") { clipSchedule -group true -groupIndex $clipIndex -groupIndex $part2Index -track $track -groupName $group $sch; } return { $newOrigName, $newClip }; } global proc string[] doSplitClipArgList( string $version, string $args[] ) { int $versionNo = $version; string $timeMethod = $args[0]; float $stime = ( $timeMethod != "currTimeMethod" ) ? $args[1] : ( `currentTime -q` ); string $editor = $args[2]; string $sourceMethod = ( $versionNo >= 2 ) ? $args[3] : "keepSourceMethod" ; string $selClips[]; if (($versionNo >= 3) && ($args[4] != "")) { $selClips[0] = $args[4]; } else { $selClips = getSelectedClips("includeCache"); } string $splitClips[] = {}; int $nclips = size($selClips); if ($nclips == 0) error((uiRes("m_doSplitClipArgList.kSelectClips"))); int $cacheClips = 0; string $clip; for ($clip in $selClips) { if (nodeType($clip) != "animClip") { $cacheClips++; continue; } string $sch = getClipScheduler( $clip ); string $ch[] = `clipSchedule -q -character $sch`; if (size($ch) == 0) error((uiRes("m_doSplitClipArgList.kNoScheduler"))); int $clipIndex = getClipIndex( $clip, $sch ); string $clipName = `clipSchedule -ci $clipIndex -q -n $sch`; float $clipStart = `clipSchedule -ci $clipIndex -q -s $sch`; float $clipPreCycle = `clipSchedule -ci $clipIndex -q -preCycle $sch`; float $clipPostCycle = `clipSchedule -ci $clipIndex -q -postCycle $sch`; float $clipScale = `clipSchedule -ci $clipIndex -q -scale $sch`; float $clipOrigStart = `clipSchedule -ci $clipIndex -q -sourceStart $sch`; float $clipOrigEnd = `clipSchedule -ci $clipIndex -q -sourceEnd $sch`; float $clipDuration = ($clipOrigEnd - $clipOrigStart); if ( size($clipName) == 0 ) error( (uiRes("m_doSplitClipArgList.kClipNotFound")) ); float $startLength = $stime - $clipStart; float $startCycle = $startLength / ($clipDuration*$clipScale); // verify that the time is within the range of the clip // if ($startLength <= 0.0) { string $msg = (uiRes("m_doSplitClipArgList.kInvalidTime")); error( `format -stringArg $stime $msg` ); } // determine whether the clip needs to be split or just copied if ($clipPreCycle > 0.0 || $clipPostCycle > 0.0) error((uiRes("m_doSplitClipArgList.kNoSplitCycle"))); if ( $startCycle >= 1.0 ) error((uiRes("m_doSplitClipArgList.kSplitTime"))); float $splitTime = ($clipOrigStart + $startCycle*$clipDuration); if ($sourceMethod == "deleteSourceMethod") { string $clipSourceName = `clipSchedule -ci $clipIndex -q -scn $sch`; $splitClips = splitClip( $splitTime, $stime, $clipIndex, $sch, $ch[0] ); string $otherInstances[] = `listConnections -type animClip $clipSourceName`; if (size($otherInstances) == 0) delete $clipSourceName; } else { $splitClips = splitClipReuse( $splitTime, $stime, $clipIndex, $sch ); } ghostAppendedClip $sch $splitClips 2; } if ($cacheClips > 0) { string $splitCache[] = doSplitCacheArgList(1,$args); for ($split in $splitCache) $splitClips[size($splitClips)] = $split; } return $splitClips; }