diff options
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 138 | ||||
-rw-r--r-- | source/blender/editors/curve/editcurve.c | 155 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 39 | ||||
-rw-r--r-- | source/blender/editors/include/ED_curve.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_curve.c | 2 |
6 files changed, 165 insertions, 171 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 88d9cbb9b35..6e298a6d4f6 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -124,6 +124,7 @@ bool BKE_nurb_order_clamp_u(struct Nurb *nu); bool BKE_nurb_order_clamp_v(struct Nurb *nu); void BKE_nurb_direction_switch(struct Nurb *nu); +bool BKE_nurb_type_convert(struct Nurb *nu, const short type, const bool use_handles); void BKE_nurb_points_add(struct Nurb *nu, int number); void BKE_nurb_bezierPoints_add(struct Nurb *nu, int number); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 5d2c85e5825..5fba308e3df 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -3393,6 +3393,144 @@ bool BKE_nurb_order_clamp_v(struct Nurb *nu) return change; } +bool BKE_nurb_type_convert(Nurb *nu, const short type, const bool use_handles) +{ + BezTriple *bezt; + BPoint *bp; + int a, c, nr; + + if (nu->type == CU_POLY) { + if (type == CU_BEZIER) { /* to Bezier with vecthandles */ + nr = nu->pntsu; + bezt = (BezTriple *)MEM_callocN(nr * sizeof(BezTriple), "setsplinetype2"); + nu->bezt = bezt; + a = nr; + bp = nu->bp; + while (a--) { + copy_v3_v3(bezt->vec[1], bp->vec); + bezt->f1 = bezt->f2 = bezt->f3 = bp->f1; + bezt->h1 = bezt->h2 = HD_VECT; + bezt->weight = bp->weight; + bezt->radius = bp->radius; + bp++; + bezt++; + } + MEM_freeN(nu->bp); + nu->bp = NULL; + nu->pntsu = nr; + nu->type = CU_BEZIER; + BKE_nurb_handles_calc(nu); + } + else if (type == CU_NURBS) { + nu->type = CU_NURBS; + nu->orderu = 4; + nu->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */ + BKE_nurb_knot_calc_u(nu); + a = nu->pntsu * nu->pntsv; + bp = nu->bp; + while (a--) { + bp->vec[3] = 1.0; + bp++; + } + } + } + else if (nu->type == CU_BEZIER) { /* Bezier */ + if (type == CU_POLY || type == CU_NURBS) { + nr = use_handles ? (3 * nu->pntsu) : nu->pntsu; + nu->bp = MEM_callocN(nr * sizeof(BPoint), "setsplinetype"); + a = nu->pntsu; + bezt = nu->bezt; + bp = nu->bp; + while (a--) { + if ((type == CU_POLY && bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) || (use_handles == false)) { + /* vector handle becomes 1 poly vertice */ + copy_v3_v3(bp->vec, bezt->vec[1]); + bp->vec[3] = 1.0; + bp->f1 = bezt->f2; + if (use_handles) nr -= 2; + bp->radius = bezt->radius; + bp->weight = bezt->weight; + bp++; + } + else { + char *f = &bezt->f1; + for (c = 0; c < 3; c++, f++) { + copy_v3_v3(bp->vec, bezt->vec[c]); + bp->vec[3] = 1.0; + bp->f1 = *f; + bp->radius = bezt->radius; + bp->weight = bezt->weight; + bp++; + } + } + bezt++; + } + MEM_freeN(nu->bezt); + nu->bezt = NULL; + nu->pntsu = nr; + nu->pntsv = 1; + nu->orderu = 4; + nu->orderv = 1; + nu->type = type; + +#if 0 /* UNUSED */ + if (nu->flagu & CU_NURB_CYCLIC) c = nu->orderu - 1; + else c = 0; +#endif + + if (type == CU_NURBS) { + nu->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */ + nu->flagu |= CU_NURB_BEZIER; + BKE_nurb_knot_calc_u(nu); + } + } + } + else if (nu->type == CU_NURBS) { + if (type == CU_POLY) { + nu->type = CU_POLY; + if (nu->knotsu) MEM_freeN(nu->knotsu); /* python created nurbs have a knotsu of zero */ + nu->knotsu = NULL; + if (nu->knotsv) MEM_freeN(nu->knotsv); + nu->knotsv = NULL; + } + else if (type == CU_BEZIER) { /* to Bezier */ + nr = nu->pntsu / 3; + + if (nr < 2) { + return false; /* conversion impossible */ + } + else { + bezt = MEM_callocN(nr * sizeof(BezTriple), "setsplinetype2"); + nu->bezt = bezt; + a = nr; + bp = nu->bp; + while (a--) { + copy_v3_v3(bezt->vec[0], bp->vec); + bezt->f1 = bp->f1; + bp++; + copy_v3_v3(bezt->vec[1], bp->vec); + bezt->f2 = bp->f1; + bp++; + copy_v3_v3(bezt->vec[2], bp->vec); + bezt->f3 = bp->f1; + bezt->radius = bp->radius; + bezt->weight = bp->weight; + bp++; + bezt++; + } + MEM_freeN(nu->bp); + nu->bp = NULL; + MEM_freeN(nu->knotsu); + nu->knotsu = NULL; + nu->pntsu = nr; + nu->type = CU_BEZIER; + } + } + } + + return true; +} + /* Get edit nurbs or normal nurbs list */ ListBase *BKE_curve_nurbs_get(Curve *cu) { diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index bd72ec100fa..5c8a755b391 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3387,156 +3387,14 @@ static void findselectedNurbvert(ListBase *editnurb, Nurb **nu, BezTriple **bezt /***************** set spline type operator *******************/ -static int convertspline(short type, Nurb *nu) -{ - BezTriple *bezt; - BPoint *bp; - int a, c, nr; - - if (nu->type == CU_POLY) { - if (type == CU_BEZIER) { /* to Bezier with vecthandles */ - nr = nu->pntsu; - bezt = (BezTriple *)MEM_callocN(nr * sizeof(BezTriple), "setsplinetype2"); - nu->bezt = bezt; - a = nr; - bp = nu->bp; - while (a--) { - copy_v3_v3(bezt->vec[1], bp->vec); - bezt->f1 = bezt->f2 = bezt->f3 = bp->f1; - bezt->h1 = bezt->h2 = HD_VECT; - bezt->weight = bp->weight; - bezt->radius = bp->radius; - bp++; - bezt++; - } - MEM_freeN(nu->bp); - nu->bp = NULL; - nu->pntsu = nr; - nu->type = CU_BEZIER; - BKE_nurb_handles_calc(nu); - } - else if (type == CU_NURBS) { - nu->type = CU_NURBS; - nu->orderu = 4; - nu->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */ - BKE_nurb_knot_calc_u(nu); - a = nu->pntsu * nu->pntsv; - bp = nu->bp; - while (a--) { - bp->vec[3] = 1.0; - bp++; - } - } - } - else if (nu->type == CU_BEZIER) { /* Bezier */ - if (type == CU_POLY || type == CU_NURBS) { - nr = 3 * nu->pntsu; - nu->bp = MEM_callocN(nr * sizeof(BPoint), "setsplinetype"); - a = nu->pntsu; - bezt = nu->bezt; - bp = nu->bp; - while (a--) { - if (type == CU_POLY && bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) { - /* vector handle becomes 1 poly vertice */ - copy_v3_v3(bp->vec, bezt->vec[1]); - bp->vec[3] = 1.0; - bp->f1 = bezt->f2; - nr -= 2; - bp->radius = bezt->radius; - bp->weight = bezt->weight; - bp++; - } - else { - for (c = 0; c < 3; c++) { - copy_v3_v3(bp->vec, bezt->vec[c]); - bp->vec[3] = 1.0; - if (c == 0) bp->f1 = bezt->f1; - else if (c == 1) bp->f1 = bezt->f2; - else bp->f1 = bezt->f3; - bp->radius = bezt->radius; - bp->weight = bezt->weight; - bp++; - } - } - bezt++; - } - MEM_freeN(nu->bezt); - nu->bezt = NULL; - nu->pntsu = nr; - nu->pntsv = 1; - nu->orderu = 4; - nu->orderv = 1; - nu->type = type; - -#if 0 /* UNUSED */ - if (nu->flagu & CU_NURB_CYCLIC) c = nu->orderu - 1; - else c = 0; -#endif - - if (type == CU_NURBS) { - nu->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */ - nu->flagu |= CU_NURB_BEZIER; - BKE_nurb_knot_calc_u(nu); - } - } - } - else if (nu->type == CU_NURBS) { - if (type == CU_POLY) { - nu->type = CU_POLY; - if (nu->knotsu) MEM_freeN(nu->knotsu); /* python created nurbs have a knotsu of zero */ - nu->knotsu = NULL; - if (nu->knotsv) MEM_freeN(nu->knotsv); - nu->knotsv = NULL; - } - else if (type == CU_BEZIER) { /* to Bezier */ - nr = nu->pntsu / 3; - - if (nr < 2) { - return 1; /* conversion impossible */ - } - else { - bezt = MEM_callocN(nr * sizeof(BezTriple), "setsplinetype2"); - nu->bezt = bezt; - a = nr; - bp = nu->bp; - while (a--) { - copy_v3_v3(bezt->vec[0], bp->vec); - bezt->f1 = bp->f1; - bp++; - copy_v3_v3(bezt->vec[1], bp->vec); - bezt->f2 = bp->f1; - bp++; - copy_v3_v3(bezt->vec[2], bp->vec); - bezt->f3 = bp->f1; - bezt->radius = bp->radius; - bezt->weight = bp->weight; - bp++; - bezt++; - } - MEM_freeN(nu->bp); - nu->bp = NULL; - MEM_freeN(nu->knotsu); - nu->knotsu = NULL; - nu->pntsu = nr; - nu->type = CU_BEZIER; - } - } - } - - return 0; -} - -void ED_nurb_set_spline_type(Nurb *nu, int type) -{ - convertspline(type, nu); -} - static int set_spline_type_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); ListBase *editnurb = object_editcurve_get(obedit); Nurb *nu; - int changed = 0, type = RNA_enum_get(op->ptr, "type"); + bool change = false; + const bool use_handles = RNA_boolean_get(op->ptr, "use_handles"); + const int type = RNA_enum_get(op->ptr, "type"); if (type == CU_CARDINAL || type == CU_BSPLINE) { BKE_report(op->reports, RPT_ERROR, "Not yet implemented"); @@ -3545,14 +3403,14 @@ static int set_spline_type_exec(bContext *C, wmOperator *op) for (nu = editnurb->first; nu; nu = nu->next) { if (isNurbsel(nu)) { - if (convertspline(type, nu)) + if (BKE_nurb_type_convert(nu, type, use_handles) == false) BKE_report(op->reports, RPT_ERROR, "No conversion possible"); else - changed = 1; + change = true; } } - if (changed) { + if (change) { if (ED_curve_updateAnimPaths(obedit->data)) WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); @@ -3592,6 +3450,7 @@ void CURVE_OT_spline_type_set(wmOperatorType *ot) /* properties */ ot->prop = RNA_def_enum(ot->srna, "type", type_items, CU_POLY, "Type", "Spline type"); + RNA_def_boolean(ot->srna, "use_handles", 0, "Handles", "Use handles when converting bezier curves into polygons"); } /***************** set handle type operator *******************/ diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index a4d3c5e1ee5..e4c7a1edbcb 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -63,6 +63,7 @@ #include "BKE_library.h" #include "BKE_object.h" #include "BKE_report.h" +#include "BKE_scene.h" #include "BKE_tracking.h" #include "UI_interface.h" @@ -393,6 +394,7 @@ void GPENCIL_OT_active_frame_delete(wmOperatorType *ot) enum { GP_STROKECONVERT_PATH = 1, GP_STROKECONVERT_CURVE, + GP_STROKECONVERT_POLY, }; /* Defines for possible timing modes */ @@ -407,6 +409,7 @@ enum { static EnumPropertyItem prop_gpencil_convertmodes[] = { {GP_STROKECONVERT_PATH, "PATH", 0, "Path", ""}, {GP_STROKECONVERT_CURVE, "CURVE", 0, "Bezier Curve", ""}, + {GP_STROKECONVERT_POLY, "POLY", 0, "Polygon Curve", ""}, {0, NULL, 0, NULL, NULL} }; @@ -1278,13 +1281,14 @@ static void gp_stroke_norm_curve_weights(Curve *cu, float minmax_weights[2]) static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bGPDlayer *gpl, int mode, int norm_weights, float rad_fac, int link_strokes, tGpTimingData *gtd) { + struct Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); bGPDframe *gpf = gpencil_layer_getframe(gpl, CFRA, 0); bGPDstroke *gps, *prev_gps = NULL; Object *ob; Curve *cu; Nurb *nu = NULL; - Base *base = BASACT, *newbase = NULL; + Base *base_orig = BASACT, *base_new = NULL; float minmax_weights[2] = {1.0f, 0.0f}; /* camera framing */ @@ -1306,16 +1310,12 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG /* init the curve object (remove rotation and get curve data from it) * - must clear transforms set on object, as those skew our results */ - ob = BKE_object_add(scene, OB_CURVE); - zero_v3(ob->loc); - zero_v3(ob->rot); - cu = ob->data; + ob = BKE_object_add_only_object(bmain, OB_CURVE, gpl->info); + cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVE); + base_new = BKE_scene_base_add(scene, ob); + cu->flag |= CU_3D; - /* rename object and curve to layer name */ - rename_id((ID *)ob, gpl->info); - rename_id((ID *)cu, gpl->info); - gtd->inittime = ((bGPDstroke *)gpf->strokes.first)->inittime; /* add points to curve */ @@ -1344,6 +1344,7 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, gtd); break; case GP_STROKECONVERT_CURVE: + case GP_STROKECONVERT_POLY: /* convert after */ gp_stroke_to_bezier(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, gtd); break; default: @@ -1364,19 +1365,15 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG /* Create the path animation, if needed */ gp_stroke_path_animation(C, reports, cu, gtd); - /* Reset original object as active, else we can't edit operator's settings!!! */ - /* set layers OK */ - newbase = BASACT; - if (base) { - newbase->lay = base->lay; - ob->lay = newbase->lay; - } - - /* restore, BKE_object_add sets active */ - BASACT = base; - if (base) { - base->flag |= SELECT; + if (mode == GP_STROKECONVERT_POLY) { + for (nu = cu->nurb.first; nu; nu = nu->next) { + BKE_nurb_type_convert(nu, CU_POLY, false); + } } + + /* set the layer and select */ + base_new->lay = ob->lay = base_orig ? base_orig->lay : scene->lay; + base_new->flag = ob->flag = base_new->flag | SELECT; } /* --- */ diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index 80b10668062..1d26204095c 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -68,7 +68,6 @@ bool mouse_nurb(struct bContext *C, const int mval[2], bool extend, bool dese struct Nurb *add_nurbs_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newob); int isNurbsel(struct Nurb *nu); -void ED_nurb_set_spline_type(struct Nurb *nu, int type); int join_curve_exec(struct bContext *C, struct wmOperator *op); diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index dba33bb9ab5..479af956591 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -281,7 +281,7 @@ static int rna_Nurb_length(PointerRNA *ptr) static void rna_Nurb_type_set(PointerRNA *ptr, int value) { Nurb *nu = (Nurb *)ptr->data; - ED_nurb_set_spline_type(nu, value); + BKE_nurb_type_convert(nu, value, true); } static void rna_BPoint_array_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) |