So this is probably too late for the OP, but here a solution I slapped together that doesn't require calling the "bones from curve" tool. Hope it helps someone.
#Bones From Multiple Curves Tool - By 90ender
'''
Given a node containing more than one curve, the tool loops over
each creating a bone chain that matches it's curvature and position.
The tool is still in development and currently does not take user input.
'''
#create a normal given two points
def normalFromPoints(pfrom = hou.Vector3(3,2,1), pto = hou.Vector3(10,5,2)):
x = pto[0] - pfrom[0]
y = pto[1] - pfrom[1]
z = pto[2] - pfrom[2]
return hou.Vector3(x,y,z)
# convert a normal to a euler rotation
def normalToEuler(nto = hou.Vector3(1,1,0), nfrom = hou.Vector3(0,1,0)):
a = nto.normalized()
b = nfrom.normalized()
matrix = b.matrixToRotateTo(a)
euler = matrix.extractRotates('srt','xyz',hou.Vector3(0,0,0))
return euler
def buildBone(parent = None, pos = hou.Vector3(0,0,0), rot = hou.Vector3(0,0,0), len = 1.0, name = "chain_bone1", container = None):
if container == None:
container = hou.node("obj")
bone = container.createNode("bone", name)
bone.parm("length").set(len)
bone.parmTuple("t").set(pos)
rot[2] = 0.0
bone.parmTuple("r").set(rot)
if parent != None:
bone.parm("keeppos").set(1)
bone.setFirstInput(parent)
bone.parm("keeppos").set(0)
bone.moveParmTransformIntoPreTransform()
return bone
def buildRoot(name = "chain_root", container = None, parent = None):
if container == None:
container = hou.node("obj")
root = container.createNode("null", name)
root.parm("keeppos").set(1)
root.parm("use_dcolor").set(0)
root.parm("geoscale").set(0.5)
root.parm("controltype").set(1)
root.parm("shadedmode").set(1)
if parent != None:
root.setFirstInput(parent)
return root
#build chain of n bones along curve
#POSSIBLE TO DO: if curve has length attrib then add bones based on length.
def bonesFromCurve(curve = None, segments = 5, container = None):
#initialize curve position and variables
div = 1.0 / segments
u = 0
v = 0
apos = curve.positionAtInterior(u,v)
boneDir = hou.Vector3(0,0,-1)
#get names
rootName = "root1"
boneName = "curve_bone1"
if curve.geometry().findPrimAttrib("name") != None:
name = curve.stringAttribValue("name")
rootName = name + "_root1"
boneName = name + "_bone1"
#build root
root = buildRoot(rootName, container)
chainpos = root.moveToGoodPosition()
parent = root
bonesLst = [root]
for x in range(0, segments):
#get bone start and end positions on curve
u += div
bpos = curve.positionAtInterior(u,v)
len = apos.distanceTo(bpos)
#Calculate bone rotation along curve from up vector
n = normalFromPoints(apos, bpos)
rot = normalToEuler(n, boneDir)
#create bones here and orient and parent them
bone = buildBone(parent, apos, rot, len, boneName, container)
bone.moveToGoodPosition()
parent = bone
bonesLst.append(bone)
#set next position
apos = bpos
#need to return a bone or list of bones
return bonesLst
#TO DO: Find out how to put parameters into operation controls toolbar
#main()
selected = hou.selectedNodes()
if len(selected) < 1:
hou.ui.displayMessage("No Nodes Selected")
else:
#get curves from node
child = selected[0].displayNode()
curves = child.geometry().prims()
#TO DO: check if geo is curve
#TO DO: User input here. Check if zero
input = 10
#create subnet container
subnet = hou.node("obj").createNode("subnet", "tree_rig1")
subnet.moveToGoodPosition()
geoInSubnet = []
#iterate over curves
for i in curves:
bonesLst = bonesFromCurve(i, input, subnet) #we may need another parm for chain parents
print "done!\n"