JanErik
(Jan-Erik Arhelger)
January 25, 2023, 8:55am
1
Hey folks,
I want a dropdown for scenes, objects and viewlayers. Therefore I used the Pointer Property.
This works well for all types exept ViewLayer.
Can someone tell me why this is a valid pointer to a scene
bpy.types.Scene.job_scene = PointerProperty(
name="Scene",
type=bpy.types.Scene
)
but this isnt a valid pointer to a view layer?
bpy.types.ViewLayer = PointerProperty(
name="View Layer",
type=bpy.types.ViewLayer
)
Zyl
(Zyl)
January 25, 2023, 9:25am
2
CollectionProperty
and PointerProperty
can only contain types which inherit from bpy.types.ID
, which Scene
does, but ViewLayer
does not. The whole property system is dated and in urgent need of some work, which it does not seem to get. You will need to hack your way around to get whatever it is you want.
JanErik
(Jan-Erik Arhelger)
January 25, 2023, 9:54am
3
is there any way to get a pointer to a view layer then? Do you know a hacky way?
I would recommend you tag this as python support instead of Released Scripts and Themes
Also what is your actual objective a pointer to a scene or a pointer to a layer collection within a scene?
JanErik
(Jan-Erik Arhelger)
January 25, 2023, 11:56am
5
I wanted a dropdown to select currently available view layers.
For anyone who stumbles upon this topic in the future, you can create a custom enum like this:
vl: EnumProperty(
name="View Layer",
items=populate_enum
)
then create a custom function which checks the current scene and returns a list of the current vlayers:
def populate_enum(scene, context):
current_view_layers = []
for view_layer in bpy.context.scene.view_layers.items():
current_view_layers.append((view_layer[0],view_layer[0], ""),)
return current_view_layers
1 Like
I would suggest replacing bpy.context
with the passed context
, they may not always point to the same thing.
Also you’d likely want to store your enum function result somewhere to avoid the infamous dynamic enum bug
There are also alternatives that will mimic a drop down list.
Such as using a string with a search which would allow you to get different types of data.
# blender 3.4.1
import bpy
def coll_list(self, context, edit_text):
# always list all collection names
# coll_names = [coll.name for coll in context.scene.collection.children_recursive]
# restrict list by typing
coll_names = [coll.name for coll in context.scene.collection.children_recursive if coll.name.startswith(edit_text)]
return coll_names
def recurLayerCollection(layerColl, collName):
found = None
if (layerColl.name == collName):
return layerColl
for layer in layerColl.children:
found = recurLayerCollection(layer, collName)
if found:
return found
class TEST_PG_props(bpy.types.PropertyGroup):
coll_name: bpy.props.StringProperty(
search=coll_list)
my_mode: bpy.props.EnumProperty(
name="my_mode",
items=(
("collection", "collection", "collection"),
("View_layer", "View_layer", "View_layer"),
),
description="",
default="collection",
)
class TEST_PT_test_panel(bpy.types.Panel):
bl_idname = "TEST_PT_test_panel"
bl_label = "Test Panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Test Tab"
def draw(self, context):
my_props = context.window_manager.my_props
layout = self.layout
col = layout.column()
row = col.row()
row.prop(my_props, "my_mode", expand=True)
col.prop(my_props, "coll_name", text="name")
row = col.row()
if not my_props.coll_name:
return
if my_props.my_mode == 'collection':
tmp = bpy.data.collections.get(my_props.coll_name)
row.prop(tmp, "hide_select")
row.prop(tmp, "hide_viewport")
row.prop(tmp, "hide_render")
else:
tmp = recurLayerCollection(context.view_layer.layer_collection, my_props.coll_name)
row.prop(tmp, "exclude")
row.prop(tmp, "hide_viewport")
row.prop(tmp, "holdout")
row.prop(tmp, "indirect_only")
classes = [
TEST_PG_props,
TEST_PT_test_panel,
]
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.WindowManager.my_props = bpy.props.PointerProperty(
type=TEST_PG_props)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.WindowManager.my_props
if __name__ == "__main__":
register()
2 Likes