Python: Support multiple custom script directories in Preferences #104876

Merged
Julian Eisel merged 9 commits from JulianEisel/blender:temp-multiple-script-dirs into main 2023-04-11 15:21:06 +02:00
Member

Makes it possible to select multiple custom script directories in Preferences > File Paths, replacing the single Scripts path option. Each of these directories supports the regular script directory layout with a startup file (or files?), add-ons, modules and presets.
image.png image.png

The UI could be improved, but follows the UIs for auto run Python scripts locations.

When installing an add-on, the script directory can be chosen:
image.png

This was requested by multiple people in the Blender Studio, who argue that this should improve the workflow for many artists working on and maintaining scripts. It's mainly about separating working versions of scripts from shared ones.

NOTE: Deprecates the bpy.types.PreferencesFilePaths.script_directory property, and replaces bpy.utils.script_path_pref with bpy.utils.script_paths_pref.

Old review: https://developer.blender.org/D17007

Makes it possible to select multiple custom script directories in Preferences > File Paths, replacing the single Scripts path option. Each of these directories supports the regular script directory layout with a startup file (or files?), add-ons, modules and presets. ![image.png](/attachments/4b709f4a-3887-4441-b483-84cf69c0bb3b) ![image.png](/attachments/fcac8daf-ef6d-42ad-be6f-ae8785e5ab90) The UI could be improved, but follows the UIs for auto run Python scripts locations. When installing an add-on, the script directory can be chosen: ![image.png](/attachments/3549bb77-b4eb-4557-80b7-a570aa1ac1b9) This was requested by multiple people in the Blender Studio, who argue that this should improve the workflow for many artists working on and maintaining scripts. It's mainly about separating working versions of scripts from shared ones. NOTE: Deprecates the `bpy.types.PreferencesFilePaths.script_directory` property, and replaces `bpy.utils.script_path_pref` with `bpy.utils.script_paths_pref`. Old review: https://developer.blender.org/D17007
Julian Eisel added 3 commits 2023-02-17 14:58:47 +01:00
Julian Eisel added the
Module
Python API
label 2023-02-17 14:59:26 +01:00
Julian Eisel requested review from Campbell Barton 2023-02-17 14:59:35 +01:00
Author
Member
CC @SimonThommes @fsiddi
Author
Member

For me the main question is still how to properly deprecate bpy.types.PreferencesFilePaths.script_directory. For compatibility we'd have to keep it until 4.0, but what would it do? It could just return the first script directory, maybe printing a warning in the RNA getter.

For me the main question is still how to properly deprecate `bpy.types.PreferencesFilePaths.script_directory`. For compatibility we'd have to keep it until 4.0, but what would it do? It could just return the first script directory, maybe printing a warning in the RNA getter.
Contributor

Sorry if this is a stupid question, but will this change break the forwards compatibility of the user preferences?
So e.g. if I store 2 scripts paths, then change to an older Blender version, will the script directory setting be blank (even if it had a value before this PR)?

Mainly wondering how/if this change will impact my workflow when switching back and forth Blender versions.

Sorry if this is a stupid question, but will this change break the forwards compatibility of the user preferences? So e.g. if I store 2 scripts paths, then change to an older Blender version, will the script directory setting be blank (even if it had a value before this PR)? Mainly wondering how/if this change will impact my workflow when switching back and forth Blender versions.
Author
Member

Sorry if this is a stupid question, but will this change break the forwards compatibility of the user preferences?
So e.g. if I store 2 scripts paths, then change to an older Blender version, will the script directory setting be blank (even if it had a value before this PR)?

In the current patch the old setting won't be touched. That means if there was a value saved in an old version, it will still be there after saving the Preferences in a new version and loading them with an old version. Note that the Preferences are entirely separate between releases still (so changing 3.5 settings won't affect 3.4 settings). It will also not be updated with any of the new paths, even if no path is set in the old property. No idea if this is expected/desired or not, like I said compatibility is the main topic we need to decide on still.

