diff options
Diffstat (limited to 'source/blender/blenkernel/intern/spline_nurbs.cc')
-rw-r--r-- | source/blender/blenkernel/intern/spline_nurbs.cc | 72 |
1 files changed, 21 insertions, 51 deletions
diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc index 719ba4b7ecd..5993b9a9a27 100644 --- a/source/blender/blenkernel/intern/spline_nurbs.cc +++ b/source/blender/blenkernel/intern/spline_nurbs.cc @@ -179,65 +179,35 @@ int NURBSpline::knots_size() const void NURBSpline::calculate_knots() const { const KnotsMode mode = this->knots_mode; - const int length = this->size(); const int order = order_; + const bool is_bezier = mode == NURBSpline::KnotsMode::Bezier; + const bool is_end_point = mode == NURBSpline::KnotsMode::EndPoint; + /* 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); + /* 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); knots_.resize(this->knots_size()); - MutableSpan<float> knots = knots_; - if (mode == NURBSpline::KnotsMode::Normal || is_cyclic_) { - for (const int i : knots.index_range()) { - knots[i] = static_cast<float>(i); - } - } - else if (mode == NURBSpline::KnotsMode::EndPoint) { - float k = 0.0f; - for (const int i : IndexRange(1, knots.size())) { - knots[i - 1] = k; - if (i >= order && i <= length) { - k += 1.0f; - } - } - } - else if (mode == NURBSpline::KnotsMode::Bezier) { - BLI_assert(ELEM(order, 3, 4)); - if (order == 3) { - float k = 0.6f; - for (const int i : knots.index_range()) { - if (i >= order && i <= length) { - k += 0.5f; - } - knots[i] = std::floor(k); - } - } - else { - float k = 0.34f; - for (const int i : knots.index_range()) { - knots[i] = std::floor(k); - k += 1.0f / 3.0f; - } - } - } + int r = head; + float current = 0.0f; - if (is_cyclic_) { - const int b = length + order - 1; - if (order > 2) { - for (const int i : IndexRange(1, order - 2)) { - if (knots[b] != knots[b - i]) { - if (i == order - 1) { - knots[length + order - 2] += 1.0f; - break; - } - } - } + for (const int i : IndexRange(knots.size() - tail)) { + knots[i] = current; + r--; + if (r == 0) { + current += 1.0; + r = repeat_inner; } + } - int c = order; - for (int i = b; i < this->knots_size(); i++) { - knots[i] = knots[i - 1] + (knots[c] - knots[c - 1]); - c--; - } + const int tail_index = knots.size() - tail; + for (const int i : IndexRange(tail)) { + knots[tail_index + i] = current + (knots[i] - knots[0]); } } |