Posted by Christopher Diggins, 26 October 2012 3:55 pm
[EDIT: Nov. 12, 2012 I've updated the editor to fix a bug in the editor and include the source code]
For impatient 3ds Max developers the ability to compile and run C# programs from within 3ds Max without having to restart it can be very useful. Since I am about as impatient as they come I developed a simple plug-in for 3ds Max that allows me to edit and run C# programs as if they were scripts.
You can download the C# script editor plug-in and source code here. To install it copy the plug-in DLL file (and optionaly the PDB debug database) into the "binassemblies" sub-folder of your 3ds Max 2013 installation. This should work on both 32-bit and 64-bit flavors of 3ds Max.
Next you will have to "unblock" the DLL (at least for Windows 7, I'm not sure if it is required for Vista). Right click on the file in Windows Explorer after copying it to the "binassemblies" folder and press the unblock window.
When you restart 3ds Max, you will have a new user action in the category ".NET Plug-ins" that you will need to associate with a shortcut key or menu item. The plug-in should work for both 32-bits and 64-bit flavors of 3ds Max, but won't work on 3ds Max 2012 or earlier.
I've also included a sample program called "DemoScript_BentCylinder.cs" that you should be able to run from the editor.

The following code compiles the source code of one or more files each passed as a string.
/// Looks for and executes a public static function named Main by searching all types in the assembly.
/// If more than one Main function is found or no Main function is found an exception is thrown.
public static void RunMain(Assembly asm, params string[] args)
{
MethodInfo main = null;
foreach (var t in asm.GetTypes())
foreach (var mi in t.GetMethods(BindingFlags.Public | BindingFlags.Static))
if (mi.Name == "Main")
if (main != null)
throw new Exception("Multiple Main methods found");
else
main = mi;
if (main == null)
throw new Exception("No static public Main method found in assembly");
main.Invoke(null, new object[] { args });
}
/// Compiles source code given the language provider (e.g. CSharpCodeProvider or VBCodeProvider).
/// The named assemblies are referenced. The contents of each source code file is passed as a
/// separate "input" string. Returns the generated assembly if successful or a list of errors.
public static CompilerResults Compile(CodeDomProvider provider, IEnumerable<string> assemblies, params string[] input)
{
var param = new System.CodeDom.Compiler.CompilerParameters();
param.GenerateInMemory = true;
foreach (var asm in assemblies)
param.ReferencedAssemblies.Add(asm);
return provider.CompileAssemblyFromSource(param, input);
}
If compilation is successful the generated assembly is returned as part of the CompilerResults. Once you have the assembly you can invoke the Main entry point as long as it is a public static method of any public type using the following bit of reflection magic:
public static void RunMain(Assembly asm, params string[] args)
{
MethodInfo main = null;
foreach (var t in asm.GetTypes())
foreach (var mi in t.GetMethods(BindingFlags.Public | BindingFlags.Static))
if (mi.Name == "Main")
main = mi;
if (main == null)
throw new Exception("No static public Main method found in assembly");
main.Invoke(null, new object[] { args });
}
The rest of the code in the plug-in is pretty unremarkable but. I'd love to hear if this tool (or some derivation) finds its way into your toolbox.
Please only report comments that are spam or abusive.
11 Comments
Hirazi Blue
Posted 30 October 2012 10:14 am
Hirazi Blue
Posted 30 October 2012 12:40 pm
Christopher Diggins
Posted 30 October 2012 2:19 pm
Hirazi Blue
Posted 30 October 2012 7:33 pm
That's what I thought too, but then someone (or actually two people) pointed me to the following page in the Softimage SDK documentation that actually does seem to do something very similar: http://bit.ly/YjW5fB
Ainur
Posted 31 October 2012 11:06 pm
Keep up the impatience!
Can this plugin be adapted for IronPython?
I really like the idea of using the python language to build tools, especially with UI designers like the WPF/XAML stuff in VS...
I tried to compile a simple IronPython script with a simple XAML ui, and the assembly build worked, but 3dsmax would not accept the generated assembly...
Christopher Diggins
Posted 2 November 2012 6:54 pm
@Ainur I'm pretty sure that the code could be adapted to support IronPython. I wrote a similar tool for 3ds Max 2012 SAP. So you can use the source code from both. I have never tried to create an IronPython assembly, so I don't know what could be causing the problem.
Caspar Philippo
Posted 9 November 2012 10:28 am
Is it also possible to compile a 'standalone' plugin with this method?
Jeff_Hanna
Posted 9 November 2012 4:15 pm
Christopher Diggins
Posted 13 November 2012 3:49 am
sinushawa
Posted 15 January 2013 9:38 am
I am having a problem with the del key not working in max viewport once the scriptEditor has been run and can't seem to find in the source code where it could come from, any idea?
Christopher Diggins
Posted 15 January 2013 5:36 pm
The problem is probably related to the fact that main form derives from MaxForm. The problem is a conflict between handling key presses in Max and in the editor. I'm not sure how to resolve the issue, and I won't be able to investigate it in the short-term.
@caspar
Sorry for the long delay. No you can't compile a standalone plug-in at the current time.
Add Your Comment
You must be logged in to post a comment. Login or Register here