Cleanup: Return early in some curve functions

This commit uses continue in loops and returning early to reduce
indentation in long functions, only where this results in a significant
improvement. Also includes a few LISTBASE_FOREACH macros.
This commit is contained in:
Hans Goudey 2020-10-23 23:29:52 -05:00
parent f32ab724eb
commit 594f47ecd2
Notes: blender-bot 2023-02-14 06:42:54 +01:00
Referenced by issue #80736, Cycles CPU Preview Artifact
3 changed files with 741 additions and 744 deletions

View File

@ -461,15 +461,14 @@ short BKE_curve_type_get(const Curve *cu)
void BKE_curve_curve_dimension_update(Curve *cu)
{
ListBase *nurbs = BKE_curve_nurbs_get(cu);
Nurb *nu = nurbs->first;
if (cu->flag & CU_3D) {
for (; nu; nu = nu->next) {
LISTBASE_FOREACH (Nurb *, nu, nurbs) {
nu->flag &= ~CU_2D;
}
}
else {
for (; nu; nu = nu->next) {
LISTBASE_FOREACH (Nurb *, nu, nurbs) {
nu->flag |= CU_2D;
BKE_nurb_test_2d(nu);
@ -2673,14 +2672,6 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
continue;
}
/* check if we will calculate tilt data */
do_tilt = CU_DO_TILT(cu, nu);
/* Normal display uses the radius, better just to calculate them. */
do_radius = CU_DO_RADIUS(cu, nu);
do_weight = true;
/* check we are a single point? also check we are not a surface and that the orderu is sane,
* enforced in the UI but can go wrong possibly */
if (!BKE_nurb_check_valid_u(nu)) {
@ -2689,61 +2680,279 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
BLI_addtail(bev, bl);
bl->nr = 0;
bl->charidx = nu->charidx;
continue;
}
/* check if we will calculate tilt data */
do_tilt = CU_DO_TILT(cu, nu);
/* Normal display uses the radius, better just to calculate them. */
do_radius = CU_DO_RADIUS(cu, nu);
do_weight = true;
BevPoint *bevp;
if (for_render && cu->resolu_ren != 0) {
resolu = cu->resolu_ren;
}
else {
BevPoint *bevp;
resolu = nu->resolu;
}
if (for_render && cu->resolu_ren != 0) {
resolu = cu->resolu_ren;
segcount = SEGMENTSU(nu);
if (nu->type == CU_POLY) {
len = nu->pntsu;
BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList2");
bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints2");
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList2_seglen");
bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList2_segbevcount");
}
BLI_addtail(bev, bl);
bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
bl->nr = len;
bl->dupe_nr = 0;
bl->charidx = nu->charidx;
bevp = bl->bevpoints;
bevp->offset = 0;
bp = nu->bp;
seglen = bl->seglen;
segbevcount = bl->segbevcount;
while (len--) {
copy_v3_v3(bevp->vec, bp->vec);
bevp->tilt = bp->tilt;
bevp->radius = bp->radius;
bevp->weight = bp->weight;
bevp->split_tag = true;
bp++;
if (seglen != NULL && len != 0) {
*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);
}
}
else if (nu->type == CU_BEZIER) {
/* in case last point is not cyclic */
len = segcount * resolu + 1;
BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints");
bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelBPointsPoints");
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelBPoints_seglen");
bl->segbevcount = MEM_malloc_arrayN(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;
if (nu->flagu & CU_NURB_CYCLIC) {
a++;
prevbezt = nu->bezt + (nu->pntsu - 1);
}
else {
resolu = nu->resolu;
prevbezt = bezt;
bezt++;
}
segcount = SEGMENTSU(nu);
sub_v3_v3v3(bevp->dir, prevbezt->vec[2], prevbezt->vec[1]);
normalize_v3(bevp->dir);
if (nu->type == CU_POLY) {
len = nu->pntsu;
BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList2");
bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints2");
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList2_seglen");
bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList2_segbevcount");
}
BLI_addtail(bev, bl);
BLI_assert(segcount >= a);
bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1;
bl->nr = len;
bl->dupe_nr = 0;
bl->charidx = nu->charidx;
bevp = bl->bevpoints;
bevp->offset = 0;
bp = nu->bp;
seglen = bl->seglen;
segbevcount = bl->segbevcount;
while (a--) {
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
while (len--) {
copy_v3_v3(bevp->vec, bp->vec);
bevp->tilt = bp->tilt;
bevp->radius = bp->radius;
bevp->weight = bp->weight;
copy_v3_v3(bevp->vec, prevbezt->vec[1]);
bevp->tilt = prevbezt->tilt;
bevp->radius = prevbezt->radius;
bevp->weight = prevbezt->weight;
bevp->split_tag = true;
bp++;
if (seglen != NULL && len != 0) {
*seglen = len_v3v3(bevp->vec, bp->vec);
bevp++;
bevp->dupe_tag = false;
bevp++;
bl->nr++;
bl->dupe_nr = 1;
if (seglen != NULL) {
*seglen = len_v3v3(prevbezt->vec[1], bezt->vec[1]);
bevp->offset = *seglen;
if (*seglen > treshold) {
seglen++;
/* match segbevcount to the cleaned up bevel lists (see STEP 2) */
if (bevp->offset > treshold) {
*segbevcount = 1;
}
else {
*segbevcount = 0;
segbevcount++;
}
}
else {
/* always do all three, to prevent data hanging around */
int j;
/* BevPoint must stay aligned to 4 so sizeof(BevPoint)/sizeof(float) works */
for (j = 0; j < 3; j++) {
BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
prevbezt->vec[2][j],
bezt->vec[0][j],
bezt->vec[1][j],
&(bevp->vec[j]),
resolu,
sizeof(BevPoint));
}
/* if both arrays are NULL do nothiong */
tilt_bezpart(prevbezt,
bezt,
nu,
do_tilt ? &bevp->tilt : NULL,
do_radius ? &bevp->radius : NULL,
do_weight ? &bevp->weight : NULL,
resolu,
sizeof(BevPoint));
if (cu->twist_mode == CU_TWIST_TANGENT) {
forward_diff_bezier_cotangent(prevbezt->vec[1],
prevbezt->vec[2],
bezt->vec[0],
bezt->vec[1],
bevp->tan,
resolu,
sizeof(BevPoint));
}
/* indicate with handlecodes double points */
if (prevbezt->h1 == prevbezt->h2) {
if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT) {
bevp->split_tag = true;
}
}
else {
if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT) {
bevp->split_tag = true;
}
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++;
bevp += resolu;
}
bl->nr += resolu;
}
prevbezt = bezt;
bezt++;
}
if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic: endpoint */
copy_v3_v3(bevp->vec, prevbezt->vec[1]);
bevp->tilt = prevbezt->tilt;
bevp->radius = prevbezt->radius;
bevp->weight = prevbezt->weight;
sub_v3_v3v3(bevp->dir, prevbezt->vec[1], prevbezt->vec[0]);
normalize_v3(bevp->dir);
bl->nr++;
}
}
else if (nu->type == CU_NURBS) {
if (nu->pntsv == 1) {
len = (resolu * segcount);
BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList3");
bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints3");
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList3_seglen");
bl->segbevcount = MEM_malloc_arrayN(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->tilt : NULL,
do_radius ? &bevp->radius : NULL,
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--;
}
}
@ -2751,291 +2960,83 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
}
}
else if (nu->type == CU_BEZIER) {
/* in case last point is not cyclic */
len = segcount * resolu + 1;
BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints");
bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelBPointsPoints");
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelBPoints_seglen");
bl->segbevcount = MEM_malloc_arrayN(
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;
if (nu->flagu & CU_NURB_CYCLIC) {
a++;
prevbezt = nu->bezt + (nu->pntsu - 1);
}
else {
prevbezt = bezt;
bezt++;
}
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) {
copy_v3_v3(bevp->vec, prevbezt->vec[1]);
bevp->tilt = prevbezt->tilt;
bevp->radius = prevbezt->radius;
bevp->weight = prevbezt->weight;
bevp->split_tag = true;
bevp->dupe_tag = false;
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 */
int j;
/* BevPoint must stay aligned to 4 so sizeof(BevPoint)/sizeof(float) works */
for (j = 0; j < 3; j++) {
BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
prevbezt->vec[2][j],
bezt->vec[0][j],
bezt->vec[1][j],
&(bevp->vec[j]),
resolu,
sizeof(BevPoint));
}
/* if both arrays are NULL do nothiong */
tilt_bezpart(prevbezt,
bezt,
nu,
do_tilt ? &bevp->tilt : NULL,
do_radius ? &bevp->radius : NULL,
do_weight ? &bevp->weight : NULL,
resolu,
sizeof(BevPoint));
if (cu->twist_mode == CU_TWIST_TANGENT) {
forward_diff_bezier_cotangent(prevbezt->vec[1],
prevbezt->vec[2],
bezt->vec[0],
bezt->vec[1],
bevp->tan,
resolu,
sizeof(BevPoint));
}
/* indicate with handlecodes double points */
if (prevbezt->h1 == prevbezt->h2) {
if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT) {
bevp->split_tag = true;
}
}
else {
if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT) {
bevp->split_tag = true;
}
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;
}
prevbezt = bezt;
bezt++;
}
if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic: endpoint */
copy_v3_v3(bevp->vec, prevbezt->vec[1]);
bevp->tilt = prevbezt->tilt;
bevp->radius = prevbezt->radius;
bevp->weight = prevbezt->weight;
sub_v3_v3v3(bevp->dir, prevbezt->vec[1], prevbezt->vec[0]);
normalize_v3(bevp->dir);
bl->nr++;
}
}
else if (nu->type == CU_NURBS) {
if (nu->pntsv == 1) {
len = (resolu * segcount);
BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList3");
bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints3");
if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList3_seglen");
bl->segbevcount = MEM_malloc_arrayN(
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->tilt : NULL,
do_radius ? &bevp->radius : NULL,
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);
}
}
}
}
}
/* STEP 2: DOUBLE POINTS AND AUTOMATIC RESOLUTION, REDUCE DATABLOCKS */
LISTBASE_FOREACH (BevList *, bl, bev) {
if (bl->nr) { /* null bevel items come from single points */
bool is_cyclic = bl->poly != -1;
nr = bl->nr;
if (is_cyclic) {
bevp1 = bl->bevpoints;
bevp0 = bevp1 + (nr - 1);
if (bl->nr == 0) { /* null bevel items come from single points */
continue;
}
bool is_cyclic = bl->poly != -1;
nr = bl->nr;
if (is_cyclic) {
bevp1 = bl->bevpoints;
bevp0 = bevp1 + (nr - 1);
}
else {
bevp0 = bl->bevpoints;
bevp0->offset = 0;
bevp1 = bevp0 + 1;
}
nr--;
while (nr--) {
if (seglen != NULL) {
if (fabsf(bevp1->offset) < treshold) {
bevp0->dupe_tag = true;
bl->dupe_nr++;
}
}
else {
bevp0 = bl->bevpoints;
bevp0->offset = 0;
bevp1 = bevp0 + 1;
}
nr--;
while (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++;
}
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++;
}
}
}
bevp0 = bevp1;
bevp1++;
}
bevp0 = bevp1;
bevp1++;
}
}
LISTBASE_FOREACH_MUTABLE (BevList *, bl, bev) {
if (bl->nr && bl->dupe_nr) {
nr = bl->nr - bl->dupe_nr + 1; /* +1 because vectorbezier sets flag too */
blnew = MEM_mallocN(sizeof(BevList), "makeBevelList4");
memcpy(blnew, bl, sizeof(BevList));
blnew->bevpoints = MEM_calloc_arrayN(nr, sizeof(BevPoint), "makeBevelPoints4");
if (!blnew->bevpoints) {
MEM_freeN(blnew);
break;
}
blnew->segbevcount = bl->segbevcount;
blnew->seglen = bl->seglen;
blnew->nr = 0;
BLI_remlink(bev, bl);
BLI_insertlinkbefore(bev, bl->next, blnew); /* to make sure bevlist is tuned with nurblist */
bevp0 = bl->bevpoints;
bevp1 = blnew->bevpoints;
nr = bl->nr;
while (nr--) {
if (bevp0->dupe_tag == 0) {
memcpy(bevp1, bevp0, sizeof(BevPoint));
bevp1++;
blnew->nr++;
}
bevp0++;
}
if (bl->bevpoints != NULL) {
MEM_freeN(bl->bevpoints);
}
MEM_freeN(bl);
blnew->dupe_nr = 0;
if (bl->nr == 0 || bl->dupe_nr == 0) {
continue;
}
nr = bl->nr - bl->dupe_nr + 1; /* +1 because vectorbezier sets flag too */
blnew = MEM_mallocN(sizeof(BevList), "makeBevelList4");
memcpy(blnew, bl, sizeof(BevList));
blnew->bevpoints = MEM_calloc_arrayN(nr, sizeof(BevPoint), "makeBevelPoints4");
if (!blnew->bevpoints) {
MEM_freeN(blnew);
break;
}
blnew->segbevcount = bl->segbevcount;
blnew->seglen = bl->seglen;
blnew->nr = 0;
BLI_remlink(bev, bl);
BLI_insertlinkbefore(bev, bl->next, blnew); /* to make sure bevlist is tuned with nurblist */
bevp0 = bl->bevpoints;
bevp1 = blnew->bevpoints;
nr = bl->nr;
while (nr--) {
if (bevp0->dupe_tag == 0) {
memcpy(bevp1, bevp0, sizeof(BevPoint));
bevp1++;
blnew->nr++;
}
bevp0++;
}
if (bl->bevpoints != NULL) {
MEM_freeN(bl->bevpoints);
}
MEM_freeN(bl);
blnew->dupe_nr = 0;
}
/* STEP 3: POLYS COUNT AND AUTOHOLE */
@ -3645,7 +3646,7 @@ static bool tridiagonal_solve_with_limits(float *a,
* is affected by all other points of the curve segment, in practice the influence
* decreases exponentially with distance.
*
* Note: this algorithm assumes that the handle horizontal size if always 1/3 of the
* Note: this algorithm assumes that the handle horizontal size is always 1/3 of the
* of the interval to the next point. This rule ensures linear interpolation of time.
*
* ^ height (co 1)
@ -4389,50 +4390,52 @@ void BKE_nurbList_handles_recalculate(ListBase *editnurb,
int a;
LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bool changed = false;
if (nu->type != CU_BEZIER) {
continue;
}
for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
bool changed = false;
const bool h1_select = (bezt->f1 & flag) == flag;
const bool h2_select = (bezt->f3 & flag) == flag;
for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
if (h1_select || h2_select) {
const bool h1_select = (bezt->f1 & flag) == flag;
const bool h2_select = (bezt->f3 & flag) == flag;
float co1_back[3], co2_back[3];
if (h1_select || h2_select) {
copy_v3_v3(co1_back, bezt->vec[0]);
copy_v3_v3(co2_back, bezt->vec[2]);
float co1_back[3], co2_back[3];
BKE_nurb_handle_calc_simple_auto(nu, bezt);
copy_v3_v3(co1_back, bezt->vec[0]);
copy_v3_v3(co2_back, bezt->vec[2]);
if (h1_select) {
if (!calc_length) {
dist_ensure_v3_v3fl(bezt->vec[0], bezt->vec[1], len_v3v3(co1_back, bezt->vec[1]));
}
BKE_nurb_handle_calc_simple_auto(nu, bezt);
if (h1_select) {
if (!calc_length) {
dist_ensure_v3_v3fl(bezt->vec[0], bezt->vec[1], len_v3v3(co1_back, bezt->vec[1]));
}
else {
copy_v3_v3(bezt->vec[0], co1_back);
}
if (h2_select) {
if (!calc_length) {
dist_ensure_v3_v3fl(bezt->vec[2], bezt->vec[1], len_v3v3(co2_back, bezt->vec[1]));
}
}
else {
copy_v3_v3(bezt->vec[2], co2_back);
}
changed = true;
}
}
else {
copy_v3_v3(bezt->vec[0], co1_back);
}
if (changed) {
/* Recalculate the whole curve */
BKE_nurb_handles_calc(nu);
if (h2_select) {
if (!calc_length) {
dist_ensure_v3_v3fl(bezt->vec[2], bezt->vec[1], len_v3v3(co2_back, bezt->vec[1]));
}
}
else {
copy_v3_v3(bezt->vec[2], co2_back);
}
changed = true;
}
}
if (changed) {
/* Recalculate the whole curve */
BKE_nurb_handles_calc(nu);
}
}
}

View File

@ -152,7 +152,6 @@ void BKE_displist_normals_add(ListBase *lb)
int a, b, p1, p2, p3, p4;
LISTBASE_FOREACH (DispList *, dl, lb) {
if (dl->type == DL_INDEX3) {
if (dl->nors == NULL) {
dl->nors = MEM_callocN(sizeof(float[3]), "dlnors");
@ -306,149 +305,151 @@ static void curve_to_displist(Curve *cu,
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
LISTBASE_FOREACH (Nurb *, nu, nubase) {
if (nu->hide == 0 || editmode == false) {
if (for_render && cu->resolu_ren != 0) {
resolu = cu->resolu_ren;
if (nu->hide != 0 && editmode) {
continue;
}
if (for_render && cu->resolu_ren != 0) {
resolu = cu->resolu_ren;
}
else {
resolu = nu->resolu;
}
if (!BKE_nurb_check_valid_u(nu)) {
/* pass */
}
else if (nu->type == CU_BEZIER) {
/* count */
len = 0;
a = nu->pntsu - 1;
if (nu->flagu & CU_NURB_CYCLIC) {
a++;
}
prevbezt = nu->bezt;
bezt = prevbezt + 1;
while (a--) {
if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) {
bezt = nu->bezt;
}
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
len++;
}
else {
len += resolu;
}
if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) == 0) {
len++;
}
prevbezt = bezt;
bezt++;
}
dl = MEM_callocN(sizeof(DispList), "makeDispListbez");
/* len+1 because of 'forward_diff_bezier' function */
dl->verts = MEM_mallocN((len + 1) * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->parts = 1;
dl->nr = len;
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
data = dl->verts;
/* check that (len != 2) so we don't immediately loop back on ourselves */
if (nu->flagu & CU_NURB_CYCLIC && (dl->nr != 2)) {
dl->type = DL_POLY;
a = nu->pntsu;
}
else {
resolu = nu->resolu;
}
if (!BKE_nurb_check_valid_u(nu)) {
/* pass */
}
else if (nu->type == CU_BEZIER) {
/* count */
len = 0;
dl->type = DL_SEGM;
a = nu->pntsu - 1;
if (nu->flagu & CU_NURB_CYCLIC) {
a++;
}
prevbezt = nu->bezt;
bezt = prevbezt + 1;
while (a--) {
if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) {
bezt = nu->bezt;
}
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
len++;
}
else {
len += resolu;
}
if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) == 0) {
len++;
}
prevbezt = bezt;
bezt++;
}
dl = MEM_callocN(sizeof(DispList), "makeDispListbez");
/* len+1 because of 'forward_diff_bezier' function */
dl->verts = MEM_mallocN((len + 1) * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->parts = 1;
dl->nr = len;
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
data = dl->verts;
/* check that (len != 2) so we don't immediately loop back on ourselves */
if (nu->flagu & CU_NURB_CYCLIC && (dl->nr != 2)) {
dl->type = DL_POLY;
a = nu->pntsu;
}
else {
dl->type = DL_SEGM;
a = nu->pntsu - 1;
}
prevbezt = nu->bezt;
bezt = prevbezt + 1;
while (a--) {
if (a == 0 && dl->type == DL_POLY) {
bezt = nu->bezt;
}
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
copy_v3_v3(data, prevbezt->vec[1]);
data += 3;
}
else {
int j;
for (j = 0; j < 3; j++) {
BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
prevbezt->vec[2][j],
bezt->vec[0][j],
bezt->vec[1][j],
data + j,
resolu,
sizeof(float[3]));
}
data += 3 * resolu;
}
if (a == 0 && dl->type == DL_SEGM) {
copy_v3_v3(data, bezt->vec[1]);
}
prevbezt = bezt;
bezt++;
}
}
else if (nu->type == CU_NURBS) {
len = (resolu * SEGMENTSU(nu));
dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->parts = 1;
prevbezt = nu->bezt;
bezt = prevbezt + 1;
dl->nr = len;
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
data = dl->verts;
if (nu->flagu & CU_NURB_CYCLIC) {
dl->type = DL_POLY;
}
else {
dl->type = DL_SEGM;
}
BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3]));
}
else if (nu->type == CU_POLY) {
len = nu->pntsu;
dl = MEM_callocN(sizeof(DispList), "makeDispListpoly");
dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->parts = 1;
dl->nr = len;
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
data = dl->verts;
if ((nu->flagu & CU_NURB_CYCLIC) && (dl->nr != 2)) {
dl->type = DL_POLY;
}
else {
dl->type = DL_SEGM;
while (a--) {
if (a == 0 && dl->type == DL_POLY) {
bezt = nu->bezt;
}
a = len;
bp = nu->bp;
while (a--) {
copy_v3_v3(data, bp->vec);
bp++;
if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) {
copy_v3_v3(data, prevbezt->vec[1]);
data += 3;
}
else {
int j;
for (j = 0; j < 3; j++) {
BKE_curve_forward_diff_bezier(prevbezt->vec[1][j],
prevbezt->vec[2][j],
bezt->vec[0][j],
bezt->vec[1][j],
data + j,
resolu,
sizeof(float[3]));
}
data += 3 * resolu;
}
if (a == 0 && dl->type == DL_SEGM) {
copy_v3_v3(data, bezt->vec[1]);
}
prevbezt = bezt;
bezt++;
}
}
else if (nu->type == CU_NURBS) {
len = (resolu * SEGMENTSU(nu));
dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->parts = 1;
dl->nr = len;
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
data = dl->verts;
if (nu->flagu & CU_NURB_CYCLIC) {
dl->type = DL_POLY;
}
else {
dl->type = DL_SEGM;
}
BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3]));
}
else if (nu->type == CU_POLY) {
len = nu->pntsu;
dl = MEM_callocN(sizeof(DispList), "makeDispListpoly");
dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->parts = 1;
dl->nr = len;
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
data = dl->verts;
if ((nu->flagu & CU_NURB_CYCLIC) && (dl->nr != 2)) {
dl->type = DL_POLY;
}
else {
dl->type = DL_SEGM;
}
a = len;
bp = nu->bp;
while (a--) {
copy_v3_v3(data, bp->vec);
bp++;
data += 3;
}
}
}
@ -468,7 +469,7 @@ void BKE_displist_fill(ListBase *dispbase,
ScanFillVert *sf_vert, *sf_vert_new, *sf_vert_last;
ScanFillFace *sf_tri;
MemArena *sf_arena;
DispList *dlnew = NULL, *dl;
DispList *dlnew = NULL;
float *f1;
int colnr = 0, charidx = 0, cont = 1, tot, a, *index, nextcol = 0;
int totvert;
@ -492,8 +493,7 @@ void BKE_displist_fill(ListBase *dispbase,
BLI_scanfill_begin_arena(&sf_ctx, sf_arena);
dl = dispbase->first;
while (dl) {
LISTBASE_FOREACH (DispList *, dl, dispbase) {
if (dl->type == DL_POLY) {
if (charidx < dl->charidx) {
cont = 1;
@ -535,7 +535,6 @@ void BKE_displist_fill(ListBase *dispbase,
}
dl_flag_accum |= dl->flag;
}
dl = dl->next;
}
/* XXX (obedit && obedit->actcol) ? (obedit->actcol - 1) : 0)) { */
@ -1208,75 +1207,77 @@ void BKE_displist_make_surf(Depsgraph *depsgraph,
}
LISTBASE_FOREACH (Nurb *, nu, &nubase) {
if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) {
int resolu = nu->resolu, resolv = nu->resolv;
if (!(for_render || nu->hide == 0) || !BKE_nurb_check_valid_uv(nu)) {
continue;
}
if (for_render) {
if (cu->resolu_ren) {
resolu = cu->resolu_ren;
}
if (cu->resolv_ren) {
resolv = cu->resolv_ren;
}
int resolu = nu->resolu, resolv = nu->resolv;
if (for_render) {
if (cu->resolu_ren) {
resolu = cu->resolu_ren;
}
if (cu->resolv_ren) {
resolv = cu->resolv_ren;
}
}
if (nu->pntsv == 1) {
len = SEGMENTSU(nu) * resolu;
if (nu->pntsv == 1) {
len = SEGMENTSU(nu) * resolu;
dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->parts = 1;
dl->nr = len;
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
BLI_addtail(dispbase, dl);
dl->parts = 1;
dl->nr = len;
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
data = dl->verts;
if (nu->flagu & CU_NURB_CYCLIC) {
dl->type = DL_POLY;
}
else {
dl->type = DL_SEGM;
}
BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3]));
data = dl->verts;
if (nu->flagu & CU_NURB_CYCLIC) {
dl->type = DL_POLY;
}
else {
len = (nu->pntsu * resolu) * (nu->pntsv * resolv);
dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
data = dl->verts;
dl->type = DL_SURF;
dl->parts = (nu->pntsu * resolu); /* in reverse, because makeNurbfaces works that way */
dl->nr = (nu->pntsv * resolv);
if (nu->flagv & CU_NURB_CYCLIC) {
dl->flag |= DL_CYCL_U; /* reverse too! */
}
if (nu->flagu & CU_NURB_CYCLIC) {
dl->flag |= DL_CYCL_V;
}
BKE_nurb_makeFaces(nu, data, 0, resolu, resolv);
/* gl array drawing: using indices */
displist_surf_indices(dl);
dl->type = DL_SEGM;
}
BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3]));
}
else {
len = (nu->pntsu * resolu) * (nu->pntsv * resolv);
dl = MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts");
BLI_addtail(dispbase, dl);
dl->col = nu->mat_nr;
dl->charidx = nu->charidx;
/* dl->rt will be used as flag for render face and */
/* CU_2D conflicts with R_NOPUNOFLIP */
dl->rt = nu->flag & ~CU_2D;
data = dl->verts;
dl->type = DL_SURF;
dl->parts = (nu->pntsu * resolu); /* in reverse, because makeNurbfaces works that way */
dl->nr = (nu->pntsv * resolv);
if (nu->flagv & CU_NURB_CYCLIC) {
dl->flag |= DL_CYCL_U; /* reverse too! */
}
if (nu->flagu & CU_NURB_CYCLIC) {
dl->flag |= DL_CYCL_V;
}
BKE_nurb_makeFaces(nu, data, 0, resolu, resolv);
/* gl array drawing: using indices */
displist_surf_indices(dl);
}
}

