[Bf-blender-cvs] [9bd38a1] blender-v2.73-release: Bugfix T43293: Crash when editing shared GPencil datablock in VSE

Joshua Leung noreply at git.blender.org
Tue Jan 20 11:23:12 CET 2015


Commit: 9bd38a17961fd049c18155545bb740385f403fb0
Author: Joshua Leung
Date:   Mon Jan 19 16:38:32 2015 +1300
Branches: blender-v2.73-release
https://developer.blender.org/rB9bd38a17961fd049c18155545bb740385f403fb0

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...

Conflicts:
	source/blender/editors/gpencil/gpencil_edit.c

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

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 63f3491..0941c73 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -27,6 +27,7 @@
  *  \ingroup edgpencil
  */
 
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -103,7 +104,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
 			{
 				BLI_assert(scene && ELEM(scene->toolsettings->gpencil_src,
 				                         GP_TOOL_SOURCE_SCENE, GP_TOOL_SOURCE_OBJECT));
-
+				
 				if (scene->toolsettings->gpencil_src == GP_TOOL_SOURCE_OBJECT) {
 					/* legacy behaviour for usage with old addons requiring object-linked to objects */
 					
@@ -124,21 +125,21 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
 			case SPACE_NODE: /* Nodes Editor */
 			{
 				SpaceNode *snode = (SpaceNode *)sl;
-
+				
 				/* return the GP data for the active node block/node */
 				if (snode && snode->nodetree) {
 					/* for now, as long as there's an active node tree, default to using that in the Nodes Editor */
 					if (ptr) RNA_id_pointer_create(&snode->nodetree->id, ptr);
 					return &snode->nodetree->gpd;
 				}
-
+				
 				/* even when there is no node-tree, don't allow this to flow to scene */
 				return NULL;
 			}
 			case SPACE_SEQ: /* Sequencer */
 			{
 				SpaceSeq *sseq = (SpaceSeq *)sl;
-
+			
 				/* for now, Grease Pencil data is associated with the space (actually preview region only) */
 				/* XXX our convention for everything else is to link to data though... */
 				if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, ptr);
@@ -147,7 +148,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
 			case SPACE_IMAGE: /* Image/UV Editor */
 			{
 				SpaceImage *sima = (SpaceImage *)sl;
-
+				
 				/* for now, Grease Pencil data is associated with the space... */
 				/* XXX our convention for everything else is to link to data though... */
 				if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr);
@@ -157,23 +158,23 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
 			{
 				SpaceClip *sc = (SpaceClip *)sl;
 				MovieClip *clip = ED_space_clip_get_clip(sc);
-
+				
 				if (clip) {
 					if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
 						MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
-
+						
 						if (!track)
 							return NULL;
-
+						
 						if (ptr)
 							RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr);
-
+						
 						return &track->gpd;
 					}
 					else {
 						if (ptr)
 							RNA_id_pointer_create(&clip->id, ptr);
-
+						
 						return &clip->gpd;
 					}
 				}
@@ -183,7 +184,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr
 				return NULL;
 		}
 	}
-
+	
 	/* just fall back on the scene's GP data */
 	if (ptr) RNA_id_pointer_create((ID *)scene, ptr);
 	return (scene) ? &scene->gpd : NULL;
@@ -218,6 +219,7 @@ bGPdata *ED_gpencil_data_get_active(const bContext *C)
 
 /* -------------------------------------------------------- */
 
+// XXX: this should be removed... We really shouldn't duplicate logic like this!
 bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d)
 {
 	Base *base = scene->basact;
@@ -225,7 +227,7 @@ bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d)
 	/* We have to make sure active object is actually visible and selected, else we must use default scene gpd,
 	 * to be consistent with ED_gpencil_data_get_active's behavior.
 	 */
-
+	
 	if (base && TESTBASE(v3d, base)) {
 		gpd = base->object->gpd;
 	}
@@ -257,7 +259,7 @@ static int gp_active_layer_poll(bContext *C)
 static int gp_data_add_exec(bContext *C, wmOperator *op)
 {
 	bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+	
 	if (gpd_ptr == NULL) {
 		BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
 		return OPERATOR_CANCELLED;
@@ -265,14 +267,14 @@ static int gp_data_add_exec(bContext *C, wmOperator *op)
 	else {
 		/* decrement user count and add new datablock */
 		bGPdata *gpd = (*gpd_ptr);
-
+		
 		id_us_min(&gpd->id);
 		*gpd_ptr = gpencil_data_addnew(DATA_("GPencil"));
 	}
-
+	
 	/* notifiers */
 	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+	
 	return OPERATOR_FINISHED;
 }
 
@@ -283,7 +285,7 @@ void GPENCIL_OT_data_add(wmOperatorType *ot)
 	ot->idname = "GPENCIL_OT_data_add";
 	ot->description = "Add new Grease Pencil datablock";
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+	
 	/* callbacks */
 	ot->exec = gp_data_add_exec;
 	ot->poll = gp_add_poll;
@@ -295,7 +297,7 @@ void GPENCIL_OT_data_add(wmOperatorType *ot)
 static int gp_data_unlink_poll(bContext *C)
 {
 	bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+	
 	/* if we have access to some active data, make sure there's a datablock before enabling this */
 	return (gpd_ptr && *gpd_ptr);
 }
@@ -305,7 +307,7 @@ static int gp_data_unlink_poll(bContext *C)
 static int gp_data_unlink_exec(bContext *C, wmOperator *op)
 {
 	bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+	
 	if (gpd_ptr == NULL) {
 		BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
 		return OPERATOR_CANCELLED;
@@ -317,10 +319,10 @@ static int gp_data_unlink_exec(bContext *C, wmOperator *op)
 		id_us_min(&gpd->id);
 		*gpd_ptr = NULL;
 	}
-
+	
 	/* notifiers */
-	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); 
-
+	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+	
 	return OPERATOR_FINISHED;
 }
 
