Welcome to mirror list, hosted at ThFree Co, Russian Federation.

BKE_armature.h « blenkernel « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: fcba7d9d3655c1a4d743cb0bc384e767c34dbf6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 */
#pragma once

/** \file
 * \ingroup bke
 */
#include "BLI_listbase.h"

#ifdef __cplusplus
extern "C" {
#endif

struct AnimationEvalContext;
struct BMEditMesh;
struct Bone;
struct Depsgraph;
struct IDProperty;
struct ListBase;
struct Main;
struct Mesh;
struct Object;
struct PoseTree;
struct Scene;
struct bAction;
struct bArmature;
struct bConstraint;
struct bGPDstroke;
struct bPose;
struct bPoseChannel;

typedef struct EditBone {
  struct EditBone *next, *prev;
  /** User-Defined Properties on this Bone */
  struct IDProperty *prop;
  /**
   * Editbones have a one-way link  (i.e. children refer
   * to parents.  This is converted to a two-way link for
   * normal bones when leaving editmode.
   */
  struct EditBone *parent;
  /** (64 == MAXBONENAME) */
  char name[64];
  /**
   * Roll along axis.  We'll ultimately use the axis/angle method
   * for determining the transformation matrix of the bone.  The axis
   * is tail-head while roll provides the angle. Refer to Graphics
   * Gems 1 p. 466 (section IX.6) if it's not already in here somewhere.
   */
  float roll;

  /** Orientation and length is implicit during editing */
  float head[3];
  float tail[3];
  /**
   * All joints are considered to have zero rotation with respect to
   * their parents. Therefore any rotations specified during the
   * animation are automatically relative to the bones' rest positions.
   */
  int flag;
  int layer;
  char inherit_scale_mode;

  /* Envelope distance & weight */
  float dist, weight;
  /** put them in order! transform uses this as scale */
  float xwidth, length, zwidth;
  float rad_head, rad_tail;

  /* Bendy-Bone parameters */
  short segments;
  float roll1, roll2;
  float curve_in_x, curve_in_z;
  float curve_out_x, curve_out_z;
  float ease1, ease2;
  float scale_in[3], scale_out[3];

  /** for envelope scaling */
  float oldlength;

  /** Type of next/prev bone handles */
  char bbone_prev_type;
  char bbone_next_type;
  /** B-Bone flags. */
  int bbone_flag;
  short bbone_prev_flag;
  short bbone_next_flag;
  /** Next/prev bones to use as handle references when calculating bbones (optional) */
  struct EditBone *bbone_prev;
  struct EditBone *bbone_next;

  /* Used for display */
  /** in Armature space, rest pos matrix */
  float disp_mat[4][4];
  /** in Armature space, rest pos matrix */
  float disp_tail_mat[4][4];
  /** in Armature space, rest pos matrix (32 == MAX_BBONE_SUBDIV) */
  float disp_bbone_mat[32][4][4];

  /** connected child temporary during drawing */
  struct EditBone *bbone_child;

  /* Used to store temporary data */
  union {
    struct EditBone *ebone;
    struct Bone *bone;
    void *p;
    int i;
  } temp;
} EditBone;

typedef struct PoseTarget {
  struct PoseTarget *next, *prev;

  struct bConstraint *con; /* the constraint of this target */
  int tip;                 /* index of tip pchan in PoseTree */
} PoseTarget;

typedef struct PoseTree {
  struct PoseTree *next, *prev;

  int type;       /* type of IK that this serves (CONSTRAINT_TYPE_KINEMATIC or ..._SPLINEIK) */
  int totchannel; /* number of pose channels */

  struct ListBase targets;     /* list of targets of the tree */
  struct bPoseChannel **pchan; /* array of pose channels */
  int *parent;                 /* and their parents */

  float (*basis_change)[3][3]; /* basis change result from solver */
  int iterations;              /* iterations from the constraint */
  int stretch;                 /* disable stretching */
} PoseTree;

/* Core armature functionality. */

struct bArmature *BKE_armature_add(struct Main *bmain, const char *name);
struct bArmature *BKE_armature_from_object(struct Object *ob);
int BKE_armature_bonelist_count(const struct ListBase *lb);
void BKE_armature_bonelist_free(struct ListBase *lb, const bool do_id_user);
void BKE_armature_editbonelist_free(struct ListBase *lb, const bool do_id_user);

void BKE_armature_copy_bone_transforms(struct bArmature *armature_dst,
                                       const struct bArmature *armature_src);

void BKE_armature_transform(struct bArmature *arm, const float mat[4][4], const bool do_props);

/* Bounding box. */
struct BoundBox *BKE_armature_boundbox_get(struct Object *ob);

bool BKE_pose_minmax(
    struct Object *ob, float r_min[3], float r_max[3], bool use_hidden, bool use_select);

/**
 * Finds the best possible extension to the name on a particular axis.
 * (For renaming, check for unique names afterwards)
 * \param strip_number: removes number extensions (TODO: not used).
 * \param axis: The axis to name on.
 * \param head: The head co-ordinate of the bone on the specified axis.
 * \param tail: The tail co-ordinate of the bone on the specified axis.
 */
bool bone_autoside_name(char name[64], int strip_number, short axis, float head, float tail);

/**
 * Walk the list until the bone is found (slow!),
 * use #BKE_armature_bone_from_name_map for multiple lookups.
 */
struct Bone *BKE_armature_find_bone_name(struct bArmature *arm, const char *name);

void BKE_armature_bone_hash_make(struct bArmature *arm);
void BKE_armature_bone_hash_free(struct bArmature *arm);

bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag);

