diff options
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_primitive.c')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_primitive.c | 252 |
1 files changed, 165 insertions, 87 deletions
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 20f959e2e2c..a4c8fc770e2 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -109,7 +109,15 @@ /* ************************************************ */ /* Core/Shared Utilities */ - +static const EnumPropertyItem gpencil_primitive_type[] = { + {GP_STROKE_BOX, "BOX", 0, "Box", ""}, + {GP_STROKE_LINE, "LINE", 0, "Line", ""}, + {GP_STROKE_POLYLINE, "POLYLINE", 0, "Polyline", ""}, + {GP_STROKE_CIRCLE, "CIRCLE", 0, "Circle", ""}, + {GP_STROKE_ARC, "ARC", 0, "Arc", ""}, + {GP_STROKE_CURVE, "CURVE", 0, "Curve", ""}, + {0, NULL, 0, NULL, NULL}, +}; /* clear the session buffers (call this before AND after a paint operation) */ static void gpencil_session_validatebuffer(tGPDprimitive *p) { @@ -378,7 +386,10 @@ static void gpencil_primitive_add_segment(tGPDprimitive *tgpi) } /* Helper: set control point */ -static void gpencil_primitive_set_cp(tGPDprimitive *tgpi, float p[2], float color[4], int size) +static void gpencil_primitive_set_cp(tGPDprimitive *tgpi, + const float p[2], + float color[4], + int size) { if (tgpi->flag == IN_PROGRESS) { return; @@ -424,19 +435,20 @@ static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi } else if (tgpi->type == GP_STROKE_CIRCLE) { BLI_strncpy(msg_str, - TIP_("Circle: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust edge " + TIP_("Circle: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust subdivision " "number, Shift to square, Alt to center"), UI_MAX_DRAW_STR); } else if (tgpi->type == GP_STROKE_ARC) { - BLI_strncpy(msg_str, - TIP_("Arc: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust edge number, " - "Shift to square, Alt to center, M: Flip, E: extrude"), - UI_MAX_DRAW_STR); + BLI_strncpy( + msg_str, + TIP_("Arc: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust subdivision number, " + "Shift to square, Alt to center, M: Flip, E: extrude"), + UI_MAX_DRAW_STR); } else if (tgpi->type == GP_STROKE_CURVE) { BLI_strncpy(msg_str, - TIP_("Curve: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust edge " + TIP_("Curve: ESC to cancel, Enter/MMB to confirm, WHEEL/+- to adjust subdivision " "number, Shift to square, Alt to center, E: extrude"), UI_MAX_DRAW_STR); } @@ -516,16 +528,23 @@ static void gpencil_primitive_rectangle(tGPDprimitive *tgpi, tGPspoint *points2D coords[4][0] = tgpi->start[0]; coords[4][1] = tgpi->start[1]; - const float step = 1.0f / (float)(tgpi->tot_edges); - int i = tgpi->tot_stored_edges; - - for (int j = 0; j < 4; j++) { - float a = 0.0f; - for (int k = 0; k < tgpi->tot_edges; k++) { - tGPspoint *p2d = &points2D[i]; - interp_v2_v2v2(&p2d->x, coords[j], coords[j + 1], a); - a += step; - i++; + if (tgpi->tot_edges == 1) { + for (int j = 0; j < 4; j++) { + tGPspoint *p2d = &points2D[j]; + copy_v2_v2(&p2d->x, coords[j]); + } + } + else { + const float step = 1.0f / (float)(tgpi->tot_edges); + int i = tgpi->tot_stored_edges; + for (int j = 0; j < 4; j++) { + float a = 0.0f; + for (int k = 0; k < tgpi->tot_edges; k++) { + tGPspoint *p2d = &points2D[i]; + interp_v2_v2v2(&p2d->x, coords[j], coords[j + 1], a); + a += step; + i++; + } } } @@ -696,9 +715,9 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) bool is_depth = (bool)(*align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE)); const bool is_camera = (bool)(ts->gp_sculpt.lock_axis == 0) && (tgpi->rv3d->persp == RV3D_CAMOB) && (!is_depth); - const bool is_vertex_stroke = GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush); if (tgpi->type == GP_STROKE_BOX) { + tgpi->tot_edges--; gps->totpoints = (tgpi->tot_edges * 4 + tgpi->tot_stored_edges); } else { @@ -714,7 +733,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) /* compute screen-space coordinates for points */ tGPspoint *points2D = tgpi->points; - if (tgpi->tot_edges > 1) { + if (tgpi->tot_edges > 0) { switch (tgpi->type) { case GP_STROKE_BOX: gpencil_primitive_rectangle(tgpi, points2D); @@ -742,13 +761,13 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) gpencil_session_validatebuffer(tgpi); gpencil_init_colors(tgpi); if (gset->flag & GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE) { - BKE_curvemapping_initialize(ts->gp_sculpt.cur_primitive); + BKE_curvemapping_init(ts->gp_sculpt.cur_primitive); } if (brush_settings->flag & GP_BRUSH_USE_JITTER_PRESSURE) { - BKE_curvemapping_initialize(brush_settings->curve_jitter); + BKE_curvemapping_init(brush_settings->curve_jitter); } if (brush_settings->flag & GP_BRUSH_USE_STRENGTH_PRESSURE) { - BKE_curvemapping_initialize(brush_settings->curve_strength); + BKE_curvemapping_init(brush_settings->curve_strength); } /* get an array of depths, far depths are blended */ @@ -1021,12 +1040,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) pt->time = 0.0f; pt->flag = 0; pt->uv_fac = tpt->uv_fac; - if (is_vertex_stroke) { - copy_v4_v4(pt->vert_color, tpt->vert_color); - } - else { - zero_v4(pt->vert_color); - } + ED_gpencil_point_vertex_color_set(ts, brush, pt, tpt); if (gps->dvert != NULL) { MDeformVert *dvert = &gps->dvert[i]; @@ -1092,7 +1106,7 @@ static void gpencil_primitive_update(bContext *C, wmOperator *op, tGPDprimitive gpencil_primitive_update_strokes(C, tgpi); } -/* Initialise mouse points */ +/* Initialize mouse points. */ static void gpencil_primitive_interaction_begin(tGPDprimitive *tgpi, const wmEvent *event) { copy_v2fl_v2i(tgpi->mval, event->mval); @@ -1214,31 +1228,10 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op) tgpi->curve = false; } - /* set default edge count */ - switch (tgpi->type) { - case GP_STROKE_POLYLINE: { - RNA_int_set(op->ptr, "edges", 8); - break; - } - case GP_STROKE_LINE: { - RNA_int_set(op->ptr, "edges", 8); - break; - } - case GP_STROKE_BOX: { - RNA_int_set(op->ptr, "edges", 8); - break; - } - case GP_STROKE_CIRCLE: { - RNA_int_set(op->ptr, "edges", 96); - break; - } - default: { - RNA_int_set(op->ptr, "edges", 64); - break; - } - } - tgpi->tot_stored_edges = 0; + + tgpi->subdiv = RNA_int_get(op->ptr, "subdivision"); + RNA_int_set(op->ptr, "edges", tgpi->subdiv + 2); tgpi->tot_edges = RNA_int_get(op->ptr, "edges"); tgpi->flag = IDLE; tgpi->lock_axis = ts->gp_sculpt.lock_axis; @@ -1354,11 +1347,6 @@ static void gpencil_primitive_interaction_end(bContext *C, } } - /* Close stroke with geometry */ - if ((tgpi->type == GP_STROKE_BOX) || (tgpi->type == GP_STROKE_CIRCLE)) { - BKE_gpencil_stroke_close(gps); - } - DEG_id_tag_update(&tgpi->gpd->id, ID_RECALC_COPY_ON_WRITE); DEG_id_tag_update(&tgpi->gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); @@ -1632,9 +1620,12 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e case RIGHTMOUSE: { if (event->val == KM_PRESS) { tgpi->flag = IDLE; + int last_edges = tgpi->tot_edges; tgpi->tot_edges = tgpi->tot_stored_edges ? 1 : 0; + RNA_int_set(op->ptr, "edges", tgpi->tot_edges); gpencil_primitive_update_strokes(C, tgpi); gpencil_primitive_interaction_end(C, op, win, tgpi); + RNA_int_set(op->ptr, "edges", last_edges); return OPERATOR_FINISHED; } break; @@ -1961,22 +1952,45 @@ static void gpencil_primitive_cancel(bContext *C, wmOperator *op) gpencil_primitive_exit(C, op); } -void GPENCIL_OT_primitive(wmOperatorType *ot) +static void gpencil_primitive_common_props(wmOperatorType *ot, int subdiv, int type) { - static EnumPropertyItem primitive_type[] = { - {GP_STROKE_BOX, "BOX", 0, "Box", ""}, - {GP_STROKE_LINE, "LINE", 0, "Line", ""}, - {GP_STROKE_POLYLINE, "POLYLINE", 0, "Polyline", ""}, - {GP_STROKE_CIRCLE, "CIRCLE", 0, "Circle", ""}, - {GP_STROKE_ARC, "ARC", 0, "Arc", ""}, - {GP_STROKE_CURVE, "CURVE", 0, "Curve", ""}, - {0, NULL, 0, NULL, NULL}, - }; + PropertyRNA *prop; + + prop = RNA_def_int(ot->srna, + "subdivision", + subdiv, + 0, + MAX_EDGES, + "Subdivisions", + "Number of subdivision by edges", + 0, + MAX_EDGES); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + /* Internal prop. */ + prop = RNA_def_int(ot->srna, + "edges", + MIN_EDGES, + MIN_EDGES, + MAX_EDGES, + "Edges", + "Number of points by edge", + MIN_EDGES, + MAX_EDGES); + RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); + + RNA_def_enum(ot->srna, "type", gpencil_primitive_type, type, "Type", "Type of shape"); + prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", ""); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); +} + +void GPENCIL_OT_primitive_box(wmOperatorType *ot) +{ /* identifiers */ - ot->name = "Grease Pencil Shapes"; - ot->idname = "GPENCIL_OT_primitive"; - ot->description = "Create predefined grease pencil stroke shapes"; + ot->name = "Grease Pencil Box Shape"; + ot->idname = "GPENCIL_OT_primitive_box"; + ot->description = "Create predefined grease pencil stroke box shapes"; /* callbacks */ ot->invoke = gpencil_primitive_invoke; @@ -1985,24 +1999,88 @@ void GPENCIL_OT_primitive(wmOperatorType *ot) ot->poll = gpencil_primitive_add_poll; /* flags */ - ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* properties */ - PropertyRNA *prop; + gpencil_primitive_common_props(ot, 3, GP_STROKE_BOX); +} - prop = RNA_def_int(ot->srna, - "edges", - 4, - MIN_EDGES, - MAX_EDGES, - "Edges", - "Number of polygon edges", - MIN_EDGES, - MAX_EDGES); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); +void GPENCIL_OT_primitive_line(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Grease Pencil Line Shape"; + ot->idname = "GPENCIL_OT_primitive_line"; + ot->description = "Create predefined grease pencil stroke lines"; - RNA_def_enum(ot->srna, "type", primitive_type, GP_STROKE_BOX, "Type", "Type of shape"); + /* callbacks */ + ot->invoke = gpencil_primitive_invoke; + ot->modal = gpencil_primitive_modal; + ot->cancel = gpencil_primitive_cancel; + ot->poll = gpencil_primitive_add_poll; - prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", ""); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + + /* properties */ + gpencil_primitive_common_props(ot, 6, GP_STROKE_LINE); +} + +void GPENCIL_OT_primitive_polyline(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Grease Pencil Polyline Shape"; + ot->idname = "GPENCIL_OT_primitive_polyline"; + ot->description = "Create predefined grease pencil stroke polylines"; + + /* callbacks */ + ot->invoke = gpencil_primitive_invoke; + ot->modal = gpencil_primitive_modal; + ot->cancel = gpencil_primitive_cancel; + ot->poll = gpencil_primitive_add_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + + /* properties */ + gpencil_primitive_common_props(ot, 6, GP_STROKE_POLYLINE); +} + +void GPENCIL_OT_primitive_circle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Grease Pencil Circle Shape"; + ot->idname = "GPENCIL_OT_primitive_circle"; + ot->description = "Create predefined grease pencil stroke circle shapes"; + + /* callbacks */ + ot->invoke = gpencil_primitive_invoke; + ot->modal = gpencil_primitive_modal; + ot->cancel = gpencil_primitive_cancel; + ot->poll = gpencil_primitive_add_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + + /* properties */ + gpencil_primitive_common_props(ot, 94, GP_STROKE_CIRCLE); +} + +void GPENCIL_OT_primitive_curve(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Grease Pencil Curve Shape"; + ot->idname = "GPENCIL_OT_primitive_curve"; + ot->description = "Create predefined grease pencil stroke curve shapes"; + + /* callbacks */ + ot->invoke = gpencil_primitive_invoke; + ot->modal = gpencil_primitive_modal; + ot->cancel = gpencil_primitive_cancel; + ot->poll = gpencil_primitive_add_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + + /* properties */ + gpencil_primitive_common_props(ot, 62, GP_STROKE_CURVE); } |