Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/armature/pose_transform.c
| Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
| /* ********************************************** */ | /* ********************************************** */ | ||||
| /* Pose Apply */ | /* Pose Apply */ | ||||
| /* helper for apply_armature_pose2bones - fixes parenting of objects | /* helper for apply_armature_pose2bones - fixes parenting of objects | ||||
| * that are bone-parented to armature */ | * that are bone-parented to armature */ | ||||
| static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Object *armob) | static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Object *armob) | ||||
| { | { | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | /* Depsgraph has been ensured to be evaluated at the beginning of the operator. | ||||
| * | |||||
| * Must not evaluate depsgraph here yet, since this will ruin object matrix which we want to | |||||
| * preserve after other changes has been done in the operator. | |||||
| * | |||||
| * TODO(sergey): This seems very similar to `ignore_parent_tx()`, which was now ensured to work | |||||
| * quite reliably. Can we de-duplicate the code? Or at least verify we don't need an extra logic | |||||
| * in this function. */ | |||||
| Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); | |||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Object workob, *ob; | Object workob, *ob; | ||||
| /* go through all objects in database */ | /* go through all objects in database */ | ||||
| for (ob = bmain->objects.first; ob; ob = ob->id.next) { | for (ob = bmain->objects.first; ob; ob = ob->id.next) { | ||||
| /* if parent is bone in this armature, apply corrections */ | /* if parent is bone in this armature, apply corrections */ | ||||
| if ((ob->parent == armob) && (ob->partype == PARBONE)) { | if ((ob->parent == armob) && (ob->partype == PARBONE)) { | ||||
| /* apply current transform from parent (not yet destroyed), | /* apply current transform from parent (not yet destroyed), | ||||
| ▲ Show 20 Lines • Show All 230 Lines • ▼ Show 20 Lines | for (Bone *child = bone->childbase.first; child; child = child->next) { | ||||
| applyarmature_process_selected_rec(arm, pose, pose_eval, child, selected, pstate); | applyarmature_process_selected_rec(arm, pose, pose_eval, child, selected, pstate); | ||||
| } | } | ||||
| } | } | ||||
| /* set the current pose as the restpose */ | /* set the current pose as the restpose */ | ||||
| static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) | static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| // must be active object, not edit-object | // must be active object, not edit-object | ||||
| Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); | Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); | ||||
| const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | ||||
| bArmature *arm = BKE_armature_from_object(ob); | bArmature *arm = BKE_armature_from_object(ob); | ||||
| bPose *pose; | bPose *pose; | ||||
| bPoseChannel *pchan; | bPoseChannel *pchan; | ||||
| ListBase selected_bones; | ListBase selected_bones; | ||||
| ▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | void POSE_OT_armature_apply(wmOperatorType *ot) | ||||
| ot->description = "Apply the current pose as the new rest pose"; | ot->description = "Apply the current pose as the new rest pose"; | ||||
| /* callbacks */ | /* callbacks */ | ||||
| ot->exec = apply_armature_pose2bones_exec; | ot->exec = apply_armature_pose2bones_exec; | ||||
| ot->poll = ED_operator_posemode; | ot->poll = ED_operator_posemode; | ||||
| ot->ui = apply_armature_pose2bones_ui; | ot->ui = apply_armature_pose2bones_ui; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| RNA_def_boolean(ot->srna, | RNA_def_boolean(ot->srna, | ||||
| "selected", | "selected", | ||||
| false, | false, | ||||
| "Selected Only", | "Selected Only", | ||||
| "Only apply the selected bones (with propagation to children)"); | "Only apply the selected bones (with propagation to children)"); | ||||
| } | } | ||||
| /* set the current pose as the restpose */ | /* set the current pose as the restpose */ | ||||
| static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) | static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | ||||
| FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) { | FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) { | ||||
| /* loop over all selected pchans | /* loop over all selected pchans | ||||
| * | * | ||||
| * TODO, loop over children before parents if multiple bones | * TODO, loop over children before parents if multiple bones | ||||
| * at once are to be predictable*/ | * at once are to be predictable*/ | ||||
| FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob, pchan) { | FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob, pchan) { | ||||
| const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); | ||||
| ▲ Show 20 Lines • Show All 573 Lines • ▼ Show 20 Lines | |||||
| /* --------------- */ | /* --------------- */ | ||||
| /* generic exec for clear-pose operators */ | /* generic exec for clear-pose operators */ | ||||
| static int pose_clear_transform_generic_exec(bContext *C, | static int pose_clear_transform_generic_exec(bContext *C, | ||||
| wmOperator *op, | wmOperator *op, | ||||
| void (*clear_func)(bPoseChannel *), | void (*clear_func)(bPoseChannel *), | ||||
| const char default_ksName[]) | const char default_ksName[]) | ||||
| { | { | ||||
| Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | |||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| bool changed_multi = false; | bool changed_multi = false; | ||||
| /* sanity checks */ | /* sanity checks */ | ||||
| if (ELEM(NULL, clear_func, default_ksName)) { | if (ELEM(NULL, clear_func, default_ksName)) { | ||||
| BKE_report(op->reports, | BKE_report(op->reports, | ||||
| RPT_ERROR, | RPT_ERROR, | ||||
| "Programming error: missing clear transform function or keying set name"); | "Programming error: missing clear transform function or keying set name"); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* only clear relevant transforms for selected bones */ | /* only clear relevant transforms for selected bones */ | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) { | FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) { | ||||
| Object *ob_eval = DEG_get_evaluated_object( | // XXX: UGLY HACK (for autokey + clear transforms) | ||||
| CTX_data_depsgraph(C), ob_iter); // XXX: UGLY HACK (for autokey + clear transforms) | Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter); | ||||
| ListBase dsources = {NULL, NULL}; | ListBase dsources = {NULL, NULL}; | ||||
| bool changed = false; | bool changed = false; | ||||
| FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) { | FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) { | ||||
| /* run provided clearing function */ | /* run provided clearing function */ | ||||
| clear_func(pchan); | clear_func(pchan); | ||||
| changed = true; | changed = true; | ||||
| ▲ Show 20 Lines • Show All 217 Lines • Show Last 20 Lines | |||||