Hey,
I've been searching through some of these threads for a solution, and whilst i've found some variation of the issue i'm having trouble getting my head around the answers given.
At the moment, I have a .mcr container script that look like this:
/* Load .ms files */
fileIn "fn01_backfaceToggle.ms"
fileIn "fn02_centerPivot.ms"
fileIn "fn03_zeroPivot.ms"
fileIn "fn04_zeroMesh.ms"
fileIn "fn05_sceneLighting.ms"
fileIn "fn06_connect_edge_vert.ms"
fileIn "fn08_bottom_pivot.ms"
macroScript backface_cull_toggle category: "Baj - Custom Max Tools" toolTip:"backface cull toggle"
(
fn01_backfaceToggle()
)
macroScript center_pivot category: "Baj - Custom Max Tools" toolTip:"center pivot to mesh"
(
fn02_centerPivot()
)
macroScript zero_pivot category: "Baj - Custom Max Tools" toolTip:"zero pivot to (0,0,0)"
(
fn03_zeroPivot()
)
macroScript zero_mesh category: "Baj - Custom Max Tools" toolTip:"move mesh to (0,0,0)"
(
fn04_zeroMesh()
)
macroScript toggle_lighting category: "Baj - Custom Max Tools" toolTip:"toggle scene lighting"
(
fn05_sceneLighting()
)
macroScript new_connect category: "Baj - Custom Max Tools" toolTip:"connect edge vert"
(
fn06_connect_edge_vert()
)
macroScript bottom_pivot category: "Baj - Custom Max Tools" toolTip:"move pivot to bottom-center of bounding box"
(
fn08_bottom_pivot()
)
Each of these call a function in the relevant .ms file. E.g.
fn fn06_connect_edge_vert =
(
/*Set up keyboard shortcut to create an edge between verts or edges*/
if subobjectLevel==1 then
(
macros.run "Editable Polygon Object" "EPoly_Connect"
)
else if subobjectLevel==2 then
(
macros.run "Editable Polygon Object" "EPoly_Connect2"
)
)
Currently, these files are all saved under the same folder ("3D Max 2014\scripts\Baj-CustomMaxTools").
Now, it seems that when I start up Max, it is creating .mcr scripts in the "ENU/usermacros" folder (which, I think that judging from the documentation is the first place scripts are called when Max is started up).
However, if I have assigned one of the macroscripts above (in the .mcr file) to a keyboard shortcut, I get the following error:
"--Type error: Call needs function or class, got: undefined"
This occurs until I manually execute the main .mcr script and then everything is fine until I restart Max.
I've tried modifying the .mcr file in the "ENU/usermacros" folder to include the .ms file but i'm still coming up with the same issue.
fileIn ((getdir #scripts) + "\\Baj-CustomMaxTools\\fn06_connect_edge_vert.ms")
macroScript new_connect category: "Baj - Custom Max Tools" toolTip:"connect edge vert"
(
fn06_connect_edge_vert()
)
I didn't want to make the script file structure too convoluted as my aim is to roll this out to 2 other modellers and make changes as and when needed (which is why I separated the functions into different files so I can modify them separately).
If I needed to do this, I guess the best way would be to pack as a .mzp and then create a new .mzp file each time I have updates to the scripts?
Cheers.
Replies
On your tools specifically, something seems inefficient about running a macro that runs a function, that runs a macro. Why not just put the operation in the macro? I think the macros.run may be language dependant.
My reasoning for having the function in a separate file to the macroscript was to keep all functions separate for organisational purposes rather than traipsing through a list of functions to find the one I need to modify.
The evaluation order was confusing me the most, until Perna pointed out that I was trying to call the function before trying to initialise it. I'm still trying to get it to work, however I guess I need to look deeper into "local vs global" as when I try to define the functions within the macroscript as global, Maxscript crashes at startup.
I havn't seen struct yet within Maxscript. I assume its somewhat similar to the class system in C# (The way you have called it looks very similar).
So do you define all your functions within a struct (within a .ms file) and then create a .mcr file that allows the functions to be set as a keyboard/interface shortcut?
If you just do operations in the macros, and not use global functions, you don't have to worry about evaluation order. I only use functions if the code is going to run more than once or from different places. But to address your issue, the global functions need to be defined before the macro is evaluated. Number one or two in this link: Start up
Structs are nice because you can have one global for all your functions. Instead of a bunch. You'll keep hearing that it's best to avoid globals, but one or two per complex tool is necessary.
Yeah, they just go in an MS file inside a Standard Script or Plugin path. But again, I only create functions if the code will be reused or executed from different locations (like a hotkey or UI). I would never create a macro that just runs a function without arguments.
BTW, this is just how I work. I think it's mostly the right way, but with small adjustments to make it faster to iterate on tools.
http://apps.jhaywood.com/Blog/?e=51577&d=07/13/2010&s=Autocomplete%20in%20the%20MaxScript%20Editor
it can be hit and miss sometimes Maybe just my copy of max hmmm
Although, the past month or so I've been using Sublime Text 2, with a package I found on Scriptspot that lets you execute scripts remotely. Then I edited JHaywood's API script to output a sublime text autocomplete file. It's a very nice setup.
See "How to install a Properties / API" section here: https://code.google.com/p/scite-files/wiki/Customization#How_to_install_a_.properties_file