Sunday, April 29, 2012

C# action item plugin for 3ds Max

It has been a while since the last time when I made some good progress on my 3D project. My guess is that I have had a lack of motivation and clear planning. And recently Sam has got a brilliant idea which should resolve most of my issues! We are doing Agile now!

Having a list of goals for a relatively short period is a good motivation for me: I work very well having visible and reasonable deadlines. And dealing with clear and shorter tasks helps to go forward with "baby steps". This is important given that I work on this project in my spare time.

So, here is my plan for this 3 week iteration! It has only one story: Creating a plugin that imports OBJ files into my scene.

You may want to ask - why do I need to create a whole plugin for a task that can be performed by simply clicking the Import menu? Well, due to our work process, I need a more sophisticated import procedure. I want to update the existing objects rather than delete and re-create them. Sam does modeling and I do texturing, and it is important to bring in his changes without deleting any material that are already in the scene.

So, my plugin will work in the following way. It will look up for the existing objects that are about to be updated and will rename them if necessary. Then it will proceed with the import. After the import is done, it will grab all the materials of the old objects and apply them to the new ones. After that, the old objects can be deleted.

This is the long term task. In this iteration I aim for a simpler goal: a simple, straightforward import of OBJ files. OBJ is a standard 3D object file format which we use to exchange files between our applications. I just want to familiarize myself with writing action item plugins and with the file import SDK.
And it is so super-easy to write these plugins with the new .NET SDK! I will show you how :)

First of all, I downloaded the Microsoft Visual C# 2010 Express from here. It is a free tool from Microsoft to create C# applications.

Then I went to the online SDK help to read how to create .NET plugins.

According to the help, I only needed to create an assembly project with a class that would implement the ICuiActionCommand interface. Once the dll is compiled, it should be placed to the bin\assemblies folder. The next time Max is launched, it will dynamically load it and register an instance of the class as an action in its CUI interface. Very simple!

In reality it was too, except that back then, when I started working on this, the online help had a bug. It said: "This is done by creating a public class that implements the interface ICuiActionCommand (found in MaxCustomControls.dll)". But it was not true! MaxCustomControls.dll did not have it! I searched all the help from the beginning to the end, and everywhere it was said the same thing. It was  pretty frustrating! Then I decided to text search my class name in the Max .NET assemblies, since they all have a textual description of the interface. And I found my class! It was hiding in the UiViewModels.dll, the namespace UiViewModels::Actions. UiViewModels was not documented at all; fortunately, this bug is fixed now.

I quickly implemented the action item interface, created a simple "Hello, World!" WPF form... And here is my action in 3dsMax!

I put a button with my action on the toolbar and launched the plugin:

Here is the code behind it (I omitted the window code, since it is trivial):

As you see, the code that launches the window is located in the Execute() function.
That's it! I am done with the action item plugin!

Now I need to write a simple import procedure, and this will be the subject of my next post.
Stay tuned!

No comments:

Post a Comment