[Bf-blender-cvs] [d56f4f55b11] greasepencil-object: GPencil: New extrude operator

Antonioya noreply at git.blender.org
Sun Mar 3 16:36:36 CET 2019


Commit: d56f4f55b11f01d98f00cb867c0e6b53678ed14e
Author: Antonioya
Date:   Sun Mar 3 16:25:48 2019 +0100
Branches: greasepencil-object
https://developer.blender.org/rBd56f4f55b11f01d98f00cb867c0e6b53678ed14e

GPencil: New extrude operator

If the extrude points are the first or last of the stroke, the stroke is extended.

If the extrude points are in the middle of the stroke, a new stroke is created because the grease pencil strokes can be only with 2 extremes.

Still pending define a new icon and set by default XYZ axis in gizmo.

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

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/editors/gpencil/gpencil_edit.c
M	source/blender/editors/gpencil/gpencil_intern.h
M	source/blender/editors/gpencil/gpencil_ops.c
M	source/blender/editors/transform/transform_gizmo_extrude_3d.c

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

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index e29b4a36af4..8e8c08b2e05 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -2951,6 +2951,8 @@ def km_grease_pencil_stroke_edit_mode(params):
         *_grease_pencil_selection(params),
         # Duplicate and move selected points
         ("gpencil.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
+        # Extrude and move selected points
+        ("gpencil.extrude_move", {"type": 'E', "value": 'PRESS'}, None),
         # Delete
         op_menu("VIEW3D_MT_edit_gpencil_delete", {"type": 'X', "value": 'PRESS'}),
         op_menu("VIEW3D_MT_edit_gpencil_delete", {"type": 'DEL', "value": 'PRESS'}),
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 92c599ef071..3a0f5ce01cb 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -1231,6 +1231,16 @@ class _defs_gpencil_edit:
             keymap=(),
         )
 
+    @ToolDef.from_fn
+    def extrude():
+        return dict(
+            text="Extrude",
+            icon="ops.gpencil.extrude_move",
+            widget="VIEW3D_GGT_xform_extrude",
+            keymap=(),
+            draw_settings=_template_widget.VIEW3D_GGT_xform_extrude.draw_settings,
+        )
+
 
 class _defs_gpencil_sculpt:
 
@@ -1676,10 +1686,12 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             _defs_view3d_generic.cursor,
             None,
             *_tools_transform,
+            _defs_gpencil_edit.extrude,
             None,
             _defs_gpencil_edit.bend,
             _defs_gpencil_edit.shear,
             _defs_gpencil_edit.tosphere,
