What is the correct approach to manipulating properties on linked objects?

I’m a bit frustrated because I’ve spent my entire holiday weekend overhauling my character rigging system, so that I can finally take the plunge to linking instead of appending to scenes. No more 1.5 gig scene blend files for me!

Key shape keys (like facial expressions) are driven by a UI made of control bones, and I’ve similarly automated most corrective shape keys… but some character/clothing models have a lot of shape keys for little manual tweaks. So I made a script to go through the meshes that are parented to a rig, and for each one make a custom property group on the rig with lists of shape keys, masks, and basic things like hide and hide_render, and make drivers for all of them linked to those custom properties, so I can control them from my rig’s python UI panel.

That seemed to be working fine until I tried this with multiple characters in one scene. Now blender is throwing errors like crazy. The UI panels for one character is trying (and failing) to access custom properties that only exist on a different character, and various other things.

I’ll link to the script, but rather than trying to troubleshoot the specifics of my code, I figured I should check in and see if this is even remotely the right approach. Perhaps my google-fu is poor, but I haven’t had any luck finding any discussions of how to actually link to and a complex rig with lots of properties like this. Everything I can find just goes through the basic steps: make a group with armature and body mesh, link in new file, make proxy for rig, and boom, you are done.

This leaves me still ignorant of what to do if I need to, for example, control the pockets and zippers on clothing, and manually use a dozen case-specific shape keys on a character’s body, or whatever. Do I have to drive EVERY parameter I want to change with a bone? If so, I guess I can, but whoah boy, that’s a big back-to-the-drawing-board moment.

Here is my code:

https://pastebin.com/Sbbhdt27

It generates files such as this:
Per-character custom property groups definitions (register and import when linking): https://pastebin.com/VkdWgUpD
One-time initialization of custom properties: https://pastebin.com/yruH4ja8

I have a simple UI script that makes a panel with collapsing menus so I can access these values.

So basically, is this the wrong approach? Should I give up on having a nice control panel in the blender UI, and just make bones for every single thing I’ll ever want to change?

I don’t expect someone to troubleshoot my specific problems, but I’m outlining what I am doing here so that hopefully someone can point me in the direction of the RIGHT way to do all of this.

Thanks for your time. I appreciate it.

it sounds like the CG technical blues… I cry every-time I hear that song…

Indeed changing from one workflow to another is always painful , I’m not sure I can give you the correct answer but, here are some insight…

-Linking is the way to go but indeed you loose access to shapes keys , object properties ect…

-In general the proper way to handle this is :

PROPERTIES :

  • have the shape/prop driven by a bone transform. This, in general work best because everything goes in the same place in the graph editor, and no need to script UI stuff for that.

-In some case , you may want to use a property instead of a bone transform.
Where to put that property ? it can be anywhere, in the mesh object, in the armature object ect…
The best way is to put your property on a bone related to the stuff you’re driving. If you’ve got a bone that deform the pocket and a shape key that is changing the zipper’s pocket, you can add a property to the pocket’s bone that drive the zipper’s shape key. That way, in the graph editor the zipper’s property will be near the pocket bone transforms, nice and clean…
Putting properties on bones is better than anything else because it will update properly when linking (if you change something after linking).

You can still , if it gets too complicated, add a big stinky bone called ‘properties’ that gather all the properties of all the object in the rig, it will add a bit of mess in the graph editor but it will still work and be manageable.

I’m not sure about the property group you’re using, maybe you should try to have only boolean,float properties , but maybe it can work with property group as well, haven’t tested that.

For stuff like “hide/unhide” it’s generally put on the root bone if there isn’t other place to put them.

UI SCRIPT :
I think you’ve done something a bit special here, but with properties linked to bones it should work , I haven’t looked closely / understand what you’ve done in the scripts, but maybe with a bit of refactor it should eventually work.

  • One classic way of doing is to have one UI script per rig. You put a custom property ‘name’ in the armature data , and in the script you do something like : if we are in pose mode and selected_object.data.[“name”]=“my_rig_name” : then display UI
    You can look at rigify’s rig UI that use this technique.

( putting the property in armature object.data rather than armature object is better because of updates when linking, it won’t update if you change something after having linked the character when the property is on armature’s object rather than object.data)

