Temporary DNA struct creation for argument passing #94869
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
7 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#94869
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?
Description
Currently there are situations where it's not possible to create arguments to pass into functions without first creating data-blocks elsewhere (typically in G.main).
While this is not an urgent problem, there are situations where this is inconvenient.
Motivation
In some cases it's useful to be able to pass in a DNA-struct
two examples of this are:
ImageUser
to pass tobpy.types.Image.gl_load()
wm.keyconfigs.find_item_from_operator()
.Solutions
Here are some solutions we could consider to address this limitation:
Support Coerce Dictionaries
This would allow a dictionary to be passed as arguments to RNA functions.
An example of how this could work:
Details:
Pros:
Cons:
Support Creating Instanced of RNA Types
We could support creating data from Python which is not part of Blender's data-base (G.main).
Since this opens ourselves up for complications regarding data ownership I'd propose only to support this for specific types.
So it should not be possible to create an ID and assign it to object-data.
Types could be created using their types, e.g.
Details:
Pros:
Cons:
A context manager could be used to limit the scope of Python owned data, however this is seems awkward, especially for multiple objects. It would simplify memory management though.
NOTE: this task was created after discussing the topic with @paulgolter
Added subscriber: @ideasman42
Added subscriber: @paulgolter
Added subscriber: @mont29
Added subscriber: @Garek
Hey Campbell, nicely written down!
Just to throw in another example: #94051 (Saving single image of image sequence: image.save_render(): Could not acquire buffer from image. ). There the
image.save_render()
function would also require more input arguments.If I can speak for myself (perspective of the API user) I really only care about having the parameters to control. While it might be sometimes more convenient to work with an actual object instance of a blender type, passing arguments as dictionary would be totally fine for me! I am not 100% sure but I think it is already used in some functions.
Most of the time I have to look up the exact arguments of things in the documentation anyway so raising an exception for unknown arguments or invalid types sounds good!
It seems like the Instances of RNA Types solution is way more work to implement while I, the API user, can achieve the same thing with both solutions. I guess its more about trying to predict what is more robust and easier to maintain if in the future we have 100s of these cases. I also don't know what it means for the daily developer who has to work with Instances of RNA Types that are owned by Python, it this makes actual developing harder.
Added subscriber: @JulianEisel
Another use-case:
For the asset view template (
template_asset_view()
) we wanted to support passing filter settings. Because we couldn't easily construct a filter-settings object in Python and pass it to the template, we had to limit filtering options to an ID filter flag for now. Other workarounds would've been possible (e.g. using ID-properties), but we kept things simple, the template is too complex already.Added subscriber: @Jeroen-Bakker
Other case is when we make the GPUShaderCreateInfo available via python. D13360: GPUShaderCreateInfo for interface abstraction
Added subscriber: @GeorgiaPacific
Hey @ideasman42,
Any updates on that topic? :)
Submitted initial patch to support this by passing dictionaries that are used to initialize the struct (on top of DNA defaults), although it needs further testing: D14047
Added subscriber: @brecht
I didn't see this design proposal before the patch, but will leave my feedback here now.
Personally I don't understand how this is better than passing individual arguments to API functions, in the cases of image users, asset filters or GPUShaderCreateInfo. The advantage seems to be that you can then use the same dictionary multiple times, but none of those use cases would do that?
For image users it seems more obscure. You are expected to fill in an
ImageUser
but only 3 out of 10 fields are actually relevant to the API function. How does a user know which ones?The ability to create instances of some RNA types would be useful in general. We have clunky APIs like
to_mesh
andto_mesh_clear
for this, but they are not thread safe and may lead to memory leaks. But creating a full datablock like that is a more complex use case of course.The use case for this feature is admittedly quite rare.
In the case of an
ImageUser
.ImageUser
, passing it into a function that internally uses anImageUser
is convenient (without having to worry about details), it should always work as expected and removes the need to expand individual arguments. It's also future proof as new properties won't need to be manually passed into the function.image_user
internally would need to take the same set of arguments. This could be handled using a shared template (which would at least avoid copy-pasted arguments that could easily get out of sync).So as far as I can see there are pros/cons with both, the main down-side with splitting into individual arguments is that passing in an existing image user isn't possible, whereas the main downside with coercing is there may be some properties that aren't used.
More generally:
ImageUser
case isn't compelling enough but other use-cases are, since @JulianEisel & @Jeroen-Bakker replied noting this kind of functionality would have come in handy for them.The API foc dealing with image buffers will need significant additions/changes at some point. What we really need is data types for and iterators over image layers/passes/views. And image users should also uses names instead of indices. So I don't think it's future proof for this use case. And I don't understand how this actually helps the other uses cases.
I'm not suggesting we tackle creating data now, but personally I would not bother doing this dictionary coercing at all.
If others like this design, it's not a big deal either way, I can go along with the majority.
The motivation for coercing dictionaries into DNA/RNA was a request from @paulgolter to allow passing in ImageUsers (which seemed reasonable to me at the time), and support for some situations where you don't have an image user.
I'm not particularly invested in D14047 as a solution for passing arguments to
save_render(..)
(although it could still be useful elsewhere).Taking named arguments (as suggested in D14003) seems fine - if these use a shared template we could avoid duplicating the same 3-4 arguments around.
Is this worth supporting now? Or does it depend on those names being more easily accessible for passing in names to be useful?
For names, I don't think there's a way of getting a list of layers/passes/views and their names yet. So using names in
save_render
right now is not helpful.Once we have a proper API, probably we'd have something like
image.layers- [x].passes- [x].views- [x].buffer.save(...)
instead of passing names.There would need to be a way to first access the frame of the image so we might need an intermediate accessor type to expose layers (or this could be supported by ImageUser).
It might be worth checking on how this could work and how much work this is to support (before spending more time on D14047).
At this point I'd rather have @brecht & @paulgolter discuss if a short term workaround is reasonable or not.