diff options
author | Hans Goudey <h.goudey@me.com> | 2020-07-30 07:45:31 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-07-30 07:54:39 +0300 |
commit | 5893a1562fdb48d636731425a114b58e9bd9ab72 (patch) | |
tree | 5454b3b45f838061d34278a41a18d6181146b148 /source/blender/blenkernel | |
parent | 24d035b383c416e80f70d21a46d62e1f62736c4a (diff) |
Cleanup: split curve bevel into separate file
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 199 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve_bevel.c | 272 |
3 files changed, 273 insertions, 199 deletions
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 95f06d02055..ada341ff570 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -100,6 +100,7 @@ set(SRC intern/context.c intern/crazyspace.c intern/curve.c + intern/curve_bevel.c intern/curve_decimate.c intern/curve_deform.c intern/curveprofile.c diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index fb424b2d859..acc3c52c08c 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1726,205 +1726,6 @@ static void forward_diff_bezier_cotangent(const float p0[3], } } -/* ***************** BEVEL ****************** */ - -void BKE_curve_bevel_make(Object *ob, ListBase *disp) -{ - DispList *dl, *dlnew; - Curve *bevcu, *cu; - float *fp, facx, facy, angle, dangle; - int nr, a; - - cu = ob->data; - BLI_listbase_clear(disp); - - /* if a font object is being edited, then do nothing */ - // XXX if ( ob == obedit && ob->type == OB_FONT ) return; - - if (cu->bevobj) { - if (cu->bevobj->type != OB_CURVE) { - return; - } - - bevcu = cu->bevobj->data; - if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) { - ListBase bevdisp = {NULL, NULL}; - facx = cu->bevobj->scale[0]; - facy = cu->bevobj->scale[1]; - - if (cu->bevobj->runtime.curve_cache) { - dl = cu->bevobj->runtime.curve_cache->disp.first; - } - else { - BLI_assert(cu->bevobj->runtime.curve_cache != NULL); - dl = NULL; - } - - while (dl) { - if (ELEM(dl->type, DL_POLY, DL_SEGM)) { - dlnew = MEM_mallocN(sizeof(DispList), "makebevelcurve1"); - *dlnew = *dl; - dlnew->verts = MEM_malloc_arrayN( - dl->parts * dl->nr, 3 * sizeof(float), "makebevelcurve1"); - memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr); - - if (dlnew->type == DL_SEGM) { - dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE); - } - - BLI_addtail(disp, dlnew); - fp = dlnew->verts; - nr = dlnew->parts * dlnew->nr; - while (nr--) { - fp[2] = fp[1] * facy; - fp[1] = -fp[0] * facx; - fp[0] = 0.0; - fp += 3; - } - } - dl = dl->next; - } - - BKE_displist_free(&bevdisp); - } - } - else if (cu->ext1 == 0.0f && cu->ext2 == 0.0f) { - /* pass */ - } - else if (cu->ext2 == 0.0f) { - dl = MEM_callocN(sizeof(DispList), "makebevelcurve2"); - dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), "makebevelcurve2"); - BLI_addtail(disp, dl); - dl->type = DL_SEGM; - dl->parts = 1; - dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; - dl->nr = 2; - - fp = dl->verts; - fp[0] = fp[1] = 0.0; - fp[2] = -cu->ext1; - fp[3] = fp[4] = 0.0; - fp[5] = cu->ext1; - } - else if ((cu->flag & (CU_FRONT | CU_BACK)) == 0 && cu->ext1 == 0.0f) { - /* We make a full round bevel in that case. */ - - nr = 4 + 2 * cu->bevresol; - - dl = MEM_callocN(sizeof(DispList), "makebevelcurve p1"); - dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve p1"); - BLI_addtail(disp, dl); - dl->type = DL_POLY; - dl->parts = 1; - dl->flag = DL_BACK_CURVE; - dl->nr = nr; - - /* a circle */ - fp = dl->verts; - dangle = (2.0f * (float)M_PI / (nr)); - angle = -(nr - 1) * dangle; - - for (a = 0; a < nr; a++) { - fp[0] = 0.0; - fp[1] = (cosf(angle) * (cu->ext2)); - fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1; - angle += dangle; - fp += 3; - } - } - else { - /* The general case for nonzero extrusion or an incomplete loop. */ - dl = MEM_callocN(sizeof(DispList), "makebevelcurve"); - if ((cu->flag & (CU_FRONT | CU_BACK)) == 0) { - /* The full loop. */ - nr = 4 * cu->bevresol + 6; - dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; - } - else if ((cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) { - /* Half the loop. */ - nr = 2 * (cu->bevresol + 1) + ((cu->ext1 == 0.0f) ? 1 : 2); - dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; - } - else { - /* One quarter of the loop (just front or back). */ - nr = (cu->ext1 == 0.0f) ? cu->bevresol + 2 : cu->bevresol + 3; - dl->flag = (cu->flag & CU_FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE; - } - - dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve"); - BLI_addtail(disp, dl); - /* Use a different type depending on whether the loop is complete or not. */ - dl->type = ((cu->flag & (CU_FRONT | CU_BACK)) == 0) ? DL_POLY : DL_SEGM; - dl->parts = 1; - dl->nr = nr; - - fp = dl->verts; - dangle = (float)M_PI_2 / (cu->bevresol + 1); - angle = 0.0; - - /* Build the back section. */ - if (cu->flag & CU_BACK || !(cu->flag & CU_FRONT)) { - angle = (float)M_PI_2 * 3.0f; - for (a = 0; a < cu->bevresol + 2; a++) { - fp[0] = 0.0; - fp[1] = (float)(cosf(angle) * (cu->ext2)); - fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1; - angle += dangle; - fp += 3; - } - if ((cu->ext1 != 0.0f) && !(cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) { - /* Add the extrusion if we're only building the back. */ - fp[0] = 0.0; - fp[1] = cu->ext2; - fp[2] = cu->ext1; - } - } - - /* Build the front section. */ - if (cu->flag & CU_FRONT || !(cu->flag & CU_BACK)) { - if ((cu->ext1 != 0.0f) && !(cu->flag & CU_BACK) && (cu->flag & CU_FRONT)) { - /* Add the extrusion if we're only building the back. */ - fp[0] = 0.0; - fp[1] = cu->ext2; - fp[2] = -cu->ext1; - fp += 3; - } - /* Don't duplicate the last back vertex. */ - angle = (cu->ext1 == 0.0f && (cu->flag & CU_BACK)) ? dangle : 0; - int front_len = (cu->ext1 == 0.0f && ((cu->flag & CU_BACK) || !(cu->flag & CU_FRONT))) ? - cu->bevresol + 1 : - cu->bevresol + 2; - for (a = 0; a < front_len; a++) { - fp[0] = 0.0; - fp[1] = (float)(cosf(angle) * (cu->ext2)); - fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1; - angle += dangle; - fp += 3; - } - } - - /* Build the other half only if we're building the full loop. */ - if (!(cu->flag & (CU_FRONT | CU_BACK))) { - for (a = 0; a < cu->bevresol + 1; a++) { - fp[0] = 0.0; - fp[1] = (float)(cosf(angle) * (cu->ext2)); - fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1; - angle += dangle; - fp += 3; - } - - angle = (float)M_PI; - for (a = 0; a < cu->bevresol + 1; a++) { - fp[0] = 0.0; - fp[1] = (float)(cosf(angle) * (cu->ext2)); - fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1; - angle += dangle; - fp += 3; - } - } - } -} - static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], diff --git a/source/blender/blenkernel/intern/curve_bevel.c b/source/blender/blenkernel/intern/curve_bevel.c new file mode 100644 index 00000000000..7f23f0215cc --- /dev/null +++ b/source/blender/blenkernel/intern/curve_bevel.c @@ -0,0 +1,272 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup bke + * + * Handle curve object data bevel options, + * both extruding + */ + +#include <string.h> + +#include "BLI_listbase.h" +#include "BLI_math_base.h" + +#include "MEM_guardedalloc.h" + +#include "DNA_curve_types.h" +#include "DNA_object_types.h" + +#include "BKE_curve.h" +#include "BKE_displist.h" + +typedef enum CurveBevelFillType { + BACK = 0, + FRONT, + HALF, + FULL, +} CurveBevelFillType; + +static CurveBevelFillType curve_bevel_get_fill_type(const Curve *curve) +{ + if (!(curve->flag & (CU_FRONT | CU_BACK))) { + return FULL; + } + if ((curve->flag & CU_FRONT) && (curve->flag & CU_BACK)) { + return HALF; + } + + return (curve->flag & CU_FRONT) ? FRONT : BACK; +} + +static void curve_bevel_make_extrude_and_fill(Curve *cu, + ListBase *disp, + const bool use_extrude, + const CurveBevelFillType fill_type) +{ + DispList *dl = MEM_callocN(sizeof(DispList), __func__); + + int nr; + if (fill_type == FULL) { + /* The full loop. */ + nr = 4 * cu->bevresol + 6; + dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; + } + else if (fill_type == HALF) { + /* Half the loop. */ + nr = 2 * (cu->bevresol + 1) + (use_extrude ? 2 : 1); + dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; + } + else { + /* One quarter of the loop (just front or back). */ + nr = use_extrude ? cu->bevresol + 3 : cu->bevresol + 2; + dl->flag = (fill_type == FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE; + } + + dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__); + BLI_addtail(disp, dl); + /* Use a different type depending on whether the loop is complete or not. */ + dl->type = (fill_type == FULL) ? DL_POLY : DL_SEGM; + dl->parts = 1; + dl->nr = nr; + + float *fp = dl->verts; + const float dangle = (float)M_PI_2 / (cu->bevresol + 1); + float angle = 0.0f; + + /* Build the back section. */ + if (ELEM(fill_type, BACK, HALF, FULL)) { + angle = (float)M_PI_2 * 3.0f; + for (int i = 0; i < cu->bevresol + 2; i++) { + fp[0] = 0.0f; + fp[1] = (float)(cosf(angle) * (cu->ext2)); + fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1; + angle += dangle; + fp += 3; + } + if (use_extrude && fill_type == BACK) { + /* Add the extrusion if we're only building the back. */ + fp[0] = 0.0f; + fp[1] = cu->ext2; + fp[2] = cu->ext1; + } + } + + /* Build the front section. */ + if (ELEM(fill_type, FRONT, HALF, FULL)) { + if (use_extrude && fill_type == FRONT) { + /* Add the extrusion if we're only building the front. */ + fp[0] = 0.0f; + fp[1] = cu->ext2; + fp[2] = -cu->ext1; + fp += 3; + } + /* Don't duplicate the last back vertex. */ + angle = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? dangle : 0; + int front_len = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? cu->bevresol + 1 : + cu->bevresol + 2; + for (int i = 0; i < front_len; i++) { + fp[0] = 0.0f; + fp[1] = (float)(cosf(angle) * (cu->ext2)); + fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1; + angle += dangle; + fp += 3; + } + } + + /* Build the other half only if we're building the full loop. */ + if (fill_type == FULL) { + for (int i = 0; i < cu->bevresol + 1; i++) { + fp[0] = 0.0f; + fp[1] = (float)(cosf(angle) * (cu->ext2)); + fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1; + angle += dangle; + fp += 3; + } + + angle = (float)M_PI; + for (int i = 0; i < cu->bevresol + 1; i++) { + fp[0] = 0.0f; + fp[1] = (float)(cosf(angle) * (cu->ext2)); + fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1; + angle += dangle; + fp += 3; + } + } +} + +static void curve_bevel_make_full_circle(Curve *cu, ListBase *disp) +{ + const int nr = 4 + 2 * cu->bevresol; + + DispList *dl = MEM_callocN(sizeof(DispList), __func__); + dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__); + BLI_addtail(disp, dl); + dl->type = DL_POLY; + dl->parts = 1; + dl->flag = DL_BACK_CURVE; + dl->nr = nr; + + float *fp = dl->verts; + const float dangle = (2.0f * (float)M_PI / (nr)); + float angle = -(nr - 1) * dangle; + + for (int i = 0; i < nr; i++) { + fp[0] = 0.0; + fp[1] = (cosf(angle) * (cu->ext2)); + fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1; + angle += dangle; + fp += 3; + } +} + +static void curve_bevel_make_only_extrude(Curve *cu, ListBase *disp) +{ + DispList *dl = MEM_callocN(sizeof(DispList), __func__); + dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), __func__); + BLI_addtail(disp, dl); + dl->type = DL_SEGM; + dl->parts = 1; + dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE; + dl->nr = 2; + + float *fp = dl->verts; + fp[0] = fp[1] = 0.0; + fp[2] = -cu->ext1; + fp[3] = fp[4] = 0.0; + fp[5] = cu->ext1; +} + +static void curve_bevel_make_from_object(Curve *cu, ListBase *disp) +{ + if (cu->bevobj->type != OB_CURVE) { + return; + } + + Curve *bevcu = cu->bevobj->data; + if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) { + ListBase bevdisp = {NULL, NULL}; + float facx = cu->bevobj->scale[0]; + float facy = cu->bevobj->scale[1]; + + DispList *dl; + if (cu->bevobj->runtime.curve_cache) { + dl = cu->bevobj->runtime.curve_cache->disp.first; + } + else { + BLI_assert(cu->bevobj->runtime.curve_cache != NULL); + dl = NULL; + } + + while (dl) { + if (ELEM(dl->type, DL_POLY, DL_SEGM)) { + DispList *dlnew = MEM_mallocN(sizeof(DispList), __func__); + *dlnew = *dl; + dlnew->verts = MEM_malloc_arrayN(dl->parts * dl->nr, 3 * sizeof(float), __func__); + memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr); + + if (dlnew->type == DL_SEGM) { + dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE); + } + + BLI_addtail(disp, dlnew); + float *fp = dlnew->verts; + int nr = dlnew->parts * dlnew->nr; + while (nr--) { + fp[2] = fp[1] * facy; + fp[1] = -fp[0] * facx; + fp[0] = 0.0; + fp += 3; + } + } + dl = dl->next; + } + + BKE_displist_free(&bevdisp); + } +} + +void BKE_curve_bevel_make(Object *ob, ListBase *disp) +{ + Curve *curve = ob->data; + + const bool use_extrude = curve->ext1 != 0.0f; + const bool use_bevel = curve->ext2 != 0.0f; + + BLI_listbase_clear(disp); + + if (curve->bevobj) { + curve_bevel_make_from_object(curve, disp); + } + else if (!(use_extrude || use_bevel)) { + /* Pass. */ + } + else if (use_extrude && !use_bevel) { + curve_bevel_make_only_extrude(curve, disp); + } + else { + CurveBevelFillType fill_type = curve_bevel_get_fill_type(curve); + + if (!use_extrude && fill_type == FULL) { + curve_bevel_make_full_circle(curve, disp); + } + else { + /* The general case for nonzero extrusion or an incomplete loop. */ + curve_bevel_make_extrude_and_fill(curve, disp, use_extrude, fill_type); + } + } +} |