Notifications
Clear all

[Closed] Mini-Challenge #5. Are you ready?

there is only one right number. it’s 753

ok, will glad to see the difference (and why i not get 753 as well).

lo found them all

(
 	 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!

 lo1

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.

http://docs.autodesk.com/3DSMAX/14/ENU/MAXScript%20Help%202012/files/GUID-45E2F1A9-AFBB-413F-AEAD-7C9816BA94E-2065.htm

Cheers for sharing Lo, very interesting method. I was way off

 lo1

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?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

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.
7 Replies
(@denist)
Joined: 11 months ago

Posts: 0

for example you are not checking baseobject…

(@panayot)
Joined: 11 months ago

Posts: 0

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
)

(@denist)
Joined: 11 months ago

Posts: 0

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

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

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

(@panayot)
Joined: 11 months ago

Posts: 0

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.

(@denist)
Joined: 11 months ago

Posts: 0

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…

(@panayot)
Joined: 11 months ago

Posts: 0

too bad then… thanks for spending a time to check this

 lo1

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.

Page 3 / 5