GPv3: Layer Parenting/Transforms #117247

Merged
Falk David merged 50 commits from filedescriptor/blender:gpv3-layer-parenting into main 2024-02-07 16:28:24 +01:00
Member

This implements layer parenting and layer transforms.

  • Adds a new "Transform" panel in the object-data properties with the (local) translation, rotation and scale.
  • Adds a new "Relations" panel with the parent property (and also bone name in case the parent is an armature).
  • When converting from GPv2 to GPv3, the parent and transforms are converted too.
  • Bone names are updated if they are renamed in the armature.

image

Implementation details:

  • The positions in the drawings are always in layer space. During extraction, we transform the positions to object space. Note that this could be optimized further and done in the render engine itself.
  • This means that e.g. the selection code (which needs to know where the positions are on screen) now takes this transform into account.
  • The layer transform is calculated when accessed (from the location, rotation, scale properties).
  • Code that needs to know where the positions are on screen now takes this new transform into account.
This implements layer parenting and layer transforms. * Adds a new "Transform" panel in the object-data properties with the (local) translation, rotation and scale. * Adds a new "Relations" panel with the parent property (and also bone name in case the parent is an armature). * When converting from GPv2 to GPv3, the parent and transforms are converted too. * Bone names are updated if they are renamed in the armature. ![image](/attachments/8e64b210-6c71-4cd8-8b95-62049c05cf8e) Implementation details: * The positions in the drawings are always in layer space. During extraction, we transform the positions to object space. Note that this could be optimized further and done in the render engine itself. * This means that e.g. the selection code (which needs to know where the positions are on screen) now takes this transform into account. * The layer transform is calculated when accessed (from the location, rotation, scale properties). * Code that needs to know where the positions are on screen now takes this new transform into account.
Falk David added 2 commits 2024-01-17 18:48:00 +01:00
Falk David added 1 commit 2024-01-17 18:52:53 +01:00
Falk David requested review from Brecht Van Lommel 2024-01-17 18:54:09 +01:00
Falk David requested review from Hans Goudey 2024-01-17 18:54:10 +01:00
Author
Member

@brecht @HooglyBoogly I'd like to get some feedback on the implementation of this before I go any further. The PR is marked WIP, but it is in a working state.

@brecht @HooglyBoogly I'd like to get some feedback on the implementation of this before I go any further. The PR is marked WIP, but it is in a working state.

From the devtalk topic I understood you wanted to write the transform to attributes instead of affecting the strokes immediately. Is this an intermediate step towards that, or was there a change in plans?

From the devtalk topic I understood you wanted to write the transform to attributes instead of affecting the strokes immediately. Is this an intermediate step towards that, or was there a change in plans?
Author
Member

@brecht This is just implementing the layer parenting. The layer transforms would have to be implemented on top of this (somehow).

@brecht This is just implementing the layer parenting. The layer transforms would have to be implemented on top of this (somehow).
Brecht Van Lommel requested changes 2024-01-18 12:17:50 +01:00
Brecht Van Lommel left a comment
Owner

It's just confusing to me to have a modifier named Transform, which applies the parenting transform to the strokes. From the name, you'd expect it to work like the Transform Geometry node, with translation/rotation/scale inputs.

So it would be good if you could give context like, this modifier is intended to gain functionality X, to be placed at the start/end/middle of the modifier stack, work as a virtual modifier node visible to users. Or if those things are unknown still, to mention that.

