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:
authorDalai Felinto <dfelinto@gmail.com>2018-10-05 18:56:27 +0300
committerDalai Felinto <dfelinto@gmail.com>2018-10-05 18:56:27 +0300
commit13dfb911497a7d22d3d5fc473c526c5330a835e1 (patch)
treee48e876f90d9bbd2f34b8147cc07db39267ef861 /source/blender/editors/armature/armature_edit.c
parentdef3b8c68c09ac8659e12c88230fc5eb18c9159d (diff)
Multi-Objects: ARMATURE_OT_calculate_roll
The patch itself was fine (save for sending notifiers for objects instead of ob). But I couldn't apply it, so I re-did from scratch. Based on D3394 by @codemanx
Diffstat (limited to 'source/blender/editors/armature/armature_edit.c')
-rw-r--r--source/blender/editors/armature/armature_edit.c239
1 files changed, 129 insertions, 110 deletions
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 1f3ec04d63e..6a479e947fe 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -295,153 +295,172 @@ static const EnumPropertyItem prop_calc_roll_types[] = {
static int armature_calc_roll_exec(bContext *C, wmOperator *op)
{
- Object *ob = CTX_data_edit_object(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob_active = CTX_data_edit_object(C);
+ int ret = OPERATOR_FINISHED;
+
eCalcRollTypes type = RNA_enum_get(op->ptr, "type");
const bool axis_only = RNA_boolean_get(op->ptr, "axis_only");
/* axis_flip when matching the active bone never makes sense */
bool axis_flip = ((type >= CALC_ROLL_ACTIVE) ? RNA_boolean_get(op->ptr, "axis_flip") :
(type >= CALC_ROLL_TAN_NEG_X) ? true : false);
- float imat[3][3];
-
- bArmature *arm = ob->data;
- EditBone *ebone;
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &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;
- if ((type >= CALC_ROLL_NEG_X) && (type <= CALC_ROLL_TAN_NEG_Z)) {
- type -= (CALC_ROLL_ACTIVE - CALC_ROLL_NEG_X);
- axis_flip = true;
- }
+ float imat[3][3];
+ EditBone *ebone;
- copy_m3_m4(imat, ob->obmat);
- invert_m3(imat);
+ if ((type >= CALC_ROLL_NEG_X) && (type <= CALC_ROLL_TAN_NEG_Z)) {
+ type -= (CALC_ROLL_ACTIVE - CALC_ROLL_NEG_X);
+ axis_flip = true;
+ }
- if (type == CALC_ROLL_CURSOR) { /* Cursor */
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
- float cursor_local[3];
- const View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d);
+ copy_m3_m4(imat, ob->obmat);
+ invert_m3(imat);
- invert_m4_m4(ob->imat, ob->obmat);
- copy_v3_v3(cursor_local, cursor->location);
- mul_m4_v3(ob->imat, cursor_local);
+ if (type == CALC_ROLL_CURSOR) { /* Cursor */
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
+ float cursor_local[3];
+ const View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d);
+ invert_m4_m4(ob->imat, ob->obmat);
+ copy_v3_v3(cursor_local, cursor->location);
+ mul_m4_v3(ob->imat, cursor_local);
- /* cursor */
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
- float cursor_rel[3];
- sub_v3_v3v3(cursor_rel, cursor_local, ebone->head);
- if (axis_flip) negate_v3(cursor_rel);
- if (normalize_v3(cursor_rel) != 0.0f) {
- ebone->roll = ED_armature_ebone_roll_to_vector(ebone, cursor_rel, axis_only);
+ /* cursor */
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
+ float cursor_rel[3];
+ sub_v3_v3v3(cursor_rel, cursor_local, ebone->head);
+ if (axis_flip) negate_v3(cursor_rel);
+ if (normalize_v3(cursor_rel) != 0.0f) {
+ ebone->roll = ED_armature_ebone_roll_to_vector(ebone, cursor_rel, axis_only);
+ changed = true;
+ }
}
}
}
- }
- else if (ELEM(type, CALC_ROLL_TAN_POS_X, CALC_ROLL_TAN_POS_Z)) {
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (ebone->parent) {
- bool is_edit = (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone));
- bool is_edit_parent = (EBONE_VISIBLE(arm, ebone->parent) && EBONE_EDITABLE(ebone->parent));
-
- if (is_edit || is_edit_parent) {
- EditBone *ebone_other = ebone->parent;
- float dir_a[3];
- float dir_b[3];
- float vec[3];
- bool is_vec_zero;
-
- sub_v3_v3v3(dir_a, ebone->tail, ebone->head);
- normalize_v3(dir_a);
-
- /* find the first bone in the chane with a different direction */
- do {
- sub_v3_v3v3(dir_b, ebone_other->head, ebone_other->tail);
- normalize_v3(dir_b);
-
- if (type == CALC_ROLL_TAN_POS_Z) {
- cross_v3_v3v3(vec, dir_a, dir_b);
- }
- else {
- add_v3_v3v3(vec, dir_a, dir_b);
- }
- } while ((is_vec_zero = (normalize_v3(vec) < 0.00001f)) &&
- (ebone_other = ebone_other->parent));
+ else if (ELEM(type, CALC_ROLL_TAN_POS_X, CALC_ROLL_TAN_POS_Z)) {
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (ebone->parent) {
+ bool is_edit = (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone));
+ bool is_edit_parent = (EBONE_VISIBLE(arm, ebone->parent) && EBONE_EDITABLE(ebone->parent));
+
+ if (is_edit || is_edit_parent) {
+ EditBone *ebone_other = ebone->parent;
+ float dir_a[3];
+ float dir_b[3];
+ float vec[3];
+ bool is_vec_zero;
+
+ sub_v3_v3v3(dir_a, ebone->tail, ebone->head);
+ normalize_v3(dir_a);
+
+ /* find the first bone in the chane with a different direction */
+ do {
+ sub_v3_v3v3(dir_b, ebone_other->head, ebone_other->tail);
+ normalize_v3(dir_b);
+
+ if (type == CALC_ROLL_TAN_POS_Z) {
+ cross_v3_v3v3(vec, dir_a, dir_b);
+ }
+ else {
+ add_v3_v3v3(vec, dir_a, dir_b);
+ }
+ } while ((is_vec_zero = (normalize_v3(vec) < 0.00001f)) &&
+ (ebone_other = ebone_other->parent));
- if (!is_vec_zero) {
- if (axis_flip) negate_v3(vec);
+ if (!is_vec_zero) {
+ if (axis_flip) negate_v3(vec);
- if (is_edit) {
- ebone->roll = ED_armature_ebone_roll_to_vector(ebone, vec, axis_only);
- }
+ if (is_edit) {
+ ebone->roll = ED_armature_ebone_roll_to_vector(ebone, vec, axis_only);
+ changed = true;
+ }
- /* parentless bones use cross product with child */
- if (is_edit_parent) {
- if (ebone->parent->parent == NULL) {
- ebone->parent->roll = ED_armature_ebone_roll_to_vector(ebone->parent, vec, axis_only);
+ /* parentless bones use cross product with child */
+ if (is_edit_parent) {
+ if (ebone->parent->parent == NULL) {
+ ebone->parent->roll = ED_armature_ebone_roll_to_vector(ebone->parent, vec, axis_only);
+ changed = true;
+ }
}
}
}
}
}
}
- }
- else {
- float vec[3] = {0.0f, 0.0f, 0.0f};
- if (type == CALC_ROLL_VIEW) { /* View */
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No region view3d available");
- return OPERATOR_CANCELLED;
- }
+ else {
+ float vec[3] = {0.0f, 0.0f, 0.0f};
+ if (type == CALC_ROLL_VIEW) { /* View */
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (rv3d == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No region view3d available");
+ ret = OPERATOR_CANCELLED;
+ goto cleanup;
+ }
- copy_v3_v3(vec, rv3d->viewinv[2]);
- mul_m3_v3(imat, vec);
- }
- else if (type == CALC_ROLL_ACTIVE) {
- float mat[3][3];
- ebone = (EditBone *)arm->act_edbone;
- if (ebone == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active bone set");
- return OPERATOR_CANCELLED;
+ copy_v3_v3(vec, rv3d->viewinv[2]);
+ mul_m3_v3(imat, vec);
}
+ else if (type == CALC_ROLL_ACTIVE) {
+ float mat[3][3];
+ bArmature *arm_active = ob_active->data;
+ ebone = (EditBone *)arm_active->act_edbone;
+ if (ebone == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active bone set");
+ ret = OPERATOR_CANCELLED;
+ goto cleanup;
+ }
- ED_armature_ebone_to_mat3(ebone, mat);
- copy_v3_v3(vec, mat[2]);
- }
- else { /* Axis */
- assert(type <= 5);
- if (type < 3) vec[type] = 1.0f;
- else vec[type - 2] = -1.0f;
- mul_m3_v3(imat, vec);
- normalize_v3(vec);
- }
+ ED_armature_ebone_to_mat3(ebone, mat);
+ copy_v3_v3(vec, mat[2]);
+ }
+ else { /* Axis */
+ assert(type <= 5);
+ if (type < 3) vec[type] = 1.0f;
+ else vec[type - 2] = -1.0f;
+ mul_m3_v3(imat, vec);
+ normalize_v3(vec);
+ }
- if (axis_flip) negate_v3(vec);
+ if (axis_flip) negate_v3(vec);
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
- /* roll func is a callback which assumes that all is well */
- ebone->roll = ED_armature_ebone_roll_to_vector(ebone, vec, axis_only);
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
+ /* roll func is a callback which assumes that all is well */
+ ebone->roll = ED_armature_ebone_roll_to_vector(ebone, vec, axis_only);
+ changed = true;
+ }
}
}
- }
- if (arm->flag & ARM_MIRROR_EDIT) {
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
- EditBone *ebone_mirr = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
- if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) {
- ebone->roll = -ebone_mirr->roll;
+ if (arm->flag & ARM_MIRROR_EDIT) {
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
+ EditBone *ebone_mirr = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
+ if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) {
+ ebone->roll = -ebone_mirr->roll;
+ }
}
}
}
- }
- /* note, notifier might evolve */
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
+ if (changed) {
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
+ }
+ }
- return OPERATOR_FINISHED;
+cleanup:
+ MEM_freeN(objects);
+ return ret;
}
void ARMATURE_OT_calculate_roll(wmOperatorType *ot)