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;
|
||||
}
|
||||
|
||||
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);
|
||||
EditBone *bone;
|
||||
@@ -144,19 +146,21 @@ static int armature_click_extrude_exec(bContext *C, wmOperator * /*op*/)
|
||||
|
||||
/* find the active or selected bone */
|
||||
for (ebone = static_cast<EditBone *>(arm->edbo->first); ebone; ebone = ebone->next) {
|
||||
if (EBONE_VISIBLE(arm, ebone)) {
|
||||
if (ebone->flag & BONE_TIPSEL || arm->act_edbone == ebone) {
|
||||
break;
|
||||
}
|
||||
if (!EBONE_VISIBLE(arm, ebone)) {
|
||||
continue;
|
||||
}
|
||||
if (ebone->flag & BONE_TIPSEL || arm->act_edbone == ebone) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ebone == nullptr) {
|
||||
for (ebone = static_cast<EditBone *>(arm->edbo->first); ebone; ebone = ebone->next) {
|
||||
if (EBONE_VISIBLE(arm, ebone)) {
|
||||
if (ebone->flag & BONE_ROOTSEL || arm->act_edbone == ebone) {
|
||||
break;
|
||||
}
|
||||
if (!EBONE_VISIBLE(arm, ebone)) {
|
||||
continue;
|
||||
}
|
||||
if (ebone->flag & BONE_ROOTSEL || arm->act_edbone == ebone) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ebone == nullptr) {
|
||||
@@ -302,14 +306,14 @@ static EditBone *get_named_editbone(ListBase *edbo, const char *name)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void preEditBoneDuplicate(ListBase *editbones)
|
||||
static void pre_edit_bone_duplicate(ListBase *editbones)
|
||||
{
|
||||
/* clear temp */
|
||||
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.
|
||||
*/
|
||||
static bPoseChannel *pchan_duplicate_map(const bPose *pose,
|
||||
@@ -330,7 +334,7 @@ static bPoseChannel *pchan_duplicate_map(const bPose *pose,
|
||||
return pchan_dst;
|
||||
}
|
||||
|
||||
void postEditBoneDuplicate(ListBase *editbones, Object *ob)
|
||||
static void pose_edit_bone_duplicate(ListBase *editbones, Object *ob)
|
||||
{
|
||||
if (ob->pose == nullptr) {
|
||||
return;
|
||||
@@ -382,60 +386,64 @@ void postEditBoneDuplicate(ListBase *editbones, Object *ob)
|
||||
BLI_ghash_free(name_map, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static void updateDuplicateSubtarget(EditBone *dup_bone,
|
||||
ListBase *editbones,
|
||||
Object *ob,
|
||||
bool lookup_mirror_subtarget)
|
||||
static void update_duplicate_subtarget(EditBone *dup_bone,
|
||||
ListBase *editbones,
|
||||
Object *ob,
|
||||
const bool lookup_mirror_subtarget)
|
||||
{
|
||||
/* If an edit bone has been duplicated, lets update its constraints if the
|
||||
* 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;
|
||||
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))) {
|
||||
ListBase *conlist = &pchan->constraints;
|
||||
LISTBASE_FOREACH (bConstraint *, curcon, conlist) {
|
||||
/* does this constraint have a subtarget in
|
||||
* this armature?
|
||||
if (!BKE_constraint_targets_get(curcon, &targets)) {
|
||||
continue;
|
||||
}
|
||||
LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
|
||||
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)) {
|
||||
LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
|
||||
if ((ct->tar == ob) && (ct->subtarget[0])) {
|
||||
oldtarget = get_named_editbone(editbones, ct->subtarget);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
bActionConstraint *act_con = (bActionConstraint *)curcon->data;
|
||||
@@ -587,7 +595,7 @@ static void updateDuplicateActionConstraintSettings(
|
||||
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 */
|
||||
bKinematicConstraint *ik = (bKinematicConstraint *)curcon->data;
|
||||
@@ -596,9 +604,9 @@ static void updateDuplicateKinematicConstraintSettings(bConstraint *curcon)
|
||||
ik->poleangle = angle_wrap_rad(ik->poleangle);
|
||||
}
|
||||
|
||||
static void updateDuplicateLocRotConstraintSettings(Object *ob,
|
||||
bPoseChannel *pchan,
|
||||
bConstraint *curcon)
|
||||
static void update_duplicate_loc_rot_constraint_settings(Object *ob,
|
||||
bPoseChannel *pchan,
|
||||
bConstraint *curcon)
|
||||
{
|
||||
/* This code assumes that bRotLimitConstraint and bLocLimitConstraint have the same fields in
|
||||
* the same memory locations. */
|
||||
@@ -668,9 +676,9 @@ static void updateDuplicateLocRotConstraintSettings(Object *ob,
|
||||
limit->zmax = max_vec[2];
|
||||
}
|
||||
|
||||
static void updateDuplicateTransformConstraintSettings(Object *ob,
|
||||
bPoseChannel *pchan,
|
||||
bConstraint *curcon)
|
||||
static void update_duplicate_transform_constraint_settings(Object *ob,
|
||||
bPoseChannel *pchan,
|
||||
bConstraint *curcon)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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
|
||||
* 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) {
|
||||
switch (curcon->type) {
|
||||
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;
|
||||
case CONSTRAINT_TYPE_KINEMATIC:
|
||||
updateDuplicateKinematicConstraintSettings(curcon);
|
||||
update_duplicate_kinematics_constraint_settings(curcon);
|
||||
break;
|
||||
case CONSTRAINT_TYPE_LOCLIMIT:
|
||||
case CONSTRAINT_TYPE_ROTLIMIT:
|
||||
updateDuplicateLocRotConstraintSettings(ob, pchan, curcon);
|
||||
update_duplicate_loc_rot_constraint_settings(ob, pchan, curcon);
|
||||
break;
|
||||
case CONSTRAINT_TYPE_TRANSFORM:
|
||||
updateDuplicateTransformConstraintSettings(ob, pchan, curcon);
|
||||
update_duplicate_transform_constraint_settings(ob, pchan, curcon);
|
||||
break;
|
||||
case CONSTRAINT_TYPE_TRACKTO:
|
||||
updateDuplicateConstraintTrackToSettings(curcon);
|
||||
update_duplicate_constraint_track_to_settings(curcon);
|
||||
break;
|
||||
case CONSTRAINT_TYPE_LOCKTRACK:
|
||||
updateDuplicateConstraintLockTrackSettings(curcon);
|
||||
update_duplicate_constraint_lock_track_settings(curcon);
|
||||
break;
|
||||
case CONSTRAINT_TYPE_DAMPTRACK:
|
||||
updateDuplicateConstraintDampTrackSettings(curcon);
|
||||
update_duplicate_constraint_damp_track_settings(curcon);
|
||||
break;
|
||||
case CONSTRAINT_TYPE_SHRINKWRAP:
|
||||
updateDuplicateConstraintShrinkwrapSettings(curcon);
|
||||
update_duplicate_constraint_shrinkwrap_settings(curcon);
|
||||
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) {
|
||||
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? */
|
||||
|
||||
preEditBoneDuplicate(arm->edbo);
|
||||
pre_edit_bone_duplicate(arm->edbo);
|
||||
|
||||
/* Select mirrored bones */
|
||||
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. */
|
||||
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);
|
||||
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? */
|
||||
|
||||
preEditBoneDuplicate(arm->edbo);
|
||||
pre_edit_bone_duplicate(arm->edbo);
|
||||
|
||||
/* Deselect ebones depending on input axis and 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;
|
||||
|
||||
/* 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
|
||||
* (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 */
|
||||
updateDuplicateCustomBoneShapes(C, ebone, obedit);
|
||||
update_duplicate_custom_bone_shapes(C, ebone, obedit);
|
||||
/* Mirror any settings on the pose bone. */
|
||||
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;
|
||||
}
|
||||
|
||||
postEditBoneDuplicate(arm->edbo, obedit);
|
||||
pose_edit_bone_duplicate(arm->edbo, obedit);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
|
||||
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));
|
||||
ebone = ebone->next)
|
||||
{
|
||||
if (EBONE_VISIBLE(arm, ebone)) {
|
||||
/* 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 (!EBONE_VISIBLE(arm, ebone)) {
|
||||
continue;
|
||||
}
|
||||
/* 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 (totbone == 1 && first) {
|
||||
|
||||
@@ -233,9 +233,6 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, Bone *actBone);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Duplicate method (cross objects). */
|
||||
|
||||
Reference in New Issue
Block a user