GPv3: Render boundary strokes with half width to hide gaps on boundaries

The leak detection filter in the fill tool flood-fill method can cause
gaps between filled areas and boundary strokes. This is undesirable, so
the boundary stroke radius is scaled by half for drawing, typically
creating enough overlap between boundaries and the generated fill
strokes to hide artifacts. This behavior is copied from GPv2.

Pull Request: https://projects.blender.org/blender/blender/pulls/122307
This commit is contained in:
Lukas Tönne
2024-05-27 14:43:58 +02:00
parent dbe39fb202
commit aa88ced5c2
3 changed files with 15 additions and 12 deletions

View File

@@ -270,7 +270,8 @@ void draw_grease_pencil_stroke(const RegionView3D &rv3d,
const bool cyclic,
const eGPDstroke_Caps cap_start,
const eGPDstroke_Caps cap_end,
const bool fill_stroke)
const bool fill_stroke,
const float radius_scale)
{
if (indices.is_empty()) {
return;
@@ -295,7 +296,7 @@ void draw_grease_pencil_stroke(const RegionView3D &rv3d,
auto draw_point = [&](const int point_i) {
constexpr const float radius_to_pixel_factor =
1.0f / bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
const float thickness = radii[point_i] * radius_to_pixel_factor;
const float thickness = radii[point_i] * radius_scale * radius_to_pixel_factor;
constexpr const float min_thickness = 0.05f;
immAttr4fv(attr_color, colors[point_i]);
@@ -348,7 +349,8 @@ void draw_grease_pencil_strokes(const RegionView3D &rv3d,
const VArray<ColorGeometry4f> &colors,
const float4x4 &layer_to_world,
const int mode,
const bool use_xray)
const bool use_xray,
const float radius_scale)
{
GPU_program_point_size(true);
@@ -370,11 +372,6 @@ void draw_grease_pencil_strokes(const RegionView3D &rv3d,
/* Note: Serial loop without GrainSize, since immediate mode drawing can't happen in worker
* threads, has to be from the main thread. */
strokes_mask.foreach_index([&](const int stroke_i) {
const float stroke_radius = radii[stroke_i];
if (stroke_radius <= 0) {
return;
}
if (!use_xray) {
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
@@ -396,7 +393,8 @@ void draw_grease_pencil_strokes(const RegionView3D &rv3d,
cyclic[stroke_i],
eGPDstroke_Caps(stroke_start_caps[stroke_i]),
eGPDstroke_Caps(stroke_end_caps[stroke_i]),
false);
false,
radius_scale);
break;
case GP_MATERIAL_MODE_DOT:
case GP_MATERIAL_MODE_SQUARE:

View File

@@ -527,7 +527,8 @@ void draw_grease_pencil_stroke(const RegionView3D &rv3d,
bool cyclic,
eGPDstroke_Caps cap_start,
eGPDstroke_Caps cap_end,
bool fill_stroke);
bool fill_stroke,
float radius_scale = 1.0f);
/**
* Draw points as quads or circles.
*/
@@ -549,7 +550,8 @@ void draw_grease_pencil_strokes(const RegionView3D &rv3d,
const VArray<ColorGeometry4f> &colors,
const float4x4 &layer_to_world,
int mode,
bool use_xray);
bool use_xray,
float radius_scale = 1.0f);
} // namespace image_render

View File

@@ -952,6 +952,8 @@ bke::CurvesGeometry fill_strokes(const ViewContext &view_context,
const float2 fill_point_view = math::safe_divide(
fill_point - win_center - offset * float2(win_size), zoom) +
win_center;
/* Scale stroke radius by half to hide gaps between filled areas and boundaries. */
const float radius_scale = 0.5f;
image_render::RegionViewData region_view_data = image_render::region_init(region, win_size);
@@ -1007,7 +1009,8 @@ bke::CurvesGeometry fill_strokes(const ViewContext &view_context,
colors,
layer_to_world,
fill_draw_mode,
use_xray);
use_xray,
radius_scale);
}
image_render::clear_viewmat();