Blender V4.3
armature.cc File Reference
#include <cctype>
#include <cfloat>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <optional>
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_string_ref.hh"
#include "BLI_utildefines.h"
#include "BLT_translation.hh"
#include "DNA_defaults.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_listBase.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_action.hh"
#include "BKE_anim_data.hh"
#include "BKE_anim_visualization.h"
#include "BKE_armature.hh"
#include "BKE_constraint.h"
#include "BKE_curve.hh"
#include "BKE_idprop.hh"
#include "BKE_idtype.hh"
#include "BKE_lib_id.hh"
#include "BKE_lib_query.hh"
#include "BKE_main.hh"
#include "BKE_object.hh"
#include "BKE_object_types.hh"
#include "BKE_scene.hh"
#include "ANIM_bone_collections.hh"
#include "DEG_depsgraph_build.hh"
#include "DEG_depsgraph_query.hh"
#include "BIK_api.h"
#include "BLI_math_base_safe.h"
#include "BLO_read_write.hh"
#include "CLG_log.h"

Go to the source code of this file.

Functions

Prototypes
static void copy_bonechildren (Bone *bone_dst, const Bone *bone_src, const Bone *bone_src_act, Bone **r_bone_dst_act, const int flag)
 
static void copy_bonechildren_custom_handles (Bone *bone_dst, bArmature *arm_dst)
 
Generic Data-Level Functions
bArmatureBKE_armature_add (Main *bmain, const char *name)
 
bArmatureBKE_armature_from_object (Object *ob)
 
int BKE_armature_bonelist_count (const ListBase *lb)
 
void BKE_armature_bonelist_free (ListBase *lb, const bool do_id_user)
 
void BKE_armature_editbonelist_free (ListBase *lb, const bool do_id_user)
 
Armature Transform Copy
static void copy_bone_transform (Bone *bone_dst, const Bone *bone_src)
 
void BKE_armature_copy_bone_transforms (bArmature *armature_dst, const bArmature *armature_src)
 
Armature Transform by 4x4 Matrix
See also
ED_armature_edit_transform for the edit-mode version of this function.
static void armature_transform_recurse (ListBase *bonebase, const float mat[4][4], const bool do_props, const float mat3[3][3], const float scale, const Bone *bone_parent, const float arm_mat_parent_inv[4][4])
 
void BKE_armature_transform (bArmature *arm, const float mat[4][4], const bool do_props)
 
Armature Bone Find by Name

Using fast GHash lookups when available.

static Boneget_named_bone_bonechildren (ListBase *lb, const char *name)
 
BoneBKE_armature_find_bone_name (bArmature *arm, const char *name)
 
static void armature_bone_from_name_insert_recursive (GHash *bone_hash, ListBase *lb)
 
static GHasharmature_bone_from_name_map (bArmature *arm)
 
void BKE_armature_bone_hash_make (bArmature *arm)
 
void BKE_armature_bone_hash_free (bArmature *arm)
 
Armature Bone Flags
bool BKE_armature_bone_flag_test_recursive (const Bone *bone, int flag)
 
Bone auto-side name support
bool bone_autoside_name (char name[MAXBONENAME], int, short axis, float head, float tail)
 
Armature B-Bone Support
static void equalize_cubic_bezier (const float control[4][3], int temp_segments, int final_segments, const float *segment_scales, float *r_t_points)
 
static void evaluate_cubic_bezier (const float control[4][3], float t, float r_pos[3], float r_tangent[3])
 
void BKE_pchan_bbone_handles_get (bPoseChannel *pchan, bPoseChannel **r_prev, bPoseChannel **r_next)
 
void BKE_pchan_bbone_spline_params_get (bPoseChannel *pchan, const bool rest, BBoneSplineParameters *param)
 
void BKE_pchan_bbone_spline_setup (bPoseChannel *pchan, const bool rest, const bool for_deform, Mat4 *result_array)
 
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)
 
static void make_bbone_spline_matrix (BBoneSplineParameters *param, const float scalemats[2][4][4], const float pos[3], const float axis[3], float roll, float scalex, float scalez, float result[4][4])
 
static void ease_handle_axis (const float deriv1[3], const float deriv2[3], float r_axis[3])
 
int BKE_pchan_bbone_spline_compute (BBoneSplineParameters *param, const bool for_deform, Mat4 *result_array)
 
static void allocate_bbone_cache (bPoseChannel *pchan, const int segments, const bool use_boundaries)
 
static void compute_bbone_segment_boundaries (bPoseChannel *pchan)
 
void BKE_pchan_bbone_segments_cache_compute (bPoseChannel *pchan)
 
void BKE_pchan_bbone_segments_cache_copy (bPoseChannel *pchan, bPoseChannel *pchan_from)
 
void BKE_pchan_bbone_deform_clamp_segment_index (const bPoseChannel *pchan, float head_tail, int *r_index, float *r_blend_next)
 
static void find_bbone_segment_index_straight (const bPoseChannel *pchan, const float *co, int *r_index, float *r_blend_next)
 
float bbone_segment_bsp_signed_distance (const bPoseChannel_BBoneSegmentBoundary &boundary, const float *co)
 
static void find_bbone_segment_index_curved (const bPoseChannel *pchan, const float *co, int *r_index, float *r_blend_next)
 
void BKE_pchan_bbone_deform_segment_index (const bPoseChannel *pchan, const float *co, int *r_index, float *r_blend_next)
 
Bone Space to Space Conversion API
void BKE_armature_mat_world_to_pose (Object *ob, const float inmat[4][4], float outmat[4][4])
 
