diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-11-02 13:37:15 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-11-03 13:49:38 +0300 |
commit | b8438a870dffb7a3ca3636d8bfa4e37dbf907c71 (patch) | |
tree | 6754e23ceda86c5ec2486cf4b1fc5a19da572f1c | |
parent | e5ccc1e19d7a412314f372623f163626e16dff94 (diff) |
Fix T46626: Crash generating previews
Brush.toggle_brush was allowed to be an invalid pointer,
it worked for the one operator that used it - but in general bad practice,
requiring a lookup on every access.
Ensure the pointer is kept valid now.
-rw-r--r-- | source/blender/blenkernel/BKE_brush.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 16 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_ops.c | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_main_api.c | 1 |
5 files changed, 22 insertions, 5 deletions
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index aff3fb08df6..ea7ad0f8e46 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -44,6 +44,7 @@ struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode) struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode); struct Brush *BKE_brush_copy(struct Brush *brush); void BKE_brush_make_local(struct Brush *brush); +void BKE_brush_unlink(struct Main *bmain, struct Brush *brush); void BKE_brush_free(struct Brush *brush); void BKE_brush_sculpt_reset(struct Brush *brush); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index e0ffd830804..4d619c8d24a 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -215,11 +215,27 @@ void BKE_brush_free(Brush *brush) MEM_freeN(brush->gradient); } +/** + * \note Currently users don't remove brushes from the UI (as is done for scene, text... etc) + * This is only used by RNA, which can remove brushes. + */ +void BKE_brush_unlink(Main *bmain, Brush *brush) +{ + Brush *brush_iter; + + for (brush_iter = bmain->brush.first; brush_iter; brush_iter = brush_iter->id.next) { + if (brush_iter->toggle_brush == brush) { + brush_iter->toggle_brush = NULL; + } + } +} + static void extern_local_brush(Brush *brush) { id_lib_extern((ID *)brush->mtex.tex); id_lib_extern((ID *)brush->mask_mtex.tex); id_lib_extern((ID *)brush->clone.image); + id_lib_extern((ID *)brush->toggle_brush); id_lib_extern((ID *)brush->paint_curve); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index aeb3168c1bc..2da3f395c1f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2131,6 +2131,7 @@ static void lib_link_brush(FileData *fd, Main *main) brush->mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mtex.tex); brush->mask_mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mask_mtex.tex); brush->clone.image = newlibadr_us(fd, brush->id.lib, brush->clone.image); + brush->toggle_brush = newlibadr(fd, brush->id.lib, brush->toggle_brush); brush->paint_curve = newlibadr_us(fd, brush->id.lib, brush->paint_curve); } } @@ -8771,6 +8772,7 @@ static void expand_brush(FileData *fd, Main *mainvar, Brush *brush) expand_doit(fd, mainvar, brush->mtex.tex); expand_doit(fd, mainvar, brush->mask_mtex.tex); expand_doit(fd, mainvar, brush->clone.image); + expand_doit(fd, mainvar, brush->toggle_brush); expand_doit(fd, mainvar, brush->paint_curve); } diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 05eda4da63b..91e372b7f5a 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -407,12 +407,9 @@ static Brush *brush_tool_toggle(Main *bmain, Brush *brush_orig, const int tool, return br; } - else if (brush_orig->toggle_brush && - BLI_findindex(bmain->brush.first, brush_orig->toggle_brush) != -1) - { + else if (brush_orig->toggle_brush) { /* if current brush is using the desired tool, try to toggle - * back to the previously selected brush (if it was set, and - * if it still exists) */ + * back to the previously selected brush. */ return brush_orig->toggle_brush; } else diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index b38f4fa67b6..a67717191f4 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -494,6 +494,7 @@ static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, PointerRNA { Brush *brush = brush_ptr->data; if (ID_REAL_USERS(brush) <= 0) { + BKE_brush_unlink(bmain, brush); BKE_libblock_free(bmain, brush); RNA_POINTER_INVALIDATE(brush_ptr); } |