Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/spline_bezier.cc35
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_curve_subdivide.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc8
3 files changed, 39 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index f719a1cfda2..36ccadf521b 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -345,8 +345,14 @@ bool BezierSpline::point_is_sharp(const int index) const
ELEM(handle_types_right_[index], HandleType::Vector, HandleType::Free);
}
+/**
+ * \warning: This functiona assumes that the spline has more than one point.
+ */
bool BezierSpline::segment_is_vector(const int index) const
{
+ /* Two control points are necessary to form a segment, that should be checked by the caller. */
+ BLI_assert(this->size() > 1);
+
if (index == this->size() - 1) {
if (is_cyclic_) {
return handle_types_right_.last() == HandleType::Vector &&
@@ -507,13 +513,18 @@ Span<int> BezierSpline::control_point_offsets() const
offset_cache_.resize(size + 1);
MutableSpan<int> offsets = offset_cache_;
-
- int offset = 0;
- for (const int i : IndexRange(size)) {
- offsets[i] = offset;
- offset += this->segment_is_vector(i) ? 1 : resolution_;
+ if (size == 1) {
+ offsets.first() = 0;
+ offsets.last() = 1;
+ }
+ else {
+ int offset = 0;
+ for (const int i : IndexRange(size)) {
+ offsets[i] = offset;
+ offset += this->segment_is_vector(i) ? 1 : resolution_;
+ }
+ offsets.last() = offset;
}
- offsets.last() = offset;
offset_cache_dirty_ = false;
return offsets;
@@ -600,14 +611,22 @@ Span<float3> BezierSpline::evaluated_positions() const
return evaluated_position_cache_;
}
- this->ensure_auto_handles();
-
const int size = this->size();
const int eval_size = this->evaluated_points_size();
evaluated_position_cache_.resize(eval_size);
MutableSpan<float3> positions = evaluated_position_cache_;
+ if (size == 1) {
+ /* Use a special case for single point splines to avoid checking in #evaluate_segment. */
+ BLI_assert(eval_size == 1);
+ positions.first() = positions_.first();
+ position_cache_dirty_ = false;
+ return positions;
+ }
+
+ this->ensure_auto_handles();
+
Span<int> offsets = this->control_point_offsets();
const int grain_size = std::max(512 / resolution_, 1);
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_subdivide.cc
index f32a68bc042..61165902028 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_subdivide.cc
@@ -308,8 +308,12 @@ static SplinePtr subdivide_spline(const Spline &spline,
const VArray<int> &cuts,
const int spline_offset)
{
- /* Since we expect to access each value many times, it should be worth it to make sure the
- * attribute is a real span (especially considering the note below). Using the offset at each
+ if (spline.size() <= 1) {
+ return spline.copy();
+ }
+
+ /* Since we expect to access each value many times, it should be worth it to make sure count
+ * of cuts is a real span (especially considering the note below). Using the offset at each
* point facilitates subdividing in parallel later. */
Array<int> offsets = get_subdivided_offsets(spline, cuts, spline_offset);
const int result_size = offsets.last() + int(!spline.is_cyclic());
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
index a856d593bc2..5a79fcffd4d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
@@ -283,8 +283,12 @@ static SplinePtr subdivide_spline(const Spline &spline,
const VArray<int> &cuts,
const int spline_offset)
{
- /* Since we expect to access each value many times, it should be worth it to make sure the
- * attribute is a real span (especially considering the note below). Using the offset at each
+ if (spline.size() <= 1) {
+ return spline.copy();
+ }
+
+ /* Since we expect to access each value many times, it should be worth it to make sure count
+ * of cuts is a real span (especially considering the note below). Using the offset at each
* point facilitates subdividing in parallel later. */
Array<int> offsets = get_subdivided_offsets(spline, cuts, spline_offset);
const int result_size = offsets.last() + int(!spline.is_cyclic());