Unable to select multiple Grease Pencil layers with Python #103329

Open
opened 2022-12-19 04:00:20 +01:00 by Bun ny · 25 comments

System Information
Operating system:
Graphics card:

Blender Version
Broken: 3.4
Worked:

Short description of error
Setting the Grease Pencil Layer property "select" with Python doesn't seem to work. Tried various update tags with no luck. Similar layer properties, such as the booleans "lock" and "hide", work as expected with the same code as below.

Exact steps for others to reproduce the error
select_bug.blend
Open Blender from a console/terminal and keep that window in view, open the attached .blend, click the play button in the Text Editor header to run the example script (which sets all layers' select property to True), then hover the mouse cursor over the Python console and press Enter to run the command: print([gpl for gpl in bpy.context.object.data.layers if gpl.select])

**System Information** Operating system: Graphics card: **Blender Version** Broken: 3.4 Worked: **Short description of error** Setting the Grease Pencil Layer property "select" with Python doesn't seem to work. Tried various update tags with no luck. Similar layer properties, such as the booleans "lock" and "hide", work as expected with the same code as below. **Exact steps for others to reproduce the error** [select_bug.blend](https://archive.blender.org/developer/F14071553/select_bug.blend) Open Blender from a console/terminal and keep that window in view, open the attached .blend, click the play button in the Text Editor header to run the example script (which sets all layers' select property to True), then hover the mouse cursor over the Python console and press Enter to run the command: print([gpl for gpl in bpy.context.object.data.layers if gpl.select])
Author

Added subscriber: @bunny

Added subscriber: @bunny

#104226 was marked as duplicate of this issue

#104226 was marked as duplicate of this issue

Added subscriber: @mano-wii

Added subscriber: @mano-wii

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'

The code returns as expected, but it seems that some update is missing.

The code returns as expected, but it seems that some update is missing.

Added subscriber: @antoniov

Added subscriber: @antoniov

@bunny what you want to do? select the layer in the properties list? First, you can select only one layer at time and this is done using layer active_index. The select is a property for the internal Dopesheet channel selection but is not related to the grease pencil active layer.

@bunny what you want to do? select the layer in the properties list? First, you can select only one layer at time and this is done using layer `active_index`. The `select` is a property for the internal Dopesheet channel selection but is not related to the grease pencil active layer.
Author

When animating, I interact with layers exclusively in the Dope Sheet, where multiple layers can be selected by shift-clicking the channels in a familiar way.
I've written operators and app handlers which live in the Dope Sheet and affect all such selected layers by using the list comprehension [gpl for gpl in gpd.layers if gpl.select] to mimic context access. That works great when everything is contained within a single execute function, but what I want to do is be able to select layers in the Dope Sheet (which match some potentially complex condition) with one operator and then operate on those selected layers with a different operator -- one even belonging to an entirely separate addon.
This would make it possible to "chain" smaller operators as is possible elsewhere (a good example might be the Bone Selection Sets addon), even across different addons, rather than always having to have both the "select routine" and the "execute routine" in the same operator, which can end up causing code duplication and too many operator properties/arguments. For instance, often only the "select routine" is needed, when that select prop affects an app handler.

When animating, I interact with layers exclusively in the Dope Sheet, where multiple layers can be selected by shift-clicking the channels in a familiar way. I've written operators and app handlers which live in the Dope Sheet and affect all such selected layers by using the list comprehension [gpl for gpl in gpd.layers if gpl.select] to mimic context access. That works great when everything is contained within a single execute function, but what I want to do is be able to select layers in the Dope Sheet (which match some potentially complex condition) with one operator and then operate on those selected layers with a *different* operator -- one even belonging to an entirely separate addon. This would make it possible to "chain" smaller operators as is possible elsewhere (a good example might be the Bone Selection Sets addon), even across different addons, rather than always having to have both the "select routine" and the "execute routine" in the same operator, which can end up causing code duplication and too many operator properties/arguments. For instance, often only the "select routine" is needed, when that select prop affects an app handler.

Added subscriber: @amelief

Added subscriber: @amelief

@bunny If you want work with the dopesheet channels, then use the layers maybe is not the best solution. @amelief You know very well the dopesheet code. Could you advice how to do this in python? or maybe, you know what notifier is missing in the RNA code (line 1825 in rna_gpencil.c)

@bunny If you want work with the dopesheet channels, then use the layers maybe is not the best solution. @amelief You know very well the dopesheet code. Could you advice how to do this in python? or maybe, you know what notifier is missing in the RNA code (line `1825` in `rna_gpencil.c`)

If I understand correctly, it's about the select flag of the layer and not the frame (so it would be line 2236 instead of 1825 in rna_gpencil.c), right ?