> Sorry if this is a stupid question, but will this change break the forwards compatibility of the user preferences? > So e.g. if I store 2 scripts paths, then change to an older Blender version, will the script directory setting be blank (even if it had a value before this PR)? In the current patch the old setting won't be touched. That means if there was a value saved in an old version, it will still be there after saving the Preferences in a new version and loading them with an old version. Note that the Preferences are entirely separate between releases still (so changing 3.5 settings won't affect 3.4 settings). It will also not be updated with any of the new paths, even if no path is set in the old property. No idea if this is expected/desired or not, like I said compatibility is the main topic we need to decide on still.
Campbell Barton requested changes 2023-02-18 02:23:18 +01:00
@ -347,0 +345,4 @@
DEPRECATED. Use `script_paths_pref` which supports multiple script paths now. Returns the
first valid of these script paths for now, for compatibility.
"""
# TODO how to handle deprecation of this?

This comment can be removed and a deprecation warning can be shown, e.g.

from warnings import warn
warnings.warn(
    "bpy.utils.script_path_pref() is deprecated, use script_paths_pref() instead!"
    DeprecationWarning,
    stacklevel=2,
)
This comment can be removed and a deprecation warning can be shown, e.g. ``` from warnings import warn warnings.warn( "bpy.utils.script_path_pref() is deprecated, use script_paths_pref() instead!" DeprecationWarning, stacklevel=2, ) ```

Note that I think we could even consider removing the function, scripts that use it are likely not to function properly and I don't think its a widely used function either (none of the add-ons distributed with Blender use it for e.g.).

Note that I think we could even consider removing the function, scripts that use it are likely not to function properly and I don't think its a widely used function either (none of the add-ons distributed with Blender use it for e.g.).
JulianEisel marked this conversation as resolved
@ -347,0 +351,4 @@
def script_paths_pref():
"""returns the user preference script directory paths or None"""

Should read "Returns a list of user preference script directories." or similar.

Should read `"Returns a list of user preference script directories."` or similar.
JulianEisel marked this conversation as resolved
@ -347,0 +354,4 @@
"""returns the user preference script directory paths or None"""
paths = []
for script_directory in _preferences.filepaths.script_directories:
if script_directory.directory:

picky assign a value and avoid accessing script_directory.directory twice.

*picky* assign a value and avoid accessing `script_directory.directory` twice.
JulianEisel marked this conversation as resolved
@ -1142,0 +1170,4 @@
new_dir.directory = self.directory
new_dir.name = os.path.basename(self.directory.rstrip(os.sep))
assert(context.preferences.is_dirty == True)

newer autopep8 removes parenthesis after assert (they're not needed), so prefer not to add them.

newer autopep8 removes parenthesis after assert (they're not needed), so prefer not to add them.
JulianEisel marked this conversation as resolved
@ -1142,0 +1197,4 @@
script_directories.remove(script_directory)
break
assert(context.preferences.is_dirty == True)

newer autopep8 removes parenthesis after assert (they're not needed), so prefer not to add them.

newer autopep8 removes parenthesis after assert (they're not needed), so prefer not to add them.
JulianEisel marked this conversation as resolved
@ -668,0 +671,4 @@
typedef struct NamedDirectoryPathEntry {
struct NamedDirectoryPathEntry *next, *prev;
char name[64]; /* MAX_NAME */

Worth mentioning the name is to be unique, and I think it would be best to make this non-empty too (details in other comment).

Worth mentioning the name is to be unique, and I think it would be best to make this non-empty too (details in other comment).
JulianEisel marked this conversation as resolved
@ -344,6 +345,45 @@ static void rna_userdef_script_autoexec_update(Main *UNUSED(bmain),
USERDEF_TAG_DIRTY;
}
static void rna_userdef_script_directory_name_set(PointerRNA *ptr, const char *value)

If DEFAULT or an empty string is passed in, use a fallback name such as "Untitled" or "Path", this avoids having to account for unlikely corner cases - maybe the user has a points to a script dir called DEFAULT and gets an error in the operator.

Disallowing empty strings is just a convention from data-block naming, which I think would be good to enforce here too since it's not expected and means the enum identifier for e.g. would be an empty string - probably it works for the most-part but could cause issues (empty strings have a special meaning for enum separators .. for e.g.). Python scripts may do truth checks on a value without realizing an empty string is a valid value... so we can avoid all this with a default name.

If `DEFAULT` or an empty string is passed in, use a fallback name such as "Untitled" or "Path", this avoids having to account for unlikely corner cases - maybe the user has a points to a script dir called `DEFAULT` and gets an error in the operator. Disallowing empty strings is just a convention from data-block naming, which I think would be good to enforce here too since it's not expected and means the enum identifier for e.g. would be an empty string - probably it works for the most-part but could cause issues (empty strings have a special meaning for enum separators .. for e.g.). Python scripts may do truth checks on a value without realizing an empty string is a valid value... so we can avoid all this with a default name.
JulianEisel marked this conversation as resolved
Brecht Van Lommel added this to the Python API project 2023-02-20 10:39:50 +01:00
Member

I do think it would make sense to show the Default directory as read-only in the list, as you can explicitly select it when installing an add-on. It's a bit confusing without that right now, imo.

I'm also wondering if it could make sense to also add toggle to enable/disable each individual directory. This could be a nice way of switching between different addon environments, especially for people like myself that need to switch between developing an addon in an isolated environment and using it from a shared environment. Just an idea. Maybe this bleeds too much into user profiles, which is related but a bit separate.

I do think it would make sense to show the `Default` directory as read-only in the list, as you can explicitly select it when installing an add-on. It's a bit confusing without that right now, imo. I'm also wondering if it could make sense to also add toggle to enable/disable each individual directory. This could be a nice way of switching between different addon environments, especially for people like myself that need to switch between developing an addon in an isolated environment and using it from a shared environment. Just an idea. Maybe this bleeds too much into user profiles, which is related but a bit separate.
First-time contributor

the toggling sounds usefull, would also be nice to expose enable disable to the python API.

the toggling sounds usefull, would also be nice to expose enable disable to the python API.
Campbell Barton changed title from Python: Support multiple custom script directories in Preferences to WIP: Python: Support multiple custom script directories in Preferences 2023-03-15 22:59:40 +01:00

From a meeting with Brecht and Francesco we're looking into larger changes to how extensions (including scripts) are handled, this will likely involve re-arranging the script layout.

To avoid introducing changes here only to be remove soon after, we agreed this PR should be put on hold. If the extensions project doesn't proceed then I don't see any issues with this patch.

The extensions project is in early planning stages so no official proposal yet, although it's likely we will support multiple extensions paths so this patch may even be used with some minor changes.

From a meeting with Brecht and Francesco we're looking into larger changes to how extensions (including scripts) are handled, this will likely involve re-arranging the script layout. To avoid introducing changes here only to be remove soon after, we agreed this PR should be put on hold. If the extensions project doesn't proceed then I don't see any issues with this patch. The extensions project is in early planning stages so no official proposal yet, although it's likely we will support multiple extensions paths so this patch may even be used with some minor changes.
First-time contributor

is it possible to join the extensions convo with Brecht & Francesco?

is it possible to join the extensions convo with Brecht & Francesco?

is it possible to join the extensions convo with Brecht & Francesco?

Currently this is in the planning stages, the proposal isn't yet ready to receive feedback.

> is it possible to join the extensions convo with Brecht & Francesco? Currently this is in the planning stages, the proposal isn't yet ready to receive feedback.
Julian Eisel added 2 commits 2023-03-24 16:02:48 +01:00
Julian Eisel reviewed 2023-03-24 16:03:16 +01:00
@ -347,0 +345,4 @@
DEPRECATED. Use `script_paths_pref` which supports multiple script paths now. Returns the
first valid of these script paths for now, for compatibility.
"""
# TODO how to handle deprecation of this?
Author
Member