void BKE_armature_loc_world_to_pose (Object *ob, const float inloc[3], float outloc[3])
 
Bone Matrix Calculation API
void BKE_bone_offset_matrix_get (const Bone *bone, float offs_bone[4][4])
 
void BKE_bone_parent_transform_calc_from_pchan (const bPoseChannel *pchan, BoneParentTransform *r_bpt)
 
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], BoneParentTransform *r_bpt)
 
void BKE_bone_parent_transform_clear (BoneParentTransform *bpt)
 
void BKE_bone_parent_transform_invert (BoneParentTransform *bpt)
 
void BKE_bone_parent_transform_combine (const BoneParentTransform *in1, const BoneParentTransform *in2, BoneParentTransform *result)
 
void BKE_bone_parent_transform_apply (const BoneParentTransform *bpt, const float inmat[4][4], float outmat[4][4])
 
void BKE_armature_mat_pose_to_bone (bPoseChannel *pchan, const float inmat[4][4], float outmat[4][4])
 
void BKE_armature_mat_bone_to_pose (bPoseChannel *pchan, const float inmat[4][4], float outmat[4][4])
 
void BKE_armature_loc_pose_to_bone (bPoseChannel *pchan, const float inloc[3], float outloc[3])
 
Bone Matrix Read/Write API

High level functions for transforming bones and reading the transform values.

void BKE_armature_mat_pose_to_bone_ex (Depsgraph *depsgraph, Object *ob, bPoseChannel *pchan, const float inmat[4][4], float outmat[4][4])
 
void BKE_pchan_mat3_to_rot (bPoseChannel *pchan, const float mat[3][3], bool use_compat)
 
void BKE_pchan_rot_to_mat3 (const bPoseChannel *pchan, float r_mat[3][3])
 
void BKE_pchan_apply_mat4 (bPoseChannel *pchan, const float mat[4][4], bool use_compat)
 
void BKE_armature_mat_pose_to_delta (float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4])
 
Rotation Mode Conversions

Used for Objects and Pose Channels, since both can have multiple rotation representations.

void BKE_rotMode_change_values (float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode)
 
Bone Vector, Roll Conversion

Used for Objects and Pose Channels, since both can have multiple rotation representations.

How it Works

This is the bone transformation trick; they're hierarchical so each bone(b) is in the coord system of bone(b-1):

arm_mat(b)= arm_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b)

-> yoffs is just the y axis translation in parent's coord system -> d_root is the translation of the bone root, also in parent's coord system

pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)

we then - in init deform - store the deform in chan_mat, such that:

pose_mat(b)= arm_mat(b) * chan_mat(b)

void mat3_to_vec_roll (const float mat[3][3], float r_vec[3], float *r_roll)
 
void mat3_vec_to_roll (const float mat[3][3], const float vec[3], float *r_roll)
 
void vec_roll_to_mat3_normalized (const float nor[3], const float roll, float r_mat[3][3])
 
void vec_roll_to_mat3 (const float vec[3], const float roll, float r_mat[3][3])
 
Armature Bone Matrix Calculation (Recursive)
void BKE_armature_where_is_bone (Bone *bone, const Bone *bone_parent, const bool use_recursion)
 
void BKE_armature_where_is (bArmature *arm)
 
Pose Rebuild
static int rebuild_pose_bone (bPose *pose, Bone *bone, bPoseChannel *parchan, int counter, Bone **r_last_visited_bone_p)
 
void BKE_pose_clear_pointers (bPose *pose)
 
void BKE_pose_remap_bone_pointers (bArmature *armature, bPose *pose)
 
static bPoseChannelpose_channel_find_bone (bPose *pose, Bone *bone)
 
void BKE_pchan_rebuild_bbone_handles (bPose *pose, bPoseChannel *pchan)
 
void BKE_pose_channels_clear_with_null_bone (bPose *pose, const bool do_id_user)
 
void BKE_pose_rebuild (Main *bmain, Object *ob, bArmature *arm, const bool do_id_user)
 
void BKE_pose_ensure (Main *bmain, Object *ob, bArmature *arm, const bool do_id_user)
 
Pose Solver
void BKE_pchan_to_mat4 (const bPoseChannel *pchan, float r_chanmat[4][4])
 
void BKE_pchan_calc_mat (bPoseChannel *pchan)
 
void BKE_pose_where_is_bone_tail (bPoseChannel *pchan)
 
void BKE_pose_where_is_bone (Depsgraph *depsgraph, Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, bool do_extra)
 
void BKE_pose_where_is (Depsgraph *depsgraph, Scene *scene, Object *ob)
 
Calculate Bounding Box (Armature & Pose)
std::optional< blender::Bounds< blender::float3 > > BKE_armature_min_max (const Object *ob)
 
void BKE_pchan_minmax (const Object *ob, const bPoseChannel *pchan, const bool use_empty_drawtype, float r_min[3], float r_max[3])
 
std::optional< blender::Bounds< blender::float3 > > BKE_pose_minmax (const Object *ob, const bool use_select)
 
Graph Evaluation
bPoseChannelBKE_armature_ik_solver_find_root (bPoseChannel *pchan, bKinematicConstraint *data)
 
bPoseChannelBKE_armature_splineik_solver_find_root (bPoseChannel *pchan, bSplineIKConstraint *data)
 

Armature Data-block

IDTypeInfo IDType_ID_AR
 
static void armature_init_data (ID *id)
 
