Fix: GPv3 sometimes crashes when drawing

This was because the size and bounds of points were not properly
checked in some places.
Additionally, the smoothing algorithm should only be run if the
smoothing window is larg enough.
This commit is contained in:
Falk David
2023-10-10 16:22:20 +02:00
parent cf2ea5979c
commit fa2a05ef86
2 changed files with 26 additions and 0 deletions

View File

@@ -8,6 +8,7 @@
#include <limits>
#include "BLI_math_vector.hh"
#include "BLI_stack.hh"
#include "BKE_grease_pencil.hh"
@@ -80,6 +81,18 @@ Array<float2> polyline_fit_curve(Span<float2> points,
const float error_threshold,
const IndexMask &corner_mask)
{
if (points.is_empty()) {
return {};
}
double total_length = 0.0;
for (const int point_i : points.index_range().drop_front(1)) {
total_length += math::distance(points[point_i - 1], points[point_i]);
}
/* Just return a dot. */
if (total_length < 1e-8) {
return Array<float2>({points[0], points[0], points[0]});
}
Array<int32_t> indices(corner_mask.size());
corner_mask.to_indices(indices.as_mutable_span());
uint *indicies_ptr = corner_mask.is_empty() ? nullptr : reinterpret_cast<uint *>(indices.data());
@@ -118,6 +131,12 @@ IndexMask polyline_detect_corners(Span<float2> points,
const float angle_threshold,
IndexMaskMemory &memory)
{
if (points.is_empty()) {
return {};
}
if (points.size() == 1) {
return IndexMask::from_indices<int>({0}, memory);
}
uint *r_corners;
uint r_corner_len;
const int error = curve_fit_corners_detect_fl(*points.data(),

View File

@@ -44,6 +44,9 @@ static Array<float2> sample_curve_2d(Span<float2> positions, const int64_t resol
{
BLI_assert(positions.size() % 3 == 0);
const int64_t num_handles = positions.size() / 3;
if (num_handles == 1) {
return Array<float2>(resolution, positions[1]);
}
const int64_t num_segments = num_handles - 1;
const int64_t num_points = num_segments * resolution;
@@ -234,6 +237,10 @@ struct PaintOperationExecutor {
const IndexRange points,
const IndexRange smooth_window)
{
/* We don't do active smoothing for when we have just 3 points or less. */
if (smooth_window.size() < 4) {
return;
}
Span<float2> screen_space_coords_smooth_slice = self.screen_space_coords_.as_span().slice(
smooth_window);