[Bf-blender-cvs] [32ffc63] master: Bugfix T43293: Crash when editing shared GPencil datablock in VSE

Joshua Leung noreply at git.blender.org
Mon Jan 19 07:14:44 CET 2015


Commit: 32ffc63d20908c6433e0e92488be3b5568f81f69
Author: Joshua Leung
Date:   Mon Jan 19 16:38:32 2015 +1300
Branches: master
https://developer.blender.org/rB32ffc63d20908c6433e0e92488be3b5568f81f69

Bugfix T43293: Crash when editing shared GPencil datablock in VSE

The problem here was that when a Grease Pencil datablock is shared between
the 3D view and another one of the editors, all the strokes were getting handled
by the editing operators, even if those strokes could not be displayed/used
in that context. As a result, the coordinate conversion methods would fail,
as some of the needed data would not be set.

The fix here involves not including any offending strokes in such cases...

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

M	source/blender/editors/gpencil/gpencil_edit.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
M	source/blender/editors/screen/screen_context.c
M	source/blender/editors/transform/transform_conversions.c

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

diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 3dae252..caa22a4 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -620,6 +620,10 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
 		
 		/* make copies of selected strokes, and deselect these once we're done */
 		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) {
 				if (gps->totpoints == 1) {
 					/* Special Case: If there's just a single point in this stroke... */
@@ -728,6 +732,10 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
 		
 		/* make copies of selected strokes, and deselect these once we're done */
 		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) {
 				if (gps->totpoints == 1) {
 					/* Special Case: If there's just a single point in this stroke... */
@@ -936,6 +944,11 @@ static int gp_delete_selected_strokes(bContext *C)
 		for (gps = gpf->strokes.first; gps; gps = gpsn) {
 			gpsn = gps->next;
 			
+			/* skip strokes that are invalid for current view */
+			if (ED_gpencil_stroke_can_use(C, gps) == false)
+				continue;
+			
+			/* free stroke if selected */
 			if (gps->flag & GP_STROKE_SELECT) {
 				/* free stroke memory arrays, then stroke itself */
 				if (gps->points) MEM_freeN(gps->points);
@@ -975,6 +988,10 @@ static int gp_dissolve_selected_points(bContext *C)
 		for (gps = gpf->strokes.first; gps; gps = gpsn) {
 			gpsn = 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) {
 				bGPDspoint *pt;
 				int i;
@@ -1050,6 +1067,11 @@ static int gp_delete_selected_points(bContext *C)
 		for (gps = gpf->strokes.first; gps; gps = gpsn) {
 			gpsn = 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) {
 				bGPDspoint *pt;
 				int i;
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 7967d6a..9ba77a4 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -136,11 +136,14 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op)
 					bGPDspoint *pt;
 					int i;
 					
-					for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
-						pt->flag &= ~GP_SPOINT_SELECT;
+					/* only edit strokes that are valid in this view... */
+					if (ED_gpencil_stroke_can_use(C, gps)) {
+						for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+							pt->flag &= ~GP_SPOINT_SELECT;
+						}
+						
+						gps->flag &= ~GP_STROKE_SELECT;
 					}
-					
-					gps->flag &= ~GP_STROKE_SELECT;
 				}
 			}
 		}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index c7218e8..289cbc5 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -90,6 +90,42 @@ bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
 
 /* ******************************************************** */
 
+/* Check whether given stroke can be edited given the supplied context */
+// XXX: do we need additional flags for screenspace vs dataspace?
+bool ED_gpencil_stroke_can_use_direct(const ScrArea *sa, const bGPDstroke *gps)
+{
+	/* sanity check */
+	if (ELEM(NULL, sa, gps))
+		return false;
+
+	/* filter stroke types by flags + spacetype */
+	if (gps->flag & GP_STROKE_3DSPACE) {
+		/* 3D strokes - only in 3D view */
+		return (sa->spacetype == SPACE_VIEW3D);
+	}
+	else if (gps->flag & GP_STROKE_2DIMAGE) {
+		/* Special "image" strokes - only in Image Editor */
+		return (sa->spacetype == SPACE_IMAGE);
+	}
+	else if (gps->flag & GP_STROKE_2DSPACE) {
+		/* 2D strokes (dataspace) - for any 2D view (i.e. everything other than 3D view) */
+		return (sa->spacetype != SPACE_VIEW3D);
+	}
+	else {
+		/* view aligned - anything goes */
+		return true;
+	}
+}
+
+/* Check whether given stroke can be edited in the current context */
+bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
+{
+	ScrArea *sa = CTX_wm_area(C);
+	return ED_gpencil_stroke_can_use_direct(sa, gps);
+}
+
+/* ******************************************************** */
+
 /* Init handling for space-conversion function (from passed-in parameters) */
 void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
 {
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index b0d1be1..c4f08ca 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -43,6 +43,7 @@ struct Object;
 struct bGPdata;
 struct bGPDlayer;
 struct bGPDframe;
+struct bGPDstroke;
 struct PointerRNA;
 struct ImBuf;
 struct wmKeyConfig;
@@ -80,6 +81,11 @@ struct bGPdata *ED_gpencil_data_get_active_direct(struct ID *screen_id, struct S
 /* 3D View */
 struct bGPdata  *ED_gpencil_data_get_active_v3d(struct Scene *scene, struct View3D *v3d);
 
+/* ----------- Stroke Editing Utilities ---------------- */
+
+bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *sa, const struct bGPDstroke *gps);
+bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
+
 /* ----------- Grease Pencil Operators ----------------- */
 
 void ED_keymap_gpencil(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index ce9c608..3431ce9 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -497,7 +497,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
 					bGPDstroke *gps;
 					
 					for (gps = gpf->strokes.first; gps; gps = gps->next) {
-						CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps);
+						if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
+							CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps);
+						}
 					}
 				}
 			}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 5dc34d2..9c59ff1 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -7321,6 +7321,11 @@ static void createTransGPencil(bContext *C, TransInfo *t)
 			bGPDstroke *gps;
 			
 			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 (propedit) {
 					/* Proportional Editing... */
 					if (propedit_connected) {
@@ -7424,6 +7429,11 @@ static void createTransGPencil(bContext *C, TransInfo *t)
 				TransData *tail = td;
 				bool stroke_ok;
 				
+				/* skip strokes that are invalid for current view */
+				if (ED_gpencil_stroke_can_use(C, gps) == false) {
+					continue;
+				}
+				
 				/* What we need to include depends on proportional editing settings... */
 				if (propedit) {
 					if (propedit_connected) {




More information about the Bf-blender-cvs mailing list