static void copy_bone_collection (bArmature *armature_dst, BoneCollection *&bcoll_dst, const BoneCollection *bcoll_src, const int lib_id_flag)
 
static void armature_copy_data (Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int flag)
 
static void armature_free_data (ID *id)
 
static void armature_foreach_id_bone (Bone *bone, LibraryForeachIDData *data)
 
static void armature_foreach_id_editbone (EditBone *edit_bone, LibraryForeachIDData *data)
 
static void armature_foreach_id_bone_collection (BoneCollection *bcoll, LibraryForeachIDData *data)
 
static void armature_foreach_id (ID *id, LibraryForeachIDData *data)
 
static void write_bone (BlendWriter *writer, Bone *bone)
 
static void write_bone_collection (BlendWriter *writer, BoneCollection *bcoll)
 
static void armature_blend_write (BlendWriter *writer, ID *id, const void *id_address)
 
static void direct_link_bones (BlendDataReader *reader, Bone *bone)
 
static void direct_link_bone_collection (BlendDataReader *reader, BoneCollection *bcoll)
 
static void read_bone_collections (BlendDataReader *reader, bArmature *arm)
 
static void armature_blend_read_data (BlendDataReader *reader, ID *id)
 
static void armature_undo_preserve (BlendLibReader *, ID *id_new, ID *id_old)
 

Function Documentation

◆ allocate_bbone_cache()

◆ armature_blend_read_data()

◆ armature_blend_write()

◆ armature_bone_from_name_insert_recursive()

static void armature_bone_from_name_insert_recursive ( GHash * bone_hash,
ListBase * lb )
static

◆ armature_bone_from_name_map()

static GHash * armature_bone_from_name_map ( bArmature * arm)
static

Create a (name -> bone) map.

Note
typically bPose.chanhash us used via BKE_pose_channel_find_name this is for the cases we can't use pose channels.

Definition at line 806 of file armature.cc.

References armature_bone_from_name_insert_recursive(), BKE_armature_bonelist_count(), BLI_ghash_str_new_ex(), and bArmature::bonebase.

Referenced by BKE_armature_bone_hash_make().

◆ armature_copy_data()

static void armature_copy_data ( Main * ,
std::optional< Library * > ,
ID * id_dst,
const ID * id_src,
const int flag )
static

Only copy internal data of Armature ID from source to already allocated/initialized destination. You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs.

WARNING! This function will not handle ID user count!

Parameters
flagCopying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more).

Definition at line 135 of file armature.cc.

References bArmature::act_bone, bArmature::act_edbone, bArmature_Runtime::active_collection_index, ANIM_armature_bonecoll_active_index_set(), ANIM_armature_runtime_refresh(), BKE_armature_bone_hash_make(), BLI_duplicatelist(), bArmature::bonebase, bArmature::bonehash, bArmature::collection_array, bArmature::collection_array_num, copy_bone_collection(), copy_bonechildren(), copy_bonechildren_custom_handles(), bArmature::edbo, ListBase::first, flag, LIB_ID_CREATE_NO_USER_REFCOUNT, MEM_dupallocN, Bone::next, Bone::parent, and bArmature::runtime.

◆ armature_foreach_id()

◆ armature_foreach_id_bone()

◆ armature_foreach_id_bone_collection()

static void armature_foreach_id_bone_collection ( BoneCollection * bcoll,
LibraryForeachIDData * data )
static

◆ armature_foreach_id_editbone()

static void armature_foreach_id_editbone ( EditBone * edit_bone,
LibraryForeachIDData * data )
static

◆ armature_free_data()

static void armature_free_data ( ID * id)
static

◆ armature_init_data()

static void armature_init_data ( ID * id)
static

◆ armature_transform_recurse()

static void armature_transform_recurse ( ListBase * bonebase,
const float mat[4][4],
const bool do_props,
const float mat3[3][3],
const float scale,
const Bone * bone_parent,
const float arm_mat_parent_inv[4][4] )
static

◆ armature_undo_preserve()

static void armature_undo_preserve ( BlendLibReader * ,
ID * id_new,
ID * id_old )
static

Definition at line 469 of file armature.cc.

References blender::animrig::bonecolls_copy_expanded_flag().

◆ bbone_segment_bsp_signed_distance()

float bbone_segment_bsp_signed_distance ( const bPoseChannel_BBoneSegmentBoundary & boundary,
const float * co )
inline

Computes signed distance to the segment boundary BSP plane.

Definition at line 1843 of file armature.cc.

References dot_v3v3().

Referenced by find_bbone_segment_index_curved().

◆ BKE_armature_add()

bArmature * BKE_armature_add ( Main * bmain,
const char * name )

◆ BKE_armature_bone_flag_test_recursive()

bool BKE_armature_bone_flag_test_recursive ( const Bone * bone,
int flag )

◆ BKE_armature_bone_hash_free()

void BKE_armature_bone_hash_free ( bArmature * arm)

Definition at line 821 of file armature.cc.

References BLI_ghash_free(), and bArmature::bonehash.

Referenced by armature_free_data(), and ED_armature_from_edit().

◆ BKE_armature_bone_hash_make()

◆ BKE_armature_bonelist_count()

int BKE_armature_bonelist_count ( const ListBase * lb)

◆ BKE_armature_bonelist_free()

void BKE_armature_bonelist_free ( ListBase * lb,
const bool do_id_user )

◆ BKE_armature_copy_bone_transforms()

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

◆ BKE_armature_editbonelist_free()

void BKE_armature_editbonelist_free ( ListBase * lb,
const bool do_id_user )

◆ BKE_armature_find_bone_name()

