From 80e63236464a7e864c45e163dd059ffe61735926 Mon Sep 17 00:00:00 2001 From: Jason Wilkins Date: Tue, 20 Jul 2010 02:18:10 +0000 Subject: [PATCH] * Images for brush icons are now reloaded when they are needed from an external file * First, try to load the file from the given filename. This is either absolute or relative to the current .blend * If file is found using the given filename directly then look for the file in the datafiles/brushicons directory (local, user, or system). * Note: This commit does not update the .blend to reference the default icons * Note: This commit does not make sure that the build system copies the default icons to the 2.52/datafiles/brushicons directory --- release/scripts/ui/space_view3d_toolbar.py | 11 ++++-- source/blender/blenkernel/BKE_brush.h | 3 ++ source/blender/blenkernel/intern/brush.c | 33 ++++++++++++++++- source/blender/blenloader/intern/readfile.c | 9 ++++- .../editors/interface/interface_icons.c | 2 +- source/blender/makesdna/DNA_brush_types.h | 1 + source/blender/makesrna/intern/rna_brush.c | 37 ++++++++++++++++++- source/blender/makesrna/intern/rna_image.c | 17 --------- 8 files changed, 87 insertions(+), 26 deletions(-) diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py index fa1a4dec317..51fe070d0c5 100644 --- a/release/scripts/ui/space_view3d_toolbar.py +++ b/release/scripts/ui/space_view3d_toolbar.py @@ -567,10 +567,10 @@ class VIEW3D_PT_tools_brush(PaintPanel): if edit.sculpt_paint_use_unified_size: if edit.sculpt_paint_unified_lock_brush_size: row.prop(edit, "sculpt_paint_unified_lock_brush_size", toggle=True, text="", icon='LOCKED') - row.prop(edit, "sculpt_paint_unified_unprojected_radius", text="Unified Radius", slider=True) + row.prop(edit, "sculpt_paint_unified_unprojected_radius", text="Radius", slider=True) else: row.prop(edit, "sculpt_paint_unified_lock_brush_size", toggle=True, text="", icon='UNLOCKED') - row.prop(edit, "sculpt_paint_unified_size", text="Unified Radius", slider=True) + row.prop(edit, "sculpt_paint_unified_size", text="Radius", slider=True) else: if brush.lock_brush_size: @@ -1122,8 +1122,11 @@ class VIEW3D_PT_tools_brush_appearance(PaintPanel): col = layout.column() col.label(text="Icon:") - #col.template_ID_preview(brush, "image_icon", open="image.open", filter="is_image_icon", rows=3, cols=8) - col.template_ID_preview(brush, "image_icon", open="image.open", rows=3, cols=8) + + row = col.row(align=True) + row.template_ID(brush, "image_icon") + row = col.row(align=True) + row.prop(brush, "image_icon_path", text="") # ********** default tools for weightpaint **************** diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index 6a209167f93..a2168d2a888 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -44,6 +44,9 @@ struct Brush *copy_brush(struct Brush *brush); void make_local_brush(struct Brush *brush); void free_brush(struct Brush *brush); +/* image icon function */ +struct Image *get_brush_icon(struct Brush *brush); + /* brush library operations used by different paint panels */ int brush_set_nr(struct Brush **current_brush, int nr, const char *name); int brush_delete(struct Brush **current_brush); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index c47f5a3ddba..cea9ba32160 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -132,8 +132,6 @@ Brush *copy_brush(Brush *brush) if(brush->mtex.tex) id_us_plus((ID*)brush->mtex.tex); - if(brush->image_icon) id_us_plus((ID*)brush->image_icon); - brushn->curve= curvemapping_copy(brush->curve); /* enable fake user by default */ @@ -205,6 +203,37 @@ void make_local_brush(Brush *brush) } } +/* image icon function */ +Image* get_brush_icon(Brush *brush) +{ + + if (!(brush->image_icon) && brush->image_icon_path[0]) { + // first use the path directly to try and load the file + brush->image_icon= BKE_add_image_file(brush->image_icon_path, 1); + + // otherwise lets try to find it in other directories + if (!(brush->image_icon)) { + char path[240]; + char *folder; + + folder= BLI_get_folder(BLENDER_DATAFILES, "brushicons"); + + path[0] = 0; + + BLI_make_file_string(G.sce, path, folder, brush->image_icon_path); + + if (path[0]) + brush->image_icon= BKE_add_image_file(path, 1); + } + + // remove user count so image isn't saved on exit + if (brush->image_icon) + id_us_min((ID*)(brush->image_icon)); + } + + return brush->image_icon; +} + /* Library Operations */ int brush_set_nr(Brush **current_brush, int nr, const char *name) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fce87302d30..675ccb152d2 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1539,8 +1539,11 @@ static void lib_link_brush(FileData *fd, Main *main) brush->id.flag -= LIB_NEEDLINK; brush->mtex.tex= newlibadr_us(fd, brush->id.lib, brush->mtex.tex); - brush->image_icon= newlibadr_us(fd, brush->id.lib, brush->image_icon); brush->clone.image= newlibadr_us(fd, brush->id.lib, brush->clone.image); + + // Image icons not saved if only used as an icon, + // but if it used elsewhere in the file it will have been saved + brush->image_icon= newlibadr_us(fd, brush->id.lib, brush->image_icon); } } } @@ -10981,6 +10984,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for (brush= main->brush.first; brush; brush= brush->id.next) { /* Sanity Check */ + // brush icon loaded but not the path + //if (brush->image_icon && !(brush->image_icon_path[0])) + // BLI_strncpy(brush->image_icon_path, brush->image_icon->name, sizeof(brush->image_icon_path)); + // infinite number of dabs if (brush->spacing == 0) brush->spacing = 10; diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 232b6f7f317..c6fafce0ffd 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -981,7 +981,7 @@ int ui_id_icon_get(bContext *C, ID *id, int preview) case ID_BR: { /* use the image in the brush as the icon */ /* XXX redundancy here can be reduced be rewriting this switch as an if */ - ID* ima_id = (ID*)((Brush*)id)->image_icon; + ID* ima_id = (ID*)get_brush_icon((Brush*)id); id = ima_id ? ima_id : id; iconid= BKE_icon_getid(id); /* checks if not exists, or changed */ diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 3b2ce6b436e..5fdc3e6dc5c 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -54,6 +54,7 @@ typedef struct Brush { struct CurveMapping *curve; /* falloff curve */ struct MTex mtex; struct Image *image_icon; + char image_icon_path[240]; float normal_weight; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 6d5a06d4f81..22f61c3efcd 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -104,6 +104,36 @@ static int rna_Brush_is_imapaint_brush(Brush *me, bContext *C) return 0; } +static void rna_Brush_image_icon_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Brush *br= (Brush*)ptr->data; + + if (br->image_icon) { + // store path to external image so it can be reloaded later + BLI_strncpy(br->image_icon_path, br->image_icon->name, sizeof(br->image_icon_path)); + + // setting or loading image_icon bumps its user count + // we do not want writefile to save the image if a brush is the only user, + // so decrement the user count by one + id_us_min((ID*)(br->image_icon)); + } + else { + memset(br->image_icon_path, 0, sizeof(br->image_icon_path)); + } + + WM_main_add_notifier(NC_BRUSH|NA_EDITED, br); +} + +static void rna_Brush_image_icon_path_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Brush *br= (Brush*)ptr->data; + + if (br->image_icon) + br->image_icon = NULL; + + WM_main_add_notifier(NC_BRUSH|NA_EDITED, br); +} + #else static void rna_def_brush_texture_slot(BlenderRNA *brna) @@ -642,7 +672,12 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_struct_type(prop, "Image"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Image Icon", ""); - RNA_def_property_update(prop, 0, "rna_Brush_update"); + RNA_def_property_update(prop, 0, "rna_Brush_image_icon_update"); + + prop= RNA_def_property(srna, "image_icon_path", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_sdna(prop, NULL, "image_icon_path"); + RNA_def_property_ui_text(prop, "Image Icon Filepath", "File path for brush icon"); + RNA_def_property_update(prop, 0, "rna_Brush_image_icon_path_update"); /* clone tool */ prop= RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 7144b409299..7d8248b58ed 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -213,12 +213,6 @@ static int rna_Image_depth_get(PointerRNA *ptr) return depth; } -static int rna_Image_is_image_icon(Image *me, bContext *C) -{ - const char prefix[] = ".imageicon."; - return strncmp(me->id.name+2, prefix, sizeof(prefix)-1) == 0; -} - #else static void rna_def_imageuser(BlenderRNA *brna) @@ -298,9 +292,6 @@ static void rna_def_image(BlenderRNA *brna) {IMA_STD_FIELD, "ODD", 0, "Lower First", "Lower field first"}, {0, NULL, 0, NULL, NULL}}; - FunctionRNA *func; - PropertyRNA *parm; - srna= RNA_def_struct(brna, "Image", "ID"); RNA_def_struct_ui_text(srna, "Image", "Image datablock referencing an external or packed image"); RNA_def_struct_ui_icon(srna, ICON_IMAGE_DATA); @@ -342,14 +333,6 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Field Order", "Order of video fields. Select which lines are displayed first"); RNA_def_property_update(prop, NC_IMAGE|ND_DISPLAY, NULL); - /* functions */ - func= RNA_def_function(srna, "is_image_icon", "rna_Image_is_image_icon"); - RNA_def_function_ui_description(func, "Returns true if Image name is prefixed with .imageicon."); - parm= RNA_def_pointer(func, "context", "Context", "", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_boolean(func, "ret", 0, "", ""); - RNA_def_function_return(func, parm); - /* booleans */ prop= RNA_def_property(srna, "fields", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_FIELDS);