diff options
author | Laurynas Duburas <laurynas> | 2022-03-11 03:34:27 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-03-11 03:34:27 +0300 |
commit | 0602852860dda7dfc0ea20c72e03b7f96c981f1a (patch) | |
tree | f6679aba0cfdfcda8e0e244549eb739e025953e0 /source/blender/blenkernel/intern/spline_nurbs.cc | |
parent | 27fb63381e9b0963976237c58ca2cfc9bc5ddfd8 (diff) |
Curve: Improve NURBS knot generation modes
This patch enables all 8 combinations of Nurbs modes: Cyclic,
Bezier and Endpoint. Also removes restriction on Bezier Nurbs order.
The most significant changes are mode combinations bringing new
meaning. In D13891 is a scheme showing NURBS with same control
points in a modes, and also further description of each possible case.
Differential Revision: https://developer.blender.org/D13891
Diffstat (limited to 'source/blender/blenkernel/intern/spline_nurbs.cc')
-rw-r--r-- | source/blender/blenkernel/intern/spline_nurbs.cc | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc index c2479e9e595..1e0fb874d11 100644 --- a/source/blender/blenkernel/intern/spline_nurbs.cc +++ b/source/blender/blenkernel/intern/spline_nurbs.cc @@ -142,15 +142,11 @@ bool NURBSpline::check_valid_size_and_order() const return false; } - if (!is_cyclic_ && this->knots_mode == KnotsMode::Bezier) { - if (order_ == 4) { - if (this->size() < 5) { - return false; - } - } - else if (order_ != 3) { + if (ELEM(this->knots_mode, KnotsMode::Bezier, KnotsMode::EndPointBezier)) { + if (this->knots_mode == KnotsMode::Bezier && this->size() <= order_) { return false; } + return (!is_cyclic_ || this->size() % (order_ - 1) == 0); } return true; @@ -166,12 +162,15 @@ void NURBSpline::calculate_knots() const { const KnotsMode mode = this->knots_mode; const int order = order_; - const bool is_bezier = mode == NURBSpline::KnotsMode::Bezier; - const bool is_end_point = mode == NURBSpline::KnotsMode::EndPoint; + const bool is_bezier = ELEM( + mode, NURBSpline::KnotsMode::Bezier, NURBSpline::KnotsMode::EndPointBezier); + const bool is_end_point = ELEM( + mode, NURBSpline::KnotsMode::EndPoint, NURBSpline::KnotsMode::EndPointBezier); /* Inner knots are always repeated once except on Bezier case. */ const int repeat_inner = is_bezier ? order - 1 : 1; /* How many times to repeat 0.0 at the beginning of knot. */ - const int head = is_end_point && !is_cyclic_ ? order : (is_bezier ? order / 2 : 1); + const int head = is_end_point ? (order - (is_cyclic_ ? 1 : 0)) : + (is_bezier ? min_ii(2, repeat_inner) : 1); /* Number of knots replicating widths of the starting knots. * Covers both Cyclic and EndPoint cases. */ const int tail = is_cyclic_ ? 2 * order - 1 : (is_end_point ? order : 0); @@ -182,7 +181,13 @@ void NURBSpline::calculate_knots() const int r = head; float current = 0.0f; - for (const int i : IndexRange(knots.size() - tail)) { + const int offset = is_end_point && is_cyclic_ ? 1 : 0; + if (offset) { + knots[0] = current; + current += 1.0f; + } + + for (const int i : IndexRange(offset, knots.size() - offset - tail)) { knots[i] = current; r--; if (r == 0) { |