Let's say you have a rigged character...

Let’s say you have a rigged character, along with 50 props and things, all parented to the armature.

Now you have an updated character mesh that you want to substitute in this scene; the character have a fifty shape keys and relative drivers, and since, when you append the new one, it comes along with the old armature which it’s parented to, all its drivers are linked to this armature.

AFAIK you have two choices:
1) relink the new character and all its drivers, modifiers, constraints etc to the old armature one by one

2) change all the props to be children of the appended armature (someone parented to object, some to armature, some to bones), that means to clear parents and do a new parenting one by one

What will your workflow, apart from tearing off your hair and start to use another application?

@moderators,
in spite of its form, this post is not a help request, rather it’s primarily intended to be a bump to the need of a decent asset manager, or a better workflow for appending or/and for managing such situations (like multiple drag and drop, for instance), and I would like to have a feedback from users, so I would be grateful if you could not move this thread in support forums, thanks.

Of course it would be great if somebody can suggest me an easy way to manage this issue and prove that I’m a moron :rolleyes:.

paolo

Very kind of you Mods!

It seems you don’t understand how severe are the problems exposed here.

paolo

If I did have such problems, I would probably try write some scripts to help.
Scripts are very good for doing repetative tasks with known workflow.

dirty-stick,
one thing is having a problem as user, other is to have time, wish and skill to make scripts to resolve the bad design of blender.

paolo

If you don’t want your thread moved to the support section, perhaps don’t frame it as a support question?

Note, I didn’t move this thread, but as it exists, this is definitely where it belongs.

@9105826,
I asked please not to move this thread, I cannot demand it.

I don’t understand if you were you to actually move this thread, whoever he was, he is evidently able to read only literally (given that he even read it).

EDIT: To be fair, the issue described doesn’t pertain neither to animation nor to rigging, I might have made an example with objects, not involving any armature.

paolo

So… given the responses thus far… I probably shouldn’t touch this thread with a 10 foot pole… but I’ve been known to do stupid shit before…

Gotcha, one rigged character, 50 props and things all attached to an armature…

Now you have an updated character mesh that you want to substitute in this scene; the character have a fifty shape keys and relative drivers, and since, when you append the new one, it comes along with the old armature which it’s parented to, all its drivers are linked to this armature.

OK, updated character, 50 thingys, what I’m not getting here is when you say “append in the new one, it comes along with the old armature which it’s parented to”, so why is that happening? Your updated character is a different blend file from the first one, right? Old character is one .blend file and the new character is a different blend file, right? New character, new armature, right? You should be appending from 2 different files, old character & new character. So I fail to under stand your armature problem here…

AFAIK you have two choices:
1) relink the new character and all its drivers, modifiers, constraints etc to the old armature one by one

relink??? maybe, but I thought you were asking about appending…

when you append the new one, it comes along with the old armature

So what’s really going on here? Linking & appending are a bit different, like comparing apples to old rotten gym shoes…

Randy

Thank you Randy for doing this stupid thing, I appreciate!

The situation described is realistic, I said a character because I have just this case, but it could be a tree with foliage, maybe a room with furnitures, or some abstract structure for motion graphic…

I will try to explain, I have a character in two different files (say A and B), the armature is exactly the same, the character is a little different.

When I append the character mesh from file B into A, it comes with its armature (B), and all its drivers are ‘linked’ to this armature, that is every Driver Target ID of its drivers is pointing to the armature B; if I want to make the character B a child of the armature A, all its drivers are broken (see image).


The same if the character has modifiers with target objects, they are also appended along with the character, so I have them duplicated in the scene, the old ones parented to armature A, and the new ones to armature B.
All is working, but I must stay with two armatures, one for the props only and one for the character, but this is not good at all, so I would try to fix this situation without spending a whole day.

I hope I clarified myself enough in spite of my bad English

Thank you,
paolo

Hi Paolo,

Got to be honest here, I really thought about this, for a long time, and I just don’t understand it.

Why would one ever want to make one armature (character) the child of another armature (character)?

The same if the character has modifiers with target objects, they are also appended along with the character, so I have them duplicated in the scene, the old ones parented to armature A, and the new ones to armature B.
All is working, but I must stay with two armatures, one for the props only and one for the character, but this is not good at all, so I would try to fix this situation without spending a whole day.

I’m not understanding you here. Can you show me the files, and the steps needed to produce your problem?

You can upload both .blend files to grapicall.org, once uploaded, you will be given a url to the file. Post the url here, or if you don’t want it out in public, so everyone can download your file, send me the links via a private message. Write a text file on how the create the problem iin one of the blender files, or post it a the same site and include the url so I can read it and I’ll really take a good look at it.

Randy