+
         ],
         'SCULPT_GPENCIL': [
             *_tools_gpencil_select,
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 4ba74582774..bb96ba29503 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -754,6 +754,213 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot)
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+/* ************** Extrude Selected Strokes **************** */
+
+/* helper to copy a point to temp area */
+static void copy_point(bGPDstroke *gps,
+					bGPDspoint *temp_points,
+					MDeformVert *temp_dverts,
+					int from_idx, int to_idx)
+{
+	bGPDspoint *pt = &temp_points[from_idx];
+	bGPDspoint *pt_final = &gps->points[to_idx];
+
+	copy_v3_v3(&pt_final->x, &pt->x);
+	pt_final->pressure = pt->pressure;
+	pt_final->strength = pt->strength;
+	pt_final->time = pt->time;
+	pt_final->flag = pt->flag;
+	pt_final->uv_fac = pt->uv_fac;
+	pt_final->uv_rot = pt->uv_rot;
+
+	if (gps->dvert != NULL) {
+		MDeformVert *dvert = &temp_dverts[from_idx];
+		MDeformVert *dvert_final = &gps->dvert[to_idx];
+
+		dvert_final->totweight = dvert->totweight;
+		dvert_final->dw = dvert->dw;
+	}
+}
+
+static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps)
+{
+	bGPDspoint *temp_points = NULL;
+	MDeformVert *temp_dverts = NULL;
+	bGPDspoint *pt = NULL;
+	const bGPDspoint *pt_start = &gps->points[0];
+	const bGPDspoint *pt_last = &gps->points[gps->totpoints - 1];
+	const bool do_first = (pt_start->flag & GP_SPOINT_SELECT);
+	const bool do_last = ((pt_last->flag & GP_SPOINT_SELECT) && (pt_start != pt_last));
+	const bool do_stroke = (do_first || do_last);
+
+	/* review points in the midle of stroke to create new strokes */
+	for (int i = 0; i < gps->totpoints; i++) {
+		/* skip first and last point */
+		if ((i == 0) || (i == gps->totpoints - 1)) {
+			continue;
+		}
+
+		pt = &gps->points[i];
+		if (pt->flag == GP_SPOINT_SELECT) {
+			/* duplicate original stroke data */
+			bGPDstroke *gps_new = MEM_dupallocN(gps);
+			gps_new->prev = gps_new->next = NULL;
+
+			/* add new points array */
+			gps_new->totpoints = 1;
+			gps_new->points = MEM_callocN(sizeof(bGPDspoint), __func__);
+			gps_new->dvert = NULL;
+
+			if (gps->dvert != NULL) {
+				gps_new->dvert = MEM_callocN(sizeof(MDeformVert), __func__);
+			}
+
+			gps->flag |= GP_STROKE_RECALC_GEOMETRY;
+			gps_new->triangles = NULL;
+			gps_new->tot_triangles = 0;
+			BLI_insertlinkafter(&gpf->strokes, gps, gps_new);
+
+			/* copy selected point data to new stroke */
+			copy_point(gps_new, gps->points, gps->dvert, i, 0);
+
+			/* deselect orinal point */
+			pt->flag &= ~GP_SPOINT_SELECT;
+		}
+	}
+
+	/* review first and last point to reuse same stroke */
+	int i2 = 0;
+	int totnewpoints, oldtotpoints;
+	/* if first or last, reuse stroke and resize */
+	if ((do_first) || (do_last)) {
+		totnewpoints = gps->totpoints;
+		if (do_first) {
+			totnewpoints++;
+		}
+		if (do_last) {
+			totnewpoints++;
+		}
+
+		/* duplicate points in a temp area */
+		temp_points = MEM_dupallocN(gps->points);
+		oldtotpoints = gps->totpoints;
+		if (gps->dvert != NULL) {
+			temp_dverts = MEM_dupallocN(gps->dvert);
+		}
+
+		/* if first point, need move all one position */
+		if (do_first) {
+			i2 = 1;
+		}
+
+		/* resize the points arrays */
+		gps->totpoints = totnewpoints;
+		gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints);
+		if (gps->dvert != NULL) {
+			gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints);
+		}
+
+		/* move points to new position */
+		for (int i = 0; i < oldtotpoints; i++) {
+			copy_point(gps, temp_points, temp_dverts, i, i2);
+			i2++;
+		}
+		gps->flag |= GP_STROKE_RECALC_GEOMETRY;
+
+		/* if first point, add new point at the begining */
+		if (do_first) {
+			copy_point(gps, temp_points, temp_dverts, 0, 0);
+			/* deselect old */
+			pt = &gps->points[1];
+			pt->flag &= ~GP_SPOINT_SELECT;
+			/* select new */
+			pt = &gps->points[0];
+			pt->flag |= GP_SPOINT_SELECT;
+		}
+
+		/* if last point, add new point at the end */
+		if (do_last) {
+			copy_point(gps, temp_points, temp_dverts,
+				oldtotpoints - 1, gps->totpoints - 1);
+
+			/* deselect old */
+			pt = &gps->points[gps->totpoints - 2];
+			pt->flag &= ~GP_SPOINT_SELECT;
+			/* select new */
+			pt = &gps->points[gps->totpoints - 1];
+			pt->flag |= GP_SPOINT_SELECT;
+		}
+
+		MEM_SAFE_FREE(temp_points);
+		MEM_SAFE_FREE(temp_dverts);
+	}
+
+	/* if the stroke is not reused, deselect */
+	if (!do_stroke) {
+		gps->flag &= ~GP_STROKE_SELECT;
+	}
+}
+
+static int gp_extrude_exec(bContext *C, wmOperator *op)
+{
+	Object *obact = CTX_data_active_object(C);
+	bGPdata *gpd = (bGPdata *)obact->data;
+	bGPDstroke *gps;
+
+	if (gpd == NULL) {
+		BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
+		return OPERATOR_CANCELLED;
+	}
+
+	if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) {
+		BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition");
+		return OPERATOR_CANCELLED;
+	}
+
+	CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+	{
+		bGPDframe *gpf = gpl->actframe;
+
+		if (gpf == NULL)
+			continue;
+
+		for (gps = gpf->strokes.first; gps; gps = gps->next) {
+			/* skip strokes that are invalid for current view */
+			if (ED_gpencil_stroke_can_use(C, gps) == false) {
+				continue;
+			}
+
+			if (gps->flag & GP_STROKE_SELECT) {
+				gpencil_add_move_points(gpf, gps);
+			}
+		}
+	}
+	CTX_DATA_END;
+
+	/* updates */
+	DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+	DEG_id_tag_update(&obact->id, ID_RECALC_COPY_ON_WRITE);
+	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+	return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_extrude(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Extrude Stroke Points";
+	ot->idname = "GPENCIL_OT_extrude";
+	ot->description = "Extrude the selected Grease Pencil points";
+
+	/* callbacks */
+	ot->exec = gp_extrude_exec;
+	ot->poll = gp_stroke_edit_poll;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+
 /* ******************* Copy/Paste Strokes ************************* */
 /* Grease Pencil stroke data copy/paste buffer:
  * - The copy operation collects all segments of selected strokes,
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 416f3093886..aa47319e3d9 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -390,6 +390,7 @@ void GPENCIL_OT_delete(struct wmOperatorType *ot);
 void GPENCIL_OT_dissolve(struct wmOperatorType *ot);
 void GPENCIL_OT_copy(struct wmOperatorType *ot);
 void GPENCIL_OT_paste(struct wmOperatorType *ot);
+void GPENCIL_OT_extrude(struct wmOperatorType *ot);
 
 void GPENCIL_OT_move_to_layer(struct wmOperatorType *ot);
 void GPENCIL_OT_layer_change(struct wmOperatorType *ot);
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 60b2fb5d64e..e3b13b26672 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -254,6 +254,7 @@ void ED_operatortypes_gpencil(void)
 	WM_operatortype_append(GPENCIL_OT_dissolve);
 	WM_operatortype_append(GPENCIL_OT_copy);
 	WM_operatortype_append(GPENCIL_OT_paste);
+	WM_operatortype_append(GPENCIL_OT_extrude);
 
 	WM_operatortype_append(GPENCIL_OT_move_to_layer);
 	WM_operatortype_append(GPENCIL_OT_layer_change);
@@ -361,6 +362,13 @@ void ED_operatormacros_gpencil(void)
 	otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
 	RNA_boolean_set(otmacro->ptr, "gpencil_strokes", true);
 
+	/* Extrude + Move = Interactively add new points */
+	ot = WM_operatortype_append_macro("GPENCIL_OT_extrude_move", "Extrude Stroke Points",
+									  "Extrude selected points and move them",
+									  OPTYPE_UNDO | OPTYPE_REGISTER);
+	WM_operatortype_macro_define(ot, "GPENCIL_OT_extrude");
+	otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+	RNA_boolean_set(otmacro->ptr, "gpencil_strokes", true);
 }
 
 /* ****************************************** */
dif

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list