void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmature *arm);

/**
 * Using `vec` with dist to bone `b1 - b2`.
 */
float distfactor_to_bone(
    const float vec[3], const float b1[3], const float b2[3], float rad1, float rad2, float rdist);

/**
 * Updates vectors and matrices on rest-position level, only needed
 * after editing armature itself, now only on reading file.
 */
void BKE_armature_where_is(struct bArmature *arm);
/**
 * Recursive part, calculates rest-position of entire tree of children.
 * \note Used when exiting edit-mode too.
 */
void BKE_armature_where_is_bone(struct Bone *bone,
                                const struct Bone *bone_parent,
                                const bool use_recursion);
/**
 * Clear pointers of object's pose
 * (needed in remap case, since we cannot always wait for a complete pose rebuild).
 */
void BKE_pose_clear_pointers(struct bPose *pose);
void BKE_pose_remap_bone_pointers(struct bArmature *armature, struct bPose *pose);
/**
 * Update the links for the B-Bone handles from Bone data.
 */
void BKE_pchan_rebuild_bbone_handles(struct bPose *pose, struct bPoseChannel *pchan);
void BKE_pose_channels_clear_with_null_bone(struct bPose *pose, const bool do_id_user);
/**
 * Only after leave edit-mode, duplicating, validating older files, library syncing.
 *
 * \note pose->flag is set for it.
 *
 * \param bmain: May be NULL, only used to tag depsgraph as being dirty.
 */
void BKE_pose_rebuild(struct Main *bmain,
                      struct Object *ob,
                      struct bArmature *arm,
                      const bool do_id_user);
/**
 * Ensures object's pose is rebuilt if needed.
 *
 * \param bmain: May be NULL, only used to tag depsgraph as being dirty.
 */
void BKE_pose_ensure(struct Main *bmain,
                     struct Object *ob,
                     struct bArmature *arm,
                     const bool do_id_user);
/**
 * \note This is the only function adding poses.
 * \note This only reads anim data from channels, and writes to channels.
 */
void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
/**
 * The main armature solver, does all constraints excluding IK.
 *
 * \param pchan: pose-channel - validated, as having bone and parent pointer.
 * \param do_extra: when zero skips loc/size/rot, constraints and strip modifiers.
 */
