Mini-Challenge #5. Are you ready?


#41

for example you are not checking baseobject…


#42

that’s better.


#43

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
)


#44

Actually, it should probably be done like this:

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

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


#45

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
			false
		)
		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.


#46

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]
   	animated
   )
   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
   )
   

findAnimatedNodes
nodes:753
time:201 memory:264L

findAnimatedMaterialNodes
nodes:249
time:140 memory:264L

findAnimatedTransformNodes
nodes:183
time:85 memory:264L

it’s not bad, is it?


#47

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…


#48

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


#49

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


#50

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


#51

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


#52

Of course! So simple, thank you.


#53

lo,
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.


#54

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			
				false
			)
			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.


#55

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


#56

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.


#57

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.


#58

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


#59

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.


#60

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…