From d296c66ab18bbf45f4eceb55878133be09b9a76c Mon Sep 17 00:00:00 2001 From: YimingWu Date: Wed, 28 Feb 2024 16:20:48 +0100 Subject: [PATCH] GPv3: Show Line Art options in Object > Add menu The Object > Add > Grease Pencil menu will now show Scene/Collection/Object Line Art options. Pull Request: https://projects.blender.org/blender/blender/pulls/118833 --- scripts/startup/bl_ui/space_view3d.py | 7 ++ source/blender/editors/object/object_add.cc | 115 +++++++++++++++--- .../makesdna/DNA_grease_pencil_types.h | 1 + source/blender/makesdna/DNA_object_types.h | 6 +- source/blender/makesrna/intern/rna_object.cc | 12 +- 5 files changed, 116 insertions(+), 25 deletions(-) diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 248f0926603..9ccb029ab29 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -2589,6 +2589,13 @@ class VIEW3D_MT_grease_pencil_add(Menu): layout.operator("object.grease_pencil_add", text="Empty", icon='EMPTY_AXIS').type = 'EMPTY' layout.operator("object.grease_pencil_add", text="Stroke", icon='STROKE').type = 'STROKE' layout.operator("object.grease_pencil_add", text="Suzanne", icon='MONKEY').type = 'MONKEY' + layout.separator() + layout.operator("object.grease_pencil_add", text="Scene Line Art", icon='SCENE').type = 'LINEART_SCENE' + layout.operator( + "object.grease_pencil_add", + text="Collection Line Art", + icon='GROUP').type = 'LINEART_COLLECTION' + layout.operator("object.grease_pencil_add", text="Object Line Art", icon='CUBE').type = 'LINEART_OBJECT' class VIEW3D_MT_add(Menu): diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index 41ae217cdce..ca651ea0e65 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -80,6 +80,7 @@ #include "BKE_mball.hh" #include "BKE_mesh.hh" #include "BKE_mesh_runtime.hh" +#include "BKE_modifier.hh" #include "BKE_nla.h" #include "BKE_node.hh" #include "BKE_object.hh" @@ -1376,9 +1377,9 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) ob_name = CTX_DATA_(BLT_I18NCONTEXT_ID_GPENCIL, "Stroke"); break; } - case GP_LRT_OBJECT: - case GP_LRT_SCENE: - case GP_LRT_COLLECTION: { + case GREASE_PENCIL_LINEART_OBJECT: + case GREASE_PENCIL_LINEART_SCENE: + case GREASE_PENCIL_LINEART_COLLECTION: { ob_name = CTX_DATA_(BLT_I18NCONTEXT_ID_GPENCIL, "LineArt"); break; } @@ -1427,9 +1428,9 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) ED_gpencil_create_monkey(C, ob, mat); break; } - case GP_LRT_SCENE: - case GP_LRT_COLLECTION: - case GP_LRT_OBJECT: { + case GREASE_PENCIL_LINEART_SCENE: + case GREASE_PENCIL_LINEART_COLLECTION: + case GREASE_PENCIL_LINEART_OBJECT: { float radius = RNA_float_get(op->ptr, "radius"); float scale[3]; copy_v3_fl(scale, radius); @@ -1447,11 +1448,11 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) BLI_addtail(&ob->greasepencil_modifiers, md); BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, (GpencilModifierData *)md); - if (type == GP_LRT_COLLECTION) { + if (type == GREASE_PENCIL_LINEART_COLLECTION) { md->source_type = LINEART_SOURCE_COLLECTION; md->source_collection = CTX_data_collection(C); } - else if (type == GP_LRT_OBJECT) { + else if (type == GREASE_PENCIL_LINEART_OBJECT) { md->source_type = LINEART_SOURCE_OBJECT; md->source_object = ob_orig; } @@ -1515,7 +1516,11 @@ static void object_add_ui(bContext * /*C*/, wmOperator *op) uiItemR(layout, op->ptr, "type", UI_ITEM_NONE, nullptr, ICON_NONE); int type = RNA_enum_get(op->ptr, "type"); - if (ELEM(type, GP_LRT_COLLECTION, GP_LRT_OBJECT, GP_LRT_SCENE)) { + if (ELEM(type, + GREASE_PENCIL_LINEART_COLLECTION, + GREASE_PENCIL_LINEART_OBJECT, + GREASE_PENCIL_LINEART_SCENE)) + { uiItemR(layout, op->ptr, "use_lights", UI_ITEM_NONE, nullptr, ICON_NONE); uiItemR(layout, op->ptr, "use_in_front", UI_ITEM_NONE, nullptr, ICON_NONE); bool in_front = RNA_boolean_get(op->ptr, "use_in_front"); @@ -1623,9 +1628,9 @@ static int object_grease_pencil_add_exec(bContext *C, wmOperator *op) ob_name = CTX_DATA_(BLT_I18NCONTEXT_ID_GPENCIL, "Suzanne"); break; } - case GP_LRT_OBJECT: - case GP_LRT_SCENE: - case GP_LRT_COLLECTION: { + case GREASE_PENCIL_LINEART_OBJECT: + case GREASE_PENCIL_LINEART_SCENE: + case GREASE_PENCIL_LINEART_COLLECTION: { ob_name = CTX_DATA_(BLT_I18NCONTEXT_ID_GPENCIL, "LineArt"); break; } @@ -1662,10 +1667,65 @@ static int object_grease_pencil_add_exec(bContext *C, wmOperator *op) greasepencil::create_suzanne(*bmain, *object, mat, scene->r.cfra); break; } - case GP_LRT_OBJECT: - case GP_LRT_SCENE: - case GP_LRT_COLLECTION: { - /* TODO. */ + case GREASE_PENCIL_LINEART_OBJECT: + case GREASE_PENCIL_LINEART_SCENE: + case GREASE_PENCIL_LINEART_COLLECTION: { + Object *original_active_object = CTX_data_active_object(C); + + const int type = RNA_enum_get(op->ptr, "type"); + const bool use_in_front = RNA_boolean_get(op->ptr, "use_in_front"); + const bool use_lights = RNA_boolean_get(op->ptr, "use_lights"); + const int stroke_depth_order = RNA_enum_get(op->ptr, "stroke_depth_order"); + const float stroke_depth_offset = RNA_float_get(op->ptr, "stroke_depth_offset"); + + greasepencil::create_blank(*bmain, *object, scene->r.cfra); + + auto *grease_pencil = reinterpret_cast(object->data); + auto *new_md = reinterpret_cast( + BKE_modifier_new(eModifierType_GreasePencilLineart)); + auto *md = reinterpret_cast(new_md); + + BLI_addtail(&object->modifiers, md); + BKE_modifier_unique_name(&object->modifiers, new_md); + BKE_modifiers_persistent_uid_init(*object, *new_md); + + if (type == GREASE_PENCIL_LINEART_COLLECTION) { + md->source_type = LINEART_SOURCE_COLLECTION; + md->source_collection = CTX_data_collection(C); + } + else if (type == GREASE_PENCIL_LINEART_OBJECT) { + md->source_type = LINEART_SOURCE_OBJECT; + md->source_object = original_active_object; + } + else { + /* Whole scene. */ + md->source_type = LINEART_SOURCE_SCENE; + } + /* Only created one layer and one material. */ + STRNCPY(md->target_layer, grease_pencil->get_active_layer()->name().c_str()); + md->target_material = BKE_object_material_get(object, 0); + if (md->target_material) { + id_us_plus(&md->target_material->id); + } + + if (use_lights) { + object->dtx |= OB_USE_GPENCIL_LIGHTS; + } + else { + object->dtx &= ~OB_USE_GPENCIL_LIGHTS; + } + + /* Stroke object is drawn in front of meshes by default. */ + if (use_in_front) { + object->dtx |= OB_DRAW_IN_FRONT; + } + else { + if (stroke_depth_order == GP_DRAWMODE_3D) { + grease_pencil->flag |= GREASE_PENCIL_STROKE_ORDER_3D; + } + md->stroke_depth_offset = stroke_depth_offset; + } + break; } } @@ -1691,6 +1751,29 @@ void OBJECT_OT_grease_pencil_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_object_gpencil_type_items, 0, "Type", ""); + RNA_def_boolean(ot->srna, + "use_in_front", + true, + "Show In Front", + "Show line art grease pencil in front of everything"); + RNA_def_float(ot->srna, + "stroke_depth_offset", + 0.05f, + 0.0f, + FLT_MAX, + "Stroke Offset", + "Stroke offset for the line art modifier", + 0.0f, + 0.5f); + RNA_def_boolean( + ot->srna, "use_lights", false, "Use Lights", "Use lights for this grease pencil object"); + RNA_def_enum( + ot->srna, + "stroke_depth_order", + rna_enum_gpencil_add_stroke_depth_order_items, + GP_DRAWMODE_3D, + "Stroke Depth Order", + "Defines how the strokes are ordered in 3D space (for objects not displayed 'In Front')"); ED_object_add_unit_props_radius(ot); ED_object_add_generic_props(ot, false); diff --git a/source/blender/makesdna/DNA_grease_pencil_types.h b/source/blender/makesdna/DNA_grease_pencil_types.h index 7baf8ed18f3..3e025883173 100644 --- a/source/blender/makesdna/DNA_grease_pencil_types.h +++ b/source/blender/makesdna/DNA_grease_pencil_types.h @@ -335,6 +335,7 @@ typedef struct GreasePencilLayerTreeGroup { typedef enum GreasePencilFlag { GREASE_PENCIL_ANIM_CHANNEL_EXPANDED = (1 << 0), GREASE_PENCIL_AUTOLOCK_LAYERS = (1 << 1), + GREASE_PENCIL_STROKE_ORDER_3D = (1 << 2), } GreasePencilFlag; /** diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 5af3f2f9e91..f1f2901638f 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -634,9 +634,9 @@ enum { GP_EMPTY = 0, GP_STROKE = 1, GP_MONKEY = 2, - GP_LRT_SCENE = 3, - GP_LRT_OBJECT = 4, - GP_LRT_COLLECTION = 5, + GREASE_PENCIL_LINEART_SCENE = 3, + GREASE_PENCIL_LINEART_OBJECT = 4, + GREASE_PENCIL_LINEART_COLLECTION = 5, }; /** #Object.boundtype */ diff --git a/source/blender/makesrna/intern/rna_object.cc b/source/blender/makesrna/intern/rna_object.cc index 0cef6833e58..44ac12562dc 100644 --- a/source/blender/makesrna/intern/rna_object.cc +++ b/source/blender/makesrna/intern/rna_object.cc @@ -157,18 +157,18 @@ const EnumPropertyItem rna_enum_object_gpencil_type_items[] = { {GP_STROKE, "STROKE", ICON_STROKE, "Stroke", "Create a simple stroke with basic colors"}, {GP_MONKEY, "MONKEY", ICON_MONKEY, "Monkey", "Construct a Suzanne grease pencil object"}, RNA_ENUM_ITEM_SEPR, - {GP_LRT_SCENE, - "LRT_SCENE", + {GREASE_PENCIL_LINEART_SCENE, + "LINEART_SCENE", ICON_SCENE_DATA, "Scene Line Art", "Quickly set up line art for the entire scene"}, - {GP_LRT_COLLECTION, - "LRT_COLLECTION", + {GREASE_PENCIL_LINEART_COLLECTION, + "LINEART_COLLECTION", ICON_OUTLINER_COLLECTION, "Collection Line Art", "Quickly set up line art for the active collection"}, - {GP_LRT_OBJECT, - "LRT_OBJECT", + {GREASE_PENCIL_LINEART_OBJECT, + "LINEART_OBJECT", ICON_OBJECT_DATA, "Object Line Art", "Quickly set up line art for the active object"},