[Bf-blender-cvs] [01cac12522e] temp-gpencil-bezier-stroke-type: GPencil: Initial curve pen functionality
Falk David
noreply at git.blender.org
Sat Mar 20 12:32:15 CET 2021
Commit: 01cac12522e58913dfa79e6e03a19f20ce068cda
Author: Falk David
Date: Wed Jan 20 20:03:15 2021 +0100
Branches: temp-gpencil-bezier-stroke-type
https://developer.blender.org/rB01cac12522e58913dfa79e6e03a19f20ce068cda
GPencil: Initial curve pen functionality
===================================================================
M source/blender/draw/engines/overlay/overlay_gpencil.c
M source/blender/editors/gpencil/gpencil_curve_draw.c
===================================================================
diff --git a/source/blender/draw/engines/overlay/overlay_gpencil.c b/source/blender/draw/engines/overlay/overlay_gpencil.c
index b5f6d973692..558f8927a74 100644
--- a/source/blender/draw/engines/overlay/overlay_gpencil.c
+++ b/source/blender/draw/engines/overlay/overlay_gpencil.c
@@ -139,7 +139,7 @@ void OVERLAY_edit_gpencil_cache_init(OVERLAY_Data *vedata)
}
/* Handles and curve point for Edit mode. */
- if (GPENCIL_EDIT_MODE(gpd)) {
+ if (GPENCIL_EDIT_MODE(gpd) || GPENCIL_PAINT_MODE(gpd)) {
DRWState state = DRW_STATE_WRITE_COLOR;
DRW_PASS_CREATE(psl->edit_gpencil_curve_ps, state | pd->clipping_state);
diff --git a/source/blender/editors/gpencil/gpencil_curve_draw.c b/source/blender/editors/gpencil/gpencil_curve_draw.c
index 7b4956a867e..37e0d7a450d 100644
--- a/source/blender/editors/gpencil/gpencil_curve_draw.c
+++ b/source/blender/editors/gpencil/gpencil_curve_draw.c
@@ -25,15 +25,24 @@
#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLT_translation.h"
+
+#include "DNA_brush_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
+#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
+#include "BKE_gpencil_curve.h"
#include "BKE_gpencil_geom.h"
+#include "BKE_main.h"
+#include "BKE_paint.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -44,6 +53,7 @@
#include "ED_gpencil.h"
#include "ED_screen.h"
+#include "ED_view3d.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@@ -51,50 +61,268 @@
#include "gpencil_intern.h"
/* ------------------------------------------------------------------------- */
+/* Structs & enums */
+typedef enum eGPDcurve_draw_state {
+ IN_MOVE = 0,
+ IN_SET_VECTOR = 1,
+ IN_DRAG_ALIGNED_HANDLE = 2,
+ IN_DRAG_FREE_HANDLE = 3,
+} eGPDcurve_draw_state;
typedef struct tGPDcurve_draw {
+ Scene *scene;
+ ARegion *region;
+ Object *ob;
bGPdata *gpd;
+ bGPDlayer *gpl;
bGPDframe *gpf;
bGPDstroke *gps;
bGPDcurve *gpc;
+ int cframe;
+
+ GP_SpaceConversion gsc;
+
+ /* imval of current event */
int imval[2];
- short flag;
+ /* imval of previous event */
+ int imval_prev[2];
+ /* imval when mouse was last pressed */
+ int imval_start[2];
+ /* imval when mouse was last released */
+ int imval_end[2];
+ bool is_mouse_down;
+
+ bool is_cyclic;
+
+ eGPDcurve_draw_state state;
} tGPDcurve_draw;
-typedef enum eGPDcurve_draw_state {
- MOUSE_DOWN = (1 << 0),
-} eGPDcurve_draw_state;
+/* Forward declaration */
+static void gpencil_curve_draw_init(bContext *C, wmOperator *op, const wmEvent *event);
+static void gpencil_curve_draw_update(bContext *C, tGPDcurve_draw *tcd);
+static void gpencil_curve_draw_confirm(bContext *C, wmOperator *op, tGPDcurve_draw *tcd);
+static void gpencil_curve_draw_exit(bContext *C, wmOperator *op);
+
+/* ------------------------------------------------------------------------- */
+/* Helper functions */
+
+static void debug_print_state(tGPDcurve_draw *tcd)
+{
+ const char *state_str[] = {
+ "MOVE",
+ "VECTOR",
+ "ALIGN",
+ "FREE",
+ };
+ printf("State: %s\tMouse x=%d\ty=%d\tpressed:%s\n",
+ state_str[tcd->state],
+ tcd->imval[0],
+ tcd->imval[1],
+ (tcd->is_mouse_down) ? "TRUE" : "FALSE");
+}
+
+static void gpencil_project_mval_to_v3(
+ Scene *scene, ARegion *region, Object *ob, const int mval_i[2], float r_out[3])
+{
+ ToolSettings *ts = scene->toolsettings;
+ float mval_f[2], mval_prj[2], rvec[3], dvec[3], zfac;
+ copy_v2fl_v2i(mval_f, mval_i);
+
+ ED_gpencil_drawing_reference_get(scene, ob, ts->gpencil_v3d_align, rvec);
+ zfac = ED_view3d_calc_zfac(region->regiondata, rvec, NULL);
+
+ if (ED_view3d_project_float_global(region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
+ V3D_PROJ_RET_OK) {
+ sub_v2_v2v2(mval_f, mval_prj, mval_f);
+ ED_view3d_win_to_delta(region, mval_f, dvec, zfac);
+ sub_v3_v3v3(r_out, rvec, dvec);
+ }
+ else {
+ zero_v3(r_out);
+ }
+}
-void gpencil_curve_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
+static void gpencil_push_new_curve_point(tGPDcurve_draw *tcd)
{
+ bGPDcurve *gpc = tcd->gpc;
+ int old_num_points = gpc->tot_curve_points;
+ int new_num_points = old_num_points + 1;
+ gpc->tot_curve_points = new_num_points;
+
+ gpc->curve_points = MEM_recallocN(gpc->curve_points, sizeof(bGPDcurve_point) * new_num_points);
+
+ bGPDcurve_point *old_last = &gpc->curve_points[gpc->tot_curve_points - 2];
+ bGPDcurve_point *new_last = &gpc->curve_points[gpc->tot_curve_points - 1];
+ memcpy(new_last, old_last, sizeof(bGPDcurve_point));
+
+ new_last->bezt.h1 = new_last->bezt.h2 = HD_VECT;
+
+ old_last->flag &= ~GP_CURVE_POINT_SELECT;
+ BEZT_DESEL_ALL(&old_last->bezt);
+
+ BKE_gpencil_stroke_update_geometry_from_editcurve(
+ tcd->gps, tcd->gpd->curve_edit_resolution, true);
+}
+
+static void gpencil_set_handle_type_last_point(tGPDcurve_draw *tcd, eBezTriple_Handle type)
+{
+ bGPDcurve *gpc = tcd->gpc;
+ bGPDcurve_point *cpt = &gpc->curve_points[gpc->tot_curve_points - 1];
+ cpt->bezt.h1 = cpt->bezt.h2 = type;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Main drawing functions */
+
+static void gpencil_curve_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ARegion *region = CTX_wm_region(C);
+ Object *ob = CTX_data_active_object(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
+ ToolSettings *ts = scene->toolsettings;
+ Paint *paint = &ts->gp_paint->paint;
+ int cfra = CFRA;
+
+ /* Allocate temp curve draw data. */
tGPDcurve_draw *tcd = MEM_callocN(sizeof(tGPDcurve_draw), __func__);
+ tcd->scene = scene;
+ tcd->region = region;
tcd->gpd = gpd;
- copy_v2_v2_int(tcd->imval, event->mval);
+ tcd->ob = ob;
/* Initialize mouse state */
- tcd->flag |= event->val == KM_PRESS ? MOUSE_DOWN : 0;
+ copy_v2_v2_int(tcd->imval, event->mval);
+ copy_v2_v2_int(tcd->imval_prev, event->mval);
+ tcd->is_mouse_down = (event->val == KM_PRESS);
+ tcd->state = IN_MOVE;
+
+ if ((paint->brush == NULL) || (paint->brush->gpencil_settings == NULL)) {
+ BKE_brush_gpencil_paint_presets(bmain, ts, true);
+ }
+ Brush *brush = BKE_paint_toolslots_brush_get(paint, 0);
+ BKE_brush_tool_set(brush, paint, 0);
+ BKE_paint_brush_set(paint, brush);
+ BrushGpencilSettings *brush_settings = brush->gpencil_settings;
+ // tcd->brush = brush;
+
+ /* Get active layer or create a new one. */
+ bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
+ if (gpl == NULL) {
+ gpl = BKE_gpencil_layer_addnew(tcd->gpd, DATA_("Curve"), true);
+ }
+ tcd->gpl = gpl;
+
+ /* Recalculate layer transform matrix to avoid problems if props are animated. */
+ loc_eul_size_to_mat4(
+ tcd->gpl->layer_mat, tcd->gpl->location, tcd->gpl->rotation, tcd->gpl->scale);
+ invert_m4_m4(tcd->gpl->layer_invmat, tcd->gpl->layer_mat);
+
+ /* Get current frame or create new one. */
+ short add_frame_mode;
+ if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
+ add_frame_mode = GP_GETFRAME_ADD_COPY;
+ }
+ else {
+ add_frame_mode = GP_GETFRAME_ADD_NEW;
+ }
+
+ tcd->cframe = cfra;
+ bool need_tag = tcd->gpl->actframe == NULL;
+ bGPDframe *gpf = BKE_gpencil_layer_frame_get(tcd->gpl, tcd->cframe, add_frame_mode);
+ if (need_tag) {
+ DEG_id_tag_update(&tcd->gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ }
+ tcd->gpf = gpf;
+
+ /* Create stroke. */
+ int mat_idx = BKE_gpencil_object_material_get_index_from_brush(ob, brush);
+ bGPDstroke *gps = BKE_gpencil_stroke_new(mat_idx, 1, brush->size);
+ gps->thickness = brush->size;
+ gps->hardeness = brush_settings->hardeness;
+ copy_v2_v2(gps->aspect_ratio, brush_settings->aspect_ratio);
+
+ float first_pt[3];
+ gpencil_project_mval_to_v3(scene, region, ob, tcd->imval, first_pt);
+ gps->points[0].pressure = 1.0f;
+ gps->points[0].strength = 1.0f;
+ copy_v3_v3(&gps->points[0].x, first_pt);
+
+ BLI_addtail(&gpf->strokes, gps);
+ tcd->gps = gps;
+
+ /* Create editcurve. */
+ BKE_gpencil_stroke_editcurve_update(tcd->gpd, tcd->gpl, tcd->gps);
+ bGPDcurve_point *cpt = &gps->editcurve->curve_points[0];
+ cpt->flag |= GP_CURVE_POINT_SELECT;
+ BEZT_SEL_ALL(&cpt->bezt);
+ gps->editcurve->flag |= GP_CURVE_SELECT;
+ tcd->gpc = tcd->gps->editcurve;
+
+ /* Calc geometry data. */
+ BKE_gpencil_stroke_geometry_update(tcd->gpd, gps);
+
+ /* Initialize space conversion. */
+ gpencil_point_conversion_init(C, &tcd->gsc);
+
+ gpencil_curve_draw_update(C, tcd);
op->customdata = tcd;
}
-void gpencil_curve_draw_update(bContext *C, tGPDcurve_draw *tcd)
+static void gpencil_curve_draw_update(bContext *C, tGPDcurve_draw *tcd)
{
- printf("Update curve draw\n");
- bGPdata *gpd = tgpi->gpd;
+ // printf("Update curve draw\n");
+ bGPdata *gpd = tcd->gpd;
+ bGPDstroke *gps = tcd->gps;
+ bGPDcurve *gpc = tcd->gpc;
+ int tot_points = gpc->tot_curve_points;
+ bGPDcurve_point *cpt = &gpc->curve_points[tot_points - 1];
+ BezTriple *bezt = &cpt->bezt;
+
+ float co[3];
+ switch (tcd->state) {
+ case IN_MOVE: {
+ gpencil_project_mval_to_v3(tcd->scene, tcd->region, tcd->ob, tcd->imval, co);
+ copy_v3_v3(&bezt->vec[1], co);
+ BKE_gpencil_editcurve_recalculate_handles(gps);
+ break;
+ }
+ case IN_DRAG_ALIGNED_HANDLE: {
+ float vec[3];
+ gpencil_project_mval_to_v3(tcd->scene, tcd->region, tcd->ob, tcd->imval, co);
+ sub_v3_v3v3(vec, &bezt->vec[1], co);
+ add_v3_v3(vec, &bezt->vec[1]);
+ copy_v3_v3(&bezt->vec[0], vec);
+ copy_v3_v3(&bezt->vec[2], co);
+ // BKE_gpencil_editcurve_recalculate_handles(gps);
+ break;
+ }
+ case IN_DRAG_FREE_HANDLE: {
+ gpencil_project_mval_to_v3(tcd->scene, tcd->region, tcd->ob, tcd->imval, co);
+ copy_v3_v3(&bezt->vec[2], co);
+ break;
+ }
+ default:
+ break;
+ }
+
+ BKE_gpencil_stroke_update_geometry_from_editcurve(gps, gpd->curve_edit_resolution, true);
+ BKE_gpencil_stroke_geometry_update(gpd, gps);
DEG_id_tag_update(&gpd->id, ID_RECALC_COPY_ON_WRITE);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list