I am not sure it's a missing notifier issue. Notifiers in are the same than for the lock flag, and that one is working properly.
Plus, if I open the standard "New 2D animation" file, and try to change selection of layer "Fills" in the console I get this :

>>> gp = C.active_object.data
>>> gp.layers['Fills'].select

False

>>> gp.layers['Fills'].select = True
>>> gp.layers['Fills'].select

False

So it seems that the flag is not updated at all.

If I understand correctly, it's about the `select` flag of the layer and not the frame (so it would be line `2236` instead of `1825` in `rna_gpencil.c`), right ? I am not sure it's a missing notifier issue. Notifiers in are the same than for the `lock` flag, and that one is working properly. Plus, if I open the standard "New 2D animation" file, and try to change selection of layer "Fills" in the console I get this : ``` >>> gp = C.active_object.data >>> gp.layers['Fills'].select False >>> gp.layers['Fills'].select = True >>> gp.layers['Fills'].select False ``` So it seems that the flag is not updated at all.

By the way, there is also a missing notifier for the selecttag of the frame.
I think this should be dealt with in another issue. It seems really easy to fix.

By the way, there is also a missing notifier for the `select`tag of the **frame**. I think this should be dealt with in another issue. It seems really easy to fix.
Member

Added subscriber: @lichtwerk

Added subscriber: @lichtwerk
Member

@amelief : this just seems to miss ND_ANIMCHAN | NA_EDITEDin the RNA_def_property_update

@amelief : this just seems to miss `ND_ANIMCHAN | NA_EDITED`in the `RNA_def_property_update`

@lichtwerk You are right, good catch ! :) I wonder if all notifiers flags are needed, cause now we'd have ND_ANIMCHAN | NA_EDITED | NC_GPENCIL | ND_DATA | NA_SELECTED

@lichtwerk You are right, good catch ! :) I wonder if all notifiers flags are needed, cause now we'd have `ND_ANIMCHAN | NA_EDITED | NC_GPENCIL | ND_DATA | NA_SELECTED`
Member

@amelief : in fact, just swapping NA_SELECTED with NA_EDITED is enough

So

RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_EDITED, "rna_GPencil_update");
@amelief : in fact, just swapping `NA_SELECTED` with `NA_EDITED` is enough So ``` RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_EDITED, "rna_GPencil_update"); ```

Perfect ! Do you want to do the patch for this @lichtwerk or should I do it ?
I will create an issue for frame selection update, and the fix diff for it.

Perfect ! Do you want to do the patch for this @lichtwerk or should I do it ? I will create an issue for frame selection update, and the fix diff for it.
Member

@amelief : go ahead. (it would still be nice to do a bit of digging in regards to why NA_SELECTED seems to work just fine on some layer props (active_index, lock, ...) but not on others, havent done this research... patch would probably go through without, but it is always good to justify changes with a proper reasoning)

@amelief : go ahead. (it would still be nice to do a bit of digging in regards to why `NA_SELECTED` seems to work just fine on some layer props (`active_index`, `lock`, ...) but not on others, havent done this research... patch would probably go through without, but it is always good to justify changes with a proper reasoning)

@lichtwerk Yes, I was thinking the same. Actually, for grease pencil api at least, it is only used for active and active_index, and not lock, which makes sense.
I do not know how this notifier flags work, I guess NA_SELECTED only checks the active elements in grease pencil and do not dig into selected frames/layers.

But then, for frame selection, NC_GPENCIL | ND_DATA seems to be enough, so it seems confusing (see D16832)

@lichtwerk Yes, I was thinking the same. Actually, for grease pencil api at least, it is only used for `active` and `active_index`, and not `lock`, which makes sense. I do not know how this notifier flags work, I guess `NA_SELECTED` only checks the active elements in grease pencil and do not dig into selected frames/layers. But then, for frame selection, `NC_GPENCIL | ND_DATA` seems to be enough, so it seems confusing (see [D16832](https://archive.blender.org/developer/D16832))
Member

The listener action_listener only has the difference of setting SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC (in case of NA_SELECTED vs NA_EDITED) As a consequence, animchan_sync_gplayer clears GP_LAYER_SELECT (when the layer is not also active)

The listener `action_listener` only has the difference of setting `SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC` (in case of `NA_SELECTED` vs `NA_EDITED`) As a consequence, `animchan_sync_gplayer` clears `GP_LAYER_SELECT` (when the layer is not also active)
Member

c5338fd162 is the relevant commit here.
So an idea would be to isolate SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC to actions actually involving changing the active status (and not do it for everything selection)

We could use the notifier action NA_ACTIVATED, to make this more explicit (note I havent tested this thouroughly)
P3405: T103329_snippet



diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 2f22121f7de..9883e3ad264 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -512,7 +512,7 @@ static void action_listener(const wmSpaceTypeListenerParams *params)
         if (wmn->action == NA_EDITED) {
           ED_area_tag_redraw(area);
         }
-        else if (wmn->action == NA_SELECTED) {
+        else if (wmn->action == NA_ACTIVATED) {
           saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
           ED_area_tag_refresh(area);
         }
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index cf02b8fe61c..d6050dd1a3f 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -2339,7 +2339,7 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
       prop, "rna_GPencil_active_layer_get", "rna_GPencil_active_layer_set", NULL, NULL);
   RNA_def_property_flag(prop, PROP_EDITABLE);
   RNA_def_property_ui_text(prop, "Active Layer", "Active grease pencil layer");
-  RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
+  RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_ACTIVATED, NULL);
 
   prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
   RNA_def_property_int_funcs(prop,
@@ -2347,7 +2347,7 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
                              "rna_GPencil_active_layer_index_set",
                              "rna_GPencil_active_layer_index_range");
   RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer");
-  RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
+  RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_ACTIVATED, NULL);
 
   /* Active Layer - As an enum (for selecting active layer for annotations) */
   prop = RNA_def_property(srna, "active_note", PROP_ENUM, PROP_NONE);

