Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2020-07-01 17:38:07 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2020-07-08 11:06:57 +0300
commit01c8aa12a17775cce03106a576f3c498d28131e4 (patch)
tree0ec11befa4e3444fd94256736ba0f09e0317dc92 /source/blender
parent7fcb6bc59c85beab36dbfcec91d0cfaf5291f029 (diff)
Apply Modifier: support applying as shape key and keeping the modifier.
This can be useful to save the result of a cloth simulation as a shape key without destroying the simulation, so it's possible to e.g. re-run it to get other shapes, or simply use the new shape key to start the simulation already in a draped state. It also makes sense to allow applying as shape key even when the mesh is shared, because the operation itself just adds a shape key. To support this, split the apply operator into Apply and Apply As Shapekey so that they can have different poll callbacks. Differential Revision: https://developer.blender.org/D8173
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/include/ED_object.h3
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_modifier.c110
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/modifiers/intern/MOD_ui_common.c19
5 files changed, 102 insertions, 32 deletions
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index a851eb735b8..5ec4de5d597 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -389,7 +389,8 @@ bool ED_object_modifier_apply(struct Main *bmain,
struct Scene *scene,
struct Object *ob,
struct ModifierData *md,
- int mode);
+ int mode,
+ bool keep_modifier);
int ED_object_modifier_copy(struct ReportList *reports,
struct Object *ob,
struct ModifierData *md);
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index afc87c0caba..9dc204b9083 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -167,6 +167,7 @@ void OBJECT_OT_modifier_move_up(struct wmOperatorType *ot);
void OBJECT_OT_modifier_move_down(struct wmOperatorType *ot);
void OBJECT_OT_modifier_move_to_index(struct wmOperatorType *ot);
void OBJECT_OT_modifier_apply(struct wmOperatorType *ot);
+void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot);
void OBJECT_OT_modifier_convert(struct wmOperatorType *ot);
void OBJECT_OT_modifier_copy(struct wmOperatorType *ot);
void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 74109563929..6c929ad781e 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -822,7 +822,8 @@ bool ED_object_modifier_apply(Main *bmain,
Scene *scene,
Object *ob,
ModifierData *md,
- int mode)
+ int mode,
+ bool keep_modifier)
{
int prev_mode;
@@ -830,7 +831,7 @@ bool ED_object_modifier_apply(Main *bmain,
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
return false;
}
- if (ID_REAL_USERS(ob->data) > 1) {
+ if (mode != MODIFIER_APPLY_SHAPE && ID_REAL_USERS(ob->data) > 1) {
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
return false;
}
@@ -869,8 +870,11 @@ bool ED_object_modifier_apply(Main *bmain,
}
md_eval->mode = prev_mode;
- BLI_remlink(&ob->modifiers, md);
- BKE_modifier_free(md);
+
+ if (!keep_modifier) {
+ BLI_remlink(&ob->modifiers, md);
+ BKE_modifier_free(md);
+ }
BKE_object_free_derived_caches(ob);
@@ -1326,7 +1330,7 @@ void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot)
/** \name Apply Modifier Operator
* \{ */
-static bool modifier_apply_poll(bContext *C)
+static bool modifier_apply_poll_ex(bContext *C, bool allow_shared)
{
if (!edit_modifier_poll_generic(C, &RNA_Modifier, 0, false)) {
return false;
@@ -1341,7 +1345,7 @@ static bool modifier_apply_poll(bContext *C)
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data");
return false;
}
- if ((ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
+ 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;
}
@@ -1356,14 +1360,18 @@ static bool modifier_apply_poll(bContext *C)
return true;
}
-static int modifier_apply_exec(bContext *C, wmOperator *op)
+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);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
- int apply_as = RNA_enum_get(op->ptr, "apply_as");
if (md == NULL) {
return OPERATOR_CANCELLED;
@@ -1373,7 +1381,8 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
char name[MAX_NAME];
strcpy(name, md->name);
- if (!ED_object_modifier_apply(bmain, op->reports, depsgraph, scene, ob, md, apply_as)) {
+ if (!ED_object_modifier_apply(
+ bmain, op->reports, depsgraph, scene, ob, md, apply_as, keep_modifier)) {
return OPERATOR_CANCELLED;
}
@@ -1388,6 +1397,11 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int modifier_apply_exec(bContext *C, wmOperator *op)
+{
+ return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_DATA, false);
+}
+
static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval;
@@ -1397,16 +1411,6 @@ static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *eve
return retval;
}
-static const EnumPropertyItem modifier_apply_as_items[] = {
- {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
- {MODIFIER_APPLY_SHAPE,
- "SHAPE",
- 0,
- "New Shape",
- "Apply deform-only modifier to a new shape on this object"},
- {0, NULL, 0, NULL, NULL},
-};
-
void OBJECT_OT_modifier_apply(wmOperatorType *ot)
{
ot->name = "Apply Modifier";
@@ -1420,12 +1424,68 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- RNA_def_enum(ot->srna,
- "apply_as",
- modifier_apply_as_items,
- MODIFIER_APPLY_DATA,
- "Apply as",
- "How to apply the modifier to the geometry");
+ edit_modifier_properties(ot);
+ edit_modifier_report_property(ot);
+}
+
+/** \} */
+
+/* ------------------------------------------------------------------- */
+/** \name Apply Modifier As Shapekey Operator
+ * \{ */
+
+static bool modifier_apply_as_shapekey_poll(bContext *C)
+{
+ return modifier_apply_poll_ex(C, true);
+}
+
+static int modifier_apply_as_shapekey_exec(bContext *C, wmOperator *op)
+{
+ bool keep = RNA_boolean_get(op->ptr, "keep_modifier");
+
+ return modifier_apply_exec_ex(C, op, MODIFIER_APPLY_SHAPE, keep);
+}
+
+static int modifier_apply_as_shapekey_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ int retval;
+ if (edit_modifier_invoke_properties(C, op, event, &retval)) {
+ return modifier_apply_as_shapekey_exec(C, op);
+ }
+ else {
+ return retval;
+ }
+}
+
+static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(C),
+ struct wmOperatorType *UNUSED(op),
+ struct PointerRNA *values)
+{
+ bool keep = RNA_boolean_get(values, "keep_modifier");
+
+ if (keep) {
+ return BLI_strdup("Apply modifier as a new shapekey and keep it in the stack");
+ }
+
+ return NULL;
+}
+
+void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot)
+{
+ ot->name = "Apply Modifier As Shapekey";
+ ot->description = "Apply modifier as a new shapekey and remove from the stack";
+ ot->idname = "OBJECT_OT_modifier_apply_as_shapekey";
+
+ ot->invoke = modifier_apply_as_shapekey_invoke;
+ ot->exec = modifier_apply_as_shapekey_exec;
+ ot->poll = modifier_apply_as_shapekey_poll;
+ ot->get_description = modifier_apply_as_shapekey_get_description;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ RNA_def_boolean(
+ ot->srna, "keep_modifier", false, "Keep Modifier", "Do not remove the modifier from stack");
edit_modifier_properties(ot);
edit_modifier_report_property(ot);
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index e28bbb3fb1c..92880e5a114 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -130,6 +130,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_modifier_move_down);
WM_operatortype_append(OBJECT_OT_modifier_move_to_index);
WM_operatortype_append(OBJECT_OT_modifier_apply);
+ WM_operatortype_append(OBJECT_OT_modifier_apply_as_shapekey);
WM_operatortype_append(OBJECT_OT_modifier_convert);
WM_operatortype_append(OBJECT_OT_modifier_copy);
WM_operatortype_append(OBJECT_OT_multires_subdivide);
diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c
index 137f52782a9..01b9e972086 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.c
+++ b/source/blender/modifiers/intern/MOD_ui_common.c
@@ -231,12 +231,19 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v)
/* Apply as shapekey. */
if (BKE_modifier_is_same_topology(md) && !BKE_modifier_is_non_geometrical(md)) {
- uiItemEnumO(layout,
- "OBJECT_OT_modifier_apply",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply As Shapekey"),
- ICON_SHAPEKEY_DATA,
- "apply_as",
- MODIFIER_APPLY_SHAPE);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply As Shapekey"),
+ ICON_SHAPEKEY_DATA,
+ "OBJECT_OT_modifier_apply_as_shapekey",
+ "keep_modifier",
+ false);
+
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save As Shapekey"),
+ ICON_SHAPEKEY_DATA,
+ "OBJECT_OT_modifier_apply_as_shapekey",
+ "keep_modifier",
+ true);
}
/* Duplicate. */