diff options
author | Lukas Treyer <treyer@arch.ethz.ch> | 2014-03-28 14:41:56 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-03-28 14:44:33 +0400 |
commit | 97cb76a45d689a0d39e1d194f51119412e6c8e00 (patch) | |
tree | e84bbf4505589a6c03b7a9b698fe48fe4854e202 | |
parent | 3977b7612fa5d21d8e5b7af04da571149db7d2d9 (diff) |
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
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_curve.py | 19 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 158 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_curve_types.h | 11 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_curve.c | 21 |
6 files changed, 188 insertions, 24 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index 8a3e31d8308..acfc4d1e263 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -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): diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 864682c5607..44c9bc9ebbe 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -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(); diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 33cb2c0fb23..4b251396376 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -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"); diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 30d8bf429f0..8fadfa69fac 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -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" diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index ebba59ec785..0c9e9b01a76 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_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 diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index ee6d9df1726..31709f90249 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -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"); |