@@ -331,7 +333,7 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot)
 	ot->idname = "GPENCIL_OT_data_unlink";
 	ot->description = "Unlink active Grease Pencil datablock";
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+	
 	/* callbacks */
 	ot->exec = gp_data_unlink_exec;
 	ot->poll = gp_data_unlink_poll;
@@ -343,7 +345,7 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot)
 static int gp_layer_add_exec(bContext *C, wmOperator *op)
 {
 	bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+	
 	/* if there's no existing Grease-Pencil data there, add some */
 	if (gpd_ptr == NULL) {
 		BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
@@ -351,13 +353,13 @@ static int gp_layer_add_exec(bContext *C, wmOperator *op)
 	}
 	if (*gpd_ptr == NULL)
 		*gpd_ptr = gpencil_data_addnew(DATA_("GPencil"));
-
+	
 	/* add new layer now */
 	gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), 1);
-
+	
 	/* notifiers */
 	WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+	
 	return OPERATOR_FINISHED;
 }
 
@@ -389,9 +391,9 @@ static int gp_layer_remove_exec(bContext *C, wmOperator *op)
 	if (gpl->flag & GP_LAYER_LOCKED) {
 		BKE_report(op->reports, RPT_ERROR, "Cannot delete locked layers");
 		return OPERATOR_CANCELLED;
-	}	
+	}
 	
-	/* make the layer before this the new active layer 
+	/* make the layer before this the new active layer
 	 * - use the one after if this is the first
 	 * - if this is the only layer, this naturally becomes NULL
 	 */
@@ -399,7 +401,7 @@ static int gp_layer_remove_exec(bContext *C, wmOperator *op)
 		gpencil_layer_setactive(gpd, gpl->prev);
 	else
 		gpencil_layer_setactive(gpd, gpl->next);
-		
+	
 	/* delete the layer now... */
 	gpencil_layer_delete(gpd, gpl);
 	
@@ -440,7 +442,7 @@ static int gp_layer_move_exec(bContext *C, wmOperator *op)
 	/* sanity checks */
 	if (ELEM(NULL, gpd, gpl))
 		return OPERATOR_CANCELLED;
-		
+	
 	/* up or down? */
 	if (direction == GP_LAYER_MOVE_UP) {
 		/* up */
@@ -466,19 +468,19 @@ void GPENCIL_OT_layer_move(wmOperatorType *ot)
 		{GP_LAYER_MOVE_DOWN, "DOWN", 0, "Down", ""},
 		{0, NULL, 0, NULL, NULL}
 	};
-
+	
 	/* identifiers */
 	ot->name = "Move Grease Pencil Layer";
 	ot->idname = "GPENCIL_OT_layer_move";
 	ot->description = "Move the active Grease Pencil layer up/down in the list";
-
+	
 	/* api callbacks */
 	ot->exec = gp_layer_move_exec;
 	ot->poll = gp_active_layer_poll;
-
+	
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+	
 	ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
 }
 
@@ -518,7 +520,7 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes)
 		else {
 			size_t len = 0;
 			
-			/* is this the end of current island yet? 
+			/* is this the end of current island yet?
 			 * 1) Point i-1 was the last one that was selected
 			 * 2) Point i is the last in the array
 			 */
@@ -529,7 +531,7 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes)
 				len = i - start_idx + 1;
 			}
 			//printf("copying from %d to %d = %d\n", start_idx, i, len);
-			
+		
 			/* make copies of the relevant data */
 			if (len) {
 				bGPDstroke *gpsd;
@@ -577,6 +579,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... */
@@ -595,7 +601,7 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
 					gp_duplicate_points(gps, &new_strokes);
 				}
 				
-				/* deselect original stroke, or else the originals get moved too 
+				/* deselect original stroke, or else the originals get moved too
 				 * (when using the copy + move macro)
 				 */
 				gps->flag &= ~GP_STROKE_SELECT;
@@ -635,7 +641,7 @@ static int gp_actframe_delete_poll(bContext *C)
 {
 	bGPdata *gpd = ED_gpencil_data_get_active(C);
 	bGPDlayer *gpl = gpencil_layer_getactive(gpd);
-
+	
 	/* only if there's an active layer with an active frame */
 	return (gpl && gpl->actframe);
 }
@@ -647,7 +653,7 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
 	bGPdata *gpd = ED_gpencil_data_get_active(C);
 	bGPDlayer *gpl = gpencil_layer_getact

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list