Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-08-18 15:35:51 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-08-18 15:38:20 +0400
commit6c7467e0da9cf241b1eac7dfe91e6aefe1d985ce (patch)
tree29575be83368f2d641221d3bf3b3e93a17ae3865 /source
parent05cb63ecf75095444c8ce2bc11b3067bb207d8bf (diff)
Fix T41085: Blender crashes when using "spline" or "segments" for bevel curve factor.
Root of the issue goes to the fact that bevel list calculation might drop some points if they're at the same position. This made spline length calculation goes wrong. Now the length of the bevel segments is stored in the bevel list, so values are always reliable. Initial patch by Lukas Treyer with some tweaks from me.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_curve.h1
-rw-r--r--source/blender/blenkernel/intern/curve.c164
-rw-r--r--source/blender/blenkernel/intern/displist.c168
-rw-r--r--source/blender/blenkernel/intern/object.c6
-rw-r--r--source/blender/makesdna/DNA_curve_types.h4
5 files changed, 210 insertions, 133 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index c6aaeb8cc64..01770538390 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -111,6 +111,7 @@ struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu);
float *BKE_curve_make_orco(struct Scene *scene, struct Object *ob, int *r_numVerts);
float *BKE_curve_surf_make_orco(struct Object *ob);
+void BKE_curve_bevelList_free(struct ListBase *bev);
void BKE_curve_bevelList_make(struct Object *ob, struct ListBase *nurbs, bool for_render);
void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob, struct ListBase *disp,
const bool for_render, const bool use_render_resolution);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index a6f7bd442af..8d776c277fe 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2500,6 +2500,21 @@ static void bevlist_firstlast_direction_calc_from_bpoint(Nurb *nu, BevList *bl)
}
}
+void BKE_curve_bevelList_free(ListBase *bev)
+{
+ BevList *bl, *blnext;
+ for (bl = bev->first; bl != NULL; bl = blnext) {
+ blnext = bl->next;
+ if (bl->seglen != NULL) {
+ MEM_freeN(bl->seglen);
+ }
+ if (bl->segbevcount != NULL) {
+ MEM_freeN(bl->segbevcount);
+ }
+ MEM_freeN(bl);
+ }
+}
+
void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
{
/*
@@ -2508,21 +2523,29 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
* - separate in individual blocks with BoundBox
* - AutoHole detection
*/
- Curve *cu;
+
+ /* this function needs an object, because of tflag and upflag */
+ Curve *cu = ob->data;
Nurb *nu;
BezTriple *bezt, *prevbezt;
BPoint *bp;
BevList *bl, *blnew, *blnext;
BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0;
+ const float treshold = 0.00001f;
float min, inp;
+ float *seglen;
struct BevelSort *sortdata, *sd, *sd1;
- int a, b, nr, poly, resolu = 0, len = 0;
+ int a, b, nr, poly, resolu = 0, len = 0, segcount;
+ int *segbevcount;
bool do_tilt, do_radius, do_weight;
bool is_editmode = false;
ListBase *bev;
- /* this function needs an object, because of tflag and upflag */
- cu = ob->data;
+ /* segbevcount alsp requires seglen. */
+ const bool need_seglen =
+ ELEM(cu->bevfac1_mapping,CU_BEVFAC_MAP_SEGMENT, CU_BEVFAC_MAP_SPLINE) ||
+ ELEM(cu->bevfac2_mapping,CU_BEVFAC_MAP_SEGMENT, CU_BEVFAC_MAP_SPLINE);
+
bev = &ob->curve_cache->bev;
@@ -2531,7 +2554,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
/* STEP 1: MAKE POLYS */
- BLI_freelistN(&(ob->curve_cache->bev));
+ BKE_curve_bevelList_free(&ob->curve_cache->bev);
nu = nurbs->first;
if (cu->editnurb && ob->type != OB_FONT) {
is_editmode = 1;
@@ -2561,9 +2584,15 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
else
resolu = nu->resolu;
+ segcount = SEGMENTSU(nu);
+
if (nu->type == CU_POLY) {
len = nu->pntsu;
bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelList2");
+ if (need_seglen) {
+ bl->seglen = MEM_mallocN(segcount * sizeof(float), "makeBevelList2_seglen");
+ bl->segbevcount = MEM_mallocN(segcount * sizeof(int), "makeBevelList2_segbevcount");
+ }
BLI_addtail(bev, bl);
bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
@@ -2571,7 +2600,11 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
bl->dupe_nr = 0;
bl->charidx = nu->charidx;
bevp = bl->bevpoints;
+ bevp->offset = 0;
bp = nu->bp;
+ seglen = bl->seglen;
+ segbevcount = bl->segbevcount;
+ BLI_assert(segcount >= len);
while (len--) {
copy_v3_v3(bevp->vec, bp->vec);
@@ -2579,23 +2612,53 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
bevp->radius = bp->radius;
bevp->weight = bp->weight;
bevp->split_tag = true;
- bevp++;
bp++;
+ if (seglen != NULL) {
+ *seglen = len_v3v3(bevp->vec, bp->vec);
+ bevp++;
+ bevp->offset = *seglen;
+ if (*seglen > treshold) *segbevcount = 1;
+ else *segbevcount = 0;
+ seglen++;
+ segbevcount++;
+ }
+ else {
+ bevp++;
+ }
}
if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
+ if (seglen != NULL) {
+ *seglen = len_v3v3(bevp->vec, nu->bp->vec);
+ bl->bevpoints->offset = *seglen;
+ *segbevcount = 1;
+ }
}
}
else if (nu->type == CU_BEZIER) {
/* in case last point is not cyclic */
- len = resolu * (nu->pntsu + (nu->flagu & CU_NURB_CYCLIC) - 1) + 1;
+ len = segcount * resolu + 1;
+
bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelBPoints");
+ if (need_seglen) {
+ bl->seglen = MEM_mallocN(segcount * sizeof(float), "makeBevelBPoints_seglen");
+ bl->segbevcount = MEM_mallocN(segcount * sizeof(int), "makeBevelBPoints_segbevcount");
+ }
BLI_addtail(bev, bl);
bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
bl->charidx = nu->charidx;
+
bevp = bl->bevpoints;
+ seglen = bl->seglen;
+ segbevcount = bl->segbevcount;
+
+ bevp->offset = 0;
+ if (seglen != NULL) {
+ *seglen = 0;
+ *segbevcount = 0;
+ }
a = nu->pntsu - 1;
bezt = nu->bezt;
@@ -2611,6 +2674,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
sub_v3_v3v3(bevp->dir, prevbezt->vec[2], prevbezt->vec[1]);
normalize_v3(bevp->dir);
+ BLI_assert(segcount >= a);
+
while (a--) {
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
@@ -2623,6 +2688,14 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
bevp++;
bl->nr++;
bl->dupe_nr = 1;
+ if (seglen != NULL) {
+ *seglen = len_v3v3(prevbezt->vec[1], bezt->vec[1]);
+ bevp->offset = *seglen;
+ seglen++;
+ /* match segbevcount to the cleaned up bevel lists (see STEP 2) */
+ if (bevp->offset > treshold) *segbevcount = 1;
+ segbevcount++;
+ }
}
else {
/* always do all three, to prevent data hanging around */
@@ -2660,8 +2733,28 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
else if (prevbezt->h2 == 0 || prevbezt->h2 == HD_VECT)
bevp->split_tag = true;
}
+
+ /* seglen */
+ if (seglen != NULL) {
+ *seglen = 0;
+ *segbevcount = 0;
+ for (j = 0; j < resolu; j++) {
+ bevp0 = bevp;
+ bevp++;
+ bevp->offset = len_v3v3(bevp0->vec, bevp->vec);
+ /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */
+ if (bevp->offset > treshold) {
+ *seglen += bevp->offset;
+ *segbevcount += 1;
+ }
+ }
+ seglen++;
+ segbevcount++;
+ }
+ else {
+ bevp += resolu;
+ }
bl->nr += resolu;
- bevp += resolu;
}
prevbezt = bezt;
bezt++;
@@ -2681,15 +2774,22 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
}
else if (nu->type == CU_NURBS) {
if (nu->pntsv == 1) {
- len = (resolu * SEGMENTSU(nu));
+ len = (resolu * segcount);
bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelList3");
+ if (need_seglen) {
+ bl->seglen = MEM_mallocN(segcount * sizeof(float), "makeBevelList3_seglen");
+ bl->segbevcount = MEM_mallocN(segcount * sizeof(int), "makeBevelList3_segbevcount");
+ }
BLI_addtail(bev, bl);
bl->nr = len;
bl->dupe_nr = 0;
bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
bl->charidx = nu->charidx;
+
bevp = bl->bevpoints;
+ seglen = bl->seglen;
+ segbevcount = bl->segbevcount;
BKE_nurb_makeCurve(nu, &bevp->vec[0],
do_tilt ? &bevp->alfa : NULL,
@@ -2697,6 +2797,31 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
do_weight ? &bevp->weight : NULL,
resolu, sizeof(BevPoint));
+ /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */
+ if (seglen != NULL) {
+ nr = segcount;
+ bevp0 = bevp;
+ bevp++;
+ while (nr) {
+ int j;
+ *seglen = 0;
+ *segbevcount = 0;
+ /* We keep last bevel segment zero-length. */
+ for (j = 0; j < ((nr == 1) ? (resolu - 1) : resolu); j++) {
+ bevp->offset = len_v3v3(bevp0->vec, bevp->vec);
+ if (bevp->offset > treshold) {
+ *seglen += bevp->offset;
+ *segbevcount += 1;
+ }
+ bevp0 = bevp;
+ bevp++;
+ }
+ seglen++;
+ segbevcount++;
+ nr--;
+ }
+ }
+
if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
}
@@ -2717,15 +2842,24 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
}
else {
bevp0 = bl->bevpoints;
+ bevp0->offset = 0;
bevp1 = bevp0 + 1;
}
nr--;
while (nr--) {
- if (fabsf(bevp0->vec[0] - bevp1->vec[0]) < 0.00001f) {
- if (fabsf(bevp0->vec[1] - bevp1->vec[1]) < 0.00001f) {
- if (fabsf(bevp0->vec[2] - bevp1->vec[2]) < 0.00001f) {
- bevp0->dupe_tag = true;
- bl->dupe_nr++;
+ if (seglen != NULL) {
+ if (fabsf(bevp1->offset) < treshold) {
+ bevp0->dupe_tag = true;
+ bl->dupe_nr++;
+ }
+ }
+ else {
+ if (fabsf(bevp0->vec[0] - bevp1->vec[0]) < 0.00001f) {
+ if (fabsf(bevp0->vec[1] - bevp1->vec[1]) < 0.00001f) {
+ if (fabsf(bevp0->vec[2] - bevp1->vec[2]) < 0.00001f) {
+ bevp0->dupe_tag = true;
+ bl->dupe_nr++;
+ }
}
}
}
@@ -2742,6 +2876,8 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
nr = bl->nr - bl->dupe_nr + 1; /* +1 because vectorbezier sets flag too */
blnew = MEM_mallocN(sizeof(BevList) + nr * sizeof(BevPoint), "makeBevelList4");
memcpy(blnew, bl, sizeof(BevList));
+ blnew->segbevcount = bl->segbevcount;
+ blnew->seglen = bl->seglen;
blnew->nr = 0;
BLI_remlink(bev, bl);
BLI_insertlinkbefore(bev, blnext, blnew); /* to make sure bevlijst is tuned with nurblist */
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 43c13f1c896..e01ff24dad3 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1356,31 +1356,57 @@ static void fillBevelCap(Nurb *nu, DispList *dlb, float *prev_fp, ListBase *disp
BLI_addtail(dispbase, dl);
}
+static void calc_bevfac_segment_mapping(BevList *bl, float bevfac, float spline_length, int *r_bev, float *r_blend)
+{
+ float normlen, normsum = 0.0f;
+ float *seglen = bl->seglen;
+ int *segbevcount = bl->segbevcount;
+ int bevcount = 0, nr = bl->nr;
+
+ float bev_fl = bevfac * (bl->nr - 1);
+ *r_bev = (int)bev_fl;
+
+ while (bevcount < nr - 1) {
+ normlen = *seglen / spline_length;
+ if (normsum + normlen > bevfac){
+ bev_fl = bevcount + (bevfac - normsum) / normlen * *segbevcount;
+ *r_bev = (int) bev_fl;
+ *r_blend = bev_fl - *r_bev;
+ break;
+ }
+ normsum += normlen;
+ bevcount += *segbevcount;
+ segbevcount++;
+ seglen++;
+ }
+}
-static void calc_bevfac_spline_mapping(BevList *bl, float bevfac, float spline_length, const float *bevp_array,
+static void calc_bevfac_spline_mapping(BevList *bl, float bevfac,
+ float spline_length,
int *r_bev, float *r_blend)
{
const float len_target = bevfac * spline_length;
- float len = 0.0f;
- float len_step = 0.0f;
- int i;
- for (i = 0; i < bl->nr - 1; i++) {
- float len_next;
- len_step = bevp_array[i];
- len_next = len + len_step;
+ BevPoint *bevp = bl->bevpoints;
+ float len_next = 0.0f, len = 0.0f;
+ int i = 0, nr = bl->nr;
+
+ while (nr--) {
+ bevp++;
+ len_next = len + bevp->offset;
if (len_next > len_target) {
break;
}
len = len_next;
+ i++;
}
*r_bev = i;
- *r_blend = (len_target - len) / len_step;
+ *r_blend = (len_target - len) / bevp->offset;
}
-static void calc_bevfac_mapping_default(
- BevList *bl,
- int *r_start, float *r_firstblend, int *r_steps, float *r_lastblend)
+static void calc_bevfac_mapping_default(BevList *bl,
+ int *r_start, float *r_firstblend,
+ int *r_steps, float *r_lastblend)
{
*r_start = 0;
*r_steps = bl->nr;
@@ -1388,19 +1414,11 @@ static void calc_bevfac_mapping_default(
*r_lastblend = 1.0f;
}
-static void calc_bevfac_mapping(
- Curve *cu, BevList *bl, Nurb *nu, const bool use_render_resolution,
+static void calc_bevfac_mapping(Curve *cu, BevList *bl, Nurb *nu,
int *r_start, float *r_firstblend, int *r_steps, float *r_lastblend)
{
- const int resolu = (nu->type == CU_POLY) ?
- 1 : (use_render_resolution && (cu->resolu_ren != 0)) ?
- cu->resolu_ren : cu->resolu;
- const int segcount = ((nu->type == CU_POLY) ? bl->nr : nu->pntsu) - 1;
-
- float l, startf, endf, tmpf, total_length = 0.0f;
- float *bevp_array = NULL;
- float *segments = NULL;
- int end = 0, i, j;
+ float tmpf, total_length = 0.0f;
+ int end = 0, i;
if ((BKE_nurb_check_valid_u(nu) == false) ||
/* not essential, but skips unnecessary calculation */
@@ -1411,57 +1429,12 @@ static void calc_bevfac_mapping(
return;
}
- if ((cu->bevfac1_mapping != CU_BEVFAC_MAP_RESOLU) ||
- (cu->bevfac2_mapping != CU_BEVFAC_MAP_RESOLU))
+ if (ELEM(cu->bevfac1_mapping,
+ CU_BEVFAC_MAP_SEGMENT,
+ CU_BEVFAC_MAP_SPLINE))
{
- BezTriple *bezt, *bezt_prev;
- BevPoint *bevp, *bevp_prev;
- int bevp_i;
-
- bevp_array = MEM_mallocN(sizeof(*bevp_array) * (bl->nr - 1), "bevp_dists");
- segments = MEM_callocN(sizeof(*segments) * segcount, "bevp_segmentlengths");
- bevp_prev = bl->bevpoints;
- bevp = bevp_prev + 1;
-
- if (nu->type == CU_BEZIER) {
- bezt_prev = nu->bezt;
- bezt = bezt_prev + 1;
- for (i = 0, bevp_i = 0; i < segcount; i++, bezt_prev++, bezt++) {
- float seglen = 0.0f;
- if (bezt_prev->h2 == HD_VECT && bezt->h1 == HD_VECT) {
- seglen = len_v3v3(bevp->vec, bevp_prev->vec);
- BLI_assert(bevp_i < bl->nr - 1);
- bevp_array[bevp_i++] = seglen;
-
- bevp_prev = bevp++;
- }
- else {
- for (j = 0; j < resolu; j++, bevp_prev = bevp++) {
- l = len_v3v3(bevp->vec, bevp_prev->vec);
- seglen += l;
- BLI_assert(bevp_i < bl->nr - 1);
- bevp_array[bevp_i++] = l;
- }
- }
- BLI_assert(i < segcount);
- segments[i] = seglen;
- total_length += seglen;
- seglen = 0.0f;
- }
- }
- else {
- float seglen = 0.0f;
- for (i = 1, j = 0; i < bl->nr; i++, bevp_prev = bevp++) {
- BLI_assert(i - 1 < bl->nr);
- bevp_array[i - 1] = len_v3v3(bevp->vec, bevp_prev->vec);
- total_length += bevp_array[i - 1];
- seglen += bevp_array[i - 1];
- if ((i % resolu) == 0 || (bl->nr - 1) == i) {
- BLI_assert(j < segcount);
- segments[j++] = seglen;
- seglen = 0.0f;
- }
- }
+ for (i = 0; i < SEGMENTSU(nu); i++) {
+ total_length += bl->seglen[i];
}
}
@@ -1470,31 +1443,18 @@ static void calc_bevfac_mapping(
{
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:
{
- float sum = 0.0f;
- 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 * resolu + (cu->bevfac1 - sum) / l * resolu;
- *r_start = (int) startf;
- *r_firstblend = 1.0f - (startf - *r_start);
- break;
- }
- sum += l;
- }
+ calc_bevfac_segment_mapping(bl, cu->bevfac1, total_length, r_start, r_firstblend);
+ *r_firstblend = 1.0f - *r_firstblend;
break;
}
case CU_BEVFAC_MAP_SPLINE:
{
- calc_bevfac_spline_mapping(bl, cu->bevfac1, total_length, bevp_array, r_start, r_firstblend);
+ calc_bevfac_spline_mapping(bl, cu->bevfac1, total_length, r_start, r_firstblend);
*r_firstblend = 1.0f - *r_firstblend;
break;
}
@@ -1512,27 +1472,13 @@ static void calc_bevfac_mapping(
}
case CU_BEVFAC_MAP_SEGMENT:
{
- float sum = 0.0f;
- const float end_fl = cu->bevfac2 * (bl->nr - 1);
- end = (int)end_fl;
-
+ calc_bevfac_segment_mapping(bl, cu->bevfac2, total_length, &end, r_lastblend);
*r_steps = end - *r_start + 2;
- for (i = 0; i < segcount; i++) {
- l = segments[i] / total_length;
- if (sum + l > cu->bevfac2) {
- endf = i * resolu + (cu->bevfac2 - sum) / l * 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);
+ calc_bevfac_spline_mapping(bl, cu->bevfac2, total_length, &end, r_lastblend);
*r_steps = end - *r_start + 2;
break;
}
@@ -1550,13 +1496,6 @@ static void calc_bevfac_mapping(
*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,
@@ -1575,7 +1514,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
ListBase dlbev;
ListBase nubase = {NULL, NULL};
- BLI_freelistN(&(ob->curve_cache->bev));
+ BKE_curve_bevelList_free(&ob->curve_cache->bev);
/* We only re-evlauate path if evaluation is not happening for orco.
* If the calculation happens for orco, we should never free data which
@@ -1667,8 +1606,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
continue;
}
- calc_bevfac_mapping(cu, bl, nu, use_render_resolution,
- &start, &firstblend, &steps, &lastblend);
+ calc_bevfac_mapping(cu, bl, nu, &start, &firstblend, &steps, &lastblend);
}
for (dlb = dlbev.first; dlb; dlb = dlb->next) {
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 6f1ffcdd5a9..ef4df8bd719 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -180,7 +180,7 @@ void BKE_object_free_curve_cache(Object *ob)
{
if (ob->curve_cache) {
BKE_displist_free(&ob->curve_cache->disp);
- BLI_freelistN(&ob->curve_cache->bev);
+ BKE_curve_bevelList_free(&ob->curve_cache->bev);
if (ob->curve_cache->path) {
free_path(ob->curve_cache->path);
}
@@ -322,7 +322,7 @@ void BKE_object_free_derived_caches(Object *ob)
if (ob->curve_cache) {
BKE_displist_free(&ob->curve_cache->disp);
- BLI_freelistN(&ob->curve_cache->bev);
+ BKE_curve_bevelList_free(&ob->curve_cache->bev);
if (ob->curve_cache->path) {
free_path(ob->curve_cache->path);
ob->curve_cache->path = NULL;
@@ -408,7 +408,7 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
/* Free runtime curves data. */
if (ob->curve_cache) {
- BLI_freelistN(&ob->curve_cache->bev);
+ BKE_curve_bevelList_free(&ob->curve_cache->bev);
if (ob->curve_cache->path)
free_path(ob->curve_cache->path);
MEM_freeN(ob->curve_cache);
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 16d85ab4d3b..87496fb491f 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -72,7 +72,7 @@ typedef struct Path {
#
#
typedef struct BevPoint {
- float vec[3], alfa, radius, weight;
+ float vec[3], alfa, radius, weight, offset;
float sina, cosa; /* 2D Only */
float dir[3], tan[3], quat[4]; /* 3D Only */
short split_tag, dupe_tag;
@@ -86,6 +86,8 @@ typedef struct BevList {
int nr, dupe_nr;
int poly, hole;
int charidx;
+ int *segbevcount;
+ float *seglen;
/* over-alloc */
BevPoint bevpoints[0];