[Bf-blender-cvs] [163e434] GPencil_Editing_Stage3: GP Editing: Snapping Tools (Shift S)
Joshua Leung
noreply at git.blender.org
Sun Nov 15 07:41:55 CET 2015
Commit: 163e434b32d7965015c4cf4c5d9f3ae30bf73976
Author: Joshua Leung
Date: Sun Nov 15 19:41:27 2015 +1300
Branches: GPencil_Editing_Stage3
https://developer.blender.org/rB163e434b32d7965015c4cf4c5d9f3ae30bf73976
GP Editing: Snapping Tools (Shift S)
This commit introduces the ability to snap GP points to the cursor/grid,
as well as snapping the cursor to GP points. Currently this functionality
is only available in the 3D view (since the cursor/grid settings are only
available in that view), where they are most needed.
Later, some of these operators can be extended to other editors on an
"as-needed" basis, based on finding some way of dealing with the lack
of 2D cursor in those views.
Coded during my recent travels :)
===================================================================
M release/scripts/startup/bl_ui/properties_grease_pencil_common.py
M release/scripts/startup/bl_ui/space_view3d.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
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 3c2f2c6..ee1ff62 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -390,6 +390,26 @@ class GPENCIL_PIE_sculpt(Menu):
###############################
+class GPENCIL_MT_snap(Menu):
+ bl_label = "Snap"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("gpencil.snap_to_grid", text="Selection to Grid")
+ layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor").use_offset = False
+ layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
+
+ layout.separator()
+
+ layout.operator("gpencil.snap_cursor_to_selected", text="Cursor to Selected")
+ layout.operator("view3d.snap_cursor_to_center", text="Cursor to Center")
+ layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid")
+
+
+###############################
+
+
class GPENCIL_UL_layer(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.GPencilLayer)
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index da1bcfc..590128f 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2882,13 +2882,17 @@ class VIEW3D_MT_edit_gpencil(Menu):
layout.separator()
layout.menu("VIEW3D_MT_edit_gpencil_transform")
+ layout.operator("transform.mirror", text="Mirror")
+ layout.menu("GPENCIL_MT_snap")
+
+ layout.separator()
+
layout.menu("VIEW3D_MT_object_animation") # NOTE: provides keyingset access...
layout.separator()
layout.menu("VIEW3D_MT_edit_gpencil_delete")
layout.operator("gpencil.duplicate_move", text="Duplicate")
- layout.operator("transform.mirror", text="Mirror")
layout.separator()
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 5a980a3..c4e2db6 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -960,4 +960,189 @@ void GPENCIL_OT_dissolve(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
}
+/* ****************** Snapping - Strokes <-> Cursor ************************ */
+
+/* Poll callback for snap operators */
+/* NOTE: For now, we only allow these in the 3D view, as other editors do not
+ * define a cursor or gridstep which can be used
+ */
+static int gp_snap_poll(bContext *C)
+{
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ ScrArea *sa = CTX_wm_area(C);
+
+ return (gpd != NULL) && ((sa != NULL) && (sa->spacetype == SPACE_VIEW3D));
+}
+
+/* --------------------------------- */
+
+static int gp_snap_to_grid(bContext *C, wmOperator *op)
+{
+ RegionView3D *rv3d = CTX_wm_region_data(C);
+ float gridf = rv3d->gridview;
+
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+
+ // TOOD: if entire stroke is selected, offset entire stroke by same amount?
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ /* only if point is selected.. */
+ if (pt->flag & GP_SPOINT_SELECT) {
+ pt->x = gridf * floorf(0.5f + pt->x / gridf);
+ pt->y = gridf * floorf(0.5f + pt->y / gridf);
+ pt->z = gridf * floorf(0.5f + pt->z / gridf);
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_snap_to_grid(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Snap Selection to Grid";
+ ot->idname = "GPENCIL_OT_snap_to_grid";
+ ot->description = "Snap selected points to the nearest grid points";
+
+ /* callbacks */
+ ot->exec = gp_snap_to_grid;
+ ot->poll = gp_snap_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ------------------------------- */
+
+static int gp_snap_to_cursor(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ const bool use_offset = RNA_boolean_get(op->ptr, "use_offset");
+ const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d);
+
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+
+ /* only continue if this stroke is selected (editable doesn't guarantee this)... */
+ if ((gps->flag & GP_STROKE_SELECT) == 0)
+ continue;
+
+ if (use_offset) {
+ float offset[3];
+
+ /* compute offset from first point of stroke to cursor */
+ /* TODO: Allow using midpoint instead? */
+ sub_v3_v3v3(offset, cursor_global, &gps->points->x);
+
+ /* apply offset to all points in the stroke */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ add_v3_v3(&pt->x, offset);
+ }
+ }
+ else {
+ /* affect each selected point */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ copy_v3_v3(&pt->x, cursor_global);
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_snap_to_cursor(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Snap Selection to Cursor";
+ ot->idname = "GPENCIL_OT_snap_to_cursor";
+ ot->description = "Snap selected points/strokes to the cursor";
+
+ /* callbacks */
+ ot->exec = gp_snap_to_cursor;
+ ot->poll = gp_snap_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ ot->prop = RNA_def_boolean(ot->srna, "use_offset", true, "With Offset",
+ "Offset the entire stroke instead of selected points only");
+}
+
+/* ------------------------------- */
+
+static int gp_snap_cursor_to_sel(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+
+ float *cursor = ED_view3d_cursor3d_get(scene, v3d);
+ float centroid[3] = {0.0f};
+ float min[3] = {0.0f};
+ float max[3] = {0.0f};
+ size_t count = 0;
+
+ /* calculate midpoints from selected points */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+
+ /* only continue if this stroke is selected (editable doesn't guarantee this)... */
+ if ((gps->flag & GP_STROKE_SELECT) == 0)
+ continue;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ add_v3_v3(centroid, &pt->x);
+ minmax_v3v3_v3(min, max, &pt->x);
+ count++;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ if (v3d->around == V3D_CENTROID) {
+ mul_v3_fl(centroid, 1.0f / (float)count);
+ copy_v3_v3(cursor, centroid);
+ }
+ else {
+ mid_v3_v3v3(cursor, min, max);
+ }
+
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_snap_cursor_to_selected(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Snap Cursor to Selected Points";
+ ot->idname = "GPENCIL_OT_snap_cursor_to_selected";
+ ot->description = "Snap cursor to center of selected points";
+
+ /* callbacks */
+ ot->exec = gp_snap_cursor_to_sel;
+ ot->poll = gp_snap_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+
/* ************************************************ */
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 2480d92..9e7b88c 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -165,6 +165,12 @@ void GPENCIL_OT_paste(struct wmOperatorType *ot);
void GPENCIL_OT_move_to_layer(struct wmOperatorType *ot);
void GPENCIL_OT_layer_change(struct wmOperatorType *ot);
+void GPENCIL_OT_snap_to_grid(struct wmOperatorType *ot);
+void GPENCIL_OT_snap_to_cursor(struct wmOperatorType *ot);
+void GPENCIL_OT_snap_cursor_to_selected(struct wmOperatorType *ot);
+void GPENCIL_OT_snap_cursor_to_center(struct wmOperatorType *ot);
+
+
/* stroke sculpting -- */
void GPENCIL_OT_brush_paint(struct wmOperatorType *ot);
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index bcb233c..3ed6b35 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -201,6 +201,9 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "GPENCIL_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "GPENCIL_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
#endif
+
+ /* snap */
+ WM_keymap_add_menu(keymap, "GPENCIL_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
/* Show/Hide */
/* NOTE: These are available only in EditMode now, since they clash with general-purpose hotkeys */
@@ -309,6 +312,10 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_move_to_layer);
WM_operatortype_append(GPENCIL_OT_layer_change);
+ WM_operatortype_append(GPENCIL_OT_snap_to_grid);
+ WM_operatortype_append(GPENCIL_OT_snap_to_cursor);
+ WM_operatortype_append(GPENCIL_OT_snap_cursor_to_selected);
+
WM_operatortype_append(GPENCIL_OT_brush_paint);
/* Editing (Buttons) ------------ */
More information about the Bf-blender-cvs
mailing list