diff options
author | Chris Want <cwant@ualberta.ca> | 2007-05-18 01:28:33 +0400 |
---|---|---|
committer | Chris Want <cwant@ualberta.ca> | 2007-05-18 01:28:33 +0400 |
commit | 34d7028931c8db8ce7441b74a94ea20969ead9ff (patch) | |
tree | 2d6dc2596e64f1fee7cccd2d9ecee9f8ae755dfb /source/blender/src | |
parent | 53b434919b769ff49c30642d5f93023c8a267e42 (diff) |
Plumifero's wishlist:
* When duplicating bones that have constraints (edit mode),
duplicate them too with TARGET field updated.
This is code that I wrote a few years ago before the armature
refactor. It is simple code that compiles and seems to work fine,
but should be checked by Ton or somebody else with better knowledge
of the current armature system.
Usage description, (stolen from the first time this code was
committed):
"Duplicating bones in edit mode now also duplicates the constraints
associated with that bone ... if the constraint subtarget bone is
also duplicated the new constraint points to this new bone as it's
subtarget."
Diffstat (limited to 'source/blender/src')
-rw-r--r-- | source/blender/src/editarmature.c | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 477e8d339ec..4db106478ce 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -1539,6 +1539,54 @@ void addvert_armature(void) } +static EditBone *get_named_editbone(char *name) +{ + EditBone *eBone; + + if (name) + for (eBone=G.edbo.first; eBone; eBone=eBone->next){ + if (!strcmp (name, eBone->name)) + return eBone; + } + + return NULL; +} + +static void update_dup_subtarget(EditBone *dupBone) +{ + /* If an edit bone has been duplicated, lets + * update it's constraints if the subtarget + * they point to has also been duplicated + */ + EditBone *oldtarget, *newtarget; + bPoseChannel *chan; + bConstraint *curcon; + ListBase *conlist; + char *subname; + + + if ( (chan = verify_pose_channel(OBACT->pose, dupBone->name)) ) + if ( (conlist = &chan->constraints) ) + for (curcon = conlist->first; curcon; curcon=curcon->next) { + /* does this constraint have a subtarget in + * this armature? + */ + subname = get_con_subtarget_name(curcon, G.obedit); + oldtarget = get_named_editbone(subname); + if (oldtarget) + /* was the subtarget bone duplicated too? If + * so, update the constraint to point at the + * duplicate of the old subtarget. + */ + if (oldtarget->flag & BONE_SELECTED){ + newtarget = (EditBone*) oldtarget->temp; + strcpy(subname, newtarget->name); + } + } + +} + + void adduplicate_armature(void) { bArmature *arm= G.obedit->data; @@ -1570,7 +1618,24 @@ void adduplicate_armature(void) /* Lets duplicate the list of constraits that the * current bone has. */ - /* temporal removed (ton) */ + if (OBACT->pose) { + bPoseChannel *chanold, *channew; + ListBase *listold, *listnew; + + chanold = verify_pose_channel (OBACT->pose, curBone->name); + if (chanold) { + listold = &chanold->constraints; + if (listold){ + channew = + verify_pose_channel(OBACT->pose, eBone->name); + if (channew) { + listnew = &channew->constraints; + copy_constraints (listnew, listold); + } + } + } + } + } } } @@ -1603,8 +1668,8 @@ void adduplicate_armature(void) /* Lets try to fix any constraint subtargets that might have been duplicated */ - /* temporal removed (ton) */ - } + update_dup_subtarget(eBone); + } } } |