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:
Diffstat (limited to 'source/blender/editors/armature/armature_relations.c')
-rw-r--r--source/blender/editors/armature/armature_relations.c204
1 files changed, 124 insertions, 80 deletions
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index dec67caacb1..e48c2df74e5 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -47,12 +47,15 @@
#include "BKE_animsys.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_report.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -245,23 +248,23 @@ int join_armature_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
- bArmature *arm = (ob) ? ob->data : NULL;
+ Object *ob_active = CTX_data_active_object(C);
+ bArmature *arm = (ob_active) ? ob_active->data : NULL;
bPose *pose, *opose;
bPoseChannel *pchan, *pchann;
EditBone *curbone;
float mat[4][4], oimat[4][4];
bool ok = false;
- /* Ensure we're not in editmode and that the active object is an armature. */
- if (!ob || ob->type != OB_ARMATURE)
+ /* Ensure we're not in editmode and that the active object is an armature*/
+ if (!ob_active || ob_active->type != OB_ARMATURE)
return OPERATOR_CANCELLED;
if (!arm || arm->edbo)
return OPERATOR_CANCELLED;
- CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+ CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
{
- if (base->object == ob) {
+ if (ob_iter == ob_active) {
ok = true;
break;
}
@@ -278,34 +281,34 @@ int join_armature_exec(bContext *C, wmOperator *op)
ED_armature_to_edit(arm);
/* get pose of active object and move it out of posemode */
- pose = ob->pose;
- ob->mode &= ~OB_MODE_POSE;
+ pose = ob_active->pose;
+ ob_active->mode &= ~OB_MODE_POSE;
- CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
+ CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
{
- if ((base->object->type == OB_ARMATURE) && (base->object != ob)) {
+ if ((ob_iter->type == OB_ARMATURE) && (ob_iter != ob_active)) {
tJoinArmature_AdtFixData afd = {NULL};
- bArmature *curarm = base->object->data;
+ bArmature *curarm = ob_iter->data;
/* we assume that each armature datablock is only used in a single place */
- BLI_assert(ob->data != base->object->data);
+ BLI_assert(ob_active->data != ob_iter->data);
/* init callback data for fixing up AnimData links later */
- afd.srcArm = base->object;
- afd.tarArm = ob;
+ afd.srcArm = ob_iter;
+ afd.tarArm = ob_active;
afd.names_map = BLI_ghash_str_new("join_armature_adt_fix");
/* Make a list of editbones in current armature */
- ED_armature_to_edit(base->object->data);
+ ED_armature_to_edit(ob_iter->data);
/* Get Pose of current armature */
- opose = base->object->pose;
- base->object->mode &= ~OB_MODE_POSE;
+ opose = ob_iter->pose;
+ ob_iter->mode &= ~OB_MODE_POSE;
//BASACT->flag &= ~OB_MODE_POSE;
/* Find the difference matrix */
- invert_m4_m4(oimat, ob->obmat);
- mul_m4_m4m4(mat, oimat, base->object->obmat);
+ invert_m4_m4(oimat, ob_active->obmat);
+ mul_m4_m4m4(mat, oimat, ob_iter->obmat);
/* Copy bones and posechannels from the object to the edit armature */
for (pchan = opose->chanbase.first; pchan; pchan = pchann) {
@@ -345,7 +348,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
}
/* Fix Constraints and Other Links to this Bone and Armature */
- joined_armature_fix_links(bmain, ob, base->object, pchan, curbone);
+ joined_armature_fix_links(bmain, ob_active, ob_iter, pchan, curbone);
/* Rename pchan */
BLI_strncpy(pchan->name, curbone->name, sizeof(pchan->name));
@@ -368,21 +371,21 @@ int join_armature_exec(bContext *C, wmOperator *op)
* so that we don't have to worry about ambiguities re which armature
* a bone came from!
*/
- if (base->object->adt) {
- if (ob->adt == NULL) {
+ if (ob_iter->adt) {
+ if (ob_active->adt == NULL) {
/* no animdata, so just use a copy of the whole thing */
- ob->adt = BKE_animdata_copy(bmain, base->object->adt, false);
+ ob_active->adt = BKE_animdata_copy(bmain, ob_iter->adt, 0);
}
else {
/* merge in data - we'll fix the drivers manually */
- BKE_animdata_merge_copy(bmain, &ob->id, &base->object->id, ADT_MERGECOPY_KEEP_DST, false);
+ BKE_animdata_merge_copy(bmain, &ob_active->id, &ob_iter->id, ADT_MERGECOPY_KEEP_DST, false);
}
}
if (curarm->adt) {
if (arm->adt == NULL) {
/* no animdata, so just use a copy of the whole thing */
- arm->adt = BKE_animdata_copy(bmain, curarm->adt, false);
+ arm->adt = BKE_animdata_copy(bmain, curarm->adt, 0);
}
else {
/* merge in data - we'll fix the drivers manually */
@@ -391,16 +394,17 @@ int join_armature_exec(bContext *C, wmOperator *op)
}
/* Free the old object data */
- ED_base_object_free_and_unlink(bmain, scene, base);
+ ED_object_base_free_and_unlink(bmain, scene, ob_iter);
}
}
CTX_DATA_END;
- DAG_relations_tag_update(bmain); /* because we removed object(s) */
+ DEG_relations_tag_update(bmain); /* because we removed object(s) */
ED_armature_from_edit(bmain, arm);
ED_armature_edit_free(arm);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
return OPERATOR_FINISHED;
@@ -547,8 +551,15 @@ static void separate_armature_bones(Main *bmain, Object *ob, short sel)
/* clear the pchan->parent var of any pchan that had this as its parent */
for (pchn = ob->pose->chanbase.first; pchn; pchn = pchn->next) {
- if (pchn->parent == pchan)
+ if (pchn->parent == pchan) {
pchn->parent = NULL;
+ }
+ if (pchn->bbone_next == pchan) {
+ pchn->bbone_next = NULL;
+ }
+ if (pchn->bbone_prev == pchan) {
+ pchn->bbone_prev = NULL;
+ }
}
/* free any of the extra-data this pchan might have */
@@ -571,79 +582,93 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- Object *oldob, *newob;
- Base *oldbase, *newbase;
-
- /* sanity checks */
- if (obedit == NULL)
- return OPERATOR_CANCELLED;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ bool ok = false;
/* set wait cursor in case this takes a while */
WM_cursor_wait(1);
- /* we are going to do this as follows (unlike every other instance of separate):
- * 1. exit editmode +posemode for active armature/base. Take note of what this is.
- * 2. duplicate base - BASACT is the new one now
- * 3. for each of the two armatures, enter editmode -> remove appropriate bones -> exit editmode + recalc
- * 4. fix constraint links
- * 5. make original armature active and enter editmode
- */
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &bases_len);
- /* 1) only edit-base selected */
- /* TODO: use context iterators for this? */
CTX_DATA_BEGIN(C, Base *, base, visible_bases)
{
- if (base->object == obedit) base->flag |= SELECT;
- else base->flag &= ~SELECT;
+ ED_object_base_select(base, BA_DESELECT);
}
CTX_DATA_END;
- /* 1) store starting settings and exit editmode */
- oldob = obedit;
- oldbase = BASACT;
- oldob->mode &= ~OB_MODE_POSE;
- //oldbase->flag &= ~OB_POSEMODE;
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ Object *obedit = base_iter->object;
- ED_armature_from_edit(bmain, obedit->data);
- ED_armature_edit_free(obedit->data);
+ Object *oldob, *newob;
+ Base *oldbase, *newbase;
- /* 2) duplicate base */
- newbase = ED_object_add_duplicate(bmain, scene, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
- DAG_relations_tag_update(bmain);
+ /* we are going to do this as follows (unlike every other instance of separate):
+ * 1. exit editmode +posemode for active armature/base. Take note of what this is.
+ * 2. duplicate base - BASACT is the new one now
+ * 3. for each of the two armatures, enter editmode -> remove appropriate bones -> exit editmode + recalc
+ * 4. fix constraint links
+ * 5. make original armature active and enter editmode
+ */
- newob = newbase->object;
- newbase->flag &= ~SELECT;
+ /* 1) only edit-base selected */
+ ED_object_base_select(base_iter, BA_SELECT);
+ /* 1) store starting settings and exit editmode */
+ oldob = obedit;
+ oldbase = base_iter;
+ oldob->mode &= ~OB_MODE_POSE;
+ //oldbase->flag &= ~OB_POSEMODE;
- /* 3) remove bones that shouldn't still be around on both armatures */
- separate_armature_bones(bmain, oldob, 1);
- separate_armature_bones(bmain, newob, 0);
+ ED_armature_from_edit(bmain, obedit->data);
+ ED_armature_edit_free(obedit->data);
+ /* 2) duplicate base */
- /* 4) fix links before depsgraph flushes */ // err... or after?
- separated_armature_fix_links(bmain, oldob, newob);
+ /* only duplicate linked armature */
+ newbase = ED_object_add_duplicate(bmain, scene, view_layer, oldbase, USER_DUP_ARM);
- DAG_id_tag_update(&oldob->id, OB_RECALC_DATA); /* this is the original one */
- DAG_id_tag_update(&newob->id, OB_RECALC_DATA); /* this is the separated one */
+ DEG_relations_tag_update(bmain);
+ newob = newbase->object;
+ newbase->flag &= ~BASE_SELECTED;
- /* 5) restore original conditions */
- obedit = oldob;
- ED_armature_to_edit(obedit->data);
+ /* 3) remove bones that shouldn't still be around on both armatures */
+ separate_armature_bones(bmain, oldob, 1);
+ separate_armature_bones(bmain, newob, 0);
- /* parents tips remain selected when connected children are removed. */
- ED_armature_edit_deselect_all(obedit);
- BKE_report(op->reports, RPT_INFO, "Separated bones");
+ /* 4) fix links before depsgraph flushes */ // err... or after?
+ separated_armature_fix_links(bmain, oldob, newob);
- /* note, notifier might evolve */
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
+ DEG_id_tag_update(&oldob->id, ID_RECALC_GEOMETRY); /* this is the original one */
+ DEG_id_tag_update(&newob->id, ID_RECALC_GEOMETRY); /* this is the separated one */
+
+
+ /* 5) restore original conditions */
+ obedit = oldob;
+
+ ED_armature_to_edit(obedit->data);
+
+ /* parents tips remain selected when connected children are removed. */
+ ED_armature_edit_deselect_all(obedit);
+
+ ok = true;
+
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
+ }
+ MEM_freeN(bases);
/* recalc/redraw + cleanup */
WM_cursor_wait(0);
+ if (ok) {
+ BKE_report(op->reports, RPT_INFO, "Separated bones");
+ }
+
return OPERATOR_FINISHED;
}
@@ -867,9 +892,8 @@ static void editbone_clear_parent(EditBone *ebone, int mode)
static int armature_parent_clear_exec(bContext *C, wmOperator *op)
{
- Object *ob = CTX_data_edit_object(C);
- bArmature *arm = (bArmature *)ob->data;
- int val = RNA_enum_get(op->ptr, "type");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ const int val = RNA_enum_get(op->ptr, "type");
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
{
@@ -877,10 +901,30 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- ED_armature_edit_sync_selection(arm->edbo);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *ob = objects[ob_index];
+ bArmature *arm = ob->data;
+ bool changed = false;
- /* note, notifier might evolve */
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
+ for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (EBONE_EDITABLE(ebone)) {
+ changed = true;
+ break;
+ }
+ }
+
+ if (!changed) {
+ continue;
+ }
+
+ ED_armature_edit_sync_selection(arm->edbo);
+
+ /* Note, notifier might evolve. */
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
+ }
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}