While I have some experience with coding in general with things like PHP and even some 3d coding experience with MEL and python in Maya, I’ve yet to dive into doing any scripting within MODO. So I thought I’d go about trying that out as it’s my main 3d app of choice. After a quick refresher in Python at www.codeacademy.com, I headed over to sdk.luxology.com to brush up on scripting in MODO, figuring it’d be pretty easy to transfer over what I knew from Maya. Wow was I in for a wake up call. Maybe it’s just me, but the wiki feels unorganized, and in general not very helpful, especially when compared to something like this: http://download.autodesk.com/us/maya/2011help/CommandsPython/. With that in mind, here’s what I was able to do just poking around.

Let’s start with what the script does.

  1. It creates a random from 1 to 10
  2. Creates that many cubes
  3. Each Cube is randomly placed within the scene from 0 to 10 on the X, Y, and Z axis.

Not terribly exciting, but everyone has to start somewhere. How do we start? Within MODO, go to System > Open User Scripts Folder. MODO will open the folder where all of your scripts should be placed. In a texteditor, create a file called randomCubes.py and save it in that location. Switch back over to your text editor. Since we’ll be using Python for this example, we’ll need to let MODO know that we’re writing this in Python. Why it can’t tell that based on the extension of the file I haven’t a clue, but type the following code into your text editor on line 1:

#python

Make sure that line is at the top of every Python script you write for MODO, or it won’t work. Going back to the description of our script, let’s start with step 1 of creating a random number from 1 to 10. Add the following line of code to your file:

import random
num_cubes = random.randint(1,11)

This is just plain Python. What we’re doing here is using the Python function randin() to generate a random number from 1 to 10 (inclusive, which is why it’s going out to 11) and assigning that to the variable “num_cubes” so we can use that later. So now that we’ve got our random number, we need to start making some cubes. How do we do that? Well it looks like a lot of this due to lack of documentation of MODO commands is performing a command and seeing what the result is. In the menu bar go to Layout > Palettes > Command History. Using the tabs at the top you can see a history of the commands you’ve performed, as well as a list of all commands available within MODO. For now, click on the Command History tab.

modo-command-historyUsing the modeling tools, create a cube that’s 1 m x 1m x 1m at the origin (remember to click the apply button). Once you’ve done that, switch back to the Command History window. You should see the following commands that were used to create that cube.

modo-commands-cubeThe middle column is what we’re interested — those are the commands that MODO is firing internally to create the cube. So we know what the commands are, but how do we use that within our Python script? MODO comes with a number of helper libraries, one of which being lx, which contains a number of functions that allows Python to communicate with MODO. What looks to be the most important function available is eval() which allows you to evaluate MODO commands, like the ones we saw in the Command History. Back in your Python script, under “#python”, add the following line of code to import the lx library:

import lx

Now to make a cube. According to the Command History, the first thing we need to do is activate the cube tool with the command “tool.set prim.cube on”. To use that within our script, add the following line:

lx.eval('tool.set prim.cube.on')

The next thing the happened was that MODO set the value of the position of the cube to 0 on the X, Y, and Z axes. We can do that by adding the following code:

lx.eval('tool.attr prim.cube cenX 0')
lx.eval('tool.attr prim.cube cenY 0')
lx.eval('tool.attr prim.cube cenZ 0')

See where is says 0 on every one? That’s what you’re setting the value cenX, cenY, and cenZ to. If we look at step 3 of our description, we didn’t want our cubes at the origin, we wanted them randomly distributed from 1 to 10 on each axis. To do that, change your code so it looks like this:

lx.eval('tool.attr prim.cube cenX %s' % random.randint(0,11))
lx.eval('tool.attr prim.cube cenY %s' % random.randint(0,11))
lx.eval('tool.attr prim.cube cenZ %s' % random.randint(0,11))

Here, we’re replacing those zeros with a random integrer from 0 to 10 (inclusive). Next in the Command History was setting the size of the cube in the X, Y, and Z axes. Do that in our script by adding the following code:

lx.eval('tool.attr prim.cube sizeX 1')
lx.eval('tool.attr prim.cube sizeY 1')
lx.eval('tool.attr prim.cube sizeZ 1')

Finally, the last thing that happened was that the tool was applied, using the command “tool.doApply”. Do that in our script by adding the following code:

lx.eval('tool.doApply')

Great! Our script will create a single cube and randomly place it from 0 to 10 on each axes. Close, but not quite what we were doing. We now need to loop over the creation of the cube so that it’s performed a number of times we stored in our variable “num_cubes”. To do that, we’ll take our code for creating the cube, and enclose it within a for loop going from 0 to num_cubes. Look at the (finished) code below to see what I mean:

#python

import lx
import random
	
num_cubes = random.randint(1,11)

for i in range(num_cubes):
	lx.eval('tool.set prim.cube on')
	lx.eval('tool.attr prim.cube cenX %s' % random.randint(0,11))
	lx.eval('tool.attr prim.cube cenY %s' % random.randint(0,11))
	lx.eval('tool.attr prim.cube cenZ %s' % random.randint(0,11))
	lx.eval('tool.attr prim.cube sizeX 1')
	lx.eval('tool.attr prim.cube sizeY 1')
	lx.eval('tool.attr prim.cube sizeZ 1')
	lx.eval('tool.doApply')

The script is now complete. Save it, and in the textbox at the bottom of the Command history, type “@randomCubes.py” (using the @ symbol is how to call scripts within your user directory). You should see some cubes appear in your scene. You keep running the command to create more and more cubes. To be honest, it’s not a terribly existing script, but it does build some fundamentals for making more complicated scripts.

  1. We need to include #python at the top of any Python script so MODO will recognize it as Python
  2. We can see what commands MODO is using by performing the action manually and then looking at the command within the command history
  3. We can run that command in Python by enclosing it the function lx.eval()