Randy,
I was doing just a hypothetical case, now I would make this files real to be able to append them, that’s why this thread starts with “Let’s say…”, and I asked moderators to not move this thread in the support forums.
It seems that nobody understood that.

I’m trying to point out the severe deficiencies of the UI, or to get from users the correct workflow in the case I’m missing it.

With ‘character’ I mean the ‘mesh’, not the armature, so I want to make a mesh(B) the child of an armature(A).
Please try and re read with this in mind, that is the very point.

Sorry but I am not able to explain the matter better than this, however every expert user must have faced this situation before, and he should have met this issue, although not so complicate as in my example.

Thank you anyway,
paolo

Heres an A and B file.
A: http://www.pasteall.org/blend/33126
B: http://www.pasteall.org/blend/33128

A’s armature legs have been renamed, B has a head shape key, value controlled with Bone.001.
Open A, delete mesh, append B > Objects > Cube, now you want to try make the B mesh use the A armature.

I was able the change the shape key driver targets from Armature.001 to Armature, with this script.

import bpy

for d in bpy.context.active_object.data.shape_keys.animation_data.drivers:
    for dv in d.driver.variables:
        for t in dv.targets:
            if t.id == bpy.data.objects['Armature.001']:
                t.id = bpy.data.objects['Armature']

Select mesh then run from text editor.
Im sure other coders could make better scripts to swap data.

I guess what you want is a script/addon to scan the mesh and swap the armature, or a function in blender to append B mesh to armature A.

Dirty-stick, thank you very much, very kind of you! It’s easy and it works!

I will try to change this script into an addon, so to give it an easy interface, I think it worth it!

If I succeed I’ll post it.

paolo

Dirty-stick, really your script runs like a charm!

I have tested it over an object with 20 shape-key drivers and multiple variables, and it accomplished the task in a mere second; if I had to do it manually one by one, waiting every time for internal calculations, it should have taken around a quarter of hour, maybe more, and it would have been very tedious!

From now on it will be in my tools.

Thanks a lot again!!

paolo

Good to know it worked.
Maybe a better script will be written in the future, for swapping data.

Yeah, it could really useful IMO!

in this very moment I’m digging blender python (without any skill) to try and find a way to give a small GUI to the script, basically a pair of drop down menus with a list of scene objects to choose from, we will see…

Cheers,
paolo

Ah-Ha!!! This is where I was failing to understand you:

When I was thinking character, I was thinking complete character mesh, armature & all other data in one single file ‘a’ and again, once complete character mesh, armature, & data in another file ‘b’. I’m sorry I wasn’t understanding you correctly, that’s why I asked to see the files.

For me, if I had 2 character meshes and had rigged one of them ‘A’, then I wanted to use the same armature for ‘B’, I would append in the armature object from ‘A’ into the ‘B’ file. Even if the ‘B’ character mesh was created by modifying the ‘A’ mesh, with the ‘B’ mesh having all the vertex groups, shape keys, etc that mesh ‘A’ has, I would think it would pretty much work by just appending the armature object.

I don’t have a lot of spare time to play with blender right now. I will take a look at dirty-stick’s files & script when I can, and see what we have. Then take a look at adding an interface to the script.

To be honest, sometimes you need just little scripts like this to help your work flow. I once created a machine that had over 150 separate mesh objects for the left side alone, so when I mirrored the objects over to make the right side, there’s no easy way to change the names from left to right for the objects. Not wanting to re-name all the objects manually, I wrote a script to do it for me. (spent about the same amount of time writing the script as it would have taken to rename the objects, so saved myself nothing time wise, until the next time I need to do this task) I have written about 6 such custom scripts for myself.

Randy

Yeah Randy, I’m conscious of my difficulties with English, and I’m quite sure that I was not yet able to show clearly the case, actually rather frequent in my workflow.

Even if the ‘B’ character mesh was created by modifying the ‘A’ mesh, with the ‘B’ mesh having all the vertex groups, shape keys, etc that mesh ‘A’ has, I would think it would pretty much work by just appending the armature object.

sadly it’s not an easy task at all, because all drivers of the mesh get broken, specifically, the targets of variables of every drive point to the wrong armature, and you have to replace them one by one; what makes the task very painful is that after each change you have to wait for blender to accomplish some sort of calculation which can take a long time, and you spend a lot of time in editing, waiting, editing, waiting, and so forth.

And here the script by dirty-stick comes very handy, it can do all the work in a flash, with no delays!
As you say, although the opportunities to use it may be rare, the time that you need it it can save you a lot of time and cursing!

Sadly I am not able to understand how to code GUI elements, even looking at examples and templates, I’m not a coder, so I can’t contribute, but the script is very easy in itself and when needed it can be tweaked for the task just by changing the names of targets, and I can live with it.

