Include() doesen't remove "include" in mcr after compile

Include() doesen't remove "include" in mcr after compile

Anonymous
Not applicable
456 Views
2 Replies
Message 1 of 3

Include() doesen't remove "include" in mcr after compile

Anonymous
Not applicable
I met with exactly the same problem as Jon Huhn in the following thread. Just want to know has this
"inconvenience" been fixed in max 2008 or not ?


forums.cgsociety.org/showthread.php?t=286940




Thanks for your input. But I'm still confused about something, and here's why:

Let's say you're developing a macroscript, and you're saving your working copy on a seperate drive/folder than Max's installation. However, as soon as you evaluate the script, max creates a new version of that script and stores it in its own 3dsmax/UI/MacroScripts folder with a slightly different name, which then allows the script to be registered as a macroscript. So far, so good.

But now you use an include file in your working script, and you have the refereced file in the same folder as your working copy. You evaluate the main script, and again Max makes a copy of the script and stores it in 3dsmax/UI/MacroScripts to be registered as a macroscript. However this time the entire contents of the refereced include file are now stored in the evaluated file, but the "include" statement is still present one line above it!!

There's no need for max to reference the include file in this evaluated version of the script, because it already contains the full text of the include file. So why would it STILL need to link to redundant information?







Sounds pretty obvious: Don't use include in MacroScripts

Here is why: The include() function has been around since the first MAXScript release with Max 2.0.
The MacroScripts were added to Max 3.0 and were intended to be automatically generated by the
MacroRecorder (which would never use include() anyway), and to create relatively short UI scripts. So
MacroScripts never worked well with, say, encypting or include, because they were supposed to be
machine-generated, short, or both.

Normally, when you write a MacroScript, your best strategy is to package the UI in the Macro definition
and put any extensive functions into a separate file (probably defining a structure of functions?)
which is loaded from \StdPlugs\StdScripts folder before the UI\Macroscripts directory has been
scanned.

This makes it possible to keep UI and functions separated. You can freely use include() in your
functions .ms file if it is too large. Just don't use it in .mcr files...

I would still consider the fact that the include statement is left in the final .mcr file a bug, but there might
be technical reasons for it we don't know. The only reasons I know are historical ones...







I only has access to max 8.0 now, and it is exactly the same circumstance as described in the above
thread. mxs master Bobo suggested to seperate function and ui layout code. but this just make things
a little bit more clear. The downside is still I can't access external functions in a macroscript, so i can't
really reuse functions contained in other ms script files. I have to make functions sefl-contained
functions in a macroscript itself, right?


yes i can delete the include "xxxxx.ms" line of code in the auto-generated xxCategory-xxMacroscript.mcr
file, but i then lost the ability to autoupdate when the ms script file updates...

Is this fixed in the new version of max or planned to be fixed in the future release ?
0 Likes
457 Views
2 Replies
Replies (2)
Message 2 of 3

Anonymous
Not applicable

I only has access to max 8.0 now, and it is exactly the same circumstance as described in the above
thread. mxs master Bobo suggested to seperate function and ui layout code. but this just make things
a little bit more clear. The downside is still I can't access external functions in a macroscript, so i can't
really reuse functions contained in other ms script files.
I have to make functions sefl-contained functions in a macroscript itself, right?


Wrong 🙂

As mentioned in the answer, you can create a global struct, put all your library functions in it, save the MS file to StdPlugs\StdScripts\, then access the functions from the macroscript as you would any built-in function. Since the struct is global, it gives you access to all contained functions from any script, macro or the listener, while polluting the global scope with just ONE new variable.

For example, you can say in a file MYFUNCTIONS.MS saved in StdPlugs\StdScripts

(--open local scope
global OglopFunctions --declare struct variable as global
struct OglopFunctions --define structure containing only functions
(
fn someFunction arg1 arg2 = (print arg1 + rag2),
fn anotherFunction arg1 =
(
format "You called AnotherFunction with argument %!\n" arg1
),
fn yetAnotherFunction =
(
print "That's enough!"
)
)--end struct
)--end local scope


Now you can write a MacroScript that calls any of these functions when its button is pressed - since the content of StdPlugs\StdScripts is ALWAYS evaluated before the content of the Ui\Macroscripts folder, the struct will always be visible to Macros (and any other scripts not in StdPlugs\StdScripts, all of which are generally loaded later).

So you can say

macroScript TestMyFunctions category:"Test"
(
OglopFunctions.anotherFunction "Test"
)


If you evaluate, customize a toolbar with it and press the button, you should see in the Listener:

You called AnotherFunction with argument Test!

Note that many built-in MacroScripts shipping with Max make use of this approach - StdPlugs\StdScripts is full of system libraries written in MAXScript used by other scripts to do stuff...
0 Likes
Message 3 of 3

Anonymous
Not applicable
Thank u very much , now it's clear.

just a small question.

if i have nested function definition in the struct itself, i would also add struct. before the function call right ?

I think i needn't do this, because the fn in the same struct are in the same scope. but if i call

OglopFunctions.yetAnotherFunction()

in my macro script, will yetAnotherFunction see someFunction ( if i don't put OglopFunctions. before someFunction in my struct definition)?

Btw, r u the same mxs mater Bobo on CGTALK?


(--open local scope

global OglopFunctions --declare struct variable as global

struct OglopFunctions --define structure containing only functions
(
fn someFunction arg1 arg2 = (print arg1 + rag2),

fn anotherFunction arg1 =
(
format "You called AnotherFunction with argument %!\n" arg1
),


fn yetAnotherFunction =
(
print "That's enough!"

-- nested function definition, do i need to put OglopFunctions. before function call like this?
OglopFunctions.someFunction(arg1,arg2)

)

)--end struct


)--end local scope



edit: tested this way, i have to use it like this

OglopFunctions.someFunction(arg1,arg2)

if i have nested function definition.
0 Likes