82 ListBase targets = {
nullptr,
nullptr};
87 if (ct->tar == srcArm) {
88 if (ct->subtarget[0] ==
'\0') {
92 else if (
STREQ(ct->subtarget, pchan->
name)) {
110 data->action_slot_handle,
136 ID *src_id = &srcArm->
id;
137 ID *dst_id = &tarArm->
id;
140 bool changed =
false;
143 if ((
id == src_id) && strstr(fcu->
rna_path,
"pose.bones[")) {
150 if (!
STREQ(old_name, new_name) && strstr(fcu->
rna_path, old_name)) {
152 id, fcu->
rna_path,
"pose.bones", old_name, new_name, 0, 0,
false);
178 if (dtar->id == src_id) {
187 if ((dtar->rna_path && strstr(dtar->rna_path,
"pose.bones[")) || (dtar->pchan_name[0])) {
190 const char *new_name =
static_cast<const char *
>(
194 if (!
STREQ(old_name, new_name)) {
195 if ((dtar->rna_path) && strstr(dtar->rna_path, old_name)) {
198 id, dtar->rna_path,
"pose.bones", old_name, new_name, 0, 0,
false);
201 if (
STREQ(dtar->pchan_name, old_name)) {
236 bmain, ob, tarArm, srcArm, pchan, curbone, &pchant->constraints);
243 bmain, ob, tarArm, srcArm, pchan, curbone, &ob->
constraints);
282 int parent_index = -1;
284 if (src_parent_index >= 0) {
286 src_arm, src_parent_index, dest_arm, bone_collection_by_name);
307 bone_collection_by_name.
add(bcoll->
name, new_bcoll);
320 float mat[4][4], oimat[4][4];
327 if (!arm || arm->
edbo) {
332 if (ob_iter == ob_active) {
355 if (seen_armatures.
add(armature)) {
362 "Cannot join objects that share armature data: %s",
377 bone_collection_by_name.
add(bcoll->name, bcoll);
388 pose = ob_active->
pose;
392 if ((ob_iter->type ==
OB_ARMATURE) && (ob_iter != ob_active)) {
407 curarm,
i, arm, bone_collection_by_name);
413 opose = ob_iter->pose;
418 mul_m4_m4m4(mat, oimat, ob_iter->object_to_world().ptr());
422 pchann = pchan->
next;
454 curbone->
roll -=
atan2f(difmat[2][0], difmat[2][2]);
475 bcoll_ref->bcoll = bone_collection_remap.
lookup(bcoll_ref->bcoll);
499 if (ob_active->
adt ==
nullptr) {
511 if (arm->
adt ==
nullptr) {
566 ListBase targets = {
nullptr,
nullptr};
576 if (ct->subtarget[0] != 0) {
577 if (ct->tar == origArm) {
582 else if (ct->tar == newArm) {
599 ListBase targets = {
nullptr,
nullptr};
608 if (ct->subtarget[0] !=
'\0') {
609 if (ct->tar == origArm) {
614 else if (ct->tar == newArm) {
657 pchann = pchan->
next;
665 if (ebo->parent == curbone) {
666 ebo->parent =
nullptr;
668 ebo->temp.p =
nullptr;
675 if (pchn->parent == pchan) {
676 pchn->parent =
nullptr;
678 if (pchn->bbone_next == pchan) {
679 pchn->bbone_next =
nullptr;
681 if (pchn->bbone_prev == pchan) {
682 pchn->bbone_prev =
nullptr;
716 for (
Base *base_old : bases) {
717 Object *ob_old = base_old->object;
721 bool has_selected_bone =
false;
722 bool has_selected_any =
false;
726 has_selected_bone =
true;
730 has_selected_any =
true;
734 if (has_selected_bone ==
false) {
735 if (has_selected_any) {
806 ot->name =
"Separate Bones";
807 ot->idname =
"ARMATURE_OT_separate";
808 ot->description =
"Isolate selected bones into a separate armature";
825#define ARM_PAR_CONNECT 1
826#define ARM_PAR_OFFSET 2
829#define ARM_PAR_CLEAR 1
830#define ARM_PAR_CLEAR_DISCONNECT 2
853 selbone->
parent = actbone;
856 for (ebone = actbone->
parent; ebone; ebone = ebone->
parent) {
857 if (ebone->
parent == selbone) {
878 if (par == selbone) {
895 {0,
nullptr, 0,
nullptr,
nullptr},
907 if (actbone ==
nullptr) {
920 if (actmirb ==
nullptr) {
927 bool is_active_only_selected =
false;
929 is_active_only_selected =
true;
932 if (ebone != actbone) {
933 is_active_only_selected =
false;
940 if (is_active_only_selected) {
964 if (ebone != actbone) {
971 if (ebone_mirror != actmirb) {
992 bool enable_offset =
false;
994 bool enable_connect =
false;
1003 if (ebone == actbone) {
1007 if (ebone->parent != actbone) {
1008 enable_offset =
true;
1009 enable_connect =
true;
1013 enable_connect =
true;
1024 PointerRNA op_ptr = row_offset->
op(
"ARMATURE_OT_parent_set",
IFACE_(
"Keep Offset"), ICON_NONE);
1029 op_ptr = row_connect->
op(
"ARMATURE_OT_parent_set",
IFACE_(
"Connected"), ICON_NONE);
1040 ot->name =
"Make Parent";
1041 ot->idname =
"ARMATURE_OT_parent_set";
1042 ot->description =
"Set the active bone as the parent of the selected bones";
1059 {0,
nullptr, 0,
nullptr,
nullptr},
1088 for (
Object *ob : objects) {
1090 bool changed =
false;
1116 bool enable_disconnect =
false;
1118 bool enable_clear =
false;
1126 if (ebone->parent ==
nullptr) {
1129 enable_clear =
true;
1132 enable_disconnect =
true;
1144 PointerRNA op_ptr = row_clear->
op(
"ARMATURE_OT_parent_clear",
IFACE_(
"Clear Parent"), ICON_NONE);
1149 op_ptr = row_disconnect->
op(
"ARMATURE_OT_parent_clear",
IFACE_(
"Disconnect Bone"), ICON_NONE);
1160 ot->name =
"Clear Parent";
1161 ot->idname =
"ARMATURE_OT_parent_clear";
1163 "Remove the parent-child relationship between selected bones and their parents";
1178 "What way to clear parenting");
Functions to deal with Armatures.
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
void ANIM_armature_runtime_refresh(bArmature *armature)
BoneCollection * ANIM_armature_bonecoll_new(bArmature *armature, const char *name, int parent_index=-1)
Blender kernel action and pose functionality.
void BKE_pose_channels_hash_free(bPose *pose) ATTR_NONNULL(1)
void BKE_pose_channel_free(bPoseChannel *pchan) ATTR_NONNULL(1)
void BKE_animdata_merge_copy(Main *bmain, ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
AnimData * BKE_animdata_copy(Main *bmain, AnimData *adt, int flag)
void BKE_fcurves_main_cb(struct Main *bmain, blender::FunctionRef< void(ID *, FCurve *)> func)
void BKE_action_fix_paths_rename(struct ID *owner_id, struct bAction *act, int32_t slot_handle, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
char * BKE_animsys_fix_rna_path_rename(struct ID *owner_id, char *old_path, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targets, bool no_copy)
int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targets)
#define CTX_DATA_BEGIN(C, Type, instance, member)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
Main * CTX_data_main(const bContext *C)
EditBone * CTX_data_active_bone(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
#define DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
#define DRIVER_TARGETS_LOOPER_END
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
blender::Vector< Base * > BKE_view_layer_array_from_bases_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
#define GHASH_ITER(gh_iter_, ghash_)
GHash * BLI_ghash_str_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void invert_m4_m4_safe_ortho(float inverse[4][4], const float mat[4][4])
void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4])
void unit_m4(float m[4][4])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
#define STRNCPY_UTF8(dst, src)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_OPERATOR_DEFAULT
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
Object is a sort of wrapper for general info.
#define EBONE_EDITABLE(ebone)
void ED_outliner_select_sync_from_object_tag(bContext *C)
bool ED_operator_editarmature(bContext *C)
Read Guarded memory(de)allocation.
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(bContext *C, const char *title, int icon) ATTR_NONNULL()
uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void bone_free(bArmature *arm, EditBone *bone)
void ED_armature_ebone_unique_name(ListBase *ebones, char *name, EditBone *bone)
static void separate_armature_bones(Main *bmain, Object *ob, const bool is_select)
static wmOperatorStatus armature_parent_clear_invoke(bContext *C, wmOperator *, const wmEvent *)
static void joined_armature_fix_links(Main *bmain, Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone)
static const EnumPropertyItem prop_editarm_clear_parent_types[]
static wmOperatorStatus armature_parent_set_invoke(bContext *C, wmOperator *, const wmEvent *)
static wmOperatorStatus armature_parent_set_exec(bContext *C, wmOperator *op)
void ARMATURE_OT_parent_clear(wmOperatorType *ot)
static void joined_armature_fix_animdata_cb(Main *bmain, ID *id, FCurve *fcu, Object *srcArm, Object *tarArm, GHash *names_map)
static BoneCollection * join_armature_remap_collection(const bArmature *src_arm, const int src_index, bArmature *dest_arm, blender::Map< std::string, BoneCollection * > &bone_collection_by_name)
#define ARM_PAR_CLEAR_DISCONNECT
static void joined_armature_fix_links_constraints(Main *bmain, Object *ob, Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone, ListBase *lb)
void ARMATURE_OT_parent_set(wmOperatorType *ot)
static void separated_armature_fix_links(Main *bmain, Object *origArm, Object *newArm)
static void bone_connect_to_new_parent(ListBase *edbo, EditBone *selbone, EditBone *actbone, short mode)
wmOperatorStatus ED_armature_join_objects_exec(bContext *C, wmOperator *op)
static wmOperatorStatus separate_armature_exec(bContext *C, wmOperator *op)
void ARMATURE_OT_separate(wmOperatorType *ot)
static void editbone_clear_parent(EditBone *ebone, int mode)
static wmOperatorStatus armature_parent_clear_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem prop_editarm_make_parent_types[]
static void bone_connect_to_existing_parent(EditBone *bone)
bool ED_armature_edit_deselect_all(Object *obedit)
EditBone * ED_armature_ebone_find_name(const ListBase *edbo, const char *name)
void ED_armature_edit_sync_selection(ListBase *edbo)
void ED_armature_edit_free(bArmature *arm)
void ED_armature_ebone_to_mat3(EditBone *ebone, float r_mat[3][3])
void ED_armature_from_edit(Main *bmain, bArmature *arm)
void ED_armature_to_edit(bArmature *arm)
EditBone * ED_armature_ebone_get_mirrored(const ListBase *edbo, EditBone *ebo)
BMesh const char void * data
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
Value lookup_default(const Key &key, const Value &default_value) const
DEG_id_tag_update_ex(cb_data->bmain, cb_data->owner_id, ID_RECALC_TAG_FOR_UNDO|ID_RECALC_SYNC_TO_EVAL)
void MEM_freeN(void *vmemh)
bool bone_is_visible(const bArmature *armature, const Bone *bone)
bool bone_is_selected(const bArmature *armature, const Bone *bone)
int armature_bonecoll_find_index(const bArmature *armature, const ::BoneCollection *bcoll)
int armature_bonecoll_find_parent_index(const bArmature *armature, int bcoll_index)
Base * add_duplicate(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base, eDupli_ID_Flags dupflag)
void base_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
struct IDProperty * system_properties
ListBase bone_collections
struct BoneCollection ** collection_array
struct EditBone * act_edbone
struct bPoseChannel * next
void enabled_set(bool enabled)
uiLayout & row(bool align)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
struct ReportList * reports
void WM_cursor_wait(bool val)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)