Properties driving properties driving posebones

I have developed a script that imports native files from Daz Studio, and run into Blender limits when facial poses are imported. The Genesis 3 character has a face rig, and poses are implemented as object properties driving the face bones. The problem is that there are a lot of poses, and in Blender a scripted expression can not exceed 256 characters. Even with a shoehorn (single-letter variables names, no spaces, floats represented by integers/1000), the string becomes longer than 256 characters.

To evade this limitation, I considered using a hierarchy of properties to drive the bones. The poses are divided into four categories: face units, face expressions, visemes, and others. For each category, bone, and component, there is a property driven by the original object properties, and the bones are then driven by these intermediate properties. The number of poses in each category is sufficiently small so the scripted expression does not exceed 256 characters.

However, I now have an update problem. A change in the properties does not change the face pose unless an explicit update (toggle in and out of edit mode, step back and forward in time) is performed. Originally I had properties driving posebones, which update correctly. But now I have properties driving other properties driving posebones, and problems with update. Is there some way to force updates to be done correctly. Like telling Blender which properties to update first (the drivers) and which to update later (the drivens).

I made some partial progress by skipping drivers altogether, and defining update functions instead. The following script defines an object property rot1 which updates an intermediate property rot2 which updates the object rotation.


bl_info = {
    "name": "Test",
    "category": "Test"}

import bpy
from bpy.props import FloatVectorProperty
from mathutils import Vector
import math

class MyPanel(bpy.types.Panel):
    bl_label = "MyPanel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "Test"

    def draw(self, context):
        ob = context.object
        layout = self.layout
        layout.prop(ob, "rot1")
        layout.prop(ob, "rot2")
        layout.prop(ob, "rotation_euler")

def updateRot1(self, context):
    self.rot2 = 2*Vector(self.rot1)

def updateRot2(self, context):
    self.rotation_euler = 3*Vector(self.rot2)*math.pi/180

def register():
    bpy.types.Object.rot1 = FloatVectorProperty(
        default = (0,0,0),
        size = 3,
        update = updateRot1)

    bpy.types.Object.rot2 = FloatVectorProperty(
        default = (0,0,0),
        size = 3,
        update = updateRot2)

    bpy.utils.register_module(__name__)

def unregister():
    bpy.utils.unregister_module(__name__)

if __name__ == "__main__":
    register()

When I move the rot1 sliders, the rot2 sliders and the object rotation are both updated, which is more or less what I want. By using update functions I think that one can get around the 256 character limit as well, so the intermediate property rot2 is actually redundant.

However, the script does not quite perform as desired. If I set keys for the rot1 property, rot2 and object rotation do not update when the frame slider is changed. So it appears that the update function is only called when the property slider is manipulated directly, and not on frame change.

Is there some way to make properties call their update function on frame change? I have seen something about update tagging, but I don’t quite see how that would work here.

I understand the difficulities to make properties (controller) as same as daz studio way.
One problem is, All daz properties have “value” and “Raw value”

“Raw value” is how User change the property without other porperty controlled value.
“Value” is actuall current value of the property.
then each properties (controller) change other properies “delta” value only.

“Value” = "Raw Value(user direct change value) " + “delta (controlled by other controller) value”

to make such “propertiyA” which is controlled by other properties in blender, but user can change value,
there need to be “propertyDeltaA” , “propertyRawA”, “propertyA”
then PropertyA = “propertyRawA(for user controll)” + "propertyDeltaA (hidden)

about OBJ , there is already “delta rotation” and “delta translation”, then we need to make “Raw rotation” and “Raw translation” proeprty, which user can controll.

but Amature bone rotation, we have no “delta rotation” proeprties. then we need to make t
“delta boneA rotation X”, “Raw boneA rotation X” too.

then when other properties change BoneA rotation, it need to change “delta BoneA rotationX” values.
to User can change “Raw boneA rotation X” then BoneA rotationX will change on Blender 3d view.

it is heavy redaundant process, but to up-date realtime, I think,you need to set all properties (driver) like that.

Thank you for your reply, but this is not what I asked about. The problem is not how to map DAZ properties to Blender, but that there are too many of them. E.g., I use single-letter variable names to keep the lengths of the scripted expressions down, which means that there cannot be more than 52 properties (A-Z, a-z) driving a given bone.

So I want to figure out some way to get around this limitation, without having to manually force a scene update.

sorry, I miss understand. when I make simple “ctrlA” which change Eular rotation,
it seems work, but when I set keys for ctrlA, It could not up-date the Eular rotation between key frames.

then as you said, I needed to manually change ctrl A values on each frame, to see real rotation values.
sorry just take your time.