-You can still do another way : one big dirty script with some general option and specific case handled with the armature.data[“name”]'s trick …

-Haven’t tested but something like : display all the props of the bones selected should work , but it’s like using the custom property panel in the N panel of the 3D view.

-With the stinky ‘property’ bone that gather all props you can display all the props of the rig at once and have one script to rule them all…
The UI script will look for the “properties” bone of the selected rig and display all the props.

This can be a workaround if that get’s too complicated, you’ll do better next time when starting from start with the linking workflow.

Hope that all this will help you !
Good luck !

That makes sense. I hadn’t thought to use custom properties on individual bones. I was organizing different types of keys and different characters under nested menus, with one UI script per character as you said… but then I was in the situation that character_A.py was throwing errors because rig_A.character_A.character_B’s_property was not found… when A’s script was never actually referencing any of B’s properties. O.o

In any case, clearly I’m doing something wrong, but your idea should get around that. I just need a UI script to show the custom properties of the active pose bone, whatever it may be, and that should do it. I suppose I can even get fancy and do some formatting based on the property name, or something. That’s a much simpler and more flexible approach anyway. I didn’t want to have to make control bones for every single property, because that would get crazy, but putting custom properties ON a smaller number of bones is so simple I feel silly for not having thought of it.

I have seen people using other 3d software like Maya and 3DS, and having nice master control UI panels for every aspect of a rig. That was what I was trying to re-create, but I guess that is not an option in Blender at the moment.

I certainly won’t look a gift horse in the mouth, because Blender is amazing software that has opened up 3D work as a hobby for me… but would it be fair to say that linking and other asset management/sharing features are currently one of the areas where it is weaker than others?

Still, a lower priority than the new dependency graph and viewport. Mmm… eevee…

Anyway, thank you very much!

I’m glad it helped you !

About fancy rig’s UI : there are many attempts to make something, but it’s quite complicated and using many workarounds.
One great thing about them is that they allow to select bones from the panel , because it can get messy when animating. But IMO it’s great to have but not a show stopper either.
You can still have a good UI script that allow you to get things more organized. You can look at more or less official rigs (from open movies or cg cookie, rigify ) to see how they manage things.

About linking system : the good thing is that it’s simple and stable, but it need more features. Overhides are planned for 2.8 that should allow you to tweak a linked shader, change a modifier value ect… it’s related to dependancy graph. That will solve many production’s corner cases. Because now the solution I found is to make a driver, some people use script that change properties when opening a shot file. That should also allow different characters to share the same rig, because for now they all get the same animation.
That last point allow in the other hand something really cool for free. If you’ve got complex characters you may want when animating to use a lowpoly model instead, to have faster playback. In your character’s .blend you can make a second group with lowpoly geometry, both use the same armature and in your shot file you can just select the empty that do the dupligroup and change the group it duplicate. This can be scripted easily too.
There have been some issue too with simulations, when linked simulations caches would go into the original rig folder instead of the shot file thus being always overwritten. I haven’t get into that stuff for a long time but I think it work quite better now thanks to recent open movies.

I know that 3DS max had a library linking system ( Xref ) that was completely broken, so users that I know tend to append in shot instead of linking. I know that it was the case for a long time, don’t know how it is now.

In maya it’s very nice, and really think for collaborative work. You can link a mesh in a scene , do the rig (vertex groups, bones, shapes ect…) take that and link it in a shot, overrhide materials when there are shading issue ect… If you change the original mesh everything follows. But I’m not a maya user so I don’t know the corner cases.

Asset management is “to me” something else, I don’t know what features are in other softwares. In blender it’s a kind of DIY for now, but that’s beeing worked by Bastien Montagne , he already solve a big issue with library , that was that if you break a link ( like you’ve renamed your character blend file) and open a shot you were totally screwed . Now this is fixed and you can easily repair your shot file. I think 2.8 will also improve a lot of things in that area. If I understand correctly you will be able to make custom repository (material , characters, ect…) more easily, very exiting stuff too.

In blender I think the good point is that it’s simple and efficient and also quite stable, but still lack some features to get around corner cases.
But I must admit that I don’t know much how it’s going in other softwares. Maybe someone else can try to give a fair comparison .