◆ BKE_armature_from_object()

bArmature * BKE_armature_from_object ( Object * ob)

◆ BKE_armature_ik_solver_find_root()

◆ BKE_armature_loc_pose_to_bone()

void BKE_armature_loc_pose_to_bone ( bPoseChannel * pchan,
const float inloc[3],
float outloc[3] )

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).

Definition at line 2270 of file armature.cc.

References BKE_armature_mat_pose_to_bone(), copy_v3_v3(), and unit_m4().

Referenced by snap_sel_to_grid_exec(), and snap_selected_to_location().

◆ BKE_armature_loc_world_to_pose()

void BKE_armature_loc_world_to_pose ( Object * ob,
const float inloc[3],
float outloc[3] )

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).

Definition at line 2005 of file armature.cc.

References BKE_armature_mat_world_to_pose(), copy_v3_v3(), and unit_m4().

◆ BKE_armature_mat_bone_to_pose()

void BKE_armature_mat_bone_to_pose ( bPoseChannel * pchan,
const float inmat[4][4],
float outmat[4][4] )

Convert Bone-Space Matrix to Pose-Space Matrix.

Definition at line 2260 of file armature.cc.

References BKE_bone_parent_transform_apply(), and BKE_bone_parent_transform_calc_from_pchan().

Referenced by BKE_constraint_mat_convertspace(), and BKE_pose_where_is_bone().

◆ BKE_armature_mat_pose_to_bone()

void BKE_armature_mat_pose_to_bone ( bPoseChannel * pchan,
const float inmat[4][4],
float outmat[4][4] )

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).

Definition at line 2249 of file armature.cc.

References BKE_bone_parent_transform_apply(), BKE_bone_parent_transform_calc_from_pchan(), and BKE_bone_parent_transform_invert().

Referenced by apply_targetless_ik(), BKE_armature_loc_pose_to_bone(), BKE_armature_mat_pose_to_bone_ex(), BKE_constraint_apply_for_pose(), BKE_constraint_mat_convertspace(), BKE_pchan_bbone_spline_params_get(), pose_visual_transform_apply_exec(), and blender::animrig::visualkey_get_values().

◆ BKE_armature_mat_pose_to_bone_ex()

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

◆ BKE_armature_mat_pose_to_delta()

void BKE_armature_mat_pose_to_delta ( float delta_mat[4][4],
float pose_mat[4][4],
float arm_mat[4][4] )

Remove rest-position effects from pose-transform for obtaining 'visual' transformation of pose-channel. (used by the Visual-Keyframing stuff).

Definition at line 2365 of file armature.cc.

References invert_m4_m4(), and mul_m4_m4m4().

◆ BKE_armature_mat_world_to_pose()

void BKE_armature_mat_world_to_pose ( Object * ob,
const float inmat[4][4],
float outmat[4][4] )

Convert World-Space Matrix to Pose-Space Matrix.

Definition at line 1989 of file armature.cc.

References invert_m4_m4(), and mul_m4_m4m4().

Referenced by BKE_armature_loc_world_to_pose().

◆ BKE_armature_min_max()

std::optional< blender::Bounds< blender::float3 > > BKE_armature_min_max ( const Object * ob)

Return the posed Armature bounding box in object-local coordinate space.

Definition at line 3024 of file armature.cc.

References BKE_pose_minmax(), and blender::math::transform_point().

Referenced by BKE_object_boundbox_get(), and snapArmature().

◆ BKE_armature_splineik_solver_find_root()

◆ BKE_armature_transform()

◆ BKE_armature_where_is()

void BKE_armature_where_is ( bArmature * arm)

Updates vectors and matrices on rest-position level, only needed after editing armature itself, now only on reading file.

Definition at line 2663 of file armature.cc.

References BKE_armature_where_is_bone(), bArmature::bonebase, and LISTBASE_FOREACH.

Referenced by blo_do_versions_pre250().

◆ BKE_armature_where_is_bone()

void BKE_armature_where_is_bone ( Bone * bone,
const Bone * bone_parent,
bool use_recursion )

◆ BKE_bone_offset_matrix_get()

void BKE_bone_offset_matrix_get ( const Bone * bone,
float offs_bone[4][4] )

Simple helper, computes the offset bone matrix: offs_bone = yoffs(b-1) + root(b) + bonemat(b).

Definition at line 2025 of file armature.cc.

References BLI_assert, Bone::bone_mat, copy_m4_m3(), copy_v3_v3(), Bone::head, Bone::length, and Bone::parent.

Referenced by applyarmature_process_selected_recursive(), BKE_armature_where_is_bone(), and BKE_bone_parent_transform_calc_from_pchan().

◆ BKE_bone_parent_transform_apply()

◆ BKE_bone_parent_transform_calc_from_matrices()

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],
BoneParentTransform * r_bpt )

◆ BKE_bone_parent_transform_calc_from_pchan()

void BKE_bone_parent_transform_calc_from_pchan ( const bPoseChannel * pchan,
BoneParentTransform * r_bpt )

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).

Definition at line 2039 of file armature.cc.

References Bone::arm_mat, BKE_bone_offset_matrix_get(), BKE_bone_parent_transform_calc_from_matrices(), bPoseChannel::bone, Bone::flag, Bone::inherit_scale_mode, Bone::parent, bPoseChannel::parent, and bPoseChannel::pose_mat.

Referenced by add_pose_transdata(), BKE_armature_mat_bone_to_pose(), and BKE_armature_mat_pose_to_bone().