void BKE_pose_where_is_bone(struct Depsgraph *depsgraph,
                            struct Scene *scene,
                            struct Object *ob,
                            struct bPoseChannel *pchan,
                            float ctime,
                            bool do_extra);
/**
 * Calculate tail of pose-channel.
 */
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan);

/**
 * Evaluate the action and apply it to the pose. If any pose bones are selected, only FCurves that
 * relate to those bones are evaluated.
 */
void BKE_pose_apply_action_selected_bones(struct Object *ob,
                                          struct bAction *action,
                                          struct AnimationEvalContext *anim_eval_context);
/**
 * Evaluate the action and apply it to the pose. Ignore selection state of the bones.
 */
void BKE_pose_apply_action_all_bones(struct Object *ob,
                                     struct bAction *action,
                                     struct AnimationEvalContext *anim_eval_context);

void BKE_pose_apply_action_blend(struct Object *ob,
                                 struct bAction *action,
                                 struct AnimationEvalContext *anim_eval_context,
                                 float blend_factor);

void vec_roll_to_mat3(const float vec[3], const float roll, float r_mat[3][3]);

/**
 * Calculates the rest matrix of a bone based on its vector and a roll around that vector.
 */
void vec_roll_to_mat3_normalized(const float nor[3], const float roll, float r_mat[3][3]);
/**
 * Computes vector and roll based on a rotation.
 * "mat" must contain only a rotation, and no scaling.
 */
void mat3_to_vec_roll(const float mat[3][3], float r_vec[3], float *r_roll);
/**
 * Computes roll around the vector that best approximates the matrix.
 * If `vec` is the Y vector from purely rotational `mat`, result should be exact.
 */
void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll);

/* Common Conversions Between Co-ordinate Spaces */

/**
 * Convert World-Space Matrix to Pose-Space Matrix.
 */
void BKE_armature_mat_world_to_pose(struct Object *ob,
                                    const float inmat[4][4],
                                    float outmat[4][4]);
/**
 * Convert World-Space Location to Pose-Space Location
 * \note this cannot be used to convert to pose-space location of the supplied
 * pose-channel into its local space (i.e. 'visual'-keyframing).
 */
void BKE_armature_loc_world_to_pose(struct Object *ob, const float inloc[3], float outloc[3]);
/**
 * Convert Pose-Space Matrix to Bone-Space Matrix.
 * \note this cannot be used to convert to pose-space transforms of the supplied
 * pose-channel into its local space (i.e. 'visual'-keyframing).
 */
void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan,
                                   const float inmat[4][4],
                                   float outmat[4][4]);
/**
 * Convert Pose-Space Location to Bone-Space Location
 * \note this cannot be used to convert to pose-space location of the supplied
 * pose-channel into its local space (i.e. 'visual'-keyframing).
 */
void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan,
                                   const float inloc[3],
                                   float outloc[3]);
/**
 * Convert Bone-Space Matrix to Pose-Space Matrix.
 */
void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan,
                                   const float inmat[4][4],
                                   float outmat[4][4]);
/**
 * Remove rest-position effects from pose-transform for obtaining
 * 'visual' transformation of pose-channel.
 * (used by the Visual-Keyframing stuff).
 */
void BKE_armature_mat_pose_to_delta(float delta_mat[4][4],
                                    float pose_mat[4][4],
                                    float arm_mat[4][4]);

void BKE_armature_mat_pose_to_bone_ex(struct Depsgraph *depsgraph,
                                      struct Object *ob,
                                      struct bPoseChannel *pchan,
                                      const float inmat[4][4],
                                      float outmat[4][4]);

/**
 * Same as #BKE_object_mat3_to_rot().
 */
void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, const float mat[3][3], bool use_compat);
/**
 * Same as #BKE_object_rot_to_mat3().
 */
void BKE_pchan_rot_to_mat3(const struct bPoseChannel *pchan, float r_mat[3][3]);
/**
 * Apply a 4x4 matrix to the pose bone,
 * similar to #BKE_object_apply_mat4().
 */