@antoniov , @amelief : mind giving this a good testrun? (seems to work as expected in simple test UI wise -- so clicking on channels will make the layer active in the Properties Editor, clicking on a layer in the Properties Editor wil select its channel plus the script presented here also works)

c5338fd162 is the relevant commit here. So an idea would be to isolate SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC to actions actually involving changing the `active` status (and not do it for everything `selection`) We could use the notifier action NA_ACTIVATED, to make this more explicit (note I havent tested this thouroughly) [P3405: T103329_snippet](https://archive.blender.org/developer/P3405.txt) ``` diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 2f22121f7de..9883e3ad264 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -512,7 +512,7 @@ static void action_listener(const wmSpaceTypeListenerParams *params) if (wmn->action == NA_EDITED) { ED_area_tag_redraw(area); } - else if (wmn->action == NA_SELECTED) { + else if (wmn->action == NA_ACTIVATED) { saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC; ED_area_tag_refresh(area); } diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index cf02b8fe61c..d6050dd1a3f 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -2339,7 +2339,7 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) prop, "rna_GPencil_active_layer_get", "rna_GPencil_active_layer_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Active Layer", "Active grease pencil layer"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_ACTIVATED, NULL); prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_funcs(prop, @@ -2347,7 +2347,7 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) "rna_GPencil_active_layer_index_set", "rna_GPencil_active_layer_index_range"); RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_ACTIVATED, NULL); /* Active Layer - As an enum (for selecting active layer for annotations) */ prop = RNA_def_property(srna, "active_note", PROP_ENUM, PROP_NONE); ``` @antoniov , @amelief : mind giving this a good testrun? (seems to work as expected in simple test UI wise -- so clicking on channels will make the layer active in the Properties Editor, clicking on a layer in the Properties Editor wil select its channel plus the script presented here also works)

Hey @lichtwerk , I've tested it and it seems to work. My only concern is that NA_SELECTED seems to be widely used in the code of grease pencil, especially when it comes to layers. So we actually have to go through each of them to se if they change the active flag or not. I can start on that, but it could take some time.

Hey @lichtwerk , I've tested it and it seems to work. My only concern is that `NA_SELECTED` seems to be widely used in the code of grease pencil, especially when it comes to layers. So we actually have to go through each of them to se if they change the `active` flag or not. I can start on that, but it could take some time.
Member

@amelief : thx testing! If you could check on NA_SELECTED (and possibly change the occurances where activation is required to NA_ACTIVATED) that would be awesome!

@amelief : thx testing! If you could check on `NA_SELECTED` (and possibly change the occurances where activation is required to `NA_ACTIVATED`) that would be awesome!

One thing that may be weird with our solution is that one layer could be selected while another is active (and not selected). In this case the interface shows unconsistent information, as in this image. Wouldn't that be an issue ? Maybe @antoniov you have an opinion on this.

inconsistent_layer_selection-annotated.png

I don't know how these things work with object selection for example

One thing that may be weird with our solution is that one layer could be selected while another is active (and not selected). In this case the interface shows unconsistent information, as in this image. Wouldn't that be an issue ? Maybe @antoniov you have an opinion on this. ![inconsistent_layer_selection-annotated.png](https://archive.blender.org/developer/F14082843/inconsistent_layer_selection-annotated.png) I don't know how these things work with object selection for example
Member

Added subscriber: @KevinCBurke

Added subscriber: @KevinCBurke
Philipp Oeser removed the
Interest
Grease Pencil
label 2023-02-09 15:19:07 +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
6 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#103329
No description provided.