◆ BKE_bone_parent_transform_clear()

◆ BKE_bone_parent_transform_combine()

◆ BKE_bone_parent_transform_invert()

◆ BKE_pchan_apply_mat4()

void BKE_pchan_apply_mat4 ( bPoseChannel * pchan,
const float mat[4][4],
bool use_compat )

◆ BKE_pchan_bbone_deform_clamp_segment_index()

void BKE_pchan_bbone_deform_clamp_segment_index ( const bPoseChannel * pchan,
float head_tail,
int * r_index,
float * r_blend_next )

Calculate index and blend factor for the two B-Bone segment nodes affecting the specified point along the bone.

Parameters
pchanPose channel.
head_tailhead-tail position along the bone (auto-clamped between 0 and 1).
r_indexOUTPUT index of the first segment joint affecting the point.
r_blend_nextOUTPUT blend factor between the first and the second segment in [0..1]

Definition at line 1800 of file armature.cc.

References blend, bPoseChannel::bone, CLAMP, float, floorf, int, and Bone::segments.

Referenced by constraint_target_to_mat4(), find_bbone_segment_index_curved(), and find_bbone_segment_index_straight().

◆ BKE_pchan_bbone_deform_segment_index()

void BKE_pchan_bbone_deform_segment_index ( const bPoseChannel * pchan,
const float * co,
int * r_index,
float * r_blend_next )

Calculate index and blend factor for the two B-Bone segment nodes affecting the specified point in object (pose) space.

Parameters
pchanPose channel.
coPose space coordinates of the point being deformed.
r_indexOUTPUT index of the first segment joint affecting the point.
r_blend_nextOUTPUT blend factor between the first and the second segment in [0..1]

Definition at line 1970 of file armature.cc.

References bPoseChannel_Runtime::bbone_segment_boundaries, find_bbone_segment_index_curved(), find_bbone_segment_index_straight(), and bPoseChannel::runtime.

Referenced by armdef_accumulate_bone(), and b_bone_deform().

◆ BKE_pchan_bbone_handles_compute()

◆ BKE_pchan_bbone_handles_get()

void BKE_pchan_bbone_handles_get ( bPoseChannel * pchan,
bPoseChannel ** r_prev,
bPoseChannel ** r_next )

◆ BKE_pchan_bbone_segments_cache_compute()

◆ BKE_pchan_bbone_segments_cache_copy()

◆ BKE_pchan_bbone_spline_compute()

◆ BKE_pchan_bbone_spline_params_get()

void BKE_pchan_bbone_spline_params_get ( bPoseChannel * pchan,
bool rest,
BBoneSplineParameters * param )

Compute B-Bone spline parameters for the given channel.

Definition at line 1087 of file armature.cc.

References add_v3_v3v3(), Bone::arm_head, Bone::arm_mat, Bone::arm_tail, BBONE_ADD_PARENT_END_ROLL, Bone::bbone_flag, BBONE_HANDLE_RELATIVE, BBONE_HANDLE_SCALE_ANY, BBONE_HANDLE_SCALE_EASE, BBONE_HANDLE_SCALE_X, BBONE_HANDLE_SCALE_Y, BBONE_HANDLE_SCALE_Z, BBONE_HANDLE_TANGENT, Bone::bbone_next_flag, Bone::bbone_next_type, Bone::bbone_prev_flag, Bone::bbone_prev_type, BBONE_SCALE_EASING, BKE_armature_mat_pose_to_bone(), BKE_pchan_bbone_handles_get(), bPoseChannel::bone, copy_m4_m4(), copy_v3_fl(), copy_v3_fl3(), copy_v3_v3(), BBoneSplineParameters::curve_in_x, Bone::curve_in_x, bPoseChannel::curve_in_x, BBoneSplineParameters::curve_in_z, Bone::curve_in_z, bPoseChannel::curve_in_z, BBoneSplineParameters::curve_out_x, Bone::curve_out_x, bPoseChannel::curve_out_x, BBoneSplineParameters::curve_out_z, Bone::curve_out_z, bPoseChannel::curve_out_z, BBoneSplineParameters::do_scale, BBoneSplineParameters::ease1, Bone::ease1, bPoseChannel::ease1, BBoneSplineParameters::ease2, Bone::ease2, bPoseChannel::ease2, fabsf, invert_m4_m4(), BBoneSplineParameters::length, Bone::length, mat4_to_size(), mul_m4_m4m4(), mul_v3_m4v3(), mul_v3_v3(), next, BBoneSplineParameters::next_bbone, BBoneSplineParameters::next_h, BBoneSplineParameters::next_mat, normalize_m4(), bPoseChannel::pose_head, bPoseChannel::pose_mat, bPoseChannel::pose_tail, BBoneSplineParameters::prev_bbone, BBoneSplineParameters::prev_h, BBoneSplineParameters::prev_mat, BBoneSplineParameters::roll1, Bone::roll1, bPoseChannel::roll1, BBoneSplineParameters::roll2, Bone::roll2, bPoseChannel::roll2, BBoneSplineParameters::scale, BBoneSplineParameters::scale_in, Bone::scale_in, bPoseChannel::scale_in, BBoneSplineParameters::scale_out, Bone::scale_out, bPoseChannel::scale_out, BBoneSplineParameters::segments, Bone::segments, sub_v3_v3v3(), BBoneSplineParameters::use_next, BBoneSplineParameters::use_prev, and zero_v3().

Referenced by BKE_pchan_bbone_spline_setup().

◆ BKE_pchan_bbone_spline_setup()

