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
This commit is contained in:
parent
27fb63381e
commit
0602852860
Notes:
blender-bot
2023-02-14 03:34:17 +01:00
Referenced by commit18af9da572
, Fix: Versioning problem with cyclic bezier NURBS Referenced by commitdbd9472ef5
, Fix: Assert in set spline type node after recent commit Referenced by issue #101160, Regression: deleting a point in a (cyclic) nurbs curve permanently converts to poly, subdividing as well
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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_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)
|
||||
{
|
||||
const char *msg_template = "";
|
||||
uint16_t points_needed = 0;
|
||||
|
||||
if (pnts <= 1) {
|
||||
msg_template = TIP_("At least two points required.");
|
||||
}
|
||||
else if (type == CU_NURBS) {
|
||||
if (pnts < order) {
|
||||
msg_template = TIP_("Must have more control points than Order");
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (message_dst) {
|
||||
BLI_snprintf(message_dst, maxncpy, msg_template, points_needed, dir);
|
||||
}
|
||||
return msg_template[0];
|
||||
}
|
||||
|
||||
bool BKE_nurb_check_valid_u(const Nurb *nu)
|
||||
{
|
||||
if (nu->pntsu <= 1) {
|
||||
return false;
|
||||
}
|
||||
if (nu->type != CU_NURBS) {
|
||||
return true; /* not a nurb, lets assume its valid */
|
||||
}
|
||||
|
||||
if (nu->pntsu < nu->orderu) {
|
||||
return false;
|
||||
}
|
||||
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 (nu->orderu != 3) {
|
||||
return false; /* order must be 3 or 4 */
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return !BKE_nurb_valid_message(
|
||||
nu->pntsu, nu->orderu, nu->flagu, nu->type, nu->pntsv > 1, "U", nullptr, 0);
|
||||
}
|
||||
|
||||
bool BKE_nurb_check_valid_v(const Nurb *nu)
|
||||
{
|
||||
if (nu->pntsv <= 1) {
|
||||
return false;
|
||||
}
|
||||
if (nu->type != CU_NURBS) {
|
||||
return true; /* not a nurb, lets assume its valid */
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "BKE_armature.h"
|
||||
#include "BKE_asset.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_fcurve_driver.h"
|
||||
|
@ -2571,18 +2572,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
||||
* - "versioning_userdef.c", #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 302, 6)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
if (ts->uv_relax_method == 0) {
|
||||
|
@ -2600,5 +2590,51 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
tool_settings->snap_flag_node = tool_settings->snap_flag;
|
||||
tool_settings->snap_uv_flag |= tool_settings->snap_flag & SCE_SNAP;
|
||||
}
|
||||
|
||||
/* Alter NURBS knot mode flags to fit new modes. */
|
||||
LISTBASE_FOREACH (Curve *, curve, &bmain->curves) {
|
||||
LISTBASE_FOREACH (Nurb *, nurb, &curve->nurb) {
|
||||
/* Previously other flags were ignored if CU_NURB_CYCLIC is set. */
|
||||
if (nurb->flagu & CU_NURB_CYCLIC) {
|
||||
nurb->flagu = CU_NURB_CYCLIC;
|
||||
}
|
||||
/* CU_NURB_BEZIER and CU_NURB_ENDPOINT were ignored if combined. */
|
||||
else if (nurb->flagu & CU_NURB_BEZIER && nurb->flagu & CU_NURB_ENDPOINT) {
|
||||
nurb->flagu &= ~(CU_NURB_BEZIER | CU_NURB_ENDPOINT);
|
||||
BKE_nurb_knot_calc_u(nurb);
|
||||
}
|
||||
/* Bezier NURBS of order 3 were clamped to first control point. */
|
||||
else if (nurb->orderu == 3 && (nurb->flagu & CU_NURB_BEZIER)) {
|
||||
nurb->flagu |= CU_NURB_ENDPOINT;
|
||||
}
|
||||
|
||||
/* Previously other flags were ignored if CU_NURB_CYCLIC is set. */
|
||||
if (nurb->flagv & CU_NURB_CYCLIC) {
|
||||
nurb->flagv = CU_NURB_CYCLIC;
|
||||
}
|
||||
/* CU_NURB_BEZIER and CU_NURB_ENDPOINT were ignored if used together. */
|
||||
else if (nurb->flagv & CU_NURB_BEZIER && nurb->flagv & CU_NURB_ENDPOINT) {
|
||||
nurb->flagv &= ~(CU_NURB_BEZIER | CU_NURB_ENDPOINT);
|
||||
BKE_nurb_knot_calc_v(nurb);
|
||||
}
|
||||
/* Bezier NURBS of order 3 were clamped to first control point. */
|
||||
else if (nurb->orderv == 3 && (nurb->flagv & CU_NURB_BEZIER)) {
|
||||
nurb->flagv |= CU_NURB_ENDPOINT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
* \note Be sure to check when bumping the version:
|
||||
* - "versioning_userdef.c", #blo_do_versions_userdef
|
||||
* - "versioning_userdef.c", #do_versions_theme
|
||||
*
|
||||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4958,7 +4958,7 @@ bool ed_editnurb_spin(
|
|||
/* It is challenging to create a good approximation of a circle with uniform knots vector
|
||||
* (which is forced in Blender for cyclic NURBS curves). Here a NURBS circle is constructed
|
||||
* by connecting four Bezier arcs. */
|
||||
nu->flagv |= CU_NURB_CYCLIC | CU_NURB_BEZIER;
|
||||
nu->flagv |= CU_NURB_CYCLIC | CU_NURB_BEZIER | CU_NURB_ENDPOINT;
|
||||
BKE_nurb_knot_calc_v(nu);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ Nurb *ED_curve_add_nurbs_primitive(
|
|||
nu->pntsv = 1;
|
||||
nu->orderu = 3;
|
||||
nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * nu->pntsu, "addNurbprim6");
|
||||
nu->flagu = CU_NURB_CYCLIC | CU_NURB_BEZIER;
|
||||
nu->flagu = CU_NURB_CYCLIC | CU_NURB_BEZIER | CU_NURB_ENDPOINT;
|
||||
bp = nu->bp;
|
||||
|
||||
for (a = 0; a < 8; a++) {
|
||||
|
@ -407,7 +407,7 @@ Nurb *ED_curve_add_nurbs_primitive(
|
|||
mul_m4_v3(mat, bp->vec);
|
||||
bp++;
|
||||
}
|
||||
nu->flagu = CU_NURB_BEZIER;
|
||||
nu->flagu = CU_NURB_BEZIER | CU_NURB_ENDPOINT;
|
||||
BKE_nurb_knot_calc_u(nu);
|
||||
|
||||
BLI_addtail(editnurb, nu); /* temporal for spin */
|
||||
|
|
|
@ -562,6 +562,38 @@ static void rna_Curve_offset_set(PointerRNA *ptr, float value)
|
|||
cu->offset = 1.0f + value;
|
||||
}
|
||||
|
||||
static int rna_Nurb_valid_message_u_length(PointerRNA *ptr)
|
||||
{
|
||||
char buff[64];
|
||||
Nurb *nu = (Nurb *)ptr->data;
|
||||
BKE_nurb_valid_message(
|
||||
nu->pntsu, nu->orderu, nu->flagu, nu->type, nu->pntsv > 1, "U", buff, sizeof(buff));
|
||||
return strlen(buff);
|
||||
}
|
||||
|
||||
static void rna_Nurb_valid_message_u(PointerRNA *ptr, char *value)
|
||||
{
|
||||
Nurb *nu = (Nurb *)ptr->data;
|
||||
BKE_nurb_valid_message(
|
||||
nu->pntsu, nu->orderu, nu->flagu, nu->type, nu->pntsv > 1, "U", value, 64);
|
||||
}
|
||||
|
||||
static int rna_Nurb_valid_message_v_length(PointerRNA *ptr)
|
||||
{
|
||||
char buff[64];
|
||||
Nurb *nu = (Nurb *)ptr->data;
|
||||
BKE_nurb_valid_message(
|
||||
nu->pntsv, nu->orderv, nu->flagv, nu->type, nu->pntsv > 1, "V", buff, sizeof(buff));
|
||||
return strlen(buff);
|
||||
}
|
||||
|
||||
static void rna_Nurb_valid_message_v(PointerRNA *ptr, char *value)
|
||||
{
|
||||
Nurb *nu = (Nurb *)ptr->data;
|
||||
BKE_nurb_valid_message(
|
||||
nu->pntsv, nu->orderv, nu->flagv, nu->type, nu->pntsv > 1, "V", value, 64);
|
||||
}
|
||||
|
||||
static int rna_Curve_body_length(PointerRNA *ptr);
|
||||
static void rna_Curve_body_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
|
@ -1995,24 +2027,20 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Cyclic V", "Make this surface a closed loop in the V direction");
|
||||
RNA_def_property_update(prop, 0, "rna_Nurb_update_cyclic_v");
|
||||
|
||||
/* NOTE: endpoint and bezier flags should never be on at the same time! */
|
||||
prop = RNA_def_property(srna, "use_endpoint_u", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flagu", CU_NURB_ENDPOINT);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Endpoint U",
|
||||
"Make this nurbs curve or surface meet the endpoints in the U direction "
|
||||
"(Cyclic U must be disabled)");
|
||||
"Make this nurbs curve or surface meet the endpoints in the U direction");
|
||||
RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_u");
|
||||
|
||||
prop = RNA_def_property(srna, "use_endpoint_v", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flagv", CU_NURB_ENDPOINT);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Endpoint V",
|
||||
"Make this nurbs surface meet the endpoints in the V direction "
|
||||
"(Cyclic V must be disabled)");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Endpoint V", "Make this nurbs surface meet the endpoints in the V direction ");
|
||||
RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_v");
|
||||
|
||||
prop = RNA_def_property(srna, "use_bezier_u", PROP_BOOLEAN, PROP_NONE);
|
||||
|
@ -2021,19 +2049,28 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Bezier U",
|
||||
"Make this nurbs curve or surface act like a Bezier spline in the U direction "
|
||||
"(Order U must be 3 or 4, Cyclic U must be disabled)");
|
||||
"Make this nurbs curve or surface act like a Bezier spline in the U direction");
|
||||
RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_u");
|
||||
|
||||
prop = RNA_def_property(srna, "use_bezier_v", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flagv", CU_NURB_BEZIER);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Bezier V",
|
||||
"Make this nurbs surface act like a Bezier spline in the V direction "
|
||||
"(Order V must be 3 or 4, Cyclic V must be disabled)");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Bezier V", "Make this nurbs surface act like a Bezier spline in the V direction");
|
||||
RNA_def_property_update(prop, 0, "rna_Nurb_update_knot_v");
|
||||
|
||||
prop = RNA_def_property(srna, "valid_message_u", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_string_funcs(
|
||||
prop, "rna_Nurb_valid_message_u", "rna_Nurb_valid_message_u_length", NULL);
|
||||
RNA_def_property_ui_text(prop, "Valid U", "Validation message for NURBS definition in U");
|
||||
|
||||
prop = RNA_def_property(srna, "valid_message_v", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_string_funcs(
|
||||
prop, "rna_Nurb_valid_message_v", "rna_Nurb_valid_message_v_length", NULL);
|
||||
RNA_def_property_ui_text(prop, "Valid V", "Validation message for NURBS definition in V");
|
||||
|
||||
prop = RNA_def_property(srna, "use_smooth", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_SMOOTH);
|
||||
RNA_def_property_ui_text(prop, "Smooth", "Smooth the normals of the surface or beveled curve");
|
||||
|
|
|
@ -65,6 +65,7 @@ static void nurbs_to_bezier_assign(const Span<T> input,
|
|||
|
||||
switch (knotsMode) {
|
||||
case NURBSpline::KnotsMode::Bezier:
|
||||
case NURBSpline::KnotsMode::EndPointBezier:
|
||||
scale_input_assign<T>(input, 3, 1, r_output);
|
||||
break;
|
||||
case NURBSpline::KnotsMode::Normal:
|
||||
|
|
Loading…
Reference in New Issue