There is one thing that is making doing this very hard… I can find no way to have any sort of value that I can toggle. Well, I could make custom classes for property groups for every single new prop or clothing item, but that seems silly.

I know I can just use ints to drive boolean values, like “hide_render” and the like, though that seems inelegant. An afternoon of googling has turned up a lot of people trying to find something like this, and being told you can’t… though a lot of those discussions are old.

Is there still no way to make a UI based on a dynamic set of properties, that can include something like a check-box?

I don’t mean to sound complainy or anything, and I accept that this might not be possible. But it seems as if I MUST be missing something, if I can’t do something as basic as toggling a value between 1 and 0 with a button, somehow.

I have partly answered my own question, so I will leave this here for anyone else who runs across it. If a lot of objects are going to have the same custom property, you can register it as an RNA property, which may be enough to get you googling. But if you really do want to have just one-off unique properties that you can easily toggle from your UI, you can do something like this:

class ToggleBoneProperty(bpy.types.Operator): bl_idname = “bone.bool”
bl_label = “toggle”
propname = bpy.props.StringProperty()

def execute(self, context):
    print("Toggled", self.propname)        
    bpy.context.active_pose_bone[self.propname] = not bpy.context.active_pose_bone[self.propname] 
    bpy.context.scene.frame_set(bpy.context.scene.frame_current) # Force update
    return{'FINISHED'}   

def register():
bpy.utils.register_class(ToggleBoneProperty)

def unregister():
bpy.utils.unregister_class(ToggleBoneProperty)

register()

You can then use it in your UI panel with layout.operator. If you want to get fancy you can make a wrapper to change the icon or text based on the state of the bool with something like this:

def drawBool(self, layout, name, icons = ("", ""), strings = ("", "")):
    bone = bpy.context.active_pose_bone
    if bone[name] == 0:
        boolValue = False
    else:
        boolValue = True
    layout.operator("bone.bool", text=strings[boolValue], icon = icons[boolValue]).propname = name   

Where the “icons” and “strings” tuple contain what should be displayed of the bool is false or true, respectively.

I used the IF statement with boolValue to make it to the right thing if the property got accidentally set to a float like 1.0 instead of 1/0

The downside of this is that you can’t keyframe it from your UI panel, but have to go into the actual bone custom properties, at least to make the initial keyframe.

I hope that helps someone

I have another question. I can supply a Blend file if needed, but the problem seems to be easily replicatable.

Obviously my rig has drivers that control other parts of it. I’m using Rigify, if nothing else. So when I make a rig and mesh, group them, then link the group in a new blend file and make a rig proxy, I get a lot of console messages saying that there is a dependency loop.

NAME rig depends on NAME rig through Proxy.
NAME rig depends on NAME rig through Driver.

This is kind of confusing. I know obviously that one instance of the rig name refers to the proxy and another to the linked object, but why the dependency loop? It doesn’t seem to actually cause any problems, but I’ve learned it’s a bad idea to totally ignore warnings just because you don’t know why they are happening :slight_smile:

Hello,

Sorry for the late reply, I don’t come here often…
About accessing value like hide toggles, indeed you have to make custom props and drivers, that’s at least how it’s done on many rigs I’ve seen.
That can work for many things, like modifiers , material , object properties (visibility ect…), I haven’t tested it with hotter stuff like particles.

You can still in your UI script access them directly . With python you can access and modify all linked data but once you’ll reload your scene it will load default settings. So that can work if it’s only a comfort feature, like hiding something while you’re animating but it won’t be saved.

I’ve seen that in open movies like Cosmos Landromat, they have made some script that runs when you open the .blend file so they can modify settings like material or particles per shot.

Indeed all these workaround aren’t perfect, the 2.8 with the override system should allow things to run a lot smoother , it’s aiming at solving all these kind of issues.

About the armless dependency cycle, I get these kind of message regularly but haven’t investigated that much. Sometime it just work anyway. You can have regular dependency issue if you notice a time shift when positioning bones.
One good test is to move a bone , cancel, if the bone stays in place and moving one frame restore the good bone position, then you’ve got a real issue.
Maybe these message then can help you.
I don’t know that much on this subject , maybe someone else can enlighten us a bit more…
If you’re only using rigify rig, then it should be safe and production proof .