(
local ts = timestamp()
local mem = heapfree
global animatedNodes = #()
fn myCallbackFilterFunction theAnimatable theParent theSubAnimIndex theGrandParent theNode =
(
if isController theanimatable and theanimatable.keys.count>0 then
(
appendIfUnique animatedNodes theNode
false
)
else true
)
with redraw off
(
trackbar.filter = #all
local filtind = maxops.trackbar.registerFilter myCallbackFilterFunction undefined "." 1 active:on
select objects
maxops.trackbar.redraw forceRedraw:on
maxops.trackbar.unregisterfilter filtind
clearSelection()
format "Time: %ms
" (timestamp()-ts)
format "Memory: %
" (mem-heapfree)
format "Nodes Found: %
" ((animatedNodes).count)
ok
)
)
^ This is great, I never would of realized it could of been done this way.
I have a question though, about the line:
local filtind = maxops.trackbar.registerFilter myCallbackFilterFunction undefined "." 1 active:on
Does the fn myCallbackFilterFunction want 5 parameters? I see you are passing 3. I don’t understand how that’s working… Are you passing ‘undefined’ for ‘theAnimatable’ and then “.” for theParent and then “1” for theSubAnimIndex? How do you pass theNode parameter? You guys write code that flies over my head sometimes… even after digging into the maxscript help where the fn came from. Great challenge!
I am never calling the filter function directly in the code. 3dsmax calls the function for every animatable in the scene, and supplies all 5 parameters.
Sure, my pleasure.
Denis, I did not understand: is this the method you’re using as well or do you have a different trick up your sleeve to be shown later?
no… it was my plan B for today… i use subanim recursive check. i will show it as soon as i get the max.
lo,
i know that you see the shortcoming of your method. it’s the selecting. the performance of the method depends on background callbacks. the method needs more tests… e.g. with opened material editor or trackview…
Yep, awesome work!
My question still remain – why I get just 600 nodes?
Well, my Explorer8 not show any forums formating issue with [i] inside
block,
but just in case, i attach my code as text file.
aha, that make sense, thanks
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
)
but you have to find all controllers first. selectKeys and numSelKeys are controller (or animatable subanim) methods
SelectKeys is mapped, so SelectKeys objects is valid.
NumSelKeys does require a controller though.
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…
You’re right. Callbacks should be taken into account. How about this:
fn longSelectionCallback =
(
-- do something long and annoying
sleep 1
)
-- add evil selection callbacks for testing
callbacks.addScript #selectionSetChanged "longSelectionCallback()" id:#testCB
global whenCB = when select objects[1] changes id:#testCB do longSelectionCallback()
(
local ts = timestamp()
local mem = heapfree
global animatedNodes = #()
fn myCallbackFilterFunction theAnimatable theParent theSubAnimIndex theGrandParent theNode =
(
if isController theanimatable and theanimatable.keys.count>0 then
(
appendIfUnique animatedNodes theNode
false
)
else true
)
with redraw off
(
trackbar.filter = #all
local filtind = maxops.trackbar.registerFilter myCallbackFilterFunction undefined "." 1 active:on
disableRefMsgs()
local sel = getCurrentSelection()
select objects
maxops.trackbar.redraw forceRedraw:on
maxops.trackbar.unregisterfilter filtind
select sel
enableRefMsgs()
format "Time: %ms
" (timestamp()-ts)
format "Memory: %
" (mem-heapfree)
format "Nodes Found: %
" ((animatedNodes).count)
ok
)
callbacks.removeScripts id:#testCB
deleteChangeHandler whenCB
)
This way no callbacks get called. I checked it with trackview and material editor open, they made no difference.