+1 tag for Google+

Saturday, 17 September 2016

PyMel: Creating and Accessing the Notes Attribute in an Object

Today I find myself wondering how I can access the 'notes' section of a Maya object using script.

I searched the internet and found out that to access the notes in an object are stored in an attribute called 'notes'. No surprises.

What surprised me, was when I went through the attributes of a newly created Maya object, I could not find that attribute!

So I do the following experiment.

Consider myObject which is a newly created object in the scene (an empty group).

from pymel.core import *
myObject = group(empty=True)

At this point, it does not contain the attribute 'notes'. The following list comprehension looks through each of myObject's attributes, and only includes attributes with 'notes' in its name in the resulting list:
[x for x in myObject.listAttr() if 'notes' in x.lower()]

This returned an empty list. It means that the attribute does not exist.
# Result: [] #

However, if I enter something into the notes section via the Maya Attribute Editor, and I run the same statement, [x for x in myObject.listAttr() if 'notes' in x.lower()]

the script editor will now display the following result:
# Result: [Attribute(u'null1.notes')] #

This means that the attribute now exists.

After further searching, I came to a useful blog post that mentions that we can create the 'notes' attribute ourselves through script:

The blog post used MEL examples, so I created the 'notes' attribute via PyMel.

if not [x for x in myObject.listAttr() if 'notes' in x.lower()]:
    myObject.addAttr('notes', dataType='string')
    myObject.notes.set('hello')

This block of code will create the notes attribute and set the value to 'hello'. In the Attribute Editor under the 'notes' section, I will be able to see the field update to contain 'hello'.

Here comes something unexpected.

At this point, if I use the attribute editor to delete the 'hello', leaving the notes field empty again, and then I run:
[x for x in myObject.listAttr() if 'notes' in x.lower()]
# Result: [] #

Maya returns an empty list again. The attribute got removed.

Now, I enter something in the notes field in the Attribute Editor again, so that it is not empty. Then I run the following to test if the 'notes' attribute exists. This time I use the attributeQuery() command:
attributeQuery('notes', node=myObject, exists=True)
# Result: True #

Maya created the 'notes' attribute again.

Now I try to give it an empty string by code (not using the Attribute Editor), to see if Maya will still remove the attribute automatically.
myObject.notes.set('')

Now we try to query the existence of the 'notes' attribute:
attributeQuery('notes', node=myObject, exists=True)
# Result: True #

The attribute exists. Maya did not remove the attribute when we set the attribute to an empty string via script.

Thus we can conclude these things about the 'notes' attribute in Maya nodes.
- in Maya, objects are created without the 'notes' attribute by default
- to use the 'notes' attribute for the first time (via script), we need to create the 'notes' attribute.
- the 'notes' attribute is automatically created when we enter something the 'notes' field using the Attribute Editor
the 'notes' attribute is automatically remove when we clear the 'notes' field using the Attribute Editor


- when we assign an empty string to the 'notes' attribute via script, Maya does not remove the 'notes' attribute

Thursday, 15 September 2016

Finding the Centre Position of a Polygon Face: Maya Python API

In the past few days I found myself having to find the position of face centres of a polygon.

Looking through the Maya documentations I find no MEL or Python commands that can do this. So I had to do a Google search the answer.

The most useful solution I found was from a discussion in Google Groups, in a reply by Justin Israel (who works in Weta Digital according to his Google+ profile):
https://groups.google.com/d/msg/python_inside_maya/UoMVxr0deVo/OJ2K8IpevxQJ

Here is an excerpt of Justin's answer:
import pymel.core as pm
import maya.OpenMaya as OpenMaya

face = pm.MeshFace("pCube1.f[64]")
pt = face.__apimfn__().center(OpenMaya.MSpace.kWorld)
centerPoint = pm.datatypes.Point(pt)

Here is another interesting article discussing how we can go about finding the centre position of a face: http://mayastation.typepad.com/maya-station/2009/11/where-is-the-center-of-a-polygon.html

Tuesday, 13 September 2016

Maya Expressions 03 - Changing Colours



In this next installment of my tutorial series on Maya expressions, We put our conditional statements to practical use by showing how we can use expressions to get the translate Y of one object to drive the colour attributes of another object.

I also show some code checking techniques by using the print command to expose useful information to the script editor, showing what is going on in our expressions during execution time, so we can ensure that flow of the execution is as we intend it to be.

I hope that it also shows that all attributes use numerical values in one for or another before they are evaluated to result in colours, vectors or on/off states.

Wednesday, 7 September 2016

The Zen of Python: Import This

I have been coding quite a bit in Python these few months.

In the midst of research and reading up, I revisited the Zen of Python. This is a set of 20 software principles that influenced the development of the language.

Having read this a few years back (it was first written around 1999), now I am seeing some of the principles in a new light. I'm still learning and finding my way around so I decided to learn more about what these principles mean to different people.

Here's a great presentation I found on Slideshare.net when I dug deeper into how different people explain each of these 20 principles in their own ways.



Incidentally I just found out that the Zen of Python is coded into the language itself. You can get Python to display this by entering this line of code:

import this

It will return the following result, right inside your interpreter:

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Tuesday, 12 July 2016

Modelling and Setting Up Rail / Roller Coaster Tracks


Upon the request of  a former colleague and good friend, I decided to post a video showing exactly how to set up a roller coaster track in Maya.

In this video I show how I go about modelling roller coaster tracks. In the video I go through the technical steps as well as the thought processes I go through my head as I tackle the task.

This video is a bit long but I believe I cover quite a bit of ground on how to handle curves, extrusion, motion path, constraints and the animation snapshot tool.

I hope you find something useful from the video