Macros Running In Secret?

Macros Running In Secret?

Anonymous
Not applicable
491 Views
8 Replies
Message 1 of 9

Macros Running In Secret?

Anonymous
Not applicable
Ok, so I've got this macro I made that replaces max's own isolate selection. It basically just hides everything that isn't selected and stores them in a selection set. If you run it and the selection set exists, then it knows it should unhide the objects instead. This has worked fine for a few years and still does (zero issues encountered).

...But I thought I'd add some visual feedback. My idea was to implement the "on isChecked" handler in the macroscript. This way the user could choose if they wanted visual feedback or not by simply putting the macro in a toolbar, that way it would appear pressed when in "isolation mode". This didn't take long to implement and works a charm ...kind of and this is where the problems begin.

It seems that macros or this macro is run every now and then. Like when after you've created created an object and rightclick (wtf), or when you maximize/minimize a viewport and so on. This is very visible to the user due to the nature of the script, hiding and unhiding objects. Furthermore when the macro is invoked in this way it appears to be running "silently" or in a special scope, because none of the print statements work. The macro is toggled on at max startup which might hint at the problem. If all macros are evaluated at startup they have to be done so in a special way, so that tons of dialogs aren't opened and objects created or whatever. I guess this is where the "on execute" handler comes in to play? How do you use it properly as things seem to work quite well without it.

I'd be very greatful if someone could explain this to me as I just can't figure out what is going on by simply looking at the code.




Below you will find the two versions of the script.




Version 1, no toggling, works fine.

--###########################################
MacroScript IsolateSelectionImproved
Category:"Benzie"
ToolTip:"Isolate Selection Improved"
buttontext:"IsoSel"

(
with redraw off(
if selectionSets!= undefined then
(
unhide selectionSets
deleteItem selectionSets "IsoSelTemporaryHidden"
)else
(
local tmpInvSelection = for obj in objects where (not (obj.ishiddenInVpt or obj.isSelected)) collect obj
selectionSets = tmpInvSelection
hide selectionSets
)
)
)--end macro
--################################################






Version 2, toggling enabled, serious problems. It needs to be in a toolbar to work at all.
--################################################
MacroScript Benzie_IsolateSelectionImproved
Category:"Benzie"
ToolTip:"Isolate Selection Improved"
buttontext:"IsoSel 2"


-- START MACRO
(

fn benzieIsolateSelection isolate:true =(
with redraw off(
if isolate == false then(
unhide selectionSets
deleteItem selectionSets "IsoSelTemporaryHidden"
)else(
local tmpInvSelection = for obj in objects where (not (obj.ishiddenInVpt or obj.isSelected)) collect obj
selectionSets = tmpInvSelection
hide selectionSets
)
)--end redraw
)--end fn


on execute do(
--I don't want to do anything but execute is needed for ischecked to work
print "in execute do"
)

on isChecked do(
if selectionSets== undefined then(
benzieIsolateSelection isolate:true
return true
)else (
benzieIsolateSelection isolate:false
return false
)
)--end is checked


)--END MACRO
--##########################################################




Thanks in advance :)
0 Likes
492 Views
8 Replies
Replies (8)
Message 2 of 9

Anonymous
Not applicable
Sorry for double post.
I have tried running the following script from the max help, but it does not work. Could someone please confirm?



macroScript testCloseDialogs category:"MXS Help"
(
rollout testCloseRollout "Test" --define a rollout
(
label lb_test "testing CloseDialogs handler..."
)

on isChecked do testCloseRollout.open --return true if rollout is open

--if isChecked returns false (the rollout is not open in a dialog),
--the on execute handler will be called and will create the dialog.


on execute do createDialog testCloseRollout


--If isChecked returns true and the user pressed the button again,
--instead of calling the on execute handler, the macroScript will call
--the on closeDialogs handler and destroy the dialog.


on closeDialogs do destroyDialog testCloseRollout

)
0 Likes
Message 3 of 9

Anonymous
Not applicable
The MAXScript Help script works for me (tried in 2008 and 2010).

You are misunderstanding the use of the on isChecked handler.

These handlers (isEnabled, isChecked etc.) are called each time the toolbar is repainted.

You should not perform any actions in them, only return a true or false value as result of the handler call to determine whether the button will appear checked or appear disabled.

In other words, on isChecked() is not called only when you check/uncheck the button, but whenever MAX wants to know how to redraw its icon, and this happens quite often as you have noticed.

You should always perform the hiding/unhiding actions inside the on execute() handler which is what is called when you check/uncheck the button with the mouse.

Hope this helps.
0 Likes
Message 4 of 9

Anonymous
Not applicable
Here is how it should be changed:


MacroScript Benzie_IsolateSelectionImproved
Category:"Benzie"
ToolTip:"Isolate Selection Improved"
buttontext:"IsoSel 2"

