Modifiers: Support applying modifiers for multi-user data
The current behaviour is to prevent multi-user data from having its modifier applied. Instead, with this patch, we now warn the user that if they want to proceed the object will be made single-user. Note that this only makes the object data single-user. Not the material or actions. As a future step we can apply the same behaviour for the Grease Pencil modifiers Differential Revision: https://developer.blender.org/D14381
This commit is contained in:
parent
218bcff32d
commit
35f34a3cf8
|
@ -381,6 +381,8 @@ struct Object *ED_object_add_type(struct bContext *C,
|
|||
*/
|
||||
void ED_object_single_user(struct Main *bmain, struct Scene *scene, struct Object *ob);
|
||||
|
||||
void ED_object_single_obdata_user(struct Main *bmain, struct Scene *scene, struct Object *ob);
|
||||
|
||||
/* object motion paths */
|
||||
|
||||
/**
|
||||
|
|
|
@ -1363,7 +1363,7 @@ void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot)
|
|||
/** \name Apply Modifier Operator
|
||||
* \{ */
|
||||
|
||||
static bool modifier_apply_poll_ex(bContext *C, bool allow_shared)
|
||||
static bool modifier_apply_poll(bContext *C)
|
||||
{
|
||||
if (!edit_modifier_poll_generic(C, &RNA_Modifier, 0, false, false)) {
|
||||
return false;
|
||||
|
@ -1378,10 +1378,6 @@ static bool modifier_apply_poll_ex(bContext *C, bool allow_shared)
|
|||
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data");
|
||||
return false;
|
||||
}
|
||||
if (!allow_shared && (ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
|
||||
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied to multi-user data");
|
||||
return false;
|
||||
}
|
||||
if (md != NULL) {
|
||||
if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
|
||||
(BKE_modifier_is_same_topology(md) == false)) {
|
||||
|
@ -1393,11 +1389,6 @@ static bool modifier_apply_poll_ex(bContext *C, bool allow_shared)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool modifier_apply_poll(bContext *C)
|
||||
{
|
||||
return modifier_apply_poll_ex(C, false);
|
||||
}
|
||||
|
||||
static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, bool keep_modifier)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
@ -1406,11 +1397,19 @@ static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, boo
|
|||
Object *ob = ED_object_active_context(C);
|
||||
ModifierData *md = edit_modifier_property_get(op, ob, 0);
|
||||
const bool do_report = RNA_boolean_get(op->ptr, "report");
|
||||
const bool do_single_user = RNA_boolean_get(op->ptr, "single_user");
|
||||
|
||||
if (md == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (do_single_user && ID_REAL_USERS(ob->data) > 1) {
|
||||
ED_object_single_obdata_user(bmain, scene, ob);
|
||||
BKE_main_id_newptr_and_tag_clear(bmain);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
|
||||
int reports_len;
|
||||
char name[MAX_NAME];
|
||||
if (do_report) {
|
||||
|
@ -1447,6 +1446,19 @@ static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
{
|
||||
int retval;
|
||||
if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) {
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
|
||||
Object *ob = (ptr.owner_id != NULL) ? (Object *)ptr.owner_id : ED_object_active_context(C);
|
||||
|
||||
if ((ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "single_user");
|
||||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_boolean_set(op->ptr, prop, true);
|
||||
}
|
||||
if (RNA_property_boolean_get(op->ptr, prop)) {
|
||||
return WM_operator_confirm_message(
|
||||
C, op, "Make object data single-user and apply modifier");
|
||||
}
|
||||
}
|
||||
return modifier_apply_exec(C, op);
|
||||
}
|
||||
return retval;
|
||||
|
@ -1467,6 +1479,13 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
|
|||
|
||||
edit_modifier_properties(ot);
|
||||
edit_modifier_report_property(ot);
|
||||
|
||||
PropertyRNA *prop = RNA_def_boolean(ot->srna,
|
||||
"single_user",
|
||||
false,
|
||||
"Make Data Single User",
|
||||
"Make the object's data single user if needed");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -1477,7 +1496,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
|
|||
|
||||
static bool modifier_apply_as_shapekey_poll(bContext *C)
|
||||
{
|
||||
return modifier_apply_poll_ex(C, true);
|
||||
return modifier_apply_poll(C);
|
||||
}
|
||||
|
||||
static int modifier_apply_as_shapekey_exec(bContext *C, wmOperator *op)
|
||||
|
|
|
@ -1893,6 +1893,19 @@ static void single_obdata_users(
|
|||
}
|
||||
}
|
||||
|
||||
void ED_object_single_obdata_user(Main *bmain, Scene *scene, Object *ob)
|
||||
{
|
||||
FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) {
|
||||
ob_iter->flag &= ~OB_DONE;
|
||||
}
|
||||
FOREACH_SCENE_OBJECT_END;
|
||||
|
||||
/* Tag only the one object. */
|
||||
ob->flag |= OB_DONE;
|
||||
|
||||
single_obdata_users(bmain, scene, NULL, NULL, OB_DONE);
|
||||
}
|
||||
|
||||
static void single_object_action_users(
|
||||
Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d, const int flag)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue