Jump to content


  • Content count

  • Donations

    0.00 CAD 
  • Joined

  • Last visited

Community Reputation

0 Neutral

About calin_casian

  • Rank
  • Birthday 07/03/1975

Personal Information

  • Name
    Calin Casian
  • Location
    Los Angeles
  1. Hi, I posted some files on my blog if somebody is interested how to do a stretchy spine. Any feedback is welcomed cheers calin
  2. Maya Python to Houdini Python

    Thanks Simon, I'll look into the list() thing, seems the right way to do it although shading nodes don't have representation in the viewer but maybe there's something else. If you're interested to see some rig bits in both packages please check my blog regularly or subscribe to the RSS. I'll try and post here a link every time I'll post some scenes and scripts. cheers calin
  3. Maya Python to Houdini Python

    Hi, I'm trying to port some maya python rigging scripts to houdini python scripts to post it on my rigging blog as examples, shameless plug follows: Please visit my blog at http://vanillarigging.blogspot.com If all goes well maybe start some sort of transition guide or repository about python in maya and houdini. I know that sort of thing will help the houdini community. Anyway I'm kind of lost at the first attempt to get a selection out of houdini. Here is maya code "maya.cmds.ls(selection=True)" which will return a list of all the objects selected, transforms, shaders, custom nodes you name it. I was advised that I could do something like this in houdini loop trough all children of /obj and test for selection with hou.Node.isSelected(). This works but I think this method has some big issues. First is the loop, if I have thousands of objects it might take a while . The bigger issue to me id the fact that this seems to go backwards, instead of saying give me the selection it says give me all the objects then take the selected out. Could someone (Luke, maybe) please point me to a better, simpler way of getting my selection from houdini, wink wink, see the simplicity of mayas cheers calin ps. I'm sure tons of question will follow because here is the script I'm trying to port: import maya.cmds as mc # Build the UI def startUI(): print 'starting the UI' # end of UI def createJoints(nrJoints, boneLength): # create a number of joints, 'nrJoints' along the Y axis # the joints will be spread apart by the 'boneLength' value print 'Create Joints' jointsList = [] # create the root joint then orient it to point in +Y jointName = mc.joint(position=(0,0,0), name='spineJoint1', orientation=(-90,0,90)) jointsList.append(jointName) for i in range(2, nrJoints): jointName = mc.joint(position=(boneLength,0,0), relative=True, name='spineJoint' + str(i)) jointsList.append(jointName) return jointsList def addBoneLengthToJoints(jointsList): # add an 'originalLength' attribute to every joint that follows after root # that stores the original length. Since the translate X is taken as original # length the joints must be oriented along X for custon skeletons print 'Add original bone length attribute to joints' selection = mc.ls(selection=True) # take the root joint out of the joint list because there is no bone length # on the root joint stretchJointsList = jointsList[1:] for i in stretchJointsList: mc.select(i, replace=True) tempXvalue = mc.getAttr(i + '.translateX') mc.addAttr(longName='originalLength', attributeType='double', defaultValue=tempXvalue) mc.setAttr(i + '.originalLength', lock=True) return stretchJointsList def createSpineHierarchy(): # create a spine hierarchy where the joints are unde the skeleton group, # the controls under controls group and everything else is under the helpers group print 'Create spine hierarchy' spineRig = mc.createNode('transform', name='spineRig') spineSkeleton = mc.createNode('transform', name='spineSkeleton', parent=spineRig) spineControls = mc.createNode('transform', name='spineControls', parent=spineRig) spineHelpers = mc.createNode('transform', name='spineHelpers', parent=spineRig) mc.setAttr('spineSkeleton.template', 1) spineHierarchyList = [spineRig, spineSkeleton, spineControls, spineHelpers] return spineHierarchyList def buildStretchySpine(spineJointsList, stretchJointsList): # create the stretchy spine setup based on the provided diagram print 'Build stretchy spine' # adding spline IK solver to the bones print 'Add IK solver' mc.ikHandle(name='spineIkHandle', startJoint=spineJointsList[0], endEffector=spineJointsList[-1], solver='ikSplineSolver', numSpans=2) spineSolverCurveShape = mc.ikHandle('spineIkHandle', query=True, curve=True) spineSolverCurve = mc.listRelatives(spineSolverCurveShape, parent=True) mc.setAttr(spineSolverCurve[0] + '.template', 1) spineCurve = 'spineCurve' mc.rename(spineSolverCurve[0], spineCurve) mc.parent(spineCurve, 'spineHelpers') # create the curveInfo node that will compute the arclen of the spine print "Add cruveInfo node that computes the spine's length" spineCurveInfoNode = mc.arclen(spineCurve, constructionHistory=True) spineLengthNode = 'spineComputeCurveLength' mc.rename(spineCurveInfoNode, spineLengthNode) # store the original curve length in the 'originalLength' attribute print "Add spine curve original length attribute" spineCurveOrigLength = mc.getAttr(spineLengthNode + '.arcLength') mc.select(spineCurve, replace=True) mc.addAttr(longName='originalLength', attributeType='double', defaultValue=spineCurveOrigLength) mc.setAttr(spineCurve + '.originalLength', lock=True) mc.parent('spineIkHandle', 'spineHelpers') mc.setAttr('spineIkHandle.visibility', 0) # create a locator which will be a control for spine options, stretchiness # we default this value to .2 which means that the spine will stretch and # compress with .2 of the difference between the original length and the # current length print 'Create a control for the spine options' spineOptions = mc.createNode('transform', name='spineOptionsCtrl', parent='spineControls') mc.createNode('locator', name='spineOptionsCtrlShape', parent=spineOptions) mc.setAttr(spineOptions + '.translateX', 4) mc.parentConstraint('spineJoint1', spineOptions, maintainOffset=True) print 'Add spine options attributes' mc.select(spineOptions, replace=True) mc.addAttr(longName='spineStretchiness', attributeType='double', minValue=0, maxValue=1, defaultValue=0.2, keyable=True) # create the stretchiness network which mainly consists of adding shading nodes # and connect attributes print 'Add stretchiness network' # create a plusMinusAverage node. this node will take the current length # and subtract the original length to find out with how much the curve changed spineSubtractOriginalCurveLengthNode = mc.shadingNode('plusMinusAverage', asUtility=True, name='spineSubtractOriginalCurveLength') mc.connectAttr(spineLengthNode + '.arcLength', spineSubtractOriginalCurveLengthNode + '.input1D[0]', force=True) mc.connectAttr(spineCurve + '.originalLength', spineSubtractOriginalCurveLengthNode + '.input1D[1]', force=True) mc.setAttr(spineSubtractOriginalCurveLengthNode + '.operation', 2) # create a multiplyDivide node that multiplies the result from the subtract node with # the spine stretchiness to find out what's the length we care about spineMultiplyStretchinessNode = mc.shadingNode('multiplyDivide', asUtility=True, name='spineMultiplyStretchiness') mc.connectAttr(spineSubtractOriginalCurveLengthNode + '.output1D', spineMultiplyStretchinessNode + '.input1X', force=True) mc.connectAttr(spineOptions + '.spineStretchiness', spineMultiplyStretchinessNode + '.input2X', force=True) # create a plusMinusAverage node and we add back the original curve to find out the # total length of the curve we have to stretch the bones spineAddOriginalCurveLengthNode = mc.shadingNode('plusMinusAverage', asUtility=True, name='spineAddOriginalCurveLength') mc.connectAttr(spineMultiplyStretchinessNode + '.outputX', spineAddOriginalCurveLengthNode + '.input1D[0]', force=True) mc.connectAttr(spineCurve + '.originalLength', spineAddOriginalCurveLengthNode + '.input1D[1]', force=True) # create a multiplyDivide node and divide the total length we care about with the original # length to find out the ratio. spineDivideByOriginalCurveLengthNode = mc.shadingNode('multiplyDivide', asUtility=True, name='spineDivideByOriginalCurveLength') mc.connectAttr(spineAddOriginalCurveLengthNode + '.output1D', spineDivideByOriginalCurveLengthNode + '.input1X', force=True) mc.connectAttr(spineCurve + '.originalLength', spineDivideByOriginalCurveLengthNode + '.input2X', force=True) mc.setAttr(spineDivideByOriginalCurveLengthNode + '.operation', 2) # once we know the ration we have to create a multiplyDivide node for each joint # and multyply the original bone length with the computed ratio print "Change the bone Tx value to accomodate stretchiness" for i in stretchJointsList: spineMultiplyByOriginalBoneLengthNode = mc.shadingNode('multiplyDivide', asUtility=True, name='spine' + i + 'MultiplyOriginalLength') mc.connectAttr(spineDivideByOriginalCurveLengthNode + '.outputX', spineMultiplyByOriginalBoneLengthNode + '.input1X', force=True) mc.connectAttr(i + '.originalLength', spineMultiplyByOriginalBoneLengthNode + '.input2X', force=True) mc.connectAttr(spineMultiplyByOriginalBoneLengthNode + '.outputX', i + '.translateX', force=True) def createClusters(): print 'Create clusters' for i in range(0,5): cv = 'spineCurve.cv[%d]' %i cluster = mc.cluster(cv, name='spineCurveCluster' + str(i)) mc.parent(cluster, 'spineHelpers') def main(createJointsOption, nrJoints, boneLength): if createJointsOption==1: spineJointsList = createJoints(nrJoints, 2) spineHierarchyList = createSpineHierarchy() mc.parent(spineJointsList[0], spineHierarchyList[1]) stretchJointsList = addBoneLengthToJoints(spineJointsList) buildStretchySpine(spineJointsList, stretchJointsList) createClusters() main(1, 20, 2)
  4. New Muscle Tutorial Videos

    Hi guys Thx for the feedback. Althought Jason mantioned about HDA building blocks, and yes that is the final intent, I figured it would be useful to start with a couple of hardcore videos and explain what's happening under the hood. Why? well let's say I'll make a 3 point muscle HDA and all of the sudden you'll want 4 point muscle HDA, with this videos you will have the knowledge to modify the HDAs and create your own. Plus it may take a while till all the HDAs are in place and we didn't want to stall you from using the raw tools., especially now with Python I have to rewrite the autorig tools in python and there is also a quadruped autorig in the works. take care calin
  5. The proxy geometry is scattered because when autorig splits up the geometry is at the origin. In the animation rig each piece of proxy geometry is inside the bone thus the bone transform is applied to the proxy chunk. In the animation rig there is a button Set Proxy which will compute the bone transforms in world space and apply those values to the proxy chunks. So press that button and all should fall into place. To the groups from weighted geo question the answer is yes and no. Yes you can create groups but you don't have control over the names so you will need to change all the names in the animation rig. The autorig creates the groups with the appropriate names. Te reason for the proxy geometry is, as you mentioned, to start with the animation right away and probably the most important one is the speed of the rig in proxy mode. There is no weighting/deform process in the proxy so the rig is faster to work with, also most of the time the deform/rendered geometry is much heavier than the proxy one plus it has all sorts of additional deformers (muscles, wires). cheers calin
  6. How Heavy Are Your Rigs?

    Yes it's the next version, or actually it uses different types of bodyparts calin
  7. How Heavy Are Your Rigs?

    I have an animation rig with proxy geometry 20k points. All the geometry is saved with the otl, no references. It uses about 45M. I do have blendshapes and unfortunately I didn't use sopcreateedit so I probably have 15M only in the blendshapes. The animation rig is the final animation rig except the deformation part so it has fk-ik blends and all the other stuff. I probably should mention that it uses a 4 bone fk spine so nothing fancy about that. I added a sin() to the COG so the whole rigs cooks. Here are my stats from performance monitor: -single instance first time (so the bone cache doesn't kick in) average of 28 fps -single instance second time average of 34 fps - 2 characters, the memory doubled as expected so now I'm using 90-100M, average of 21 fps - 3 characters, the memory went to 150M, average of 14 fps I'll let you know the deform stats as soon as I'm done with it. cheers calin
  8. Auto Rigged Character

    Hi, wery nice. I'm glad that you like it. In some ways that was the purpose of the autorig, be flexible, reduce the amount of time spend on rigging and convert people from other packages . cheers calin
  9. Multi Weight Enveloping

    @peship Yes I'm not a huge fan of layered rigs, my motto is make it as simple as possible. I think it's just another way of rigging. Why need multiple chain bones with multiple IKs when I can have multiple ik solvers running on the same chain and blend between the solutions. I don't wanna start any software war but from my perspective I may say that layered skeletons are just a simple hack to get around what's possible and what's not possible in some other packages. It's been proven by C.O.R.E. that Houdini can be used to create a full CG feature animation w/wo all the differences and that's the important thing ... About the rotation order, you can use fetch and chops tricks to get around it. About changing the rotation order for all the animation controls; why not make them right in the first place, make one null change the rotation order and from this point copy and paste. If you need to change the icon go inside the null and have fun... take care calin
  10. Multi Weight Enveloping

    So I may be a little bit rusty since I haven't use maya for a long time... Please open the attached file: Here is a short description for people who doesn't have PLE -cube1: -tx:-2 -ty:0 -tz:2 -rx:0 -ry:0 -rz:0 -null1: -tx:2 -ty:-2 -tz:0 -rx:35 -ry:-6 -rz:-7 -cube3(child of null1): -tx:0 -ty:0 -tz:0 -rx:0 -ry:0 -rz:0 -cube2(orient constrained to cube1 and 3): -tx:0 -ty:0 -tz:0 -rx:17.382 -ry:-3.538 -rz:-3.032 -interp Type: Shortest -W0:1 -W1:1 Rotate cube3 rx: 146 (which is 181 in total) result: cube2 flips Change Interp Type to No Flip. Rotate cube3 rx: 326 (which is 361 in total) result: cube2 is in a bizarre state(flipped twice), due to gimbal lock or rotation order. It's rotations are rx:81.21, ry:-0.459 rz:173.535. Please someone tell me how I end up with this values when I rotate cube3 only in X Change Interp Type to Average. Rotate cube3 rx: 326 (which is 361 in total) result: cube2 is in a bizarre state(flipped twice), due to gimbal lock or rotation order. It's rotations are rx:81.21, ry:-0.459 rz:173.535. So the same result. Even more when cube3 rx:360 cube2 rx:-165.473 ry:19.162 rz:-32.409. Again can someone explain to me how over a 35 degrees rotation in X I end up with cube2 rx:81.21->-165.473 and so on. Change Interp Type to Longest. Rotate cube3 rx: 146 (which is 181 in total) result: cube2 flips, save as in shortest Change Interp Type to cache. Rotate cube3 rx: 326 (which is 361 in total) result: same as average and no flip I'm just a normal user going back to maya and try something out. I may not used the orient constraint in the right way that's why I posted the scene so someone with more experience than me can fix it. take care calin ps. I'm sure in the end for every problem there is a solution, it may be dirty but hey if it's working... Oh I can't upload .mp files so please change the extension from .zip to .mp blend.zip
  11. Biped Auto Rig Tool - Sidefx Technical Evening

    Well, thank you guys I really appreciate it. I think we all want to make Houdini's character tools intuitive, easy to use = artist friendly and extremely powerful (like the rest of Houdini). I'll be waiting for any feedback/bugs/RFEs from you once the tool will be out. Right... back to work,... Muscles.... calin
  12. Multi Weight Enveloping

    I don't know if this is what you would expect to see but please take a look at the attached files. calin weirdBlend_mod.hipnc weirdRotationOrders_mod.hipnc
  13. Muscles And Jiggle

    Well, I can say something. By it's nature the meta capture will give you a more localized capture which means you'll have more control over your final mesh so you don't have tangled skin. The inflate will work on the unified/merged muscle surface so yes you'll need to build the metaball surface to some level of detail but on the other hand it will be much faster than any nurbs/poly surface in wrap mode. Wrap deformers can be realy slow if you have a heavy mesh and you can't have fine control over sliding and other skin attributes. I think that's about it, when comes to how much I can say about our solution at the moment... more to come in the future Nice, I would love to see the result... I'm planning to build some muscle groups as digital assets (eg, biceps, trapezius, pectoralis) so in the end it should be pretty easy to set up. not sure at the moment take care calin
  14. Muscles And Jiggle

    I have a couple of questions/concerns in regard with the muscle system in maya. I used maya a lot but a long time ago so I may not be up to date... Jiggle is my main concern. In the old days alias said that jiggle was developed to simulate lag, a extension to the softbody. I believe they had an example with a fat guy walking around and the belly jiggles. Now the problem: as far as I know, but I may be wrong, maya's jiggle is in world space, which makes it unusable with muscles whom jiggle in their local space. I believe even alias said that jiggle is good for fat tissue, because fat doesn't have a coherent structure like muscle fiber thus jiggles in the world space. The second one is the surface that defines the muscle shape. Nurbs and Polys can tangle themselfs if you compress/twist the muscle to the limit. Metaballs are the perfect solution, no matter how much tou compress a metaball muscle it will still have a nice/smooth surface. As Simon said, and I'm not saying/implying anything else, wait for the 8.1 before you make a decision... calin
  15. Constrain To Surface

    you can also add a second imput to your asset and put the blend node inside the DA so that it blends between the DA null and whatever you have on the second imput. If you don't want to use DA imputs you can put the fetch node inside the DA and promote the parameters related to the fetch node, I would say fetch object and fetch world transform calin