void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, const float mat[4][4], bool use_compat);
/**
 * Convert the loc/rot/size to \a r_chanmat (typically #bPoseChannel.chan_mat).
 */
void BKE_pchan_to_mat4(const struct bPoseChannel *pchan, float r_chanmat[4][4]);

/**
 * Convert the loc/rot/size to mat4 (`pchan.chan_mat`),
 * used in `constraint.c` too.
 */
void BKE_pchan_calc_mat(struct bPoseChannel *pchan);

/**
 * Simple helper, computes the offset bone matrix:
 * `offs_bone = yoffs(b-1) + root(b) + bonemat(b)`.
 */
void BKE_bone_offset_matrix_get(const struct Bone *bone, float offs_bone[4][4]);

/* Transformation inherited from the parent bone. These matrices apply the effects of
 * HINGE/NO_SCALE/NO_LOCAL_LOCATION options over the pchan loc/rot/scale transformations. */
typedef struct BoneParentTransform {
  float rotscale_mat[4][4]; /* parent effect on rotation & scale pose channels */
  float loc_mat[4][4];      /* parent effect on location pose channel */
  float post_scale[3];      /* additional scale to apply with post-multiply */
} BoneParentTransform;

/* Matrix-like algebra operations on the transform */
void BKE_bone_parent_transform_clear(struct BoneParentTransform *bpt);
void BKE_bone_parent_transform_invert(struct BoneParentTransform *bpt);
void BKE_bone_parent_transform_combine(const struct BoneParentTransform *in1,
                                       const struct BoneParentTransform *in2,
                                       struct BoneParentTransform *result);

void BKE_bone_parent_transform_apply(const struct BoneParentTransform *bpt,
                                     const float inmat[4][4],
                                     float outmat[4][4]);

/**
 * Get the current parent transformation for the given pose bone.
 *
 * Construct the matrices (rot/scale and loc)
 * to apply the PoseChannels into the armature (object) space.
 * I.e. (roughly) the `pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b)` in the
 *     `pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)`
 * ...function.
 *
 * This allows to get the transformations of a bone in its object space,
 * *before* constraints (and IK) get applied (used by pose evaluation code).
 * And reverse: to find pchan transformations needed to place a bone at a given loc/rot/scale
 * in object space (used by interactive transform, and snapping code).
 *
 * Note that, with the HINGE/NO_SCALE/NO_LOCAL_LOCATION options, the location matrix
 * will differ from the rotation/scale matrix...
 *
 * \note This cannot be used to convert to pose-space transforms of the supplied
 * pose-channel into its local space (i.e. 'visual'-keyframing).
 * (NOTE(@mont29): I don't understand that, so I keep it :p).
 */
void BKE_bone_parent_transform_calc_from_pchan(const struct bPoseChannel *pchan,
                                               struct BoneParentTransform *r_bpt);
/**
 * Compute the parent transform using data decoupled from specific data structures.
 *
 * \param bone_flag: #Bone.flag containing settings.
 * \param offs_bone: delta from parent to current arm_mat (or just arm_mat if no parent).
 * \param parent_arm_mat: arm_mat of parent, or NULL.
 * \param parent_pose_mat: pose_mat of parent, or NULL.
 * \param r_bpt: OUTPUT parent transform.
 */
void BKE_bone_parent_transform_calc_from_matrices(int bone_flag,
                                                  int inherit_scale_mode,
                                                  const float offs_bone[4][4],
                                                  const float parent_arm_mat[4][4],
                                                  const float parent_pose_mat[4][4],
                                                  struct BoneParentTransform *r_bpt);

/**
 * Rotation Mode Conversions - Used for Pose-Channels + Objects.
 *
 * Called from RNA when rotation mode changes
 * - the result should be that the rotations given in the provided pointers have had conversions
 *   applied (as appropriate), such that the rotation of the element hasn't 'visually' changed.
 */
void BKE_rotMode_change_values(
    float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode);

/* B-Bone support */
#define MAX_BBONE_SUBDIV 32

