Procedural bone creation

   7318   7   1
User Avatar
Member
3 posts
Joined: March 2017
Offline
Hey guys,

I'm new to rigging in houdini and every tutorial I find goes over manually creating bones in the viewport. I'm trying to figure out how to generate bones in a more procedural way.

For example, say I wanted to scatter bones onto a sphere and export this as a skinned mesh FBX for use in Unity? The bones would all be parented to a single root.

Is this possible? I've seen some people recommend python scripting to create bones but it feels a bit overly complicated for something like this.
User Avatar
Staff
3455 posts
Joined: July 2005
Offline
python would be the preferred method, since bones are Objects.
Michael Goldfarb | www.odforce.net
Training Lead
SideFX
www.sidefx.com
User Avatar
Member
3 posts
Joined: March 2017
Offline
Thanks for the response. It does seem like python is the easiest way to do this. I finally got it working after looking at the sop_skinning_converter. You can view the python script by right clicking on the node and selecting Type Properties than the Scripts tab. I didn't even realize you could bundle python scripts with an HDA which is very cool.

Now I'm trying to figure out how to procedurally influence weights and have multiple mesh's share the same rig.

If anybody else is interested here's the python code.

def GenerateBones():    
    print("Creating Bones")    
    
    ThisNode = hou.pwd()
    
    ContainerObject = hou.node("/obj").createNode("subnet", "%s_Generated_Bones" % (ThisNode.name()))
    
    Root = ContainerObject.createNode("null", "root")
    Geometry = ContainerObject.createNode("geo")
    hou.node(Geometry.path()+"/file1").destroy()
    Geometry.moveToGoodPosition()
    
    ObjMerge = Geometry.createNode("object_merge")
    ObjMerge.parm("objpath1").set(ThisNode.path()+"/IN")
    ObjMerge.parm("xformtype").set("local")
        
    # Setup Capture
    CaptureNode = None
    CaptureMethod = ThisNode.parm("capture_method").eval()
    
    #Biharmonic Capture
    if CaptureMethod == 0:
        CaptLines = Geometry.createNode("bonecapturelines")
        CaptLines.parm("rootpath").set(Root.path())
        SolidEmbed = Geometry.createNode("solidembed::2.0")
        SolidEmbed.setInput(0, ObjMerge)
        SolidEmbed.setInput(1, CaptLines)
        CaptureNode = Geometry.createNode("bonecapturebiharmonic")
        CaptureNode.setInput(0, ObjMerge)
        CaptureNode.setInput(1, SolidEmbed)
        for node in [CaptLines, SolidEmbed, CaptureNode]:
                node.moveToGoodPosition()

    #Proximity Capture
    elif CaptureMethod == 1:
        CaptureNode = Geometry.createNode("captureproximity")
        CaptureNode.setNextInput(ObjMerge)    
        CaptureNode.parm("rootpath").set(Root.path())
        CaptureNode.parm("maxinfluences").set(ThisNode.parm("max_bone_influence").eval())
        CaptureNode.parm("usecaptpose").set(1)
        CaptureNode.parm("forcecook").pressButton()
        CaptureNode.moveToGoodPosition()
    
    Deform = Geometry.createNode("deform")
    Deform.setNextInput(CaptureNode)
    Deform.parm("donormal").set(1)
    Deform.parm("fast").set(1)
    Deform.moveToGoodPosition()

    Deform.setDisplayFlag(True)
    Deform.setRenderFlag(True)
    
    CaptureRadius = ThisNode.parm("capture_radius").eval()
    
    # Make Bones
    for i, point in enumerate(hou.node(ThisNode.path()+"/POINTS_OUT").geometry().points()):
        bone = ContainerObject.createNode("bone", "bone_%i" % i)
        
        bone.parm("rOrd").set(0)
        CaptureLength = [0.1, 0.001]
        bone.parm("length").set(CaptureLength[CaptureMethod])
        bone.parm("displaycapture").set(True)
        bone.parm("captposelen").set(0.1)
        
        Position = point.attribValue("P")        
        for i, parm in enumerate(['tx', 'ty', 'tz']):
            bone.parm(parm).set(Position[i])        
    
        for parm in ['crtopcapx', 'crtopcapy', 'crtopcapz', 'crbotcapx', 'crbotcapy', 'crbotcapz']:
            bone.parm(parm).set(CaptureRadius)
            
        bone.setNextInput(Root)
        bone.moveToGoodPosition()
    
    hou.hscript("bonealigncapture -c %s/bone*" % str(ContainerObject.path()))
                    
    ContainerObject.moveToGoodPosition()
    
    print "Bones Creation complete! Output at %s" % ContainerObject.path()
User Avatar
Member
240 posts
Joined: Nov. 2012
Offline
Thanks for sharing the code!

This is an area the games team will be tackling in the future (we've done a few things like the skinning converter and the retiming tool) so any feedback you have or any findings you're willing to share is great.

We want to know what the desired workflow would be when procedurally manipulating skeletons
Luiz Kruel
Senior Technical Artist
SideFX
User Avatar
Member
670 posts
Joined: Sept. 2013
Online
lkruel
We want to know what the desired workflow would be when procedurally manipulating skeletons

A node (or at least a shelf tool) that skeleton meshes to bones would be really useful.

So we`ll able to create all sorts of random creatures without going through a rigging process each time.
Edited by Konstantin Magnus - June 27, 2018 04:19:04

Attachments:
skeleton.png (23.4 KB)

https://procegen.konstantinmagnus.de/ [procegen.konstantinmagnus.de]
User Avatar
Member
54 posts
Joined: March 2015
Online
I'm trying to get the above python script to work, but I don't think I'm putting it in the right place. What's the best way to get that python script working in Houdini? Thank you!
User Avatar
Member
94 posts
Joined: Nov. 2017
Offline
Currently doing the skeleton stuff myself. Initially with precreated bone chains which just get aligned with the skeleton. But so far that's great for updating the mesh. Best thing so far is creating FK controls for bones with automatic node alignment and network box drawing. Saves so much time once it's scripted.
User Avatar
Member
80 posts
Joined: Feb. 2018
Offline
lkruel
We want to know what the desired workflow would be when procedurally manipulating skeletons

Thanks for looking into this subject!
I think there is a lot of potential here for procedural modelling to become more relevant for creatures and characters. It might seem like there is not much interest in this area but pairing procedural modelling and rigging together could really be a paradigm shift especially if it could integrate with muscles system. Artists could generate a lot of variations of a model with animations and poses as well as muscles and skin deformation. I think it's just not on a lot of peoples radar mostly due to inertia and the fact that there isn't a lot of procedural modelling of creatures going on.

I could rant about this for a while but on to practical considerations:
A lot of the data required for rigging can be generated at the Sop level when creating the procedural meshes in the first place.
Ideally the nodes would take the a bunch of curves and generate bones based on them, then maybe have a separate node to generate the skin weights. It would be good to have to an option of influencing the bones with attributes or groups for example designating which bones are IK which one is the end effector or limiting certain bones skin weights.
This would be consistent with the ongoing theme of bringing things into Sops from other contexts.
I would eventually like to package my creature generator as a hda so I would greatly prefer nodes rather than a shelf tools, because they could be incorporated more seamlessly, even if they require a bit more information from the user to work.
Sorry for the long post, here are some gifs of what I'm working on:
Edited by FFD - Nov. 17, 2019 03:09:24

Attachments:
creature.gif (893.2 KB)
Creature1.gif (117.8 KB)
insta.gif (84.9 KB)

3D Freelancer
https://www.artstation.com/ffd [www.artstation.com]
  • Quick Links