Home Website Youtube GitHub

RBF Solver Mirror Setup?

Hey,
Any chance for support with that one?
Wonder if I should look for another solution or stick with RBF manager

Hello,
I will post a little update here, just in case someone would be interested too.
Long story short - Thanks to great support from @Rafael it sorted out as a super simple issue - what I was missing is to set mirror attributes on the parent node that the rbf node drives.

Here’s the full message from Rafael:

Rafael:mGear Developer

Hey Krzym,
I figured it out!
I recreated the scene as per your video and then attempted to get the mirroring working. It was very annoying and time consuming(This should be fixed in the future, hopefully).
But the issue seems to be that the invert attrs need to be correctly applied to the controls BEFORE the RBF setups are created.
Here are some images.


and


The reason for this is that the invert mirror attributes get copied to the parent node that the rbf node drives. Like here.
So if the invert mirror attrs are not filled in, or wrong before the rbf node setup is created, they will continue to be in the mirroring process because the RBF manager factors in the parents invert attrs as well.
This is exciting because I have forgotten all about this when I created this. Wow, it has been a long day trying to figure this out.
I attached a scene with the mirrored behavior, Maya 2020.2. Let me know if this works for you!

Scene: https://www.dropbox.com/s/wb64xadcutgq8o8/rbf_creation_test01.mb

Also, if you have existing setups you can just go to the _driven node above it and correctly apply the invert mirror attributes.
I saw in your video that you were scrolling through the entire list of attributes while creating RBF nodes, you can right click to display different types of attrs.


Let me know if you can replicate this behavior or if anything I said was not clear.


Besides that, I was trying to use simple joints instead of the control_01 (I ended up creating control_01(without the shape in PRE script) to keep RBF Manager working correctly).
But here’s the simple script I managed to copy from rigbits.rbf_manager_ui, maybe it would be helpful for someone

.

from mgear import rigbits
import maya.cmds as mc
import pymel.core as pm

def addRBFToSetup(driverControl, driverNode, drivenNode, setupName, driverAttrs, drivenAttrs, rbfType="weightDriver"):
    """query the user in case of a new setup or adding additional RBFs to
    existing.

    Returns:
        TYPE: Description
    """
    
    ### Check function parameters
    #
    try:
        pm.PyNode(driverControl)
    except pm.MayaNodeError:
        pm.displayWarning(
            "Driver control not found")
        return
    #
    try:
        pm.PyNode(driverNode)
    except pm.MayaNodeError:
        pm.displayWarning(
            "Driver node/joint not found")
        return
    if driverNode == "":
        return
    #
    
    try:
        pm.PyNode(drivenNode)
    except pm.MayaNodeError:
        pm.displayWarning(
            "Driven node not found")
        return
    #
    if not setupName:
        pm.displayWarning("Please provide setup name: NAME_R0")
        return
    #
    if not drivenAttrs:
        drivenAttrs = [
            "translateX", 
            "translateY", 
            "translateZ", 
            "rotateX", 
            "rotateY", 
            "rotateZ"
            ]
    #
    if not driverAttrs:
        driverAttrs = [
            "rotateX", 
            "rotateY", 
            "rotateZ"
            ]
    #####
    
    
    for check in driverControl, driverNode, drivenNode, setupName, driverAttrs, drivenAttrs, rbfType:
        print check

    # This does prevents a driver to be its own driven
    if not drivenNode or drivenNode == driverNode:
        pm.displayWarning("Select Node to be driven!")
        return
        
    drivenNodeType = mc.nodeType(drivenNode)
    # smart display all when needed
    if drivenNodeType in ["transform", "joint"]:
        attrType = "keyable"
    else:
        attrType = "all"
    
    parentNode = False
    
    drivenType = mc.nodeType(drivenNode)
    
    if drivenType in ["transform", "joint"]:
        parentNode = True
        drivenNode = rigbits.rbf_node.addDrivenGroup(drivenNode)
    # create RBFNode instance, apply settings
    rbfNode = rigbits.rbf_manager_ui.sortRBF(drivenNode, rbfType=rbfType)
    rbfNode.setSetupName(setupName)
    rbfNode.setDriverControlAttr(driverControl)
    rbfNode.setDriverNode(driverNode, driverAttrs)
    defaultVals = rbfNode.setDrivenNode(drivenNode,
                                        drivenAttrs,
                                        parent=parentNode)
    
    
    rbfNode.applyDefaultPose() 

    return rbfNode

def addPose(rbfNode, poseInput, poseValue):
    if not rbfNode:
        return
    driverNode = rbfNode.getDriverNode()[0]
    driverAttrs = rbfNode.getDriverNodeAttributes()
    
    #covert transforms to list:
    poseValue = [item for sublist in poseValue for item in sublist]  
    rbfNode.addPose(poseInput=poseInput, poseValue=poseValue)
    return

#########################################
## LOAD THE DATA

driverControl = "arm_R0_fk0_ctl"
driverNode = "blend_arm_R0_0_jnt"

drivenNode = "rbf01_R0_ctl"

setupName = "test_R0"

driverAttrs = [
            "rotateX", 
            "rotateY", 
            "rotateZ"
            ]

drivenAttrs = [
            "translateX", 
            "translateY", 
            "translateZ", 
            "rotateX", 
            "rotateY", 
            "rotateZ"
            ]



## create RBF
rbfNode = addRBFToSetup(driverControl, driverNode, drivenNode, setupName, driverAttrs, drivenAttrs)


## addPose
addPose(rbfNode, [0.0, 90.0, 0.0], [ [0.0, 10.0, 0.0] , [0.0, 0.0, 0.0]])
addPose(rbfNode, [0.0, -90.0, 0.0], [ [10.0, 0.0, 0.0] , [0.0, 0.0, 0.0]])

Workflow I’m using it in order:

  • Manually test joint positions/skinning
  • Export RBF settings (Driver transform, Joints transform, Required attrs etc.)
  • On build create RBF nodes, add poses

Please be aware that this might need some tests, I’m not checking how it’s related to other RBFs. But it works on a clean scene.

Cheers,
Krzysztof


Edit:
So if anyone would like to use joints it is as simple as that:

  1. Add mirror attributes to the joint:
    attribute.add_mirror_config_channels(obj, conf=[0, 0, 1, 1, 1, 0, 0, 0, 0])
  2. Rename the joints before RBF creation to match CTLs naming
    e.g. blendSupport0arm_L0_ctl

Mirror works perfect.

4 Likes

Thank you so much!!!