[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