It's just confusing to me to have a modifier named Transform, which applies the parenting transform to the strokes. From the name, you'd expect it to work like the Transform Geometry node, with translation/rotation/scale inputs. So it would be good if you could give context like, this modifier is intended to gain functionality X, to be placed at the start/end/middle of the modifier stack, work as a virtual modifier node visible to users. Or if those things are unknown still, to mention that.
@ -38,0 +40,4 @@
static void rna_grease_pencil_dependency_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
{
DEG_id_tag_update(&rna_grease_pencil(ptr)->id, ID_RECALC_TRANSFORM);

This should be ID_RECALC_GEOMETRY, since here the transform is getting applied to the geometry. ID_RECALC_TRANSFORM is for when the object matrix is affected.

This should be `ID_RECALC_GEOMETRY`, since here the transform is getting applied to the geometry. `ID_RECALC_TRANSFORM` is for when the object matrix is affected.
filedescriptor marked this conversation as resolved
@ -38,0 +42,4 @@
{
DEG_id_tag_update(&rna_grease_pencil(ptr)->id, ID_RECALC_TRANSFORM);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_OBJECT | ND_PARENT, rna_grease_pencil(ptr));

Same here, this doesn't seem like the appropriate modifier if the mechanism is different. Probably NC_GPENCIL | NA_EDITED is better.

Same here, this doesn't seem like the appropriate modifier if the mechanism is different. Probably `NC_GPENCIL | NA_EDITED` is better.
filedescriptor marked this conversation as resolved
Author
Member

@brecht Right, I was sort of following the way parenting works for Object where it creates a virtual armature modifier. My idea was that we could then also use this modifier to port the grease pencil offset modifier. This way, we don't just have a modifier that's only used for the single purpose of layer parenting.

@brecht Right, I was sort of following the way parenting works for `Object` where it creates a virtual armature modifier. My idea was that we could then also use this modifier to port the [grease pencil offset](https://docs.blender.org/manual/en/latest/grease_pencil/modifiers/deform/offset.html) modifier. This way, we don't just have a modifier that's only used for the single purpose of layer parenting.

It doesn't really make sense to me to have the same modifier do parenting and be a replacement for the offset modifier. Parenting is something you want to apply exactly once, and at a particular position in the stack. So then you need to add some boolean to say if the modifier does parenting or not, which I don't think would be very clear.

It doesn't really make sense to me to have the same modifier do parenting and be a replacement for the offset modifier. Parenting is something you want to apply exactly once, and at a particular position in the stack. So then you need to add some boolean to say if the modifier does parenting or not, which I don't think would be very clear.
Author
Member

@brecht Alright, in that case, I can maybe rename this modifier to be specific to parenting.

And I suppose the offset modifier (maybe should be named transform since it also changes roatation/scale) could be used to apply the layer transforms? Maybe with a checkbox that switches between using layer attributes and a single value (similar to how it works with geometry nodes modifiers).

@brecht Alright, in that case, I can maybe rename this modifier to be specific to parenting. And I suppose the offset modifier (maybe should be named transform since it also changes roatation/scale) could be used to apply the layer transforms? Maybe with a checkbox that switches between using layer attributes and a single value (similar to how it works with geometry nodes modifiers).

If the transform attributes are a built-in feature that most grease pencil geometry nodes are expected to understand, similar to instance/object transforms, then I don't think applying them should be done in the offset modifier.

Most of the time users shouldn't be thinking of applying them at all, because as far as they are concerned they are already being applied automatically at some point before rendering.

The way I would imagine is more that you have a Transform modifier, that can either apply directly to the strokes or write to the transform attributes. This is what users use if they want to procedurally apply some transformation. Might have options to work in layer space or object space.

And then you could have an Apply Transform modifier that applies any transform attributes to the strokes. Maybe this modifier includes the parenting functionality. This is what gets applied automatically at the end of the modifier stack, or what a user may use manually if for some reason they want to bring all stroke vertex positions into the same space.

If the transform attributes are a built-in feature that most grease pencil geometry nodes are expected to understand, similar to instance/object transforms, then I don't think applying them should be done in the offset modifier. Most of the time users shouldn't be thinking of applying them at all, because as far as they are concerned they are already being applied automatically at some point before rendering. The way I would imagine is more that you have a Transform modifier, that can either apply directly to the strokes or write to the transform attributes. This is what users use if they want to procedurally apply some transformation. Might have options to work in layer space or object space. And then you could have an Apply Transform modifier that applies any transform attributes to the strokes. Maybe this modifier includes the parenting functionality. This is what gets applied automatically at the end of the modifier stack, or what a user may use manually if for some reason they want to bring all stroke vertex positions into the same space.
Brecht Van Lommel reviewed 2024-01-18 13:11:08 +01:00
@ -0,0 +71,4 @@
}
return float4x4(float4x4_view(parent.object_to_world));
}();
drawing->strokes_for_write().transform(parent_matrix);

