GPv3: Move to layer #117244

Merged
Falk David merged 42 commits from mendio/blender:GPv3_OP_Move_to_layer into main 2024-02-05 12:03:11 +01:00

This PR adds the Move to Layer operator from GPv2.

This PR adds the Move to Layer operator from GPv2.
Matias Mendiola added the
Module
Grease Pencil
label 2024-01-17 18:00:58 +01:00
Matias Mendiola added 23 commits 2024-01-17 18:01:05 +01:00
Matias Mendiola added this to the Grease Pencil project 2024-01-17 18:01:27 +01:00
Matias Mendiola requested review from Hans Goudey 2024-01-17 18:01:50 +01:00
Matias Mendiola requested review from Falk David 2024-01-17 18:02:17 +01:00
Matias Mendiola reviewed 2024-01-17 18:06:30 +01:00
@ -1789,0 +1867,4 @@
curves_num += c_src + c_dst;
/* got an Assert with this line. */
curves_dst.resize(points_num, curves_num);
Author
Member

@HooglyBoogly do you mind to look at this? I've got an assert with this Resize line. Points and curves numbers seems to be right in my tests

@HooglyBoogly do you mind to look at this? I've got an assert with this Resize line. Points and curves numbers seems to be right in my tests
Member

When adding curves, you have to set the new curve offsets too, otherwise the new values will be uninitialized.

Side note, this code would be easier to read using full words instead of "p" "c" etc. And if the new sizes were declared as const int ... = in one line.

If you end up using geometry::join_geometries though, it shouldn't be necessary to resize curves manually at all though.

When adding curves, you have to set the new curve offsets too, otherwise the new values will be uninitialized. Side note, this code would be easier to read using full words instead of "p" "c" etc. And if the new sizes were declared as `const int ... = ` in one line. If you end up using `geometry::join_geometries` though, it shouldn't be necessary to resize curves manually at all though.
Author
Member

Thanks! do you have any code sample using geometry::join_geometries maybe is the right way to do this

Thanks! do you have any code sample using `geometry::join_geometries` maybe is the right way to do this
Member

No great example yet. The general structure would look like this though:

