mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Anim: Duplicate rename operator for bones
This implements an operator that duplicates edit bones and does a search replace at the same time. Crucially, the search replace is done before name collisions are checked so this avoids a potential rename to append `.001` by blender. When the "replace" is left empty, the "search" is just removed. The search and replace has no fancy regex logic built in. When called, the operator pops up a GUI On a technical level this is very much identical to the existing `ARMATURE_OT_duplicate` but I had to create a separate operator that has an invoke function for the menu. Otherwise the menu pops up every time you press `shift+D`. I refactored out a separate function to avoid code duplication Pull Request: https://projects.blender.org/blender/blender/pulls/154553
This commit is contained in:
parent
a80b9d811a
commit
f67497581b
4 changed files with 76 additions and 2 deletions
|
|
@ -5632,6 +5632,7 @@ class VIEW3D_MT_edit_armature(Menu):
|
|||
layout.operator("armature.extrude_forked")
|
||||
|
||||
layout.operator("armature.duplicate_move")
|
||||
layout.operator("armature.duplicate_rename")
|
||||
layout.operator("armature.fill")
|
||||
|
||||
layout.separator()
|
||||
|
|
|
|||
|
|
@ -1107,12 +1107,14 @@ EditBone *duplicateEditBone(EditBone *cur_bone,
|
|||
return duplicateEditBoneObjects(cur_bone, name, editbones, ob, ob);
|
||||
}
|
||||
|
||||
static wmOperatorStatus armature_duplicate_selected_exec(bContext *C, wmOperator *op)
|
||||
static wmOperatorStatus armature_duplicate_selected(bContext *C,
|
||||
const bool do_flip_names,
|
||||
StringRefNull search,
|
||||
StringRefNull replace)
|
||||
{
|
||||
const Main *bmain = CTX_data_main(C);
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
const bool do_flip_names = RNA_boolean_get(op->ptr, "do_flip_names");
|
||||
|
||||
/* cancel if nothing selected */
|
||||
if (CTX_DATA_COUNT(C, selected_bones) == 0) {
|
||||
|
|
@ -1166,6 +1168,11 @@ static wmOperatorStatus armature_duplicate_selected_exec(bContext *C, wmOperator
|
|||
new_bone_name = new_bone_name_buff;
|
||||
}
|
||||
}
|
||||
std::string buffer(new_bone_name);
|
||||
if (!search.is_empty()) {
|
||||
BLI_string_replace(buffer, search, replace);
|
||||
new_bone_name = buffer.data();
|
||||
}
|
||||
|
||||
ebone = duplicateEditBone(ebone_iter, new_bone_name, arm->edbo, ob);
|
||||
|
||||
|
|
@ -1242,6 +1249,12 @@ static wmOperatorStatus armature_duplicate_selected_exec(bContext *C, wmOperator
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static wmOperatorStatus armature_duplicate_selected_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool do_flip_names = RNA_boolean_get(op->ptr, "do_flip_names");
|
||||
return armature_duplicate_selected(C, do_flip_names, "", "");
|
||||
}
|
||||
|
||||
void ARMATURE_OT_duplicate(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
|
|
@ -1264,6 +1277,64 @@ void ARMATURE_OT_duplicate(wmOperatorType *ot)
|
|||
"Try to flip names of the bones, if possible, instead of adding a number extension");
|
||||
}
|
||||
|
||||
static wmOperatorStatus armature_duplicate_rename_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool do_flip_names = RNA_boolean_get(op->ptr, "do_flip_names");
|
||||
std::string search = RNA_string_get(op->ptr, "search");
|
||||
std::string replace = RNA_string_get(op->ptr, "replace");
|
||||
if (search.empty()) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No search term defined");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
return armature_duplicate_selected(C, do_flip_names, search, replace);
|
||||
}
|
||||
|
||||
static wmOperatorStatus armature_duplicate_rename_invoke(bContext *C,
|
||||
wmOperator *op,
|
||||
const wmEvent *event)
|
||||
{
|
||||
return WM_operator_props_popup_confirm(C, op, event);
|
||||
}
|
||||
|
||||
void ARMATURE_OT_duplicate_rename(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Duplicate and Rename";
|
||||
ot->idname = "ARMATURE_OT_duplicate_rename";
|
||||
ot->description =
|
||||
"Make copies of the selected bones within the same armature and replace a part of their "
|
||||
"name";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->invoke = armature_duplicate_rename_invoke;
|
||||
ot->exec = armature_duplicate_rename_exec;
|
||||
ot->poll = ED_operator_editarmature;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_boolean(
|
||||
ot->srna,
|
||||
"do_flip_names",
|
||||
false,
|
||||
"Flip Names",
|
||||
"Try to flip names of the bones, if possible, instead of adding a number extension");
|
||||
|
||||
RNA_def_string(ot->srna,
|
||||
"search",
|
||||
nullptr,
|
||||
MAXBONENAME,
|
||||
"Search",
|
||||
"A part of the current bone name that will be replaced");
|
||||
RNA_def_string(ot->srna,
|
||||
"replace",
|
||||
nullptr,
|
||||
MAXBONENAME,
|
||||
"Replace",
|
||||
"The substitute to be inserted into the place of the given search term. If left "
|
||||
"empty the search term will be removed");
|
||||
}
|
||||
|
||||
/* Get the duplicated or existing mirrored copy of the bone. */
|
||||
static EditBone *get_symmetrized_bone(bArmature *arm, EditBone *bone)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ void ARMATURE_OT_shortest_path_pick(wmOperatorType *ot);
|
|||
void ARMATURE_OT_delete(wmOperatorType *ot);
|
||||
void ARMATURE_OT_dissolve(wmOperatorType *ot);
|
||||
void ARMATURE_OT_duplicate(wmOperatorType *ot);
|
||||
void ARMATURE_OT_duplicate_rename(wmOperatorType *ot);
|
||||
void ARMATURE_OT_symmetrize(wmOperatorType *ot);
|
||||
void ARMATURE_OT_extrude(wmOperatorType *ot);
|
||||
void ARMATURE_OT_hide(wmOperatorType *ot);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ void ED_operatortypes_armature()
|
|||
WM_operatortype_append(ARMATURE_OT_delete);
|
||||
WM_operatortype_append(ARMATURE_OT_dissolve);
|
||||
WM_operatortype_append(ARMATURE_OT_duplicate);
|
||||
WM_operatortype_append(ARMATURE_OT_duplicate_rename);
|
||||
WM_operatortype_append(ARMATURE_OT_symmetrize);
|
||||
WM_operatortype_append(ARMATURE_OT_extrude);
|
||||
WM_operatortype_append(ARMATURE_OT_hide);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue