Refactor: armature_add.cc
No functional changes expected. Change function names to be snake case as defined in the style guide[1]. Change functions to static if they aren't called outside the file. Use `continue` to un-indent code. Make function arguments `const` where possible. [1] https://developer.blender.org/docs/handbook/guidelines/c_cpp/#naming Pull Request: https://projects.blender.org/blender/blender/pulls/129946
This commit is contained in:
committed by
Christoph Lendenfeld
parent
c06c96b2b8
commit
c2371028e0
@@ -97,7 +97,9 @@ EditBone *ED_armature_ebone_add(bArmature *arm, const char *name)
|
|||||||
return bone;
|
return bone;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditBone *ED_armature_ebone_add_primitive(Object *obedit_arm, float length, bool view_aligned)
|
EditBone *ED_armature_ebone_add_primitive(Object *obedit_arm,
|
||||||
|
const float length,
|
||||||
|
const bool view_aligned)
|
||||||
{
|
{
|
||||||
bArmature *arm = static_cast<bArmature *>(obedit_arm->data);
|
bArmature *arm = static_cast<bArmature *>(obedit_arm->data);
|
||||||
EditBone *bone;
|
EditBone *bone;
|
||||||
@@ -144,19 +146,21 @@ static int armature_click_extrude_exec(bContext *C, wmOperator * /*op*/)
|
|||||||
|
|
||||||
/* find the active or selected bone */
|
/* find the active or selected bone */
|
||||||
for (ebone = static_cast<EditBone *>(arm->edbo->first); ebone; ebone = ebone->next) {
|
for (ebone = static_cast<EditBone *>(arm->edbo->first); ebone; ebone = ebone->next) {
|
||||||
if (EBONE_VISIBLE(arm, ebone)) {
|
if (!EBONE_VISIBLE(arm, ebone)) {
|
||||||
if (ebone->flag & BONE_TIPSEL || arm->act_edbone == ebone) {
|
continue;
|
||||||
break;
|
}
|
||||||
}
|
if (ebone->flag & BONE_TIPSEL || arm->act_edbone == ebone) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ebone == nullptr) {
|
if (ebone == nullptr) {
|
||||||
for (ebone = static_cast<EditBone *>(arm->edbo->first); ebone; ebone = ebone->next) {
|
for (ebone = static_cast<EditBone *>(arm->edbo->first); ebone; ebone = ebone->next) {
|
||||||
if (EBONE_VISIBLE(arm, ebone)) {
|
if (!EBONE_VISIBLE(arm, ebone)) {
|
||||||
if (ebone->flag & BONE_ROOTSEL || arm->act_edbone == ebone) {
|
continue;
|
||||||
break;
|
}
|
||||||
}
|
if (ebone->flag & BONE_ROOTSEL || arm->act_edbone == ebone) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ebone == nullptr) {
|
if (ebone == nullptr) {
|
||||||
@@ -302,14 +306,14 @@ static EditBone *get_named_editbone(ListBase *edbo, const char *name)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void preEditBoneDuplicate(ListBase *editbones)
|
static void pre_edit_bone_duplicate(ListBase *editbones)
|
||||||
{
|
{
|
||||||
/* clear temp */
|
/* clear temp */
|
||||||
ED_armature_ebone_listbase_temp_clear(editbones);
|
ED_armature_ebone_listbase_temp_clear(editbones);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function for #postEditBoneDuplicate,
|
* Helper function for #pose_edit_bone_duplicate,
|
||||||
* return the destination pchan from the original.
|
* return the destination pchan from the original.
|
||||||
*/
|
*/
|
||||||
static bPoseChannel *pchan_duplicate_map(const bPose *pose,
|
static bPoseChannel *pchan_duplicate_map(const bPose *pose,
|
||||||
@@ -330,7 +334,7 @@ static bPoseChannel *pchan_duplicate_map(const bPose *pose,
|
|||||||
return pchan_dst;
|
return pchan_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void postEditBoneDuplicate(ListBase *editbones, Object *ob)
|
static void pose_edit_bone_duplicate(ListBase *editbones, Object *ob)
|
||||||
{
|
{
|
||||||
if (ob->pose == nullptr) {
|
if (ob->pose == nullptr) {
|
||||||
return;
|
return;
|
||||||
@@ -382,60 +386,64 @@ void postEditBoneDuplicate(ListBase *editbones, Object *ob)
|
|||||||
BLI_ghash_free(name_map, nullptr, nullptr);
|
BLI_ghash_free(name_map, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateSubtarget(EditBone *dup_bone,
|
static void update_duplicate_subtarget(EditBone *dup_bone,
|
||||||
ListBase *editbones,
|
ListBase *editbones,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
bool lookup_mirror_subtarget)
|
const bool lookup_mirror_subtarget)
|
||||||
{
|
{
|
||||||
/* If an edit bone has been duplicated, lets update its constraints if the
|
/* If an edit bone has been duplicated, lets update its constraints if the
|
||||||
* subtarget they point to has also been duplicated.
|
* subtarget they point to has also been duplicated.
|
||||||
*/
|
*/
|
||||||
|
bPoseChannel *pchan = BKE_pose_channel_ensure(ob->pose, dup_bone->name);
|
||||||
|
|
||||||
|
if (!pchan) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
EditBone *oldtarget, *newtarget;
|
EditBone *oldtarget, *newtarget;
|
||||||
bPoseChannel *pchan;
|
ListBase *conlist = &pchan->constraints;
|
||||||
|
LISTBASE_FOREACH (bConstraint *, curcon, conlist) {
|
||||||
|
/* does this constraint have a subtarget in
|
||||||
|
* this armature?
|
||||||
|
*/
|
||||||
|
ListBase targets = {nullptr, nullptr};
|
||||||
|
|
||||||
if ((pchan = BKE_pose_channel_ensure(ob->pose, dup_bone->name))) {
|
if (!BKE_constraint_targets_get(curcon, &targets)) {
|
||||||
ListBase *conlist = &pchan->constraints;
|
continue;
|
||||||
LISTBASE_FOREACH (bConstraint *, curcon, conlist) {
|
}
|
||||||
/* does this constraint have a subtarget in
|
LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
|
||||||
* this armature?
|
if ((ct->tar != ob) && (!ct->subtarget[0])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
oldtarget = get_named_editbone(editbones, ct->subtarget);
|
||||||
|
if (!oldtarget) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* was the subtarget bone duplicated too? If
|
||||||
|
* so, update the constraint to point at the
|
||||||
|
* duplicate of the old subtarget.
|
||||||
*/
|
*/
|
||||||
ListBase targets = {nullptr, nullptr};
|
if (oldtarget->temp.ebone) {
|
||||||
|
newtarget = oldtarget->temp.ebone;
|
||||||
|
STRNCPY(ct->subtarget, newtarget->name);
|
||||||
|
}
|
||||||
|
else if (lookup_mirror_subtarget) {
|
||||||
|
/* The subtarget was not selected for duplication, try to see if a mirror bone of
|
||||||
|
* the current target exists */
|
||||||
|
char name_flip[MAXBONENAME];
|
||||||
|
|
||||||
if (BKE_constraint_targets_get(curcon, &targets)) {
|
BLI_string_flip_side_name(name_flip, oldtarget->name, false, sizeof(name_flip));
|
||||||
LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
|
newtarget = get_named_editbone(editbones, name_flip);
|
||||||
if ((ct->tar == ob) && (ct->subtarget[0])) {
|
if (newtarget) {
|
||||||
oldtarget = get_named_editbone(editbones, ct->subtarget);
|
STRNCPY(ct->subtarget, newtarget->name);
|
||||||
if (oldtarget) {
|
|
||||||
/* was the subtarget bone duplicated too? If
|
|
||||||
* so, update the constraint to point at the
|
|
||||||
* duplicate of the old subtarget.
|
|
||||||
*/
|
|
||||||
if (oldtarget->temp.ebone) {
|
|
||||||
newtarget = oldtarget->temp.ebone;
|
|
||||||
STRNCPY(ct->subtarget, newtarget->name);
|
|
||||||
}
|
|
||||||
else if (lookup_mirror_subtarget) {
|
|
||||||
/* The subtarget was not selected for duplication, try to see if a mirror bone of
|
|
||||||
* the current target exists */
|
|
||||||
char name_flip[MAXBONENAME];
|
|
||||||
|
|
||||||
BLI_string_flip_side_name(name_flip, oldtarget->name, false, sizeof(name_flip));
|
|
||||||
newtarget = get_named_editbone(editbones, name_flip);
|
|
||||||
if (newtarget) {
|
|
||||||
STRNCPY(ct->subtarget, newtarget->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BKE_constraint_targets_flush(curcon, &targets, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BKE_constraint_targets_flush(curcon, &targets, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateActionConstraintSettings(
|
static void update_duplicate_action_constraint_settings(
|
||||||
EditBone *dup_bone, EditBone *orig_bone, Object *ob, bPoseChannel *pchan, bConstraint *curcon)
|
EditBone *dup_bone, EditBone *orig_bone, Object *ob, bPoseChannel *pchan, bConstraint *curcon)
|
||||||
{
|
{
|
||||||
bActionConstraint *act_con = (bActionConstraint *)curcon->data;
|
bActionConstraint *act_con = (bActionConstraint *)curcon->data;
|
||||||
@@ -587,7 +595,7 @@ static void updateDuplicateActionConstraintSettings(
|
|||||||
DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
|
DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateKinematicConstraintSettings(bConstraint *curcon)
|
static void update_duplicate_kinematics_constraint_settings(bConstraint *curcon)
|
||||||
{
|
{
|
||||||
/* IK constraint */
|
/* IK constraint */
|
||||||
bKinematicConstraint *ik = (bKinematicConstraint *)curcon->data;
|
bKinematicConstraint *ik = (bKinematicConstraint *)curcon->data;
|
||||||
@@ -596,9 +604,9 @@ static void updateDuplicateKinematicConstraintSettings(bConstraint *curcon)
|
|||||||
ik->poleangle = angle_wrap_rad(ik->poleangle);
|
ik->poleangle = angle_wrap_rad(ik->poleangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateLocRotConstraintSettings(Object *ob,
|
static void update_duplicate_loc_rot_constraint_settings(Object *ob,
|
||||||
bPoseChannel *pchan,
|
bPoseChannel *pchan,
|
||||||
bConstraint *curcon)
|
bConstraint *curcon)
|
||||||
{
|
{
|
||||||
/* This code assumes that bRotLimitConstraint and bLocLimitConstraint have the same fields in
|
/* This code assumes that bRotLimitConstraint and bLocLimitConstraint have the same fields in
|
||||||
* the same memory locations. */
|
* the same memory locations. */
|
||||||
@@ -668,9 +676,9 @@ static void updateDuplicateLocRotConstraintSettings(Object *ob,
|
|||||||
limit->zmax = max_vec[2];
|
limit->zmax = max_vec[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateTransformConstraintSettings(Object *ob,
|
static void update_duplicate_transform_constraint_settings(Object *ob,
|
||||||
bPoseChannel *pchan,
|
bPoseChannel *pchan,
|
||||||
bConstraint *curcon)
|
bConstraint *curcon)
|
||||||
{
|
{
|
||||||
bTransformConstraint *trans = (bTransformConstraint *)curcon->data;
|
bTransformConstraint *trans = (bTransformConstraint *)curcon->data;
|
||||||
|
|
||||||
@@ -869,31 +877,33 @@ static void track_axis_x_swap(char &value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateConstraintTrackToSettings(bConstraint *curcon)
|
static void update_duplicate_constraint_track_to_settings(bConstraint *curcon)
|
||||||
{
|
{
|
||||||
bTrackToConstraint *data = static_cast<bTrackToConstraint *>(curcon->data);
|
bTrackToConstraint *data = static_cast<bTrackToConstraint *>(curcon->data);
|
||||||
track_axis_x_swap(data->reserved1);
|
track_axis_x_swap(data->reserved1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateConstraintLockTrackSettings(bConstraint *curcon)
|
static void update_duplicate_constraint_lock_track_settings(bConstraint *curcon)
|
||||||
{
|
{
|
||||||
bLockTrackConstraint *data = static_cast<bLockTrackConstraint *>(curcon->data);
|
bLockTrackConstraint *data = static_cast<bLockTrackConstraint *>(curcon->data);
|
||||||
track_axis_x_swap(data->trackflag);
|
track_axis_x_swap(data->trackflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateConstraintDampTrackSettings(bConstraint *curcon)
|
static void update_duplicate_constraint_damp_track_settings(bConstraint *curcon)
|
||||||
{
|
{
|
||||||
bDampTrackConstraint *data = static_cast<bDampTrackConstraint *>(curcon->data);
|
bDampTrackConstraint *data = static_cast<bDampTrackConstraint *>(curcon->data);
|
||||||
track_axis_x_swap(data->trackflag);
|
track_axis_x_swap(data->trackflag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateConstraintShrinkwrapSettings(bConstraint *curcon)
|
static void update_duplicate_constraint_shrinkwrap_settings(bConstraint *curcon)
|
||||||
{
|
{
|
||||||
bShrinkwrapConstraint *data = static_cast<bShrinkwrapConstraint *>(curcon->data);
|
bShrinkwrapConstraint *data = static_cast<bShrinkwrapConstraint *>(curcon->data);
|
||||||
track_axis_x_swap(data->trackAxis);
|
track_axis_x_swap(data->trackAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateConstraintSettings(EditBone *dup_bone, EditBone *orig_bone, Object *ob)
|
static void update_duplicate_constraint_settings(EditBone *dup_bone,
|
||||||
|
EditBone *orig_bone,
|
||||||
|
Object *ob)
|
||||||
{
|
{
|
||||||
/* If an edit bone has been duplicated, lets update its constraints if the
|
/* If an edit bone has been duplicated, lets update its constraints if the
|
||||||
* subtarget they point to has also been duplicated.
|
* subtarget they point to has also been duplicated.
|
||||||
@@ -910,35 +920,35 @@ static void updateDuplicateConstraintSettings(EditBone *dup_bone, EditBone *orig
|
|||||||
LISTBASE_FOREACH (bConstraint *, curcon, conlist) {
|
LISTBASE_FOREACH (bConstraint *, curcon, conlist) {
|
||||||
switch (curcon->type) {
|
switch (curcon->type) {
|
||||||
case CONSTRAINT_TYPE_ACTION:
|
case CONSTRAINT_TYPE_ACTION:
|
||||||
updateDuplicateActionConstraintSettings(dup_bone, orig_bone, ob, pchan, curcon);
|
update_duplicate_action_constraint_settings(dup_bone, orig_bone, ob, pchan, curcon);
|
||||||
break;
|
break;
|
||||||
case CONSTRAINT_TYPE_KINEMATIC:
|
case CONSTRAINT_TYPE_KINEMATIC:
|
||||||
updateDuplicateKinematicConstraintSettings(curcon);
|
update_duplicate_kinematics_constraint_settings(curcon);
|
||||||
break;
|
break;
|
||||||
case CONSTRAINT_TYPE_LOCLIMIT:
|
case CONSTRAINT_TYPE_LOCLIMIT:
|
||||||
case CONSTRAINT_TYPE_ROTLIMIT:
|
case CONSTRAINT_TYPE_ROTLIMIT:
|
||||||
updateDuplicateLocRotConstraintSettings(ob, pchan, curcon);
|
update_duplicate_loc_rot_constraint_settings(ob, pchan, curcon);
|
||||||
break;
|
break;
|
||||||
case CONSTRAINT_TYPE_TRANSFORM:
|
case CONSTRAINT_TYPE_TRANSFORM:
|
||||||
updateDuplicateTransformConstraintSettings(ob, pchan, curcon);
|
update_duplicate_transform_constraint_settings(ob, pchan, curcon);
|
||||||
break;
|
break;
|
||||||
case CONSTRAINT_TYPE_TRACKTO:
|
case CONSTRAINT_TYPE_TRACKTO:
|
||||||
updateDuplicateConstraintTrackToSettings(curcon);
|
update_duplicate_constraint_track_to_settings(curcon);
|
||||||
break;
|
break;
|
||||||
case CONSTRAINT_TYPE_LOCKTRACK:
|
case CONSTRAINT_TYPE_LOCKTRACK:
|
||||||
updateDuplicateConstraintLockTrackSettings(curcon);
|
update_duplicate_constraint_lock_track_settings(curcon);
|
||||||
break;
|
break;
|
||||||
case CONSTRAINT_TYPE_DAMPTRACK:
|
case CONSTRAINT_TYPE_DAMPTRACK:
|
||||||
updateDuplicateConstraintDampTrackSettings(curcon);
|
update_duplicate_constraint_damp_track_settings(curcon);
|
||||||
break;
|
break;
|
||||||
case CONSTRAINT_TYPE_SHRINKWRAP:
|
case CONSTRAINT_TYPE_SHRINKWRAP:
|
||||||
updateDuplicateConstraintShrinkwrapSettings(curcon);
|
update_duplicate_constraint_shrinkwrap_settings(curcon);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateDuplicateCustomBoneShapes(bContext *C, EditBone *dup_bone, Object *ob)
|
static void update_duplicate_custom_bone_shapes(bContext *C, EditBone *dup_bone, Object *ob)
|
||||||
{
|
{
|
||||||
if (ob->pose == nullptr) {
|
if (ob->pose == nullptr) {
|
||||||
return;
|
return;
|
||||||
@@ -1069,7 +1079,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
ED_armature_edit_sync_selection(arm->edbo); /* XXX why is this needed? */
|
ED_armature_edit_sync_selection(arm->edbo); /* XXX why is this needed? */
|
||||||
|
|
||||||
preEditBoneDuplicate(arm->edbo);
|
pre_edit_bone_duplicate(arm->edbo);
|
||||||
|
|
||||||
/* Select mirrored bones */
|
/* Select mirrored bones */
|
||||||
if (arm->flag & ARM_MIRROR_EDIT) {
|
if (arm->flag & ARM_MIRROR_EDIT) {
|
||||||
@@ -1151,7 +1161,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Lets try to fix any constraint sub-targets that might have been duplicated. */
|
/* Lets try to fix any constraint sub-targets that might have been duplicated. */
|
||||||
updateDuplicateSubtarget(ebone, arm->edbo, ob, false);
|
update_duplicate_subtarget(ebone, arm->edbo, ob, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1170,7 +1180,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
postEditBoneDuplicate(arm->edbo, ob);
|
pose_edit_bone_duplicate(arm->edbo, ob);
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
|
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
|
||||||
DEG_id_tag_update(&ob->id, ID_RECALC_SELECT);
|
DEG_id_tag_update(&ob->id, ID_RECALC_SELECT);
|
||||||
@@ -1244,7 +1254,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
ED_armature_edit_sync_selection(arm->edbo); /* XXX why is this needed? */
|
ED_armature_edit_sync_selection(arm->edbo); /* XXX why is this needed? */
|
||||||
|
|
||||||
preEditBoneDuplicate(arm->edbo);
|
pre_edit_bone_duplicate(arm->edbo);
|
||||||
|
|
||||||
/* Deselect ebones depending on input axis and direction.
|
/* Deselect ebones depending on input axis and direction.
|
||||||
* A symmetrizable selection contains selected ebones of the input direction
|
* A symmetrizable selection contains selected ebones of the input direction
|
||||||
@@ -1404,12 +1414,12 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
|
|||||||
ebone->bbone_next_flag = ebone_iter->bbone_next_flag;
|
ebone->bbone_next_flag = ebone_iter->bbone_next_flag;
|
||||||
|
|
||||||
/* Lets try to fix any constraint sub-targets that might have been duplicated. */
|
/* Lets try to fix any constraint sub-targets that might have been duplicated. */
|
||||||
updateDuplicateSubtarget(ebone, arm->edbo, obedit, true);
|
update_duplicate_subtarget(ebone, arm->edbo, obedit, true);
|
||||||
/* Try to update constraint options so that they are mirrored as well
|
/* Try to update constraint options so that they are mirrored as well
|
||||||
* (need to supply bone_iter as well in case we are working with existing bones) */
|
* (need to supply bone_iter as well in case we are working with existing bones) */
|
||||||
updateDuplicateConstraintSettings(ebone, ebone_iter, obedit);
|
update_duplicate_constraint_settings(ebone, ebone_iter, obedit);
|
||||||
/* Mirror bone shapes if possible */
|
/* Mirror bone shapes if possible */
|
||||||
updateDuplicateCustomBoneShapes(C, ebone, obedit);
|
update_duplicate_custom_bone_shapes(C, ebone, obedit);
|
||||||
/* Mirror any settings on the pose bone. */
|
/* Mirror any settings on the pose bone. */
|
||||||
mirror_pose_bone(*obedit, *ebone);
|
mirror_pose_bone(*obedit, *ebone);
|
||||||
}
|
}
|
||||||
@@ -1446,7 +1456,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
|
|||||||
arm->act_edbone = arm->act_edbone->temp.ebone;
|
arm->act_edbone = arm->act_edbone->temp.ebone;
|
||||||
}
|
}
|
||||||
|
|
||||||
postEditBoneDuplicate(arm->edbo, obedit);
|
pose_edit_bone_duplicate(arm->edbo, obedit);
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
|
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
|
||||||
DEG_id_tag_update(&obedit->id, ID_RECALC_SELECT);
|
DEG_id_tag_update(&obedit->id, ID_RECALC_SELECT);
|
||||||
@@ -1531,126 +1541,127 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
|
|||||||
for (ebone = static_cast<EditBone *>(arm->edbo->first); ((ebone) && (ebone != first));
|
for (ebone = static_cast<EditBone *>(arm->edbo->first); ((ebone) && (ebone != first));
|
||||||
ebone = ebone->next)
|
ebone = ebone->next)
|
||||||
{
|
{
|
||||||
if (EBONE_VISIBLE(arm, ebone)) {
|
if (!EBONE_VISIBLE(arm, ebone)) {
|
||||||
/* we extrude per definition the tip */
|
continue;
|
||||||
do_extrude = SKIP_EXTRUDE;
|
|
||||||
if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) {
|
|
||||||
do_extrude = TIP_EXTRUDE;
|
|
||||||
}
|
|
||||||
else if (ebone->flag & BONE_ROOTSEL) {
|
|
||||||
/* but, a bone with parent deselected we do the root... */
|
|
||||||
if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) {
|
|
||||||
/* pass */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
do_extrude = ROOT_EXTRUDE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_extrude) {
|
|
||||||
/* we re-use code for mirror editing... */
|
|
||||||
flipbone = nullptr;
|
|
||||||
if (arm->flag & ARM_MIRROR_EDIT) {
|
|
||||||
flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
|
|
||||||
if (flipbone) {
|
|
||||||
forked_iter = false; /* we extrude 2 different bones */
|
|
||||||
if (flipbone->flag & (BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED)) {
|
|
||||||
/* don't want this bone to be selected... */
|
|
||||||
flipbone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((flipbone == nullptr) && (forked_iter)) {
|
|
||||||
flipbone = ebone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (a = 0; a < 2; a++) {
|
|
||||||
if (a == 1) {
|
|
||||||
if (flipbone == nullptr) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
std::swap(flipbone, ebone);
|
|
||||||
}
|
|
||||||
|
|
||||||
totbone++;
|
|
||||||
newbone = static_cast<EditBone *>(MEM_callocN(sizeof(EditBone), "extrudebone"));
|
|
||||||
|
|
||||||
if (do_extrude == TIP_EXTRUDE) {
|
|
||||||
copy_v3_v3(newbone->head, ebone->tail);
|
|
||||||
copy_v3_v3(newbone->tail, newbone->head);
|
|
||||||
newbone->parent = ebone;
|
|
||||||
|
|
||||||
/* copies it, in case mirrored bone */
|
|
||||||
newbone->flag = ebone->flag & (BONE_TIPSEL | BONE_RELATIVE_PARENTING);
|
|
||||||
|
|
||||||
if (newbone->parent) {
|
|
||||||
newbone->flag |= BONE_CONNECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (do_extrude == ROOT_EXTRUDE) {
|
|
||||||
copy_v3_v3(newbone->head, ebone->head);
|
|
||||||
copy_v3_v3(newbone->tail, ebone->head);
|
|
||||||
newbone->parent = ebone->parent;
|
|
||||||
|
|
||||||
newbone->flag = BONE_TIPSEL;
|
|
||||||
|
|
||||||
if (newbone->parent && (ebone->flag & BONE_CONNECTED)) {
|
|
||||||
newbone->flag |= BONE_CONNECTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newbone->color = ebone->color;
|
|
||||||
|
|
||||||
newbone->weight = ebone->weight;
|
|
||||||
newbone->dist = ebone->dist;
|
|
||||||
newbone->xwidth = ebone->xwidth;
|
|
||||||
newbone->zwidth = ebone->zwidth;
|
|
||||||
newbone->rad_head = ebone->rad_tail; /* don't copy entire bone. */
|
|
||||||
newbone->rad_tail = ebone->rad_tail;
|
|
||||||
newbone->segments = 1;
|
|
||||||
newbone->layer = ebone->layer;
|
|
||||||
|
|
||||||
/* Bendy-Bone parameters */
|
|
||||||
newbone->roll1 = ebone->roll1;
|
|
||||||
newbone->roll2 = ebone->roll2;
|
|
||||||
newbone->curve_in_x = ebone->curve_in_x;
|
|
||||||
newbone->curve_in_z = ebone->curve_in_z;
|
|
||||||
newbone->curve_out_x = ebone->curve_out_x;
|
|
||||||
newbone->curve_out_z = ebone->curve_out_z;
|
|
||||||
newbone->ease1 = ebone->ease1;
|
|
||||||
newbone->ease2 = ebone->ease2;
|
|
||||||
|
|
||||||
copy_v3_v3(newbone->scale_in, ebone->scale_in);
|
|
||||||
copy_v3_v3(newbone->scale_out, ebone->scale_out);
|
|
||||||
|
|
||||||
STRNCPY(newbone->name, ebone->name);
|
|
||||||
|
|
||||||
if (flipbone && forked_iter) { /* only set if mirror edit */
|
|
||||||
if (strlen(newbone->name) < (MAXBONENAME - 2)) {
|
|
||||||
BLI_strncat(newbone->name, (a == 0) ? "_L" : "_R", sizeof(newbone->name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ED_armature_ebone_unique_name(arm->edbo, newbone->name, nullptr);
|
|
||||||
|
|
||||||
/* Copy bone collection membership. */
|
|
||||||
BLI_duplicatelist(&newbone->bone_collections, &ebone->bone_collections);
|
|
||||||
|
|
||||||
/* Add the new bone to the list */
|
|
||||||
BLI_addtail(arm->edbo, newbone);
|
|
||||||
if (!first) {
|
|
||||||
first = newbone;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore ebone if we were flipping */
|
|
||||||
if (a == 1 && flipbone) {
|
|
||||||
std::swap(flipbone, ebone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Deselect the old bone */
|
|
||||||
ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
|
|
||||||
}
|
}
|
||||||
|
/* We extrude per definition the tip. */
|
||||||
|
do_extrude = SKIP_EXTRUDE;
|
||||||
|
if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) {
|
||||||
|
do_extrude = TIP_EXTRUDE;
|
||||||
|
}
|
||||||
|
else if (ebone->flag & BONE_ROOTSEL) {
|
||||||
|
/* but, a bone with parent deselected we do the root... */
|
||||||
|
if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) {
|
||||||
|
/* pass */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
do_extrude = ROOT_EXTRUDE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_extrude) {
|
||||||
|
/* we re-use code for mirror editing... */
|
||||||
|
flipbone = nullptr;
|
||||||
|
if (arm->flag & ARM_MIRROR_EDIT) {
|
||||||
|
flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
|
||||||
|
if (flipbone) {
|
||||||
|
forked_iter = false; /* we extrude 2 different bones */
|
||||||
|
if (flipbone->flag & (BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED)) {
|
||||||
|
/* don't want this bone to be selected... */
|
||||||
|
flipbone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((flipbone == nullptr) && (forked_iter)) {
|
||||||
|
flipbone = ebone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (a = 0; a < 2; a++) {
|
||||||
|
if (a == 1) {
|
||||||
|
if (flipbone == nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::swap(flipbone, ebone);
|
||||||
|
}
|
||||||
|
|
||||||
|
totbone++;
|
||||||
|
newbone = static_cast<EditBone *>(MEM_callocN(sizeof(EditBone), "extrudebone"));
|
||||||
|
|
||||||
|
if (do_extrude == TIP_EXTRUDE) {
|
||||||
|
copy_v3_v3(newbone->head, ebone->tail);
|
||||||
|
copy_v3_v3(newbone->tail, newbone->head);
|
||||||
|
newbone->parent = ebone;
|
||||||
|
|
||||||
|
/* copies it, in case mirrored bone */
|
||||||
|
newbone->flag = ebone->flag & (BONE_TIPSEL | BONE_RELATIVE_PARENTING);
|
||||||
|
|
||||||
|
if (newbone->parent) {
|
||||||
|
newbone->flag |= BONE_CONNECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (do_extrude == ROOT_EXTRUDE) {
|
||||||
|
copy_v3_v3(newbone->head, ebone->head);
|
||||||
|
copy_v3_v3(newbone->tail, ebone->head);
|
||||||
|
newbone->parent = ebone->parent;
|
||||||
|
|
||||||
|
newbone->flag = BONE_TIPSEL;
|
||||||
|
|
||||||
|
if (newbone->parent && (ebone->flag & BONE_CONNECTED)) {
|
||||||
|
newbone->flag |= BONE_CONNECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newbone->color = ebone->color;
|
||||||
|
|
||||||
|
newbone->weight = ebone->weight;
|
||||||
|
newbone->dist = ebone->dist;
|
||||||
|
newbone->xwidth = ebone->xwidth;
|
||||||
|
newbone->zwidth = ebone->zwidth;
|
||||||
|
newbone->rad_head = ebone->rad_tail; /* don't copy entire bone. */
|
||||||
|
newbone->rad_tail = ebone->rad_tail;
|
||||||
|
newbone->segments = 1;
|
||||||
|
newbone->layer = ebone->layer;
|
||||||
|
|
||||||
|
/* Bendy-Bone parameters */
|
||||||
|
newbone->roll1 = ebone->roll1;
|
||||||
|
newbone->roll2 = ebone->roll2;
|
||||||
|
newbone->curve_in_x = ebone->curve_in_x;
|
||||||
|
newbone->curve_in_z = ebone->curve_in_z;
|
||||||
|
newbone->curve_out_x = ebone->curve_out_x;
|
||||||
|
newbone->curve_out_z = ebone->curve_out_z;
|
||||||
|
newbone->ease1 = ebone->ease1;
|
||||||
|
newbone->ease2 = ebone->ease2;
|
||||||
|
|
||||||
|
copy_v3_v3(newbone->scale_in, ebone->scale_in);
|
||||||
|
copy_v3_v3(newbone->scale_out, ebone->scale_out);
|
||||||
|
|
||||||
|
STRNCPY(newbone->name, ebone->name);
|
||||||
|
|
||||||
|
if (flipbone && forked_iter) { /* only set if mirror edit */
|
||||||
|
if (strlen(newbone->name) < (MAXBONENAME - 2)) {
|
||||||
|
BLI_strncat(newbone->name, (a == 0) ? "_L" : "_R", sizeof(newbone->name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ED_armature_ebone_unique_name(arm->edbo, newbone->name, nullptr);
|
||||||
|
|
||||||
|
/* Copy bone collection membership. */
|
||||||
|
BLI_duplicatelist(&newbone->bone_collections, &ebone->bone_collections);
|
||||||
|
|
||||||
|
/* Add the new bone to the list */
|
||||||
|
BLI_addtail(arm->edbo, newbone);
|
||||||
|
if (!first) {
|
||||||
|
first = newbone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore ebone if we were flipping */
|
||||||
|
if (a == 1 && flipbone) {
|
||||||
|
std::swap(flipbone, ebone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deselect the old bone */
|
||||||
|
ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
|
||||||
}
|
}
|
||||||
/* if only one bone, make this one active */
|
/* if only one bone, make this one active */
|
||||||
if (totbone == 1 && first) {
|
if (totbone == 1 && first) {
|
||||||
|
|||||||
@@ -233,9 +233,6 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, Bone *actBone);
|
|||||||
|
|
||||||
/* Duplicate method. */
|
/* Duplicate method. */
|
||||||
|
|
||||||
/** Call this before doing any duplication. */
|
|
||||||
void preEditBoneDuplicate(ListBase *editbones);
|
|
||||||
void postEditBoneDuplicate(ListBase *editbones, Object *ob);
|
|
||||||
EditBone *duplicateEditBone(EditBone *cur_bone, const char *name, ListBase *editbones, Object *ob);
|
EditBone *duplicateEditBone(EditBone *cur_bone, const char *name, ListBase *editbones, Object *ob);
|
||||||
|
|
||||||
/* Duplicate method (cross objects). */
|
/* Duplicate method (cross objects). */
|
||||||
|
|||||||
Reference in New Issue
Block a user