Mini-Challenge #5. Are you ready?


for example you are not checking baseobject…


that’s better.


aha, that make sense, thanks :slight_smile:

meanwhile a funny idea hang round in my head,
but i have work to do right now.

pseudo code:

mapped fn getAnimated nodes &result = (
	selectKeys nodes
	if numSelKeys nodes > 0 do append result nodes


Actually, it should probably be done like this:

local sel = getCurrentSelection()
select objects
maxops.trackbar.redraw forceRedraw:on			
maxops.trackbar.unregisterfilter filtind		
select sel

to avoid situation in which the filter function raises an exception and max is left in an unstable state of no ref messages.


Here is a variation that finds only nodes with animated materials. As Denis expected, the execution time goes up by about 1000% and memory by much more than that.

fn myCallbackFilterFunction theAnimatable theParent theSubAnimIndex theGrandParent theNode = 
		if theParent != undefined and theNode.material != undefined and isController theAnimatable and
			theAnimatable.keys.count > 0 and findItem animatedNodes theNode == 0 and
			findItem (refs.dependents theAnimatable) theNode.material > 0 then
			append animatedNodes theNode
		else true
Time: 1172ms
Memory: 65720L
Nodes Found: 249

though to be practical, if this is the goal, it would probably be faster to traverse scene materials instead of nodes.


here is me with my method :slight_smile: :

   fn isNodeAnimated node = 
   	animated = off
   	object = node
   	if iskindof node SubAnim do
   		animated = (node.keys != undefined) and (node.keys.count > 0)
   		object = node.object
   	if iskindof object maxwrapper do for ca in object.custattributes while not animated do animated = isNodeAnimated ca
   	for k=1 to node.numsubs while not animated do animated = isNodeAnimated node[k]
   fn findAnimatedNodes nodes: = 
   	if nodes == unsupplied do nodes = objects as array
   	for node in nodes where (isNodeAnimated node) collect node
   fn findAnimatedMaterialNodes nodes: = 
   	if nodes == unsupplied do nodes = objects as array
   	for node in nodes where node.mat != undefined and (isNodeAnimated node.mat) collect node
   fn findAnimatedTransformNodes nodes: = 
   	if nodes == unsupplied do nodes = objects as array
   	for node in nodes where (isNodeAnimated node.controller) collect node

time:201 memory:264L

time:140 memory:264L

time:85 memory:264L

it’s not bad, is it?


i’ve check you method on my machine:
Time: 225ms
Memory: 456L
Nodes Found: 753

so i stay with my method for a while :wink:

PS. lo,
to make the method complete you have to set previous CallbackFilterFunction back…


but you have to find all controllers first. selectKeys and numSelKeys are controller (or animatable subanim) methods


Very nice! I would stay with your method too, if only for the sake of simplicity.


you can set #mat trackbar.filter to filter only material keys… it has to make everything faster


SelectKeys is mapped, so SelectKeys objects is valid.
NumSelKeys does require a controller though.


Of course! So simple, thank you.


as i said, i wanted to try the method with callbackfilterfunction… technically it might be faster. we have to stop recursing the node after finding any animated track.


Good idea. The difference is not noticable with 1000 nodes, but ~200% faster (~40% faster than your method) with 10000 nodes.

global approvedNode

	fn myCallbackFilterFunction theAnimatable theParent theSubAnimIndex theGrandParent theNode = 
		if approvedNode == theNode then false else
			if isController theAnimatable and theAnimatable.keys.count > 0 then
				approvedNode = theNode
				append animatedNodes theNode			
			else true

technically we are not cutting the traversal of the node when we find it is animated, but we exit the function much faster for all subsequent animatables in the node.


i’ve tested it on 2010(64) and 2012(64).
it’s exactly the same time: 362
memory is slightly different: 129880L against 110664L


yep. sounds right. the reason to stay for me with my method is a simple way to make filters.
we found some way to make searching of animated materials for your method, but to find animated modifiers might be a problem.


there is another problem of the trackbar method… the trackbar might be hidden. in this case we have to set it to visible. it causes max and its viewport redraw. for heavy scenes it will be an issue.


I guess it all depends on the context of the tool.


Yeah, I know, for that I post my idea as pseudo code. I like and use Nested Object Controller Functions (deleteTime, reverseTime, scaleTime, …) and SelectKeys is one of them, so just quickly presume that there may have some meat on this bone. And yep, NumSelKeys requre a controller, this is the unfinished part.


i’ve played with the idea to use selectKeys function…
#1: it’s slow. it takes ~1100 ms on my machine for the test scene (1,000 nodes)
#2: i hoped to use some event to catch all nodes that received change notification. no luck. there is no node (node based) event that fires on key selection change. The controller that holds keys fires event with “when select” construct, but it can’t help in our case.

so it could be a very clever move but unfortunately it doesn’t work…