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/pose_lib.c')
-rw-r--r--source/blender/editors/armature/pose_lib.c2881
1 files changed, 1470 insertions, 1411 deletions
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 41df3086fa8..443bcdde028 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -72,7 +72,9 @@
/* ******* XXX ********** */
-static void action_set_activemarker(void *UNUSED(a), void *UNUSED(b), void *UNUSED(c)) {}
+static void action_set_activemarker(void *UNUSED(a), void *UNUSED(b), void *UNUSED(c))
+{
+}
/* ************************************************************* */
/* == POSE-LIBRARY TOOL FOR BLENDER ==
@@ -93,84 +95,84 @@ static void action_set_activemarker(void *UNUSED(a), void *UNUSED(b), void *UNUS
*/
/* ************************************************************* */
-
/* gets the first available frame in poselib to store a pose on
* - frames start from 1, and a pose should occur on every frame... 0 is error!
*/
static int poselib_get_free_index(bAction *act)
{
- TimeMarker *marker;
- int low = 0, high = 0;
- bool changed = false;
-
- /* sanity checks */
- if (ELEM(NULL, act, act->markers.first)) return 1;
-
- /* As poses are not stored in chronological order, we must iterate over this list
- * a few times until we don't make any new discoveries (mostly about the lower bound).
- * Prevents problems with deleting then trying to add new poses [#27412]
- */
- do {
- changed = false;
-
- for (marker = act->markers.first; marker; marker = marker->next) {
- /* only increase low if value is 1 greater than low, to find "gaps" where
- * poses were removed from the poselib
- */
- if (marker->frame == (low + 1)) {
- low++;
- changed = true;
- }
-
- /* value replaces high if it is the highest value encountered yet */
- if (marker->frame > high) {
- high = marker->frame;
- changed = true;
- }
- }
- } while (changed != 0);
-
- /* - if low is not equal to high, then low+1 is a gap
- * - if low is equal to high, then high+1 is the next index (add at end)
- */
- if (low < high)
- return (low + 1);
- else
- return (high + 1);
+ TimeMarker *marker;
+ int low = 0, high = 0;
+ bool changed = false;
+
+ /* sanity checks */
+ if (ELEM(NULL, act, act->markers.first))
+ return 1;
+
+ /* As poses are not stored in chronological order, we must iterate over this list
+ * a few times until we don't make any new discoveries (mostly about the lower bound).
+ * Prevents problems with deleting then trying to add new poses [#27412]
+ */
+ do {
+ changed = false;
+
+ for (marker = act->markers.first; marker; marker = marker->next) {
+ /* only increase low if value is 1 greater than low, to find "gaps" where
+ * poses were removed from the poselib
+ */
+ if (marker->frame == (low + 1)) {
+ low++;
+ changed = true;
+ }
+
+ /* value replaces high if it is the highest value encountered yet */
+ if (marker->frame > high) {
+ high = marker->frame;
+ changed = true;
+ }
+ }
+ } while (changed != 0);
+
+ /* - if low is not equal to high, then low+1 is a gap
+ * - if low is equal to high, then high+1 is the next index (add at end)
+ */
+ if (low < high)
+ return (low + 1);
+ else
+ return (high + 1);
}
/* returns the active pose for a poselib */
static TimeMarker *poselib_get_active_pose(bAction *act)
{
- if ((act) && (act->active_marker))
- return BLI_findlink(&act->markers, act->active_marker - 1);
- else
- return NULL;
+ if ((act) && (act->active_marker))
+ return BLI_findlink(&act->markers, act->active_marker - 1);
+ else
+ return NULL;
}
/* Get object that Pose Lib should be found on */
/* XXX C can be zero */
static Object *get_poselib_object(bContext *C)
{
- ScrArea *sa;
+ ScrArea *sa;
- /* sanity check */
- if (C == NULL)
- return NULL;
+ /* sanity check */
+ if (C == NULL)
+ return NULL;
- sa = CTX_wm_area(C);
+ sa = CTX_wm_area(C);
- if (sa && (sa->spacetype == SPACE_PROPERTIES))
- return ED_object_context(C);
- else
- return BKE_object_pose_armature_get(CTX_data_active_object(C));
+ if (sa && (sa->spacetype == SPACE_PROPERTIES))
+ return ED_object_context(C);
+ else
+ return BKE_object_pose_armature_get(CTX_data_active_object(C));
}
/* Poll callback for operators that require existing PoseLib data (with poses) to work */
static bool has_poselib_pose_data_poll(bContext *C)
{
- Object *ob = get_poselib_object(C);
- return (ob && ob->poselib);
+ Object *ob = get_poselib_object(C);
+ return (ob && ob->poselib);
}
/* Poll callback for operators that require existing PoseLib data (with poses)
@@ -178,8 +180,8 @@ static bool has_poselib_pose_data_poll(bContext *C)
*/
static bool has_poselib_pose_data_for_editing_poll(bContext *C)
{
- Object *ob = get_poselib_object(C);
- return (ob && ob->poselib && !ID_IS_LINKED(ob->poselib));
+ Object *ob = get_poselib_object(C);
+ return (ob && ob->poselib && !ID_IS_LINKED(ob->poselib));
}
/* ----------------------------------- */
@@ -187,29 +189,29 @@ static bool has_poselib_pose_data_for_editing_poll(bContext *C)
/* Initialize a new poselib (whether it is needed or not) */
static bAction *poselib_init_new(Main *bmain, Object *ob)
{
- /* sanity checks - only for armatures */
- if (ELEM(NULL, ob, ob->pose))
- return NULL;
+ /* sanity checks - only for armatures */
+ if (ELEM(NULL, ob, ob->pose))
+ return NULL;
- /* init object's poselib action (unlink old one if there) */
- if (ob->poselib)
- id_us_min(&ob->poselib->id);
+ /* init object's poselib action (unlink old one if there) */
+ if (ob->poselib)
+ id_us_min(&ob->poselib->id);
- ob->poselib = BKE_action_add(bmain, "PoseLib");
- ob->poselib->idroot = ID_OB;
+ ob->poselib = BKE_action_add(bmain, "PoseLib");
+ ob->poselib->idroot = ID_OB;
- return ob->poselib;
+ return ob->poselib;
}
/* Initialize a new poselib (checks if that needs to happen) */
static bAction *poselib_validate(Main *bmain, Object *ob)
{
- if (ELEM(NULL, ob, ob->pose))
- return NULL;
- else if (ob->poselib == NULL)
- return poselib_init_new(bmain, ob);
- else
- return ob->poselib;
+ if (ELEM(NULL, ob, ob->pose))
+ return NULL;
+ else if (ob->poselib == NULL)
+ return poselib_init_new(bmain, ob);
+ else
+ return ob->poselib;
}
/* ************************************************************* */
@@ -217,70 +219,70 @@ static bAction *poselib_validate(Main *bmain, Object *ob)
static int poselib_new_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
- Object *ob = get_poselib_object(C);
+ Main *bmain = CTX_data_main(C);
+ Object *ob = get_poselib_object(C);
- /* sanity checks */
- if (ob == NULL)
- return OPERATOR_CANCELLED;
+ /* sanity checks */
+ if (ob == NULL)
+ return OPERATOR_CANCELLED;
- /* new method here deals with the rest... */
- poselib_init_new(bmain, ob);
+ /* new method here deals with the rest... */
+ poselib_init_new(bmain, ob);
- /* notifier here might evolve? */
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ /* notifier here might evolve? */
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void POSELIB_OT_new(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "New Pose Library";
- ot->idname = "POSELIB_OT_new";
- ot->description = "Add New Pose Library to active Object";
+ /* identifiers */
+ ot->name = "New Pose Library";
+ ot->idname = "POSELIB_OT_new";
+ ot->description = "Add New Pose Library to active Object";
- /* callbacks */
- ot->exec = poselib_new_exec;
- ot->poll = ED_operator_posemode;
+ /* callbacks */
+ ot->exec = poselib_new_exec;
+ ot->poll = ED_operator_posemode;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ------------------------------------------------ */
static int poselib_unlink_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob = get_poselib_object(C);
+ Object *ob = get_poselib_object(C);
- /* sanity checks */
- if (ELEM(NULL, ob, ob->poselib))
- return OPERATOR_CANCELLED;
+ /* sanity checks */
+ if (ELEM(NULL, ob, ob->poselib))
+ return OPERATOR_CANCELLED;
- /* there should be a poselib (we just checked above!), so just lower its user count and remove */
- id_us_min(&ob->poselib->id);
- ob->poselib = NULL;
+ /* there should be a poselib (we just checked above!), so just lower its user count and remove */
+ id_us_min(&ob->poselib->id);
+ ob->poselib = NULL;
- /* notifier here might evolve? */
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+ /* notifier here might evolve? */
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void POSELIB_OT_unlink(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Unlink Pose Library";
- ot->idname = "POSELIB_OT_unlink";
- ot->description = "Remove Pose Library from active Object";
+ /* identifiers */
+ ot->name = "Unlink Pose Library";
+ ot->idname = "POSELIB_OT_unlink";
+ ot->description = "Remove Pose Library from active Object";
- /* callbacks */
- ot->exec = poselib_unlink_exec;
- ot->poll = has_poselib_pose_data_poll;
+ /* callbacks */
+ ot->exec = poselib_unlink_exec;
+ ot->poll = has_poselib_pose_data_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************* */
@@ -291,81 +293,81 @@ void POSELIB_OT_unlink(wmOperatorType *ot)
*/
static int poselib_sanitize_exec(bContext *C, wmOperator *op)
{
- Object *ob = get_poselib_object(C);
- bAction *act = (ob) ? ob->poselib : NULL;
- DLRBT_Tree keys;
- ActKeyColumn *ak;
- TimeMarker *marker, *markern;
-
- /* validate action */
- if (act == NULL) {
- BKE_report(op->reports, RPT_WARNING, "No action to validate");
- return OPERATOR_CANCELLED;
- }
-
- /* determine which frames have keys */
- BLI_dlrbTree_init(&keys);
- action_to_keylist(NULL, act, &keys, 0);
-
- /* for each key, make sure there is a corresponding pose */
- for (ak = keys.first; ak; ak = ak->next) {
- /* check if any pose matches this */
- /* TODO: don't go looking through the list like this every time... */
- for (marker = act->markers.first; marker; marker = marker->next) {
- if (IS_EQ((double)marker->frame, (double)ak->cfra)) {
- marker->flag = -1;
- break;
- }
- }
-
- /* add new if none found */
- if (marker == NULL) {
- /* add pose to poselib */
- marker = MEM_callocN(sizeof(TimeMarker), "ActionMarker");
-
- BLI_snprintf(marker->name, sizeof(marker->name), "F%d Pose", (int)ak->cfra);
-
- marker->frame = (int)ak->cfra;
- marker->flag = -1;
-
- BLI_addtail(&act->markers, marker);
- }
- }
-
- /* remove all untagged poses (unused), and remove all tags */
- for (marker = act->markers.first; marker; marker = markern) {
- markern = marker->next;
-
- if (marker->flag != -1)
- BLI_freelinkN(&act->markers, marker);
- else
- marker->flag = 0;
- }
-
- /* free temp memory */
- BLI_dlrbTree_free(&keys);
-
- /* send notifiers for this - using keyframe editing notifiers, since action
- * may be being shown in anim editors as active action
- */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
+ Object *ob = get_poselib_object(C);
+ bAction *act = (ob) ? ob->poselib : NULL;
+ DLRBT_Tree keys;
+ ActKeyColumn *ak;
+ TimeMarker *marker, *markern;
+
+ /* validate action */
+ if (act == NULL) {
+ BKE_report(op->reports, RPT_WARNING, "No action to validate");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* determine which frames have keys */
+ BLI_dlrbTree_init(&keys);
+ action_to_keylist(NULL, act, &keys, 0);
+
+ /* for each key, make sure there is a corresponding pose */
+ for (ak = keys.first; ak; ak = ak->next) {
+ /* check if any pose matches this */
+ /* TODO: don't go looking through the list like this every time... */
+ for (marker = act->markers.first; marker; marker = marker->next) {
+ if (IS_EQ((double)marker->frame, (double)ak->cfra)) {
+ marker->flag = -1;
+ break;
+ }
+ }
+
+ /* add new if none found */
+ if (marker == NULL) {
+ /* add pose to poselib */
+ marker = MEM_callocN(sizeof(TimeMarker), "ActionMarker");
+
+ BLI_snprintf(marker->name, sizeof(marker->name), "F%d Pose", (int)ak->cfra);
+
+ marker->frame = (int)ak->cfra;
+ marker->flag = -1;
+
+ BLI_addtail(&act->markers, marker);
+ }
+ }
+
+ /* remove all untagged poses (unused), and remove all tags */
+ for (marker = act->markers.first; marker; marker = markern) {
+ markern = marker->next;
+
+ if (marker->flag != -1)
+ BLI_freelinkN(&act->markers, marker);
+ else
+ marker->flag = 0;
+ }
+
+ /* free temp memory */
+ BLI_dlrbTree_free(&keys);
+
+ /* send notifiers for this - using keyframe editing notifiers, since action
+ * may be being shown in anim editors as active action
+ */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
}
void POSELIB_OT_action_sanitize(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Sanitize Pose Library Action";
- ot->idname = "POSELIB_OT_action_sanitize";
- ot->description = "Make action suitable for use as a Pose Library";
+ /* identifiers */
+ ot->name = "Sanitize Pose Library Action";
+ ot->idname = "POSELIB_OT_action_sanitize";
+ ot->description = "Make action suitable for use as a Pose Library";
- /* callbacks */
- ot->exec = poselib_sanitize_exec;
- ot->poll = has_poselib_pose_data_for_editing_poll;
+ /* callbacks */
+ ot->exec = poselib_sanitize_exec;
+ ot->poll = has_poselib_pose_data_for_editing_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ------------------------------------------ */
@@ -373,615 +375,631 @@ void POSELIB_OT_action_sanitize(wmOperatorType *ot)
/* Poll callback for adding poses to a PoseLib */
static bool poselib_add_poll(bContext *C)
{
- /* There are 2 cases we need to be careful with:
- * 1) When this operator is invoked from a hotkey, there may be no PoseLib yet
- * 2) If a PoseLib already exists, we can't edit the action if it is a lib-linked
- * actions, as data will be lost when saving the file
- */
- if (ED_operator_posemode(C)) {
- Object *ob = get_poselib_object(C);
- if (ob) {
- if ((ob->poselib == NULL) || !ID_IS_LINKED(ob->poselib)) {
- return true;
- }
- }
- }
- return false;
+ /* There are 2 cases we need to be careful with:
+ * 1) When this operator is invoked from a hotkey, there may be no PoseLib yet
+ * 2) If a PoseLib already exists, we can't edit the action if it is a lib-linked
+ * actions, as data will be lost when saving the file
+ */
+ if (ED_operator_posemode(C)) {
+ Object *ob = get_poselib_object(C);
+ if (ob) {
+ if ((ob->poselib == NULL) || !ID_IS_LINKED(ob->poselib)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
static void poselib_add_menu_invoke__replacemenu(bContext *C, uiLayout *layout, void *UNUSED(arg))
{
- Object *ob = get_poselib_object(C);
- bAction *act = ob->poselib; /* never NULL */
- TimeMarker *marker;
-
- wmOperatorType *ot = WM_operatortype_find("POSELIB_OT_pose_add", 1);
-
- BLI_assert(ot != NULL);
-
- /* set the operator execution context correctly */
- uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
-
- /* add each marker to this menu */
- for (marker = act->markers.first; marker; marker = marker->next) {
- PointerRNA props_ptr;
- uiItemFullO_ptr(
- layout, ot,
- marker->name, ICON_ARMATURE_DATA, NULL,
- WM_OP_EXEC_DEFAULT, 0, &props_ptr);
- RNA_int_set(&props_ptr, "frame", marker->frame);
- RNA_string_set(&props_ptr, "name", marker->name);
- }
-}
-
-static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
-{
- Scene *scene = CTX_data_scene(C);
- Object *ob = get_poselib_object(C);
- bPose *pose = (ob) ? ob->pose : NULL;
- uiPopupMenu *pup;
- uiLayout *layout;
-
- /* sanity check */
- if (ELEM(NULL, ob, pose))
- return OPERATOR_CANCELLED;
-
- /* start building */
- pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
+ Object *ob = get_poselib_object(C);
+ bAction *act = ob->poselib; /* never NULL */
+ TimeMarker *marker;
- /* add new (adds to the first unoccupied frame) */
- uiItemIntO(layout, IFACE_("Add New"), ICON_NONE, "POSELIB_OT_pose_add", "frame", poselib_get_free_index(ob->poselib));
+ wmOperatorType *ot = WM_operatortype_find("POSELIB_OT_pose_add", 1);
- /* check if we have any choices to add a new pose in any other way */
- if ((ob->poselib) && (ob->poselib->markers.first)) {
- /* add new (on current frame) */
- uiItemIntO(layout, IFACE_("Add New (Current Frame)"), ICON_NONE, "POSELIB_OT_pose_add", "frame", CFRA);
+ BLI_assert(ot != NULL);
- /* replace existing - submenu */
- uiItemMenuF(layout, IFACE_("Replace Existing..."), 0, poselib_add_menu_invoke__replacemenu, NULL);
- }
+ /* set the operator execution context correctly */
+ uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
- UI_popup_menu_end(C, pup);
-
- /* this operator is only for a menu, not used further */
- return OPERATOR_INTERFACE;
+ /* add each marker to this menu */
+ for (marker = act->markers.first; marker; marker = marker->next) {
+ PointerRNA props_ptr;
+ uiItemFullO_ptr(
+ layout, ot, marker->name, ICON_ARMATURE_DATA, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr);
+ RNA_int_set(&props_ptr, "frame", marker->frame);
+ RNA_string_set(&props_ptr, "name", marker->name);
+ }
}
+static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = get_poselib_object(C);
+ bPose *pose = (ob) ? ob->pose : NULL;
+ uiPopupMenu *pup;
+ uiLayout *layout;
+
+ /* sanity check */
+ if (ELEM(NULL, ob, pose))
+ return OPERATOR_CANCELLED;
+
+ /* start building */
+ pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
+
+ /* add new (adds to the first unoccupied frame) */
+ uiItemIntO(layout,
+ IFACE_("Add New"),
+ ICON_NONE,
+ "POSELIB_OT_pose_add",
+ "frame",
+ poselib_get_free_index(ob->poselib));
+
+ /* check if we have any choices to add a new pose in any other way */
+ if ((ob->poselib) && (ob->poselib->markers.first)) {
+ /* add new (on current frame) */
+ uiItemIntO(layout,
+ IFACE_("Add New (Current Frame)"),
+ ICON_NONE,
+ "POSELIB_OT_pose_add",
+ "frame",
+ CFRA);
+
+ /* replace existing - submenu */
+ uiItemMenuF(
+ layout, IFACE_("Replace Existing..."), 0, poselib_add_menu_invoke__replacemenu, NULL);
+ }
+
+ UI_popup_menu_end(C, pup);
+
+ /* this operator is only for a menu, not used further */
+ return OPERATOR_INTERFACE;
+}
static int poselib_add_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Object *ob = get_poselib_object(C);
- bAction *act = poselib_validate(bmain, ob);
- bPose *pose = (ob) ? ob->pose : NULL;
- TimeMarker *marker;
- KeyingSet *ks;
- int frame = RNA_int_get(op->ptr, "frame");
- char name[64];
-
- /* sanity check (invoke should have checked this anyway) */
- if (ELEM(NULL, ob, pose))
- return OPERATOR_CANCELLED;
-
- /* get name to give to pose */
- RNA_string_get(op->ptr, "name", name);
-
- /* add pose to poselib - replaces any existing pose there
- * - for the 'replace' option, this should end up finding the appropriate marker,
- * so no new one will be added
- */
- for (marker = act->markers.first; marker; marker = marker->next) {
- if (marker->frame == frame) {
- BLI_strncpy(marker->name, name, sizeof(marker->name));
- break;
- }
- }
- if (marker == NULL) {
- marker = MEM_callocN(sizeof(TimeMarker), "ActionMarker");
-
- BLI_strncpy(marker->name, name, sizeof(marker->name));
- marker->frame = frame;
-
- BLI_addtail(&act->markers, marker);
- }
-
- /* validate name */
- BLI_uniquename(&act->markers, marker, DATA_("Pose"), '.', offsetof(TimeMarker, name), sizeof(marker->name));
-
- /* use Keying Set to determine what to store for the pose */
-
- /* this includes custom props :)*/
- ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_WHOLE_CHARACTER_SELECTED_ID);
-
- ANIM_apply_keyingset(C, NULL, act, ks, MODIFYKEY_MODE_INSERT, (float)frame);
-
- /* store new 'active' pose number */
- act->active_marker = BLI_listbase_count(&act->markers);
- DEG_id_tag_update(&act->id, ID_RECALC_COPY_ON_WRITE);
-
- /* done */
- return OPERATOR_FINISHED;
+ Main *bmain = CTX_data_main(C);
+ Object *ob = get_poselib_object(C);
+ bAction *act = poselib_validate(bmain, ob);
+ bPose *pose = (ob) ? ob->pose : NULL;
+ TimeMarker *marker;
+ KeyingSet *ks;
+ int frame = RNA_int_get(op->ptr, "frame");
+ char name[64];
+
+ /* sanity check (invoke should have checked this anyway) */
+ if (ELEM(NULL, ob, pose))
+ return OPERATOR_CANCELLED;
+
+ /* get name to give to pose */
+ RNA_string_get(op->ptr, "name", name);
+
+ /* add pose to poselib - replaces any existing pose there
+ * - for the 'replace' option, this should end up finding the appropriate marker,
+ * so no new one will be added
+ */
+ for (marker = act->markers.first; marker; marker = marker->next) {
+ if (marker->frame == frame) {
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+ break;
+ }
+ }
+ if (marker == NULL) {
+ marker = MEM_callocN(sizeof(TimeMarker), "ActionMarker");
+
+ BLI_strncpy(marker->name, name, sizeof(marker->name));
+ marker->frame = frame;
+
+ BLI_addtail(&act->markers, marker);
+ }
+
+ /* validate name */
+ BLI_uniquename(
+ &act->markers, marker, DATA_("Pose"), '.', offsetof(TimeMarker, name), sizeof(marker->name));
+
+ /* use Keying Set to determine what to store for the pose */
+
+ /* this includes custom props :)*/
+ ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_WHOLE_CHARACTER_SELECTED_ID);
+
+ ANIM_apply_keyingset(C, NULL, act, ks, MODIFYKEY_MODE_INSERT, (float)frame);
+
+ /* store new 'active' pose number */
+ act->active_marker = BLI_listbase_count(&act->markers);
+ DEG_id_tag_update(&act->id, ID_RECALC_COPY_ON_WRITE);
+
+ /* done */
+ return OPERATOR_FINISHED;
}
void POSELIB_OT_pose_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "PoseLib Add Pose";
- ot->idname = "POSELIB_OT_pose_add";
- ot->description = "Add the current Pose to the active Pose Library";
-
- /* api callbacks */
- ot->invoke = poselib_add_menu_invoke;
- ot->exec = poselib_add_exec;
- ot->poll = poselib_add_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_int(ot->srna, "frame", 1, 0, INT_MAX, "Frame", "Frame to store pose on", 0, INT_MAX);
- RNA_def_string(ot->srna, "name", "Pose", 64, "Pose Name", "Name of newly added Pose");
+ /* identifiers */
+ ot->name = "PoseLib Add Pose";
+ ot->idname = "POSELIB_OT_pose_add";
+ ot->description = "Add the current Pose to the active Pose Library";
+
+ /* api callbacks */
+ ot->invoke = poselib_add_menu_invoke;
+ ot->exec = poselib_add_exec;
+ ot->poll = poselib_add_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_int(ot->srna, "frame", 1, 0, INT_MAX, "Frame", "Frame to store pose on", 0, INT_MAX);
+ RNA_def_string(ot->srna, "name", "Pose", 64, "Pose Name", "Name of newly added Pose");
}
/* ----- */
/* can be called with C == NULL */
-static const EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+static const EnumPropertyItem *poselib_stored_pose_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
{
- Object *ob = get_poselib_object(C);
- bAction *act = (ob) ? ob->poselib : NULL;
- TimeMarker *marker;
- EnumPropertyItem *item = NULL, item_tmp = {0};
- int totitem = 0;
- int i = 0;
-
- if (C == NULL) {
- return DummyRNA_NULL_items;
- }
-
- /* check that the action exists */
- if (act) {
- /* add each marker to the list */
- for (marker = act->markers.first, i = 0; marker; marker = marker->next, i++) {
- item_tmp.identifier = item_tmp.name = marker->name;
- item_tmp.icon = ICON_ARMATURE_DATA;
- item_tmp.value = i;
- RNA_enum_item_add(&item, &totitem, &item_tmp);
- }
- }
-
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
-
- return item;
+ Object *ob = get_poselib_object(C);
+ bAction *act = (ob) ? ob->poselib : NULL;
+ TimeMarker *marker;
+ EnumPropertyItem *item = NULL, item_tmp = {0};
+ int totitem = 0;
+ int i = 0;
+
+ if (C == NULL) {
+ return DummyRNA_NULL_items;
+ }
+
+ /* check that the action exists */
+ if (act) {
+ /* add each marker to the list */
+ for (marker = act->markers.first, i = 0; marker; marker = marker->next, i++) {
+ item_tmp.identifier = item_tmp.name = marker->name;
+ item_tmp.icon = ICON_ARMATURE_DATA;
+ item_tmp.value = i;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+ }
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
}
static int poselib_remove_exec(bContext *C, wmOperator *op)
{
- Object *ob = get_poselib_object(C);
- bAction *act = (ob) ? ob->poselib : NULL;
- TimeMarker *marker;
- int marker_index;
- FCurve *fcu;
- PropertyRNA *prop;
-
- /* check if valid poselib */
- if (act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
- return OPERATOR_CANCELLED;
- }
-
- prop = RNA_struct_find_property(op->ptr, "pose");
- if (RNA_property_is_set(op->ptr, prop)) {
- marker_index = RNA_property_enum_get(op->ptr, prop);
- }
- else {
- marker_index = act->active_marker - 1;
- }
-
- /* get index (and pointer) of pose to remove */
- marker = BLI_findlink(&act->markers, marker_index);
- if (marker == NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index);
- return OPERATOR_CANCELLED;
- }
-
- /* remove relevant keyframes */
- for (fcu = act->curves.first; fcu; fcu = fcu->next) {
- BezTriple *bezt;
- unsigned int i;
-
- if (fcu->bezt) {
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- /* check if remove */
- if (IS_EQF(bezt->vec[1][0], (float)marker->frame)) {
- delete_fcurve_key(fcu, i, 1);
- break;
- }
- }
- }
- }
-
- /* remove poselib from list */
- BLI_freelinkN(&act->markers, marker);
-
- /* fix active pose number */
- act->active_marker = 0;
-
- /* send notifiers for this - using keyframe editing notifiers, since action
- * may be being shown in anim editors as active action
- */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- DEG_id_tag_update(&act->id, ID_RECALC_COPY_ON_WRITE);
-
- /* done */
- return OPERATOR_FINISHED;
+ Object *ob = get_poselib_object(C);
+ bAction *act = (ob) ? ob->poselib : NULL;
+ TimeMarker *marker;
+ int marker_index;
+ FCurve *fcu;
+ PropertyRNA *prop;
+
+ /* check if valid poselib */
+ if (act == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
+ return OPERATOR_CANCELLED;
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "pose");
+ if (RNA_property_is_set(op->ptr, prop)) {
+ marker_index = RNA_property_enum_get(op->ptr, prop);
+ }
+ else {
+ marker_index = act->active_marker - 1;
+ }
+
+ /* get index (and pointer) of pose to remove */
+ marker = BLI_findlink(&act->markers, marker_index);
+ if (marker == NULL) {
+ BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index);
+ return OPERATOR_CANCELLED;
+ }
+
+ /* remove relevant keyframes */
+ for (fcu = act->curves.first; fcu; fcu = fcu->next) {
+ BezTriple *bezt;
+ unsigned int i;
+
+ if (fcu->bezt) {
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ /* check if remove */
+ if (IS_EQF(bezt->vec[1][0], (float)marker->frame)) {
+ delete_fcurve_key(fcu, i, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ /* remove poselib from list */
+ BLI_freelinkN(&act->markers, marker);
+
+ /* fix active pose number */
+ act->active_marker = 0;
+
+ /* send notifiers for this - using keyframe editing notifiers, since action
+ * may be being shown in anim editors as active action
+ */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ DEG_id_tag_update(&act->id, ID_RECALC_COPY_ON_WRITE);
+
+ /* done */
+ return OPERATOR_FINISHED;
}
void POSELIB_OT_pose_remove(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "PoseLib Remove Pose";
- ot->idname = "POSELIB_OT_pose_remove";
- ot->description = "Remove nth pose from the active Pose Library";
-
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = poselib_remove_exec;
- ot->poll = has_poselib_pose_data_for_editing_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to remove");
- RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
- RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
- ot->prop = prop;
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "PoseLib Remove Pose";
+ ot->idname = "POSELIB_OT_pose_remove";
+ ot->description = "Remove nth pose from the active Pose Library";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = poselib_remove_exec;
+ ot->poll = has_poselib_pose_data_for_editing_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to remove");
+ RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
}
static int poselib_rename_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- Object *ob = get_poselib_object(C);
- bAction *act = (ob) ? ob->poselib : NULL;
- TimeMarker *marker;
-
- /* check if valid poselib */
- if (act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
- return OPERATOR_CANCELLED;
- }
-
- /* get index (and pointer) of pose to remove */
- marker = BLI_findlink(&act->markers, act->active_marker - 1);
- if (marker == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
- return OPERATOR_CANCELLED;
- }
- else {
- /* use the existing name of the marker as the name, and use the active marker as the one to rename */
- RNA_enum_set(op->ptr, "pose", act->active_marker - 1);
- RNA_string_set(op->ptr, "name", marker->name);
- }
-
- /* part to sync with other similar operators... */
- return WM_operator_props_popup_confirm(C, op, event);
+ Object *ob = get_poselib_object(C);
+ bAction *act = (ob) ? ob->poselib : NULL;
+ TimeMarker *marker;
+
+ /* check if valid poselib */
+ if (act == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* get index (and pointer) of pose to remove */
+ marker = BLI_findlink(&act->markers, act->active_marker - 1);
+ if (marker == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* use the existing name of the marker as the name, and use the active marker as the one to rename */
+ RNA_enum_set(op->ptr, "pose", act->active_marker - 1);
+ RNA_string_set(op->ptr, "name", marker->name);
+ }
+
+ /* part to sync with other similar operators... */
+ return WM_operator_props_popup_confirm(C, op, event);
}
static int poselib_rename_exec(bContext *C, wmOperator *op)
{
- Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
- bAction *act = (ob) ? ob->poselib : NULL;
- TimeMarker *marker;
- char newname[64];
-
- /* check if valid poselib */
- if (act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
- return OPERATOR_CANCELLED;
- }
-
- /* get index (and pointer) of pose to remove */
- marker = BLI_findlink(&act->markers, RNA_enum_get(op->ptr, "pose"));
- if (marker == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
- return OPERATOR_CANCELLED;
- }
-
- /* get new name */
- RNA_string_get(op->ptr, "name", newname);
-
- /* copy name and validate it */
- BLI_strncpy(marker->name, newname, sizeof(marker->name));
- BLI_uniquename(&act->markers, marker, DATA_("Pose"), '.', offsetof(TimeMarker, name), sizeof(marker->name));
-
- /* send notifiers for this - using keyframe editing notifiers, since action
- * may be being shown in anim editors as active action
- */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
- /* done */
- return OPERATOR_FINISHED;
+ Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+ bAction *act = (ob) ? ob->poselib : NULL;
+ TimeMarker *marker;
+ char newname[64];
+
+ /* check if valid poselib */
+ if (act == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* get index (and pointer) of pose to remove */
+ marker = BLI_findlink(&act->markers, RNA_enum_get(op->ptr, "pose"));
+ if (marker == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* get new name */
+ RNA_string_get(op->ptr, "name", newname);
+
+ /* copy name and validate it */
+ BLI_strncpy(marker->name, newname, sizeof(marker->name));
+ BLI_uniquename(
+ &act->markers, marker, DATA_("Pose"), '.', offsetof(TimeMarker, name), sizeof(marker->name));
+
+ /* send notifiers for this - using keyframe editing notifiers, since action
+ * may be being shown in anim editors as active action
+ */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
}
void POSELIB_OT_pose_rename(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "PoseLib Rename Pose";
- ot->idname = "POSELIB_OT_pose_rename";
- ot->description = "Rename specified pose from the active Pose Library";
-
- /* api callbacks */
- ot->invoke = poselib_rename_invoke;
- ot->exec = poselib_rename_exec;
- ot->poll = has_poselib_pose_data_for_editing_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- /* NOTE: name not pose is the operator's "main" property,
- * so that it will get activated in the popup for easy renaming */
- ot->prop = RNA_def_string(ot->srna, "name", "RenamedPose", 64, "New Pose Name", "New name for pose");
- prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to rename");
- RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
- RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "PoseLib Rename Pose";
+ ot->idname = "POSELIB_OT_pose_rename";
+ ot->description = "Rename specified pose from the active Pose Library";
+
+ /* api callbacks */
+ ot->invoke = poselib_rename_invoke;
+ ot->exec = poselib_rename_exec;
+ ot->poll = has_poselib_pose_data_for_editing_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ /* NOTE: name not pose is the operator's "main" property,
+ * so that it will get activated in the popup for easy renaming */
+ ot->prop = RNA_def_string(
+ ot->srna, "name", "RenamedPose", 64, "New Pose Name", "New name for pose");
+ prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to rename");
+ RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
}
static int poselib_move_exec(bContext *C, wmOperator *op)
{
- Object *ob = get_poselib_object(C);
- bAction *act = (ob) ? ob->poselib : NULL;
- TimeMarker *marker;
- int marker_index;
- int dir;
- PropertyRNA *prop;
-
- /* check if valid poselib */
- if (act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
- return OPERATOR_CANCELLED;
- }
-
- prop = RNA_struct_find_property(op->ptr, "pose");
- if (RNA_property_is_set(op->ptr, prop)) {
- marker_index = RNA_property_enum_get(op->ptr, prop);
- }
- else {
- marker_index = act->active_marker - 1;
- }
-
- /* get index (and pointer) of pose to remove */
- marker = BLI_findlink(&act->markers, marker_index);
- if (marker == NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index);
- return OPERATOR_CANCELLED;
- }
-
- dir = RNA_enum_get(op->ptr, "direction");
-
- /* move pose */
- if (BLI_listbase_link_move(&act->markers, marker, dir)) {
- act->active_marker = marker_index + dir + 1;
-
- /* send notifiers for this - using keyframe editing notifiers, since action
- * may be being shown in anim editors as active action
- */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- }
- else {
- return OPERATOR_CANCELLED;
- }
-
- /* done */
- return OPERATOR_FINISHED;
+ Object *ob = get_poselib_object(C);
+ bAction *act = (ob) ? ob->poselib : NULL;
+ TimeMarker *marker;
+ int marker_index;
+ int dir;
+ PropertyRNA *prop;
+
+ /* check if valid poselib */
+ if (act == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
+ return OPERATOR_CANCELLED;
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "pose");
+ if (RNA_property_is_set(op->ptr, prop)) {
+ marker_index = RNA_property_enum_get(op->ptr, prop);
+ }
+ else {
+ marker_index = act->active_marker - 1;
+ }
+
+ /* get index (and pointer) of pose to remove */
+ marker = BLI_findlink(&act->markers, marker_index);
+ if (marker == NULL) {
+ BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index);
+ return OPERATOR_CANCELLED;
+ }
+
+ dir = RNA_enum_get(op->ptr, "direction");
+
+ /* move pose */
+ if (BLI_listbase_link_move(&act->markers, marker, dir)) {
+ act->active_marker = marker_index + dir + 1;
+
+ /* send notifiers for this - using keyframe editing notifiers, since action
+ * may be being shown in anim editors as active action
+ */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* done */
+ return OPERATOR_FINISHED;
}
void POSELIB_OT_pose_move(wmOperatorType *ot)
{
- PropertyRNA *prop;
- static const EnumPropertyItem pose_lib_pose_move[] = {
- {-1, "UP", 0, "Up", ""},
- {1, "DOWN", 0, "Down", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
- /* identifiers */
- ot->name = "PoseLib Move Pose";
- ot->idname = "POSELIB_OT_pose_move";
- ot->description = "Move the pose up or down in the active Pose Library";
-
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = poselib_move_exec;
- ot->poll = has_poselib_pose_data_for_editing_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to move");
- RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
- RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
- ot->prop = prop;
-
- RNA_def_enum(ot->srna, "direction", pose_lib_pose_move, 0, "Direction",
- "Direction to move the chosen pose towards");
+ PropertyRNA *prop;
+ static const EnumPropertyItem pose_lib_pose_move[] = {
+ {-1, "UP", 0, "Up", ""},
+ {1, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "PoseLib Move Pose";
+ ot->idname = "POSELIB_OT_pose_move";
+ ot->description = "Move the pose up or down in the active Pose Library";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = poselib_move_exec;
+ ot->poll = has_poselib_pose_data_for_editing_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_enum(ot->srna, "pose", DummyRNA_NULL_items, 0, "Pose", "The pose to move");
+ RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
+
+ RNA_def_enum(ot->srna,
+ "direction",
+ pose_lib_pose_move,
+ 0,
+ "Direction",
+ "Direction to move the chosen pose towards");
}
-
-
/* ************************************************************* */
/* Pose-Lib Browsing/Previewing Operator */
/* Simple struct for storing settings/data for use during PoseLib preview */
typedef struct tPoseLib_PreviewData {
- /** tPoseLib_Backup structs for restoring poses. */
- ListBase backups;
- /** LinkData structs storing list of poses which match the current search-string. */
- ListBase searchp;
-
- /** active scene. */
- Scene *scene;
- /** active area. */
- ScrArea *sa;
-
- /** RNA-Pointer to Object 'ob' .*/
- PointerRNA rna_ptr;
- /** object to work on. */
- Object *ob;
- /** object's armature data. */
- bArmature *arm;
- /** object's pose. */
- bPose *pose;
- /** poselib to use. */
- bAction *act;
- /** 'active' pose. */
- TimeMarker *marker;
-
- /** total number of elements to work on. */
- int totcount;
-
- /** state of main loop. */
- short state;
- /** redraw/update settings during main loop. */
- short redraw;
- /** flags for various settings. */
- short flag;
-
- /** position of cursor in searchstr (cursor occurs before the item at the nominated index) */
- short search_cursor;
- /** (Part of) Name to search for to filter poses that get shown. */
- char searchstr[64];
- /** Previously set searchstr (from last loop run),
- * so that we can detected when to rebuild searchp. */
- char searchold[64];
-
- /** Info-text to print in header. */
- char headerstr[UI_MAX_DRAW_STR];
+ /** tPoseLib_Backup structs for restoring poses. */
+ ListBase backups;
+ /** LinkData structs storing list of poses which match the current search-string. */
+ ListBase searchp;
+
+ /** active scene. */
+ Scene *scene;
+ /** active area. */
+ ScrArea *sa;
+
+ /** RNA-Pointer to Object 'ob' .*/
+ PointerRNA rna_ptr;
+ /** object to work on. */
+ Object *ob;
+ /** object's armature data. */
+ bArmature *arm;
+ /** object's pose. */
+ bPose *pose;
+ /** poselib to use. */
+ bAction *act;
+ /** 'active' pose. */
+ TimeMarker *marker;
+
+ /** total number of elements to work on. */
+ int totcount;
+
+ /** state of main loop. */
+ short state;
+ /** redraw/update settings during main loop. */
+ short redraw;
+ /** flags for various settings. */
+ short flag;
+
+ /** position of cursor in searchstr (cursor occurs before the item at the nominated index) */
+ short search_cursor;
+ /** (Part of) Name to search for to filter poses that get shown. */
+ char searchstr[64];
+ /** Previously set searchstr (from last loop run),
+ * so that we can detected when to rebuild searchp. */
+ char searchold[64];
+
+ /** Info-text to print in header. */
+ char headerstr[UI_MAX_DRAW_STR];
} tPoseLib_PreviewData;
/* defines for tPoseLib_PreviewData->state values */
enum {
- PL_PREVIEW_ERROR = -1,
- PL_PREVIEW_RUNNING,
- PL_PREVIEW_CONFIRM,
- PL_PREVIEW_CANCEL,
- PL_PREVIEW_RUNONCE,
+ PL_PREVIEW_ERROR = -1,
+ PL_PREVIEW_RUNNING,
+ PL_PREVIEW_CONFIRM,
+ PL_PREVIEW_CANCEL,
+ PL_PREVIEW_RUNONCE,
};
/* defines for tPoseLib_PreviewData->redraw values */
enum {
- PL_PREVIEW_NOREDRAW = 0,
- PL_PREVIEW_REDRAWALL,
- PL_PREVIEW_REDRAWHEADER,
+ PL_PREVIEW_NOREDRAW = 0,
+ PL_PREVIEW_REDRAWALL,
+ PL_PREVIEW_REDRAWHEADER,
};
/* defines for tPoseLib_PreviewData->flag values */
enum {
- PL_PREVIEW_FIRSTTIME = (1 << 0),
- PL_PREVIEW_SHOWORIGINAL = (1 << 1),
- PL_PREVIEW_ANY_BONE_SELECTED = (1 << 2),
+ PL_PREVIEW_FIRSTTIME = (1 << 0),
+ PL_PREVIEW_SHOWORIGINAL = (1 << 1),
+ PL_PREVIEW_ANY_BONE_SELECTED = (1 << 2),
};
/* ---------------------------- */
/* simple struct for storing backup info */
typedef struct tPoseLib_Backup {
- struct tPoseLib_Backup *next, *prev;
+ struct tPoseLib_Backup *next, *prev;
- bPoseChannel *pchan; /* pose channel backups are for */
+ bPoseChannel *pchan; /* pose channel backups are for */
- bPoseChannel olddata; /* copy of pose channel's old data (at start) */
- IDProperty *oldprops; /* copy (needs freeing) of pose channel's properties (at start) */
+ bPoseChannel olddata; /* copy of pose channel's old data (at start) */
+ IDProperty *oldprops; /* copy (needs freeing) of pose channel's properties (at start) */
} tPoseLib_Backup;
/* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */
static void poselib_backup_posecopy(tPoseLib_PreviewData *pld)
{
- bActionGroup *agrp;
- bPoseChannel *pchan;
- bool selected = false;
-
- /* determine whether any bone is selected. */
- LISTBASE_FOREACH (bPoseChannel *, bchan, &pld->pose->chanbase) {
- selected = bchan->bone != NULL && bchan->bone->flag & BONE_SELECTED;
- if (selected) {
- pld->flag |= PL_PREVIEW_ANY_BONE_SELECTED;
- break;
- }
- }
- if (!selected) {
- pld->flag &= ~PL_PREVIEW_ANY_BONE_SELECTED;
- }
-
- /* for each posechannel that has an actionchannel in */
- for (agrp = pld->act->groups.first; agrp; agrp = agrp->next) {
- /* try to find posechannel */
- pchan = BKE_pose_channel_find_name(pld->pose, agrp->name);
-
- /* backup data if available */
- if (pchan) {
- tPoseLib_Backup *plb;
-
- /* store backup */
- plb = MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup");
-
- plb->pchan = pchan;
- memcpy(&plb->olddata, plb->pchan, sizeof(bPoseChannel));
-
- if (pchan->prop)
- plb->oldprops = IDP_CopyProperty(pchan->prop);
-
- BLI_addtail(&pld->backups, plb);
-
- /* mark as being affected */
- pld->totcount++;
- }
- }
+ bActionGroup *agrp;
+ bPoseChannel *pchan;
+ bool selected = false;
+
+ /* determine whether any bone is selected. */
+ LISTBASE_FOREACH (bPoseChannel *, bchan, &pld->pose->chanbase) {
+ selected = bchan->bone != NULL && bchan->bone->flag & BONE_SELECTED;
+ if (selected) {
+ pld->flag |= PL_PREVIEW_ANY_BONE_SELECTED;
+ break;
+ }
+ }
+ if (!selected) {
+ pld->flag &= ~PL_PREVIEW_ANY_BONE_SELECTED;
+ }
+
+ /* for each posechannel that has an actionchannel in */
+ for (agrp = pld->act->groups.first; agrp; agrp = agrp->next) {
+ /* try to find posechannel */
+ pchan = BKE_pose_channel_find_name(pld->pose, agrp->name);
+
+ /* backup data if available */
+ if (pchan) {
+ tPoseLib_Backup *plb;
+
+ /* store backup */
+ plb = MEM_callocN(sizeof(tPoseLib_Backup), "tPoseLib_Backup");
+
+ plb->pchan = pchan;
+ memcpy(&plb->olddata, plb->pchan, sizeof(bPoseChannel));
+
+ if (pchan->prop)
+ plb->oldprops = IDP_CopyProperty(pchan->prop);
+
+ BLI_addtail(&pld->backups, plb);
+
+ /* mark as being affected */
+ pld->totcount++;
+ }
+ }
}
/* Restores original pose */
static void poselib_backup_restore(tPoseLib_PreviewData *pld)
{
- tPoseLib_Backup *plb;
+ tPoseLib_Backup *plb;
- for (plb = pld->backups.first; plb; plb = plb->next) {
- /* copy most of data straight back */
- memcpy(plb->pchan, &plb->olddata, sizeof(bPoseChannel));
+ for (plb = pld->backups.first; plb; plb = plb->next) {
+ /* copy most of data straight back */
+ memcpy(plb->pchan, &plb->olddata, sizeof(bPoseChannel));
- /* just overwrite values of properties from the stored copies (there should be some) */
- if (plb->oldprops)
- IDP_SyncGroupValues(plb->pchan->prop, plb->oldprops);
+ /* just overwrite values of properties from the stored copies (there should be some) */
+ if (plb->oldprops)
+ IDP_SyncGroupValues(plb->pchan->prop, plb->oldprops);
- /* TODO: constraints settings aren't restored yet,
- * even though these could change (though not that likely) */
- }
+ /* TODO: constraints settings aren't restored yet,
+ * even though these could change (though not that likely) */
+ }
}
/* Free list of backups, including any side data it may use */
static void poselib_backup_free_data(tPoseLib_PreviewData *pld)
{
- tPoseLib_Backup *plb, *plbn;
+ tPoseLib_Backup *plb, *plbn;
- for (plb = pld->backups.first; plb; plb = plbn) {
- plbn = plb->next;
+ for (plb = pld->backups.first; plb; plb = plbn) {
+ plbn = plb->next;
- /* free custom data */
- if (plb->oldprops) {
- IDP_FreeProperty(plb->oldprops);
- MEM_freeN(plb->oldprops);
- }
+ /* free custom data */
+ if (plb->oldprops) {
+ IDP_FreeProperty(plb->oldprops);
+ MEM_freeN(plb->oldprops);
+ }
- /* free backup element now */
- BLI_freelinkN(&pld->backups, plb);
- }
+ /* free backup element now */
+ BLI_freelinkN(&pld->backups, plb);
+ }
}
/* ---------------------------- */
@@ -993,186 +1011,187 @@ static void poselib_backup_free_data(tPoseLib_PreviewData *pld)
*/
static void poselib_apply_pose(tPoseLib_PreviewData *pld)
{
- PointerRNA *ptr = &pld->rna_ptr;
- bArmature *arm = pld->arm;
- bPose *pose = pld->pose;
- bPoseChannel *pchan;
- bAction *act = pld->act;
- bActionGroup *agrp;
-
- KeyframeEditData ked = {{NULL}};
- KeyframeEditFunc group_ok_cb;
- int frame = 1;
- const bool any_bone_selected = pld->flag & PL_PREVIEW_ANY_BONE_SELECTED;
-
- /* get the frame */
- if (pld->marker)
- frame = pld->marker->frame;
- else
- return;
-
-
- /* init settings for testing groups for keyframes */
- group_ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
- ked.f1 = ((float)frame) - 0.5f;
- ked.f2 = ((float)frame) + 0.5f;
-
- /* start applying - only those channels which have a key at this point in time! */
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- /* check if group has any keyframes */
- if (ANIM_animchanneldata_keyframes_loop(&ked, NULL, agrp, ALE_GROUP, NULL, group_ok_cb, NULL)) {
- /* has keyframe on this frame, so try to get a PoseChannel with this name */
- pchan = BKE_pose_channel_find_name(pose, agrp->name);
-
- if (pchan) {
- bool ok = 0;
-
- /* check if this bone should get any animation applied */
- if (!any_bone_selected) {
- /* if no bones are selected, then any bone is ok */
- ok = 1;
- }
- else if (pchan->bone) {
- /* only ok if bone is visible and selected */
- if ((pchan->bone->flag & BONE_SELECTED) &&
- (pchan->bone->flag & BONE_HIDDEN_P) == 0 &&
- (pchan->bone->layer & arm->layer))
- {
- ok = 1;
- }
- }
-
- if (ok)
- animsys_evaluate_action_group(ptr, act, agrp, (float)frame);
- }
- }
- }
+ PointerRNA *ptr = &pld->rna_ptr;
+ bArmature *arm = pld->arm;
+ bPose *pose = pld->pose;
+ bPoseChannel *pchan;
+ bAction *act = pld->act;
+ bActionGroup *agrp;
+
+ KeyframeEditData ked = {{NULL}};
+ KeyframeEditFunc group_ok_cb;
+ int frame = 1;
+ const bool any_bone_selected = pld->flag & PL_PREVIEW_ANY_BONE_SELECTED;
+
+ /* get the frame */
+ if (pld->marker)
+ frame = pld->marker->frame;
+ else
+ return;
+
+ /* init settings for testing groups for keyframes */
+ group_ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
+ ked.f1 = ((float)frame) - 0.5f;
+ ked.f2 = ((float)frame) + 0.5f;
+
+ /* start applying - only those channels which have a key at this point in time! */
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ /* check if group has any keyframes */
+ if (ANIM_animchanneldata_keyframes_loop(
+ &ked, NULL, agrp, ALE_GROUP, NULL, group_ok_cb, NULL)) {
+ /* has keyframe on this frame, so try to get a PoseChannel with this name */
+ pchan = BKE_pose_channel_find_name(pose, agrp->name);
+
+ if (pchan) {
+ bool ok = 0;
+
+ /* check if this bone should get any animation applied */
+ if (!any_bone_selected) {
+ /* if no bones are selected, then any bone is ok */
+ ok = 1;
+ }
+ else if (pchan->bone) {
+ /* only ok if bone is visible and selected */
+ if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->flag & BONE_HIDDEN_P) == 0 &&
+ (pchan->bone->layer & arm->layer)) {
+ ok = 1;
+ }
+ }
+
+ if (ok)
+ animsys_evaluate_action_group(ptr, act, agrp, (float)frame);
+ }
+ }
+ }
}
/* Auto-keys/tags bones affected by the pose used from the poselib */
static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData *pld)
{
- bPose *pose = pld->pose;
- bPoseChannel *pchan;
- bAction *act = pld->act;
- bActionGroup *agrp;
-
- KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
- ListBase dsources = {NULL, NULL};
- bool autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id);
- const bool any_bone_selected = pld->flag & PL_PREVIEW_ANY_BONE_SELECTED;
-
- /* start tagging/keying */
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- /* only for selected bones unless there aren't any selected, in which case all are included */
- pchan = BKE_pose_channel_find_name(pose, agrp->name);
-
- if (pchan) {
- if (!any_bone_selected || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) {
- if (autokey) {
- /* add datasource override for the PoseChannel, to be used later */
- ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan);
-
- /* clear any unkeyed tags */
- if (pchan->bone)
- pchan->bone->flag &= ~BONE_UNKEYED;
- }
- else {
- /* add unkeyed tags */
- if (pchan->bone)
- pchan->bone->flag |= BONE_UNKEYED;
- }
- }
- }
- }
-
- /* perform actual auto-keying now */
- if (autokey) {
- /* insert keyframes for all relevant bones in one go */
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
- BLI_freelistN(&dsources);
- }
-
- /* send notifiers for this */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ bPose *pose = pld->pose;
+ bPoseChannel *pchan;
+ bAction *act = pld->act;
+ bActionGroup *agrp;
+
+ KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
+ ListBase dsources = {NULL, NULL};
+ bool autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id);
+ const bool any_bone_selected = pld->flag & PL_PREVIEW_ANY_BONE_SELECTED;
+
+ /* start tagging/keying */
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ /* only for selected bones unless there aren't any selected, in which case all are included */
+ pchan = BKE_pose_channel_find_name(pose, agrp->name);
+
+ if (pchan) {
+ if (!any_bone_selected || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) {
+ if (autokey) {
+ /* add datasource override for the PoseChannel, to be used later */
+ ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan);
+
+ /* clear any unkeyed tags */
+ if (pchan->bone)
+ pchan->bone->flag &= ~BONE_UNKEYED;
+ }
+ else {
+ /* add unkeyed tags */
+ if (pchan->bone)
+ pchan->bone->flag |= BONE_UNKEYED;
+ }
+ }
+ }
+ }
+
+ /* perform actual auto-keying now */
+ if (autokey) {
+ /* insert keyframes for all relevant bones in one go */
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ BLI_freelistN(&dsources);
+ }
+
+ /* send notifiers for this */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
/* Apply the relevant changes to the pose */
static void poselib_preview_apply(bContext *C, wmOperator *op)
{
- tPoseLib_PreviewData *pld = (tPoseLib_PreviewData *)op->customdata;
-
- /* only recalc pose (and its dependencies) if pose has changed */
- if (pld->redraw == PL_PREVIEW_REDRAWALL) {
- /* don't clear pose if firsttime */
- if ((pld->flag & PL_PREVIEW_FIRSTTIME) == 0)
- poselib_backup_restore(pld);
- else
- pld->flag &= ~PL_PREVIEW_FIRSTTIME;
-
- /* pose should be the right one to draw (unless we're temporarily not showing it) */
- if ((pld->flag & PL_PREVIEW_SHOWORIGINAL) == 0) {
- RNA_int_set(op->ptr, "pose_index", BLI_findindex(&pld->act->markers, pld->marker));
- poselib_apply_pose(pld);
- }
- else
- RNA_int_set(op->ptr, "pose_index", -2); /* -2 means don't apply any pose */
-
- /* old optimize trick... this enforces to bypass the depsgraph
- * - note: code copied from transform_generics.c -> recalcData()
- */
- // FIXME: shouldn't this use the builtin stuff?
- if ((pld->arm->flag & ARM_DELAYDEFORM) == 0)
- DEG_id_tag_update(&pld->ob->id, ID_RECALC_GEOMETRY); /* sets recalc flags */
- else
- BKE_pose_where_is(CTX_data_depsgraph(C), pld->scene, pld->ob);
- }
-
- /* do header print - if interactively previewing */
- if (pld->state == PL_PREVIEW_RUNNING) {
- if (pld->flag & PL_PREVIEW_SHOWORIGINAL) {
- ED_area_status_text(pld->sa, IFACE_("PoseLib Previewing Pose: [Showing Original Pose]"));
- ED_workspace_status_text(C, IFACE_("Use Tab to start previewing poses again"));
- }
- else if (pld->searchstr[0]) {
- char tempstr[65];
- char markern[64];
- short index;
-
- /* get search-string */
- index = pld->search_cursor;
-
- if (index >= 0 && index < sizeof(tempstr) - 1) {
- memcpy(&tempstr[0], &pld->searchstr[0], index);
- tempstr[index] = '|';
- memcpy(&tempstr[index + 1], &pld->searchstr[index], (sizeof(tempstr) - 1) - index);
- }
- else {
- BLI_strncpy(tempstr, pld->searchstr, sizeof(tempstr));
- }
-
- /* get marker name */
- BLI_strncpy(markern, pld->marker ? pld->marker->name : "No Matches", sizeof(markern));
-
- BLI_snprintf(pld->headerstr, sizeof(pld->headerstr),
- IFACE_("PoseLib Previewing Pose: Filter - [%s] | "
- "Current Pose - \"%s\""),
- tempstr, markern);
- ED_area_status_text(pld->sa, pld->headerstr);
- ED_workspace_status_text(C, IFACE_("Use ScrollWheel or PageUp/Down to change pose"));
- }
- else {
- BLI_snprintf(pld->headerstr, sizeof(pld->headerstr),
- IFACE_("PoseLib Previewing Pose: \"%s\""),
- pld->marker->name);
- ED_area_status_text(pld->sa, pld->headerstr);
- ED_workspace_status_text(C, NULL);
- }
- }
-
- /* request drawing of view + clear redraw flag */
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pld->ob);
- pld->redraw = PL_PREVIEW_NOREDRAW;
+ tPoseLib_PreviewData *pld = (tPoseLib_PreviewData *)op->customdata;
+
+ /* only recalc pose (and its dependencies) if pose has changed */
+ if (pld->redraw == PL_PREVIEW_REDRAWALL) {
+ /* don't clear pose if firsttime */
+ if ((pld->flag & PL_PREVIEW_FIRSTTIME) == 0)
+ poselib_backup_restore(pld);
+ else
+ pld->flag &= ~PL_PREVIEW_FIRSTTIME;
+
+ /* pose should be the right one to draw (unless we're temporarily not showing it) */
+ if ((pld->flag & PL_PREVIEW_SHOWORIGINAL) == 0) {
+ RNA_int_set(op->ptr, "pose_index", BLI_findindex(&pld->act->markers, pld->marker));
+ poselib_apply_pose(pld);
+ }
+ else
+ RNA_int_set(op->ptr, "pose_index", -2); /* -2 means don't apply any pose */
+
+ /* old optimize trick... this enforces to bypass the depsgraph
+ * - note: code copied from transform_generics.c -> recalcData()
+ */
+ // FIXME: shouldn't this use the builtin stuff?
+ if ((pld->arm->flag & ARM_DELAYDEFORM) == 0)
+ DEG_id_tag_update(&pld->ob->id, ID_RECALC_GEOMETRY); /* sets recalc flags */
+ else
+ BKE_pose_where_is(CTX_data_depsgraph(C), pld->scene, pld->ob);
+ }
+
+ /* do header print - if interactively previewing */
+ if (pld->state == PL_PREVIEW_RUNNING) {
+ if (pld->flag & PL_PREVIEW_SHOWORIGINAL) {
+ ED_area_status_text(pld->sa, IFACE_("PoseLib Previewing Pose: [Showing Original Pose]"));
+ ED_workspace_status_text(C, IFACE_("Use Tab to start previewing poses again"));
+ }
+ else if (pld->searchstr[0]) {
+ char tempstr[65];
+ char markern[64];
+ short index;
+
+ /* get search-string */
+ index = pld->search_cursor;
+
+ if (index >= 0 && index < sizeof(tempstr) - 1) {
+ memcpy(&tempstr[0], &pld->searchstr[0], index);
+ tempstr[index] = '|';
+ memcpy(&tempstr[index + 1], &pld->searchstr[index], (sizeof(tempstr) - 1) - index);
+ }
+ else {
+ BLI_strncpy(tempstr, pld->searchstr, sizeof(tempstr));
+ }
+
+ /* get marker name */
+ BLI_strncpy(markern, pld->marker ? pld->marker->name : "No Matches", sizeof(markern));
+
+ BLI_snprintf(pld->headerstr,
+ sizeof(pld->headerstr),
+ IFACE_("PoseLib Previewing Pose: Filter - [%s] | "
+ "Current Pose - \"%s\""),
+ tempstr,
+ markern);
+ ED_area_status_text(pld->sa, pld->headerstr);
+ ED_workspace_status_text(C, IFACE_("Use ScrollWheel or PageUp/Down to change pose"));
+ }
+ else {
+ BLI_snprintf(pld->headerstr,
+ sizeof(pld->headerstr),
+ IFACE_("PoseLib Previewing Pose: \"%s\""),
+ pld->marker->name);
+ ED_area_status_text(pld->sa, pld->headerstr);
+ ED_workspace_status_text(C, NULL);
+ }
+ }
+
+ /* request drawing of view + clear redraw flag */
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pld->ob);
+ pld->redraw = PL_PREVIEW_NOREDRAW;
}
/* ---------------------------- */
@@ -1182,351 +1201,373 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
*/
static void poselib_preview_get_next(tPoseLib_PreviewData *pld, int step)
{
- /* stop if not going anywhere, as we assume that there is a direction to move in */
- if (step == 0)
- return;
-
- /* search-string dictates a special approach */
- if (pld->searchstr[0]) {
- TimeMarker *marker;
- LinkData *ld, *ldn, *ldc;
-
- /* free and rebuild if needed (i.e. if search-str changed) */
- if (!STREQ(pld->searchstr, pld->searchold)) {
- /* free list of temporary search matches */
- BLI_freelistN(&pld->searchp);
-
- /* generate a new list of search matches */
- for (marker = pld->act->markers.first; marker; marker = marker->next) {
- /* does the name partially match?
- * - don't worry about case, to make it easier for users to quickly input a name (or
- * part of one), which is the whole point of this feature
- */
- if (BLI_strcasestr(marker->name, pld->searchstr)) {
- /* make link-data to store reference to it */
- ld = MEM_callocN(sizeof(LinkData), "PoseMatch");
- ld->data = marker;
- BLI_addtail(&pld->searchp, ld);
- }
- }
-
- /* set current marker to NULL (so that we start from first) */
- pld->marker = NULL;
- }
-
- /* check if any matches */
- if (BLI_listbase_is_empty(&pld->searchp)) {
- pld->marker = NULL;
- return;
- }
-
- /* find first match */
- for (ldc = pld->searchp.first; ldc; ldc = ldc->next) {
- if (ldc->data == pld->marker)
- break;
- }
- if (ldc == NULL)
- ldc = pld->searchp.first;
-
- /* Loop through the matches in a cyclic fashion, incrementing/decrementing step as appropriate
- * until step == 0. At this point, marker should be the correct marker.
- */
- if (step > 0) {
- for (ld = ldc; ld && step; ld = ldn, step--)
- ldn = (ld->next) ? ld->next : pld->searchp.first;
- }
- else {
- for (ld = ldc; ld && step; ld = ldn, step++)
- ldn = (ld->prev) ? ld->prev : pld->searchp.last;
- }
-
- /* set marker */
- if (ld)
- pld->marker = ld->data;
- }
- else {
- TimeMarker *marker, *next;
-
- /* if no marker, because we just ended searching, then set that to the start of the list */
- if (pld->marker == NULL)
- pld->marker = pld->act->markers.first;
-
- /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate
- * until step == 0. At this point, marker should be the correct marker.
- */
- if (step > 0) {
- for (marker = pld->marker; marker && step; marker = next, step--)
- next = (marker->next) ? marker->next : pld->act->markers.first;
- }
- else {
- for (marker = pld->marker; marker && step; marker = next, step++)
- next = (marker->prev) ? marker->prev : pld->act->markers.last;
- }
-
- /* it should be fairly impossible for marker to be NULL */
- if (marker)
- pld->marker = marker;
- }
+ /* stop if not going anywhere, as we assume that there is a direction to move in */
+ if (step == 0)
+ return;
+
+ /* search-string dictates a special approach */
+ if (pld->searchstr[0]) {
+ TimeMarker *marker;
+ LinkData *ld, *ldn, *ldc;
+
+ /* free and rebuild if needed (i.e. if search-str changed) */
+ if (!STREQ(pld->searchstr, pld->searchold)) {
+ /* free list of temporary search matches */
+ BLI_freelistN(&pld->searchp);
+
+ /* generate a new list of search matches */
+ for (marker = pld->act->markers.first; marker; marker = marker->next) {
+ /* does the name partially match?
+ * - don't worry about case, to make it easier for users to quickly input a name (or
+ * part of one), which is the whole point of this feature
+ */
+ if (BLI_strcasestr(marker->name, pld->searchstr)) {
+ /* make link-data to store reference to it */
+ ld = MEM_callocN(sizeof(LinkData), "PoseMatch");
+ ld->data = marker;
+ BLI_addtail(&pld->searchp, ld);
+ }
+ }
+
+ /* set current marker to NULL (so that we start from first) */
+ pld->marker = NULL;
+ }
+
+ /* check if any matches */
+ if (BLI_listbase_is_empty(&pld->searchp)) {
+ pld->marker = NULL;
+ return;
+ }
+
+ /* find first match */
+ for (ldc = pld->searchp.first; ldc; ldc = ldc->next) {
+ if (ldc->data == pld->marker)
+ break;
+ }
+ if (ldc == NULL)
+ ldc = pld->searchp.first;
+
+ /* Loop through the matches in a cyclic fashion, incrementing/decrementing step as appropriate
+ * until step == 0. At this point, marker should be the correct marker.
+ */
+ if (step > 0) {
+ for (ld = ldc; ld && step; ld = ldn, step--)
+ ldn = (ld->next) ? ld->next : pld->searchp.first;
+ }
+ else {
+ for (ld = ldc; ld && step; ld = ldn, step++)
+ ldn = (ld->prev) ? ld->prev : pld->searchp.last;
+ }
+
+ /* set marker */
+ if (ld)
+ pld->marker = ld->data;
+ }
+ else {
+ TimeMarker *marker, *next;
+
+ /* if no marker, because we just ended searching, then set that to the start of the list */
+ if (pld->marker == NULL)
+ pld->marker = pld->act->markers.first;
+
+ /* Loop through the markers in a cyclic fashion, incrementing/decrementing step as appropriate
+ * until step == 0. At this point, marker should be the correct marker.
+ */
+ if (step > 0) {
+ for (marker = pld->marker; marker && step; marker = next, step--)
+ next = (marker->next) ? marker->next : pld->act->markers.first;
+ }
+ else {
+ for (marker = pld->marker; marker && step; marker = next, step++)
+ next = (marker->prev) ? marker->prev : pld->act->markers.last;
+ }
+
+ /* it should be fairly impossible for marker to be NULL */
+ if (marker)
+ pld->marker = marker;
+ }
}
/* specially handle events for searching */
-static void poselib_preview_handle_search(tPoseLib_PreviewData *pld, unsigned short event, char ascii)
+static void poselib_preview_handle_search(tPoseLib_PreviewData *pld,
+ unsigned short event,
+ char ascii)
{
- /* try doing some form of string manipulation first */
- switch (event) {
- case BACKSPACEKEY:
- if (pld->searchstr[0] && pld->search_cursor) {
- short len = strlen(pld->searchstr);
- short index = pld->search_cursor;
- short i;
-
- for (i = index; i <= len; i++)
- pld->searchstr[i - 1] = pld->searchstr[i];
-
- pld->search_cursor--;
-
- poselib_preview_get_next(pld, 1);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- return;
- }
- break;
-
- case DELKEY:
- if (pld->searchstr[0] && pld->searchstr[1]) {
- short len = strlen(pld->searchstr);
- short index = pld->search_cursor;
- int i;
-
- if (index < len) {
- for (i = index; i < len; i++)
- pld->searchstr[i] = pld->searchstr[i + 1];
-
- poselib_preview_get_next(pld, 1);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- return;
- }
- }
- break;
- }
-
- if (ascii) {
- /* character to add to the string */
- short index = pld->search_cursor;
- short len = (pld->searchstr[0]) ? strlen(pld->searchstr) : 0;
- short i;
-
- if (len) {
- for (i = len; i > index; i--)
- pld->searchstr[i] = pld->searchstr[i - 1];
- }
- else
- pld->searchstr[1] = 0;
-
- pld->searchstr[index] = ascii;
- pld->search_cursor++;
-
- poselib_preview_get_next(pld, 1);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- }
+ /* try doing some form of string manipulation first */
+ switch (event) {
+ case BACKSPACEKEY:
+ if (pld->searchstr[0] && pld->search_cursor) {
+ short len = strlen(pld->searchstr);
+ short index = pld->search_cursor;
+ short i;
+
+ for (i = index; i <= len; i++)
+ pld->searchstr[i - 1] = pld->searchstr[i];
+
+ pld->search_cursor--;
+
+ poselib_preview_get_next(pld, 1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ return;
+ }
+ break;
+
+ case DELKEY:
+ if (pld->searchstr[0] && pld->searchstr[1]) {
+ short len = strlen(pld->searchstr);
+ short index = pld->search_cursor;
+ int i;
+
+ if (index < len) {
+ for (i = index; i < len; i++)
+ pld->searchstr[i] = pld->searchstr[i + 1];
+
+ poselib_preview_get_next(pld, 1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ return;
+ }
+ }
+ break;
+ }
+
+ if (ascii) {
+ /* character to add to the string */
+ short index = pld->search_cursor;
+ short len = (pld->searchstr[0]) ? strlen(pld->searchstr) : 0;
+ short i;
+
+ if (len) {
+ for (i = len; i > index; i--)
+ pld->searchstr[i] = pld->searchstr[i - 1];
+ }
+ else
+ pld->searchstr[1] = 0;
+
+ pld->searchstr[index] = ascii;
+ pld->search_cursor++;
+
+ poselib_preview_get_next(pld, 1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ }
}
/* handle events for poselib_preview_poses */
static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, const wmEvent *event)
{
- tPoseLib_PreviewData *pld = op->customdata;
- int ret = OPERATOR_RUNNING_MODAL;
-
- /* only accept 'press' event, and ignore 'release', so that we don't get double actions */
- if (ELEM(event->val, KM_PRESS, KM_NOTHING) == 0) {
- //printf("PoseLib: skipping event with type '%s' and val %d\n", WM_key_event_string(event->type, false), event->val);
- return ret;
- }
-
- /* backup stuff that needs to occur before every operation
- * - make a copy of searchstr, so that we know if cache needs to be rebuilt
- */
- BLI_strncpy(pld->searchold, pld->searchstr, sizeof(pld->searchold));
-
- /* if we're currently showing the original pose, only certain events are handled */
- if (pld->flag & PL_PREVIEW_SHOWORIGINAL) {
- switch (event->type) {
- /* exit - cancel */
- case ESCKEY:
- case RIGHTMOUSE:
- pld->state = PL_PREVIEW_CANCEL;
- break;
-
- /* exit - confirm */
- case LEFTMOUSE:
- case RETKEY:
- case PADENTER:
- case SPACEKEY:
- pld->state = PL_PREVIEW_CONFIRM;
- break;
-
- /* view manipulation */
- /* we add pass through here, so that the operators responsible for these can still run,
- * even though we still maintain control (as RUNNING_MODAL flag is still set too)
- */
- case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
- case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
- case PADPLUSKEY: case PADMINUS:
- case MIDDLEMOUSE: case MOUSEMOVE:
- //pld->redraw = PL_PREVIEW_REDRAWHEADER;
- ret = OPERATOR_PASS_THROUGH;
- break;
-
- /* quicky compare to original */
- case TABKEY:
- pld->flag &= ~PL_PREVIEW_SHOWORIGINAL;
- pld->redraw = PL_PREVIEW_REDRAWALL;
- break;
- }
-
- /* EXITS HERE... */
- return ret;
- }
-
- /* NORMAL EVENT HANDLING... */
- /* searching takes priority over normal activity */
- switch (event->type) {
- /* exit - cancel */
- case ESCKEY:
- case RIGHTMOUSE:
- pld->state = PL_PREVIEW_CANCEL;
- break;
-
- /* exit - confirm */
- case LEFTMOUSE:
- case RETKEY:
- case PADENTER:
- case SPACEKEY:
- pld->state = PL_PREVIEW_CONFIRM;
- break;
-
- /* toggle between original pose and poselib pose*/
- case TABKEY:
- pld->flag |= PL_PREVIEW_SHOWORIGINAL;
- pld->redraw = PL_PREVIEW_REDRAWALL;
- break;
-
- /* change to previous pose (cyclic) */
- case PAGEUPKEY:
- case WHEELUPMOUSE:
- poselib_preview_get_next(pld, -1);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- break;
-
- /* change to next pose (cyclic) */
- case PAGEDOWNKEY:
- case WHEELDOWNMOUSE:
- poselib_preview_get_next(pld, 1);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- break;
-
- /* jump 5 poses (cyclic, back) */
- case DOWNARROWKEY:
- poselib_preview_get_next(pld, -5);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- break;
-
- /* jump 5 poses (cyclic, forward) */
- case UPARROWKEY:
- poselib_preview_get_next(pld, 5);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- break;
-
- /* change to next pose or searching cursor control */
- case RIGHTARROWKEY:
- if (pld->searchstr[0]) {
- /* move text-cursor to the right */
- if (pld->search_cursor < strlen(pld->searchstr))
- pld->search_cursor++;
- pld->redraw = PL_PREVIEW_REDRAWHEADER;
- }
- else {
- /* change to next pose (cyclic) */
- poselib_preview_get_next(pld, 1);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- }
- break;
-
- /* change to next pose or searching cursor control */
- case LEFTARROWKEY:
- if (pld->searchstr[0]) {
- /* move text-cursor to the left */
- if (pld->search_cursor)
- pld->search_cursor--;
- pld->redraw = PL_PREVIEW_REDRAWHEADER;
- }
- else {
- /* change to previous pose (cyclic) */
- poselib_preview_get_next(pld, -1);
- pld->redraw = PL_PREVIEW_REDRAWALL;
- }
- break;
-
- /* change to first pose or start of searching string */
- case HOMEKEY:
- if (pld->searchstr[0]) {
- pld->search_cursor = 0;
- pld->redraw = PL_PREVIEW_REDRAWHEADER;
- }
- else {
- /* change to first pose */
- pld->marker = pld->act->markers.first;
- pld->act->active_marker = 1;
-
- pld->redraw = PL_PREVIEW_REDRAWALL;
- }
- break;
-
- /* change to last pose or start of searching string */
- case ENDKEY:
- if (pld->searchstr[0]) {
- pld->search_cursor = strlen(pld->searchstr);
- pld->redraw = PL_PREVIEW_REDRAWHEADER;
- }
- else {
- /* change to last pose */
- pld->marker = pld->act->markers.last;
- pld->act->active_marker = BLI_listbase_count(&pld->act->markers);
-
- pld->redraw = PL_PREVIEW_REDRAWALL;
- }
- break;
-
- /* view manipulation */
- /* we add pass through here, so that the operators responsible for these can still run,
- * even though we still maintain control (as RUNNING_MODAL flag is still set too)
- */
- case MIDDLEMOUSE: case MOUSEMOVE:
- //pld->redraw = PL_PREVIEW_REDRAWHEADER;
- ret = OPERATOR_PASS_THROUGH;
- break;
-
- /* view manipulation, or searching */
- case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
- case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
- case PADPLUSKEY: case PADMINUS:
- if (pld->searchstr[0]) {
- /* searching... */
- poselib_preview_handle_search(pld, event->type, event->ascii);
- }
- else {
- /* view manipulation (see above) */
- //pld->redraw = PL_PREVIEW_REDRAWHEADER;
- ret = OPERATOR_PASS_THROUGH;
- }
- break;
-
- /* otherwise, assume that searching might be able to handle it */
- default:
- poselib_preview_handle_search(pld, event->type, event->ascii);
- break;
- }
-
- return ret;
+ tPoseLib_PreviewData *pld = op->customdata;
+ int ret = OPERATOR_RUNNING_MODAL;
+
+ /* only accept 'press' event, and ignore 'release', so that we don't get double actions */
+ if (ELEM(event->val, KM_PRESS, KM_NOTHING) == 0) {
+ //printf("PoseLib: skipping event with type '%s' and val %d\n", WM_key_event_string(event->type, false), event->val);
+ return ret;
+ }
+
+ /* backup stuff that needs to occur before every operation
+ * - make a copy of searchstr, so that we know if cache needs to be rebuilt
+ */
+ BLI_strncpy(pld->searchold, pld->searchstr, sizeof(pld->searchold));
+
+ /* if we're currently showing the original pose, only certain events are handled */
+ if (pld->flag & PL_PREVIEW_SHOWORIGINAL) {
+ switch (event->type) {
+ /* exit - cancel */
+ case ESCKEY:
+ case RIGHTMOUSE:
+ pld->state = PL_PREVIEW_CANCEL;
+ break;
+
+ /* exit - confirm */
+ case LEFTMOUSE:
+ case RETKEY:
+ case PADENTER:
+ case SPACEKEY:
+ pld->state = PL_PREVIEW_CONFIRM;
+ break;
+
+ /* view manipulation */
+ /* we add pass through here, so that the operators responsible for these can still run,
+ * even though we still maintain control (as RUNNING_MODAL flag is still set too)
+ */
+ case PAD0:
+ case PAD1:
+ case PAD2:
+ case PAD3:
+ case PAD4:
+ case PAD5:
+ case PAD6:
+ case PAD7:
+ case PAD8:
+ case PAD9:
+ case PADPLUSKEY:
+ case PADMINUS:
+ case MIDDLEMOUSE:
+ case MOUSEMOVE:
+ //pld->redraw = PL_PREVIEW_REDRAWHEADER;
+ ret = OPERATOR_PASS_THROUGH;
+ break;
+
+ /* quicky compare to original */
+ case TABKEY:
+ pld->flag &= ~PL_PREVIEW_SHOWORIGINAL;
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ break;
+ }
+
+ /* EXITS HERE... */
+ return ret;
+ }
+
+ /* NORMAL EVENT HANDLING... */
+ /* searching takes priority over normal activity */
+ switch (event->type) {
+ /* exit - cancel */
+ case ESCKEY:
+ case RIGHTMOUSE:
+ pld->state = PL_PREVIEW_CANCEL;
+ break;
+
+ /* exit - confirm */
+ case LEFTMOUSE:
+ case RETKEY:
+ case PADENTER:
+ case SPACEKEY:
+ pld->state = PL_PREVIEW_CONFIRM;
+ break;
+
+ /* toggle between original pose and poselib pose*/
+ case TABKEY:
+ pld->flag |= PL_PREVIEW_SHOWORIGINAL;
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* change to previous pose (cyclic) */
+ case PAGEUPKEY:
+ case WHEELUPMOUSE:
+ poselib_preview_get_next(pld, -1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* change to next pose (cyclic) */
+ case PAGEDOWNKEY:
+ case WHEELDOWNMOUSE:
+ poselib_preview_get_next(pld, 1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* jump 5 poses (cyclic, back) */
+ case DOWNARROWKEY:
+ poselib_preview_get_next(pld, -5);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* jump 5 poses (cyclic, forward) */
+ case UPARROWKEY:
+ poselib_preview_get_next(pld, 5);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ break;
+
+ /* change to next pose or searching cursor control */
+ case RIGHTARROWKEY:
+ if (pld->searchstr[0]) {
+ /* move text-cursor to the right */
+ if (pld->search_cursor < strlen(pld->searchstr))
+ pld->search_cursor++;
+ pld->redraw = PL_PREVIEW_REDRAWHEADER;
+ }
+ else {
+ /* change to next pose (cyclic) */
+ poselib_preview_get_next(pld, 1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ /* change to next pose or searching cursor control */
+ case LEFTARROWKEY:
+ if (pld->searchstr[0]) {
+ /* move text-cursor to the left */
+ if (pld->search_cursor)
+ pld->search_cursor--;
+ pld->redraw = PL_PREVIEW_REDRAWHEADER;
+ }
+ else {
+ /* change to previous pose (cyclic) */
+ poselib_preview_get_next(pld, -1);
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ /* change to first pose or start of searching string */
+ case HOMEKEY:
+ if (pld->searchstr[0]) {
+ pld->search_cursor = 0;
+ pld->redraw = PL_PREVIEW_REDRAWHEADER;
+ }
+ else {
+ /* change to first pose */
+ pld->marker = pld->act->markers.first;
+ pld->act->active_marker = 1;
+
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ /* change to last pose or start of searching string */
+ case ENDKEY:
+ if (pld->searchstr[0]) {
+ pld->search_cursor = strlen(pld->searchstr);
+ pld->redraw = PL_PREVIEW_REDRAWHEADER;
+ }
+ else {
+ /* change to last pose */
+ pld->marker = pld->act->markers.last;
+ pld->act->active_marker = BLI_listbase_count(&pld->act->markers);
+
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ }
+ break;
+
+ /* view manipulation */
+ /* we add pass through here, so that the operators responsible for these can still run,
+ * even though we still maintain control (as RUNNING_MODAL flag is still set too)
+ */
+ case MIDDLEMOUSE:
+ case MOUSEMOVE:
+ //pld->redraw = PL_PREVIEW_REDRAWHEADER;
+ ret = OPERATOR_PASS_THROUGH;
+ break;
+
+ /* view manipulation, or searching */
+ case PAD0:
+ case PAD1:
+ case PAD2:
+ case PAD3:
+ case PAD4:
+ case PAD5:
+ case PAD6:
+ case PAD7:
+ case PAD8:
+ case PAD9:
+ case PADPLUSKEY:
+ case PADMINUS:
+ if (pld->searchstr[0]) {
+ /* searching... */
+ poselib_preview_handle_search(pld, event->type, event->ascii);
+ }
+ else {
+ /* view manipulation (see above) */
+ //pld->redraw = PL_PREVIEW_REDRAWHEADER;
+ ret = OPERATOR_PASS_THROUGH;
+ }
+ break;
+
+ /* otherwise, assume that searching might be able to handle it */
+ default:
+ poselib_preview_handle_search(pld, event->type, event->ascii);
+ break;
+ }
+
+ return ret;
}
/* ---------------------------- */
@@ -1534,277 +1575,295 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
/* Init PoseLib Previewing data */
static void poselib_preview_init_data(bContext *C, wmOperator *op)
{
- tPoseLib_PreviewData *pld;
- Object *ob = get_poselib_object(C);
- int pose_index = RNA_int_get(op->ptr, "pose_index");
-
- /* set up preview state info */
- op->customdata = pld = MEM_callocN(sizeof(tPoseLib_PreviewData), "PoseLib Preview Data");
-
- /* get basic data */
- pld->ob = ob;
- pld->arm = (ob) ? (ob->data) : NULL;
- pld->pose = (ob) ? (ob->pose) : NULL;
- pld->act = (ob) ? (ob->poselib) : NULL;
-
- pld->scene = CTX_data_scene(C);
- pld->sa = CTX_wm_area(C);
-
- /* get starting pose based on RNA-props for this operator */
- if (pose_index == -1)
- pld->marker = poselib_get_active_pose(pld->act);
- else if (pose_index == -2)
- pld->flag |= PL_PREVIEW_SHOWORIGINAL;
- else
- pld->marker = (pld->act) ? BLI_findlink(&pld->act->markers, pose_index) : NULL;
-
- /* check if valid poselib */
- if (ELEM(NULL, pld->ob, pld->pose, pld->arm)) {
- BKE_report(op->reports, RPT_ERROR, "Pose lib is only for armatures in pose mode");
- pld->state = PL_PREVIEW_ERROR;
- return;
- }
- if (pld->act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object does not have a valid pose lib");
- pld->state = PL_PREVIEW_ERROR;
- return;
- }
- if (pld->marker == NULL) {
- if (pld->act->markers.first) {
- /* just use first one then... */
- pld->marker = pld->act->markers.first;
- if (pose_index > -2)
- BKE_report(op->reports, RPT_WARNING, "Pose lib had no active pose");
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "Pose lib has no poses to preview/apply");
- pld->state = PL_PREVIEW_ERROR;
- return;
- }
- }
-
- /* get ID pointer for applying poses */
- RNA_id_pointer_create(&ob->id, &pld->rna_ptr);
-
- /* make backups for restoring pose */
- poselib_backup_posecopy(pld);
-
- /* set flags for running */
- pld->state = PL_PREVIEW_RUNNING;
- pld->redraw = PL_PREVIEW_REDRAWALL;
- pld->flag |= PL_PREVIEW_FIRSTTIME;
-
- /* set depsgraph flags */
- /* make sure the lock is set OK, unlock can be accidentally saved? */
- pld->pose->flag |= POSE_LOCKED;
- pld->pose->flag &= ~POSE_DO_UNLOCK;
-
- /* clear strings + search */
- pld->headerstr[0] = pld->searchstr[0] = pld->searchold[0] = '\0';
- pld->search_cursor = 0;
+ tPoseLib_PreviewData *pld;
+ Object *ob = get_poselib_object(C);
+ int pose_index = RNA_int_get(op->ptr, "pose_index");
+
+ /* set up preview state info */
+ op->customdata = pld = MEM_callocN(sizeof(tPoseLib_PreviewData), "PoseLib Preview Data");
+
+ /* get basic data */
+ pld->ob = ob;
+ pld->arm = (ob) ? (ob->data) : NULL;
+ pld->pose = (ob) ? (ob->pose) : NULL;
+ pld->act = (ob) ? (ob->poselib) : NULL;
+
+ pld->scene = CTX_data_scene(C);
+ pld->sa = CTX_wm_area(C);
+
+ /* get starting pose based on RNA-props for this operator */
+ if (pose_index == -1)
+ pld->marker = poselib_get_active_pose(pld->act);
+ else if (pose_index == -2)
+ pld->flag |= PL_PREVIEW_SHOWORIGINAL;
+ else
+ pld->marker = (pld->act) ? BLI_findlink(&pld->act->markers, pose_index) : NULL;
+
+ /* check if valid poselib */
+ if (ELEM(NULL, pld->ob, pld->pose, pld->arm)) {
+ BKE_report(op->reports, RPT_ERROR, "Pose lib is only for armatures in pose mode");
+ pld->state = PL_PREVIEW_ERROR;
+ return;
+ }
+ if (pld->act == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Object does not have a valid pose lib");
+ pld->state = PL_PREVIEW_ERROR;
+ return;
+ }
+ if (pld->marker == NULL) {
+ if (pld->act->markers.first) {
+ /* just use first one then... */
+ pld->marker = pld->act->markers.first;
+ if (pose_index > -2)
+ BKE_report(op->reports, RPT_WARNING, "Pose lib had no active pose");
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Pose lib has no poses to preview/apply");
+ pld->state = PL_PREVIEW_ERROR;
+ return;
+ }
+ }
+
+ /* get ID pointer for applying poses */
+ RNA_id_pointer_create(&ob->id, &pld->rna_ptr);
+
+ /* make backups for restoring pose */
+ poselib_backup_posecopy(pld);
+
+ /* set flags for running */
+ pld->state = PL_PREVIEW_RUNNING;
+ pld->redraw = PL_PREVIEW_REDRAWALL;
+ pld->flag |= PL_PREVIEW_FIRSTTIME;
+
+ /* set depsgraph flags */
+ /* make sure the lock is set OK, unlock can be accidentally saved? */
+ pld->pose->flag |= POSE_LOCKED;
+ pld->pose->flag &= ~POSE_DO_UNLOCK;
+
+ /* clear strings + search */
+ pld->headerstr[0] = pld->searchstr[0] = pld->searchold[0] = '\0';
+ pld->search_cursor = 0;
}
/* After previewing poses */
static void poselib_preview_cleanup(bContext *C, wmOperator *op)
{
- tPoseLib_PreviewData *pld = (tPoseLib_PreviewData *)op->customdata;
- Scene *scene = pld->scene;
- Object *ob = pld->ob;
- bPose *pose = pld->pose;
- bArmature *arm = pld->arm;
- bAction *act = pld->act;
- TimeMarker *marker = pld->marker;
-
- /* redraw the header so that it doesn't show any of our stuff anymore */
- ED_area_status_text(pld->sa, NULL);
- ED_workspace_status_text(C, NULL);
-
- /* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
- pose->flag |= POSE_DO_UNLOCK;
-
- /* clear pose if canceled */
- if (pld->state == PL_PREVIEW_CANCEL) {
- poselib_backup_restore(pld);
-
- /* old optimize trick... this enforces to bypass the depgraph
- * - note: code copied from transform_generics.c -> recalcData()
- */
- if ((arm->flag & ARM_DELAYDEFORM) == 0)
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); /* sets recalc flags */
- else
- BKE_pose_where_is(CTX_data_depsgraph(C), scene, ob);
- }
- else if (pld->state == PL_PREVIEW_CONFIRM) {
- /* tag poses as appropriate */
- poselib_keytag_pose(C, scene, pld);
-
- /* change active pose setting */
- act->active_marker = BLI_findindex(&act->markers, marker) + 1;
- action_set_activemarker(act, marker, NULL);
-
- /* Update event for pose and deformation children */
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
-
- /* updates */
- if (IS_AUTOKEY_MODE(scene, NORMAL)) {
- //remake_action_ipos(ob->action);
- }
- else
- BKE_pose_where_is(CTX_data_depsgraph(C), scene, ob);
- }
-
- /* Request final redraw of the view. */
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pld->ob);
-
- /* free memory used for backups and searching */
- poselib_backup_free_data(pld);
- BLI_freelistN(&pld->searchp);
-
- /* free temp data for operator */
- MEM_freeN(pld);
- op->customdata = NULL;
+ tPoseLib_PreviewData *pld = (tPoseLib_PreviewData *)op->customdata;
+ Scene *scene = pld->scene;
+ Object *ob = pld->ob;
+ bPose *pose = pld->pose;
+ bArmature *arm = pld->arm;
+ bAction *act = pld->act;
+ TimeMarker *marker = pld->marker;
+
+ /* redraw the header so that it doesn't show any of our stuff anymore */
+ ED_area_status_text(pld->sa, NULL);
+ ED_workspace_status_text(C, NULL);
+
+ /* this signal does one recalc on pose, then unlocks, so ESC or edit will work */
+ pose->flag |= POSE_DO_UNLOCK;
+
+ /* clear pose if canceled */
+ if (pld->state == PL_PREVIEW_CANCEL) {
+ poselib_backup_restore(pld);
+
+ /* old optimize trick... this enforces to bypass the depgraph
+ * - note: code copied from transform_generics.c -> recalcData()
+ */
+ if ((arm->flag & ARM_DELAYDEFORM) == 0)
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); /* sets recalc flags */
+ else
+ BKE_pose_where_is(CTX_data_depsgraph(C), scene, ob);
+ }
+ else if (pld->state == PL_PREVIEW_CONFIRM) {
+ /* tag poses as appropriate */
+ poselib_keytag_pose(C, scene, pld);
+
+ /* change active pose setting */
+ act->active_marker = BLI_findindex(&act->markers, marker) + 1;
+ action_set_activemarker(act, marker, NULL);
+
+ /* Update event for pose and deformation children */
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+
+ /* updates */
+ if (IS_AUTOKEY_MODE(scene, NORMAL)) {
+ //remake_action_ipos(ob->action);
+ }
+ else
+ BKE_pose_where_is(CTX_data_depsgraph(C), scene, ob);
+ }
+
+ /* Request final redraw of the view. */
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pld->ob);
+
+ /* free memory used for backups and searching */
+ poselib_backup_free_data(pld);
+ BLI_freelistN(&pld->searchp);
+
+ /* free temp data for operator */
+ MEM_freeN(pld);
+ op->customdata = NULL;
}
/* End previewing operation */
static int poselib_preview_exit(bContext *C, wmOperator *op)
{
- tPoseLib_PreviewData *pld = op->customdata;
- int exit_state = pld->state;
+ tPoseLib_PreviewData *pld = op->customdata;
+ int exit_state = pld->state;
- /* finish up */
- poselib_preview_cleanup(C, op);
+ /* finish up */
+ poselib_preview_cleanup(C, op);
- if (ELEM(exit_state, PL_PREVIEW_CANCEL, PL_PREVIEW_ERROR))
- return OPERATOR_CANCELLED;
- else
- return OPERATOR_FINISHED;
+ if (ELEM(exit_state, PL_PREVIEW_CANCEL, PL_PREVIEW_ERROR))
+ return OPERATOR_CANCELLED;
+ else
+ return OPERATOR_FINISHED;
}
/* Cancel previewing operation (called when exiting Blender) */
static void poselib_preview_cancel(bContext *C, wmOperator *op)
{
- poselib_preview_exit(C, op);
+ poselib_preview_exit(C, op);
}
/* main modal status check */
static int poselib_preview_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- tPoseLib_PreviewData *pld = op->customdata;
- int ret;
+ tPoseLib_PreviewData *pld = op->customdata;
+ int ret;
- /* 1) check state to see if we're still running */
- if (pld->state != PL_PREVIEW_RUNNING)
- return poselib_preview_exit(C, op);
+ /* 1) check state to see if we're still running */
+ if (pld->state != PL_PREVIEW_RUNNING)
+ return poselib_preview_exit(C, op);
- /* 2) handle events */
- ret = poselib_preview_handle_event(C, op, event);
+ /* 2) handle events */
+ ret = poselib_preview_handle_event(C, op, event);
- /* 3) apply changes and redraw, otherwise, confirming goes wrong */
- if (pld->redraw)
- poselib_preview_apply(C, op);
+ /* 3) apply changes and redraw, otherwise, confirming goes wrong */
+ if (pld->redraw)
+ poselib_preview_apply(C, op);
- return ret;
+ return ret;
}
/* Modal Operator init */
static int poselib_preview_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- tPoseLib_PreviewData *pld;
+ tPoseLib_PreviewData *pld;
- /* check if everything is ok, and init settings for modal operator */
- poselib_preview_init_data(C, op);
- pld = (tPoseLib_PreviewData *)op->customdata;
+ /* check if everything is ok, and init settings for modal operator */
+ poselib_preview_init_data(C, op);
+ pld = (tPoseLib_PreviewData *)op->customdata;
- if (pld->state == PL_PREVIEW_ERROR) {
- /* an error occurred, so free temp mem used */
- poselib_preview_cleanup(C, op);
- return OPERATOR_CANCELLED;
- }
+ if (pld->state == PL_PREVIEW_ERROR) {
+ /* an error occurred, so free temp mem used */
+ poselib_preview_cleanup(C, op);
+ return OPERATOR_CANCELLED;
+ }
- /* do initial apply to have something to look at */
- poselib_preview_apply(C, op);
+ /* do initial apply to have something to look at */
+ poselib_preview_apply(C, op);
- /* add temp handler if we're running as a modal operator */
- WM_event_add_modal_handler(C, op);
+ /* add temp handler if we're running as a modal operator */
+ WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_RUNNING_MODAL;
}
/* Repeat operator */
static int poselib_preview_exec(bContext *C, wmOperator *op)
{
- tPoseLib_PreviewData *pld;
+ tPoseLib_PreviewData *pld;
- /* check if everything is ok, and init settings for modal operator */
- poselib_preview_init_data(C, op);
- pld = (tPoseLib_PreviewData *)op->customdata;
+ /* check if everything is ok, and init settings for modal operator */
+ poselib_preview_init_data(C, op);
+ pld = (tPoseLib_PreviewData *)op->customdata;
- if (pld->state == PL_PREVIEW_ERROR) {
- /* an error occurred, so free temp mem used */
- poselib_preview_cleanup(C, op);
- return OPERATOR_CANCELLED;
- }
+ if (pld->state == PL_PREVIEW_ERROR) {
+ /* an error occurred, so free temp mem used */
+ poselib_preview_cleanup(C, op);
+ return OPERATOR_CANCELLED;
+ }
- /* the exec() callback is effectively a 'run-once' scenario, so set the state to that
- * so that everything draws correctly
- */
- pld->state = PL_PREVIEW_RUNONCE;
+ /* the exec() callback is effectively a 'run-once' scenario, so set the state to that
+ * so that everything draws correctly
+ */
+ pld->state = PL_PREVIEW_RUNONCE;
- /* apply the active pose */
- poselib_preview_apply(C, op);
+ /* apply the active pose */
+ poselib_preview_apply(C, op);
- /* now, set the status to exit */
- pld->state = PL_PREVIEW_CONFIRM;
+ /* now, set the status to exit */
+ pld->state = PL_PREVIEW_CONFIRM;
- /* cleanup */
- return poselib_preview_exit(C, op);
+ /* cleanup */
+ return poselib_preview_exit(C, op);
}
void POSELIB_OT_browse_interactive(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "PoseLib Browse Poses";
- ot->idname = "POSELIB_OT_browse_interactive";
- ot->description = "Interactively browse poses in 3D-View";
-
- /* callbacks */
- ot->invoke = poselib_preview_invoke;
- ot->modal = poselib_preview_modal;
- ot->cancel = poselib_preview_cancel;
- ot->exec = poselib_preview_exec;
- ot->poll = has_poselib_pose_data_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
-
- /* properties */
- // TODO: make the pose_index into a proper enum instead of a cryptic int...
- ot->prop = RNA_def_int(ot->srna, "pose_index", -1, -2, INT_MAX, "Pose", "Index of the pose to apply (-2 for no change to pose, -1 for poselib active pose)", 0, INT_MAX);
-
- // XXX: percentage vs factor?
- /* not used yet */
+ /* identifiers */
+ ot->name = "PoseLib Browse Poses";
+ ot->idname = "POSELIB_OT_browse_interactive";
+ ot->description = "Interactively browse poses in 3D-View";
+
+ /* callbacks */
+ ot->invoke = poselib_preview_invoke;
+ ot->modal = poselib_preview_modal;
+ ot->cancel = poselib_preview_cancel;
+ ot->exec = poselib_preview_exec;
+ ot->poll = has_poselib_pose_data_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ /* properties */
+ // TODO: make the pose_index into a proper enum instead of a cryptic int...
+ ot->prop = RNA_def_int(
+ ot->srna,
+ "pose_index",
+ -1,
+ -2,
+ INT_MAX,
+ "Pose",
+ "Index of the pose to apply (-2 for no change to pose, -1 for poselib active pose)",
+ 0,
+ INT_MAX);
+
+ // XXX: percentage vs factor?
+ /* not used yet */
#if 0
- RNA_def_float_factor(
- ot->srna, "blend_factor", 1.0f, 0.0f, 1.0f, "Blend Factor",
- "Amount that the pose is applied on top of the existing poses", 0.0f, 1.0f);
+ RNA_def_float_factor(
+ ot->srna, "blend_factor", 1.0f, 0.0f, 1.0f, "Blend Factor",
+ "Amount that the pose is applied on top of the existing poses", 0.0f, 1.0f);
#endif
}
void POSELIB_OT_apply_pose(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Apply Pose Library Pose";
- ot->idname = "POSELIB_OT_apply_pose";
- ot->description = "Apply specified Pose Library pose to the rig";
-
- /* callbacks */
- ot->exec = poselib_preview_exec;
- ot->poll = has_poselib_pose_data_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- /* TODO: make the pose_index into a proper enum instead of a cryptic int... */
- ot->prop = RNA_def_int(ot->srna, "pose_index", -1, -2, INT_MAX, "Pose", "Index of the pose to apply (-2 for no change to pose, -1 for poselib active pose)", 0, INT_MAX);
+ /* identifiers */
+ ot->name = "Apply Pose Library Pose";
+ ot->idname = "POSELIB_OT_apply_pose";
+ ot->description = "Apply specified Pose Library pose to the rig";
+
+ /* callbacks */
+ ot->exec = poselib_preview_exec;
+ ot->poll = has_poselib_pose_data_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ /* TODO: make the pose_index into a proper enum instead of a cryptic int... */
+ ot->prop = RNA_def_int(
+ ot->srna,
+ "pose_index",
+ -1,
+ -2,
+ INT_MAX,
+ "Pose",
+ "Index of the pose to apply (-2 for no change to pose, -1 for poselib active pose)",
+ 0,
+ INT_MAX);
}