1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup bke
22 */
23
24 #include <math.h>
25 #include <stddef.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "MEM_guardedalloc.h"
30
31 /* Allow using deprecated functionality for .blend file I/O. */
32 #define DNA_DEPRECATED_ALLOW
33
34 #include "DNA_anim_types.h"
35 #include "DNA_armature_types.h"
36 #include "DNA_constraint_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
39
40 #include "BLI_blenlib.h"
41 #include "BLI_ghash.h"
42 #include "BLI_math.h"
43 #include "BLI_session_uuid.h"
44 #include "BLI_string_utils.h"
45 #include "BLI_utildefines.h"
46
47 #include "BLT_translation.h"
48
49 #include "BKE_action.h"
50 #include "BKE_anim_data.h"
51 #include "BKE_anim_visualization.h"
52 #include "BKE_animsys.h"
53 #include "BKE_armature.h"
54 #include "BKE_constraint.h"
55 #include "BKE_deform.h"
56 #include "BKE_fcurve.h"
57 #include "BKE_idprop.h"
58 #include "BKE_idtype.h"
59 #include "BKE_lib_id.h"
60 #include "BKE_lib_query.h"
61 #include "BKE_main.h"
62 #include "BKE_object.h"
63
64 #include "DEG_depsgraph_build.h"
65
66 #include "BIK_api.h"
67
68 #include "RNA_access.h"
69
70 #include "BLO_read_write.h"
71
72 #include "CLG_log.h"
73
74 static CLG_LogRef LOG = {"bke.action"};
75
76 /* *********************** NOTE ON POSE AND ACTION **********************
77 *
78 * - Pose is the local (object level) component of armature. The current
79 * object pose is saved in files, and (will be) is presorted for dependency
80 * - Actions have fewer (or other) channels, and write data to a Pose
81 * - Currently ob->pose data is controlled in BKE_pose_where_is only. The (recalc)
82 * event system takes care of calling that
83 * - The NLA system (here too) uses Poses as interpolation format for Actions
84 * - Therefore we assume poses to be static, and duplicates of poses have channels in
85 * same order, for quick interpolation reasons
86 *
87 * ****************************** (ton) ************************************ */
88
89 /**************************** Action Datablock ******************************/
90
91 /*********************** Armature Datablock ***********************/
92
93 /**
94 * Only copy internal data of Action ID from source
95 * to already allocated/initialized destination.
96 * You probably never want to use that directly,
97 * use #BKE_id_copy or #BKE_id_copy_ex for typical needs.
98 *
99 * WARNING! This function will not handle ID user count!
100 *
101 * \param flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more).
102 */
action_copy_data(Main * UNUSED (bmain),ID * id_dst,const ID * id_src,const int UNUSED (flag))103 static void action_copy_data(Main *UNUSED(bmain),
104 ID *id_dst,
105 const ID *id_src,
106 const int UNUSED(flag))
107 {
108 bAction *action_dst = (bAction *)id_dst;
109 const bAction *action_src = (const bAction *)id_src;
110
111 bActionGroup *group_dst, *group_src;
112 FCurve *fcurve_dst, *fcurve_src;
113
114 /* Duplicate the lists of groups and markers. */
115 BLI_duplicatelist(&action_dst->groups, &action_src->groups);
116 BLI_duplicatelist(&action_dst->markers, &action_src->markers);
117
118 /* Copy F-Curves, fixing up the links as we go. */
119 BLI_listbase_clear(&action_dst->curves);
120
121 for (fcurve_src = action_src->curves.first; fcurve_src; fcurve_src = fcurve_src->next) {
122 /* Duplicate F-Curve. */
123
124 /* XXX TODO pass subdata flag?
125 * But surprisingly does not seem to be doing any ID refcounting... */
126 fcurve_dst = BKE_fcurve_copy(fcurve_src);
127
128 BLI_addtail(&action_dst->curves, fcurve_dst);
129
130 /* Fix group links (kindof bad list-in-list search, but this is the most reliable way). */
131 for (group_dst = action_dst->groups.first, group_src = action_src->groups.first;
132 group_dst && group_src;
133 group_dst = group_dst->next, group_src = group_src->next) {
134 if (fcurve_src->grp == group_src) {
135 fcurve_dst->grp = group_dst;
136
137 if (group_dst->channels.first == fcurve_src) {
138 group_dst->channels.first = fcurve_dst;
139 }
140 if (group_dst->channels.last == fcurve_src) {
141 group_dst->channels.last = fcurve_dst;
142 }
143 break;
144 }
145 }
146 }
147 }
148
149 /** Free (or release) any data used by this action (does not free the action itself). */
action_free_data(struct ID * id)150 static void action_free_data(struct ID *id)
151 {
152 bAction *action = (bAction *)id;
153 /* No animdata here. */
154
155 /* Free F-Curves. */
156 BKE_fcurves_free(&action->curves);
157
158 /* Free groups. */
159 BLI_freelistN(&action->groups);
160
161 /* Free pose-references (aka local markers). */
162 BLI_freelistN(&action->markers);
163 }
164
action_foreach_id(ID * id,LibraryForeachIDData * data)165 static void action_foreach_id(ID *id, LibraryForeachIDData *data)
166 {
167 bAction *act = (bAction *)id;
168
169 LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
170 BKE_fcurve_foreach_id(fcu, data);
171 }
172
173 LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
174 BKE_LIB_FOREACHID_PROCESS(data, marker->camera, IDWALK_CB_NOP);
175 }
176 }
177
action_blend_write(BlendWriter * writer,ID * id,const void * id_address)178 static void action_blend_write(BlendWriter *writer, ID *id, const void *id_address)
179 {
180 bAction *act = (bAction *)id;
181 if (act->id.us > 0 || BLO_write_is_undo(writer)) {
182 BLO_write_id_struct(writer, bAction, id_address, &act->id);
183 BKE_id_blend_write(writer, &act->id);
184
185 BKE_fcurve_blend_write(writer, &act->curves);
186
187 LISTBASE_FOREACH (bActionGroup *, grp, &act->groups) {
188 BLO_write_struct(writer, bActionGroup, grp);
189 }
190
191 LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
192 BLO_write_struct(writer, TimeMarker, marker);
193 }
194 }
195 }
196
action_blend_read_data(BlendDataReader * reader,ID * id)197 static void action_blend_read_data(BlendDataReader *reader, ID *id)
198 {
199 bAction *act = (bAction *)id;
200
201 BLO_read_list(reader, &act->curves);
202 BLO_read_list(reader, &act->chanbase); /* XXX deprecated - old animation system */
203 BLO_read_list(reader, &act->groups);
204 BLO_read_list(reader, &act->markers);
205
206 /* XXX deprecated - old animation system <<< */
207 LISTBASE_FOREACH (bActionChannel *, achan, &act->chanbase) {
208 BLO_read_data_address(reader, &achan->grp);
209
210 BLO_read_list(reader, &achan->constraintChannels);
211 }
212 /* >>> XXX deprecated - old animation system */
213
214 BKE_fcurve_blend_read_data(reader, &act->curves);
215
216 LISTBASE_FOREACH (bActionGroup *, agrp, &act->groups) {
217 BLO_read_data_address(reader, &agrp->channels.first);
218 BLO_read_data_address(reader, &agrp->channels.last);
219 }
220 }
221
blend_read_lib_constraint_channels(BlendLibReader * reader,ID * id,ListBase * chanbase)222 static void blend_read_lib_constraint_channels(BlendLibReader *reader, ID *id, ListBase *chanbase)
223 {
224 LISTBASE_FOREACH (bConstraintChannel *, chan, chanbase) {
225 BLO_read_id_address(reader, id->lib, &chan->ipo);
226 }
227 }
228
action_blend_read_lib(BlendLibReader * reader,ID * id)229 static void action_blend_read_lib(BlendLibReader *reader, ID *id)
230 {
231 bAction *act = (bAction *)id;
232
233 /* XXX deprecated - old animation system <<< */
234 LISTBASE_FOREACH (bActionChannel *, chan, &act->chanbase) {
235 BLO_read_id_address(reader, act->id.lib, &chan->ipo);
236 blend_read_lib_constraint_channels(reader, &act->id, &chan->constraintChannels);
237 }
238 /* >>> XXX deprecated - old animation system */
239
240 BKE_fcurve_blend_read_lib(reader, &act->id, &act->curves);
241
242 LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
243 if (marker->camera) {
244 BLO_read_id_address(reader, act->id.lib, &marker->camera);
245 }
246 }
247 }
248
blend_read_expand_constraint_channels(BlendExpander * expander,ListBase * chanbase)249 static void blend_read_expand_constraint_channels(BlendExpander *expander, ListBase *chanbase)
250 {
251 LISTBASE_FOREACH (bConstraintChannel *, chan, chanbase) {
252 BLO_expand(expander, chan->ipo);
253 }
254 }
255
action_blend_read_expand(BlendExpander * expander,ID * id)256 static void action_blend_read_expand(BlendExpander *expander, ID *id)
257 {
258 bAction *act = (bAction *)id;
259
260 /* XXX deprecated - old animation system -------------- */
261 LISTBASE_FOREACH (bActionChannel *, chan, &act->chanbase) {
262 BLO_expand(expander, chan->ipo);
263 blend_read_expand_constraint_channels(expander, &chan->constraintChannels);
264 }
265 /* --------------------------------------------------- */
266
267 /* F-Curves in Action */
268 BKE_fcurve_blend_read_expand(expander, &act->curves);
269
270 LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
271 if (marker->camera) {
272 BLO_expand(expander, marker->camera);
273 }
274 }
275 }
276
277 IDTypeInfo IDType_ID_AC = {
278 .id_code = ID_AC,
279 .id_filter = FILTER_ID_AC,
280 .main_listbase_index = INDEX_ID_AC,
281 .struct_size = sizeof(bAction),
282 .name = "Action",
283 .name_plural = "actions",
284 .translation_context = BLT_I18NCONTEXT_ID_ACTION,
285 .flags = IDTYPE_FLAGS_NO_ANIMDATA,
286
287 .init_data = NULL,
288 .copy_data = action_copy_data,
289 .free_data = action_free_data,
290 .make_local = NULL,
291 .foreach_id = action_foreach_id,
292 .foreach_cache = NULL,
293
294 .blend_write = action_blend_write,
295 .blend_read_data = action_blend_read_data,
296 .blend_read_lib = action_blend_read_lib,
297 .blend_read_expand = action_blend_read_expand,
298 };
299
300 /* ***************** Library data level operations on action ************** */
301
BKE_action_add(Main * bmain,const char name[])302 bAction *BKE_action_add(Main *bmain, const char name[])
303 {
304 bAction *act;
305
306 act = BKE_id_new(bmain, ID_AC, name);
307
308 return act;
309 }
310
311 /* .................................. */
312
313 /* *************** Action Groups *************** */
314
315 /* Get the active action-group for an Action */
get_active_actiongroup(bAction * act)316 bActionGroup *get_active_actiongroup(bAction *act)
317 {
318 bActionGroup *agrp = NULL;
319
320 if (act && act->groups.first) {
321 for (agrp = act->groups.first; agrp; agrp = agrp->next) {
322 if (agrp->flag & AGRP_ACTIVE) {
323 break;
324 }
325 }
326 }
327
328 return agrp;
329 }
330
331 /* Make the given Action-Group the active one */
set_active_action_group(bAction * act,bActionGroup * agrp,short select)332 void set_active_action_group(bAction *act, bActionGroup *agrp, short select)
333 {
334 bActionGroup *grp;
335
336 /* sanity checks */
337 if (act == NULL) {
338 return;
339 }
340
341 /* Deactivate all others */
342 for (grp = act->groups.first; grp; grp = grp->next) {
343 if ((grp == agrp) && (select)) {
344 grp->flag |= AGRP_ACTIVE;
345 }
346 else {
347 grp->flag &= ~AGRP_ACTIVE;
348 }
349 }
350 }
351
352 /* Sync colors used for action/bone group with theme settings */
action_group_colors_sync(bActionGroup * grp,const bActionGroup * ref_grp)353 void action_group_colors_sync(bActionGroup *grp, const bActionGroup *ref_grp)
354 {
355 /* only do color copying if using a custom color (i.e. not default color) */
356 if (grp->customCol) {
357 if (grp->customCol > 0) {
358 /* copy theme colors on-to group's custom color in case user tries to edit color */
359 bTheme *btheme = U.themes.first;
360 ThemeWireColor *col_set = &btheme->tarm[(grp->customCol - 1)];
361
362 memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
363 }
364 else {
365 /* if a reference group is provided, use the custom color from there... */
366 if (ref_grp) {
367 /* assumption: reference group has a color set */
368 memcpy(&grp->cs, &ref_grp->cs, sizeof(ThemeWireColor));
369 }
370 /* otherwise, init custom color with a generic/placeholder color set if
371 * no previous theme color was used that we can just keep using
372 */
373 else if (grp->cs.solid[0] == 0) {
374 /* define for setting colors in theme below */
375 rgba_uchar_args_set(grp->cs.solid, 0xff, 0x00, 0x00, 255);
376 rgba_uchar_args_set(grp->cs.select, 0x81, 0xe6, 0x14, 255);
377 rgba_uchar_args_set(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
378 }
379 }
380 }
381 }
382
383 /* Add a new action group with the given name to the action */
action_groups_add_new(bAction * act,const char name[])384 bActionGroup *action_groups_add_new(bAction *act, const char name[])
385 {
386 bActionGroup *agrp;
387
388 /* sanity check: must have action and name */
389 if (ELEM(NULL, act, name)) {
390 return NULL;
391 }
392
393 /* allocate a new one */
394 agrp = MEM_callocN(sizeof(bActionGroup), "bActionGroup");
395
396 /* make it selected, with default name */
397 agrp->flag = AGRP_SELECTED;
398 BLI_strncpy(agrp->name, name[0] ? name : DATA_("Group"), sizeof(agrp->name));
399
400 /* add to action, and validate */
401 BLI_addtail(&act->groups, agrp);
402 BLI_uniquename(
403 &act->groups, agrp, DATA_("Group"), '.', offsetof(bActionGroup, name), sizeof(agrp->name));
404
405 /* return the new group */
406 return agrp;
407 }
408
409 /* Add given channel into (active) group
410 * - assumes that channel is not linked to anything anymore
411 * - always adds at the end of the group
412 */
action_groups_add_channel(bAction * act,bActionGroup * agrp,FCurve * fcurve)413 void action_groups_add_channel(bAction *act, bActionGroup *agrp, FCurve *fcurve)
414 {
415 /* sanity checks */
416 if (ELEM(NULL, act, agrp, fcurve)) {
417 return;
418 }
419
420 /* if no channels anywhere, just add to two lists at the same time */
421 if (BLI_listbase_is_empty(&act->curves)) {
422 fcurve->next = fcurve->prev = NULL;
423
424 agrp->channels.first = agrp->channels.last = fcurve;
425 act->curves.first = act->curves.last = fcurve;
426 }
427
428 /* if the group already has channels, the F-Curve can simply be added to the list
429 * (i.e. as the last channel in the group)
430 */
431 else if (agrp->channels.first) {
432 /* if the group's last F-Curve is the action's last F-Curve too,
433 * then set the F-Curve as the last for the action first so that
434 * the lists will be in sync after linking
435 */
436 if (agrp->channels.last == act->curves.last) {
437 act->curves.last = fcurve;
438 }
439
440 /* link in the given F-Curve after the last F-Curve in the group,
441 * which means that it should be able to fit in with the rest of the
442 * list seamlessly
443 */
444 BLI_insertlinkafter(&agrp->channels, agrp->channels.last, fcurve);
445 }
446
447 /* otherwise, need to find the nearest F-Curve in group before/after current to link with */
448 else {
449 bActionGroup *grp;
450
451 /* firstly, link this F-Curve to the group */
452 agrp->channels.first = agrp->channels.last = fcurve;
453
454 /* Step through the groups preceding this one,
455 * finding the F-Curve there to attach this one after. */
456 for (grp = agrp->prev; grp; grp = grp->prev) {
457 /* if this group has F-Curves, we want weave the given one in right after the last channel
458 * there, but via the Action's list not this group's list
459 * - this is so that the F-Curve is in the right place in the Action,
460 * but won't be included in the previous group.
461 */
462 if (grp->channels.last) {
463 /* once we've added, break here since we don't need to search any further... */
464 BLI_insertlinkafter(&act->curves, grp->channels.last, fcurve);
465 break;
466 }
467 }
468
469 /* If grp is NULL, that means we fell through, and this F-Curve should be added as the new
470 * first since group is (effectively) the first group. Thus, the existing first F-Curve becomes
471 * the second in the chain, etc. etc.
472 */
473 if (grp == NULL) {
474 BLI_insertlinkbefore(&act->curves, act->curves.first, fcurve);
475 }
476 }
477
478 /* set the F-Curve's new group */
479 fcurve->grp = agrp;
480 }
481
482 /* Reconstruct group channel pointers.
483 * Assumes that the channels are still in the proper order, i.e. that channels of the same group
484 * are adjacent in the act->channels list. It also assumes that the groups
485 * referred to by the FCurves are already in act->groups.
486 */
BKE_action_groups_reconstruct(bAction * act)487 void BKE_action_groups_reconstruct(bAction *act)
488 {
489 /* Sanity check. */
490 if (ELEM(NULL, act, act->groups.first)) {
491 return;
492 }
493
494 /* Clear out all group channels. Channels that are actually in use are
495 * reconstructed below; this step is necessary to clear out unused groups. */
496 LISTBASE_FOREACH (bActionGroup *, group, &act->groups) {
497 BLI_listbase_clear(&group->channels);
498 }
499
500 bActionGroup *grp;
501 bActionGroup *last_grp = NULL;
502 LISTBASE_FOREACH (FCurve *, fcurve, &act->curves) {
503 if (fcurve->grp == NULL) {
504 continue;
505 }
506
507 grp = fcurve->grp;
508 if (last_grp != grp) {
509 /* If this is the first time we see this group, this must be the first channel. */
510 grp->channels.first = fcurve;
511 }
512
513 /* This is the last channel, until it's overwritten by a later iteration. */
514 grp->channels.last = fcurve;
515 last_grp = grp;
516 }
517 }
518
519 /* Remove the given channel from all groups */
action_groups_remove_channel(bAction * act,FCurve * fcu)520 void action_groups_remove_channel(bAction *act, FCurve *fcu)
521 {
522 /* sanity checks */
523 if (ELEM(NULL, act, fcu)) {
524 return;
525 }
526
527 /* check if any group used this directly */
528 if (fcu->grp) {
529 bActionGroup *agrp = fcu->grp;
530
531 if (agrp->channels.first == agrp->channels.last) {
532 if (agrp->channels.first == fcu) {
533 BLI_listbase_clear(&agrp->channels);
534 }
535 }
536 else if (agrp->channels.first == fcu) {
537 if ((fcu->next) && (fcu->next->grp == agrp)) {
538 agrp->channels.first = fcu->next;
539 }
540 else {
541 agrp->channels.first = NULL;
542 }
543 }
544 else if (agrp->channels.last == fcu) {
545 if ((fcu->prev) && (fcu->prev->grp == agrp)) {
546 agrp->channels.last = fcu->prev;
547 }
548 else {
549 agrp->channels.last = NULL;
550 }
551 }
552
553 fcu->grp = NULL;
554 }
555
556 /* now just remove from list */
557 BLI_remlink(&act->curves, fcu);
558 }
559
560 /* Find a group with the given name */
BKE_action_group_find_name(bAction * act,const char name[])561 bActionGroup *BKE_action_group_find_name(bAction *act, const char name[])
562 {
563 /* sanity checks */
564 if (ELEM(NULL, act, act->groups.first, name) || (name[0] == 0)) {
565 return NULL;
566 }
567
568 /* do string comparisons */
569 return BLI_findstring(&act->groups, name, offsetof(bActionGroup, name));
570 }
571
572 /* Clear all 'temp' flags on all groups */
action_groups_clear_tempflags(bAction * act)573 void action_groups_clear_tempflags(bAction *act)
574 {
575 bActionGroup *agrp;
576
577 /* sanity checks */
578 if (ELEM(NULL, act, act->groups.first)) {
579 return;
580 }
581
582 /* flag clearing loop */
583 for (agrp = act->groups.first; agrp; agrp = agrp->next) {
584 agrp->flag &= ~AGRP_TEMP;
585 }
586 }
587
588 /* *************** Pose channels *************** */
589
BKE_pose_channel_session_uuid_generate(bPoseChannel * pchan)590 void BKE_pose_channel_session_uuid_generate(bPoseChannel *pchan)
591 {
592 pchan->runtime.session_uuid = BLI_session_uuid_generate();
593 }
594
595 /**
596 * Return a pointer to the pose channel of the given name
597 * from this pose.
598 */
BKE_pose_channel_find_name(const bPose * pose,const char * name)599 bPoseChannel *BKE_pose_channel_find_name(const bPose *pose, const char *name)
600 {
601 if (ELEM(NULL, pose, name) || (name[0] == '\0')) {
602 return NULL;
603 }
604
605 if (pose->chanhash) {
606 return BLI_ghash_lookup(pose->chanhash, (const void *)name);
607 }
608
609 return BLI_findstring(&((const bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name));
610 }
611
612 /**
613 * Looks to see if the channel with the given name
614 * already exists in this pose - if not a new one is
615 * allocated and initialized.
616 *
617 * \note Use with care, not on Armature poses but for temporal ones.
618 * \note (currently used for action constraints and in rebuild_pose).
619 */
BKE_pose_channel_verify(bPose * pose,const char * name)620 bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name)
621 {
622 bPoseChannel *chan;
623
624 if (pose == NULL) {
625 return NULL;
626 }
627
628 /* See if this channel exists */
629 chan = BKE_pose_channel_find_name(pose, name);
630 if (chan) {
631 return chan;
632 }
633
634 /* If not, create it and add it */
635 chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
636
637 BKE_pose_channel_session_uuid_generate(chan);
638
639 BLI_strncpy(chan->name, name, sizeof(chan->name));
640
641 chan->custom_scale = 1.0f;
642
643 /* init vars to prevent math errors */
644 unit_qt(chan->quat);
645 unit_axis_angle(chan->rotAxis, &chan->rotAngle);
646 chan->size[0] = chan->size[1] = chan->size[2] = 1.0f;
647
648 chan->scale_in_x = chan->scale_in_y = 1.0f;
649 chan->scale_out_x = chan->scale_out_y = 1.0f;
650
651 chan->limitmin[0] = chan->limitmin[1] = chan->limitmin[2] = -M_PI;
652 chan->limitmax[0] = chan->limitmax[1] = chan->limitmax[2] = M_PI;
653 chan->stiffness[0] = chan->stiffness[1] = chan->stiffness[2] = 0.0f;
654 chan->ikrotweight = chan->iklinweight = 0.0f;
655 unit_m4(chan->constinv);
656
657 chan->protectflag = OB_LOCK_ROT4D; /* lock by components by default */
658
659 BLI_addtail(&pose->chanbase, chan);
660 if (pose->chanhash) {
661 BLI_ghash_insert(pose->chanhash, chan->name, chan);
662 }
663
664 return chan;
665 }
666
667 #ifndef NDEBUG
BKE_pose_channels_is_valid(const bPose * pose)668 bool BKE_pose_channels_is_valid(const bPose *pose)
669 {
670 if (pose->chanhash) {
671 bPoseChannel *pchan;
672 for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
673 if (BLI_ghash_lookup(pose->chanhash, pchan->name) != pchan) {
674 return false;
675 }
676 }
677 }
678
679 return true;
680 }
681
682 #endif
683
684 /**
685 * Find the active pose-channel for an object
686 * (we can't just use pose, as layer info is in armature)
687 *
688 * \note #Object, not #bPose is used here, as we need layer info from Armature.
689 */
BKE_pose_channel_active(Object * ob)690 bPoseChannel *BKE_pose_channel_active(Object *ob)
691 {
692 bArmature *arm = (ob) ? ob->data : NULL;
693 bPoseChannel *pchan;
694
695 if (ELEM(NULL, ob, ob->pose, arm)) {
696 return NULL;
697 }
698
699 /* find active */
700 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
701 if ((pchan->bone) && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer)) {
702 return pchan;
703 }
704 }
705
706 return NULL;
707 }
708
709 /**
710 * Use this when detecting the "other selected bone",
711 * when we have multiple armatures in pose mode.
712 *
713 * In this case the active-selected is an obvious choice when finding the target for a
714 * constraint for eg. however from the users perspective the active pose bone of the
715 * active object is the _real_ active bone, so any other non-active selected bone
716 * is a candidate for being the other selected bone, see: T58447.
717 */
BKE_pose_channel_active_or_first_selected(struct Object * ob)718 bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob)
719 {
720 bArmature *arm = (ob) ? ob->data : NULL;
721
722 if (ELEM(NULL, ob, ob->pose, arm)) {
723 return NULL;
724 }
725
726 bPoseChannel *pchan = BKE_pose_channel_active(ob);
727 if (pchan && (pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone)) {
728 return pchan;
729 }
730
731 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
732 if (pchan->bone != NULL) {
733 if ((pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone)) {
734 return pchan;
735 }
736 }
737 }
738 return NULL;
739 }
740
741 /**
742 * \see #ED_armature_ebone_get_mirrored (edit-mode, matching function)
743 */
BKE_pose_channel_get_mirrored(const bPose * pose,const char * name)744 bPoseChannel *BKE_pose_channel_get_mirrored(const bPose *pose, const char *name)
745 {
746 char name_flip[MAXBONENAME];
747
748 BLI_string_flip_side_name(name_flip, name, false, sizeof(name_flip));
749
750 if (!STREQ(name_flip, name)) {
751 return BKE_pose_channel_find_name(pose, name_flip);
752 }
753
754 return NULL;
755 }
756
BKE_pose_ikparam_get_name(bPose * pose)757 const char *BKE_pose_ikparam_get_name(bPose *pose)
758 {
759 if (pose) {
760 switch (pose->iksolver) {
761 case IKSOLVER_STANDARD:
762 return NULL;
763 case IKSOLVER_ITASC:
764 return "bItasc";
765 }
766 }
767 return NULL;
768 }
769
770 /**
771 * Allocate a new pose on the heap, and copy the src pose and its channels
772 * into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL.
773 *
774 * \param dst: Should be freed already, makes entire duplicate.
775 */
BKE_pose_copy_data_ex(bPose ** dst,const bPose * src,const int flag,const bool copy_constraints)776 void BKE_pose_copy_data_ex(bPose **dst,
777 const bPose *src,
778 const int flag,
779 const bool copy_constraints)
780 {
781 bPose *outPose;
782 bPoseChannel *pchan;
783 ListBase listb;
784
785 if (!src) {
786 *dst = NULL;
787 return;
788 }
789
790 outPose = MEM_callocN(sizeof(bPose), "pose");
791
792 BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
793
794 /* Rebuild ghash here too, so that name lookups below won't be too bad...
795 * BUT this will have the penalty that the ghash will be built twice
796 * if BKE_pose_rebuild() gets called after this...
797 */
798 if (outPose->chanbase.first != outPose->chanbase.last) {
799 outPose->chanhash = NULL;
800 BKE_pose_channels_hash_make(outPose);
801 }
802
803 outPose->iksolver = src->iksolver;
804 outPose->ikdata = NULL;
805 outPose->ikparam = MEM_dupallocN(src->ikparam);
806 outPose->avs = src->avs;
807
808 for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
809 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
810 id_us_plus((ID *)pchan->custom);
811 }
812
813 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
814 BKE_pose_channel_session_uuid_generate(pchan);
815 }
816
817 /* warning, O(n2) here, if done without the hash, but these are rarely used features. */
818 if (pchan->custom_tx) {
819 pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name);
820 }
821 if (pchan->bbone_prev) {
822 pchan->bbone_prev = BKE_pose_channel_find_name(outPose, pchan->bbone_prev->name);
823 }
824 if (pchan->bbone_next) {
825 pchan->bbone_next = BKE_pose_channel_find_name(outPose, pchan->bbone_next->name);
826 }
827
828 if (copy_constraints) {
829 BKE_constraints_copy_ex(
830 &listb, &pchan->constraints, flag, true); /* BKE_constraints_copy NULLs listb */
831 pchan->constraints = listb;
832
833 /* XXX: This is needed for motionpath drawing to work.
834 * Dunno why it was setting to null before... */
835 pchan->mpath = animviz_copy_motionpath(pchan->mpath);
836 }
837
838 if (pchan->prop) {
839 pchan->prop = IDP_CopyProperty_ex(pchan->prop, flag);
840 }
841
842 pchan->draw_data = NULL; /* Drawing cache, no need to copy. */
843
844 /* Runtime data, no need to copy. */
845 BKE_pose_channel_runtime_reset_on_copy(&pchan->runtime);
846 }
847
848 /* for now, duplicate Bone Groups too when doing this */
849 if (copy_constraints) {
850 BLI_duplicatelist(&outPose->agroups, &src->agroups);
851 }
852
853 *dst = outPose;
854 }
855
BKE_pose_copy_data(bPose ** dst,const bPose * src,const bool copy_constraints)856 void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints)
857 {
858 BKE_pose_copy_data_ex(dst, src, 0, copy_constraints);
859 }
860
BKE_pose_itasc_init(bItasc * itasc)861 void BKE_pose_itasc_init(bItasc *itasc)
862 {
863 if (itasc) {
864 itasc->iksolver = IKSOLVER_ITASC;
865 itasc->minstep = 0.01f;
866 itasc->maxstep = 0.06f;
867 itasc->numiter = 100;
868 itasc->numstep = 4;
869 itasc->precision = 0.005f;
870 itasc->flag = ITASC_AUTO_STEP | ITASC_INITIAL_REITERATION;
871 itasc->feedback = 20.0f;
872 itasc->maxvel = 50.0f;
873 itasc->solver = ITASC_SOLVER_SDLS;
874 itasc->dampmax = 0.5;
875 itasc->dampeps = 0.15;
876 }
877 }
BKE_pose_ikparam_init(bPose * pose)878 void BKE_pose_ikparam_init(bPose *pose)
879 {
880 bItasc *itasc;
881 switch (pose->iksolver) {
882 case IKSOLVER_ITASC:
883 itasc = MEM_callocN(sizeof(bItasc), "itasc");
884 BKE_pose_itasc_init(itasc);
885 pose->ikparam = itasc;
886 break;
887 case IKSOLVER_STANDARD:
888 default:
889 pose->ikparam = NULL;
890 break;
891 }
892 }
893
894 /* only for real IK, not for auto-IK */
pose_channel_in_IK_chain(Object * ob,bPoseChannel * pchan,int level)895 static bool pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan, int level)
896 {
897 bConstraint *con;
898 Bone *bone;
899
900 /* No need to check if constraint is active (has influence),
901 * since all constraints with CONSTRAINT_IK_AUTO are active */
902 for (con = pchan->constraints.first; con; con = con->next) {
903 if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
904 bKinematicConstraint *data = con->data;
905 if ((data->rootbone == 0) || (data->rootbone > level)) {
906 if ((data->flag & CONSTRAINT_IK_AUTO) == 0) {
907 return true;
908 }
909 }
910 }
911 }
912 for (bone = pchan->bone->childbase.first; bone; bone = bone->next) {
913 pchan = BKE_pose_channel_find_name(ob->pose, bone->name);
914 if (pchan && pose_channel_in_IK_chain(ob, pchan, level + 1)) {
915 return true;
916 }
917 }
918 return false;
919 }
920
BKE_pose_channel_in_IK_chain(Object * ob,bPoseChannel * pchan)921 bool BKE_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
922 {
923 return pose_channel_in_IK_chain(ob, pchan, 0);
924 }
925
926 /**
927 * Removes the hash for quick lookup of channels, must
928 * be done when adding/removing channels.
929 */
BKE_pose_channels_hash_make(bPose * pose)930 void BKE_pose_channels_hash_make(bPose *pose)
931 {
932 if (!pose->chanhash) {
933 bPoseChannel *pchan;
934
935 pose->chanhash = BLI_ghash_str_new("make_pose_chan gh");
936 for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
937 BLI_ghash_insert(pose->chanhash, pchan->name, pchan);
938 }
939 }
940 }
941
BKE_pose_channels_hash_free(bPose * pose)942 void BKE_pose_channels_hash_free(bPose *pose)
943 {
944 if (pose->chanhash) {
945 BLI_ghash_free(pose->chanhash, NULL, NULL);
946 pose->chanhash = NULL;
947 }
948 }
949
pose_channels_remove_internal_links(Object * ob,bPoseChannel * unlinked_pchan)950 static void pose_channels_remove_internal_links(Object *ob, bPoseChannel *unlinked_pchan)
951 {
952 LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
953 if (pchan->bbone_prev == unlinked_pchan) {
954 pchan->bbone_prev = NULL;
955 }
956 if (pchan->bbone_next == unlinked_pchan) {
957 pchan->bbone_next = NULL;
958 }
959 if (pchan->custom_tx == unlinked_pchan) {
960 pchan->custom_tx = NULL;
961 }
962 }
963 }
964
965 /**
966 * Selectively remove pose channels.
967 */
BKE_pose_channels_remove(Object * ob,bool (* filter_fn)(const char * bone_name,void * user_data),void * user_data)968 void BKE_pose_channels_remove(Object *ob,
969 bool (*filter_fn)(const char *bone_name, void *user_data),
970 void *user_data)
971 {
972 /* Erase any associated pose channel, along with any references to them */
973 if (ob->pose) {
974 bPoseChannel *pchan, *pchan_next;
975 bConstraint *con;
976
977 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan_next) {
978 pchan_next = pchan->next;
979
980 if (filter_fn(pchan->name, user_data)) {
981 /* Bone itself is being removed */
982 BKE_pose_channel_free(pchan);
983 pose_channels_remove_internal_links(ob, pchan);
984 if (ob->pose->chanhash) {
985 BLI_ghash_remove(ob->pose->chanhash, pchan->name, NULL, NULL);
986 }
987 BLI_freelinkN(&ob->pose->chanbase, pchan);
988 }
989 else {
990 /* Maybe something the bone references is being removed instead? */
991 for (con = pchan->constraints.first; con; con = con->next) {
992 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
993 ListBase targets = {NULL, NULL};
994 bConstraintTarget *ct;
995
996 if (cti && cti->get_constraint_targets) {
997 cti->get_constraint_targets(con, &targets);
998
999 for (ct = targets.first; ct; ct = ct->next) {
1000 if (ct->tar == ob) {
1001 if (ct->subtarget[0]) {
1002 if (filter_fn(ct->subtarget, user_data)) {
1003 con->flag |= CONSTRAINT_DISABLE;
1004 ct->subtarget[0] = 0;
1005 }
1006 }
1007 }
1008 }
1009
1010 if (cti->flush_constraint_targets) {
1011 cti->flush_constraint_targets(con, &targets, 0);
1012 }
1013 }
1014 }
1015
1016 if (pchan->bbone_prev) {
1017 if (filter_fn(pchan->bbone_prev->name, user_data)) {
1018 pchan->bbone_prev = NULL;
1019 }
1020 }
1021 if (pchan->bbone_next) {
1022 if (filter_fn(pchan->bbone_next->name, user_data)) {
1023 pchan->bbone_next = NULL;
1024 }
1025 }
1026
1027 if (pchan->custom_tx) {
1028 if (filter_fn(pchan->custom_tx->name, user_data)) {
1029 pchan->custom_tx = NULL;
1030 }
1031 }
1032 }
1033 }
1034 }
1035 }
1036
1037 /**
1038 * Deallocates a pose channel.
1039 * Does not free the pose channel itself.
1040 */
BKE_pose_channel_free_ex(bPoseChannel * pchan,bool do_id_user)1041 void BKE_pose_channel_free_ex(bPoseChannel *pchan, bool do_id_user)
1042 {
1043 if (pchan->custom) {
1044 if (do_id_user) {
1045 id_us_min(&pchan->custom->id);
1046 }
1047 pchan->custom = NULL;
1048 }
1049
1050 if (pchan->mpath) {
1051 animviz_free_motionpath(pchan->mpath);
1052 pchan->mpath = NULL;
1053 }
1054
1055 BKE_constraints_free_ex(&pchan->constraints, do_id_user);
1056
1057 if (pchan->prop) {
1058 IDP_FreeProperty_ex(pchan->prop, do_id_user);
1059 pchan->prop = NULL;
1060 }
1061
1062 /* Cached data, for new draw manager rendering code. */
1063 MEM_SAFE_FREE(pchan->draw_data);
1064
1065 /* Cached B-Bone shape and other data. */
1066 BKE_pose_channel_runtime_free(&pchan->runtime);
1067 }
1068
1069 /** Clears the runtime cache of a pose channel without free. */
BKE_pose_channel_runtime_reset(bPoseChannel_Runtime * runtime)1070 void BKE_pose_channel_runtime_reset(bPoseChannel_Runtime *runtime)
1071 {
1072 memset(runtime, 0, sizeof(*runtime));
1073 }
1074
1075 /* Reset all non-persistent fields. */
BKE_pose_channel_runtime_reset_on_copy(bPoseChannel_Runtime * runtime)1076 void BKE_pose_channel_runtime_reset_on_copy(bPoseChannel_Runtime *runtime)
1077 {
1078 const SessionUUID uuid = runtime->session_uuid;
1079 memset(runtime, 0, sizeof(*runtime));
1080 runtime->session_uuid = uuid;
1081 }
1082
1083 /** Deallocates runtime cache of a pose channel */
BKE_pose_channel_runtime_free(bPoseChannel_Runtime * runtime)1084 void BKE_pose_channel_runtime_free(bPoseChannel_Runtime *runtime)
1085 {
1086 BKE_pose_channel_free_bbone_cache(runtime);
1087 }
1088
1089 /** Deallocates runtime cache of a pose channel's B-Bone shape. */
BKE_pose_channel_free_bbone_cache(bPoseChannel_Runtime * runtime)1090 void BKE_pose_channel_free_bbone_cache(bPoseChannel_Runtime *runtime)
1091 {
1092 runtime->bbone_segments = 0;
1093 MEM_SAFE_FREE(runtime->bbone_rest_mats);
1094 MEM_SAFE_FREE(runtime->bbone_pose_mats);
1095 MEM_SAFE_FREE(runtime->bbone_deform_mats);
1096 MEM_SAFE_FREE(runtime->bbone_dual_quats);
1097 }
1098
BKE_pose_channel_free(bPoseChannel * pchan)1099 void BKE_pose_channel_free(bPoseChannel *pchan)
1100 {
1101 BKE_pose_channel_free_ex(pchan, true);
1102 }
1103
1104 /**
1105 * Removes and deallocates all channels from a pose.
1106 * Does not free the pose itself.
1107 */
BKE_pose_channels_free_ex(bPose * pose,bool do_id_user)1108 void BKE_pose_channels_free_ex(bPose *pose, bool do_id_user)
1109 {
1110 bPoseChannel *pchan;
1111
1112 if (pose->chanbase.first) {
1113 for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
1114 BKE_pose_channel_free_ex(pchan, do_id_user);
1115 }
1116
1117 BLI_freelistN(&pose->chanbase);
1118 }
1119
1120 BKE_pose_channels_hash_free(pose);
1121
1122 MEM_SAFE_FREE(pose->chan_array);
1123 }
1124
BKE_pose_channels_free(bPose * pose)1125 void BKE_pose_channels_free(bPose *pose)
1126 {
1127 BKE_pose_channels_free_ex(pose, true);
1128 }
1129
BKE_pose_free_data_ex(bPose * pose,bool do_id_user)1130 void BKE_pose_free_data_ex(bPose *pose, bool do_id_user)
1131 {
1132 /* free pose-channels */
1133 BKE_pose_channels_free_ex(pose, do_id_user);
1134
1135 /* free pose-groups */
1136 if (pose->agroups.first) {
1137 BLI_freelistN(&pose->agroups);
1138 }
1139
1140 /* free IK solver state */
1141 BIK_clear_data(pose);
1142
1143 /* free IK solver param */
1144 if (pose->ikparam) {
1145 MEM_freeN(pose->ikparam);
1146 }
1147 }
1148
BKE_pose_free_data(bPose * pose)1149 void BKE_pose_free_data(bPose *pose)
1150 {
1151 BKE_pose_free_data_ex(pose, true);
1152 }
1153
1154 /**
1155 * Removes and deallocates all data from a pose, and also frees the pose.
1156 */
BKE_pose_free_ex(bPose * pose,bool do_id_user)1157 void BKE_pose_free_ex(bPose *pose, bool do_id_user)
1158 {
1159 if (pose) {
1160 BKE_pose_free_data_ex(pose, do_id_user);
1161 /* free pose */
1162 MEM_freeN(pose);
1163 }
1164 }
1165
BKE_pose_free(bPose * pose)1166 void BKE_pose_free(bPose *pose)
1167 {
1168 BKE_pose_free_ex(pose, true);
1169 }
1170
1171 /**
1172 * Copy the internal members of each pose channel including constraints
1173 * and ID-Props, used when duplicating bones in editmode.
1174 * (unlike copy_pose_channel_data which only does posing-related stuff).
1175 *
1176 * \note use when copying bones in editmode (on returned value from #BKE_pose_channel_verify)
1177 */
BKE_pose_channel_copy_data(bPoseChannel * pchan,const bPoseChannel * pchan_from)1178 void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_from)
1179 {
1180 /* copy transform locks */
1181 pchan->protectflag = pchan_from->protectflag;
1182
1183 /* copy rotation mode */
1184 pchan->rotmode = pchan_from->rotmode;
1185
1186 /* copy bone group */
1187 pchan->agrp_index = pchan_from->agrp_index;
1188
1189 /* ik (dof) settings */
1190 pchan->ikflag = pchan_from->ikflag;
1191 copy_v3_v3(pchan->limitmin, pchan_from->limitmin);
1192 copy_v3_v3(pchan->limitmax, pchan_from->limitmax);
1193 copy_v3_v3(pchan->stiffness, pchan_from->stiffness);
1194 pchan->ikstretch = pchan_from->ikstretch;
1195 pchan->ikrotweight = pchan_from->ikrotweight;
1196 pchan->iklinweight = pchan_from->iklinweight;
1197
1198 /* bbone settings (typically not animated) */
1199 pchan->bbone_next = pchan_from->bbone_next;
1200 pchan->bbone_prev = pchan_from->bbone_prev;
1201
1202 /* constraints */
1203 BKE_constraints_copy(&pchan->constraints, &pchan_from->constraints, true);
1204
1205 /* id-properties */
1206 if (pchan->prop) {
1207 /* unlikely but possible it exists */
1208 IDP_FreeProperty(pchan->prop);
1209 pchan->prop = NULL;
1210 }
1211 if (pchan_from->prop) {
1212 pchan->prop = IDP_CopyProperty(pchan_from->prop);
1213 }
1214
1215 /* custom shape */
1216 pchan->custom = pchan_from->custom;
1217 if (pchan->custom) {
1218 id_us_plus(&pchan->custom->id);
1219 }
1220
1221 pchan->custom_scale = pchan_from->custom_scale;
1222 pchan->drawflag = pchan_from->drawflag;
1223 }
1224
1225 /* checks for IK constraint, Spline IK, and also for Follow-Path constraint.
1226 * can do more constraints flags later
1227 */
1228 /* pose should be entirely OK */
BKE_pose_update_constraint_flags(bPose * pose)1229 void BKE_pose_update_constraint_flags(bPose *pose)
1230 {
1231 bPoseChannel *pchan, *parchan;
1232 bConstraint *con;
1233
1234 /* clear */
1235 for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
1236 pchan->constflag = 0;
1237 }
1238 pose->flag &= ~POSE_CONSTRAINTS_TIMEDEPEND;
1239
1240 /* detect */
1241 for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
1242 for (con = pchan->constraints.first; con; con = con->next) {
1243 if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
1244 bKinematicConstraint *data = (bKinematicConstraint *)con->data;
1245
1246 pchan->constflag |= PCHAN_HAS_IK;
1247
1248 if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0)) {
1249 pchan->constflag |= PCHAN_HAS_TARGET;
1250 }
1251
1252 /* negative rootbone = recalc rootbone index. used in do_versions */
1253 if (data->rootbone < 0) {
1254 data->rootbone = 0;
1255
1256 if (data->flag & CONSTRAINT_IK_TIP) {
1257 parchan = pchan;
1258 }
1259 else {
1260 parchan = pchan->parent;
1261 }
1262
1263 while (parchan) {
1264 data->rootbone++;
1265 if ((parchan->bone->flag & BONE_CONNECTED) == 0) {
1266 break;
1267 }
1268 parchan = parchan->parent;
1269 }
1270 }
1271 }
1272 else if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) {
1273 bFollowPathConstraint *data = (bFollowPathConstraint *)con->data;
1274
1275 /* for drawing constraint colors when color set allows this */
1276 pchan->constflag |= PCHAN_HAS_CONST;
1277
1278 /* if we have a valid target, make sure that this will get updated on frame-change
1279 * (needed for when there is no anim-data for this pose)
1280 */
1281 if ((data->tar) && (data->tar->type == OB_CURVE)) {
1282 pose->flag |= POSE_CONSTRAINTS_TIMEDEPEND;
1283 }
1284 }
1285 else if (con->type == CONSTRAINT_TYPE_SPLINEIK) {
1286 pchan->constflag |= PCHAN_HAS_SPLINEIK;
1287 }
1288 else {
1289 pchan->constflag |= PCHAN_HAS_CONST;
1290 }
1291 }
1292 }
1293 pose->flag &= ~POSE_CONSTRAINTS_NEED_UPDATE_FLAGS;
1294 }
1295
BKE_pose_tag_update_constraint_flags(bPose * pose)1296 void BKE_pose_tag_update_constraint_flags(bPose *pose)
1297 {
1298 pose->flag |= POSE_CONSTRAINTS_NEED_UPDATE_FLAGS;
1299 }
1300
1301 /* Clears all BONE_UNKEYED flags for every pose channel in every pose
1302 * This should only be called on frame changing, when it is acceptable to
1303 * do this. Otherwise, these flags should not get cleared as poses may get lost.
1304 */
framechange_poses_clear_unkeyed(Main * bmain)1305 void framechange_poses_clear_unkeyed(Main *bmain)
1306 {
1307 Object *ob;
1308 bPose *pose;
1309 bPoseChannel *pchan;
1310
1311 /* This needs to be done for each object that has a pose */
1312 /* TODO: proxies may/may not be correctly handled here... (this needs checking) */
1313 for (ob = bmain->objects.first; ob; ob = ob->id.next) {
1314 /* we only need to do this on objects with a pose */
1315 if ((pose = ob->pose)) {
1316 for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
1317 if (pchan->bone) {
1318 pchan->bone->flag &= ~BONE_UNKEYED;
1319 }
1320 }
1321 }
1322 }
1323 }
1324
1325 /* ************************** Bone Groups ************************** */
1326
1327 /* Adds a new bone-group (name may be NULL) */
BKE_pose_add_group(bPose * pose,const char * name)1328 bActionGroup *BKE_pose_add_group(bPose *pose, const char *name)
1329 {
1330 bActionGroup *grp;
1331
1332 if (!name) {
1333 name = DATA_("Group");
1334 }
1335
1336 grp = MEM_callocN(sizeof(bActionGroup), "PoseGroup");
1337 BLI_strncpy(grp->name, name, sizeof(grp->name));
1338 BLI_addtail(&pose->agroups, grp);
1339 BLI_uniquename(&pose->agroups, grp, name, '.', offsetof(bActionGroup, name), sizeof(grp->name));
1340
1341 pose->active_group = BLI_listbase_count(&pose->agroups);
1342
1343 return grp;
1344 }
1345
1346 /* Remove the given bone-group (expects 'virtual' index (+1 one, used by active_group etc.))
1347 * index might be invalid ( < 1), in which case it will be find from grp. */
BKE_pose_remove_group(bPose * pose,bActionGroup * grp,const int index)1348 void BKE_pose_remove_group(bPose *pose, bActionGroup *grp, const int index)
1349 {
1350 bPoseChannel *pchan;
1351 int idx = index;
1352
1353 if (idx < 1) {
1354 idx = BLI_findindex(&pose->agroups, grp) + 1;
1355 }
1356
1357 BLI_assert(idx > 0);
1358
1359 /* adjust group references (the trouble of using indices!):
1360 * - firstly, make sure nothing references it
1361 * - also, make sure that those after this item get corrected
1362 */
1363 for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
1364 if (pchan->agrp_index == idx) {
1365 pchan->agrp_index = 0;
1366 }
1367 else if (pchan->agrp_index > idx) {
1368 pchan->agrp_index--;
1369 }
1370 }
1371
1372 /* now, remove it from the pose */
1373 BLI_freelinkN(&pose->agroups, grp);
1374 if (pose->active_group >= idx) {
1375 const bool has_groups = !BLI_listbase_is_empty(&pose->agroups);
1376 pose->active_group--;
1377 if (pose->active_group == 0 && has_groups) {
1378 pose->active_group = 1;
1379 }
1380 else if (pose->active_group < 0 || !has_groups) {
1381 pose->active_group = 0;
1382 }
1383 }
1384 }
1385
1386 /* Remove the indexed bone-group (expects 'virtual' index (+1 one, used by active_group etc.)) */
BKE_pose_remove_group_index(bPose * pose,const int index)1387 void BKE_pose_remove_group_index(bPose *pose, const int index)
1388 {
1389 bActionGroup *grp = NULL;
1390
1391 /* get group to remove */
1392 grp = BLI_findlink(&pose->agroups, index - 1);
1393 if (grp) {
1394 BKE_pose_remove_group(pose, grp, index);
1395 }
1396 }
1397
1398 /* ************** F-Curve Utilities for Actions ****************** */
1399
1400 /* Check if the given action has any keyframes */
action_has_motion(const bAction * act)1401 bool action_has_motion(const bAction *act)
1402 {
1403 FCurve *fcu;
1404
1405 /* return on the first F-Curve that has some keyframes/samples defined */
1406 if (act) {
1407 for (fcu = act->curves.first; fcu; fcu = fcu->next) {
1408 if (fcu->totvert) {
1409 return true;
1410 }
1411 }
1412 }
1413
1414 /* nothing found */
1415 return false;
1416 }
1417
1418 /* Calculate the extents of given action */
calc_action_range(const bAction * act,float * start,float * end,short incl_modifiers)1419 void calc_action_range(const bAction *act, float *start, float *end, short incl_modifiers)
1420 {
1421 FCurve *fcu;
1422 float min = 999999999.0f, max = -999999999.0f;
1423 short foundvert = 0, foundmod = 0;
1424
1425 if (act) {
1426 for (fcu = act->curves.first; fcu; fcu = fcu->next) {
1427 /* if curve has keyframes, consider them first */
1428 if (fcu->totvert) {
1429 float nmin, nmax;
1430
1431 /* get extents for this curve
1432 * - no "selected only", since this is often used in the backend
1433 * - no "minimum length" (we will apply this later), otherwise
1434 * single-keyframe curves will increase the overall length by
1435 * a phantom frame (T50354)
1436 */
1437 BKE_fcurve_calc_range(fcu, &nmin, &nmax, false, false);
1438
1439 /* compare to the running tally */
1440 min = min_ff(min, nmin);
1441 max = max_ff(max, nmax);
1442
1443 foundvert = 1;
1444 }
1445
1446 /* if incl_modifiers is enabled, need to consider modifiers too
1447 * - only really care about the last modifier
1448 */
1449 if ((incl_modifiers) && (fcu->modifiers.last)) {
1450 FModifier *fcm = fcu->modifiers.last;
1451
1452 /* only use the maximum sensible limits of the modifiers if they are more extreme */
1453 switch (fcm->type) {
1454 case FMODIFIER_TYPE_LIMITS: /* Limits F-Modifier */
1455 {
1456 FMod_Limits *fmd = (FMod_Limits *)fcm->data;
1457
1458 if (fmd->flag & FCM_LIMIT_XMIN) {
1459 min = min_ff(min, fmd->rect.xmin);
1460 }
1461 if (fmd->flag & FCM_LIMIT_XMAX) {
1462 max = max_ff(max, fmd->rect.xmax);
1463 }
1464 break;
1465 }
1466 case FMODIFIER_TYPE_CYCLES: /* Cycles F-Modifier */
1467 {
1468 FMod_Cycles *fmd = (FMod_Cycles *)fcm->data;
1469
1470 if (fmd->before_mode != FCM_EXTRAPOLATE_NONE) {
1471 min = MINAFRAMEF;
1472 }
1473 if (fmd->after_mode != FCM_EXTRAPOLATE_NONE) {
1474 max = MAXFRAMEF;
1475 }
1476 break;
1477 }
1478 /* TODO: function modifier may need some special limits */
1479
1480 default: /* all other standard modifiers are on the infinite range... */
1481 min = MINAFRAMEF;
1482 max = MAXFRAMEF;
1483 break;
1484 }
1485
1486 foundmod = 1;
1487 }
1488 }
1489 }
1490
1491 if (foundvert || foundmod) {
1492 /* ensure that action is at least 1 frame long (for NLA strips to have a valid length) */
1493 if (min == max) {
1494 max += 1.0f;
1495 }
1496
1497 *start = min;
1498 *end = max;
1499 }
1500 else {
1501 *start = 0.0f;
1502 *end = 1.0f;
1503 }
1504 }
1505
1506 /* Return flags indicating which transforms the given object/posechannel has
1507 * - if 'curves' is provided, a list of links to these curves are also returned
1508 */
action_get_item_transforms(bAction * act,Object * ob,bPoseChannel * pchan,ListBase * curves)1509 short action_get_item_transforms(bAction *act, Object *ob, bPoseChannel *pchan, ListBase *curves)
1510 {
1511 PointerRNA ptr;
1512 FCurve *fcu;
1513 char *basePath = NULL;
1514 short flags = 0;
1515
1516 /* build PointerRNA from provided data to obtain the paths to use */
1517 if (pchan) {
1518 RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan, &ptr);
1519 }
1520 else if (ob) {
1521 RNA_id_pointer_create((ID *)ob, &ptr);
1522 }
1523 else {
1524 return 0;
1525 }
1526
1527 /* get the basic path to the properties of interest */
1528 basePath = RNA_path_from_ID_to_struct(&ptr);
1529 if (basePath == NULL) {
1530 return 0;
1531 }
1532
1533 /* search F-Curves for the given properties
1534 * - we cannot use the groups, since they may not be grouped in that way...
1535 */
1536 for (fcu = act->curves.first; fcu; fcu = fcu->next) {
1537 const char *bPtr = NULL, *pPtr = NULL;
1538
1539 /* If enough flags have been found,
1540 * we can stop checking unless we're also getting the curves. */
1541 if ((flags == ACT_TRANS_ALL) && (curves == NULL)) {
1542 break;
1543 }
1544
1545 /* just in case... */
1546 if (fcu->rna_path == NULL) {
1547 continue;
1548 }
1549
1550 /* step 1: check for matching base path */
1551 bPtr = strstr(fcu->rna_path, basePath);
1552
1553 if (bPtr) {
1554 /* we must add len(basePath) bytes to the match so that we are at the end of the
1555 * base path so that we don't get false positives with these strings in the names
1556 */
1557 bPtr += strlen(basePath);
1558
1559 /* step 2: check for some property with transforms
1560 * - to speed things up, only check for the ones not yet found
1561 * unless we're getting the curves too
1562 * - if we're getting the curves, the BLI_genericNodeN() creates a LinkData
1563 * node wrapping the F-Curve, which then gets added to the list
1564 * - once a match has been found, the curve cannot possibly be any other one
1565 */
1566 if ((curves) || (flags & ACT_TRANS_LOC) == 0) {
1567 pPtr = strstr(bPtr, "location");
1568 if (pPtr) {
1569 flags |= ACT_TRANS_LOC;
1570
1571 if (curves) {
1572 BLI_addtail(curves, BLI_genericNodeN(fcu));
1573 }
1574 continue;
1575 }
1576 }
1577
1578 if ((curves) || (flags & ACT_TRANS_SCALE) == 0) {
1579 pPtr = strstr(bPtr, "scale");
1580 if (pPtr) {
1581 flags |= ACT_TRANS_SCALE;
1582
1583 if (curves) {
1584 BLI_addtail(curves, BLI_genericNodeN(fcu));
1585 }
1586 continue;
1587 }
1588 }
1589
1590 if ((curves) || (flags & ACT_TRANS_ROT) == 0) {
1591 pPtr = strstr(bPtr, "rotation");
1592 if (pPtr) {
1593 flags |= ACT_TRANS_ROT;
1594
1595 if (curves) {
1596 BLI_addtail(curves, BLI_genericNodeN(fcu));
1597 }
1598 continue;
1599 }
1600 }
1601
1602 if ((curves) || (flags & ACT_TRANS_BBONE) == 0) {
1603 /* bbone shape properties */
1604 pPtr = strstr(bPtr, "bbone_");
1605 if (pPtr) {
1606 flags |= ACT_TRANS_BBONE;
1607
1608 if (curves) {
1609 BLI_addtail(curves, BLI_genericNodeN(fcu));
1610 }
1611 continue;
1612 }
1613 }
1614
1615 if ((curves) || (flags & ACT_TRANS_PROP) == 0) {
1616 /* custom properties only */
1617 pPtr = strstr(bPtr, "[\"");
1618 if (pPtr) {
1619 flags |= ACT_TRANS_PROP;
1620
1621 if (curves) {
1622 BLI_addtail(curves, BLI_genericNodeN(fcu));
1623 }
1624 continue;
1625 }
1626 }
1627 }
1628 }
1629
1630 /* free basePath */
1631 MEM_freeN(basePath);
1632
1633 /* return flags found */
1634 return flags;
1635 }
1636
1637 /* ************** Pose Management Tools ****************** */
1638
1639 /**
1640 * Zero the pose transforms for the entire pose or only for selected bones.
1641 */
BKE_pose_rest(bPose * pose,bool selected_bones_only)1642 void BKE_pose_rest(bPose *pose, bool selected_bones_only)
1643 {
1644 bPoseChannel *pchan;
1645
1646 if (!pose) {
1647 return;
1648 }
1649
1650 memset(pose->stride_offset, 0, sizeof(pose->stride_offset));
1651 memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
1652
1653 for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
1654 if (selected_bones_only && pchan->bone != NULL && (pchan->bone->flag & BONE_SELECTED) == 0) {
1655 continue;
1656 }
1657 zero_v3(pchan->loc);
1658 zero_v3(pchan->eul);
1659 unit_qt(pchan->quat);
1660 unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
1661 pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f;
1662
1663 pchan->roll1 = pchan->roll2 = 0.0f;
1664 pchan->curve_in_x = pchan->curve_in_y = 0.0f;
1665 pchan->curve_out_x = pchan->curve_out_y = 0.0f;
1666 pchan->ease1 = pchan->ease2 = 0.0f;
1667 pchan->scale_in_x = pchan->scale_in_y = 1.0f;
1668 pchan->scale_out_x = pchan->scale_out_y = 1.0f;
1669
1670 pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
1671 }
1672 }
1673
BKE_pose_copy_pchan_result(bPoseChannel * pchanto,const bPoseChannel * pchanfrom)1674 void BKE_pose_copy_pchan_result(bPoseChannel *pchanto, const bPoseChannel *pchanfrom)
1675 {
1676 copy_m4_m4(pchanto->pose_mat, pchanfrom->pose_mat);
1677 copy_m4_m4(pchanto->chan_mat, pchanfrom->chan_mat);
1678
1679 /* used for local constraints */
1680 copy_v3_v3(pchanto->loc, pchanfrom->loc);
1681 copy_qt_qt(pchanto->quat, pchanfrom->quat);
1682 copy_v3_v3(pchanto->eul, pchanfrom->eul);
1683 copy_v3_v3(pchanto->size, pchanfrom->size);
1684
1685 copy_v3_v3(pchanto->pose_head, pchanfrom->pose_head);
1686 copy_v3_v3(pchanto->pose_tail, pchanfrom->pose_tail);
1687
1688 pchanto->roll1 = pchanfrom->roll1;
1689 pchanto->roll2 = pchanfrom->roll2;
1690 pchanto->curve_in_x = pchanfrom->curve_in_x;
1691 pchanto->curve_in_y = pchanfrom->curve_in_y;
1692 pchanto->curve_out_x = pchanfrom->curve_out_x;
1693 pchanto->curve_out_y = pchanfrom->curve_out_y;
1694 pchanto->ease1 = pchanfrom->ease1;
1695 pchanto->ease2 = pchanfrom->ease2;
1696 pchanto->scale_in_x = pchanfrom->scale_in_x;
1697 pchanto->scale_in_y = pchanfrom->scale_in_y;
1698 pchanto->scale_out_x = pchanfrom->scale_out_x;
1699 pchanto->scale_out_y = pchanfrom->scale_out_y;
1700
1701 pchanto->rotmode = pchanfrom->rotmode;
1702 pchanto->flag = pchanfrom->flag;
1703 pchanto->protectflag = pchanfrom->protectflag;
1704 }
1705
1706 /* both poses should be in sync */
BKE_pose_copy_result(bPose * to,bPose * from)1707 bool BKE_pose_copy_result(bPose *to, bPose *from)
1708 {
1709 bPoseChannel *pchanto, *pchanfrom;
1710
1711 if (to == NULL || from == NULL) {
1712 CLOG_ERROR(
1713 &LOG, "Pose copy error, pose to:%p from:%p", (void *)to, (void *)from); /* debug temp */
1714 return false;
1715 }
1716
1717 if (to == from) {
1718 CLOG_ERROR(&LOG, "source and target are the same");
1719 return false;
1720 }
1721
1722 for (pchanfrom = from->chanbase.first; pchanfrom; pchanfrom = pchanfrom->next) {
1723 pchanto = BKE_pose_channel_find_name(to, pchanfrom->name);
1724 if (pchanto != NULL) {
1725 BKE_pose_copy_pchan_result(pchanto, pchanfrom);
1726 }
1727 }
1728 return true;
1729 }
1730
1731 /* Tag pose for recalc. Also tag all related data to be recalc. */
BKE_pose_tag_recalc(Main * bmain,bPose * pose)1732 void BKE_pose_tag_recalc(Main *bmain, bPose *pose)
1733 {
1734 pose->flag |= POSE_RECALC;
1735 /* Depsgraph components depends on actual pose state,
1736 * if pose was changed depsgraph is to be updated as well.
1737 */
1738 DEG_relations_tag_update(bmain);
1739 }
1740
1741 /* For the calculation of the effects of an Action at the given frame on an object
1742 * This is currently only used for the Action Constraint
1743 */
what_does_obaction(Object * ob,Object * workob,bPose * pose,bAction * act,char groupname[],const AnimationEvalContext * anim_eval_context)1744 void what_does_obaction(Object *ob,
1745 Object *workob,
1746 bPose *pose,
1747 bAction *act,
1748 char groupname[],
1749 const AnimationEvalContext *anim_eval_context)
1750 {
1751 bActionGroup *agrp = BKE_action_group_find_name(act, groupname);
1752
1753 /* clear workob */
1754 BKE_object_workob_clear(workob);
1755
1756 /* init workob */
1757 copy_m4_m4(workob->obmat, ob->obmat);
1758 copy_m4_m4(workob->parentinv, ob->parentinv);
1759 copy_m4_m4(workob->constinv, ob->constinv);
1760 workob->parent = ob->parent;
1761
1762 workob->rotmode = ob->rotmode;
1763
1764 workob->trackflag = ob->trackflag;
1765 workob->upflag = ob->upflag;
1766
1767 workob->partype = ob->partype;
1768 workob->par1 = ob->par1;
1769 workob->par2 = ob->par2;
1770 workob->par3 = ob->par3;
1771
1772 workob->constraints.first = ob->constraints.first;
1773 workob->constraints.last = ob->constraints.last;
1774
1775 /* Need to set pose too, since this is used for both types of Action Constraint. */
1776 workob->pose = pose;
1777 if (pose) {
1778 /* This function is most likely to be used with a temporary pose with a single bone in there.
1779 * For such cases it makes no sense to create hash since it'll only waste CPU ticks on memory
1780 * allocation and also will make lookup slower.
1781 */
1782 if (pose->chanbase.first != pose->chanbase.last) {
1783 BKE_pose_channels_hash_make(pose);
1784 }
1785 if (pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
1786 BKE_pose_update_constraint_flags(pose);
1787 }
1788 }
1789
1790 BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr));
1791
1792 /* we don't use real object name, otherwise RNA screws with the real thing */
1793 BLI_strncpy(workob->id.name, "OB<ConstrWorkOb>", sizeof(workob->id.name));
1794
1795 /* If we're given a group to use, it's likely to be more efficient
1796 * (though a bit more dangerous). */
1797 if (agrp) {
1798 /* specifically evaluate this group only */
1799 PointerRNA id_ptr;
1800
1801 /* get RNA-pointer for the workob's ID */
1802 RNA_id_pointer_create(&workob->id, &id_ptr);
1803
1804 /* execute action for this group only */
1805 animsys_evaluate_action_group(&id_ptr, act, agrp, anim_eval_context);
1806 }
1807 else {
1808 AnimData adt = {NULL};
1809
1810 /* init animdata, and attach to workob */
1811 workob->adt = &adt;
1812
1813 adt.action = act;
1814 BKE_animdata_action_ensure_idroot(&workob->id, act);
1815
1816 /* execute effects of Action on to workob (or its PoseChannels) */
1817 BKE_animsys_evaluate_animdata(&workob->id, &adt, anim_eval_context, ADT_RECALC_ANIM, false);
1818 }
1819 }
1820
BKE_pose_check_uuids_unique_and_report(const bPose * pose)1821 void BKE_pose_check_uuids_unique_and_report(const bPose *pose)
1822 {
1823 if (pose == NULL) {
1824 return;
1825 }
1826
1827 struct GSet *used_uuids = BLI_gset_new(
1828 BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids");
1829
1830 LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
1831 const SessionUUID *session_uuid = &pchan->runtime.session_uuid;
1832 if (!BLI_session_uuid_is_generated(session_uuid)) {
1833 printf("Pose channel %s does not have UUID generated.\n", pchan->name);
1834 continue;
1835 }
1836
1837 if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) {
1838 printf("Pose channel %s has duplicate UUID generated.\n", pchan->name);
1839 continue;
1840 }
1841
1842 BLI_gset_insert(used_uuids, (void *)session_uuid);
1843 }
1844
1845 BLI_gset_free(used_uuids, NULL);
1846 }
1847