136 EditBone *ebone, *newbone, *flipbone;
137 float mat[3][3], imat[3][3];
178 for (
a = 0;
a < 2;
a++) {
180 if (flipbone ==
NULL) {
206 newbone->
tail[0] = -newbone->
tail[0];
236 float tvec[3], oldcurs[3], mval_f[2];
263 ot->
name =
"Click-Extrude";
264 ot->
idname =
"ARMATURE_OT_click_extrude";
265 ot->
description =
"Create a new bone going from the last selected joint to the mouse position";
296 for (eBone = edbo->
first; eBone; eBone = eBone->
next) {
322 const char *name_src = pchan_src->
name;
328 if (pchan_dst ==
NULL) {
329 pchan_dst = pchan_src;
383 bool lookup_mirror_subtarget)
395 for (curcon = conlist->
first; curcon; curcon = curcon->
next) {
406 for (ct = targets.
first; ct; ct = ct->
next) {
418 else if (lookup_mirror_subtarget) {
460 float max_axis_val = 0;
463 for (
int i = 0; i < 3; i++) {
464 float cur_val =
fabsf(mat[0][i]);
465 if (cur_val > max_axis_val) {
467 max_axis_val = cur_val;
477 if (act_con->
type < 10 && act_con->
type != max_axis) {
479 act_con->
min = -act_con->
min;
480 act_con->
max = -act_con->
max;
482 else if (act_con->
type == max_axis + 10) {
485 else if (act_con->
type == max_axis + 20) {
491 float min_vec[3], max_vec[3];
496 min_vec[0] = act_con->
min;
497 max_vec[0] = act_con->
max;
510 act_con->
min = min_vec[0];
511 act_con->
max = max_vec[0];
521 FCurve *old_curve = ld->data;
525 char *old_path = new_curve->
rna_path;
533 for (i = 0, bezt = new_curve->
bezt; i < new_curve->totvert; i++, bezt++) {
534 const size_t slength = strlen(new_curve->
rna_path);
554 bezt->
vec[0][1] *= -1;
555 bezt->
vec[1][1] *= -1;
556 bezt->
vec[2][1] *= -1;
594 float local_mat[4][4], imat[4][4];
596 float min_vec[3], max_vec[3];
598 min_vec[0] = limit->
xmin;
599 min_vec[1] = limit->
ymin;
600 min_vec[2] = limit->
zmin;
602 max_vec[0] = limit->
xmax;
603 max_vec[1] = limit->
ymax;
604 max_vec[2] = limit->
zmax;
616 local_mat[3][0] = local_mat[3][1] = local_mat[3][2] = 0;
629 min_vec[1] = max_vec[1] * -1;
630 min_vec[2] = max_vec[2] * -1;
632 max_vec[1] = min_copy[1] * -1;
633 max_vec[2] = min_copy[2] * -1;
636 float min_x_copy = min_vec[0];
638 min_vec[0] = max_vec[0] * -1;
639 max_vec[0] = min_x_copy * -1;
646 limit->
xmin = min_vec[0];
647 limit->
ymin = min_vec[1];
648 limit->
zmin = min_vec[2];
650 limit->
xmax = max_vec[0];
651 limit->
ymax = max_vec[1];
652 limit->
zmax = max_vec[2];
661 float target_mat[4][4], own_mat[4][4], imat[4][4];
671 float old_min, old_max;
680 old_min = trans->from_min[0];
681 old_max = trans->from_max[0];
683 trans->from_min[0] = -old_max;
684 trans->from_max[0] = -old_min;
693 own_mat[3][0] = own_mat[3][1] = own_mat[3][2] = 0;
701 old_min = trans->from_min_rot[1];
702 old_max = trans->from_max_rot[1];
704 trans->from_min_rot[1] = old_max * -1;
705 trans->from_max_rot[1] = old_min * -1;
707 old_min = trans->from_min_rot[2];
708 old_max = trans->from_max_rot[2];
710 trans->from_min_rot[2] = old_max * -1;
711 trans->from_max_rot[2] = old_min * -1;
721 float imat_rot[4][4];
732 mul_m4_v3(target_mat, trans->to_min_scale);
733 mul_m4_v3(target_mat, trans->to_max_scale);
736 target_mat[3][0] = target_mat[3][1] = target_mat[3][2] = 0;
739 mul_m4_v3(target_mat, trans->to_min_rot);
740 mul_m4_v3(target_mat, trans->to_max_rot);
754 for (
int i = 0; i < 3; i++) {
760 trans->to_max_scale[i] = trans->to_min_scale[i];
761 trans->to_min_scale[i] = temp_vec[i];
767 trans->to_min[0] *= -1;
768 trans->to_max[0] *= -1;
772 for (
int i = 0; i < 3; i++) {
778 trans->to_max[i] = trans->to_min[i];
779 trans->to_min[i] = temp_vec[i];
785 trans->to_min_rot[2] *= -1;
786 trans->to_max_rot[2] *= -1;
791 trans->to_min_rot[1] *= -1;
792 trans->to_max_rot[1] *= -1;
797 for (
int i = 0; i < 3; i++) {
804 trans->to_max_rot[i] = trans->to_min_rot[i];
805 trans->to_min_rot[i] = temp_vec[i];
833 for (curcon = conlist->
first; curcon; curcon = curcon->
next) {
834 switch (curcon->
type) {
868 if (shape_ob !=
NULL) {
878 if (src_bone->
prop) {
908 memcpy(e_bone, cur_bone,
sizeof(
EditBone));
940 uint objects_len = 0;
943 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
948 Object *ob = objects[ob_index];
957 for (ebone_iter = arm->
edbo->
first; ebone_iter; ebone_iter = ebone_iter->
next) {
970 for (ebone_iter = arm->
edbo->
first; ebone_iter && ebone_iter != ebone_first_dupe;
971 ebone_iter = ebone_iter->
next) {
975 char *new_bone_name = ebone_iter->
name;
979 new_bone_name_buff, ebone_iter->
name,
false,
sizeof(new_bone_name_buff));
984 new_bone_name = new_bone_name_buff;
990 if (!ebone_first_dupe) {
991 ebone_first_dupe = ebone;
997 for (ebone_iter = arm->
edbo->
first; ebone_iter && ebone_iter != ebone_first_dupe;
998 ebone_iter = ebone_iter->
next) {
1002 if (!ebone_iter->
parent) {
1043 for (ebone_iter = arm->
edbo->
first; ebone_iter && ebone_iter != ebone_first_dupe;
1044 ebone_iter = ebone_iter->
next) {
1067 ot->
name =
"Duplicate Selected Bone(s)";
1068 ot->
idname =
"ARMATURE_OT_duplicate";
1069 ot->
description =
"Make copies of the selected bones within the same armature";
1083 "Try to flip names of the bones, if possible, instead of adding a number extension");
1097 return (mirror !=
NULL) ? mirror : bone;
1115 uint objects_len = 0;
1118 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
1119 Object *obedit = objects[ob_index];
1131 for (ebone_iter = arm->
edbo->
first; ebone_iter; ebone_iter = ebone_iter->
next) {
1137 if (
STREQ(name_flip, ebone_iter->
name)) {
1153 axis_delta = ebone->
head[axis] - ebone_iter->
head[axis];
1154 if (axis_delta == 0.0f) {
1155 axis_delta = ebone->
tail[axis] - ebone_iter->
tail[axis];
1158 if (axis_delta == 0.0f) {
1168 if (((axis_delta < 0.0f) ? -1 : 1) == direction) {
1170 ebone_dst = ebone_iter;
1173 ebone_src = ebone_iter;
1187 for (ebone_iter = arm->
edbo->
first; ebone_iter && ebone_iter != ebone_first_dupe;
1188 ebone_iter = ebone_iter->
next) {
1209 if (!
STREQ(name_flip, ebone_iter->
name)) {
1214 if (!ebone_first_dupe) {
1215 ebone_first_dupe = ebone;
1222 for (ebone_iter = arm->
edbo->
first; ebone_iter && ebone_iter != ebone_first_dupe;
1223 ebone_iter = ebone_iter->
next) {
1231 ebone->
flag = (ebone->
flag & ~flag_copy) | (ebone_iter->
flag & flag_copy);
1244 if (ebone_parent == ebone_iter->
parent) {
1250 if (ebone->
head[axis] != 0.0f) {
1257 ebone->
parent = ebone_parent;
1286 for (ebone_iter = arm->
edbo->
first; ebone_iter && ebone_iter != ebone_first_dupe;
1287 ebone_iter = ebone_iter->
next) {
1294 for (ebone_iter = arm->
edbo->
first; ebone_iter && ebone_iter != ebone_first_dupe;
1295 ebone_iter = ebone_iter->
next) {
1324 {-1,
"NEGATIVE_X", 0,
"-X to +X",
""},
1325 {+1,
"POSITIVE_X", 0,
"+X to -X",
""},
1331 ot->
idname =
"ARMATURE_OT_symmetrize";
1332 ot->
description =
"Enforce symmetry, make copies of the selection or use existing";
1343 arm_symmetrize_direction_items,
1346 "Which sides to copy from and to (when both are selected)");
1358 bool changed_multi =
false;
1360 uint objects_len = 0;
1363 for (
uint ob_index = 0; ob_index < objects_len; ob_index++) {
1364 Object *ob = objects[ob_index];
1366 bool forked_iter = forked;
1369 int a, totbone = 0, do_extrude;
1372 for (ebone = arm->
edbo->
first; ebone; ebone = ebone->next) {
1385 for (ebone = arm->
edbo->
first; ((ebone) && (ebone != first)); ebone = ebone->next) {
1394 if (ebone->parent && (ebone->parent->flag &
BONE_TIPSEL)) {
1414 if ((flipbone ==
NULL) && (forked_iter)) {
1419 for (
a = 0;
a < 2;
a++) {
1421 if (flipbone ==
NULL) {
1430 if (do_extrude ==
true) {
1454 newbone->
weight = ebone->weight;
1455 newbone->
dist = ebone->dist;
1456 newbone->
xwidth = ebone->xwidth;
1457 newbone->
zwidth = ebone->zwidth;
1458 newbone->
rad_head = ebone->rad_tail;
1459 newbone->
rad_tail = ebone->rad_tail;
1461 newbone->
layer = ebone->layer;
1464 newbone->
roll1 = ebone->roll1;
1465 newbone->
roll2 = ebone->roll2;
1470 newbone->
ease1 = ebone->ease1;
1471 newbone->
ease2 = ebone->ease2;
1479 if (flipbone && forked_iter) {
1482 strcat(newbone->
name,
"_L");
1485 strcat(newbone->
name,
"_R");
1498 if (
a == 1 && flipbone) {
1509 if (totbone == 1 && first) {
1520 changed_multi =
true;
1530 if (!changed_multi) {
1543 ot->
idname =
"ARMATURE_OT_extrude";
1544 ot->
description =
"Create new bones from the selected joints";
1566 float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3];
1616 ot->
idname =
"ARMATURE_OT_bone_primitive_add";
1617 ot->
description =
"Add a new bone located at the 3D cursor";
1649 for (i = cuts + 1; i > 1; i--) {
1651 float cutratio = 1.0f / (
float)i;
1652 float cutratioI = 1.0f - cutratio;
1667 val3[0] = val1[0] * cutratio + val2[0] * cutratioI;
1668 val3[1] = val1[1] * cutratio + val2[1] * cutratioI;
1669 val3[2] = val1[2] * cutratio + val2[2] * cutratioI;
1675 newbone->
rad_head = ((ebone->rad_head * cutratio) + (ebone->rad_tail * cutratioI));
1676 ebone->rad_tail = newbone->
rad_head;
1685 for (tbone = arm->edbo->first; tbone; tbone = tbone->
next) {
1686 if (tbone->
parent == ebone) {
1709 ot->
idname =
"ARMATURE_OT_subdivide";
1710 ot->
description =
"Break selected bones into chains of smaller bones";
1720 prop =
RNA_def_int(
ot->
srna,
"number_cuts", 1, 1, 1000,
"Number of Cuts",
"", 1, 10);
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bActionGroup * action_groups_add_new(struct bAction *act, const char name[])
void BKE_pose_channels_hash_free(struct bPose *pose)
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from)
void BKE_pose_channels_hash_make(struct bPose *pose)
void BKE_pose_channel_free(struct bPoseChannel *pchan)
struct bActionGroup * BKE_action_group_find_name(struct bAction *act, const char name[])
struct bPoseChannel * BKE_pose_channel_verify(struct bPose *pose, const char *name)
void action_groups_add_channel(struct bAction *act, struct bActionGroup *agrp, struct FCurve *fcurve)
void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, struct bConstraintOb *cob, float mat[4][4], short from, short to, const bool keep_scale)
void BKE_constraint_custom_object_space_get(float r_mat[4][4], struct bConstraint *con)
const bConstraintTypeInfo * BKE_constraint_typeinfo_get(struct bConstraint *con)
#define CTX_DATA_BEGIN_WITH_ID(C, Type, instance, member, Type_id, instance_id)
struct Scene * CTX_data_scene(const bContext *C)
struct Object * CTX_data_edit_object(const bContext *C)
struct ViewLayer * CTX_data_view_layer(const bContext *C)
struct View3D * CTX_wm_view3d(const bContext *C)
#define CTX_DATA_COUNT(C, member)
struct ARegion * CTX_wm_region(const bContext *C)
struct Main * CTX_data_main(const bContext *C)
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName)
struct FCurve * BKE_fcurve_copy(const struct FCurve *fcu)
struct IDProperty * IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
struct ID * BKE_libblock_find_name(struct Main *bmain, const short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
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)
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void mul_m3_v3(const float M[3][3], float r[3])
void unit_m3(float m[3][3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void unit_m4(float m[4][4])
bool invert_m4_m4(float R[4][4], const float A[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
bool invert_m3_m3(float R[3][3], const float A[3][3])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
float angle_wrap_rad(float angle)
MINLINE void copy_v2fl_v2i(float r[2], const int a[2])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
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_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t length) ATTR_NONNULL()
char * BLI_str_replaceN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_ANIMATION_NO_FLUSH
@ BONE_RELATIVE_PARENTING
@ CONSTRAINT_TYPE_TRANSFORM
@ CONSTRAINT_TYPE_ROTLIMIT
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_LOCLIMIT
Object is a sort of wrapper for general info.
#define EBONE_VISIBLE(arm, ebone)
#define EBONE_SELECTABLE(arm, ebone)
void ED_outliner_select_sync_from_edit_bone_tag(struct bContext *C)
bool ED_operator_editarmature(struct bContext *C)
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
Read Guarded memory(de)allocation.
static void updateDuplicateKinematicConstraintSettings(bConstraint *curcon)
void ARMATURE_OT_subdivide(wmOperatorType *ot)
static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
void postEditBoneDuplicate(struct ListBase *editbones, Object *ob)
static int armature_extrude_exec(bContext *C, wmOperator *op)
static void updateDuplicateSubtarget(EditBone *dup_bone, ListBase *editbones, Object *ob, bool lookup_mirror_subtarget)
static void updateDuplicateActionConstraintSettings(EditBone *dup_bone, EditBone *orig_bone, Object *ob, bConstraint *curcon)
static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
static EditBone * get_symmetrized_bone(bArmature *arm, EditBone *bone)
static void updateDuplicateTransformConstraintSettings(Object *ob, bPoseChannel *pchan, bConstraint *curcon)
void ARMATURE_OT_click_extrude(wmOperatorType *ot)
static void updateDuplicateConstraintSettings(EditBone *dup_bone, EditBone *orig_bone, Object *ob)
EditBone * ED_armature_ebone_add_primitive(Object *obedit_arm, float length, bool view_aligned)
void ARMATURE_OT_duplicate(wmOperatorType *ot)
void ARMATURE_OT_symmetrize(wmOperatorType *ot)
void ARMATURE_OT_extrude(wmOperatorType *ot)
static int armature_symmetrize_exec(bContext *C, wmOperator *op)
static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int armature_subdivide_exec(bContext *C, wmOperator *op)
EditBone * add_points_bone(Object *obedit, float head[3], float tail[3])
EditBone * ED_armature_ebone_add(bArmature *arm, const char *name)
void ARMATURE_OT_bone_primitive_add(wmOperatorType *ot)
static bPoseChannel * pchan_duplicate_map(const bPose *pose, GHash *name_map, bPoseChannel *pchan_src)
static void updateDuplicateLocRotConstraintSettings(Object *ob, bPoseChannel *pchan, bConstraint *curcon)
static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
EditBone * duplicateEditBone(EditBone *cur_bone, const char *name, ListBase *editbones, Object *ob)
void preEditBoneDuplicate(ListBase *editbones)
EditBone * duplicateEditBoneObjects(EditBone *cur_bone, const char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
static EditBone * get_named_editbone(ListBase *edbo, const char *name)
static void updateDuplicateCustomBoneShapes(bContext *C, EditBone *dup_bone, Object *ob)
static void copy_pchan(EditBone *src_bone, EditBone *dst_bone, Object *src_ob, Object *dst_ob)
void ED_armature_ebone_unique_name(ListBase *ebones, char *name, EditBone *bone)
bool ED_armature_edit_deselect_all(Object *obedit)
void ED_armature_edit_transform_mirror_update(Object *obedit)
void ED_armature_ebone_listbase_temp_clear(ListBase *lb)
void ED_armature_edit_refresh_layer_used(bArmature *arm)
void ED_armature_edit_sync_selection(ListBase *edbo)
void ED_armature_ebone_select_set(EditBone *ebone, bool select)
void ED_armature_edit_validate_active(struct bArmature *arm)
EditBone * ED_armature_ebone_find_name(const ListBase *edbo, const char *name)
EditBone * ED_armature_ebone_get_mirrored(const ListBase *edbo, EditBone *ebo)
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
struct EditBone * bbone_next
struct EditBone * bbone_prev
struct EditBone * act_edbone
float space_obj_world_matrix[4][4]
struct Depsgraph * depsgraph
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
struct bPoseChannel * custom_tx
struct bPoseChannel * bbone_next
struct bPoseChannel * bbone_prev
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
void WM_event_add_notifier(const bContext *C, uint type, void *reference)