View File

@ -307,12 +307,8 @@ static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu)
static void keyIndex_delNurbList(EditNurb *editnurb, ListBase *nubase)
{
Nurb *nu = nubase->first;
while (nu) {
LISTBASE_FOREACH (Nurb *, nu, nubase) {
keyIndex_delNurb(editnurb, nu);
nu = nu->next;
}
}
@ -646,250 +642,247 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs)
{
Curve *cu = (Curve *)obedit->data;
/* are there keys? */
if (cu->key) {
int a, i;
EditNurb *editnurb = cu->editnurb;
KeyBlock *currkey;
KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1);
BezTriple *bezt, *oldbezt;
BPoint *bp, *oldbp;
Nurb *newnu;
int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs);
if (cu->key == NULL) {
return;
}
float(*ofs)[3] = NULL;
float *oldkey, *newkey, *ofp;
int a, i;
EditNurb *editnurb = cu->editnurb;
KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1);
BezTriple *bezt, *oldbezt;
BPoint *bp, *oldbp;
Nurb *newnu;
int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs);
/* editing the base key should update others */
if (cu->key->type == KEY_RELATIVE) {
if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */
int totvec = 0;
float(*ofs)[3] = NULL;
float *oldkey, *newkey, *ofp;
/* Calculate needed memory to store offset */
LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
/* editing the base key should update others */
if (cu->key->type == KEY_RELATIVE) {
if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */
int totvec = 0;
if (nu->bezt) {
/* Three vects to store handles and one for tilt. */
totvec += nu->pntsu * 4;
}
else {
totvec += 2 * nu->pntsu * nu->pntsv;
}
/* Calculate needed memory to store offset */
LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (nu->bezt) {
/* Three vects to store handles and one for tilt. */
totvec += nu->pntsu * 4;
}
else {
totvec += 2 * nu->pntsu * nu->pntsv;
}
}
ofs = MEM_callocN(sizeof(float[3]) * totvec, "currkey->data");
i = 0;
LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (nu->bezt) {
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
ofs = MEM_callocN(sizeof(float[3]) * totvec, "currkey->data");
i = 0;
LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (nu->bezt) {
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
if (oldbezt) {
int j;
for (j = 0; j < 3; j++) {
sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]);
i++;
}
ofs[i][0] = bezt->tilt - oldbezt->tilt;
ofs[i][1] = bezt->radius - oldbezt->radius;
if (oldbezt) {
int j;
for (j = 0; j < 3; j++) {
sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]);
i++;
}
else {
i += 4;
}
bezt++;
ofs[i][0] = bezt->tilt - oldbezt->tilt;
ofs[i][1] = bezt->radius - oldbezt->radius;
i++;
}
else {
i += 4;
}
bezt++;
}
else {
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
while (a--) {
oldbp = getKeyIndexOrig_bp(editnurb, bp);
if (oldbp) {
sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec);
ofs[i + 1][0] = bp->tilt - oldbp->tilt;
ofs[i + 1][1] = bp->radius - oldbp->radius;
}
i += 2;
bp++;
}
else {
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
while (a--) {
oldbp = getKeyIndexOrig_bp(editnurb, bp);
if (oldbp) {
sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec);
ofs[i + 1][0] = bp->tilt - oldbp->tilt;
ofs[i + 1][1] = bp->radius - oldbp->radius;
}
i += 2;
bp++;
}
}
}
}
}
currkey = cu->key->block.first;
while (currkey) {
const bool apply_offset = (ofs && (currkey != actkey) &&
(editnurb->shapenr - 1 == currkey->relative));
LISTBASE_FOREACH (KeyBlock *, currkey, &cu->key->block) {
const bool apply_offset = (ofs && (currkey != actkey) &&
(editnurb->shapenr - 1 == currkey->relative));
float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data");
ofp = oldkey = currkey->data;
float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data");
ofp = oldkey = currkey->data;
Nurb *nu = editnurb->nurbs.first;
/* We need to restore to original curve into newnurb, *not* editcurve's nurbs.
* Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render),
* we would invalidate editcurve. */
newnu = newnurbs->first;
i = 0;
while (nu) {
if (currkey == actkey) {
const bool restore = actkey != cu->key->refkey;
Nurb *nu = editnurb->nurbs.first;
/* We need to restore to original curve into newnurb, *not* editcurve's nurbs.
* Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render),
* we would invalidate editcurve. */
newnu = newnurbs->first;
i = 0;
while (nu) {
if (currkey == actkey) {
const bool restore = actkey != cu->key->refkey;
if (nu->bezt) {
bezt = nu->bezt;
a = nu->pntsu;
BezTriple *newbezt = newnu->bezt;
while (a--) {
int j;
oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
for (j = 0; j < 3; j++, i++) {
copy_v3_v3(&fp[j * 3], bezt->vec[j]);
if (restore && oldbezt) {
copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]);
}
}
fp[9] = bezt->tilt;
fp[10] = bezt->radius;
if (restore && oldbezt) {
newbezt->tilt = oldbezt->tilt;
newbezt->radius = oldbezt->radius;
}
fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
i++;
bezt++;
newbezt++;
}
}
else {
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
BPoint *newbp = newnu->bp;
while (a--) {
oldbp = getKeyIndexOrig_bp(editnurb, bp);
copy_v3_v3(fp, bp->vec);
fp[3] = bp->tilt;
fp[4] = bp->radius;
if (restore && oldbp) {
copy_v3_v3(newbp->vec, oldbp->vec);
newbp->tilt = oldbp->tilt;
newbp->radius = oldbp->radius;
}
fp += KEYELEM_FLOAT_LEN_BPOINT;
bp++;
newbp++;
i += 2;
}
}
}
else {
int index;
const float *curofp;
if (oldkey) {
if (nu->bezt) {
bezt = nu->bezt;
a = nu->pntsu;
BezTriple *newbezt = newnu->bezt;
while (a--) {
int j;
oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
index = getKeyIndexOrig_keyIndex(editnurb, bezt);
if (index >= 0) {
int j;
curofp = ofp + index;
for (j = 0; j < 3; j++, i++) {
copy_v3_v3(&fp[j * 3], bezt->vec[j]);
for (j = 0; j < 3; j++, i++) {
copy_v3_v3(&fp[j * 3], &curofp[j * 3]);
if (restore && oldbezt) {
copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]);
if (apply_offset) {
add_v3_v3(&fp[j * 3], ofs[i]);
}
}
}
fp[9] = bezt->tilt;
fp[10] = bezt->radius;
fp[9] = curofp[9];
fp[10] = curofp[10];
if (restore && oldbezt) {
newbezt->tilt = oldbezt->tilt;
newbezt->radius = oldbezt->radius;
}
if (apply_offset) {
/* Apply tilt offsets. */
add_v3_v3(fp + 9, ofs[i]);
i++;
}
fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
i++;
fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
}
else {
int j;
for (j = 0; j < 3; j++, i++) {
copy_v3_v3(&fp[j * 3], bezt->vec[j]);
}
fp[9] = bezt->tilt;
fp[10] = bezt->radius;
fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
}
bezt++;
newbezt++;
}
}
else {
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
BPoint *newbp = newnu->bp;
while (a--) {
oldbp = getKeyIndexOrig_bp(editnurb, bp);
index = getKeyIndexOrig_keyIndex(editnurb, bp);
copy_v3_v3(fp, bp->vec);
if (index >= 0) {
curofp = ofp + index;
copy_v3_v3(fp, curofp);
fp[3] = curofp[3];
fp[4] = curofp[4];
fp[3] = bp->tilt;
fp[4] = bp->radius;
if (restore && oldbp) {
copy_v3_v3(newbp->vec, oldbp->vec);
newbp->tilt = oldbp->tilt;
newbp->radius = oldbp->radius;
if (apply_offset) {
add_v3_v3(fp, ofs[i]);
add_v3_v3(&fp[3], ofs[i + 1]);
}
}
else {
copy_v3_v3(fp, bp->vec);
fp[3] = bp->tilt;
fp[4] = bp->radius;
}
fp += KEYELEM_FLOAT_LEN_BPOINT;
bp++;
newbp++;
i += 2;
}
}
}
else {
int index;
const float *curofp;
if (oldkey) {
if (nu->bezt) {
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
index = getKeyIndexOrig_keyIndex(editnurb, bezt);
if (index >= 0) {
int j;
curofp = ofp + index;
for (j = 0; j < 3; j++, i++) {
copy_v3_v3(&fp[j * 3], &curofp[j * 3]);
if (apply_offset) {
add_v3_v3(&fp[j * 3], ofs[i]);
}
}
fp[9] = curofp[9];
fp[10] = curofp[10];
if (apply_offset) {
/* Apply tilt offsets. */
add_v3_v3(fp + 9, ofs[i]);
i++;
}
fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
}
else {
int j;
for (j = 0; j < 3; j++, i++) {
copy_v3_v3(&fp[j * 3], bezt->vec[j]);
}
fp[9] = bezt->tilt;
fp[10] = bezt->radius;
fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
}
bezt++;
}
}
else {
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
while (a--) {
index = getKeyIndexOrig_keyIndex(editnurb, bp);
if (index >= 0) {
curofp = ofp + index;
copy_v3_v3(fp, curofp);
fp[3] = curofp[3];
fp[4] = curofp[4];
if (apply_offset) {
add_v3_v3(fp, ofs[i]);
add_v3_v3(&fp[3], ofs[i + 1]);
}
}
else {
copy_v3_v3(fp, bp->vec);
fp[3] = bp->tilt;
fp[4] = bp->radius;
}
fp += KEYELEM_FLOAT_LEN_BPOINT;
bp++;
i += 2;
}
}
}
}
nu = nu->next;
newnu = newnu->next;
}
if (apply_offset) {
/* handles could become malicious after offsets applying */
calc_keyHandles(&editnurb->nurbs, newkey);
}
currkey->totelem = totvert;
if (currkey->data) {
MEM_freeN(currkey->data);
}
currkey->data = newkey;
currkey = currkey->next;
nu = nu->next;
newnu = newnu->next;
}
if (ofs) {
MEM_freeN(ofs);
if (apply_offset) {
/* handles could become malicious after offsets applying */
calc_keyHandles(&editnurb->nurbs, newkey);
}
currkey->totelem = totvert;
if (currkey->data) {
MEM_freeN(currkey->data);
}
currkey->data = newkey;
}
if (ofs) {
MEM_freeN(ofs);
}
}