I think this should clear the parent pointer in the layer, so that any following modifier does not apply the parenting transform a second time.

I think this should clear the parent pointer in the layer, so that any following modifier does not apply the parenting transform a second time.
filedescriptor marked this conversation as resolved

Although I think you may want to write the parenting information to the transform attributes before any other modifiers, so that this transform can be taken into account. Which would mean you need 3 distinct modifiers. (Writing the parenting into the transform attributes doesn't necessarily need to be an actual modifier, could just be a piece of code that runs before modifiers too).

Although I think you may want to write the parenting information to the transform attributes before any other modifiers, so that this transform can be taken into account. Which would mean you need 3 distinct modifiers. (Writing the parenting into the transform attributes doesn't necessarily need to be an actual modifier, could just be a piece of code that runs before modifiers too).
Falk David added 8 commits 2024-01-18 17:22:54 +01:00
Falk David changed title from WIP: GPv3: Layer Parenting to WIP: GPv3: Layer Parenting/Transforms 2024-01-18 17:22:57 +01:00
Falk David added 2 commits 2024-01-18 17:47:19 +01:00
Falk David added 2 commits 2024-01-18 18:06:04 +01:00
Falk David added 2 commits 2024-01-18 18:31:21 +01:00
buildbot/vexp-code-patch-lint Build done. Details
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-darwin-arm64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
2805a2b1bd
Fix draw tool and eraser working in layer space
Falk David changed title from WIP: GPv3: Layer Parenting/Transforms to GPv3: Layer Parenting/Transforms 2024-01-18 18:35:56 +01:00
Author
Member

@blender-bot build

@blender-bot build
Author
Member

This is mostly in a working state. I still have this issue of the transforms not updating when e.g. moving a parent and then right-clicking to cancel.

This is mostly in a working state. I still have this issue of the transforms not updating when e.g. moving a parent and then right-clicking to cancel.
Falk David added 1 commit 2024-01-19 11:16:25 +01:00
buildbot/vexp-code-patch-lint Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-darwin-arm64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
984ef69ca5
Merge branch 'main' into gpv3-layer-parenting
Author
Member

@blender-bot build

@blender-bot build
Falk David added 1 commit 2024-01-19 11:20:01 +01:00
Falk David requested review from Brecht Van Lommel 2024-01-19 12:01:43 +01:00
Falk David added this to the Grease Pencil project 2024-01-19 12:43:29 +01:00
Brecht Van Lommel requested changes 2024-01-19 15:30:09 +01:00
Dismissed
Brecht Van Lommel left a comment
Owner

I tried to check if the transform attribute names match other things in geometry nodes. But it seems that for instances, it stores a 4x4 matrix instead, and not as an attribute.

So I'm curious about what the geometry nodes team thinks is the right way to store this, if and how it should be consistent with the rest of the design.

CC @JacquesLucke

I tried to check if the transform attribute names match other things in geometry nodes. But it seems that for instances, it stores a 4x4 matrix instead, and not as an attribute. So I'm curious about what the geometry nodes team thinks is the right way to store this, if and how it should be consistent with the rest of the design. CC @JacquesLucke
@ -1219,0 +1375,4 @@
const float4x4 layer_matrix = math::from_loc_rot_scale<float4x4, math::EulerXYZ>(
translations[layer_i], rotations[layer_i], scales[layer_i]);
drawing->strokes_for_write().transform(layer_matrix);
}

I would expect this to remove or zero the transform attributes. So that later in the stack or nodes you can transform and apply again, without duplication.

I would expect this to remove or zero the transform attributes. So that later in the stack or nodes you can transform and apply again, without duplication.
filedescriptor marked this conversation as resolved
Falk David added 2 commits 2024-01-19 17:53:17 +01:00
Member

So I'm curious about what the geometry nodes team thinks is the right way to store this, if and how it should be consistent with the rest of the design.

The only reason the instance transforms are not stored as normal attribute in CustomData is that we don't have this custom data type yet. Once we have it, we want to move the transforms to an attribute in CustomData.

> So I'm curious about what the geometry nodes team thinks is the right way to store this, if and how it should be consistent with the rest of the design. The only reason the instance transforms are not stored as normal attribute in `CustomData` is that we don't have this custom data type yet. Once we have it, we want to move the transforms to an attribute in `CustomData`.

Any opinion on storing a matrix like instances vs. storing decomposed translation, rotation and scale as in this PR?

Some factors are:

  • Matrix is more efficient in that some matrix composition / decomposition operations can be avoided
  • Matrix can represent shear / skew
  • Consistency: instances already uses matrices
  • Value shown in the UI directly corresponding to attribute or not
  • Decomposed values are easier to inspect in the spreadsheet editor (currently at least)
Any opinion on storing a matrix like instances vs. storing decomposed translation, rotation and scale as in this PR? Some factors are: * Matrix is more efficient in that some matrix composition / decomposition operations can be avoided * Matrix can represent shear / skew * Consistency: instances already uses matrices * Value shown in the UI directly corresponding to attribute or not * Decomposed values are easier to inspect in the spreadsheet editor (currently at least)
Author
Member

I only choose the decomposed option because of the 1to1 correlation with the user interface. Storing it as a matrix (if it would be possible in custom data) would mean that the values in the UI could unexpectedly change (e.g. changing the scale can affect the rotation and vice versa)

I only choose the decomposed option because of the 1to1 correlation with the user interface. Storing it as a matrix (if it would be possible in custom data) would mean that the values in the UI could unexpectedly change (e.g. changing the scale can affect the rotation and vice versa)

If it would be stored as a matrix attribute in geometry nodes, then the properties would be regular DNA which get converted to a matrix attribute. In the same place the parent matrix gets read.

Regular objects and bones work the same way basically. The DNA properties get converted to a matrix early, which is what is then used in constraints and modifiers.

If it would be stored as a matrix attribute in geometry nodes, then the properties would be regular DNA which get converted to a matrix attribute. In the same place the parent matrix gets read. Regular objects and bones work the same way basically. The DNA properties get converted to a matrix early, which is what is then used in constraints and modifiers.
Member

Any opinion on storing a matrix like instances vs. storing decomposed translation, rotation and scale as in this PR?

For instances we used the decomposed storage originally, but it became clear fairly quickly that we have to store the matrix instead. Otherwise the transformation would result in unexpected results because shear/skew is not supported but happens often when rotating and scaling. It's not clear to me why the situation would be different here.

> Any opinion on storing a matrix like instances vs. storing decomposed translation, rotation and scale as in this PR? For instances we used the decomposed storage originally, but it became clear fairly quickly that we have to store the matrix instead. Otherwise the transformation would result in unexpected results because shear/skew is not supported but happens often when rotating and scaling. It's not clear to me why the situation would be different here.
Author
Member

Ok from what I understand, we cannot store matrices in custom data yet. So would the idea be to store

float translation[3], rotation[3], scale[3];
float transform[4][4];

all in DNA? The three fields for the RNA properties and the matrix for actual calculations?

Ok from what I understand, we cannot store matrices in custom data yet. So would the idea be to store ``` float translation[3], rotation[3], scale[3]; float transform[4][4]; ``` all in DNA? The three fields for the RNA properties and the matrix for actual calculations?
Author
Member

Will see if parts of #116166 can be merged before continuing this PR.

Will see if parts of #116166 can be merged before continuing this PR.

Ok from what I understand, we cannot store matrices in custom data yet. So would the idea be to store

float translation[3], rotation[3], scale[3];
float transform[4][4];

all in DNA? The three fields for the RNA properties and the matrix for actual calculations?

I think this is fine. The matrix will be runtime only data, so it is easy to remove from DNA once there is a better way to store it.

> Ok from what I understand, we cannot store matrices in custom data yet. So would the idea be to store > ``` > float translation[3], rotation[3], scale[3]; > float transform[4][4]; > ``` > all in DNA? The three fields for the RNA properties and the matrix for actual calculations? I think this is fine. The matrix will be runtime only data, so it is easy to remove from DNA once there is a better way to store it.
Falk David added 11 commits 2024-02-06 16:16:17 +01:00
Falk David added 2 commits 2024-02-06 16:58:04 +01:00
Author
Member

Updated the code and description:

Implementation details:

The positions in the drawings are always in layer space. During extraction, we transform the positions to object space. Note that this < > could be optimized further and done in the render engine itself.
This means that e.g. the selection code (which needs to know where the positions are on screen) now takes this transform into account.
The layer transform is calculated lazily (from the location, rotation, scale properties) and cached.

Updated the code and description: > Implementation details: > > The positions in the drawings are always in layer space. During extraction, we transform the positions to object space. Note that this < > could be optimized further and done in the render engine itself. > This means that e.g. the selection code (which needs to know where the positions are on screen) now takes this transform into account. > The layer transform is calculated lazily (from the location, rotation, scale properties) and cached.
Falk David requested review from Brecht Van Lommel 2024-02-06 17:07:19 +01:00
Author
Member

I noticed that current files will initialize the scale to 0, because there is no versioning. Should I add versioning for this?

I noticed that current files will initialize the scale to 0, because there is no versioning. Should I add versioning for this?
Falk David added 1 commit 2024-02-06 17:10:23 +01:00
buildbot/vexp-code-patch-lint Build done. Details
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
f2ed58e905
Merge branch 'main' into gpv3-layer-parenting
Author
Member

@blender-bot build

@blender-bot build
Hans Goudey requested changes 2024-02-06 20:20:22 +01:00
Hans Goudey left a comment
Member

Looks fairly straightforward actually, especially since these places already have to deal with a transform, now it's just a different one.

Looks fairly straightforward actually, especially since these places already have to deal with a transform, now it's just a different one.
@ -335,2 +327,4 @@
LayerTransformData trans_data_;
/* Runtime transform data. */
mutable SharedCache<float4x4> local_transform_;
Member

mutable is unnecessary I think, SharedCache is "const" because it's threadsafe IIRC. But anyway, is it really worth putting this in a cache? It's just creating a matrix.

I'd suggest just calculating it on demand, and only adding caching if you observe it improving performance in a real situation.

`mutable` is unnecessary I think, `SharedCache` is "const" because it's threadsafe IIRC. But anyway, is it really worth putting this in a cache? It's just creating a matrix. I'd suggest just calculating it on demand, and only adding caching if you observe it improving performance in a real situation.
filedescriptor marked this conversation as resolved
@ -242,2 +244,2 @@
DrawingTransforms::DrawingTransforms(const Object &grease_pencil_ob)
template<typename T>
static blender::MutableSpan<T> get_mutable_span_attribute(CustomData &custom_data,
Member

Are these changes still necessary? Seems this isn't used

Are these changes still necessary? Seems this isn't used
filedescriptor marked this conversation as resolved
@ -686,2 +698,4 @@
this->opacity = other.opacity;
this->parent = other.parent;
BLI_strncpy(
Member

STRNCPY

`STRNCPY`
filedescriptor marked this conversation as resolved
@ -264,9 +265,10 @@ bool select_box(const ViewContext &vc,
bool select_lasso(const ViewContext &vc,
bke::CurvesGeometry &curves,
Span<float3> deformed_positions,
float4x4 projection_matrix,
Member

const reference (applies elsewhere in the PR too, I won't write it everywhere though)

const reference (applies elsewhere in the PR too, I won't write it everywhere though)
filedescriptor marked this conversation as resolved
@ -714,2 +713,2 @@
const float obmat[4][4],
float r_pmat[4][4])
blender::float4x4 ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d,
const blender::float4x4 obmat)
Member

Nice, but how about committing this separately and switching to using the new math API inside? Also obmat should be a reference

Nice, but how about committing this separately and switching to using the new math API inside? Also `obmat` should be a reference
Author
Member

Created !117938

Created !117938
filedescriptor marked this conversation as resolved
@ -153,9 +155,10 @@ static void recalcData_curves(TransInfo *t)
void curve_populate_trans_data_structs(TransDataContainer &tc,
blender::bke::CurvesGeometry &curves,
const blender::float4x4 &matrix,
Member

matrix -> transform

`matrix` -> `transform`
filedescriptor marked this conversation as resolved
@ -295,0 +296,4 @@
* Layer parent object. Can be an armature in which case the `parsubstr` is the bone name.
*/
struct Object *parent;
char parsubstr[64];
Member

How about using char * to take up less space when it isn't used? (and to simplify assignment, etc.)

How about using `char *` to take up less space when it isn't used? (and to simplify assignment, etc.)
filedescriptor marked this conversation as resolved
Hans Goudey reviewed 2024-02-06 20:23:26 +01:00
@ -278,0 +277,4 @@
const Span<float3> positions = curves.positions();
MutableSpan<float3> positions_slice = edit_points.slice(points);
threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange range) {
for (const int point_i : range) {
Member

Could you split this inner loop to a function called copy_transformed_positions? I'm trying to use identical functions like that for when we get the time to extract that to a separate file or something.

Could you split this inner loop to a function called `copy_transformed_positions`? I'm trying to use identical functions like that for when we get the time to extract that to a separate file or something.
Author
Member

Sure! Would you want that as part of BKE_curves.hh ?

Sure! Would you want that as part of `BKE_curves.hh` ?
Member

No, just local to this file

No, just local to this file
filedescriptor marked this conversation as resolved
Member

Can be a separate task: Add conversion for layer transforms in grease_pencil_convert_legacy.cc.
Apart from that didn't spot anything that wasn't already mentioned.

Can be a separate task: Add conversion for layer transforms in `grease_pencil_convert_legacy.cc`. Apart from that didn't spot anything that wasn't already mentioned.
Falk David added 8 commits 2024-02-07 11:52:13 +01:00
Falk David added 1 commit 2024-02-07 12:11:29 +01:00
Falk David added 1 commit 2024-02-07 12:46:34 +01:00
Author
Member

@LukasTonne Since this was just 5 more lines, I added it to this PR.

@LukasTonne Since this was just 5 more lines, I added it to this PR.
Falk David added 1 commit 2024-02-07 12:50:28 +01:00
Falk David requested review from Hans Goudey 2024-02-07 12:51:56 +01:00
Brecht Van Lommel refused to review 2024-02-07 13:03:48 +01:00
Brecht Van Lommel dismissed brecht’s review 2024-02-07 13:04:35 +01:00
Reason:

Design is fine, will leave code review to others.

Falk David added 2 commits 2024-02-07 14:12:13 +01:00
buildbot/vexp-code-patch-darwin-x86_64 Build done. Details
buildbot/vexp-code-patch-darwin-arm64 Build done. Details
buildbot/vexp-code-patch-windows-amd64 Build done. Details
buildbot/vexp-code-patch-linux-x86_64 Build done. Details
buildbot/vexp-code-patch-coordinator Build done. Details
19315e09d6
Merge branch 'main' into gpv3-layer-parenting
Author
Member

@blender-bot build

@blender-bot build
Falk David added 1 commit 2024-02-07 14:54:29 +01:00
Hans Goudey approved these changes 2024-02-07 15:03:53 +01:00
@ -769,3 +761,3 @@
const IndexMask &mask,
const bke::AttrDomain selection_domain,
const Span<int2> coords,
const Span<int2> lasso_coords,
Member

Commit this name change separately too maybe?

Commit this name change separately too maybe?
Author
Member

Sure :)

Sure :)
filedescriptor marked this conversation as resolved
Falk David added 1 commit 2024-02-07 15:19:21 +01:00
Falk David merged commit 0a45acbe3b into main 2024-02-07 16:28:24 +01:00
Falk David deleted branch gpv3-layer-parenting 2024-02-07 16:28:27 +01:00
Sign in to join this conversation.
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
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#117247
No description provided.