Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/include/BIF_editarmature.h3
-rw-r--r--source/blender/python/api2_2x/Armature.c2
-rw-r--r--source/blender/python/api2_2x/Bone.c2
-rw-r--r--source/blender/src/editarmature.c160
4 files changed, 136 insertions, 31 deletions
diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h
index 9cdde5ffcb3..a48ca3bbe82 100644
--- a/source/blender/include/BIF_editarmature.h
+++ b/source/blender/include/BIF_editarmature.h
@@ -36,6 +36,7 @@ struct Object;
struct Base;
struct Bone;
struct bArmature;
+struct ListBase;
typedef struct EditBone
{
@@ -105,7 +106,7 @@ void remake_editArmature(void);
void selectconnected_armature(void);
void selectconnected_posearmature(void);
void select_bone_parent(void);
-void unique_editbone_name (char* name);
+void unique_editbone_name (struct ListBase *ebones, char* name);
void auto_align_armature(void);
void create_vgroups_from_armature(Object *ob, Object *par);
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c
index 2ccf0b7b774..4aab0515587 100644
--- a/source/blender/python/api2_2x/Armature.c
+++ b/source/blender/python/api2_2x/Armature.c
@@ -271,7 +271,7 @@ static int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value
//create a new editbone
editbone = MEM_callocN(sizeof(EditBone), "eBone");
BLI_strncpy(editbone->name, key_str, 32);
- unique_editbone_name(editbone->name);
+ unique_editbone_name(NULL, editbone->name);
editbone->dist = ((BPy_EditBone*)value)->dist;
editbone->ease1 = ((BPy_EditBone*)value)->ease1;
editbone->ease2 = ((BPy_EditBone*)value)->ease2;
diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c
index e00ccd00477..0d4c0983a67 100644
--- a/source/blender/python/api2_2x/Bone.c
+++ b/source/blender/python/api2_2x/Bone.c
@@ -782,7 +782,7 @@ static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds
//otherwise this will act as a py_object
py_editBone->editbone = NULL;
- unique_editbone_name(name);
+ unique_editbone_name(NULL, name);
BLI_strncpy(py_editBone->name, name, 32);
py_editBone->parent = NULL;
py_editBone->weight= 1.0f;
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index cc3d19295fa..8f8b0353489 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -107,6 +107,8 @@ extern float centre[3], centroid[3]; /* Originally defined in editobject.c */
/* Macros */
#define TEST_EDITARMATURE {if(G.obedit==0) return; if( (G.vd->lay & G.obedit->lay)==0 ) return;}
+/* prototypes for later */
+static EditBone *editbone_name_exists (ListBase *ebones, char *name); // proto for below
/* **************** tools on Editmode Armature **************** */
@@ -426,12 +428,93 @@ void docentre_armature (Object *ob, int centremode)
}
}
+/* Helper function for armature joining - link fixing */
+static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone)
+{
+ Object *ob;
+ bPose *pose;
+ bPoseChannel *pchant;
+ bConstraint *con;
+
+ /* let's go through all objects in database */
+ for (ob= G.main->object.first; ob; ob= ob->id.next) {
+ /* do some object-type specific things */
+ if (ob->type == OB_ARMATURE) {
+ pose= ob->pose;
+ for (pchant= pose->chanbase.first; pchant; pchant= pchant->next) {
+ for (con= pchant->constraints.first; con; con= con->next) {
+ Object *conOb;
+ char *subtarget;
+
+ /* constraint targets */
+ conOb= get_constraint_target(con, &subtarget);
+ if (conOb == srcArm) {
+ if (strcmp(subtarget, "")==0)
+ set_constraint_target(con, tarArm, "");
+ else if (strcmp(pchan->name, subtarget)==0)
+ set_constraint_target(con, tarArm, curbone->name);
+ }
+
+ /* action constraint? */
+ if (con->type == CONSTRAINT_TYPE_ACTION) {
+ bActionConstraint *data= con->data;
+ bAction *act;
+ bActionChannel *achan;
+
+ if (data->act) {
+ act= data->act;
+
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ if (strcmp(achan->name, pchan->name)==0)
+ BLI_strncpy(achan->name, curbone->name, 32);
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ /* fix object-level constraints */
+ if (ob != srcArm) {
+ for (con= ob->constraints.first; con; con= con->next) {
+ Object *conOb;
+ char *subtarget;
+
+ conOb= get_constraint_target(con, &subtarget);
+ if (conOb == srcArm) {
+ if (strcmp(subtarget, "")==0)
+ set_constraint_target(con, tarArm, "");
+ else if (strcmp(pchan->name, subtarget)==0)
+ set_constraint_target(con, tarArm, curbone->name);
+ }
+ }
+ }
+
+ /* See if an object is parented to this armature */
+ if (ob->parent && (ob->parent == srcArm)) {
+ /* Is object parented to a bone of this src armature? */
+ if (ob->partype==PARBONE) {
+ /* bone name in object */
+ if (!strcmp(ob->parsubstr, pchan->name))
+ BLI_strncpy(ob->parsubstr, curbone->name, 32);
+ }
+
+ /* make tar armature be new parent */
+ ob->parent = tarArm;
+ }
+ }
+}
+
int join_armature(void)
{
Object *ob;
+ bArmature *arm;
Base *base, *nextbase;
- ListBase eblist;
- EditBone *curbone, *next;
+ bPose *pose, *opose;
+ bPoseChannel *pchan, *pchann;
+ ListBase ebbase, eblist;
+ EditBone *curbone;
float mat[4][4], imat[4][4];
/* Ensure we're not in editmode and that the active object is an armature*/
@@ -439,27 +522,35 @@ int join_armature(void)
ob= OBACT;
if(ob->type!=OB_ARMATURE) return 0;
+ arm= get_armature(ob);
- /* Put the active armature into editmode and join the bones from the other one*/
-
- enter_editmode(EM_WAITCURSOR);
+ /* Get editbones of active armature to add editbones to */
+ ebbase.first=ebbase.last= NULL;
+ make_boneList(&ebbase, &arm->bonebase, NULL);
+ pose= ob->pose;
for (base=FIRSTBASE; base; base=nextbase) {
nextbase = base->next;
if (TESTBASE(base)){
if ((base->object->type==OB_ARMATURE) && (base->object!=ob)){
- /* Make a list of editbones */
+ /* Make a list of editbones in current armature */
eblist.first=eblist.last= NULL;
make_boneList (&eblist, &((bArmature*)base->object->data)->bonebase,NULL);
+
+ /* Get Pose of current armature */
+ opose= base->object->pose;
+
/* Find the difference matrix */
Mat4Invert(imat, ob->obmat);
Mat4MulMat4(mat, base->object->obmat, imat);
- /* Copy bones from the object to the edit armature */
- for (curbone=eblist.first; curbone; curbone=next){
- next = curbone->next;
-
- unique_editbone_name (curbone->name);
+ /* Copy bones and posechannels from the object to the edit armature */
+ for (pchan=opose->chanbase.first; pchan; pchan=pchann) {
+ pchann= pchan->next;
+ curbone= editbone_name_exists(&eblist, pchan->name);
+
+ /* Get new name */
+ unique_editbone_name (&ebbase, curbone->name);
/* Transform the bone */
{
@@ -491,8 +582,19 @@ int join_armature(void)
curbone->roll -= atan2(difmat[2][0], difmat[2][2]);
}
+
+ /* Fix Constraints and Other Links to this Bone and Armature */
+ joined_armature_fix_links(ob, base->object, pchan, curbone);
+
+ /* Rename pchan */
+ sprintf(pchan->name, curbone->name);
+
+ /* Jump Ship! */
BLI_remlink(&eblist, curbone);
- BLI_addtail(&G.edbo, curbone);
+ BLI_addtail(&ebbase, curbone);
+
+ BLI_remlink(&opose->chanbase, pchan);
+ BLI_addtail(&pose->chanbase, pchan);
}
free_and_unlink_base(base);
@@ -502,7 +604,9 @@ int join_armature(void)
DAG_scene_sort(G.scene); // because we removed object(s)
- exit_editmode(EM_FREEDATA|EM_WAITCURSOR);
+ editbones_to_armature(&ebbase, ob);
+ if (ebbase.first) BLI_freelistN(&ebbase);
+
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWOOPS, 0);
return 1;
@@ -925,8 +1029,6 @@ static void delete_bone(EditBone* exBone)
BLI_freelinkN (&G.edbo,exBone);
}
-static EditBone *editbone_name_exists (char *name); // proto for below
-
/* only editmode! */
void delete_armature(void)
{
@@ -942,7 +1044,7 @@ void delete_armature(void)
bPoseChannel *chan, *next;
for (chan=G.obedit->pose->chanbase.first; chan; chan=next) {
next= chan->next;
- curBone = editbone_name_exists (chan->name);
+ curBone = editbone_name_exists (&G.edbo, chan->name);
if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
free_constraints(&chan->constraints);
@@ -952,7 +1054,7 @@ void delete_armature(void)
for(con= chan->constraints.first; con; con= con->next) {
char *subtarget = get_con_subtarget_name(con, G.obedit);
if (subtarget) {
- curBone = editbone_name_exists (subtarget);
+ curBone = editbone_name_exists (&G.edbo, subtarget);
if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
con->flag |= CONSTRAINT_DISABLE;
subtarget[0]= 0;
@@ -1266,7 +1368,7 @@ static EditBone *add_editbone(char *name)
EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
BLI_strncpy (bone->name, name, 32);
- unique_editbone_name (bone->name);
+ unique_editbone_name(&G.edbo, bone->name);
BLI_addtail(&G.edbo, bone);
@@ -1451,7 +1553,7 @@ void adduplicate_armature(void)
curBone->temp = eBone;
eBone->temp = curBone;
- unique_editbone_name (eBone->name);
+ unique_editbone_name (&G.edbo, eBone->name);
BLI_addtail (&G.edbo, eBone);
if (!firstDup)
firstDup=eBone;
@@ -1698,11 +1800,13 @@ void clear_bone_parent(void)
}
-static EditBone *editbone_name_exists (char *name)
+static EditBone *editbone_name_exists (ListBase *ebones, char *name)
{
EditBone *eBone;
- for (eBone=G.edbo.first; eBone; eBone=eBone->next){
+ if (ebones == NULL) ebones = &G.edbo;
+
+ for (eBone=ebones->first; eBone; eBone=eBone->next){
if (!strcmp (name, eBone->name))
return eBone;
}
@@ -1710,14 +1814,14 @@ static EditBone *editbone_name_exists (char *name)
}
/* note: there's a unique_bone_name() too! */
-void unique_editbone_name (char *name)
+void unique_editbone_name (ListBase *ebones, char *name)
{
char tempname[64];
int number;
char *dot;
- if (editbone_name_exists(name)) {
+ if (editbone_name_exists(ebones, name)) {
/* Strip off the suffix, if it's a number */
number= strlen(name);
@@ -1729,7 +1833,7 @@ void unique_editbone_name (char *name)
for (number = 1; number <=999; number++){
sprintf (tempname, "%s.%03d", name, number);
- if (!editbone_name_exists(tempname)){
+ if (!editbone_name_exists(ebones, tempname)){
BLI_strncpy (name, tempname, 32);
return;
}
@@ -1837,7 +1941,7 @@ void extrude_armature(int forked)
else strcat(newbone->name, "_R");
}
}
- unique_editbone_name(newbone->name);
+ unique_editbone_name(&G.edbo, newbone->name);
/* Add the new bone to the list */
BLI_addtail(&G.edbo, newbone);
@@ -1903,7 +2007,7 @@ void subdivide_armature(void)
newbone->flag |= BONE_CONNECTED;
- unique_editbone_name (newbone->name);
+ unique_editbone_name (&G.edbo, newbone->name);
/* correct parent bones */
for (tbone = G.edbo.first; tbone; tbone=tbone->next){
@@ -2535,9 +2639,9 @@ void armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
if(G.obedit && G.obedit->data==arm) {
EditBone *eBone;
- eBone= editbone_name_exists(oldname);
+ eBone= editbone_name_exists(&G.edbo, oldname);
if(eBone) {
- unique_editbone_name (newname);
+ unique_editbone_name (&G.edbo, newname);
BLI_strncpy(eBone->name, newname, MAXBONENAME);
}
else return;