I would like though that it could become a standard command in blender, along with a better interface for Drivers (for instance, I would like some sort of advise for when a driver is broken, at least in the drivers panel; as it’s now you have to expressly select that driver for editing to discover in the N shelf that something is wrong with it).

Thank you,
paolo

hi, I made a prototype addon.
Probably some bugs with it, I think some some error checks for the active object should be added.
It should add panel to 3D view > object mode > properties, addon category Rigging.
Feel free to update it.

DT.py

# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

# DT.py @ http://blenderartists.org: 2014
# Code by dirty-stick @ http://blenderartists.org: 2014

# Todo: Add error checks for active object.

# ----------------------------------------------------------------
# Header

bl_info = {
    "name": "Driver Tools",
    "author": "dirty-stick",
    "version": (1, 0),
    "blender": (2, 70, 0),
    "location": "3D View > Object Mode > Properties > Driver Tools",
    "description": "...",
    "warning": "",
    "wiki_url": "",
    "category": "Rigging"}

import bpy

# Driver Tools PropertyGroup
class DT_props(bpy.types.PropertyGroup):
    ob1 = bpy.props.StringProperty(name="Object One", description="Object One", default='')
    ob2 = bpy.props.StringProperty(name="Object Two", description="Object Two", default='')

# ----------------------------------------------------------------

# ----------------------------------------------------------------
# Replace Driver Targets

def op_rdt(self, context):

    '''
    AD_dir
         Drivers are stored in AnimData pointers.
         This is a list of AnimData directories.
         For now, compile based on active object.
    '''
    AD_dir = []
    AD_dir.append(bpy.context.active_object.data.shape_keys.animation_data)    # rel shape key value

    # error check
    OK = True

    # ob1: check if Object
    if context.scene.DT.ob1 == '':
        self.report({"ERROR"},"Object One: Select an Object.")
        OK = False

    # ob2: check if Object
    if context.scene.DT.ob2 == '':
        self.report({"ERROR"},"Object Two: Select an Object.")
        OK = False

    # replace driver targets
    if OK:

        ob1 = bpy.data.objects[context.scene.DT.ob1]
        ob2 = bpy.data.objects[context.scene.DT.ob2]

        for ad in AD_dir:
            for d in ad.drivers:
                for dv in d.driver.variables:
                    for t in dv.targets:
                        if t.id == ob1:
                            t.id = ob2

class OT_RDT(bpy.types.Operator):
    """Replace Driver Targets that use Object One with Object Two"""
    bl_idname = "scene.replace_driver_targets"
    bl_label = "Replace Driver Targets"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        op_rdt(self, context)
        return {'FINISHED'}

# ----------------------------------------------------------------

# ----------------------------------------------------------------
# Panel

class PT_DRIVER_TOOLS(bpy.types.Panel):

    bl_label = "Driver Tools"
    bl_idname = "VIEW3D_PT_driver_tools"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_context = "object"

    @classmethod
    def poll(cls, context):
        return (context.active_object and (context.mode == 'OBJECT'))

    def draw(self, context):
        layout = self.layout

        row = layout.row()
        col = row.column(align=True)
        col.prop_search(context.scene.DT, "ob1", bpy.context.scene, "objects", text="")
        col.prop_search(context.scene.DT, "ob2", bpy.context.scene, "objects", text="")
        col.operator("scene.replace_driver_targets")

# ----------------------------------------------------------------

# ----------------------------------------------------------------
# Regiter

def register():
    bpy.utils.register_class(DT_props)
    bpy.types.Scene.DT = bpy.props.PointerProperty(type=DT_props)
    bpy.utils.register_class(OT_RDT)
    bpy.utils.register_class(PT_DRIVER_TOOLS)

def unregister():
    bpy.utils.unregister_class(PT_DRIVER_TOOLS)
    bpy.utils.unregister_class(OT_RDT)
    del bpy.types.Scene.DT
    bpy.utils.unregister_class(DT_props)

if __name__ == "__main__":
    register()

# ----------------------------------------------------------------

Hi dirty-stick,
you are really a lovely person!

I was just fighting in vain with python when I saw your post, I’m excited to give it a try.
I noticed that you put in the header “Idea by sourvinos” but it’s wrong, it was actually a your idea to make a script for the task, the mine was just a request, take it off please!

I will post my comments after some tests, though I think that you should start a new tread for it, and give it the due visibility.

Thank you a lot!

paolo

k, updated.

I dont know if it should have a thread yet, because of code problems.
The code at the moment, only works on shape key drivers.
The way the addon is designed, there will be a bug every day, ‘It dont work for x drivers.’
Thats not something I want to maintain, + the context and error checks.

It would be wise to get it to a reasonable state before making a thread.