Page MenuHome

Support for icon/preview/thumbnail of files, including py API.
ClosedPublic

Authored by Bastien Montagne (mont29) on Apr 23 2015, 10:48 AM.

Details

Summary

Basically, it:

  • Reworks a bit BKE_icon, adding a special kind of icons, which type is 0, and which has a PreviewImage in their obj field.
  • Add helper to generate such icon from a file path (including a hash to avoid re-generating a preview for an already processed path).
  • Add RNA API (to bpy.data currently - because we may want to use that in background mode too).

So now, one can request a 'Preview' for a given path, that preview has an icon_id
that can be passed as 'icon_value' parameters of UILayout functions.

Note this work is partially based on code from asset-experiments branch.

patch co-worked with @Inês Almeida (brita_).

Diff Detail

Repository
rB Blender

Event Timeline

Bastien Montagne (mont29) retitled this revision from to Support for icon/preview/thumbnail of files, including py API..
Bastien Montagne (mont29) updated this object.
Campbell Barton (campbellbarton) requested changes to this revision.Apr 26 2015, 3:15 PM
Campbell Barton (campbellbarton) edited edge metadata.

Code its self seems OK but some design am not sure about. (could read patch in more detail but think its reasonable to make design obvious up-front).

Whats not so clear from this patch:

  • Who owns the previews? (if an addon registers many previews, then unregisters ... whos responsibility is it to free them?)
  • When are they freed?

Would be good to have an example script showing intended use.

source/blender/makesrna/intern/rna_ID.c
413

*picky* brace placement

source/blender/makesrna/intern/rna_main_api.c
836–858

Putting thumbnail funcs here seems rather odd. not sure where it fits exactly,

For example, if they're in main then they should be freed when the user makes a new file, is this the case?

This revision now requires changes to proceed.Apr 26 2015, 3:15 PM

Thanks for first review. :)

Who owns the previews? (if an addon registers many previews, then unregisters ... whos responsibility is it to free them?)

Previews are owned by gFilePreviews global GHash (using given path as key).

When are they freed?

Addons should free previews they generated (calling thumbnail_preview_delete), otherwise they'll be freed by BKE_icons_free()

source/blender/makesrna/intern/rna_main_api.c
836–858

Yes, agree this is not the right place, but I do not know where to put them actually.

Thing is, i’d like to have them available even in background mode (to allow e.g. first generation of previews from heavy files (like hdr) in a background process - reading the previews from thumbnail is really quick, but generating them from org files can be too slow for UI code).

Maybe they could be class members of UILayout?

Talked with @Bastien Montagne (mont29) on IRC, summary

  • Previews are application level currently
  • Access to global resources from Python/Addons can be problematic (especially addons sharing all previews... without clear seperation).
  • Worth investigating a Python API where addons can request a preview pool, add previews to it, via files, buffers etc... and free it when they're unregistered. Otherwise addons would have to recourse manage every preview

Would like to attempt to design best preview api for scripts/addons... then investigate implimenting it, likely the recourse management side can be done entirely in Python, as we have for ops.py with a few low level calls to do real work (as are in this patch already).

Bastien Montagne (mont29) edited edge metadata.

Rework previews handling to be 'simpler' on py-level, as discussed with Campbell

Seems to be working quite nice... Note that I used bpy.utils for final previews 'module'
because app is a namedtuple, i.e. not modifiable, don’t think it would be worth
redefining the whole app module in py just to add that previews stuff?

Had to do some twisted things too to not expose app and BPyPreviewsXXX classes
in bpy.utils (all only works on some very limited areas).

Also, doc (as generated by sphinx) is not OK currently, not so urgent though,
and not sure what's the best way to handle that? Separated .rst file?

Bastien Montagne (mont29) edited edge metadata.

adding sample python template for ui preview icons (by @Inês Almeida (brita_) ).

Fix bad import in del context, and fix/enhance ui_previews template to only rescan when dir changes.

ui: preserving aspect ratio when drawing icons.

release/scripts/modules/bpy/utils.py
704–779 ↗(On Diff #4128)

We could use a regular dictionary holding weakref's as values to manage freeing.

This means we have the advantage of using a real dict (less dict logic to wrap and less API for script writers to have to remember).

Make previews a real module, and BPyPreviewsCollection a subclass of dict.

Aren't the changes done in CMakeLists.txt needed for SCons as well?

@Julian Eisel (Severin) scons only has one global file in /python, which already includes imbuf - and scons files always include all header/code files with wildcards, so no need to edit them when adding new files.

  • Merge branch 'master' into ui-preview-buttons
  • Merge branch 'master' into ui-preview-buttons
  • Cleanup: minor edits
  • Cleanup: minor edits
  • Use regular module for bpy.app._previews
  • Cleanup: style/redundant casts
  • Cleanup: minor edits
  • Rename delete -> remove
  • Avoid app._previews access via self.__class__._app
  • Remove redundant del statements
  • use easily identifiable separator for keys components
  • Comments
  • Change resource management, previews now match file-io closer
  • bpy.utils.previews api tweaks
  • remove redundant int
  • Use a resource warning
  • Rename utility to class to be clearly a private member
  • Tweak to new and load methods
  • Was clearing wrong previews
  • Preview API: be more strict with new/load
  • Merge branch 'master' into ui-preview-buttons
  • Fix crash when trying to use new preview system from py in addon's registration at startup.
  • Make it clearer that the dictionary stores collections of previews
  • cleanup dynamic enum template script and adding a new one for a simple custom icon
  • DNA; document how to ignore a struct
  • Cleanup: use r_* prefix for return args
  • Add missing TEXTEDIT_UPDATE option
  • Fix T44634: Slide edge not responding to ALT + WHEEL to change reference edge in "even mode".
  • Cleanup: #define -> enum, and get rid of useless braces in case's.
  • Deferred loading for PreviewImage and icons based on them.
  • fixing crash with deferred previews
  • Fix was correct, but let's be a bit more generic/clear here...
  • Fix bad alpha - PreviewImage are assumed to be premultiplied...
  • Move again GPU init code before UI_init one (since icons use OGL, I assue they need it initiated first).
  • Merge branch 'master' into ui-preview-buttons
  • Correct accidental sizeof void*/char mismatch
  • changes for over-allocation
  • Add safety check in PRV_DEFERRED_DATA
  • improving path handling in py samples for ui-previews
  • Merge branch 'master' into ui-preview-buttons
  • tweaks to Python scripts
  • Tweak docstrings
  • Merge branch 'master' into ui-preview-buttons
  • Merge branch 'master' into ui-preview-buttons
  • minor tweaks/rename API calls
  • Minor edits (API naming)
  • Move reload() to ImagePreview method.
  • minor var rename
  • Check if string is empty before setting UI flag
  • API naming: get -> ensure
  • missed last commit
  • de-duplicate ID->preview access
  • move icon defines out of BLI_utildefines.h
  • RNA property naming
  • Merge branch 'master' into ui-preview-buttons

Its maybe not good for the code style, but for people, who want to distibute their addon in one .py file, or on pasteall a function, wich allows to load the icon directly fom the script as base64, can be usefull. (like the css-funtion)
eg:

pcoll.load_from_base64("BlenderIcon",
 "png",
"""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""",
 "IMAGE")
This revision was automatically updated to reflect the committed changes.