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