• 2018-01-06 18:06:21
  • Yonseo
  • 0Hits

Coding in Modo (Python)

A look at Coding in Modo from an artist perspective

When you look at modo the first thing you're going to use is the command window (on the left) and the event log (on the right). The command window is where you will be typing commands and python files to execute a script. The event log is where the party is happening. This is where we can test if our script is working and see the events happening in our scene. It constantly updates when something new happens.  

Our first command

To give you an example lets execute our first command. Type this into the command window.
item.create locator
A locator is created in the 3D view. Imagine if we had to create 100 of these. We could have done this manually, but that's what scripting is all about, automating.  

Writing a script

To write a script simply create a text file and name it file.py make sure the extension ends with .py and not .txt For this tutorial you will need a text editor to type code. I use Brackets, a free and open source editor with extensions which can be found here. It works on Windows, Mac, and Linux. Inside file.py type
# python import lx lx.eval('item.create locator')
import lx simply means the modo extensions to Python are encapsulated in the lx module. According to the wiki starting with modo 301 both this and sys are now implicitly imported. Which means we don't need to include import lx in our script file, I prefer to include it. You can see the command to create a locator is wrapped inside lx.eval('') Now everytime you want to write a command in a script simply type your command inside lx.eval('')

What is lx.eval()

lx.eval() will evaluate our command.

What is lx.out()

lx.out() will print out the result.

How to execute a python file in Modo

Jump over to Modo and open the user script folder.   This is where we will save our scripts to use in Modo. Now in Modo's command window we simply type @ and the name of our file.py
If you saved your file inside a folder then you will have to type:
If you look at the event log you will notice that our script has been executed. It will display the command we typed, in our case it was '@file.py'. We wont get much more information than that. So to display some information lets modify our script file.
# python import lx lx.eval('item.create locator') locNum = lx.eval('query sceneservice locator.N ?') lx.out('The are %s locators' %locNum)
Remember to save and let's try this again. This time our script will create a locator and the event log will tell us how many locators are available in the scene. To execute the script again you can click on the command window over @file.py, this is much faster then typing our file name repeatedly.  

The commands and how they work

The command used to know how many locators are in the scene is:
query sceneservice locator.N ?
There are many commands and many of them are similar, for example If I wanted to know how many items are in the scene I would use this command:
query sceneservice item.N ?
As you can see they're not that different from eachother. We can use this command to query the number of items in the scene for any type of item. The question mark tells us we want to know something and what we want to know is what the command is asking. The .N tells the command we want a number and the word before .N is the type we are asking for, so we can replace this word with others such as bezierNode or mesh.
query sceneservice bezierNode.N ?
query sceneservice mesh.N ?

What if we don't know what type of item it is?

Each item available in the scene has an index and an id. We can get any item by either calling their index or the id. This can get a little tricky if you're new to programming. However that is what makes coding fun, you are provided with the tools and you have to build it yourself. So if the item type is on top of Mount Everest then you're going to need some good tools to get there. So we know the command to figure out how many items are in the scene, great! Now lets use this information to find the item type. An item type can be easily found with this command:
query sceneservice item.type ? 0
This command will get the first item, in other words the item with index 0. Then the event log will print out the item type. It's important to know that Modo's items start at 0 and increase so the first item on the list is number 0 not 1. This number is called the index and is placed after the question mark.

A command with no number

Lets look at another command. Notice how there is no number after the question mark. If the item with index 0 is of the type: mesh and we try the following command with no index
query sceneservice item.type ?
We will get a type: mesh which means it will always be type: mesh everytime unless we query an item with an index.
It's important when using a command to ensure you include either an index, name, or id.
This is not always the case, when using the command to find the total number of items query sceneservice item.N ? it is not necessary to include an index, name, or id. Be attentive.

Finding the item Type

Create a new file and name it findtype.py
#python import lx itemNum = lx.eval('query sceneservice item.N ?') list = range(0,itemNum) for i in list :     itemSel = lx.eval('query sceneservice item.isSelected ? %s' %i)     if itemSel == 1 :         itemType = lx.eval('query sceneservice item.type ? %s' %i)         lx.out(itemType)
With this script we can find the selected item type. If we do not have an item selected then it will not work so make sure to select an item in the scene or the hierachy.

Understanding the Code

Let's dissect this code to understand what is happening so you can create your own scripts!. First we have the variable itemNum which will be the number of items queried in the scene. Then we have a variable list which will create a list starting from 0 to itemNum. So if we have 5 items in our scene then itemNum = 5.
Let's look at line 5
For every index in the list execute the following code. We can also think of this as for every number in the list or for every item in the list. What's important to know is that i is a number and can be named index.
for i in list :     itemSel = lx.eval('query sceneservice item.isSelected ? %s' %i)     if itemSel == 1 :         itemType = lx.eval('query sceneservice item.type ? %s' %i)         lx.out(itemType)
This will loop 5 times since we have 5 items in the scene, if we had 10 items in the scene then it will loop 10 times, etc. The variable i is an integer or a number that starts at 0 and ends at itemNum.
Let's look at line 6
The variable itemSel will return with a value of 1 or 0, it will never be higher or lower, it simply means true or false. If we get a 1 it means true and a 0 means false. I am checking if the current item is selected or not.
Let's look at line 7
If itemSel is true then execute the following code
Let's look at line 8
This is where we can check the item type! Many lines of code just to get to this.
Let's look at line 9
Finally we can print out the itemType

Down the Rabbit hole

If you've turned yourself into a pickle and you can't figure out any commands, try this:
query sceneservice item ?
  try this:
query sceneservice locator ?
try this:
query sceneservice mesh ?

You get the idea, Read the event log!

This is the end for basics in Modo's Python, there's a lot more to learn so head on over to Pixel Fondue and remember to check the wiki for more Modo Python. - yonseo

Copyright © 2016 Yonseo.com