diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2022-08-06 20:16:34 +0300 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2022-08-06 20:16:34 +0300 |
commit | fecef2ae7415cd7d7cf7907b2e704ef264fbd242 (patch) | |
tree | b56777d5b5eb89e4d1c90ea3d9ec17a64c436b27 /source | |
parent | 8f915f0efba3da652ad06fa9fcfba7d6ca26e719 (diff) | |
parent | d58476049e2ae2e407d66cbb4d5eac65b594509a (diff) |
Merge branch 'blender-v3.3-release'
Diffstat (limited to 'source')
8 files changed, 91 insertions, 146 deletions
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index fa852cdd6da..aa2c93f7c5a 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -437,16 +437,6 @@ static bool nearly_parallel_normalized(const float d1[3], const float d2[3]) return compare_ff(fabsf(direction_dot), 1.0f, BEVEL_EPSILON_ANG_DOT); } -/** - * calculate the determinant of a matrix formed by three vectors - * \return dot(a, cross(b, c)) = determinant(a, b, c) - */ -static float determinant_v3v3v3(const float a[3], const float b[3], const float c[3]) -{ - return a[0] * b[1] * c[2] + a[1] * b[2] * c[0] + a[2] * b[0] * c[1] - a[0] * b[2] * c[1] - - a[1] * b[0] * c[2] - a[2] * b[1] * c[0]; -} - /* Make a new BoundVert of the given kind, inserting it at the end of the circular linked * list with entry point bv->boundstart, and return it. */ static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3]) @@ -4134,114 +4124,44 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in) VMesh *vm_out = new_adj_vmesh(bp->mem_arena, n_boundary, ns_out, vm_in->boundstart); /* First we adjust the boundary vertices of the input mesh, storing in output mesh. */ - BoundVert *bndv = vm_in->boundstart; for (int i = 0; i < n_boundary; i++) { - float co1[3], co2[3], acc[3]; - EdgeHalf *e = bndv->elast; - /* Generate tangents. This is hacked together and would ideally be done elsewhere and then only - * used here. */ - float tangent[3], tangent2[3], normal[3]; - bool convex = true; - bool orthogonal = false; - float stretch = 0.0f; - if (e) { - /* Projection direction is direction of the edge. */ - sub_v3_v3v3(tangent, e->e->v1->co, e->e->v2->co); - if (e->is_rev) { - negate_v3(tangent); - } - normalize_v3(tangent); - if (bndv->is_arc_start || bndv->is_patch_start) { - BMFace *face = e->fnext; - if (face) { - copy_v3_v3(normal, face->no); - } - else { - zero_v3(normal); - } - madd_v3_v3v3fl(co2, bndv->profile.middle, normal, 0.1f); - } - if (bndv->is_arc_start || bp->affect_type == BEVEL_AFFECT_VERTICES) { - EdgeHalf *e1 = bndv->next->elast; - BLI_assert(e1); - sub_v3_v3v3(tangent2, e1->e->v1->co, e1->e->v2->co); - if (e1->is_rev) { - negate_v3(tangent2); - } - normalize_v3(tangent2); - - convex = determinant_v3v3v3(tangent2, tangent, normal) < 0; - - add_v3_v3(tangent2, tangent); - normalize_v3(tangent2); - copy_v3_v3(tangent, tangent2); - } - /* Calculate a factor which determines how much the interpolated mesh is - * going to be stretched out into the direction of the tangent. - * It is currently using the difference along the tangent of the - * central point on the profile and the current center vertex position. */ - get_profile_point(bp, &bndv->profile, ns_in2, ns_in, co); - stretch = dot_v3v3(tangent, mesh_vert(vm_in, i, ns_in2, ns_in2)->co) - dot_v3v3(tangent, co); - stretch = fabsf(stretch); - /* Scale the tangent by stretch. The divide by ns_in2 comes from the Levin Paper. */ - mul_v3_fl(tangent, stretch / ns_in2); - orthogonal = bndv->is_patch_start; - } - else if (bndv->prev->is_patch_start) { - /* If this is the second edge of a patch and therefore #e is NULL, - * then e->fprev has to be used/not NULL. */ - BLI_assert(bndv->prev->elast); - BMFace *face = bndv->prev->elast->fnext; - if (face) { - copy_v3_v3(normal, face->no); - } - else { - zero_v3(normal); - } - orthogonal = true; - } - else { - /** Should only come here from make_cube_corner_adj_vmesh. */ - sub_v3_v3v3(co1, mesh_vert(vm_in, i, 0, 0)->co, mesh_vert(vm_in, i, 0, 1)->co); - sub_v3_v3v3(co2, mesh_vert(vm_in, i, 0, 1)->co, mesh_vert(vm_in, i, 0, 2)->co); - cross_v3_v3v3(tangent, co1, co2); - /** The following constant is chosen to best match the old results. */ - normalize_v3_length(tangent, 1.5f / ns_out); - } - /** Copy corner vertex. */ copy_v3_v3(mesh_vert(vm_out, i, 0, 0)->co, mesh_vert(vm_in, i, 0, 0)->co); - /** Copy the rest of the boundary vertices. */ for (int k = 1; k < ns_in; k++) { copy_v3_v3(co, mesh_vert(vm_in, i, 0, k)->co); - copy_v3_v3(co1, mesh_vert(vm_in, i, 0, k - 1)->co); - copy_v3_v3(co2, mesh_vert(vm_in, i, 0, k + 1)->co); - - add_v3_v3v3(acc, co1, co2); - if (bndv->is_arc_start) { - sub_v3_v3(co1, co); - sub_v3_v3(co2, co); - normalize_v3(co1); - normalize_v3(co2); - add_v3_v3v3(tangent, co1, co2); - /* This is an empirical formula to make the result look good. */ - normalize_v3(tangent); - float dot = convex ? fminf(0, dot_v3v3(tangent2, tangent)) : 1.0f; - mul_v3_fl(tangent, stretch / ns_in * dot); - } - else if (orthogonal) { - sub_v3_v3(co1, co); - cross_v3_v3v3(tangent, normal, co1); - /* This is an empirical formula to make the result look good. */ - normalize_v3_length(tangent, -bp->offset * 0.7071f / ns_in); - } - mul_v3_fl(co, 2.0f); - madd_v3_v3fl(co, acc, -0.25f); - madd_v3_v3fl(co, mesh_vert(vm_in, i, 1, k)->co, -0.5f); - add_v3_v3(co, tangent); + /* Smooth boundary rule. Custom profiles shouldn't be smoothed. */ + if (bp->profile_type != BEVEL_PROFILE_CUSTOM) { + float co1[3], co2[3], acc[3]; + copy_v3_v3(co1, mesh_vert(vm_in, i, 0, k - 1)->co); + copy_v3_v3(co2, mesh_vert(vm_in, i, 0, k + 1)->co); + + add_v3_v3v3(acc, co1, co2); + madd_v3_v3fl(acc, co, -2.0f); + madd_v3_v3fl(co, acc, -1.0f / 6.0f); + } copy_v3_v3(mesh_vert_canon(vm_out, i, 0, 2 * k)->co, co); } + } + /* Now adjust odd boundary vertices in output mesh, based on even ones. */ + BoundVert *bndv = vm_out->boundstart; + for (int i = 0; i < n_boundary; i++) { + for (int k = 1; k < ns_out; k += 2) { + get_profile_point(bp, &bndv->profile, k, ns_out, co); + + /* Smooth if using a non-custom profile. */ + if (bp->profile_type != BEVEL_PROFILE_CUSTOM) { + float co1[3], co2[3], acc[3]; + copy_v3_v3(co1, mesh_vert_canon(vm_out, i, 0, k - 1)->co); + copy_v3_v3(co2, mesh_vert_canon(vm_out, i, 0, k + 1)->co); + + add_v3_v3v3(acc, co1, co2); + madd_v3_v3fl(acc, co, -2.0f); + madd_v3_v3fl(co, acc, -1.0f / 6.0f); + } + + copy_v3_v3(mesh_vert_canon(vm_out, i, 0, k)->co, co); + } bndv = bndv->next; } vmesh_copy_equiv_verts(vm_out); @@ -4249,7 +4169,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in) /* Copy adjusted verts back into vm_in. */ for (int i = 0; i < n_boundary; i++) { for (int k = 0; k < ns_in; k++) { - copy_v3_v3(mesh_vert_canon(vm_in, i, 0, k)->co, mesh_vert_canon(vm_out, i, 0, 2 * k)->co); + copy_v3_v3(mesh_vert(vm_in, i, 0, k)->co, mesh_vert(vm_out, i, 0, 2 * k)->co); } } @@ -4334,7 +4254,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in) vmesh_copy_equiv_verts(vm_out); /* The center vertex is special. */ - gamma = sabin_gamma(n_boundary) * 0.5f; + gamma = sabin_gamma(n_boundary); beta = -gamma; /* Accumulate edge verts in co1, face verts in co2. */ float co1[3], co2[3]; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index 77616ae13b6..6bb59f29b98 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -373,19 +373,16 @@ static void edge_types_panel_draw(const bContext *UNUSED(C), Panel *panel) } sub = uiLayoutRow(col, false); - uiItemR(sub, ptr, "use_crease", 0, "", ICON_NONE); - 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_("Crease Angle Cached"), ICON_INFO); + uiItemR(sub, ptr, "use_crease", 0, IFACE_("Crease (Angle Cached)"), ICON_NONE); } else { - uiItemR(entry, + uiItemR(sub, ptr, "use_crease", 0, "", ICON_NONE); + uiItemR(sub, ptr, "crease_threshold", UI_ITEM_R_SLIDER | UI_ITEM_R_FORCE_BLANK_DECORATE, - IFACE_("Default Angle"), + NULL, ICON_NONE); } @@ -447,8 +444,6 @@ static void options_light_reference_draw(const bContext *UNUSED(C), Panel *panel 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, "use_shadow_enclosed_shapes", 0, IFACE_("Enclosed Shapes"), ICON_NONE); } static void options_panel_draw(const bContext *UNUSED(C), Panel *panel) diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 01d1e95efb3..63433113822 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -440,12 +440,17 @@ typedef enum eLineartTriangleFlags { } eLineartTriangleFlags; #define LRT_SHADOW_MASK_UNDEFINED 0 -#define LRT_SHADOW_MASK_LIT (1 << 0) +#define LRT_SHADOW_MASK_ILLUMINATED (1 << 0) #define LRT_SHADOW_MASK_SHADED (1 << 1) #define LRT_SHADOW_MASK_ENCLOSED_SHAPE (1 << 2) #define LRT_SHADOW_MASK_INHIBITED (1 << 3) #define LRT_SHADOW_SILHOUETTE_ERASED_GROUP (1 << 4) #define LRT_SHADOW_SILHOUETTE_ERASED_OBJECT (1 << 5) +#define LRT_SHADOW_MASK_ILLUMINATED_SHAPE (1 << 6) + +#define LRT_SHADOW_TEST_SHAPE_BITS \ + (LRT_SHADOW_MASK_ILLUMINATED | LRT_SHADOW_MASK_SHADED | LRT_SHADOW_MASK_INHIBITED | \ + LRT_SHADOW_MASK_ILLUMINATED_SHAPE) /** * Controls how many edges a worker thread is processing at one request. diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index 874da3b88c9..011c79025c4 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -304,13 +304,12 @@ void lineart_edge_cut(LineartData *ld, /* The enclosed shape flag will override regular lit/shaded * flags. See LineartEdgeSegment::shadow_mask_bits for details. */ if (shadow_bits == LRT_SHADOW_MASK_ENCLOSED_SHAPE) { - if (seg->shadow_mask_bits & LRT_SHADOW_MASK_LIT || e->flags & LRT_EDGE_FLAG_LIGHT_CONTOUR) { - seg->shadow_mask_bits &= ~LRT_SHADOW_MASK_LIT; + if (seg->shadow_mask_bits & LRT_SHADOW_MASK_ILLUMINATED || + e->flags & LRT_EDGE_FLAG_LIGHT_CONTOUR) { seg->shadow_mask_bits |= LRT_SHADOW_MASK_INHIBITED; } else if (seg->shadow_mask_bits & LRT_SHADOW_MASK_SHADED) { - seg->shadow_mask_bits &= ~LRT_SHADOW_MASK_SHADED; - seg->shadow_mask_bits |= LRT_SHADOW_MASK_LIT; + seg->shadow_mask_bits |= LRT_SHADOW_MASK_ILLUMINATED_SHAPE; } } else { @@ -3643,7 +3642,8 @@ static LineartData *lineart_create_render_buffer(Scene *scene, (lmd->light_contour_object != NULL)); ld->conf.shadow_selection = lmd->shadow_selection_override; - ld->conf.shadow_enclose_shapes = (lmd->calculation_flags & LRT_SHADOW_ENCLOSED_SHAPES) != 0; + ld->conf.shadow_enclose_shapes = lmd->shadow_selection_override == + LRT_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES; ld->conf.shadow_use_silhouette = lmd->shadow_use_silhouette_override != 0; ld->conf.use_back_face_culling = (lmd->calculation_flags & LRT_USE_BACK_FACE_CULLING) != 0; @@ -5227,13 +5227,22 @@ static void lineart_gpencil_generate(LineartCache *cache, } if (shaodow_selection) { if (ec->shadow_mask_bits != LRT_SHADOW_MASK_UNDEFINED) { - /* TODO(@Yiming): Give a behavior option for how to display undefined shadow info. */ - if ((shaodow_selection == LRT_SHADOW_FILTER_LIT && - (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_LIT))) || - (shaodow_selection == LRT_SHADOW_FILTER_SHADED && - (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_SHADED)))) { + /* TODO(Yiming): Give a behaviour option for how to display undefined shadow info. */ + if ((shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED && + (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_ILLUMINATED)))) { continue; } + else if ((shaodow_selection == LRT_SHADOW_FILTER_SHADED && + (!(ec->shadow_mask_bits & LRT_SHADOW_MASK_SHADED)))) { + continue; + } + else if (shaodow_selection == LRT_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES) { + uint32_t test_bits = ec->shadow_mask_bits & LRT_SHADOW_TEST_SHAPE_BITS; + if ((test_bits != LRT_SHADOW_MASK_ILLUMINATED) && + (test_bits != (LRT_SHADOW_MASK_SHADED | LRT_SHADOW_MASK_ILLUMINATED_SHAPE))) { + continue; + } + } } } if (silhouette_mode && (ec->type & (LRT_EDGE_FLAG_CONTOUR))) { diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c index d0047e235b8..bf42677d79c 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c @@ -109,9 +109,10 @@ void lineart_register_shadow_cuts(LineartData *ld, LineartEdge *e, LineartEdge * la2 = la2 * e->v2->fbcoord[3] / (e->v1->fbcoord[3] - la2 * (e->v1->fbcoord[3] - e->v2->fbcoord[3])); unsigned char shadow_bits = (es->occlusion != 0) ? LRT_SHADOW_MASK_SHADED : - LRT_SHADOW_MASK_LIT; + LRT_SHADOW_MASK_ILLUMINATED; - if (lineart_contour_viewed_from_dark_side(ld, e) && shadow_bits == LRT_SHADOW_MASK_LIT) { + if (lineart_contour_viewed_from_dark_side(ld, e) && + shadow_bits == LRT_SHADOW_MASK_ILLUMINATED) { shadow_bits = LRT_SHADOW_MASK_SHADED; } diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 2bb95caddfb..7f8e436f007 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -999,9 +999,14 @@ typedef enum eLineartGpencilModifierSource { } eLineartGpencilModifierSource; typedef enum eLineartGpencilModifierShadowFilter { + /* These options need to be ordered in this way because those latter options requires line art to + run a few extra stages. Having those values set up this way will allow + #BKE_gpencil_get_lineart_modifier_limits() to find out maximum stages needed in multiple + cached line art modifiers. */ LRT_SHADOW_FILTER_NONE = 0, - LRT_SHADOW_FILTER_LIT = 1, + LRT_SHADOW_FILTER_ILLUMINATED = 1, LRT_SHADOW_FILTER_SHADED = 2, + LRT_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES = 3, } eLineartGpencilModifierShadowFilter; typedef enum eLineartGpencilModifierSilhouetteFilter { diff --git a/source/blender/makesdna/DNA_lineart_types.h b/source/blender/makesdna/DNA_lineart_types.h index 1ff656f85ed..05380325852 100644 --- a/source/blender/makesdna/DNA_lineart_types.h +++ b/source/blender/makesdna/DNA_lineart_types.h @@ -38,7 +38,6 @@ typedef enum eLineartMainFlags { LRT_USE_BACK_FACE_CULLING = (1 << 19), LRT_USE_IMAGE_BOUNDARY_TRIMMING = (1 << 20), LRT_CHAIN_PRESERVE_DETAILS = (1 << 22), - LRT_SHADOW_ENCLOSED_SHAPES = (1 << 23), LRT_SHADOW_USE_SILHOUETTE = (1 << 24), } eLineartMainFlags; diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 0647bc62081..2dfd9d46665 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -3197,9 +3197,27 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna) }; static const EnumPropertyItem modifier_lineart_shadow_region_filtering[] = { - {LRT_SHADOW_FILTER_NONE, "NONE", 0, "None", ""}, - {LRT_SHADOW_FILTER_LIT, "LIT", 0, "Lit", ""}, - {LRT_SHADOW_FILTER_SHADED, "SHADED", 0, "Shaded", ""}, + {LRT_SHADOW_FILTER_NONE, + "NONE", + 0, + "None", + "Not filtering any lines based on illumination region"}, + {LRT_SHADOW_FILTER_ILLUMINATED, + "ILLUMINATED", + 0, + "Illuminated", + "Only selecting lines from illuminated regions"}, + {LRT_SHADOW_FILTER_SHADED, + "SHADED", + 0, + "Shaded", + "Only selecting lines from shaded regions"}, + {LRT_SHADOW_FILTER_ILLUMINATED_ENCLOSED_SHAPES, + "ILLUMINATED_ENCLOSED", + 0, + "Illuminated (Enclosed Shapes)", + "Selecting lines from lit regions, and make the combination of contour, light contour and " + "shadow lines into enclosed shapes"}, {0, NULL, 0, NULL, NULL}, }; @@ -3464,13 +3482,6 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna) "affect cast shadow and light contour since they are at the border"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update"); - prop = RNA_def_property(srna, "use_shadow_enclosed_shapes", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "calculation_flags", LRT_SHADOW_ENCLOSED_SHAPES); - RNA_def_property_ui_text(prop, - "Shadow Enclosed Shapes", - "Reproject visible lines again to get enclosed shadow shapes"); - RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); - prop = RNA_def_property(srna, "silhouette_filtering", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "silhouette_selection"); RNA_def_property_enum_items(prop, modifier_lineart_silhouette_filtering); |