import hou
# create nulls to position bone
root_null = hou.node('/obj').createNode('null', node_name = 'root_null')
root_null.setParms({'tx':0.3,'ty':0.5,'tz':0.1,'rx':66,'ry':80,'rz':-5,'geoscale':0.1})
child_null = hou.node('/obj').createNode('null', node_name = 'child_null')
child_null.setInput(0,root_null)
child_null.setParms({'tz':0.2,'geoscale':0.1})
# get null positions
root_null_t = root_null.worldTransform().extractTranslates()
child_null_t = child_null.worldTransform().extractTranslates()
# vector from root null to child null so we can rotate a vector representing our bone
# from its head to its tip, onto this vector
root_to_child_vec = child_null_t - root_null_t
# get distance of previously which will be used for the bone length
root_to_child_dist = root_null_t.distanceTo(child_null_t)
# this is the vector that represents our default bone from its head to its tip
# (which is in the negative Z by default)
orig_bone_vec = hou.Vector3(0,0,-root_to_child_dist)
# here we create a rotation matrix to rotate the vector which represents our initial bone onto
# the vector that represents root_null to child_null
root_bone_rot_mat = orig_bone_vec.matrixToRotateTo(root_to_child_vec)
# here we extarct only the rotates the that previously created matrix because we want to use it
# and the world translate values of root_null to build a new matrix that will position our bone
# correctly between root_null and child_null
root_bone_rot = root_bone_rot_mat.extractRotates()
bone_pos_and_rot_for_transf_matrix = {'translate':root_null_t,'rotate':root_bone_rot}
# build the bone transform matrix
root_bone_tansf_mat = hou.hmath.buildTransform(bone_pos_and_rot_for_transf_matrix)
# create bone
root_bone = hou.node('/obj/').createNode('bone', node_name = 'root_bone')
# set bone length
root_bone.setParms({'length':root_to_child_dist})
#transform bone with the matrix we created
root_bone.setWorldTransform(root_bone_tansf_mat)
### INITIAL BONE POS DONE. NEXT WE'LL PROPERLY ORIENT IT TO FIX X-AXIS ###
#### ALIGN BONE SO THAT THE 'X-AXIS' IS THE MAIN ROTATION AXIS. WE DO THIS USING DUMMY NULLS TO BUILD ####
#### VECTORS TO USE AS GUIDES TO ALIGN THE BONES X- AXIS WITH THE ROOT_NULL'S X-AXIS ####
#bone pre align, so that bones axes is exactly aligned with that of the root_null_t
# before we rotate the bone to fix our X axis
root_bone_pre_align_A = hou.node('/obj').createNode('null', node_name = 'root_bone_pre_align_A')
root_bone_pre_align_B = hou.node('/obj').createNode('null', node_name = 'root_bone_pre_align_B')
root_bone_pre_align_A.setInput(0,root_bone)
root_bone_pre_align_B.setInput(0,root_null)
root_bone_pre_align_A.setParms({'tx':0.1})
root_bone_pre_align_B.setParms({'ty':0.1})
root_bone_pre_align_A_t = root_bone_pre_align_A.worldTransform().extractTranslates()
root_bone_pre_align_B_t = root_bone_pre_align_B.worldTransform().extractTranslates()
root_bone_pre_align_vec_A = root_bone_pre_align_A_t - root_null_t
root_bone_pre_align_vec_B = root_bone_pre_align_B_t - root_null_t
root_bone_pre_z_rot = root_bone_pre_align_vec_A.normalized().angleTo(root_bone_pre_align_vec_B.normalized())
root_bone.setParms({'rz':root_bone_pre_z_rot})
hou.node('/obj/').deleteItems((root_bone_pre_align_A, root_bone_pre_align_B))
# bone final align
root_bone_x_align_A = hou.node('/obj').createNode('null', node_name = 'root_bone_x_align_A')
root_bone_x_align_B = hou.node('/obj').createNode('null', node_name = 'root_bone_x_align_B')
root_bone_x_align_A.setInput(0,root_null)
root_bone_x_align_B.setInput(0,root_null)
root_bone_x_align_A.setParms({'ty':0.1})
root_bone_x_align_B.setParms({'tx':0.1})
root_bone_x_align_A_t = root_bone_x_align_A.worldTransform().extractTranslates()
root_bone_x_align_B_t = root_bone_x_align_B.worldTransform().extractTranslates()
root_bone_align_x_vec_A = root_bone_x_align_A_t - root_null_t
root_bone_align_x_vec_B = root_bone_x_align_B_t - root_null_t
root_bone_z_rot = root_bone_align_x_vec_A.normalized().angleTo(root_bone_align_x_vec_B.normalized())
root_bone.setParms({'rz':root_bone_z_rot-root_bone.evalParm('rz')})
root_bone.moveParmTransformIntoPreTransform()
#hou.hscript("bonealigncapture -c *bone*")
hou.hscript('bonealigncapture -c {}'.format(root_bone.path()))
hou.node('/obj/').deleteItems((root_bone_x_align_A, root_bone_x_align_B))
Rough Python Script To Position and Orient Bone
3963 5 1-
- traileverse
- Member
- 362 posts
- Joined: Nov. 2015
- Offline
Hello, this is a rough python script to create, position and orient a bone in arbitrary space based on nulls. However, I've been careful to rotate the nulls so their axes match that of what I want for my bone axes. To the more advanced personnel, is this a good way to do this or can it be done better? If you have the time, check it out and let me know. Thanks.
hou.f*ckatdskmaya().forever()
-
- goldfarb
- Staff
- 3464 posts
- Joined: July 2005
- Offline
-
- traileverse
- Member
- 362 posts
- Joined: Nov. 2015
- Offline
Yeh thanks, didn't remember about lookat constraint lol, just thinking I need to build some sort of aim constraint(maya lingo) and lookat is there looking at me like an idiot haha. By the way, if I set up a CHOP constraint network on an object, and want to keep the values created but delete the constraint network, is baking the constraints the only way to do it?
hou.f*ckatdskmaya().forever()
-
- goldfarb
- Staff
- 3464 posts
- Joined: July 2005
- Offline
-
- traileverse
- Member
- 362 posts
- Joined: Nov. 2015
- Offline
-
- kriegmesser74
- Member
- 41 posts
- Joined: May 2021
- Offline
Raising this one from the dead... Well I have a problem... how do you get world rotations from IK chain of bones or parent blend constrained chain of bones, yes I'm trying to create triple chain IKFK switch/match...
When I use worldTransform extractRotates I'm getting some crazy values... Also I cannot use hou.parm().eval() on these bones because returned value is zero
When I use worldTransform extractRotates I'm getting some crazy values... Also I cannot use hou.parm().eval() on these bones because returned value is zero
Edited by kriegmesser74 - May 23, 2021 12:17:28
-
- Quick Links