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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-03-20 19:01:15 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-03-20 19:01:15 +0400
commitd4af049fabd4c388c1b1ed6c031030dac2efc0ec (patch)
tree763f96d5efba006bef1031633df90bac0cd68eae /source
parentf88e48fa55497c1f7d977f36a48555a42625a495 (diff)
add option to convert grease pencil into poly line directly.
Without this, bezier curves at 12 resolution are very high detail for many tasks when converted from freehand strokes. so add the option to convert 1:1 grease pencil points to curve polygons. also add use_handles option to curve conversion which is used when converting beziers to poly lines.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_curve.h1
-rw-r--r--source/blender/blenkernel/intern/curve.c138
-rw-r--r--source/blender/editors/curve/editcurve.c155
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c39
-rw-r--r--source/blender/editors/include/ED_curve.h1
-rw-r--r--source/blender/makesrna/intern/rna_curve.c2
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)