[Bf-blender-cvs] [e1a65d8] GPencil_EditStrokes: Transform tools for Grease Pencil strokes

Joshua Leung noreply at git.blender.org
Sun Sep 28 17:26:59 CEST 2014


Commit: e1a65d804d3f63f3addd0c848bd0fd1ce9d13228
Author: Joshua Leung
Date:   Mon Sep 29 03:15:02 2014 +1300
Branches: GPencil_EditStrokes
https://developer.blender.org/rBe1a65d804d3f63f3addd0c848bd0fd1ce9d13228

Transform tools for Grease Pencil strokes

Selected strokes can now be transformed (translated, rotate, scaled), using:
* D+G = Grab/Move
* D+R = Rotate
* D+S = Scale

Things are still rough around the edges though, and may not work well in all
cases yet. Known todos:
* There's an occasional crash after duplicating and moving a stroke
* 2D strokes (and other editors) may not work well yet
* Need to check on the case when there is no active object

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

M	source/blender/editors/gpencil/gpencil_ops.c
M	source/blender/editors/include/ED_transform.h
M	source/blender/editors/transform/transform.c
M	source/blender/editors/transform/transform_conversions.c
M	source/blender/editors/transform/transform_ops.c

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

diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 09b2ac9..938e2e3 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -42,6 +42,7 @@
 #include "RNA_access.h"
 
 #include "ED_gpencil.h"
+#include "ED_transform.h"
 
 #include "gpencil_intern.h"
 
@@ -83,7 +84,17 @@ void ED_keymap_gpencil(wmKeyConfig *keyconf)
 	WM_keymap_add_item(keymap, "GPENCIL_OT_select_circle", CKEY, KM_PRESS, 0, DKEY);
 	
 	/* Editing ----------------------------------------- */
+	// XXX: need to use move + copy here...
 	WM_keymap_add_item(keymap, "GPENCIL_OT_strokes_copy", EKEY, KM_PRESS, 0, DKEY);
+	
+	kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, DKEY);
+	RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+	
+	kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_rotate", RKEY, KM_PRESS, 0, DKEY);
+	RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+	
+	kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_resize", SKEY, KM_PRESS, 0, DKEY);
+	RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
 }
 
 /* ****************************************** */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index daa6864..cf84809 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -99,6 +99,7 @@ enum TfmMode {
 #define CTX_MOVIECLIP       (1 << 6)
 #define CTX_MASK            (1 << 7)
 #define CTX_PAINT_CURVE     (1 << 8)
+#define CTX_GPENCIL_STROKES (1 << 9)
 
 /* Standalone call to get the transformation center corresponding to the current situation
  * returns 1 if successful, 0 otherwise (usually means there's no selection)
@@ -146,6 +147,7 @@ int BIF_countTransformOrientation(const struct bContext *C);
 #define P_CORRECT_UV    (1 << 8)
 #define P_NO_DEFAULTS   (1 << 10)
 #define P_NO_TEXSPACE   (1 << 11)
+#define P_GPENCIL_EDIT  (1 << 12)
 
 void Transform_Properties(struct wmOperatorType *ot, int flags);
 
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 31ef76f..a659062 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -2031,6 +2031,12 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
 			options |= CTX_TEXTURE;
 		}
 	}
+	
+	if ((prop = RNA_struct_find_property(op->ptr, "gpencil_strokes")) && RNA_property_is_set(op->ptr, prop)) {
+		if (RNA_property_boolean_get(op->ptr, prop)) {
+			options |= CTX_GPENCIL_STROKES;
+		}
+	}
 
 	t->options = options;
 
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index b709808..1ad36ed 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -107,6 +107,7 @@
 #include "ED_uvedit.h"
 #include "ED_clip.h"
 #include "ED_mask.h"
+#include "ED_gpencil.h"
 
 #include "WM_api.h"  /* for WM_event_add_notifier to deal with stabilization nodes */
 #include "WM_types.h"
@@ -7198,6 +7199,110 @@ void flushTransPaintCurve(TransInfo *t)
 }
 
 
