With the latest versions of Maya creating and manipulating pivots have become far easier with native tools. Though, I've yet to see a process to do exactly what I've been looking for. I've written a fairly simple script to achieve what I've found to be the most intuitive approach to creating a bone with the position and orientation that I desire.
Here is a brief walk through of how I create bones using a custom pivot. The script I use can be found below.
Character Model by Chris Wells
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import maya.cmds as cmds | |
import pymel.core as pymel | |
def create_pivot_bone(): | |
""" | |
Create a bone from the customPivot context | |
In component mode of a mesh: | |
Press "D" or "Insert" to go into custom pivot context | |
If you click on edges verts or faces the pivot will auto align | |
If you want to aim an axis click on the axis and Ctrl+Shift on another vert/edge/face to aim it | |
When you have the pivot you want run this to create the joint with that pivot | |
*Arguments:* | |
* ``None`` | |
*Keyword Arguments:* | |
* ``None`` | |
*Returns:* | |
* ``None`` | |
*Author:* | |
* randall.hess, randall.hess@gmail.com, 9/3/2017 5:17:19 PM | |
""" | |
# get these values | |
loc_xform = None | |
loc_rp = None | |
# Get manipulator pos and orient | |
manip_pin = cmds.manipPivot(pinPivot=True) | |
manip_pos = cmds.manipPivot(q=True, p=True)[0] | |
manip_rot = cmds.manipPivot(q=True, o=True)[0] | |
# delete existing temp objs | |
temp_joint = None | |
temp_loc = None | |
temp_cluster= None | |
temp_joint_name = 'temp_joint' | |
temp_loc_name = 'temp_loc' | |
temp_cluster_name = 'temp_cluster' | |
temp_objs = [temp_joint_name, temp_loc_name] | |
# get the selectMode | |
sel_mode_obj = cmds.selectMode(q=True, o=True) | |
sel_mode_component = cmds.selectMode(q=True, co=True) | |
# store and clear selection | |
selection = cmds.ls(sl=True) | |
py_selection = pymel.ls(sl=True) | |
if len(selection) == 0: | |
cmds.warning('You must have a selection!') | |
return | |
if len(selection) > 0: | |
sel = selection[0] | |
py_sel = py_selection[0] | |
# create temp joint and set pos/rot | |
cmds.select(cl=True) | |
temp_joint= pymel.joint(n=temp_joint_name) | |
temp_loc = pymel.spaceLocator(n=temp_loc_name) | |
# get transform from the selected object | |
if type(py_sel) == pymel.nodetypes.Transform: | |
# snap loc to position | |
const = pymel.pointConstraint(sel, temp_loc, mo=False, w=1.0) | |
pymel.delete(const) | |
const = pymel.orientConstraint(sel, temp_loc, mo=False, w=1.0) | |
pymel.delete(const) | |
else: | |
# get transform from parent object | |
if type(py_sel.node()) == pymel.nodetypes.Mesh: | |
parent = py_sel.node().getParent() | |
if parent: | |
const = pymel.pointConstraint(parent, temp_loc, mo=False, w=1.0) | |
pymel.delete(const) | |
const = pymel.orientConstraint(parent, temp_loc, mo=False, w=1.0) | |
pymel.delete(const) | |
# get the transforms | |
loc_xform = pymel.xform(temp_loc, q=True, m=True, ws=True) | |
loc_rp = pymel.xform(temp_loc, q=True, ws=True, rp=True) | |
# rotate the temp_loc if manip rot has been modified | |
if not manip_rot == (0.0,0.0,0.0): | |
pymel.rotate(temp_loc, manip_rot) | |
# move position to the cluster position | |
if not manip_pos == (0.0,0.0,0.0): | |
pymel.xform(temp_loc, ws=True, t=manip_pos) | |
# get the transforms | |
loc_xform = pymel.xform(temp_loc, q=True, m=True, ws=True) | |
loc_rp = pymel.xform(temp_loc, q=True, ws=True, rp=True) | |
# get the position from the component selection | |
if not type(py_sel) == pymel.nodetypes.Transform: | |
cmds.select(selection, r=True) | |
cmds.ConvertSelectionToVertices() | |
try: | |
cluster = cmds.cluster(n=temp_cluster_name)[1] | |
except: | |
cmds.warning('You must select a mesh object!') | |
pymel.delete(temp_joint) | |
pymel.delete(temp_loc) | |
return | |
# get the cluster position | |
cmds.select(cl=True) | |
pos = cmds.xform(cluster, q=True, ws=True, rp=True) | |
# snap to the cluster | |
const = pymel.pointConstraint(cluster, temp_loc, mo=False, w=1.0) | |
pymel.delete(const) | |
cmds.delete(cluster) | |
# rotate the temp_loc if manip rot has been modified | |
if not manip_rot == (0.0,0.0,0.0): | |
pymel.rotate(temp_loc, manip_rot) | |
# move position to the cluster position | |
if not manip_pos == (0.0,0.0,0.0): | |
pymel.xform(temp_loc, ws=True, t=manip_pos) | |
# get the transforms | |
loc_xform = pymel.xform(temp_loc, q=True, m=True, ws=True) | |
loc_rp = pymel.xform(temp_loc, q=True, ws=True, rp=True) | |
# remove temp loc | |
pymel.delete(temp_loc) | |
# modify the joint and stu | |
if temp_joint: | |
if loc_xform and loc_rp: | |
pymel.xform(temp_joint, m=loc_xform, ws=True) | |
pymel.xform(temp_joint, piv=loc_rp, ws=True) | |
# freeze orient | |
pymel.select(temp_joint) | |
pymel.makeIdentity( apply=True, translate=True, rotate=True, scale=True, n=False ) | |
# unpin pivot | |
cmds.manipPivot(pinPivot=False) |
This is good stuff! Thank you for sharing!
ReplyDelete