Viewing entries in
Maya

Maya: Closest Point On Mesh & Nearest Point On Curve Nodes

Maya's built in nodes library is filled with hidden gems. You may or may not know of these nodes, but these are definitely worth knowing if you find yourself wanting to get relatively located points in space on a mesh, quickly and effectively. 

The main benefit with using nodes in this manner is that it alleviates some of the obtuse nature of utilizing Maya API within a Python environment. It's also much more quick at solving positional data.

closestPointOnMesh Node

Running in either MEL or Python:

## Python ##
cpmNode = cmds.createNode("closestPointOnMesh")

If you connect a Shape node's outMesh to it's inMesh you can now enter values of "inPosition" location to receive either the closest Face Index or the closest Vertex Index.

This means you can take any vertex on your model, query it's location in world space, flip it in any axis (using axisVal * -1) , set the inPosition attributes on the closestPointOnMeshNode to those values, and you'll get essentially what the node is seeing at that point in space.

# Python
cmds.connectAttr("polyShape.outMesh", cpmNode + ".inMesh") #replace polyShape with your shapeNode's name

# have a vertex selected in the scene (limiting it to one for simplicity's sake)
vtx = cmds.ls(sl=1, fl=1) [0] 
vtxPos = cmds.xform(vtx, q=1, t=1, ws=1) # ie. result: [2, 1, 1]
mirrorVtxPos = vtxPos
mirrorVtxPos[0] *= -1 # mirror on the X axis for this example | ie. result [-2, 1, 1]

cmds.setAttr(cpmNode + ".inPosition", mirrorVtxPos[0], mirrorVtxPos[1], mirrorVtxPos[2], type="double3") # set a compound attribute

vtxIndx = cmds.getAttr(cpmNode + ".closestVertexIndex") # vertex Index. | ie. result: [34]
faceIndx = cmds.getAttr(cpmNode + ".closestFaceIndex") # face Index. | ie. result: [10]

# formatting into strings
vertexFound = "{0}.vtx[{1}]".format(shapeName, vtxIndx)
faceFound = "{0}.f[{1}]".format(shapeName, faceIndx)

#then do whatever with the formatted strings. eg. select them
cmds.select(vertexFound)
cmds.select(faceFound)

No more endless diff lists! 

In my limited experience, this node does some really great work, it's surprisingly accurate for the most part. 

nearestPointOnCurve node

This other node is super handy when you want either positions in WS on a curve or param locations on a curve. Param positions are useful when setting up things like Point on Curve Info nodes which rely on a param position.

## Python
npC = cmds.createNode("nearestPointOnCurve")

You then proceed to connect a curve's output worldSpace attribute to it's inputCurve. Then supplying an inPosition, you will get the closest  parm value and the closest position in worldSpace.

## Python

cmds.connectAttr("yourCurveShape.worldSpace", npC + ".inputCurve")
cmds.setAttr(npC + ".inPosition", 1, 2, 3, type="double3") 

wsPos = cmds.getAttr(npC + ".position")
uParam = cmds.getAttr(npC + ".parameter")

There you have it! Easy to use, and straight-forward spacial matching that will give you the data you require without having to go digging into Maya API implementation in Python.

You can either feed the nodes the data directly in these scripts, or you can of course connect other transforms to the input Position attributes and then manipulate the transform in the scene or by code, to continually have quick calculations done without having to set attribute values. 

Maya: A Precise Way of Saving Out Skin Weights With JSON

Ever wanted to export and import skin weights in Maya with precision? In this tutorial I'll take you through the steps with learning how to use JSON within Maya's Python environment, retrieving the Skin weight data from your model and then exporting it to a file. 

Read On!

Maya: Generic AnimCurve Node Renamer

Here's a handy script that can make reading set driven animation curve nodes a little easier. The issue at hand is primarily that when you are using set driven keys on an attribute that has multiple drivers, you will often see the mysterious "animCurveUU##" or "animCurveUL##" show up.

This is because when Maya sets up it's keys, it looks at the connection of the animCurve node to see what the receiving plug from on the output of the animCurve node. Thus, when you hook up a set driven key 1:1 with an attribute, you will see them labelled clearly as what the node is controlling. However, when you start introducing multiple controllers to the input, it generates a blendWeight node which only has .input and .weight plugs on it. It doesn't have a specific attribute that can be seen. Therefore, you get new curves that are generic in naming convention, and sometimes at glance are hard to parse.

Therefore, I've come up with a simple solution for renaming these nodes. I have taken the information of what the driven attribute the blendWeighted node's output is connected to, using listConnections and then using that attribute data to rename the animCurve in question. This script also has a fail safe in it for all the attributes that are already non-generic, it just skips over them to keep their naming in-tact. This sub-string recognition is very easy in Python language.

Read On

Maya: Average Align Tool

Recently I've dipped into some 3D Studio Max work. In the process of learning 3D Studio's modelling tools, I found the align objects tool highly useful.

It's premise is simple: take in an array of points and then align them to the grid by finding the "average" in the requested axis. 

Unfortunately in Maya there wasn't a button like this in the toolbar shelf. While there is the average vertices function, I found this method of control more finite and quicker . Since the premise is simple, I decided to write a set of scripts to do the same thing. All are written in Python with the simple xform.

Read On