Object too Surface Constraints in Maya

For this tutorial I'll be using a example of a button on a shirt, but this could be any object or group node like a belt buckle or a bug on the tip of a characters nose.

If you ever wanted too attach a button to a shirt on a character you've most likely found out there is no straight forward way to do this in Maya

What you want is the button to follow alone with the surface as it deforms, this deformation can be any method in Maya, softBind, ridgedBind, softbodys,cloth etc.......

I'll discuss different methods of doing this based on;

  • The surface type ie...polys, nurbs and subD's:
  • In Maya tools vs mel, plugs-ins and scripts:
  • Pros and cons of each method:

Method One: In Maya Tools

What I mean by this are tools that are accessible from within Maya with out using mel or plug-ins

This will work for Polys and Nurbs surfaces ...Sorry no subD work flow that I can think of.

Pick a poly edge or nurbs surface isoparm on your shirt and go:

Edit Curves->Duplicate Surface Curves

At this time I like to zero transform my button

Know pick your button and shift select your new edge curve

Go to Animation->Animate->Motion Path->Attach to Motion Path and open the option box

Set Time Range to Start

Turn Follow off

Now Attach

Now your button should be attach to the curve.

This curve will update because of construction history and when your shirt deforms the button will follow alone.

Hint: use insert too change the pivot point this will allow you to offset the button from the curve.

But wait were not done:

Now pick your shirt and Shift select your button and add a Normal constraints

Hint: if you enter the scale tool you can see what your aim and up vector should be

That's it ... If you like you can pick the motion path node on your button and play with the U value to slide your button on the curve for a better position.

You'll have to edit the U value if your doing this workflow on a nurbs surface

Option: you could also use a point constaint too the curve rather than a motion path node

Pros:

  • All done with tools in Maya
  • No mel or plug-ins

Cons:

  • Update can be a little slow
  • Lots of extra curves
  • No subD workflow

Method Two: Expressions

I'm not going to go into detail because they are better ways to do this (like method one and method three) But: this is a good opportunity to introduce you to the xform function in mel.

xform is a great mel command that will allow you to set and query the location of any object or component in object and world space

this will allow us to query the location of a given component in word space and apply those coordinate values to an object (ie. a button)

the basic command is:

xform -q -t -ws pSphere1.vtx[278]

-q = query

-t = translate

-ws = worldSpace

pSphere1.vtx[278] is the vertex number

This will work on poly, nurbs and subDs, not very useful for nurbs in this case as any CV you query is always off the surface. On ploys and subD's you can also query the UV. and on subD's you can query inside the hierarchy (level 1 and 2 and 3 and ........ vtx's and uv's)

for example:

xform -q -t -ws subdivSphere1.smm[609];

// Result: -0.503906 0.648047 0.648047 //

To make this into a useful expression we need to do a few things. Get the xform function to return its world space coordinates so we can use them to apply to our target object ... Pretty simple.

float $where[] = `xform -q -t -ws pSphere1.vtx[278]`;

button.tx = $where[0];

button.ty = $where[1];

button.tz = $where[2];

I never took the time to find out how you can keep it normal to the surface using an expression, with polys you can use a normal constraint but not on subD's

Pros:

  • Pretty simple expression.
  • Only way to attach to a subD with out using a plug-in.
  • Gives you the ability to attach to a vtx and uv's and on subD's in side the hierarchy (level 1 and 2 and 3 and .......)

Cons:

  • Expression only updates if you BURP the time line.
  • Not very useful for nurbs and no normal constraint for subD's.

Method Three: Special Nodes

This Method will be divide by surface type Nurbs, Polys and subD's.

This is my preferred method for Nurbs and Polys.

I whish these nodes where accessible from the Maya GUI, maybe 5.0 will have them......tell then.

Part One: Nurbs and the pointOnSurfaceInfo node

Maya supplies this node with the software but its only available through mel.

Open the script editor and type:

createNode pointOnSurfaceInfo

You will now find this node in the outliner.

turn display ->DAG objects only off

This node will evaluate the UV off the surface and return info in world space coordinates.

Now we need to give this node an input surface, pick your shirts shape node and open up the connection editor go ... Reload Left

Now pick your pointOnSurfaceInfo node and ...Reload Right

Connect the shirtShape.World Space to the pointOnSurfaceInfo.input surface

now pick your pointOnSurfaceInfo node and Reload Right and the pick your button and go Reload Left

Warning: make sure your button is at world zero and is zero transformed or else your button will be off the surface

now connect the pointOnSurfaceInfo Results->Postion too the translate of your button.

Now open your pointOnSurfaceInfo node in your Attribute Editor and adjust your parameter U and V

Hint: if you need to know the exact location for the U and V right click on the surface and pick a surface point the resulting UV position will show up in the script editor

That's it ....the next step would be to apply a Normal Constraint.

You could also play around with the normal info supplied by the pointOnSurfaceInfo and connect this to the rotate of your button (I don't like this though seems hard to control)

This whole process could easily be scripted and I was going to write one but there are a few out on the web already done.... named below.

Part Two: Polys and the pointOnMeshInfo node

First: this node is a plug-in; you can find it in the devkit. The Alias/Wavefront web site has a compiled version of the devkit for download. Second; I've run into situations were it doesn't eval correctly I don't know why this happens but; if so: revert to method one.

Load the plug-in

Now the work flow is similar to the pointOnSurfaceInfo node set up.

createNode pointOnMeshInfo

This time your connecting the:

shapeNode.worldMesh to the pointOnMeshInfo.inMesh

Warning: make sure your button is at world zero and is zero transformed or else your button will be off the surface

Then your connect the:

pointOnMeshInfo.postion to the translate of your button

Now open your pointOnMeshInfo node in your Attribute Editor and adjust your FaceIndex

That's it ....the next step would be to apply a Normal Constraint.

Hint: if you pick a face the script editor will tell you the index number

Part Three: SubDs and the pointOnSubd node

This node is also a plug-in in the devkit.

CreateNode pointOnSubd

This time you connect the shapeNode.World Subdiv to pointOnSubd.Subd then you connect pointOnSubd.point to the translate of your button. Then adjust your UV value.

Sorry I don't know a way to achieve a normal type constraint on a subD

Pros:

  • All 3 of these nodes evaluate fast
  • The cleanest method

Cons:

  • Not accessibly from the Maya GUI
  • Only the pointOnSurfaceInfo is standard in Maya
  • Painful workflow
  • No normal constraint for subD's

Other Resources

checkout the scripts on Highend3d.com

Rivit1.0 By Michael Bazhutkin

Poly Surface Constraint v0.1 By Hamish McKenzie