diff options
author | Joshua Leung <aligorith@gmail.com> | 2015-01-19 06:38:32 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2015-01-19 09:11:18 +0300 |
commit | 32ffc63d20908c6433e0e92488be3b5568f81f69 (patch) | |
tree | 78eff17a0e82a1d7ef1bafafe5f54cb09ca1f187 /source/blender/editors/gpencil | |
parent | 0a128af21d6d06ddeb1acbccacda1fdde1843fd0 (diff) |
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...
Diffstat (limited to 'source/blender/editors/gpencil')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 22 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_select.c | 11 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_utils.c | 36 |
3 files changed, 65 insertions, 4 deletions
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 3dae25263e8..caa22a4fde2 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 7967d6a4d95..9ba77a4244e 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 c7218e8e5ff..289cbc568d2 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) { |