[Bf-blender-cvs] [237b77954aa] greasepencil-refactor: GPencil: Add collision checking for Sculpt

Antonio Vazquez noreply at git.blender.org
Sun Feb 2 16:43:54 CET 2020


Commit: 237b77954aa27ec613b820d32d7fba07efb240b1
Author: Antonio Vazquez
Date:   Sat Feb 1 20:14:33 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB237b77954aa27ec613b820d32d7fba07efb240b1

GPencil: Add collision checking for Sculpt

Instead to check all points, first a general stroke checking is done in order to avoid reading thousands of points.

===================================================================

M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/editors/gpencil/gpencil_sculpt_paint.c
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/editors/include/ED_gpencil.h
M	source/blender/makesdna/DNA_gpencil_types.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 5b2ee2d6f76..079d964c9bc 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -224,6 +224,7 @@ bool BKE_gpencil_stroke_select_check(const struct bGPDstroke *gps);
 
 struct BoundBox *BKE_gpencil_boundbox_get(struct Object *ob);
 void BKE_gpencil_centroid_3d(struct bGPdata *gpd, float r_centroid[3]);
+void BKE_gpencil_stroke_collision_get(struct bGPDstroke *gps);
 
 /* vertex groups */
 void BKE_gpencil_dvert_ensure(struct bGPDstroke *gps);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 73128818748..a9675121a67 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1327,6 +1327,13 @@ void BKE_gpencil_centroid_3d(bGPdata *gpd, float r_centroid[3])
   mul_v3_v3fl(r_centroid, tot, 0.5f);
 }
 
+/* Compute stroke collision detection center and radius. */
+void BKE_gpencil_stroke_collision_get(bGPDstroke *gps)
+{
+  INIT_MINMAX(gps->collision_min, gps->collision_max);
+  BKE_gpencil_stroke_minmax(gps, false, gps->collision_min, gps->collision_max);
+}
+
 /* create bounding box values */
 static void boundbox_gpencil(Object *ob)
 {
@@ -2794,6 +2801,9 @@ void BKE_gpencil_stroke_geometry_update(bGPDstroke *gps)
 
   /* calc uv data along the stroke */
   BKE_gpencil_stroke_uv_update(gps);
+
+  /* Calc collision center and radius. */
+  BKE_gpencil_stroke_collision_get(gps);
 }
 
 float BKE_gpencil_stroke_length(const bGPDstroke *gps, bool use_3d)
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index f3c7871de2c..00b0d84f20c 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -310,6 +310,8 @@ static void gpencil_update_geometry(bGPdata *gpd)
       }
     }
   }
+  DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+  WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
 }
 
 /* ************************************************ */
@@ -1495,6 +1497,12 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
   bool include_last = false;
   bool changed = false;
   float rot_eval = 0.0f;
+
+  /* Check if the stroke collide with brush. */
+  if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
+    return false;
+  }
+
   if (gps->totpoints == 1) {
     bGPDspoint pt_temp;
     pt = &gps->points[0];
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index b9297fd97bf..6654f1eea94 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -2556,3 +2556,47 @@ void ED_gpencil_sbuffer_vertex_color_set(ToolSettings *ts, Brush *brush, bGPdata
     zero_v4(gpd->runtime.vert_color);
   }
 }
+
+/* Check if the stroke collides with brush. */
+bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
+                                       bGPDstroke *gps,
+                                       float mval[2],
+                                       const int radius,
+                                       const float diff_mat[4][4])
+{
+  bGPDspoint pt_dummy, pt_dummy_ps;
+  float gps_collision_min[2] = {0.0f};
+  float gps_collision_max[2] = {0.0f};
+  float collision_center[2] = {0.0f};
+  float zerov3[3];
+
+  int mouse[2], center[2];
+
+  /* Check we have something to use (only for old files). */
+  if (equals_v3v3(zerov3, gps->collision_min)) {
+    BKE_gpencil_stroke_collision_get(gps);
+  }
+
+  /* Convert bound box to 2d */
+  copy_v3_v3(&pt_dummy.x, gps->collision_min);
+  gp_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps);
+  gp_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &gps_collision_min[0], &gps_collision_min[1]);
+
+  copy_v3_v3(&pt_dummy.x, gps->collision_max);
+  gp_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps);
+  gp_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &gps_collision_max[0], &gps_collision_max[1]);
+
+  /* Calc collision center and radius in 2d. */
+  add_v2_v2v2(collision_center, gps_collision_min, gps_collision_max);
+  mul_v2_v2fl(collision_center, collision_center, 0.5f);
+
+  int collision_radius = (int)(len_v2v2(gps_collision_min, gps_collision_max) * 0.5f);
+  round_v2i_v2fl(center, collision_center);
+  round_v2i_v2fl(mouse, mval);
+
+  if (len_v2v2_int(mouse, center) > radius + collision_radius) {
+    return false;
+  }
+
+  return true;
+}
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 40cc7486490..b5d53045ca2 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -35,6 +35,7 @@ struct bGPDspoint;
 struct bGPDstroke;
 struct bGPdata;
 struct tGPspoint;
+struct GP_SpaceConversion;
 
 struct ARegion;
 struct Depsgraph;
@@ -303,4 +304,10 @@ void ED_gpencil_sbuffer_vertex_color_set(struct ToolSettings *ts,
                                          struct Brush *brush,
                                          struct bGPdata *gpd);
 
+bool ED_gpencil_stroke_check_collision(struct GP_SpaceConversion *gsc,
+                                       struct bGPDstroke *gps,
+                                       float mval[2],
+                                       const int radius,
+                                       const float diff_mat[4][4]);
+
 #endif /*  __ED_GPENCIL_H__ */
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 59795acc88b..3a012ce0949 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -229,6 +229,11 @@ typedef struct bGPDstroke {
   /** Factor of opacity for Fill color (used by opacity modifier). */
   float fill_opacity_fac;
 
+  /** Min of the collision bound box used to speedup painting. */
+  float collision_min[3];
+  /** Max of the collision bound box used to speedup painting. */
+  float collision_max[3];
+
   /** UV rotation */
   float uv_rotation;
   /** UV translation (X and Y axis) */
@@ -261,7 +266,7 @@ typedef enum eGPDstroke_Flag {
    * fill color for stroke and no fill area */
   GP_STROKE_NOFILL = (1 << 8),
   /* Tag for update geometry */
-  GP_STROKE_TAG = (1 << 9),
+  GP_STROKE_TAG = (1 << 14),
   /* only for use with stroke-buffer (while drawing eraser) */
   GP_STROKE_ERASER = (1 << 15),
 } eGPDstroke_Flag;



More information about the Bf-blender-cvs mailing list