How to integrate multi-frames icons/preview images in UI code #49820
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
5 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#49820
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
So, to support one preview per pose of a PoseLibrary (first use case, many more are possible later), multi-preview (or preview frames) is being added to Blender (see the branch for details).
The main issue I’m facing here is how to use those 'frames' of preview images. I can think of two solutions, neither are really ideal to my taste (went with first one in current branch):
Wouldn’t mind having your feelings here, or even better if you have other ideas, before I change whole UI api…
Changed status to: 'Open'
Added subscribers: @mont29, @JulianEisel, @dr.sybren, @brecht
I don't understand why generating one icon ID per frame would have significantly more overhead than multiple frames under one icon ID. It should be possible to have some data structure where memory usage is quite similar?
The issue is that currently, you have one Icon struct per icon ID (stored in the global gIcons GHash). And we’d have to add to that struct a new short to store the frame of ImagePreview it refers to.
So in the perspective of pose library with tens or even hundreds of poses, and one preview frames for each pose, it might be adding a lot of those new Icon structs.
Also, (generated) Icon id system is currently bound to IDs, if we want to add it to sub-ID data, we'll have to add handling of icon_id for them…
So again, not sure which solution is best here, but I tend to dislike the idea of extending icon_id/Icon struct to PreviewImage frames, would rather keep the relation one icon_id <-> one ImagePreview, and add an optional extra parameter to index frame.
Every pose is defined by a pose marker. If we attach the preview of that pose to that marker, we still have a simple situation, right? Then we only have a constant number of preview frames per ID block.
We might want to have more than one preview frame per ID block, for example a large image and a thumbnail-sized image. However, that can be easily encoded into the least-significant bits of the generated ID.
@dr.sybren no, same as with icon_id, I would not spread PreviewImage into sub-ID data, this will quickly become unmanageable.
The whole idea of the branch is to be able to add more than one preview image to ID previews, such that sub-data can then use those additional images as their own preview (and maybe later, to have animated previews of actions or videos e.g.…).
And we already have an icon vs. 'full size' preview system, no need for anything new here. But this has nothing to do with 'preview frames'.
If the ideas is to have animations at some point, then such frames should be a separate concept from sub-ID icons I think? Animation playback would be handled by the UI code I guess and not through Python.
Is
Icon
struct memory usage significant compared to the pixel memory usage? If it is a concern, its memory usage can be reduced already by replacingdrawinfo_free
with a global callback variable, and sharing the same pointer fordrawinfo
andobj
, but it all seems to be quite minor in comparison to the whole.Not sure I understand, one way or the other you need to have some way get a frame number corresponding to some sub-ID data? So might as well return a single icon ID value then?
All are handled by UI code in the end anyway, idea of current design is to allow both with the same backend storage (set of contiguous frames in ImagePreview struct). But that’s slightly out of the scope anyway, animated preview is just idea for future so far.
No, size is not really an issue. It would add some overhead (something like 24-32 bytes per frame), but this is not critical imho.
The issue here is that dynamic icon ID system is designed to work with IDs, if we want to use it elsewhere we'll have to extend its API. Further more, icon_id is fully runtime data, generated on demand, so we'll still need to store the frame index anyway. Using icon_id here would only mean we add an extra step to generate it (and again, it would break the "one icon_id <-> one PreviewImage" relationship we have currently).
Added subscriber: @JoshuaLeung
Are there any docs on how this whole PreviewImage system currently works?
I have to agree with Sybren here that the obvious approach to solve the problem we originally had here (i.e. the need to be able to store preview images for each pose in a pose library) would have been to stick those preview images on each marker. Or, if that's too much overhead, to stick the collection of them in each action. Back when I was thinking of looking into this sometime in the future, that was what I was going to do.
If we later wanted to extend this type of functionality so that you could have say a short 5-10 second "preview" of an action (for use in the asset browser), then that case could be handled by doing something like:
As for how this all functions on the backend, here's an idea:
Instead, you could have a GHash on each relevant ID, that will store that all of that ID's icons (static + preview frames). Then, you'd change the lookup magic so that if if doesn't find something in the global ghash, it hunts for stuff in the ID.
Or, if you really do need a way to figure out which datablock to fetch from, you could have a secondary GHash for these cases, and make it so that the ID's with subframes get stored there. The keys would be the ID-level icon_id's, and the values pointers to the per-ID sub_id_icons_ghash. If your lookup fails to find an icon_id in the first collection, it goes to the second. If it finds a match in the second, it goes inside that to find the sub-icon required.
Also, is it really such a big deal that we have to "extend" some API's? I mean, there are numerous examples in the codebase now where we've got the "old/simple" version that was kept for all the existing places where that API is used, and a
*_ex()
version that takes additional parameters supporting the new stuff. I'm sure that not all of the stuff in the API really needs to be extended like this...(Besides, it's not like we really have a publically exposed C-API with all this stuff that we need to worry about! The bpy integration can adapt really easily to this sort of stuff - i.e. just make your new parameters optional, and the old code won't break; for extra brownie points, pre-empt this change in older versions by adding "extra parameter catch-bag dicts" to the API's so that the extensions you add in a future release don't break API's that easily.)
Added subscriber: @lichtwerk
No, as often, only code :P
Actually, new code in branch is exactly doing that second suggestion, but in an even more 'compact' way, since it makes PreviewImage able to store mutiple “frames”, in a way that keeps it fully compatible with its previous single framed version. So the PreviewImage of Action datablock will store all images, but keeps same behavior by default (i.e. if you access its content th old way, you just get first frame).
Animation case is actually simpler imho, you can just add a new flag to UI code to say to buttons 'this icon_id is animated' (and then UI code internally uses that info smartly - probably e.g. only playing animation when button is in active sate, etc.).
Hmmm… this sounds horribly complicated to me? I mean, if we want to really just use icon_id also for 'frames', then we just generate more Icon, and add a new 'frame' short to Icon struct, and we are done? It’s not that complicated, am just not so happy to extend the icon_id concept to sub_ID data.
Yes, I would really rather like to add extra 'frame index' parameter to our UI api (that’s what I partially did in branch already). In theory we should not have to add an extra parameter to C API, for uiBut functions e.g., since they return a button pointer, we can just add an extra helper function to set frame of icon to use in the few cases where we need other than first one, and that’s it. The issue is with the uiLayout functions - those do not return any handle of any kind, so we cannot use that 'extra optional step' approach, and have to update the whole set of functions to accept an extra parameter.
Nothing deadly here, but this is going to be noisy, and potentially annoying for other UI work done in branches…