Bevel Factor Mapping
Bevel Factor Mapping allows to control the relation between bevel factors (number between 0 and 1) and the rendered start and end point of a beveled spline. There are three options: "Resolution", "Segments", "Spline". "Resolution" option maps bevel factors as it was done < 2.71, "Spline" and "Segments" are new. * "Resolution“: Map the bevel factor to the number of subdivisions of a spline (U resolution). * "Segments“: Map the bevel factor to the length of a segment and to the number of subdivisions of a segment. * "Spline": Map the bevel factor to the length of a spline. Reviewers: yakca, sergey, campbellbarton CC: sanne Differential Revision: https://developer.blender.org/D294
This commit is contained in:
parent
3977b7612f
commit
97cb76a45d
|
@ -183,13 +183,22 @@ class DATA_PT_geometry_curve(CurveButtonsPanelCurve, Panel):
|
|||
col.prop(curve, "bevel_object", text="")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(curve, "bevel_factor_start")
|
||||
col.prop(curve, "bevel_factor_end")
|
||||
|
||||
row = col.row()
|
||||
row.active = (curve.bevel_object is not None)
|
||||
row.prop(curve, "use_fill_caps")
|
||||
row.label(text="Bevel Factor:")
|
||||
|
||||
col = layout.column()
|
||||
col.active = (curve.bevel_depth > 0 or curve.bevel_object is not None)
|
||||
row = col.row(align=True)
|
||||
row.prop(curve, "bevel_factor_mapping_start", text="")
|
||||
row.prop(curve, "bevel_factor_start", text="Start")
|
||||
row = col.row(align=True)
|
||||
row.prop(curve, "bevel_factor_mapping_end", text="")
|
||||
row.prop(curve, "bevel_factor_end", text="End")
|
||||
|
||||
row = layout.row()
|
||||
row.active = curve.bevel_object is not None
|
||||
row.prop(curve, "use_map_taper")
|
||||
row.prop(curve, "use_fill_caps")
|
||||
|
||||
|
||||
class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel):
|
||||
|
|
|
@ -182,6 +182,8 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type)
|
|||
cu->type = type;
|
||||
cu->bevfac1 = 0.0f;
|
||||
cu->bevfac2 = 1.0f;
|
||||
cu->bevfac1_mapping = CU_BEVFAC_MAP_RESOLU;
|
||||
cu->bevfac2_mapping = CU_BEVFAC_MAP_RESOLU;
|
||||
|
||||
cu->bb = BKE_boundbox_alloc_unit();
|
||||
|
||||
|
|
|
@ -1364,6 +1364,143 @@ static void fillBevelCap(Nurb *nu, DispList *dlb, float *prev_fp, ListBase *disp
|
|||
BLI_addtail(dispbase, dl);
|
||||
}
|
||||
|
||||
|
||||
static void calc_bevfac_spline_mapping(BevList *bl, float bevfac, float spline_length, const float *bevp_array,
|
||||
int *r_bev, float *r_blend)
|
||||
{
|
||||
float len = 0.0f;
|
||||
int i;
|
||||
for (i = 0; i < bl->nr; i++) {
|
||||
*r_bev = i;
|
||||
*r_blend = (bevfac * spline_length - len) / bevp_array[i];
|
||||
if (len + bevp_array[i] > bevfac * spline_length) {
|
||||
break;
|
||||
}
|
||||
len += bevp_array[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void calc_bevfac_mapping(Curve *cu, BevList *bl, int *r_start, float *r_firstblend, int *r_steps, float *r_lastblend)
|
||||
{
|
||||
BevPoint *bevp, *bevl;
|
||||
float l, startf, endf, tmpf = 0.0, sum = 0.0, total_length = 0.0f;
|
||||
float *bevp_array = NULL;
|
||||
float *segments = NULL;
|
||||
int end = 0, i, j, segcount = (int)(bl->nr / cu->resolu);
|
||||
|
||||
if ((cu->bevfac1_mapping != CU_BEVFAC_MAP_RESOLU) ||
|
||||
(cu->bevfac2_mapping != CU_BEVFAC_MAP_RESOLU))
|
||||
{
|
||||
bevp_array = MEM_mallocN(sizeof(bevp_array) * (bl->nr - 1), "bevp_dists");
|
||||
segments = MEM_callocN(sizeof(segments) * segcount, "bevp_segmentlengths");
|
||||
bevp = (BevPoint *)(bl + 1);
|
||||
bevp++;
|
||||
for (i = 1, j = 0; i < bl->nr; bevp++, i++) {
|
||||
sum = 0.0f;
|
||||
bevl = bevp - 1;
|
||||
bevp_array[i - 1] = len_v3v3(bevp->vec, bevl->vec);
|
||||
total_length += bevp_array[i - 1];
|
||||
tmpf += bevp_array[i - 1];
|
||||
if ((i % cu->resolu) == 0 || (bl->nr - 1) == i) {
|
||||
segments[j++] = tmpf;
|
||||
tmpf = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (cu->bevfac1_mapping) {
|
||||
case CU_BEVFAC_MAP_RESOLU:
|
||||
{
|
||||
const float start_fl = cu->bevfac1 * (bl->nr - 1);
|
||||
*r_start = (int)start_fl;
|
||||
|
||||
*r_firstblend = 1.0f - (start_fl - (*r_start));
|
||||
break;
|
||||
}
|
||||
case CU_BEVFAC_MAP_SEGMENT:
|
||||
{
|
||||
const float start_fl = cu->bevfac1 * (bl->nr - 1);
|
||||
*r_start = (int)start_fl;
|
||||
|
||||
for (i = 0; i < segcount; i++) {
|
||||
l = segments[i] / total_length;
|
||||
if (sum + l > cu->bevfac1) {
|
||||
startf = i * cu->resolu + (cu->bevfac1 - sum) / l * cu->resolu;
|
||||
*r_start = (int) startf;
|
||||
*r_firstblend = 1.0f - (startf - *r_start);
|
||||
break;
|
||||
}
|
||||
sum += l;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CU_BEVFAC_MAP_SPLINE:
|
||||
{
|
||||
calc_bevfac_spline_mapping(bl, cu->bevfac1, total_length, bevp_array, r_start, r_firstblend);
|
||||
*r_firstblend = 1.0f - *r_firstblend;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sum = 0.0f;
|
||||
switch (cu->bevfac2_mapping) {
|
||||
case CU_BEVFAC_MAP_RESOLU:
|
||||
{
|
||||
const float end_fl = cu->bevfac2 * (bl->nr - 1);
|
||||
end = (int)end_fl;
|
||||
|
||||
*r_steps = 2 + end - *r_start;
|
||||
*r_lastblend = end_fl - end;
|
||||
break;
|
||||
}
|
||||
case CU_BEVFAC_MAP_SEGMENT:
|
||||
{
|
||||
const float end_fl = cu->bevfac2 * (bl->nr - 1);
|
||||
end = (int)end_fl;
|
||||
|
||||
*r_steps = end - *r_start + 2;
|
||||
for (i = 0; i < segcount; i++) {
|
||||
l = segments[i] / total_length;
|
||||
if (sum + l > cu->bevfac2) {
|
||||
endf = i * cu->resolu + (cu->bevfac2 - sum) / l * cu->resolu;
|
||||
end = (int)endf;
|
||||
*r_lastblend = (endf - end);
|
||||
*r_steps = end - *r_start + 2;
|
||||
break;
|
||||
}
|
||||
sum += l;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CU_BEVFAC_MAP_SPLINE:
|
||||
{
|
||||
calc_bevfac_spline_mapping(bl, cu->bevfac2, total_length, bevp_array, &end, r_lastblend);
|
||||
*r_steps = end - *r_start + 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (end < *r_start) {
|
||||
SWAP(int, *r_start, end);
|
||||
tmpf = *r_lastblend;
|
||||
*r_lastblend = 1.0f - *r_firstblend;
|
||||
*r_firstblend = 1.0f - tmpf;
|
||||
*r_steps = end - *r_start + 2;
|
||||
}
|
||||
|
||||
if (*r_start + *r_steps > bl->nr) {
|
||||
*r_steps = bl->nr - *r_start;
|
||||
*r_lastblend = 1.0f;
|
||||
}
|
||||
|
||||
if (bevp_array) {
|
||||
MEM_freeN(bevp_array);
|
||||
}
|
||||
if (segments) {
|
||||
MEM_freeN(segments);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
|
||||
DerivedMesh **r_dm_final,
|
||||
const bool for_render, const bool for_orco, const bool use_render_resolution)
|
||||
|
@ -1460,25 +1597,12 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
|
|||
ListBase top_capbase = {NULL, NULL};
|
||||
float bottom_no[3] = {0.0f};
|
||||
float top_no[3] = {0.0f};
|
||||
float firstblend = 0.0f, lastblend = 0.0f;
|
||||
int i, start, steps;
|
||||
|
||||
calc_bevfac_mapping(cu, bl, &start, &firstblend, &steps, &lastblend);
|
||||
|
||||
for (dlb = dlbev.first; dlb; dlb = dlb->next) {
|
||||
const float bevfac1 = min_ff(cu->bevfac1, cu->bevfac2);
|
||||
const float bevfac2 = max_ff(cu->bevfac1, cu->bevfac2);
|
||||
float firstblend = 0.0f, lastblend = 0.0f;
|
||||
int i, start, steps;
|
||||
|
||||
if (bevfac2 - bevfac1 == 0.0f)
|
||||
continue;
|
||||
|
||||
start = (int)(bevfac1 * (bl->nr - 1));
|
||||
steps = 2 + (int)((bevfac2) * (bl->nr - 1)) - start;
|
||||
firstblend = 1.0f - (bevfac1 * (bl->nr - 1) - (int)(bevfac1 * (bl->nr - 1)));
|
||||
lastblend = bevfac2 * (bl->nr - 1) - (int)(bevfac2 * (bl->nr - 1));
|
||||
|
||||
if (start + steps > bl->nr) {
|
||||
steps = bl->nr - start;
|
||||
lastblend = 1.0f;
|
||||
}
|
||||
|
||||
/* for each part of the bevel use a separate displblock */
|
||||
dl = MEM_callocN(sizeof(DispList), "makeDispListbev1");
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
/* allow readfile to use deprecated functionality */
|
||||
#define DNA_DEPRECATED_ALLOW
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_sdna_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
|
|
@ -257,8 +257,10 @@ typedef struct Curve {
|
|||
|
||||
float ctime; /* current evaltime - for use by Objects parented to curves */
|
||||
float bevfac1, bevfac2;
|
||||
char bevfac1_mapping, bevfac2_mapping;
|
||||
|
||||
char pad2[2];
|
||||
|
||||
char pad2[4];
|
||||
} Curve;
|
||||
|
||||
/* **************** CURVE ********************* */
|
||||
|
@ -295,6 +297,13 @@ typedef struct Curve {
|
|||
#define CU_TWIST_MINIMUM 3
|
||||
#define CU_TWIST_TANGENT 4
|
||||
|
||||
/* bevel factor mapping */
|
||||
enum {
|
||||
CU_BEVFAC_MAP_RESOLU = 0,
|
||||
CU_BEVFAC_MAP_SEGMENT = 1,
|
||||
CU_BEVFAC_MAP_SPLINE = 2
|
||||
};
|
||||
|
||||
/* spacemode */
|
||||
#define CU_LEFT 0
|
||||
#define CU_MIDDLE 1
|
||||
|
|
|
@ -1326,7 +1326,14 @@ static void rna_def_curve(BlenderRNA *brna)
|
|||
"Allow editing on the Z axis of this curve, also allows tilt and curve radius to be used"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
static EnumPropertyItem bevfac_mapping_items[] = {
|
||||
{CU_BEVFAC_MAP_RESOLU, "RESOLUTION", 0, "Resolution", "Map the bevel factor to the number of subdivisions of a spline (U resolution)"},
|
||||
{CU_BEVFAC_MAP_SEGMENT, "SEGMENTS", 0, "Segments", "Map the bevel factor to the length of a segment and to the number of subdivisions of a segment"},
|
||||
{CU_BEVFAC_MAP_SPLINE, "SPLINE", 0, "Spline", "Map the bevel factor to the length of a spline"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "Curve", "ID");
|
||||
RNA_def_struct_ui_text(srna, "Curve", "Curve datablock storing curves, splines and NURBS");
|
||||
RNA_def_struct_ui_icon(srna, ICON_CURVE_DATA);
|
||||
|
@ -1469,6 +1476,18 @@ static void rna_def_curve(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Twist Method", "The type of tilt calculation for 3D Curves");
|
||||
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
|
||||
|
||||
prop = RNA_def_property(srna, "bevel_factor_mapping_start", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "bevfac1_mapping");
|
||||
RNA_def_property_enum_items(prop, bevfac_mapping_items);
|
||||
RNA_def_property_ui_text(prop, "Start Mapping Type", "Determines how the start bevel factor is mappend to a spline");
|
||||
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
|
||||
|
||||
prop = RNA_def_property(srna, "bevel_factor_mapping_end", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "bevfac2_mapping");
|
||||
RNA_def_property_enum_items(prop, bevfac_mapping_items);
|
||||
RNA_def_property_ui_text(prop, "End Mapping Type", "Determines how the end bevel factor is mappend to a spline");
|
||||
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
|
||||
|
||||
/* XXX - would be nice to have a better way to do this, only add for testing. */
|
||||
prop = RNA_def_property(srna, "twist_smooth", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "twist_smooth");
|
||||
|
|
Loading…
Reference in New Issue