[Bf-blender-cvs] [960455b2322] greasepencil-object: GP: New Cutter tool

Antonioya noreply at git.blender.org
Tue Jan 1 17:41:22 CET 2019


Commit: 960455b2322c28f4f3e9b016df9240fc2fdb489b
Author: Antonioya
Date:   Tue Jan 1 17:41:09 2019 +0100
Branches: greasepencil-object
https://developer.blender.org/rB960455b2322c28f4f3e9b016df9240fc2fdb489b

GP: New Cutter tool

This tool is used to cut the extremes.

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	release/scripts/startup/bl_ui/space_topbar.py
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/editors/gpencil/annotate_paint.c
M	source/blender/editors/gpencil/gpencil_edit.c
M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_merge.c
M	source/blender/editors/gpencil/gpencil_ops.c
M	source/blender/editors/gpencil/gpencil_paint.c
M	source/blender/editors/gpencil/gpencil_select.c
M	source/blender/editors/gpencil/gpencil_utils.c
M	source/blender/editors/include/ED_gpencil.h

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index f7cd09225b5..55f7047a1be 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5717,6 +5717,15 @@ def km_3d_view_tool_paint_gpencil_curve(params):
         ]},
     )
 
+def km_3d_view_tool_paint_gpencil_cutter(params):
+    return (
+        "3D View Tool: Paint Gpencil, Cutter",
+        {"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
+        {"items": [
+            ("gpencil.stroke_cutter", {"type": params.tool_mouse, "value": 'PRESS'}, None),
+        ]},
+    )
+
 def km_3d_view_tool_edit_gpencil_select(params):
     return (
         "3D View Tool: Edit Gpencil, Select",
@@ -6027,6 +6036,7 @@ def generate_keymaps(params=None):
         km_3d_view_tool_paint_gpencil_circle(params),
         km_3d_view_tool_paint_gpencil_arc(params),
         km_3d_view_tool_paint_gpencil_curve(params),
+        km_3d_view_tool_paint_gpencil_cutter(params),
         km_3d_view_tool_edit_gpencil_select(params),
         km_3d_view_tool_edit_gpencil_select_box(params),
         km_3d_view_tool_edit_gpencil_select_circle(params),
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index e7883ce0bac..18c4d8710ec 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -1060,6 +1060,16 @@ class _defs_gpencil_paint:
             ),
         )
 
+    @ToolDef.from_fn
+    def cutter():
+        return dict(
+            text="Cutter",
+            icon="ops.gpencil.stroke_cutter",
+            cursor='KNIFE',
+            widget=None,
+            keymap=(),
+        )
+
     @ToolDef.from_fn
     def line():
         return dict(
@@ -1612,6 +1622,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             _defs_view3d_generic.cursor,
             None,
             _defs_gpencil_paint.generate_from_brushes,
+            _defs_gpencil_paint.cutter,
             None,
             _defs_gpencil_paint.line,
             _defs_gpencil_paint.arc,
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py
index 6f80b4394b6..98c398b69bb 100644
--- a/release/scripts/startup/bl_ui/space_topbar.py
+++ b/release/scripts/startup/bl_ui/space_topbar.py
@@ -301,7 +301,7 @@ class _draw_left_context_mode:
                 return
 
             is_paint = True
-            if (tool.name in {"Line", "Box", "Circle", "Arc", "Curve"}):
+            if (tool.name in {"Line", "Box", "Circle", "Arc", "Curve", "Cutter"}):
                 is_paint = False
             elif (not tool.has_datablock):
                 return
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 00a797f9846..4f396757253 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1563,7 +1563,7 @@ int BKE_gpencil_get_material_index(Object *ob, Material *ma)
 /* Get points of stroke always flat to view not affected by camera view or view position */
 void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction)
 {
-	BLI_assert(totpoints >= 3);
+	BLI_assert(totpoints >= 2);
 
 	const bGPDspoint *pt0 = &points[0];
 	const bGPDspoint *pt1 = &points[1];
@@ -1578,7 +1578,15 @@ void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*
 	sub_v3_v3v3(locx, &pt1->x, &pt0->x);
 
 	/* point vector at 3/4 */
-	sub_v3_v3v3(loc3, &pt3->x, &pt0->x);
+	float v3[3];
+	if (totpoints == 2) {
+		mul_v3_v3fl(v3, &pt3->x, 0.001f);
+	}
+	else {
+		copy_v3_v3(v3, &pt3->x);
+	}
+
+	sub_v3_v3v3(loc3, v3, &pt0->x);
 
 	/* vector orthogonal to polygon plane */
 	cross_v3_v3v3(normal, locx, loc3);
@@ -1614,7 +1622,7 @@ void BKE_gpencil_stroke_2d_flat_ref(
 	const bGPDspoint *points, int totpoints,
 	float(*points2d)[2], int *r_direction)
 {
-	BLI_assert(ref_totpoints >= 3);
+	BLI_assert(totpoints >= 2);
 
 	const bGPDspoint *pt0 = &ref_points[0];
 	const bGPDspoint *pt1 = &ref_points[1];
@@ -1629,7 +1637,15 @@ void BKE_gpencil_stroke_2d_flat_ref(
 	sub_v3_v3v3(locx, &pt1->x, &pt0->x);
 
 	/* point vector at 3/4 */
-	sub_v3_v3v3(loc3, &pt3->x, &pt0->x);
+	float v3[3];
+	if (totpoints == 2) {
+		mul_v3_v3fl(v3, &pt3->x, 0.001f);
+	}
+	else {
+		copy_v3_v3(v3, &pt3->x);
+	}
+
+	sub_v3_v3v3(loc3,v3, &pt0->x);
 
 	/* vector orthogonal to polygon plane */
 	cross_v3_v3v3(normal, locx, loc3);
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index b6f81c81823..1e5b9c1ee31 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -875,7 +875,7 @@ static void gp_stroke_eraser_dostroke(
 
 		/* Second Pass: Remove any points that are tagged */
 		if (do_cull) {
-			gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false);
+			gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false, 0);
 		}
 	}
 }
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 7df626ad801..0360bf9f17a 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1829,9 +1829,10 @@ typedef struct tGPDeleteIsland {
  *    - Once we start having larger islands than that, the number required
  *      becomes much less
  * 2) Each island gets converted to a new stroke