typedef struct Mat4 {
  float mat[4][4];
} Mat4;

typedef struct BBoneSplineParameters {
  int segments;
  float length;

  /* Non-uniform scale correction. */
  bool do_scale;
  float scale[3];

  /* Handle control bone data. */
  bool use_prev, prev_bbone;
  bool use_next, next_bbone;

  float prev_h[3], next_h[3];
  float prev_mat[4][4], next_mat[4][4];

  /* Control values. */
  float ease1, ease2;
  float roll1, roll2;
  float scale_in[3], scale_out[3];
  float curve_in_x, curve_in_z, curve_out_x, curve_out_z;
} BBoneSplineParameters;

/**
 * Get "next" and "prev" bones - these are used for handle calculations.
 */
void BKE_pchan_bbone_handles_get(struct bPoseChannel *pchan,
                                 struct bPoseChannel **r_prev,
                                 struct bPoseChannel **r_next);
/**
 * Compute B-Bone spline parameters for the given channel.
 */
void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
                                       const bool rest,
                                       struct BBoneSplineParameters *r_param);

/**
 * Fills the array with the desired amount of bone->segments elements.
 * This calculation is done within unit bone space.
 */
void BKE_pchan_bbone_spline_setup(struct bPoseChannel *pchan,
                                  const bool rest,
                                  const bool for_deform,
                                  Mat4 *result_array);

/**
 * Computes the bezier handle vectors and rolls coming from custom handles.
 */
void BKE_pchan_bbone_handles_compute(const BBoneSplineParameters *param,
                                     float h1[3],
                                     float *r_roll1,
                                     float h2[3],
                                     float *r_roll2,
                                     bool ease,
                                     bool offsets);
/**
 * Fills the array with the desired amount of `bone->segments` elements.
 * This calculation is done within unit bone space.
 */
int BKE_pchan_bbone_spline_compute(struct BBoneSplineParameters *param,
                                   const bool for_deform,
                                   Mat4 *result_array);

/**
 * Compute and cache the B-Bone shape in the channel runtime struct.
 */
void BKE_pchan_bbone_segments_cache_compute(struct bPoseChannel *pchan);
/**
 * Copy cached B-Bone segments from one channel to another.
 */
void BKE_pchan_bbone_segments_cache_copy(struct bPoseChannel *pchan,
                                         struct bPoseChannel *pchan_from);

/**
 * Calculate index and blend factor for the two B-Bone segment nodes
 * affecting the point at 0 <= pos <= 1.
 */
void BKE_pchan_bbone_deform_segment_index(const struct bPoseChannel *pchan,
                                          float pos,
                                          int *r_index,
                                          float *r_blend_next);

/* like EBONE_VISIBLE */
#define PBONE_VISIBLE(arm, bone) \
  (CHECK_TYPE_INLINE(arm, bArmature *), \
   CHECK_TYPE_INLINE(bone, Bone *), \
   (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P)))

#define PBONE_SELECTABLE(arm, bone) \
  (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE))

#define PBONE_SELECTED(arm, bone) (((bone)->flag & BONE_SELECTED) & PBONE_VISIBLE(arm, bone))

/* context.selected_pose_bones */
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN(_ob, _pchan) \
  for (bPoseChannel *_pchan = (_ob)->pose->chanbase.first; _pchan; _pchan = _pchan->next) { \
    if (PBONE_VISIBLE(((bArmature *)(_ob)->data), (_pchan)->bone) && \
        ((_pchan)->bone->flag & BONE_SELECTED)) {
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_END \
  } \
  } \
  ((void)0)
/* context.visible_pose_bones */
#define FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN(_ob, _pchan) \
  for (bPoseChannel *_pchan = (_ob)->pose->chanbase.first; _pchan; _pchan = _pchan->next) { \
    if (PBONE_VISIBLE(((bArmature *)(_ob)->data), (_pchan)->bone)) {
#define FOREACH_PCHAN_VISIBLE_IN_OBJECT_END \
  } \
  } \
  ((void)0)