void BKE_pchan_bbone_spline_setup ( bPoseChannel * pchan,
bool rest,
bool for_deform,
Mat4 * result_array )

Fills the array with the desired amount of bone->segments elements. This calculation is done within unit bone space.

Definition at line 1334 of file armature.cc.

References BKE_pchan_bbone_spline_compute(), BKE_pchan_bbone_spline_params_get(), bPoseChannel::bone, and Bone::segments.

Referenced by add_verts_to_dgroups(), BKE_pchan_bbone_segments_cache_compute(), and draw_bone_update_disp_matrix_bbone().

◆ BKE_pchan_calc_mat()

void BKE_pchan_calc_mat ( bPoseChannel * pchan)

Convert the loc/rot/size to mat4 (pchan.chan_mat), used in constraint.cc too.

Definition at line 2860 of file armature.cc.

References BKE_pchan_to_mat4(), and bPoseChannel::chan_mat.

Referenced by actcon_get_tarmat(), and BKE_pose_where_is_bone().

◆ BKE_pchan_mat3_to_rot()

◆ BKE_pchan_minmax()

void BKE_pchan_minmax ( const Object * ob,
const bPoseChannel * pchan,
const bool use_empty_drawtype,
float r_min[3],
float r_max[3] )

Calculate the axis-aligned bounds of pchan in world-space, taking into account custom transform when set.

r_min and r_max are expanded to fit pchan so the caller must initialize them (typically using INIT_MINMAX).

Note
The bounds are calculated based on the head & tail of the bone or the custom object's bounds (if the bone uses a custom object). Visual elements such as the envelopes radius & bendy-bone spline segments are not included, making this not so useful for viewport culling.
Parameters
use_empty_drawtypeWhen enabled, the draw type of empty custom-objects is taken into account when calculating the bounds.

Definition at line 3040 of file armature.cc.

References ARM_NO_CUSTOM, BKE_boundbox_init_from_minmax(), BKE_boundbox_minmax(), BKE_object_boundbox_get(), BKE_object_minmax_empty_drawtype(), copy_m4_m4(), bPoseChannel::custom, bPoseChannel::custom_rotation_euler, bPoseChannel::custom_scale_xyz, bPoseChannel::custom_translation, bPoseChannel::custom_tx, Object::data, eulO_to_mat4(), bArmature::flag, max, BoundBox::min, min, minmax_v3v3_v3(), mul_m4_series, mul_v3_m4v3(), OB_EMPTY, PCHAN_CUSTOM_BONE_LENGTH, bPoseChannel::pose_head, bPoseChannel::pose_mat, bPoseChannel::pose_tail, rescale_m4(), ROT_MODE_XYZ, scale_m4_fl(), translate_m4(), and Object::type.

Referenced by BKE_pose_minmax(), and pchan_culling_calc_bsphere().

◆ BKE_pchan_rebuild_bbone_handles()

void BKE_pchan_rebuild_bbone_handles ( bPose * pose,
bPoseChannel * pchan )

Update the links for the B-Bone handles from Bone data.

Definition at line 2750 of file armature.cc.

References Bone::bbone_next, bPoseChannel::bbone_next, Bone::bbone_prev, bPoseChannel::bbone_prev, bPoseChannel::bone, and pose_channel_find_bone().

Referenced by BKE_pose_rebuild().

◆ BKE_pchan_rot_to_mat3()

◆ BKE_pchan_to_mat4()

◆ BKE_pose_channels_clear_with_null_bone()

void BKE_pose_channels_clear_with_null_bone ( bPose * pose,
const bool do_id_user )

◆ BKE_pose_clear_pointers()

void BKE_pose_clear_pointers ( bPose * pose)

Clear pointers of object's pose (needed in remap case, since we cannot always wait for a complete pose rebuild).

Definition at line 2729 of file armature.cc.

References bPose::chanbase, and LISTBASE_FOREACH.

Referenced by BKE_lib_override_library_update(), BKE_pose_rebuild(), and libblock_remap_data_preprocess_ob().

◆ BKE_pose_ensure()

◆ BKE_pose_minmax()

std::optional< blender::Bounds< blender::float3 > > BKE_pose_minmax ( const Object * ob,
bool use_select )

Calculate the axis aligned bounds of the pose of ob in world-space.

This only considers visible bones. When they are either directly (via a flag on the bone) or indirectly (via bone collections) hidden, they are not part of the bounds calculation. When a bone has a custom bone shape, that is included in the bounding box.

Note
This uses BKE_pchan_minmax, see its documentation for details on bounds calculation.
Parameters
use_selectWhen true, only consider selected bones. When false, selection state is ignored and all bones are included in the bounds.

Definition at line 3088 of file armature.cc.

References BKE_pchan_minmax(), BLI_assert, BONE_SELECTED, bPose::chanbase, Object::data, LISTBASE_FOREACH, max, min, OB_ARMATURE, PBONE_VISIBLE, Object::pose, and Object::type.

Referenced by BKE_armature_min_max(), and viewselected_exec().

◆ BKE_pose_rebuild()

◆ BKE_pose_remap_bone_pointers()

void BKE_pose_remap_bone_pointers ( bArmature * armature,
bPose * pose )

Definition at line 2737 of file armature.cc.

References BKE_armature_find_bone_name(), bPose::chanbase, and LISTBASE_FOREACH.

◆ BKE_pose_where_is()

◆ BKE_pose_where_is_bone()

◆ BKE_pose_where_is_bone_tail()

void BKE_pose_where_is_bone_tail ( bPoseChannel * pchan)

