Notifications
Clear all

[Closed] registerRedrawViewsCallback and visual selection lag

I’ve been experimenting with registerRedrawViewsCallback and changing selections but the behavior is a bit unexpected. When I set a selection the action doesn’t happen visually (I can see in the command panel that the object was selected but not in the viewport) till the second click, almost like a double click action was required. If I click from one view to the next I can see the proper selection of the previous view blink as the new view is activated. Anyone run into this and found a way to make it work properly?

I’ve tried various combinations of viewport redrawing to see if that would help with the visual aspect of the selection but have yet to find the right combination of events to make it work.

I’ve put together a simple example of this behaviour.
Usage: make a couple objects, then change active viewport

(
 	fn redrawViewCALLBACK =
 	(
 		try(select objects[viewport.activeViewport])catch()
 	)
 	try(unRegisterRedrawViewsCallback redrawViewCALLBACK)catch()
  	registerRedrawViewsCallback redrawViewCALLBACK
 )
3 Replies

This is a tricky situation, because Select() causes a viewport redraws, but doing so from the inside of a redrawViewsCallback would mean a neverending recursive loop. So it looks like MAXScript does not allow any view redraws to be caused from inside a redrawviewsCallback function to keep Max from hanging forever. In your case the viewport gets a redraw call, it updates the viewport and THEN calls the MAXScript function which selects a new object. Since the selection causes another redraw, it is suspended to avoid the vicious circle, and the selection is never shown until alother redraw is caused by something outside of the callback function (like another change of the viewport, or right-ckick/right-click through a QuadMenu etc.).

A possible solution would be to have a polled function (for example a timer on a rollout or, in Max 9, a DotNet timer object ticking in the background) to deal with the redraw. For example, the timer could be disabled by default. When the redraw callback is called, it sets the selection and then enables the timer which, some milliseconds later, calls a redrawViews() to make sure the viewport is updated, then it disables itself. The timer function should also set a timestamp variable somewhere, because calling redrawViews() would trigger another callback and get into a loop, so the redraw callback would have to check the current time against the latest time stamp from the timer and if it happened sooner than a certain threshold, do not enable the timer again…

Or it might be possible to temporarily unregister the callback, redraw the views and register again via the timer…?

As I said, it is tricky...

Thanks Bobo,

I’ve actually writen the main script to only fire off the first time the view becomes active not everytime it redraws so I’m really catching viewport switching.

Now that you have explained the reason why this happens it makes good sence.

Timer worked well enough, it has a bit of lag but atleast it doesn’t require another mouse click.

Unregistering the callback, executing the selection and then reregistering the callback didn’t seem to work.

Thanks again Bobo.