+static void createTransGPencil(bContext *C, TransInfo *t)
+{
+	Object *ob = CTX_data_active_object(C);
+	bGPdata *gpd = ED_gpencil_data_get_active(C);
+	bGPDlayer *gpl;
+	TransData *td = NULL;
+	float mtx[3][3], smtx[3][3];
+	
+	/* == Grease Pencil Strokes to Transform Data ==
+	 * Grease Pencil stroke points can be a mixture of 2D (screen-space),
+	 * or 3D coordinates. However, they're always saved as 3D points.
+	 * For now, we just do these without creating TransData2D for the 2D
+	 * strokes. This may cause issues in future though.
+	 */
+	t->total = 0;
+	
+	if (gpd == NULL)
+		return;
+	
+	/* First Pass: Count the number of datapoints required for the strokes, 
+	 * (and additional info about the configuration - e.g. 2D/3D?)
+	 */
+	for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+		/* only editable and visible layers are considered */
+		if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 &&
+		    (gpl->actframe != NULL))
+		{
+			bGPDframe *gpf = gpl->actframe;
+			bGPDstroke *gps;
+			
+			/* only selected strokes are considered */
+			for (gps = gpf->strokes.first; gps; gps = gps->next) {
+				if (gps->flag & GP_STROKE_SELECT) {
+					t->total += gps->totpoints;
+					
+					// TODO: 2D vs 3D?
+				}
+			}
+		}
+	}
+	
+	/* Stop trying if nothing selected */
+	if (t->total == 0) {
+		return;
+	}
+	
+	/* Allocate memory for data */
+	t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(GPencil)");
+	td = t->data;
+	
+	unit_m3(smtx);
+	unit_m3(mtx);
+	
+	/* Second Pass: Build transdata array */
+	for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+		/* only editable and visible layers are considered */
+		if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 &&
+		    (gpl->actframe != NULL))
+		{
+			bGPDframe *gpf = gpl->actframe;
+			bGPDstroke *gps;
+			
+			/* only selected strokes are considered */
+			for (gps = gpf->strokes.first; gps; gps = gps->next) {
+				if ((gps->flag & GP_STROKE_SELECT) && (gps->totpoints)) {
+					bGPDspoint *pt;
+					int i;
+					
+					const float ninv = 1.0f / gps->totpoints;
+					float center[3] = {0.0f};
+					
+					/* compute midpoint of stroke */
+					for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+						madd_v3_v3v3fl(center, center, &pt->x, ninv);
+					}
+					
+					/* add all points... */
+					for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++, td++) {
+						copy_v3_v3(td->iloc, &pt->x);
+						copy_v3_v3(td->center, center); // XXX: what about  t->around == local?
+						
+						td->loc = &pt->x;
+						td->flag = TD_SELECTED;
+						
+						/* configure 2D points so that they don't play up... */
+						if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) {
+							td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
+							// XXX: matrices may need to be different?
+						}
+						
+						copy_m3_m3(td->smtx, smtx);
+						copy_m3_m3(td->mtx, mtx);
+						unit_m3(td->axismtx); // XXX?
+						
+						if (ob && (ob->gpd == gpd))
+							td->ob = ob;
+					}
+				}
+			}
+		}
+	}
+}
+
+
 void createTransData(bContext *C, TransInfo *t)
 {
 	Scene *scene = t->scene;
@@ -7218,6 +7323,10 @@ void createTransData(bContext *C, TransInfo *t)
 			sort_trans_data_dist(t);
 		}
 	}
+	else if (t->options & CTX_GPENCIL_STROKES) {
+		t->flag |= T_POINTS; // XXX...
+		createTransGPencil(C, t);
+	}
 	else if (t->spacetype == SPACE_IMAGE) {
 		t->flag |= T_POINTS | T_2D_EDIT;
 		if (t->options & CTX_MASK) {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 81e065e..3507db3 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -543,7 +543,11 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
 			}
 		}
 	}
-
+	
+	if (flags & P_GPENCIL_EDIT) {
+		RNA_def_boolean(ot->srna, "gpencil_strokes", 0, "Edit Grease Pencil", "Edit selected Grease Pencil strokes");
+	}
+	
 	if ((flags & P_OPTIONS) && !(flags & P_NO_TEXSPACE)) {
 		RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Texture Space", "Edit Object data texture space");
 		prop = RNA_def_boolean(ot->srna, "remove_on_cancel", 0, "Remove on Cancel", "Remove elements on cancel");
@@ -578,7 +582,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
 
 	RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
 
-	Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS);
+	Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS | P_GPENCIL_EDIT);
 }
 
 static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
@@ -598,7 +602,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
 
 	RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
 
-	Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS);
+	Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS | P_GPENCIL_EDIT);
 }
 
 static int skin_resize_poll(bContext *C)
@@ -652,7 +656,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
 	prop = RNA_def_float_vector(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
 	RNA_def_property_subtype(prop, PROP_ANGLE);
 
-	Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
+	Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT);
 }
 
 static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
@@ -675,7 +679,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
 	prop = RNA_def_float(ot->srna, "value", 0.0f, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
 	RNA_def_property_subtype(prop, PROP_ANGLE);
 
-	Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP);
+	Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_GPENCIL_EDIT);
 }
 
 static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)




More information about the Bf-blender-cvs mailing list