[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14290] trunk/blender/source/blender: == Armature Tools - Separate (not yet functional) ==
Joshua Leung
aligorith at gmail.com
Mon Mar 31 05:40:56 CEST 2008
Revision: 14290
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14290
Author: aligorith
Date: 2008-03-31 05:40:47 +0200 (Mon, 31 Mar 2008)
Log Message:
-----------
== Armature Tools - Separate (not yet functional) ==
Initial commit of Separate tool for Armatures. Currently, the functionality is hidden behind a temporary patch, as there are still issues to be worked out (crashes under certain conditions and a re-linking issue). It may remain like this for the release if I can't get it to work correctly.
Note:
- Hotkey for separate is Ctrl-Shift-P (it's a bit clumsy, and isn't consistent with P for separate for meshes, but Select Parent(s) is better as P)
Modified Paths:
--------------
trunk/blender/source/blender/include/BIF_editarmature.h
trunk/blender/source/blender/src/editarmature.c
trunk/blender/source/blender/src/editcurve.c
trunk/blender/source/blender/src/header_view3d.c
trunk/blender/source/blender/src/space.c
Modified: trunk/blender/source/blender/include/BIF_editarmature.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editarmature.h 2008-03-30 18:08:55 UTC (rev 14289)
+++ trunk/blender/source/blender/include/BIF_editarmature.h 2008-03-31 03:40:47 UTC (rev 14290)
@@ -93,6 +93,7 @@
void free_editArmature(void);
int join_armature(void);
+void separate_armature(void);
void load_editArmature(void);
void make_bone_parent(void);
Modified: trunk/blender/source/blender/src/editarmature.c
===================================================================
--- trunk/blender/source/blender/src/editarmature.c 2008-03-30 18:08:55 UTC (rev 14289)
+++ trunk/blender/source/blender/src/editarmature.c 2008-03-31 03:40:47 UTC (rev 14290)
@@ -653,6 +653,223 @@
return 1;
}
+/* Helper function for armature separating - link fixing */
+static void separated_armature_fix_links(Object *origArm, Object *newArm, ListBase *edbo)
+{
+ Object *ob;
+ bPoseChannel *pchan;
+ bConstraint *con;
+ EditBone *ebo, *ebn;
+
+ /* 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) {
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ for (con= pchan->constraints.first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ /* constraint targets */
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ /* any targets which point to original armature are redirected to the new one only if:
+ * - the target isn't the original armature itself
+ * - the target is one of the bones which were moved into newArm
+ */
+ if ((ct->tar == origArm) && (ct->subtarget[0] != 0)) {
+ for (ebo=edbo->first, ebn=edbo->last; ebo && ebn; ebo=ebo->next, ebn=ebn->prev) {
+ /* check if either one matches */
+ if ( (strcmp(ebo->name, ct->subtarget)==0) ||
+ (strcmp(ebn->name, ct->subtarget)==0) )
+ {
+ ct->tar= newArm;
+ printf("arm = '%s' pchan = '%s', ebo = '%s', YES \n", ob->id.name+2, pchan->name, ebo->name);
+ printf("arm = '%s' pchan = '%s', ebn = '%s', YES \n", ob->id.name+2, pchan->name, ebn->name);
+ break;
+ }
+ else {
+ printf("arm = '%s' pchan = '%s', ebo = '%s', NOT\n", ob->id.name+2, pchan->name, ebo->name);
+ printf("arm = '%s' pchan = '%s', ebn = '%s', NOT \n", ob->id.name+2, pchan->name, ebn->name);
+ }
+
+ /* check if both ends have met (to stop checking) */
+ if (ebo == ebn) break;
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
+ }
+ }
+ }
+
+ /* fix object-level constraints */
+ if (ob != origArm) {
+ for (con= ob->constraints.first; con; con= con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ /* constraint targets */
+ if (cti && cti->get_constraint_targets) {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next) {
+ /* any targets which point to original armature are redirected to the new one only if:
+ * - the target isn't the original armature itself
+ * - the target is one of the bones which were moved into newArm
+ */
+ if ((ct->tar == origArm) && (ct->subtarget[0] != 0)) {
+ for (ebo=edbo->first, ebn=edbo->last; ebo && ebn; ebo=ebo->next, ebn=ebn->prev) {
+ /* check if either one matches */
+ if ( (strcmp(ebo->name, ct->subtarget)==0) ||
+ (strcmp(ebn->name, ct->subtarget)==0) )
+ {
+ ct->tar= newArm;
+ break;
+ }
+
+ /* check if both ends have met (to stop checking) */
+ if (ebo == ebn) break;
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
+ }
+ }
+
+ /* See if an object is parented to this armature */
+ if ((ob->parent) && (ob->parent == origArm)) {
+ /* Is object parented to a bone of this src armature? */
+ if (ob->partype==PARBONE) {
+ /* bone name in object */
+ for (ebo=edbo->first, ebn=edbo->last; ebo && ebn; ebo=ebo->next, ebn=ebn->prev) {
+ /* check if either one matches */
+ if ( (strcmp(ebo->name, ob->parsubstr)==0) ||
+ (strcmp(ebn->name, ob->parsubstr)==0) )
+ {
+ ob->parent= newArm;
+ break;
+ }
+
+ /* check if both ends have met (to stop checking) */
+ if (ebo == ebn) break;
+ }
+ }
+ }
+ }
+}
+
+void separate_armature (void)
+{
+ EditBone *ebo, *ebn;
+ Object *oldob;
+ Base *base, *oldbase;
+ bArmature *arm;
+ ListBase edbo = {NULL, NULL};
+
+ // 31Mar08 - Aligorith:
+ // this tool is currently not ready for production use, as it will still
+ // crash in some cases, and also constraint relinking isn't working yet
+ // remove the following two lines to test this tool... you have been warned!
+ okee("Not implemented (WIP)");
+ return;
+
+ if ( G.vd==0 || (G.vd->lay & G.obedit->lay)==0 ) return;
+ if ( okee("Separate")==0 ) return;
+
+ waitcursor(1);
+
+ arm= G.obedit->data;
+
+ /* we are going to trick everything as follows:
+ * 1. duplicate base: this is the new one, remember old pointer
+ * 2. set aside all NOT selected bones
+ * 3. load_editArmature(): this will be the new base
+ * 4. freelist and restore old armature
+ */
+
+ /* only edit-base selected */
+ base= FIRSTBASE;
+ while(base) {
+ if(base->lay & G.vd->lay) {
+ if(base->object==G.obedit) base->flag |= 1;
+ else base->flag &= ~1;
+ }
+ base= base->next;
+ }
+
+ /* set aside: everything that is not selected */
+ for (ebo= G.edbo.first; ebo; ebo= ebn) {
+ ebn= ebo->next;
+
+ /* remove from original, and move to duplicate if not-selected */
+ if ((ebo->flag & BONE_SELECTED)==0) {
+ EditBone *curbone;
+
+ /* need to make sure children don't still refer to this only if they are selected
+ * - potentially slow O(n*n) situation here...
+ */
+ for (curbone= G.edbo.first; curbone; curbone=curbone->next) {
+ if ((curbone->parent == ebo) && (curbone->flag & BONE_SELECTED)) {
+ curbone->parent= ebo->parent;
+ curbone->flag &= ~BONE_CONNECTED;
+ }
+ }
+
+ BLI_remlink(&G.edbo, ebo);
+ BLI_addtail(&edbo, ebo);
+ }
+ }
+
+ oldob= G.obedit;
+ oldbase= BASACT;
+
+ adduplicate(1, 0); /* no transform and zero so do get a linked dupli */
+
+ G.obedit= BASACT->object; /* basact is set in adduplicate() */
+
+ G.obedit->data= copy_armature(arm);
+ /* because new armature is a copy: reduce user count */
+ arm->id.us--;
+
+ load_editArmature();
+
+ BASACT->flag &= ~SELECT;
+
+ /* fix links before depsgraph flushes */ // err... or after?
+ printf("oldob = %p, obact = %p \n", oldob, G.obedit);
+ separated_armature_fix_links(oldob, G.obedit, &G.edbo);
+
+ if (G.edbo.first) free_editArmature();
+
+ G.edbo = edbo;
+
+ G.obedit= 0; /* displists behave different in edit mode */ // needed?
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); /* this is the separated one */
+ DAG_object_flush_update(G.scene, oldob, OB_RECALC_DATA); /* this is the original one */
+
+ G.obedit= oldob;
+ BASACT= oldbase;
+ BASACT->flag |= SELECT;
+
+ waitcursor(0);
+
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ allqueue(REDRAWOOPS, 0);
+}
+
/* **************** END tools on Editmode Armature **************** */
/* **************** PoseMode & EditMode *************************** */
@@ -1149,17 +1366,17 @@
static void delete_bone(EditBone* exBone)
{
- EditBone *curBone;
+ EditBone *curBone;
- /* Find any bones that refer to this bone */
- for (curBone=G.edbo.first;curBone;curBone=curBone->next){
- if (curBone->parent==exBone){
+ /* Find any bones that refer to this bone */
+ for (curBone=G.edbo.first;curBone;curBone=curBone->next) {
+ if (curBone->parent==exBone) {
curBone->parent=exBone->parent;
curBone->flag &= ~BONE_CONNECTED;
}
}
- BLI_freelinkN (&G.edbo,exBone);
+ BLI_freelinkN(&G.edbo,exBone);
}
/* only editmode! */
Modified: trunk/blender/source/blender/src/editcurve.c
===================================================================
--- trunk/blender/source/blender/src/editcurve.c 2008-03-30 18:08:55 UTC (rev 14289)
+++ trunk/blender/source/blender/src/editcurve.c 2008-03-31 03:40:47 UTC (rev 14290)
@@ -449,7 +449,7 @@
G.obedit= 0; /* displists behave different in edit mode */
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); /* this is the separated one */
- DAG_object_flush_update(G.scene, oldob, OB_RECALC_DATA); /* this is the separated one */
+ DAG_object_flush_update(G.scene, oldob, OB_RECALC_DATA); /* this is the original one */
G.obedit= oldob;
BASACT= oldbase;
Modified: trunk/blender/source/blender/src/header_view3d.c
===================================================================
--- trunk/blender/source/blender/src/header_view3d.c 2008-03-30 18:08:55 UTC (rev 14289)
+++ trunk/blender/source/blender/src/header_view3d.c 2008-03-31 03:40:47 UTC (rev 14290)
@@ -3872,6 +3872,9 @@
case 21:
armature_autoside_names(event-19);
break;
+ case 22: /* separate */
+ separate_armature();
+ break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -3961,7 +3964,7 @@
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
- if(arm->flag & ARM_MIRROR_EDIT)
+ if (arm->flag & ARM_MIRROR_EDIT)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude Forked|Shift E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
@@ -3969,6 +3972,8 @@
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Fill Between Joints|F", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list