diff options
author | Yiming Wu <xp8110@outlook.com> | 2022-06-29 17:54:29 +0300 |
---|---|---|
committer | Yiming Wu <xp8110@outlook.com> | 2022-06-29 17:54:29 +0300 |
commit | 6dd8ceef2a21f64cbb61a96560c50c162f9dae39 (patch) | |
tree | dff82af871b36d7df37213cdcc2a94dfd1ca70b2 /source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c | |
parent | 2ac5b55289d361de7fccc9be188b98df358ab932 (diff) |
LineArt: Shadow and related functionalities.
This patch includes the full shadow functionality for LineArt:
- Light contour and cast shadow lines.
- Lit/shaded region selection.
- Enclosed light/shadow shape calculation.
- Silhouette/anti-silhouette selection.
- Intersection priority based on shadow edge identifier.
Reviewed By: Sebastian Parborg (zeddb)
Differential Revision: https://developer.blender.org/D15109
Diffstat (limited to 'source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c')
-rw-r--r-- | source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c | 112 |
1 files changed, 101 insertions, 11 deletions
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index 8d77fb50c71..1c5485d2640 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -88,6 +88,8 @@ static void generate_strokes_actual( lmd->intersection_mask, lmd->thickness, lmd->opacity, + lmd->shadow_selection, + lmd->silhouette_selection, lmd->source_vertex_group, lmd->vgname, lmd->flags); @@ -193,6 +195,7 @@ static void bakeModifier(Main *UNUSED(bmain), * modifiers in the stack. */ lmd->edge_types_override = lmd->edge_types; lmd->level_end_override = lmd->level_end; + lmd->shadow_selection_override = lmd->shadow_selection; MOD_lineart_compute_feature_lines( depsgraph, lmd, &gpd->runtime.lineart_cache, (!(ob->dtx & OB_DRAW_IN_FRONT))); @@ -263,6 +266,10 @@ static void updateDepsgraph(GpencilModifierData *md, DEG_add_object_relation( ctx->node, ctx->scene->camera, DEG_OB_COMP_PARAMETERS, "Line Art Modifier"); } + if (lmd->light_contour_object) { + DEG_add_object_relation( + ctx->node, lmd->light_contour_object, DEG_OB_COMP_TRANSFORM, "Line Art Modifier"); + } } static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData) @@ -274,6 +281,7 @@ static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, walk(userData, ob, (ID **)&lmd->source_object, IDWALK_CB_NOP); walk(userData, ob, (ID **)&lmd->source_camera, IDWALK_CB_NOP); + walk(userData, ob, (ID **)&lmd->light_contour_object, IDWALK_CB_NOP); } static void panel_draw(const bContext *UNUSED(C), Panel *panel) @@ -340,31 +348,107 @@ static void edge_types_panel_draw(const bContext *UNUSED(C), Panel *panel) const bool is_baked = RNA_boolean_get(ptr, "is_baked"); const bool use_cache = RNA_boolean_get(ptr, "use_cache"); const bool is_first = BKE_gpencil_is_first_lineart_in_stack(ob_ptr.data, ptr->data); + const bool has_light = RNA_pointer_get(ptr, "light_contour_object").data != NULL; uiLayoutSetEnabled(layout, !is_baked); uiLayoutSetPropSep(layout, true); + uiLayout *sub = uiLayoutRow(layout, false); + uiLayoutSetActive(sub, has_light); + uiItemR(sub, ptr, "shadow_region_filtering", 0, IFACE_("Illumination Filtering"), ICON_NONE); + uiLayout *col = uiLayoutColumn(layout, true); - uiItemR(col, ptr, "use_contour", 0, IFACE_("Contour"), ICON_NONE); - uiItemR(col, ptr, "use_loose", 0, IFACE_("Loose"), ICON_NONE); - uiItemR(col, ptr, "use_material", 0, IFACE_("Material Borders"), ICON_NONE); - uiItemR(col, ptr, "use_edge_mark", 0, IFACE_("Edge Marks"), ICON_NONE); - uiItemR(col, ptr, "use_intersection", 0, IFACE_("Intersections"), ICON_NONE); + sub = uiLayoutRowWithHeading(col, false, IFACE_("Create")); + uiItemR(sub, ptr, "use_contour", 0, "", ICON_NONE); + + uiLayout *entry = uiLayoutRow(sub, true); + uiLayoutSetActive(entry, RNA_boolean_get(ptr, "use_contour")); + uiItemR(entry, ptr, "silhouette_filtering", 0, "", ICON_NONE); + + const int silhouette_filtering = RNA_enum_get(ptr, "silhouette_filtering"); + if (silhouette_filtering != LRT_SILHOUETTE_FILTER_NONE) { + uiItemR(entry, ptr, "use_invert_silhouette", 0, "", ICON_ARROW_LEFTRIGHT); + } - uiLayout *sub = uiLayoutRowWithHeading(col, false, IFACE_("Crease")); + sub = uiLayoutRow(col, false); uiItemR(sub, ptr, "use_crease", 0, "", ICON_NONE); - uiLayout *entry = uiLayoutRow(sub, false); + entry = uiLayoutColumn(sub, false); + uiItemL(entry, IFACE_("Crease"), ICON_NONE); uiLayoutSetActive(entry, RNA_boolean_get(ptr, "use_crease") || is_first); if (use_cache && !is_first) { - uiItemL(entry, IFACE_("Angle Cached"), ICON_INFO); + uiItemL(entry, IFACE_("Crease Angle Cached"), ICON_INFO); + } + else { + uiItemR(entry, + ptr, + "crease_threshold", + UI_ITEM_R_SLIDER | UI_ITEM_R_FORCE_BLANK_DECORATE, + IFACE_("Default Angle"), + ICON_NONE); + } + + uiItemR(col, ptr, "use_intersection", 0, IFACE_("Intersections"), ICON_NONE); + uiItemR(col, ptr, "use_material", 0, IFACE_("Material Borders"), ICON_NONE); + uiItemR(col, ptr, "use_edge_mark", 0, IFACE_("Edge Marks"), ICON_NONE); + uiItemR(col, ptr, "use_loose", 0, IFACE_("Loose"), ICON_NONE); + + entry = uiLayoutColumn(col, false); + uiLayoutSetActive(entry, has_light); + + sub = uiLayoutRow(entry, false); + uiItemR(sub, ptr, "use_light_contour", 0, IFACE_("Light Contour"), ICON_NONE); + + uiItemR(entry, ptr, "use_shadow", 0, IFACE_("Cast Shadow"), ICON_NONE); + + uiItemL(layout, IFACE_("Options"), ICON_NONE); + + sub = uiLayoutColumn(layout, false); + if (use_cache && !is_first) { + uiItemL(sub, IFACE_("Type overlapping cached"), ICON_INFO); } else { - uiItemR(entry, ptr, "crease_threshold", UI_ITEM_R_SLIDER, " ", ICON_NONE); + uiItemR(sub, + ptr, + "use_overlap_edge_type_support", + 0, + IFACE_("Allow Overlapping Types"), + ICON_NONE); } +} + +static void options_light_reference_draw(const bContext *UNUSED(C), Panel *panel) +{ + uiLayout *layout = panel->layout; + PointerRNA ob_ptr; + PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, &ob_ptr); + + const bool is_baked = RNA_boolean_get(ptr, "is_baked"); + const bool use_cache = RNA_boolean_get(ptr, "use_cache"); + const bool has_light = RNA_pointer_get(ptr, "light_contour_object").data != NULL; + const bool is_first = BKE_gpencil_is_first_lineart_in_stack(ob_ptr.data, ptr->data); - uiItemR(layout, ptr, "use_overlap_edge_type_support", 0, IFACE_("Allow Overlap"), ICON_NONE); + uiLayoutSetPropSep(layout, true); + uiLayoutSetEnabled(layout, !is_baked); + + if (use_cache && !is_first) { + uiItemL(layout, "Cached from the first line art modifier.", ICON_INFO); + return; + } + + uiItemR(layout, ptr, "light_contour_object", 0, NULL, ICON_NONE); + + uiLayout *remaining = uiLayoutColumn(layout, false); + uiLayoutSetActive(remaining, has_light); + + uiItemR(remaining, ptr, "shadow_camera_size", 0, NULL, ICON_NONE); + + uiLayout *col = uiLayoutColumn(remaining, true); + uiItemR(col, ptr, "shadow_camera_near", 0, "Near", ICON_NONE); + uiItemR(col, ptr, "shadow_camera_far", 0, "Far", ICON_NONE); + + uiItemR(layout, ptr, "shadow_enclosed_shapes", 0, IFACE_("Eclosed Shapes"), ICON_NONE); } static void options_panel_draw(const bContext *UNUSED(C), Panel *panel) @@ -584,7 +668,7 @@ static void chaining_panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "use_fuzzy_intersections", 0, NULL, ICON_NONE); uiItemR(col, ptr, "use_fuzzy_all", 0, NULL, ICON_NONE); uiItemR(col, ptr, "use_loose_edge_chain", 0, IFACE_("Loose Edges"), ICON_NONE); - uiItemR(col, ptr, "use_loose_as_contour", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "use_loose_as_contour", 0, IFACE_("Loose Edges As Contour"), ICON_NONE); uiItemR(col, ptr, "use_detail_preserve", 0, NULL, ICON_NONE); uiItemR(col, ptr, "use_geometry_space_chain", 0, IFACE_("Geometry Space"), ICON_NONE); @@ -695,6 +779,12 @@ static void panelRegister(ARegionType *region_type) gpencil_modifier_subpanel_register( region_type, "edge_types", "Edge Types", NULL, edge_types_panel_draw, panel_type); + gpencil_modifier_subpanel_register(region_type, + "light_reference", + "Light Reference", + NULL, + options_light_reference_draw, + panel_type); gpencil_modifier_subpanel_register( region_type, "geometry", "Geometry Processing", NULL, options_panel_draw, panel_type); PanelType *occlusion_panel = gpencil_modifier_subpanel_register( |