Comparing values in an array and getting only those within a range?

Comparing values in an array and getting only those within a range?

Anonymous
Not applicable
1,016 Views
4 Replies
Message 1 of 5

Comparing values in an array and getting only those within a range?

Anonymous
Not applicable

hello

I'm trying to do a thing in MEL where i have a animated camera I'm using for game cut scenes. When the camera is doing a jump cut it just animates a big distance over 2 sequential frames.

I would like to get all the ranges of frames for each shot to use for playblast / exporting tool etc. But I'm stuck with the best way to do it.

Obviosuly I can get all keyframe time values in an array just with `keyframe -q` but I'm trying all kinds of things now to get all the ranges that are begun and terminated by 2 sequential keyframes.

Eg a camera might have 2 shots which would be 1 cut but with some keys defining the motions within a shot

So i would get values like 0,1,15,30,31,40,50,51

And I want the script to return 1,30,31,50 (1:30,31:50 would be a nice format)

but i would also want 1,15,30,31,40,50 to get the same result

 

TL:DR just give me the first and last value of any range that starts and ends with 2 seqeuntial values 

thanks all.

0 Likes
Accepted solutions (1)
1,017 Views
4 Replies
Replies (4)
Message 2 of 5

Swordslayer
Advisor
Advisor

Not the most elegant solution, but anyway:

 

proc float[] getRanges(float $list[])
{
	float $item, $prev, $last = $list[size($list)-1], $results[];
	int $index = 0;

	for ($item in $list)
	{
		if ($index == 0)
			$results[$index++] = ($list[1] == $item + 1) ? $list[1] : $item;
		else if ($item == $last)
			$results[$index++] = ($item == $prev + 1) ? $prev : $item;
		else if ($item - 1 == $prev)
		{
			$results[$index++] = $prev;
			$results[$index++] = $item;
		}
		else $prev = $item;
	}
	return $results;
}

float $list[] = {0,1,15,30,31,40,50,51}; // or {1,15,30,31,40,50}
getRanges($list);
Message 3 of 5

Anonymous
Not applicable

Hey there

 

thanks for your help, I wish i understood things more so I could see how you did it. One thing though, when I run your script i actually get this which which has 2 extra entries at the begining, it work fine with the smaller data set. Thanks

 

float $list[] = {0,1,15,30,31,40,50,51};
getRanges($list);
// Result: 1 0 1 30 31 50 //
0 Likes
Message 4 of 5

Swordslayer
Advisor
Advisor
Accepted solution

Sorry about that, different behavior across versions and too little testing. Initializing the $prev to something small enough should take care of that:

 

proc float[] getRanges(float $list[])
{
	float $item, $prev = `minint`, $last = $list[size($list)-1], $results[];
	int $index = 0;

	for ($item in $list)
	{
		if ($index == 0)
			$results[$index++] = ($list[1] == $item + 1) ? $list[1] : $item;
		else if ($item == $last)
			$results[$index++] = ($item == $prev + 1) ? $prev : $item;
		else if ($item - 1 == $prev)
		{
			$results[$index++] = $prev;
			$results[$index++] = $item;
		}
		else $prev = $item;
	}
	return $results;
}

float $list[] = {0,1,15,30,31,40,50,51};
getRanges($list);

If you are on some maya version that doesn't support the minint command, replace it with -2147483648. Or just -1 if you never start the animation at negative frames.

Message 5 of 5

Anonymous
Not applicable

ahh, thanks very much indeed! Now i will trying to figure out how lol, or not, maybe just use it 🙂

 

thanks again

0 Likes