+ * If the number of points is <= limit, the stroke is deleted
  */
 void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke,
-	int tag_flags, bool select)
+	int tag_flags, bool select, int limit)
 {
 	tGPDeleteIsland *islands = MEM_callocN(sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2, "gp_point_islands");
 	bool in_island  = false;
@@ -1929,12 +1930,17 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke
 				}
 			}
 
-			/* Add new stroke to the frame */
-			if (next_stroke) {
-				BLI_insertlinkbefore(&gpf->strokes, next_stroke, new_stroke);
+			/* Add new stroke to the frame or delete if below limit */
+			if ((limit > 0) && (new_stroke->totpoints <= limit)) {
+				BKE_gpencil_free_stroke(new_stroke);
 			}
 			else {
-				BLI_addtail(&gpf->strokes, new_stroke);
+				if (next_stroke) {
+					BLI_insertlinkbefore(&gpf->strokes, next_stroke, new_stroke);
+				}
+				else {
+					BLI_addtail(&gpf->strokes, new_stroke);
+				}
 			}
 		}
 	}
@@ -1995,7 +2001,7 @@ static int gp_delete_selected_points(bContext *C)
 						gps->flag &= ~GP_STROKE_SELECT;
 
 						/* delete unwanted points by splitting stroke into several smaller ones */
-						gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false);
+						gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false, 0);
 
 						changed = true;
 					}
@@ -3471,10 +3477,10 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
 								}
 
 								/* delete selected points from destination stroke */
-								gp_stroke_delete_tagged_points(gpf_dst, gps_dst, NULL, GP_SPOINT_SELECT, false);
+								gp_stroke_delete_tagged_points(gpf_dst, gps_dst, NULL, GP_SPOINT_SELECT, false, 0);
 
 								/* delete selected points from origin stroke */
-								gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false);
+								gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false, 0);
 							}
 							/* selected strokes mode */
 							else if (mode == GP_SEPARATE_STROKE) {
@@ -3608,10 +3614,10 @@ static int gp_stroke_split_exec(bContext *C, wmOperator *UNUSED(op))
 						}
 
 						/* delete selected points from destination stroke */
-						gp_stroke_delete_tagged_points(gpf, gps_dst, NULL, GP_SPOINT_SELECT, true);
+						gp_stroke_delete_tagged_points(gpf, gps_dst, NULL, GP_SPOINT_SELECT, true, 0);
 
 						/* delete selected points from origin stroke */
-						gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false);
+						gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false, 0);
 					}
 				}
 				/* select again tagged points */
@@ -3701,3 +3707,175 @@ void GPENCIL_OT_stroke_smooth(wmOperatorType *ot)
 	RNA_def_boolean(ot->srna, "smooth_strength", false, "Strength", "");
 	RNA_def_boolean(ot->srna, "smooth_uv", false, "UV", "");
 }
+
+/* smart stroke knife */
+static bool gpencil_cutter_poll(bContext *C)
+{
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+
+	if (GPENCIL_PAINT_MODE(gpd)) {
+		if (gpd->layers.first)
+			return true;
+	}
+
+	return false;
+}
+
+static int gpencil_cutter_exec(bContext *C, wmOperator *op)
+{
+	ScrArea *sa = CTX_wm_area(C);
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+
+	/* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */
+	const float radius = 0.50f * U.widget_unit;
+	const int radius_squared = (int)(radius * radius);
+
+	int mval[2] = { 0 };
+
+	GP_SpaceConversion gsc = { NULL };
+
+	bGPDlayer *hit_layer = NULL;
+	bGPDstroke *hit_stroke = NULL;
+	bGPDspoint *hit_point = NULL;
+	bGPDspoint *pt = NULL;
+	bGPDspoint *pt1 = NULL;
+	int i = 0;
+	int hit_distance = radius_squared;
+
+	/* sanity checks */
+	if (sa == NULL) {
+		BKE_report(op->reports, RPT_ERROR, "No active area");
+		return OPERATOR_CANCELLED;
+	}
+
+	/* init space conversion stuff */
+	gp_point_conversion_init(C, &gsc);
+
+	/* get mouse location */
+	RNA_int_get_array(op->ptr, "location", mval);
+
+	/* Find stroke point which gets hit */
+	GP_EDITABLE_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
+	{
+		/* deselect stroke */
+		gps->flag &= ~GP_STROKE_SELECT;
+
+		/* firstly, check for hit-point */
+		for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+			int xy[2];
+			/* deselect point */
+			pt->flag &= ~GP_SPOINT_SELECT;
+
+			bGPDspoint pt2;
+			gp_point_to_parent_space(pt, gpstroke_iter.diff_mat, &pt2);
+			gp_point_to_xy(&gsc, gps, &pt2, &xy[0]

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list