-- START MACRO
(

fn benzieIsolateSelection isolate:true =(
with redraw off(
if isolate == false then(
unhide selectionSets
deleteItem selectionSets "IsoSelTemporaryHidden"
)else(
local tmpInvSelection = for obj in objects where (not (obj.ishiddenInVpt or obj.isSelected)) collect obj
selectionSets = tmpInvSelection
hide selectionSets
)
)--end redraw
)--end fn

--#if you check/uncheck the button, you should call the function with
--#argument based on whether the named selection exists or not
on execute do
(
benzieIsolateSelection isolate:(selectionSets==undefined)
)

--#when Max wants to know whether the button should be drawn as checked,
--#you return true when the selection set exists and false when it does not:
on isChecked return selectionSets != undefined


)--END MACRO
0 Likes
Message 5 of 9

Anonymous
Not applicable
Legend to the rescue. Thanks Bobo.

Think I've got a better understanding of this now. It did feel a bit awkward writing it my way I just got stuck in a loop and couldn't figure it out.

But the example from the help still doesn't work. I only have full time access to 3dmsax 9x64 but I've managed to test it in 2009 aswell. And it doesn't work.
0 Likes
Message 6 of 9

Anonymous
Not applicable

But the example from the help still doesn't work. I only have full time access to 3dmsax 9x64 but I've managed to test it in 2009 aswell. And it doesn't work.


What about it does not work? (I wrote it, I should fix it ;) )
I installed it in both 2008 and 2010 and it worked just as advertised.
*I copied the code you posted into a MAXScript editor
*Pressed Ctrl+E to evaluate
*Customized a toolbar with the script from the MXS Help category
*When I pressed the button, a small rollout appeared in the middle of the screen and the button got checked.
*When I pressed the button again, the dialog disappeared and the button got unchecked.

That's all it does.
What it does not do is unckeck the button if I close the dialog with its button. I might add that in the next update.
0 Likes
Message 7 of 9

Anonymous
Not applicable
Hi again,

Well I finally did get it to work, but I'm experiencing some oddities. I'm not questioning the code I'm sure it works but something else seems to be making it fail.

I initally selected the code (leaving out the macroscript definition) and drag'n'dropped it to the toolbar. Pressing the button opened the floater but did not leave the button pressed, pressing it again did not close the floater. Right clicking the button and choosing edit macro and then doing the ctrl+e thing did not solve it.
So then I copied the new working isolate selection code into the new drag'n'drop macro and pressed ctrl+e. Pressing the button now still opens the floater? Apparently the macro isn't updating in a predictable way.
So I deleted the button saved the macro as something else in the usermacros folder and changed the category from "drag'n'drop" re-evaluated and made a new button and now it works.


I found the example in the help on getting the dialog toggle to work with closing by pressing 'x'. Same thing here I copy pasted the code into an existing macro script and evaluated it but it didn't work. Then I restarted max and now it works.


I don't think my max is healthy, if i hit escape in the listener I almost always get an **interrupted** even right after startup. Any ideas on how to check what's wrong?
Is it possible to force a higher evaluation or a re-evaluation of all macro?(Just thinking loudly I'll consult the help on this)
0 Likes
Message 8 of 9

Anonymous
Not applicable
Never ever drag and drop formatted code to a toolbar.
There is a whole "MacroScripts for New Users" topic in the Reference that tries to explain how things work.

When you get an example from the Help,
*you select it ALL including the MacroScript header.
*Then you press Ctrl+E,
*right-click a toolbar,
*select Customize...,
*locate the Category of the script on the list,
*locate the script and drag it to the toolbar.
*Then optionally save the toolbar so it does not go away should Max crash before you finish the session.

Dragging and Dropping code from the Editor/Listener was meant to be used with the MacroRecorder generated code.

I tried what you described and got the same issue. I think the cause is that when DragAndDrop was implemented back in Max 3, on execute() and isChecked() handlers did not exist, so the way the code is evaluated is different. If I delete the dragged icon from the toolbar and customize the toolbar again using that same macro from the DragAndDrop category, it starts working. I suspect that the handlers don't get registered correctly when you use DragAndDrop, but I could be wrong. Anyway, if you have complex code and not a bunch of MacroRecorder lines in the pink pane of the Listener, don't drag and drop!

Also, you should NEVER EVER copy files to the MacroScripts folders. Max should do that. Anytime you evaluate code containing a MacroScript definition, you are defining an ActionItem in the Customize dialog AND its code gets managed automatically by copying to \usermacros so it can survive a restart. You are not supposed to touch those files, unless you want to delete one of them to uninstall a Macro completely.

I suspect that your Max installation is ok after all... ;)
0 Likes
Message 9 of 9

Anonymous
Not applicable
So basically what you're saying is that my favourite feature should not be used :S
I almost always start writing macros by writing a couple of lines then drag'n'dropping to the toolbar just to try things out. It is soooo convenient. But I hardly ever use the "on execute" because I thought that was old-style macro.

A lot of things are starting to clear up now, but many new questions have arisen. I'll have a good think through first though so I don't waste someones time with stupid questions.
0 Likes