bke::CurvesGeometry selected_elems = curves_copy_point_selection(...)
Curves *selected_curves = bke::curves_new_nomain(std::move(selected_elems));
Curves *layer_curves = bke::curves:new_nomain(std::move(drawing.curves_for_write()));
std::array<GeometrySet, 2> geometry_sets{GeometrySet::from_curves(selected_curves), GeometrySet::from_curves(layer_curves)};
GeometrySet joined = geometry::goin_geometries(geometry_sets);
drawing.strokes_for_write() = std::move(joined.get_curves_for_write()->geometry.wrap());
No great example yet. The general structure would look like this though: ``` bke::CurvesGeometry selected_elems = curves_copy_point_selection(...) Curves *selected_curves = bke::curves_new_nomain(std::move(selected_elems)); Curves *layer_curves = bke::curves:new_nomain(std::move(drawing.curves_for_write())); std::array<GeometrySet, 2> geometry_sets{GeometrySet::from_curves(selected_curves), GeometrySet::from_curves(layer_curves)}; GeometrySet joined = geometry::goin_geometries(geometry_sets); drawing.strokes_for_write() = std::move(joined.get_curves_for_write()->geometry.wrap());
Author
Member

Thanks Hans! after some tweaks of your code I've got this working, I'll remove the WIP to the title and wait for a more indeep review

Thanks Hans! after some tweaks of your code I've got this working, I'll remove the WIP to the title and wait for a more indeep review
mendio marked this conversation as resolved
Matias Mendiola added 1 commit 2024-01-17 19:28:40 +01:00
Matias Mendiola changed title from WIP: GPv3 Move to layer to GPv3: Move to layer 2024-01-17 19:31:31 +01:00
Matias Mendiola added 1 commit 2024-01-17 19:58:36 +01:00
Matias Mendiola added 1 commit 2024-01-17 20:02:15 +01:00
Pratik Borhade reviewed 2024-01-18 04:33:16 +01:00
@ -1605,0 +1645,4 @@
/* Iterate through all the drawings at current scene frame. */
const Array<MutableDrawingInfo> drawings_src = retrieve_editable_drawings(*scene, grease_pencil);
for (const MutableDrawingInfo &info : drawings_src) {
Member

use threading::parellel_for ? :)

use `threading::parellel_for` ? :)
Author
Member

It seems not possible, in Separate operator was told me that frames can't be inserted into a grease pencil data-block in parallel

It seems not possible, in Separate operator was told me that frames can't be inserted into a grease pencil data-block in parallel
Member

ok, wasn't aware of that. I'll note this, thanks :)

ok, wasn't aware of that. I'll note this, thanks :)
mendio marked this conversation as resolved
@ -1605,0 +1653,4 @@
continue;
}
if (grease_pencil.get_drawing_at(*layer_dst, info.frame_number) == nullptr) {
Member

!layer_dst.has_drawing_at(frame_num) looks more suitable

info.frame_number or scene->r.cfra. Not sure which is correct here (haven't checked this locally yet 😅)

`!layer_dst.has_drawing_at(frame_num)` looks more suitable `info.frame_number` or `scene->r.cfra`. Not sure which is correct here (haven't checked this locally yet 😅)
mendio marked this conversation as resolved
Pratik Borhade reviewed 2024-01-18 04:48:17 +01:00
@ -1605,0 +1658,4 @@
grease_pencil.insert_blank_frame(*layer_dst, info.frame_number, 0, BEZT_KEYTYPE_KEYFRAME);
/* Copy strokes to new CurvesGeometry. */
Drawing &drawing_dst = *grease_pencil.get_editable_drawing_at(*layer_dst, info.frame_number);
drawing_dst.strokes_for_write() = bke::curves_copy_point_selection(
Member

It seems this will create new drawing of selected points.
But in GPv2, the entire stroke is moved the dst_layer.
So I think we should use retrieve_selected_points and curves_copy_curve_selection

Also use remove_curves instead of remove_points

It seems this will create new drawing of selected points. But in GPv2, the entire stroke is moved the dst_layer. So I think we should use `retrieve_selected_points` and `curves_copy_curve_selection` Also use `remove_curves` instead of `remove_points`
mendio marked this conversation as resolved
Pratik Borhade requested changes 2024-01-18 04:55:25 +01:00
@ -1605,0 +1612,4 @@
static int grease_pencil_move_to_layer_exec(bContext *C, wmOperator *op)
{
using namespace bke::greasepencil;
Scene *scene = CTX_data_scene(C);
Member

const

const
mendio marked this conversation as resolved
@ -1605,0 +1618,4 @@
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
Layer *layer_dst = nullptr;
int layer_index = RNA_int_get(op->ptr, "layer");
Member

const

const
mendio marked this conversation as resolved
Falk David requested changes 2024-01-18 10:54:34 +01:00
Falk David left a comment
Member

I'm seeing that there is a special handling to add a new layer in move_to_layer. We shouldn't be doing this. There is already a layer_add operator, so we should be using that.

I'm seeing that there is a special handling to add a new layer in `move_to_layer`. We shouldn't be doing this. There is already a `layer_add` operator, so we should be using that.
@ -277,0 +282,4 @@
layout.operator_context = 'INVOKE_REGION_WIN'
obd = context.active_object.data
layout.operator("grease_pencil.move_to_layer", text="New Layer", icon='ADD').layer = -1
Member

Use layer_add here. This can also be invoked as a popup if that's what you want to do.

Use `layer_add` here. This can also be invoked as a popup if that's what you want to do.
Author
Member

in GPv2 we follow the Move to Collection behavior, when the user wants to move an object to a new collection, the name of the new collection can be typed in a popup window. Maybe I'm wrong but is this not possible with layer_add? At this point always use the name "Layer" for new layers. This seems like a regression from GPv2 because the user has to change the name later in the layer list, which slows down the workflow. This also applies to set Active Layer operator.

in GPv2 we follow the Move to Collection behavior, when the user wants to move an object to a new collection, the name of the new collection can be typed in a popup window. Maybe I'm wrong but is this not possible with `layer_add`? At this point always use the name "Layer" for new layers. This seems like a regression from GPv2 because the user has to change the name later in the layer list, which slows down the workflow. This also applies to set Active Layer operator.
Member

Right, the layer_add is just missing an invoke :)

Try this:

diff --git a/scripts/startup/bl_ui/properties_data_grease_pencil.py b/scripts/startup/bl_ui/properties_data_grease_pencil.py
index b683847299f..0d2499e911c 100644
--- a/scripts/startup/bl_ui/properties_data_grease_pencil.py
+++ b/scripts/startup/bl_ui/properties_data_grease_pencil.py
@@ -55,6 +55,7 @@ class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
 
         col = row.column()
         sub = col.column(align=True)
+        sub.operator_context = 'EXEC_DEFAULT'
         sub.operator("grease_pencil.layer_add", icon='ADD', text="")
         sub.menu("GREASE_PENCIL_MT_grease_pencil_add_layer_extra", icon='DOWNARROW_HLT', text="")
 
diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc
index 3fbd8684a7a..fe168226817 100644
--- a/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc
+++ b/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc
@@ -76,13 +76,14 @@ static void GREASE_PENCIL_OT_layer_add(wmOperatorType *ot)
   ot->description = "Add a new Grease Pencil layer in the active object";
 
   /* callbacks */
+  ot->invoke = WM_operator_props_popup_confirm;
   ot->exec = grease_pencil_layer_add_exec;
   ot->poll = active_grease_pencil_poll;
 
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
   PropertyRNA *prop = RNA_def_string(
-      ot->srna, "new_layer_name", nullptr, INT16_MAX, "Name", "Name of the new layer");
+      ot->srna, "new_layer_name", "Layer", INT16_MAX, "Name", "Name of the new layer");
   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
   ot->prop = prop;
 }

And then just use layer_add in the menu :)

Right, the `layer_add` is just missing an `invoke` :) Try this: ``` diff diff --git a/scripts/startup/bl_ui/properties_data_grease_pencil.py b/scripts/startup/bl_ui/properties_data_grease_pencil.py index b683847299f..0d2499e911c 100644 --- a/scripts/startup/bl_ui/properties_data_grease_pencil.py +++ b/scripts/startup/bl_ui/properties_data_grease_pencil.py @@ -55,6 +55,7 @@ class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel): col = row.column() sub = col.column(align=True) + sub.operator_context = 'EXEC_DEFAULT' sub.operator("grease_pencil.layer_add", icon='ADD', text="") sub.menu("GREASE_PENCIL_MT_grease_pencil_add_layer_extra", icon='DOWNARROW_HLT', text="") diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc index 3fbd8684a7a..fe168226817 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_layers.cc @@ -76,13 +76,14 @@ static void GREASE_PENCIL_OT_layer_add(wmOperatorType *ot) ot->description = "Add a new Grease Pencil layer in the active object"; /* callbacks */ + ot->invoke = WM_operator_props_popup_confirm; ot->exec = grease_pencil_layer_add_exec; ot->poll = active_grease_pencil_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; PropertyRNA *prop = RNA_def_string( - ot->srna, "new_layer_name", nullptr, INT16_MAX, "Name", "Name of the new layer"); + ot->srna, "new_layer_name", "Layer", INT16_MAX, "Name", "Name of the new layer"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); ot->prop = prop; } ``` And then just use `layer_add` in the menu :)
Author
Member

perfect, that works, also the set Active Layer operator is working as intended

perfect, that works, also the set Active Layer operator is working as intended
mendio marked this conversation as resolved
Matias Mendiola added 1 commit 2024-01-18 13:20:29 +01:00
Matias Mendiola added 1 commit 2024-01-18 15:14:01 +01:00
Falk David requested changes 2024-01-18 15:50:19 +01:00
Falk David left a comment
Member

Another pass :)

Another pass :)
@ -277,0 +280,4 @@
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
obd = context.active_object.data
Member

obd -> grease_pencil

`obd` -> `grease_pencil`
mendio marked this conversation as resolved
@ -277,0 +282,4 @@
layout.operator_context = 'INVOKE_REGION_WIN'
obd = context.active_object.data
nlop = layout.operator("grease_pencil.layer_add", text="New Layer", icon='ADD')
Member

This is also fine: layout.operator("grease_pencil.layer_add", text="New Layer", icon='ADD').new_layer_name = "Layer"

This is also fine: `layout.operator("grease_pencil.layer_add", text="New Layer", icon='ADD').new_layer_name = "Layer"`
Author
Member

When doing this way the Layer add popup shows empty

When doing this way the Layer add popup shows empty
Author
Member

sorry, the problem was a typo

sorry, the problem was a typo
mendio marked this conversation as resolved
@ -13,6 +13,7 @@
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
#include "BLI_stack.hh"
#include "BLI_string.h"
Member

I think this include is not needed.

I think this include is not needed.
mendio marked this conversation as resolved
@ -41,3 +43,4 @@
#include "WM_api.hh"
#include "UI_resources.hh"
using namespace blender::bke;
Member

This should be removed. If a function needs this, it can be added in that function.

This should be removed. If a function needs this, it can be added in that function.
mendio marked this conversation as resolved
@ -1605,0 +1624,4 @@
/* get layer by index */
layer_dst = grease_pencil.layers_for_write()[layer_index];
}
else {
Member

This else case can be removed.
You should be able to do Layer *layer_dst = grease_pencil.layers_for_write()[layer_index]; directly.

This `else` case can be removed. You should be able to do `Layer *layer_dst = grease_pencil.layers_for_write()[layer_index];` directly.
mendio marked this conversation as resolved
@ -16,6 +16,8 @@
#include "ED_keyframes_edit.hh"
#include "WM_api.hh"
Member

I think this include is no longer needed

I think this include is no longer needed
mendio marked this conversation as resolved
Matias Mendiola added 1 commit 2024-01-18 18:53:03 +01:00
Author
Member

@filedescriptor right now because we are no longer use the invoke in the operator when adding a new layer the code never reach grease_pencil_move_to_layer_exec, it only works when we select a layer that already exist.
Do we need to use a macro to solve this or what do you propose?

@filedescriptor right now because we are no longer use the invoke in the operator when adding a new layer the code never reach `grease_pencil_move_to_layer_exec`, it only works when we select a layer that already exist. Do we need to use a macro to solve this or what do you propose?
Matias Mendiola added 1 commit 2024-01-18 20:27:54 +01:00
Pratik Borhade reviewed 2024-01-19 10:58:19 +01:00
Pratik Borhade left a comment
Member

Hi, found some "cleanup" changes.

Hi, found some "cleanup" changes.
@ -277,0 +281,4 @@
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
grease_pencil = context.active_object.data
Member

trailing whitespace

trailing whitespace
mendio marked this conversation as resolved
@ -277,0 +283,4 @@
grease_pencil = context.active_object.data
layout.operator("grease_pencil.layer_add", text="New Layer", icon='ADD').new_layer_name = "Layer"
Member

trailing whitespace

trailing whitespace
mendio marked this conversation as resolved
@ -1605,0 +1650,4 @@
drawing_dst.tag_topology_changed();
}
else {
/* For existing Layers append the strokes to new CurvesGeometry. */
Member

I think: For existing "drawing"

I think: For existing "drawing"
Author
Member

I rephrased the comments for clarity.

I rephrased the comments for clarity.
mendio marked this conversation as resolved
@ -1605,0 +1669,4 @@
info.drawing.tag_topology_changed();
changed = true;
};
Member

; is not required 🙂

`;` is not required 🙂
mendio marked this conversation as resolved
Falk David requested changes 2024-01-19 11:35:28 +01:00
Falk David left a comment
Member

Some more cleanup comments.

Some more cleanup comments.
@ -1605,0 +1638,4 @@
}
if (!layer_dst->has_drawing_at(info.frame_number)) {
/* For new layers Insert Keyframe at current frame/layer. */
Member

/* If the target layer does not have a keyframe at the current frame, insert a new keyframe. */

`/* If the target layer does not have a keyframe at the current frame, insert a new keyframe. */`
Author
Member

I rephrased the comments in the if...else to clarify that one move/copy geometry and the other append to existing geometry.
Let me know if you think more detail is still needed in this comments.

I rephrased the comments in the `if...else` to clarify that one move/copy geometry and the other append to existing geometry. Let me know if you think more detail is still needed in this comments.
mendio marked this conversation as resolved
@ -1605,0 +1691,4 @@
/* callbacks. */
ot->exec = grease_pencil_move_to_layer_exec;
ot->poll = ot->poll = editable_grease_pencil_poll;
Member

Double ot->poll =

Double `ot->poll =`
mendio marked this conversation as resolved
Pratik Borhade requested changes 2024-01-19 11:36:57 +01:00
Pratik Borhade left a comment
Member

Just tested the PR. Looks correct apart from this one change 🙂

Just tested the PR. Looks correct apart from this one change 🙂
@ -1605,0 +1641,4 @@
/* For new layers Insert Keyframe at current frame/layer. */
grease_pencil.insert_blank_frame(*layer_dst, info.frame_number, 0, BEZT_KEYTYPE_KEYFRAME);
/* Copy strokes to new CurvesGeometry. */
Drawing &drawing_dst = *grease_pencil.get_editable_drawing_at(*layer_dst, info.frame_number);
Member

drawing_dst is nullptr when dst layer is locked.

`drawing_dst` is `nullptr` when dst layer is locked.
mendio marked this conversation as resolved
@ -1605,0 +1651,4 @@
}
else {
/* For existing Layers append the strokes to new CurvesGeometry. */
Drawing &drawing_dst = *grease_pencil.get_editable_drawing_at(*layer_dst, info.frame_number);
Member

drawing_dst is nullptr when dst layer is locked.

`drawing_dst` is `nullptr` when dst layer is locked.
mendio marked this conversation as resolved
Member

@mendio Yes, I think an operator macro makes sense. Maybe GREASE_PENCIL_OT_move_to_new_layer.

@mendio Yes, I think an operator macro makes sense. Maybe `GREASE_PENCIL_OT_move_to_new_layer`.
Falk David reviewed 2024-01-19 11:38:50 +01:00
@ -1605,0 +1699,4 @@
/* Grease Pencil layer to use. */
prop = RNA_def_int(ot->srna, "layer", 0, -1, INT_MAX, "Grease Pencil Layer", "", -1, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
RNA_def_string(
Member

This prop should be removed now.

This prop should be removed now.
mendio marked this conversation as resolved
Falk David reviewed 2024-01-19 11:40:48 +01:00
@ -1605,0 +1697,4 @@
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* Grease Pencil layer to use. */
prop = RNA_def_int(ot->srna, "layer", 0, -1, INT_MAX, "Grease Pencil Layer", "", -1, INT_MAX);
Member

It might make more sense to make this a RNA_def_string with the layer_name. Because the layer that we move to always has to exist.

It might make more sense to make this a `RNA_def_string` with the `layer_name`. Because the layer that we move to always has to exist.
Author
Member

maybe I don't get what is your idea. Right now layer property stores the layer index and that is what we use in grease_pencil_move_to_layer_exec to determine the target layer. The property that there is no longer needed is new_layer_name because now we use layer_add operator to handle adding layers.

maybe I don't get what is your idea. Right now `layer` property stores the layer index and that is what we use in `grease_pencil_move_to_layer_exec` to determine the target layer. The property that there is no longer needed is `new_layer_name` because now we use `layer_add` operator to handle adding layers.
Member

Yes I'm not talking about the new_layer_name. I mean that the layer (or maybe a better name would be target_layer) that we move the selection into could be a string property with the name rather than an index. Maybe that makes the setup for the macro a bit easier (since we'd need to find the index of the newly added layer, but we know the name already).

Yes I'm not talking about the `new_layer_name`. I mean that the `layer` (or maybe a better name would be `target_layer`) that we move the selection into could be a `string` property with the name rather than an index. Maybe that makes the setup for the macro a bit easier (since we'd need to find the index of the newly added layer, but we know the name already).
Author
Member

I see, just updated the grease_pencil_move_to_layer_exec to use an string property.
I guess we only have to tackle the macro. Do you have a sample for me to see?

I see, just updated the `grease_pencil_move_to_layer_exec` to use an string property. I guess we only have to tackle the macro. Do you have a sample for me to see?
Matias Mendiola added 2 commits 2024-01-19 13:16:49 +01:00
Matias Mendiola added 1 commit 2024-01-19 14:08:25 +01:00
Matias Mendiola added 1 commit 2024-01-19 18:06:26 +01:00
Matias Mendiola added 1 commit 2024-01-19 18:11:41 +01:00
Matias Mendiola added 1 commit 2024-01-19 19:03:57 +01:00
Pratik Borhade approved these changes 2024-01-20 07:10:19 +01:00
Pratik Borhade left a comment
Member

Thanks. Looks correct to me :)

Falk/Hans may have some suggestions

Thanks. Looks correct to me :) Falk/Hans may have some suggestions
Falk David requested changes 2024-01-23 16:51:30 +01:00
Falk David left a comment
Member

It looks like the option to move the strokes to a new layer has not be implemented yet. I would add this operator macro in this PR as well. It should only require a few lines.

It looks like the option to move the strokes to a new layer has not be implemented yet. I would add this operator macro in this PR as well. It should only require a few lines.
Member

It looks like the option to move the strokes to a new layer has not be implemented yet.

By default selected strokes are moved to new/chosen layer here (like legacy operator). Maybe I'm misunderstanding your request? 🙂

Edit: Ah got it, "new" layer 😅

> It looks like the option to move the strokes to a new layer has not be implemented yet. By default selected strokes are moved to new/chosen layer here (like legacy operator). Maybe I'm misunderstanding your request? 🙂 Edit: Ah got it, "new" layer 😅
Matias Mendiola added 1 commit 2024-02-02 14:42:03 +01:00
Matias Mendiola added 4 commits 2024-02-02 21:47:40 +01:00
Author
Member

I started to implement the macro to add a new layer and move the strokes.
The code still have problems, the macro adds the new layer but GREASE_PENCIL_OT_move_to_layer is not executed

I started to implement the macro to add a new layer and move the strokes. The code still have problems, the macro adds the new layer but `GREASE_PENCIL_OT_move_to_layer` is not executed
Falk David added 1 commit 2024-02-05 11:58:35 +01:00
Member

@mendio I updated the code since I couldn't make the macro work nicely. It was breaking when the new layer name was already taken by a layer. I replaced the logic with a boolean property on the move_to_layer operator that adds a layer (similar to what was there before). Sorry for the trouble.

@mendio I updated the code since I couldn't make the macro work nicely. It was breaking when the new layer name was already taken by a layer. I replaced the logic with a boolean property on the `move_to_layer` operator that adds a layer (similar to what was there before). Sorry for the trouble.
Falk David approved these changes 2024-02-05 12:01:29 +01:00
Falk David merged commit dcc5725741 into main 2024-02-05 12:03:11 +01:00
Falk David referenced this issue from a commit 2024-02-05 12:03:11 +01:00
Matias Mendiola deleted branch GPv3_OP_Move_to_layer 2024-02-05 15:38:53 +01:00
Jonas Dichelle referenced this issue from a commit 2024-02-08 17:29:08 +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
4 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#117244
No description provided.