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:
parent
f32ab724eb
commit
594f47ecd2
Notes:
blender-bot
2023-02-14 06:42:54 +01:00
Referenced by issue #80736, Cycles CPU Preview Artifact
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue