Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/object/object_gpencil_modifier.c
- This file was added.
| /* | |||||
| * ***** BEGIN GPL LICENSE BLOCK ***** | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License | |||||
| * as published by the Free Software Foundation; either version 2 | |||||
| * of the License, or (at your option) any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU General Public License | |||||
| * along with this program; if not, write to the Free Software Foundation, | |||||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||||
| * | |||||
| * The Original Code is Copyright (C) 2018 Blender Foundation. | |||||
| * All rights reserved. | |||||
| * | |||||
| * Contributor(s): Blender Foundation, 2018 | |||||
| * | |||||
| * ***** END GPL LICENSE BLOCK ***** | |||||
| */ | |||||
| /** \file blender/editors/object/object_gpencil_modifier.c | |||||
| * \ingroup edobj | |||||
| */ | |||||
| #include <math.h> | |||||
| #include <stdio.h> | |||||
| #include <stdlib.h> | |||||
| #include "MEM_guardedalloc.h" | |||||
| #include "DNA_gpencil_types.h" | |||||
| #include "DNA_gpencil_modifier_types.h" | |||||
| #include "DNA_object_types.h" | |||||
| #include "DNA_scene_types.h" | |||||
| #include "BLI_math.h" | |||||
| #include "BLI_listbase.h" | |||||
| #include "BLI_string.h" | |||||
| #include "BLI_string_utf8.h" | |||||
| #include "BLI_utildefines.h" | |||||
| #include "BKE_context.h" | |||||
| #include "BKE_main.h" | |||||
| #include "BKE_gpencil_modifier.h" | |||||
| #include "BKE_report.h" | |||||
| #include "BKE_object.h" | |||||
| #include "BKE_gpencil.h" | |||||
| #include "DEG_depsgraph.h" | |||||
| #include "DEG_depsgraph_build.h" | |||||
| #include "DEG_depsgraph_query.h" | |||||
| #include "RNA_access.h" | |||||
| #include "RNA_define.h" | |||||
| #include "RNA_enum_types.h" | |||||
| #include "ED_object.h" | |||||
| #include "ED_screen.h" | |||||
| #include "WM_api.h" | |||||
| #include "WM_types.h" | |||||
| #include "object_intern.h" | |||||
| /******************************** API ****************************/ | |||||
| GpencilModifierData *ED_object_gpencil_modifier_add(ReportList *reports, Main *bmain, Scene *UNUSED(scene), Object *ob, const char *name, int type) | |||||
| { | |||||
| GpencilModifierData *new_md = NULL; | |||||
| const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(type); | |||||
| if (ob->type != OB_GPENCIL) { | |||||
| BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2); | |||||
| return NULL; | |||||
| } | |||||
| if (mti->flags & eGpencilModifierTypeFlag_Single) { | |||||
| if (BKE_gpencil_modifiers_findByType(ob, type)) { | |||||
| BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed"); | |||||
| return NULL; | |||||
| } | |||||
| } | |||||
| /* get new modifier data to add */ | |||||
| new_md = BKE_gpencil_modifier_new(type); | |||||
| BLI_addtail(&ob->greasepencil_modifiers, new_md); | |||||
| if (name) { | |||||
| BLI_strncpy_utf8(new_md->name, name, sizeof(new_md->name)); | |||||
| } | |||||
| /* make sure modifier data has unique name */ | |||||
| BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, new_md); | |||||
| bGPdata *gpd = ob->data; | |||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| DEG_relations_tag_update(bmain); | |||||
| return new_md; | |||||
| } | |||||
| /* Return true if the object has a modifier of type 'type' other than | |||||
| * the modifier pointed to be 'exclude', otherwise returns false. */ | |||||
| static bool gpencil_object_has_modifier(const Object *ob, const GpencilModifierData *exclude, | |||||
| GpencilModifierType type) | |||||
| { | |||||
| GpencilModifierData *md; | |||||
| for (md = ob->greasepencil_modifiers.first; md; md = md->next) { | |||||
| if ((md != exclude) && (md->type == type)) | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| static bool gpencil_object_modifier_remove(Main *bmain, Object *ob, GpencilModifierData *md, | |||||
| bool *UNUSED(r_sort_depsgraph)) | |||||
| { | |||||
| /* It seems on rapid delete it is possible to | |||||
| * get called twice on same modifier, so make | |||||
| * sure it is in list. */ | |||||
| if (BLI_findindex(&ob->greasepencil_modifiers, md) == -1) { | |||||
| return 0; | |||||
| } | |||||
| DEG_relations_tag_update(bmain); | |||||
| BLI_remlink(&ob->greasepencil_modifiers, md); | |||||
| BKE_gpencil_modifier_free(md); | |||||
| BKE_object_free_derived_caches(ob); | |||||
| return 1; | |||||
| } | |||||
| bool ED_object_gpencil_modifier_remove(ReportList *reports, Main *bmain, Object *ob, GpencilModifierData *md) | |||||
| { | |||||
| bool sort_depsgraph = false; | |||||
| bool ok; | |||||
| ok = gpencil_object_modifier_remove(bmain, ob, md, &sort_depsgraph); | |||||
| if (!ok) { | |||||
| BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name); | |||||
| return 0; | |||||
| } | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| DEG_relations_tag_update(bmain); | |||||
| return 1; | |||||
| } | |||||
| void ED_object_gpencil_modifier_clear(Main *bmain, Object *ob) | |||||
| { | |||||
| GpencilModifierData *md = ob->greasepencil_modifiers.first; | |||||
| bool sort_depsgraph = false; | |||||
| if (!md) | |||||
| return; | |||||
| while (md) { | |||||
| GpencilModifierData *next_md; | |||||
| next_md = md->next; | |||||
| gpencil_object_modifier_remove(bmain, ob, md, &sort_depsgraph); | |||||
| md = next_md; | |||||
| } | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| DEG_relations_tag_update(bmain); | |||||
| } | |||||
| int ED_object_gpencil_modifier_move_up(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md) | |||||
| { | |||||
| if (md->prev) { | |||||
| BLI_remlink(&ob->greasepencil_modifiers, md); | |||||
| BLI_insertlinkbefore(&ob->greasepencil_modifiers, md->prev, md); | |||||
| } | |||||
| return 1; | |||||
| } | |||||
| int ED_object_gpencil_modifier_move_down(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md) | |||||
| { | |||||
| if (md->next) { | |||||
| BLI_remlink(&ob->greasepencil_modifiers, md); | |||||
| BLI_insertlinkafter(&ob->greasepencil_modifiers, md->next, md); | |||||
| } | |||||
| return 1; | |||||
| } | |||||
| static int gpencil_modifier_apply_obdata(ReportList *reports, Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, GpencilModifierData *md) | |||||
| { | |||||
| const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); | |||||
| if (mti->isDisabled && mti->isDisabled(md, 0)) { | |||||
| BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); | |||||
| return 0; | |||||
| } | |||||
| if (ob->type == OB_GPENCIL) { | |||||
| if (ELEM(NULL, ob, ob->data)) { | |||||
| return 0; | |||||
| } | |||||
| else if (mti->bakeModifier == NULL) { | |||||
| BKE_report(reports, RPT_ERROR, "Not implemented"); | |||||
| return 0; | |||||
| } | |||||
| mti->bakeModifier(bmain, depsgraph, md, ob); | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| } | |||||
| else { | |||||
| BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); | |||||
| return 0; | |||||
| } | |||||
| return 1; | |||||
| } | |||||
| int ED_object_gpencil_modifier_apply( | |||||
| Main *bmain, ReportList *reports, Depsgraph *depsgraph, | |||||
| Scene *scene, Object *ob, GpencilModifierData *md, int UNUSED(mode)) | |||||
| { | |||||
| if (ob->type == OB_GPENCIL) { | |||||
| if (ob->mode != OB_MODE_OBJECT) { | |||||
| BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in paint, sculpt or edit mode"); | |||||
| return 0; | |||||
| } | |||||
| if (((ID *)ob->data)->us > 1) { | |||||
| BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data"); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| else if (((ID *)ob->data)->us > 1) { | |||||
| BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data"); | |||||
| return 0; | |||||
| } | |||||
| if (md != ob->greasepencil_modifiers.first) | |||||
| BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected"); | |||||
| if (!gpencil_modifier_apply_obdata(reports, bmain, depsgraph, scene, ob, md)) { | |||||
| return 0; | |||||
| } | |||||
| BLI_remlink(&ob->greasepencil_modifiers, md); | |||||
| BKE_gpencil_modifier_free(md); | |||||
| return 1; | |||||
| } | |||||
| int ED_object_gpencil_modifier_copy(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md) | |||||
| { | |||||
| GpencilModifierData *nmd; | |||||
| nmd = BKE_gpencil_modifier_new(md->type); | |||||
| BKE_gpencil_modifier_copyData(md, nmd); | |||||
| BLI_insertlinkafter(&ob->greasepencil_modifiers, md, nmd); | |||||
| BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, nmd); | |||||
| return 1; | |||||
| } | |||||
| /************************ add modifier operator *********************/ | |||||
| static int gpencil_modifier_add_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Main *bmain = CTX_data_main(C); | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| Object *ob = ED_object_active_context(C); | |||||
| int type = RNA_enum_get(op->ptr, "type"); | |||||
| if (!ED_object_gpencil_modifier_add(op->reports, bmain, scene, ob, NULL, type)) | |||||
| return OPERATOR_CANCELLED; | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static const EnumPropertyItem *gpencil_modifier_add_itemf( | |||||
| bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) | |||||
| { | |||||
| Object *ob = ED_object_active_context(C); | |||||
| EnumPropertyItem *item = NULL; | |||||
| const EnumPropertyItem *md_item, *group_item = NULL; | |||||
| const GpencilModifierTypeInfo *mti; | |||||
| int totitem = 0, a; | |||||
| if (!ob) | |||||
| return rna_enum_object_greasepencil_modifier_type_items; | |||||
| for (a = 0; rna_enum_object_greasepencil_modifier_type_items[a].identifier; a++) { | |||||
| md_item = &rna_enum_object_greasepencil_modifier_type_items[a]; | |||||
| if (md_item->identifier[0]) { | |||||
| mti = BKE_gpencil_modifierType_getInfo(md_item->value); | |||||
| if (mti->flags & eGpencilModifierTypeFlag_NoUserAdd) | |||||
| continue; | |||||
| } | |||||
| else { | |||||
| group_item = md_item; | |||||
| md_item = NULL; | |||||
| continue; | |||||
| } | |||||
| if (group_item) { | |||||
| RNA_enum_item_add(&item, &totitem, group_item); | |||||
| group_item = NULL; | |||||
| } | |||||
| RNA_enum_item_add(&item, &totitem, md_item); | |||||
| } | |||||
| RNA_enum_item_end(&item, &totitem); | |||||
| *r_free = true; | |||||
| return item; | |||||
| } | |||||
| void OBJECT_OT_gpencil_modifier_add(wmOperatorType *ot) | |||||
| { | |||||
| PropertyRNA *prop; | |||||
| /* identifiers */ | |||||
| ot->name = "Add Grease Pencil Modifier"; | |||||
| ot->description = "Add a procedural operation/effect to the active grease pencil object"; | |||||
| ot->idname = "OBJECT_OT_gpencil_modifier_add"; | |||||
| /* api callbacks */ | |||||
| ot->invoke = WM_menu_invoke; | |||||
| ot->exec = gpencil_modifier_add_exec; | |||||
| ot->poll = ED_operator_object_active_editable; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | |||||
| /* properties */ | |||||
| prop = RNA_def_enum(ot->srna, "type", rna_enum_object_modifier_type_items, eGpencilModifierType_Thick, "Type", ""); | |||||
| RNA_def_enum_funcs(prop, gpencil_modifier_add_itemf); | |||||
| ot->prop = prop; | |||||
| } | |||||
| /************************ generic functions for operators using mod names and data context *********************/ | |||||
| static int gpencil_edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag) | |||||
| { | |||||
| PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type); | |||||
| Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C); | |||||
| if (!ptr.data) { | |||||
| CTX_wm_operator_poll_msg_set(C, "Context missing 'modifier'"); | |||||
| return 0; | |||||
| } | |||||
| if (!ob || ID_IS_LINKED(ob)) return 0; | |||||
| if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) return 0; | |||||
| if (ptr.id.data && ID_IS_LINKED(ptr.id.data)) return 0; | |||||
| if (ID_IS_STATIC_OVERRIDE(ob)) { | |||||
| CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers comming from static override"); | |||||
| return (((GpencilModifierData *)ptr.data)->flag & eGpencilModifierFlag_StaticOverride_Local) != 0; | |||||
| } | |||||
| return 1; | |||||
| } | |||||
| static int gpencil_edit_modifier_poll(bContext *C) | |||||
| { | |||||
| return gpencil_edit_modifier_poll_generic(C, &RNA_GpencilModifier, 0); | |||||
| } | |||||
| static void gpencil_edit_modifier_properties(wmOperatorType *ot) | |||||
| { | |||||
| RNA_def_string(ot->srna, "modifier", NULL, MAX_NAME, "Modifier", "Name of the modifier to edit"); | |||||
| } | |||||
| static int gpencil_edit_modifier_invoke_properties(bContext *C, wmOperator *op) | |||||
| { | |||||
| GpencilModifierData *md; | |||||
| if (RNA_struct_property_is_set(op->ptr, "modifier")) { | |||||
| return true; | |||||
| } | |||||
| else { | |||||
| PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_GpencilModifier); | |||||
| if (ptr.data) { | |||||
| md = ptr.data; | |||||
| RNA_string_set(op->ptr, "modifier", md->name); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| static GpencilModifierData *gpencil_edit_modifier_property_get(wmOperator *op, Object *ob, int type) | |||||
| { | |||||
| char modifier_name[MAX_NAME]; | |||||
| GpencilModifierData *md; | |||||
| RNA_string_get(op->ptr, "modifier", modifier_name); | |||||
| md = BKE_gpencil_modifiers_findByName(ob, modifier_name); | |||||
| if (md && type != 0 && md->type != type) | |||||
| md = NULL; | |||||
| return md; | |||||
| } | |||||
| /************************ remove modifier operator *********************/ | |||||
| static int gpencil_modifier_remove_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Main *bmain = CTX_data_main(C); | |||||
| Object *ob = ED_object_active_context(C); | |||||
| GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); | |||||
| if (!md || !ED_object_gpencil_modifier_remove(op->reports, bmain, ob, md)) | |||||
| return OPERATOR_CANCELLED; | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static int gpencil_modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | |||||
| { | |||||
| if (gpencil_edit_modifier_invoke_properties(C, op)) | |||||
| return gpencil_modifier_remove_exec(C, op); | |||||
| else | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| void OBJECT_OT_gpencil_modifier_remove(wmOperatorType *ot) | |||||
| { | |||||
| ot->name = "Remove Grease Pencil Modifier"; | |||||
| ot->description = "Remove a modifier from the active grease pencil object"; | |||||
| ot->idname = "OBJECT_OT_gpencil_modifier_remove"; | |||||
| ot->invoke = gpencil_modifier_remove_invoke; | |||||
| ot->exec = gpencil_modifier_remove_exec; | |||||
| ot->poll = gpencil_edit_modifier_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; | |||||
| gpencil_edit_modifier_properties(ot); | |||||
| } | |||||
| /************************ move up modifier operator *********************/ | |||||
| static int gpencil_modifier_move_up_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Object *ob = ED_object_active_context(C); | |||||
| GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); | |||||
| if (!md || !ED_object_gpencil_modifier_move_up(op->reports, ob, md)) | |||||
| return OPERATOR_CANCELLED; | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static int gpencil_modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | |||||
| { | |||||
| if (gpencil_edit_modifier_invoke_properties(C, op)) | |||||
| return gpencil_modifier_move_up_exec(C, op); | |||||
| else | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| void OBJECT_OT_gpencil_modifier_move_up(wmOperatorType *ot) | |||||
| { | |||||
| ot->name = "Move Up Modifier"; | |||||
| ot->description = "Move modifier up in the stack"; | |||||
| ot->idname = "OBJECT_OT_gpencil_modifier_move_up"; | |||||
| ot->invoke = gpencil_modifier_move_up_invoke; | |||||
| ot->exec = gpencil_modifier_move_up_exec; | |||||
| ot->poll = gpencil_edit_modifier_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; | |||||
| gpencil_edit_modifier_properties(ot); | |||||
| } | |||||
| /************************ move down modifier operator *********************/ | |||||
| static int gpencil_modifier_move_down_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Object *ob = ED_object_active_context(C); | |||||
| GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); | |||||
| if (!md || !ED_object_gpencil_modifier_move_down(op->reports, ob, md)) | |||||
| return OPERATOR_CANCELLED; | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static int gpencil_modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | |||||
| { | |||||
| if (gpencil_edit_modifier_invoke_properties(C, op)) | |||||
| return gpencil_modifier_move_down_exec(C, op); | |||||
| else | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| void OBJECT_OT_gpencil_modifier_move_down(wmOperatorType *ot) | |||||
| { | |||||
| ot->name = "Move Down Modifier"; | |||||
| ot->description = "Move modifier down in the stack"; | |||||
| ot->idname = "OBJECT_OT_gpencil_modifier_move_down"; | |||||
| ot->invoke = gpencil_modifier_move_down_invoke; | |||||
| ot->exec = gpencil_modifier_move_down_exec; | |||||
| ot->poll = gpencil_edit_modifier_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; | |||||
| gpencil_edit_modifier_properties(ot); | |||||
| } | |||||
| /************************ apply modifier operator *********************/ | |||||
| static int gpencil_modifier_apply_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Main *bmain = CTX_data_main(C); | |||||
| Depsgraph *depsgraph = CTX_data_depsgraph(C); | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| Object *ob = ED_object_active_context(C); | |||||
| GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); | |||||
| int apply_as = RNA_enum_get(op->ptr, "apply_as"); | |||||
| if (!md || !ED_object_gpencil_modifier_apply(bmain, op->reports, depsgraph, scene, ob, md, apply_as)) { | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static int gpencil_modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | |||||
| { | |||||
| if (gpencil_edit_modifier_invoke_properties(C, op)) | |||||
| return gpencil_modifier_apply_exec(C, op); | |||||
| else | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| static const EnumPropertyItem gpencil_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_gpencil_modifier_apply(wmOperatorType *ot) | |||||
| { | |||||
| ot->name = "Apply Modifier"; | |||||
| ot->description = "Apply modifier and remove from the stack"; | |||||
| ot->idname = "OBJECT_OT_gpencil_modifier_apply"; | |||||
| ot->invoke = gpencil_modifier_apply_invoke; | |||||
| ot->exec = gpencil_modifier_apply_exec; | |||||
| ot->poll = gpencil_edit_modifier_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; | |||||
| RNA_def_enum(ot->srna, "apply_as", gpencil_modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry"); | |||||
| gpencil_edit_modifier_properties(ot); | |||||
| } | |||||
| /************************ copy modifier operator *********************/ | |||||
| static int gpencil_modifier_copy_exec(bContext *C, wmOperator *op) | |||||
| { | |||||
| Object *ob = ED_object_active_context(C); | |||||
| GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); | |||||
| if (!md || !ED_object_gpencil_modifier_copy(op->reports, ob, md)) | |||||
| return OPERATOR_CANCELLED; | |||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); | |||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| static int gpencil_modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | |||||
| { | |||||
| if (gpencil_edit_modifier_invoke_properties(C, op)) | |||||
| return gpencil_modifier_copy_exec(C, op); | |||||
| else | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| void OBJECT_OT_gpencil_modifier_copy(wmOperatorType *ot) | |||||
| { | |||||
| ot->name = "Copy Modifier"; | |||||
| ot->description = "Duplicate modifier at the same position in the stack"; | |||||
| ot->idname = "OBJECT_OT_gpencil_modifier_copy"; | |||||
| ot->invoke = gpencil_modifier_copy_invoke; | |||||
| ot->exec = gpencil_modifier_copy_exec; | |||||
| ot->poll = gpencil_edit_modifier_poll; | |||||
| /* flags */ | |||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; | |||||
| gpencil_edit_modifier_properties(ot); | |||||
| } | |||||