◆ BKE_rotMode_change_values()

void BKE_rotMode_change_values ( float quat[4],
float eul[3],
float axis[3],
float * angle,
short oldMode,
short newMode )

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.

Definition at line 2383 of file armature.cc.

References axis_angle_to_eulO(), axis_angle_to_quat(), eulO_to_axis_angle(), eulO_to_quat(), IS_EQF, normalize_qt(), quat_to_axis_angle(), quat_to_eulO(), ROT_MODE_AXISANGLE, and ROT_MODE_QUAT.

Referenced by pose_bone_rotmode_exec().

◆ bone_autoside_name()

bool bone_autoside_name ( char name[MAXBONENAME],
int ,
short axis,
float head,
float tail )

Definition at line 852 of file armature.cc.

References BLI_snprintf(), ELEM, IS_EQF, len, MAXBONENAME, and STRNCPY.

◆ compute_bbone_segment_boundaries()

◆ copy_bone_collection()

static void copy_bone_collection ( bArmature * armature_dst,
BoneCollection *& bcoll_dst,
const BoneCollection * bcoll_src,
const int lib_id_flag )
static

Copies the bone collection in bcoll_src to bcoll_dst, re-hooking up all of the bone relationships to the bones in armature_dst.

Note
this function's use case is narrow in scope, intended only for use in armature_copy_data() below. You probably don't want to use this otherwise.
Parameters
lib_id_flagCopying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more).

Definition at line 106 of file armature.cc.

References BKE_armature_find_bone_name(), BLI_duplicatelist(), BoneCollection::bones, IDP_CopyProperty_ex(), LISTBASE_FOREACH, MEM_dupallocN, and BoneCollection::prop.

Referenced by armature_copy_data().

◆ copy_bone_transform()

static void copy_bone_transform ( Bone * bone_dst,
const Bone * bone_src )
static

◆ copy_bonechildren()

static void copy_bonechildren ( Bone * bone_dst,
const Bone * bone_src,
const Bone * bone_src_act,
Bone ** r_bone_dst_act,
const int flag )
static

◆ copy_bonechildren_custom_handles()

static void copy_bonechildren_custom_handles ( Bone * bone_dst,
bArmature * arm_dst )
static

◆ direct_link_bone_collection()

static void direct_link_bone_collection ( BlendDataReader * reader,
BoneCollection * bcoll )
static

◆ direct_link_bones()

◆ ease_handle_axis()

static void ease_handle_axis ( const float deriv1[3],
const float deriv2[3],
float r_axis[3] )
static

Definition at line 1489 of file armature.cc.

References copy_v3_v3(), len_squared_v3(), madd_v3_v3fl(), sqrtf, and UNLIKELY.

Referenced by BKE_pchan_bbone_spline_compute().

◆ equalize_cubic_bezier()

static void equalize_cubic_bezier ( const float control[4][3],
int temp_segments,
int final_segments,
const float * segment_scales,
float * r_t_points )
static

◆ evaluate_cubic_bezier()

static void evaluate_cubic_bezier ( const float control[4][3],
float t,
float r_pos[3],
float r_tangent[3] )
static

Definition at line 1043 of file armature.cc.

References interp_v3_v3v3(), madd_v3_v3v3fl(), and sub_v3_v3v3().

Referenced by BKE_pchan_bbone_spline_compute().

◆ find_bbone_segment_index_curved()

static void find_bbone_segment_index_curved ( const bPoseChannel * pchan,
const float * co,
int * r_index,
float * r_blend_next )
static

◆ find_bbone_segment_index_straight()

static void find_bbone_segment_index_straight ( const bPoseChannel * pchan,
const float * co,
int * r_index,
float * r_blend_next )
static

◆ get_named_bone_bonechildren()

static Bone * get_named_bone_bonechildren ( ListBase * lb,
const char * name )
static

◆ make_bbone_spline_matrix()

static void make_bbone_spline_matrix ( BBoneSplineParameters * param,
const float scalemats[2][4][4],
const float pos[3],
const float axis[3],
float roll,
float scalex,
float scalez,
float result[4][4] )
static

◆ mat3_to_vec_roll()

void mat3_to_vec_roll ( const float mat[3][3],
float r_vec[3],
float * r_roll )

Computes vector and roll based on a rotation. "mat" must contain only a rotation, and no scaling.

Definition at line 2456 of file armature.cc.

References copy_v3_v3(), and mat3_vec_to_roll().

Referenced by armature_transform_recurse(), correct_bone_roll_value(), do_version_bone_roll_256(), ED_armature_ebone_from_mat3(), and ED_armature_edit_transform().

◆ mat3_vec_to_roll()