/* Evaluation helpers */
struct bKinematicConstraint;
struct bPose;
struct bSplineIKConstraint;

struct bPoseChannel *BKE_armature_ik_solver_find_root(struct bPoseChannel *pchan,
                                                      struct bKinematicConstraint *data);
struct bPoseChannel *BKE_armature_splineik_solver_find_root(struct bPoseChannel *pchan,
                                                            struct bSplineIKConstraint *data);

void BKE_pose_splineik_init_tree(struct Scene *scene, struct Object *ob, float ctime);
void BKE_splineik_execute_tree(struct Depsgraph *depsgraph,
                               struct Scene *scene,
                               struct Object *ob,
                               struct bPoseChannel *pchan_root,
                               float ctime);

void BKE_pose_pchan_index_rebuild(struct bPose *pose);

void BKE_pose_eval_init(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *object);

void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph,
                           struct Scene *scene,
                           struct Object *object);

void BKE_pose_eval_bone(struct Depsgraph *depsgraph,
                        struct Scene *scene,
                        struct Object *object,
                        int pchan_index);

void BKE_pose_constraints_evaluate(struct Depsgraph *depsgraph,
                                   struct Scene *scene,
                                   struct Object *object,
                                   int pchan_index);

void BKE_pose_bone_done(struct Depsgraph *depsgraph, struct Object *object, int pchan_index);

void BKE_pose_eval_bbone_segments(struct Depsgraph *depsgraph,
                                  struct Object *object,
                                  int pchan_index);

void BKE_pose_iktree_evaluate(struct Depsgraph *depsgraph,
                              struct Scene *scene,
                              struct Object *object,
                              int rootchan_index);

void BKE_pose_splineik_evaluate(struct Depsgraph *depsgraph,
                                struct Scene *scene,
                                struct Object *object,
                                int rootchan_index);

void BKE_pose_eval_done(struct Depsgraph *depsgraph, struct Object *object);

void BKE_pose_eval_cleanup(struct Depsgraph *depsgraph,
                           struct Scene *scene,
                           struct Object *object);

void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, struct Object *object);
void BKE_pose_eval_proxy_done(struct Depsgraph *depsgraph, struct Object *object);
void BKE_pose_eval_proxy_cleanup(struct Depsgraph *depsgraph, struct Object *object);

void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph,
                                   struct Object *object,
                                   int pchan_index);

/* -------------------------------------------------------------------- */
/** \name Deform 3D Coordinates by Armature (armature_deform.c)
 * \{ */

/* Note that we could have a 'BKE_armature_deform_coords' that doesn't take object data
 * currently there are no callers for this though. */

void BKE_armature_deform_coords_with_gpencil_stroke(const struct Object *ob_arm,
                                                    const struct Object *ob_target,
                                                    float (*vert_coords)[3],
                                                    float (*vert_deform_mats)[3][3],
                                                    int vert_coords_len,
                                                    int deformflag,
                                                    float (*vert_coords_prev)[3],
                                                    const char *defgrp_name,
                                                    struct bGPDstroke *gps_target);

void BKE_armature_deform_coords_with_mesh(const struct Object *ob_arm,
                                          const struct Object *ob_target,
                                          float (*vert_coords)[3],
                                          float (*vert_deform_mats)[3][3],
                                          int vert_coords_len,
                                          int deformflag,
                                          float (*vert_coords_prev)[3],
                                          const char *defgrp_name,
                                          const struct Mesh *me_target);

void BKE_armature_deform_coords_with_editmesh(const struct Object *ob_arm,
                                              const struct Object *ob_target,
                                              float (*vert_coords)[3],
                                              float (*vert_deform_mats)[3][3],
                                              int vert_coords_len,
                                              int deformflag,
                                              float (*vert_coords_prev)[3],
                                              const char *defgrp_name,
                                              struct BMEditMesh *em_target);

/** \} */

#ifdef __cplusplus
}
#endif