Commit: 0602852860dda7dfc0ea20c72e03b7f96c981f1a Author: Laurynas Duburas Date: Thu Mar 10 18:34:27 2022 -0600 Branches: master https://developer.blender.org/rB0602852860dda7dfc0ea20c72e03b7f96c981f1a
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 =================================================================== M release/scripts/startup/bl_ui/properties_data_curve.py M source/blender/blenkernel/BKE_blender_version.h M source/blender/blenkernel/BKE_curve.h M source/blender/blenkernel/BKE_spline.hh M source/blender/blenkernel/intern/curve.cc M source/blender/blenkernel/intern/curve_eval.cc M source/blender/blenkernel/intern/spline_nurbs.cc M source/blender/blenloader/intern/versioning_300.c M source/blender/editors/curve/editcurve.c M source/blender/editors/curve/editcurve_add.c M source/blender/makesrna/intern/rna_curve.c M source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc =================================================================== diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index 26e5cfaae60..2ad6e5bae8a 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -289,7 +289,6 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel): if is_surf: subsub = sub.column() - subsub.active = (not act_spline.use_cyclic_v) subsub.prop(act_spline, "use_bezier_v", text="V") sub = col.column(heading="Endpoint", align=True) @@ -297,7 +296,6 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel): if is_surf: subsub = sub.column() - subsub.active = (not act_spline.use_cyclic_v) subsub.prop(act_spline, "use_endpoint_v", text="V") sub = col.column(align=True) @@ -322,6 +320,18 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel): col.prop(act_spline, "radius_interpolation", text="Radius") layout.prop(act_spline, "use_smooth") + if act_spline.type == 'NURBS': + messages = [act_spline.valid_message_u] + if is_surf and act_spline.point_count_v > 1: + messages.append(act_spline.valid_message_v) + + messages = list(filter(None, messages)) + + if len(messages) > 0: + layout.separator() + col = layout.column(align=True) + for message in messages: + col.label(text=message, icon='INFO') class DATA_PT_font(CurveButtonsPanelText, Panel): diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index a8a851bb228..1639a564508 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,7 +25,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 5 +#define BLENDER_FILE_SUBVERSION 6 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 3f65ce83b3f..394d97223e3 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -269,6 +269,14 @@ void BKE_nurb_knot_calc_v(struct Nurb *nu); bool BKE_nurb_check_valid_u(const struct Nurb *nu); bool BKE_nurb_check_valid_v(const struct Nurb *nu); bool BKE_nurb_check_valid_uv(const struct Nurb *nu); +bool BKE_nurb_valid_message(int pnts, + short order, + short flag, + short type, + bool is_surf, + const char *dir, + char *message_dst, + size_t maxncpy); bool BKE_nurb_order_clamp_u(struct Nurb *nu); bool BKE_nurb_order_clamp_v(struct Nurb *nu); diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh index 42b4702ee44..ed9b743b524 100644 --- a/source/blender/blenkernel/BKE_spline.hh +++ b/source/blender/blenkernel/BKE_spline.hh @@ -453,6 +453,7 @@ class NURBSpline final : public Spline { Normal, EndPoint, Bezier, + EndPointBezier, }; /** Method used to recalculate the knots vector when points are added or removed. */ diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 6b7f7af44e8..0b619c1a969 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -17,8 +17,8 @@ #include "BLI_index_range.hh" #include "BLI_math.h" #include "BLI_math_vec_types.hh" +#include "BLI_string.h" #include "BLI_utildefines.h" - #include "BLT_translation.h" /* Allow using deprecated functionality for .blend file I/O. */ @@ -1156,12 +1156,13 @@ void BKE_nurb_bpoint_calc_plane(struct Nurb *nu, BPoint *bp, float r_plane[3]) static void calcknots(float *knots, const int pnts, const short order, const short flag) { const bool is_cyclic = flag & CU_NURB_CYCLIC; - const bool is_bezier = flag & CU_NURB_BEZIER && !(flag & CU_NURB_ENDPOINT); - const bool is_end_point = flag & CU_NURB_ENDPOINT && !(flag & CU_NURB_BEZIER); + const bool is_bezier = flag & CU_NURB_BEZIER; + const bool is_end_point = flag & CU_NURB_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); + 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); @@ -1171,11 +1172,17 @@ static void calcknots(float *knots, const int pnts, const short order, const sho int r = head; float current = 0.0f; - for (const int i : IndexRange(knot_count - 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, knot_count - offset - tail)) { knots[i] = current; r--; if (r == 0) { - current += 1.0; + current += 1.0f; r = repeat_inner; } } @@ -4693,59 +4700,56 @@ void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, const float *key) } } -bool BKE_nurb_check_valid_u(const Nurb *nu) +bool BKE_nurb_valid_message(const int pnts, + const short order, + const short flag, + const short type, + const bool is_surf, + const char *dir, + char *message_dst, + const size_t maxncpy) { - if (nu->pntsu <= 1) { - return false; - } - if (nu->type != CU_NURBS) { - return true; /* not a nurb, lets assume its valid */ - } + const char *msg_template = ""; + uint16_t points_needed = 0; - if (nu->pntsu < nu->orderu) { - return false; + if (pnts <= 1) { + msg_template = TIP_("At least two points required."); } - if (((nu->flagu & CU_NURB_CYCLIC) == 0) && (nu->flagu & CU_NURB_BEZIER)) { - /* Bezier U Endpoints */ - if (nu->orderu == 4) { - if (nu->pntsu < 5) { - return false; /* bezier with 4 orderu needs 5 points */ - } + else if (type == CU_NURBS) { + if (pnts < order) { + msg_template = TIP_("Must have more control points than Order"); } - else { - if (nu->orderu != 3) { - return false; /* order must be 3 or 4 */ + else if (flag & CU_NURB_BEZIER) { + if (flag & CU_NURB_CYCLIC) { + const uint16_t remainder = pnts % (order - 1); + points_needed = remainder > 0 ? order - 1 - remainder : 0; + } + else if (((flag & CU_NURB_ENDPOINT) == 0) && pnts <= order) { + points_needed = order + 1 - pnts; + } + if (points_needed) { + msg_template = is_surf ? TIP_("%d more %s row(s) needed for Bezier") : + TIP_("%d more point(s) needed for Bezier"); } } } - return true; + + if (message_dst) { + BLI_snprintf(message_dst, maxncpy, msg_template, points_needed, dir); + } + return msg_template[0]; } -bool BKE_nurb_check_valid_v(const Nurb *nu) + +bool BKE_nurb_check_valid_u(const Nurb *nu) { - if (nu->pntsv <= 1) { - return false; - } - if (nu->type != CU_NURBS) { - return true; /* not a nurb, lets assume its valid */ - } + return !BKE_nurb_valid_message( + nu->pntsu, nu->orderu, nu->flagu, nu->type, nu->pntsv > 1, "U", nullptr, 0); +} - if (nu->pntsv < nu->orderv) { - return false; - } - if (((nu->flagv & CU_NURB_CYCLIC) == 0) && (nu->flagv & CU_NURB_BEZIER)) { - /* Bezier V Endpoints */ - if (nu->orderv == 4) { - if (nu->pntsv < 5) { - return false; /* bezier with 4 orderu needs 5 points */ - } - } - else { - if (nu->orderv != 3) { - return false; /* order must be 3 or 4 */ - } - } - } - return true; +bool BKE_nurb_check_valid_v(const Nurb *nu) +{ + return !BKE_nurb_valid_message( + nu->pntsv, nu->orderv, nu->flagv, nu->type, nu->pntsv > 1, "V", nullptr, 0); } bool BKE_nurb_check_valid_uv(const Nurb *nu) @@ -4767,10 +4771,6 @@ bool BKE_nurb_order_clamp_u(struct Nurb *nu) nu->orderu = max_ii(2, nu->pntsu); changed = true; } - if (((nu->flagu & CU_NURB_CYCLIC) == 0) && (nu->flagu & CU_NURB_BEZIER)) { - CLAMP(nu->orderu, 3, 4); - changed = true; - } return changed; } @@ -4781,10 +4781,6 @@ bool BKE_nurb_order_clamp_v(struct Nurb *nu) nu->orderv = max_ii(2, nu->pntsv); changed = true; } - if (((nu->flagv & CU_NURB_CYCLIC) == 0) && (nu->flagv & CU_NURB_BEZIER)) { - CLAMP(nu->orderv, 3, 4); - changed = true; - } return changed; } diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc index 1ffbed39216..59c2155255b 100644 --- a/source/blender/blenkernel/intern/curve_eval.cc +++ b/source/blender/blenkernel/intern/curve_eval.cc @@ -210,6 +210,8 @@ static NURBSpline::KnotsMode knots_mode_from_dna_nurb(const short flag) return NURBSpline::KnotsMode::EndPoint; case CU_NURB_BEZIER: return NURBSpline::KnotsMode::Bezier; + case CU_NURB_ENDPOINT | CU_NURB_BEZIER: + return NURBSpline::KnotsMode::EndPointBezier; default: return NURBSpline::KnotsMode::Normal; } diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc in @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
