Jump to content
jim c

Question on flipping bones and orientation

Recommended Posts

I'm trying to write a script that creates a rig from a series of points, i.e. basic points that make up the key places where the bones would go, pelvis, spine, bicep, forearm, etc.

I have most of it working excpet for a problem in the spine (which may be cropping up elsewhere too). When the bones are generated some of them are flipping 180 deg on the z axis, so they look OK visually, but when you rotate them in X the values are negative from the other spine bones, which is annoying and problematic. Now I could hard code the script to look for this and if it finds a "flip" i.e. Z rot == 180, to just set it back to 0, but this seems like a hack and I'm wondering whats going on that I'm doing wrong?

I'm creating the bone like so, where parent is the bone or null that the new bone is going to be parented to, and pt1 is the start point, pt2 is the end point (used to calc the bone length) and lookAtObj is is the Obj that the bone will look at, to control orientation.

def createBone(parent, pt1, pt2, boneName, lookAtObj ):
	print "setting bone name: " + boneName+"_bone"
	v1 = pt1
	v2 = pt2
	bone = hou.node(containerPath).createNode("bone")

	boneLen = v1.distanceTo(v2)
	bone.parm('length').set(boneLen)

	bone.setName(boneName+"_bone")

	if parent is None :
		bone.parm('tx').set(v1[0])
		bone.parm('ty').set(v1[1])
		bone.parm('tz').set(v1[2])
	else :
		bone.setFirstInput(parent)

	if not lookAtObj is None :
		rm = bone.buildLookatRotation(lookAtObj)
		bone.setParmTransform(rm)

	setupDefBoneRegions(bone)

	bone.moveParmTransformIntoPreTransform()
	bone.parm("Rx").set(0)
	bone.parm("Ry").set(0)
	bone.parm("Rz").set(0)

	return bone

I presume the issue is with buildLookatRotation? Or maybe there's something stupid about how I'm approaching this? If it's more helpful I can post the full script and scene.

I've added this illustration to show where it goes wonky, maybe it will make more sense to some?

post-4235-0-60894300-1385248394_thumb.jp

Edited by jim c

Share this post


Link to post
Share on other sites
Guest mantragora
If it's more helpful I can post the full script and scene.

This.

Share this post


Link to post
Share on other sites

OK, here goes. You need to load up the scene, then install the shelf tool, and then run the tool. I've commented out some of the other parts, so it just focuses on the back for the moment. Attached in the zip is the scene and script.

rig-generator.zip

Share this post


Link to post
Share on other sites

Oh, and note that for the moment I've flipped the z rotation in makeSpine(), which does fix the problem at the moment, but I'm sure it's not the best approach.

Share this post


Link to post
Share on other sites
Guest mantragora

I haven't looked what's going on inside yet, but I'm throwing some idea(and question) here:

- Why you create spine bones one by one instead of creating line and calling bonesFromCurve tool?

Edited by mantragora

Share this post


Link to post
Share on other sites

I think object lookats are a bad idea for bones unless you set an appropriate up vector. I think using curve ik is the best for spines. You can add normals to the curve to control the up vector.

Share this post


Link to post
Share on other sites

Well the idea was to use a couple of points/nulls to define the basic spine shape/length/position. Then create a temp curve from that, and resample it, and then create the real set of nulls that would be used to generate the bones. The final goal is that this will live in a DA that you plop in your scene, position the basic point,s and then hit a button to generate the rig from. It will automatically generate the mirror bones (right side) and add stuff like a basic IK setup for arms and legs, fk controls, etc.

@edward the lookats are just temporary things to figure out the correct transform. If I use a normal, then what is the appropriate normal to generate? Do I want the normal from pt2 - pt1 ?

Share this post


Link to post
Share on other sites
Guest mantragora

So? I still don't get why you can't use it to setup spine. You need only this to make it happen:

# call this from shelf, your curve needs to be selected
import objecttoolutils as jim
jim.customStateTool(kwargs, 'bonesfromcurve')

And you have your spine. The only problem I see is to generate some specified amount of bones in this spine. This tool allows you to change amount of bones but I don't know is there a way to pass it somehow to this tool. You can modify amount in viewport after tool is executed so maybe if you set you spine at the end it will not be a problem.

Or maybe Graham knows some way to pass some value to this tool.

This is not even a tool, this is some custom state that probably calls series of tools, so maybe we could dig a little more into it to see can we create our custom state. States are a mystery, it would be nice if someone could explain them a little more. It calls "bonesfromcurve" but what it is? Can we modify it?

BTW. If you are curious how I know correct command to call it (since it's not a node so you can't MMB on it to see it's name) look into your:

InstallDir\Houdini X.X.X\houdini\toolbar\ObjectStateTools.shelf

file. If you can't find some tool because it's not a node you can check this toolbar directory to find out.

Edited by mantragora

Share this post


Link to post
Share on other sites

Ahh, no I did NOT know how to do that. Probably a number of things I could do with knowing that.

Share this post


Link to post
Share on other sites

OK so there's one catch, yes, that will activate the tool, but then it sets there waiting for user input, not at all what I want to happen. I found an earlier post (around a year ago) about a similar problem and the guy ran into the same issue. Unfortunately it doesn't look like it got resolved. Still there must be a way to do this.

Share this post


Link to post
Share on other sites
Guest mantragora

OK so there's one catch, yes, that will activate the tool, but then it sets there waiting for user input, not at all what I want to happen.

If your curve is selected in network view it will execute tool and not wait for user interaction.

Share this post


Link to post
Share on other sites

OK but it's not selected, since it's being created in teh script. Is there a way to select nodes in the script?

Share this post


Link to post
Share on other sites

Oops, forgot Node.setSelected(true). OK that works, bones get added. Now just need to figure out how to change the params for the tool so I can control the number of bones it creates!

Share this post


Link to post
Share on other sites
Guest mantragora

After tool is executed in Viewport you can set number of bones and it's called "numberofbones". Probably we need to access the viewport pane and find this parameter somehow. We need Graham for this.

Share this post


Link to post
Share on other sites

OSo I've grepped around the py code in houdini/python2.xlibs/ and so far no luck figuring out what "bonesfromcurve" actually does - there's nothing other than a string entry in a dictionary that resembles this, and all the code just calls generic stuff - I suspect that this is calling some internal C++ code. But maybe I'm looking in the wrong place.

Share this post


Link to post
Share on other sites
Guest mantragora

...grepped...

Are you using Linux? :D

Edited by mantragora

Share this post


Link to post
Share on other sites
Guest mantragora

In Windows Powershell you can grep it like this:

$path = "C:\Program Files\Side Effects Software\Houdini 13.0.242\houdini\python2.7libs"
$lookfor = "bonesfromcurve"

# cls
Clear-Host

# filter and collect
$result = Get-ChildItem $path -Recurse | Where-Object {$_.Extension -eq ".py"} | Select-String $lookfor -CaseSensitive

# format output
$result | Format-Table -Property Filename, LineNumber, Pattern -AutoSize

Edited by mantragora

Share this post


Link to post
Share on other sites

It may be that using bonesfromcurve is not possible:

http://www.sidefx.com/index.php?option=com_forum&Itemid=172&page=viewtopic&p=112651&sid=6b831ecab69db2e4b6f512905c2eb7e0

according a rafal it may not work, i.e. the ability to control the params for chain name and bone count from the script. So it's back to the original question and implementing this from scratch.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×