void mat3_vec_to_roll ( const float mat[3][3],
const float 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.

Definition at line 2467 of file armature.cc.

References invert_m3_m3(), mat3_to_quat(), mul_m3_m3m3(), quat_split_swing_and_twist(), and vec_roll_to_mat3().

Referenced by applyarmature_set_edit_position(), BKE_pchan_bbone_handles_compute(), mat3_to_vec_roll(), blender::bke::tests::TEST(), and blender::bke::tests::TEST().

◆ pose_channel_find_bone()

static bPoseChannel * pose_channel_find_bone ( bPose * pose,
Bone * bone )
static

Find the matching pose channel using the bone name, if not nullptr.

Definition at line 2745 of file armature.cc.

References BKE_pose_channel_find_name(), and Bone::name.

Referenced by BKE_pchan_rebuild_bbone_handles().

◆ read_bone_collections()

◆ rebuild_pose_bone()

static int rebuild_pose_bone ( bPose * pose,
Bone * bone,
bPoseChannel * parchan,
int counter,
Bone ** r_last_visited_bone_p )
static

◆ vec_roll_to_mat3()

◆ vec_roll_to_mat3_normalized()

void vec_roll_to_mat3_normalized ( const float nor[3],
float roll,
float r_mat[3][3] )

Calculates the rest matrix of a bone based on its vector and a roll around that vector.

Given v = (v.x, v.y, v.z) our (normalized) bone vector, we want the rotation matrix M from the Y axis (so that M * (0, 1, 0) = v).

  • The rotation axis a lays on XZ plane, and it is orthonormal to v, hence to the projection of v onto XZ plane.
  • a = (v.z, 0, -v.x)

We know a is eigenvector of M (so M * a = a). Finally, we have w, such that M * w = (0, 1, 0) (i.e. the vector that will be aligned with Y axis once transformed). We know w is symmetric to v by the Y axis.

  • w = (-v.x, v.y, -v.z)

Solving this, we get (x, y and z being the components of v):

    ┌ (x^2 * y + z^2) / (x^2 + z^2),   x,   x * z * (y - 1) / (x^2 + z^2) ┐
M = │  x * (y^2 - 1)  / (x^2 + z^2),   y,    z * (y^2 - 1)  / (x^2 + z^2) │
    └ x * z * (y - 1) / (x^2 + z^2),   z,   (x^2 + z^2 * y) / (x^2 + z^2) ┘

This is stable as long as v (the bone) is not too much aligned with +/-Y (i.e. x and z components are not too close to 0).

Since v is normalized, we have x^2 + y^2 + z^2 = 1, hence x^2 + z^2 = 1 - y^2 = (1 - y)(1 + y).

This allows to simplifies M like this:

    ┌ 1 - x^2 / (1 + y),   x,     -x * z / (1 + y) ┐
M = │                -x,   y,                   -z │
    └  -x * z / (1 + y),   z,    1 - z^2 / (1 + y) ┘

Written this way, we see the case v = +Y is no more a singularity. The only one remaining is the bone being aligned with -Y.

Let's handle the asymptotic behavior when bone vector is reaching the limit of y = -1. Each of the four corner elements can vary from -1 to 1, depending on the axis a chosen for doing the rotation. And the "rotation" here is in fact established by mirroring XZ plane by that given axis, then inversing the Y-axis. For sufficiently small x and z, and with y approaching -1, all elements but the four corner ones of M will degenerate. So let's now focus on these corner elements.

We rewrite M so that it only contains its four corner elements, and combine the 1 / (1 + y) factor:

                   ┌ 1 + y - x^2,        -x * z ┐
M* = 1 / (1 + y) * │                            │
                   └      -x * z,   1 + y - z^2 ┘

When y is close to -1, computing 1 / (1 + y) will cause severe numerical instability, so we use a different approach based on x and z as inputs. We know y^2 = 1 - (x^2 + z^2), and y < 0, hence y = -sqrt(1 - (x^2 + z^2)).

Since x and z are both close to 0, we apply the binomial expansion to the second order: y = -sqrt(1 - (x^2 + z^2)) = -1 + (x^2 + z^2) / 2 + (x^2 + z^2)^2 / 8, which allows eliminating the problematic 1 constant.

A first order expansion allows simplifying to this, but second order is more precise:

                       ┌  z^2 - x^2,  -2 * x * z ┐
M* = 1 / (x^2 + z^2) * │                         │
                       └ -2 * x * z,   x^2 - z^2 ┘

P.S. In the end, this basically is a heavily optimized version of Damped Track +Y.

Definition at line 2482 of file armature.cc.

References axis_angle_normalized_to_mat3(), BLI_ASSERT_UNIT_V3, mul_m3_m3m3(), nor, unit_m3(), x, y, and z().

Referenced by ED_armature_ebone_roll_to_vector(), ED_armature_ebone_to_mat3(), blender::bke::tests::find_flip_boundary(), blender::bke::tests::test_vec_roll_to_mat3_normalized(), and vec_roll_to_mat3().

◆ write_bone()

static void write_bone ( BlendWriter * writer,
Bone * bone )
static

◆ write_bone_collection()

static void write_bone_collection ( BlendWriter * writer,
BoneCollection * bcoll )
static

Variable Documentation

◆ IDType_ID_AR

IDTypeInfo IDType_ID_AR
Initial value:
= {
sizeof(bArmature),
"Armature",
N_("armatures"),
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
}
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition BKE_idtype.hh:39
#define BLT_I18NCONTEXT_ID_ARMATURE
#define FILTER_ID_ALL
Definition DNA_ID.h:1206
#define FILTER_ID_AR
Definition DNA_ID.h:1165
@ INDEX_ID_AR
Definition DNA_ID.h:1292
@ ID_AR
struct bArmature bArmature
static void armature_undo_preserve(BlendLibReader *, ID *id_new, ID *id_old)
Definition armature.cc:469
static void armature_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int flag)
Definition armature.cc:135
static void armature_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition armature.cc:312
static void armature_free_data(ID *id)
Definition armature.cc:201
static void armature_foreach_id(ID *id, LibraryForeachIDData *data)
Definition armature.cc:256
static void armature_init_data(ID *id)
Definition armature.cc:89
static void armature_blend_read_data(BlendDataReader *reader, ID *id)
Definition armature.cc:445
#define N_(msgid)

Definition at line 477 of file armature.cc.