Will leave this up to you to decide. Can be removed in a separate change.

Will leave this up to you to decide. Can be removed in a separate change.
JulianEisel marked this conversation as resolved
@ -668,0 +671,4 @@
typedef struct NamedDirectoryPathEntry {
struct NamedDirectoryPathEntry *next, *prev;
char name[64]; /* MAX_NAME */
Author
Member

I was going to make this struct a general utility, since I can see a number of use cases for a name + directory-path struct. Not all may require a unique name, so noted that accordingly.

I was going to make this struct a general utility, since I can see a number of use cases for a name + directory-path struct. Not all may require a unique name, so noted that accordingly.
JulianEisel marked this conversation as resolved
Author
Member

From further discussions:
It's not clear how this would break with the extensions platform project. And it's quite uncertain how long this project will take to release. Meanwhile a whole number of studios keep requesting this, for the Blender Studio it's quite a priority too and they keep asking about it. So it doesn't make much sense to keep this on hold, it should be prioritized instead.

From further discussions: It's not clear how this would break with the extensions platform project. And it's quite uncertain how long this project will take to release. Meanwhile a whole number of studios keep requesting this, for the Blender Studio it's quite a priority too and they keep asking about it. So it doesn't make much sense to keep this on hold, it should be prioritized instead.
Julian Eisel changed title from WIP: Python: Support multiple custom script directories in Preferences to Python: Support multiple custom script directories in Preferences 2023-03-24 16:08:39 +01:00
Julian Eisel added 1 commit 2023-03-24 16:18:10 +01:00
2663599d78 Make generic DNA struct specific to script directories
While it may seem useful to have this kind of generic struct, it would
cause issues if the generic struct wouldn't be enough in future anymore.
Changing the DNA struct typw would be hard to do versioning for.
Author
Member

I figured that a generic struct like NamedDirectoryPathEntry probably isn't a good idea. Should we want more options for one of its use-cases (e.g. a toggle to enable/disable a script directory) and that doesn't make sense in the generic one, versioning a DNA struct type change would be hard. So now the proposed change uses a specific bUserScriptDirectory struct.

I figured that a generic struct like `NamedDirectoryPathEntry` probably isn't a good idea. Should we want more options for one of its use-cases (e.g. a toggle to enable/disable a script directory) and that doesn't make sense in the generic one, versioning a DNA struct type change would be hard. So now the proposed change uses a specific `bUserScriptDirectory` struct.
Author
Member

I do think it would make sense to show the Default directory as read-only in the list, as you can explicitly select it when installing an add-on. It's a bit confusing without that right now, imo.

This may be nice indeed, however I'm worried that this would make porting the UI to use UI lists (as we probably should) more difficult. UI lists require all list items to be in a single collection (RNA collection or custom property). We could create a dummy custom property for this, which we do in a few places already, but would rather avoid this.

Longer term I hope we can replace UI lists with the much more flexible views.

I'm also wondering if it could make sense to also add toggle to enable/disable each individual directory. This could be a nice way of switching between different addon environments, especially for people like myself that need to switch between developing an addon in an isolated environment and using it from a shared environment. Just an idea. Maybe this bleeds too much into user profiles, which is related but a bit separate.

No strong opinion here. If people think it's useful we can add this still. @pablovazquez what do you think?

> I do think it would make sense to show the `Default` directory as read-only in the list, as you can explicitly select it when installing an add-on. It's a bit confusing without that right now, imo. This may be nice indeed, however I'm worried that this would make porting the UI to use UI lists (as we probably should) more difficult. UI lists require all list items to be in a single collection (RNA collection or custom property). We could create a dummy custom property for this, which we do in a few places already, but would rather avoid this. Longer term I hope we can replace UI lists with the much more flexible [views](https://wiki.blender.org/wiki/Source/Interface/Views). > I'm also wondering if it could make sense to also add toggle to enable/disable each individual directory. This could be a nice way of switching between different addon environments, especially for people like myself that need to switch between developing an addon in an isolated environment and using it from a shared environment. Just an idea. Maybe this bleeds too much into user profiles, which is related but a bit separate. No strong opinion here. If people think it's useful we can add this still. @pablovazquez what do you think?
Member

If people think it's useful we can add this still. @pablovazquez what do you think?

I think it could be useful and doesn't get on the way of Profiles. Indeed they'd be part of Profiles but each profile can have multiple script folders.

The same concept could be used in the future e.g. for managing the list of repositories for extensions and being able to enable/disable them temporarily.

If we go for a UIList a simple checkbox icon on the right will do, akin to toggling collections in the Outliner.

> If people think it's useful we can add this still. @pablovazquez what do you think? I think it could be useful and doesn't get on the way of Profiles. Indeed they'd be part of Profiles but each profile can have multiple script folders. The same concept could be used in the future e.g. for managing the list of repositories for extensions and being able to enable/disable them temporarily. If we go for a UIList a simple checkbox icon on the right will do, akin to toggling collections in the Outliner.
Julian Eisel requested review from Campbell Barton 2023-03-27 10:22:41 +02:00
Campbell Barton requested changes 2023-03-28 13:17:54 +02:00
@ -344,3 +344,1 @@
"""returns the user preference or None"""
path = _preferences.filepaths.script_directory
return _os.path.normpath(path) if path else None
"""

Prefer this be removed as scripts that use it will have incorrect behavior.

Prefer this be removed as scripts that use it will have incorrect behavior.
JulianEisel marked this conversation as resolved
@ -800,1 +802,4 @@
if (!USER_VERSION_ATLEAST(306, 5)) {
if (userdef->pythondir_legacy[0]) {
bUserScriptDirectory *script_dir = MEM_callocN(sizeof(*script_dir),

The name should be initialized (suggest "Untitled" ?) - otherwise no strong preference, just don't leave it blank.

The name should be initialized (suggest "Untitled" ?) - otherwise no strong preference, just don't leave it blank.
JulianEisel marked this conversation as resolved
@ -347,0 +355,4 @@
}
if (STREQ(value, "DEFAULT")) {
BKE_report(
NULL, RPT_WARNING, "Name 'DEFAULT' is reserved for internal use and cannot be used");

Rather not warn as in the rare case a user runs into this - it's not as if there is anything to "fix", besides the script author adding explicit checks for "DEFAULT" which isn't useful.

Over long names will also be clipped for e.g. which doesn't warn. In general it's possible the name requested in Blender is manipulated. It can't be assumed a string literal will be used verbatim.

Rather not warn as in the rare case a user runs into this - it's not as if there is anything to "fix", besides the script author adding explicit checks for "DEFAULT" which isn't useful. Over long names will also be clipped for e.g. which doesn't warn. In general it's possible the name requested in Blender is manipulated. It can't be assumed a string literal will be used verbatim.
JulianEisel marked this conversation as resolved

Posted some technical requests for change but this does conflict somewhat with plans for changing how add-ons are used. I'll post a WIP version of the planning shortly, so the reasoning we might want to hold off on this patch can be public.

Posted some technical requests for change but this does conflict somewhat with plans for changing how add-ons are used. I'll post a WIP version of the planning shortly, so the reasoning we might want to hold off on this patch can be public.

Here's the WIP planning for the extension project which would relocate addons into multiple extensions directories: #106254

Here's the WIP planning for the extension project which would relocate addons into multiple extensions directories: #106254

@ideasman42 I don't see how that changes anything here.
The only change I can see is that scripts directory got renamed to "localhost" and put into an other folder.

That will not affect any custom script directory definitions as those do not rely on the folder being named scripts it only cares about what folders are inside of the scripts directory and that doesn't seem like it will change at all.

So I am still very confused why you are holding this up.

@ideasman42 I don't see how that changes anything here. The only change I can see is that `scripts` directory got renamed to "localhost" and put into an other folder. That will not affect any custom script directory definitions as those do not rely on the folder being named `scripts` it only cares about what folders are inside of the scripts directory and that doesn't seem like it will change at all. So I am still very confused why you are holding this up.
First-time contributor

Why do we only allow extra paths for scripts, but not for Fonts, Textures, Sound files, ...?
Seems the same UI could easily be added for those too.

Why do we only allow extra paths for scripts, but not for Fonts, Textures, Sound files, ...? Seems the same UI could easily be added for those too.

Why do we only allow extra paths for scripts, but not for Fonts, Textures, Sound files, ...?
Seems the same UI could easily be added for those too.

We do not add it for those as they do not really do anything useful currently (at least on Linux and Mac). For example, the "Sound" directory only changes the icon of the folder to a music note if it is kept as a bookmark. I doesn't do anything else.

> Why do we only allow extra paths for scripts, but not for Fonts, Textures, Sound files, ...? > Seems the same UI could easily be added for those too. We do not add it for those as they do not really do anything useful currently (at least on Linux and Mac). For example, the "Sound" directory only changes the icon of the folder to a music note if it is kept as a bookmark. I doesn't do anything else.

Re-discussed this with Brecht today. If the custom script directories keep working as the "original" scripts, this is ok.

The expectation is that a custom scripts directory contains an addons directory where add-ons are stored.

Once the extensions design is in place, these scripts directories will be turned into a <extension-repo>.txt reference.

As long as the code review notes are addressed, go ahead!

Re-discussed this with Brecht today. If the custom script directories keep working as the "original" scripts, this is ok. The expectation is that a custom `scripts` directory contains an `addons` directory where add-ons are stored. Once the extensions design is in place, these `scripts` directories will be turned into a `<extension-repo>.txt` reference. As long as the code review notes are addressed, go ahead!
Julian Eisel reviewed 2023-04-07 17:03:54 +02:00
@ -800,1 +802,4 @@
if (!USER_VERSION_ATLEAST(306, 5)) {
if (userdef->pythondir_legacy[0]) {
bUserScriptDirectory *script_dir = MEM_callocN(sizeof(*script_dir),
Author
Member

Good catch, missed that when introducing the name option.

Good catch, missed that when introducing the name option.
Julian Eisel added 2 commits 2023-04-07 17:06:04 +02:00
Julian Eisel requested review from Campbell Barton 2023-04-07 17:06:17 +02:00
Campbell Barton approved these changes 2023-04-11 15:05:39 +02:00
Julian Eisel added 1 commit 2023-04-11 15:07:04 +02:00
Julian Eisel merged commit ba25023d22 into main 2023-04-11 15:21:06 +02:00
Julian Eisel deleted branch temp-multiple-script-dirs 2023-04-11 15:21:07 +02:00
First-time contributor

Can this be set up automatically somehow?
Like for studios? You know in the user directory set up something to add an additional scripts repository.
So that an artist doesn't have to copy in any paths into this UI? :)

Like Frieder is doing with his addon here for instance but without monkeypatching?

Can this be set up automatically somehow? Like for studios? You know in the user directory set up something to add an additional scripts repository. So that an artist doesn't have to copy in any paths into this UI? :) Like Frieder is doing with his addon [here](https://github.com/friedererdmann/blender_studio_scripts) for instance but without monkeypatching?
First-time contributor

Can this be set up automatically somehow?
Like for studios? You know in the user directory set up something to add an additional scripts repository.
So that an artist doesn't have to copy in any paths into this UI? :)

perhaps application templates can do this for you?

> Can this be set up automatically somehow? > Like for studios? You know in the user directory set up something to add an additional scripts repository. > So that an artist doesn't have to copy in any paths into this UI? :) perhaps [application templates](https://docs.blender.org/manual/en/latest/advanced/app_templates.html) can do this for you?

@Eric I assume studios could have their own scripts in the users startup (or as part of running Blender) which ensure certain customization are made to the environment (including setting up script directories).

@Eric I assume studios could have their own scripts in the users startup (or as part of running Blender) which ensure certain customization are made to the environment (including setting up script directories).
Sign in to join this conversation.
No reviewers
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
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
9 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#104876
No description provided.