Blender Asked by Rakesh choudhary on December 26, 2021
I am trying to Draw Dynamic Enum property and I started using a one of the templates provided with the blender.
What I am trying to do: I have a Folder Test 2 in which I have 2 Folders –
and a __ init __.py in which I am drawing Enum.
I want to import icons from the Icons folder and for each icon, the object should be appended from the Objects.blend file present in the Blends folder.
my icons are cube, sphere, plane, Suzanne…., A cube should be appended when I select cube icon and hit add button, and similarly, the sphere should be appended when clicked on sphere icon (I have used cube, sphere, etc objects as an example, in future I will be replacing these object with the actual object I want to import).The object to be imported and icon for it has exactly the same name
If anyone wants to try complete file here is the link – To get files, Click here
So, this is my__ init __.py file –
bl_info = {
"name": "Add Object",
"author": "Rakesh",
"version": (1, 0),
"blender": (2, 83, 0),
"location": "View3D > Add > Mesh > New Object",
"description": "Adds a new Mesh Object",
"warning": "",
"category": "Add Mesh",
}
import bpy
import os
from bpy.types import (
Operator,
Panel,
PropertyGroup,
)
from bpy.props import *
import bpy.utils.previews
from bpy.types import WindowManager
class Object_OT_AddButton(Operator):
bl_idname = "add.object"
bl_label = "Add Object"
def execute(self, context):
selected_preview = bpy.data.window_managers["WinMan"].my_previews
category = context.scene.my_tool.cat
bpy.ops.wm.append(directory=os.path.join(os.path.dirname(__file__), "Blends" + os.sep + category +
".blend" + os.sep + "Object"), filepath=category + ".blend", filename=selected_preview)
return{'FINISHED'}
def update_category(self, context):
enum_previews_from_directory_items(self, context)
class Categories(PropertyGroup):
mesh_options = [
("Objects", "Objects", '', 0),
]
cat = bpy.props.EnumProperty(
items=mesh_options,
description="Select a Category",
default="Objects",
update=update_category
)
def enum_previews_from_directory_items(self, context):
category = context.scene.my_tool.cat
# Icons Directory
directory = os.path.join(os.path.dirname(
__file__), "Icons" + os.sep + category)
enum_items = []
if context is None:
return enum_items
wm = context.window_manager
directory = wm.my_previews_dir
# Get the preview collection (defined in register func).
pcoll = preview_collections["main"]
if directory == pcoll.my_previews_dir:
return pcoll.my_previews
print("Scanning directory: %s" % directory)
if directory and os.path.exists(directory):
# Scan the directory for png files
image_paths = []
for fn in os.listdir(directory):
if fn.lower().endswith(""):
image_paths.append(fn)
for i, name in enumerate(image_paths):
# generates a thumbnail preview for a file.
filepath = os.path.join(directory, name)
icon = pcoll.get(name)
if filepath in pcoll:
enum_items.append((name, name, "", pcoll[filepath].icon_id, i))
else:
thumb = pcoll.load(filepath, filepath, 'IMAGE')
enum_items.append((name, name, "", thumb.icon_id, i))
pcoll.my_previews = enum_items
pcoll.my_previews_dir = directory
return pcoll.my_previews
class PreviewsExamplePanel(Panel):
"""Creates a Panel in the Object properties window"""
bl_label = "Add object Panel"
bl_idname = "OBJECT_PT_previews"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
layout = self.layout
wm = context.window_manager
scene = context.scene
mytool = scene.my_tool
col = layout.column()
col.prop(context.scene.my_tool, "cat", text="Category")
row = layout.row()
row.template_icon_view(wm, "my_previews", show_labels=True)
row = layout.row()
row.operator("add.object", icon="RESTRICT_RENDER_OFF", text="Add")
# We can store multiple preview collections here,
# however in this example we only store "main"
preview_collections = {}
def register():
from bpy.types import WindowManager
from bpy.props import (
StringProperty,
EnumProperty,
)
WindowManager.my_previews_dir = StringProperty(
name="Folder Path",
subtype='DIR_PATH',
default=""
)
WindowManager.my_previews = EnumProperty(
items=enum_previews_from_directory_items,
)
import bpy.utils.previews
pcoll = bpy.utils.previews.new()
pcoll.my_previews_dir = ""
pcoll.my_previews = ()
preview_collections["main"] = pcoll
bpy.utils.register_class(Object_OT_AddButton)
bpy.utils.register_class(Categories)
bpy.types.Scene.my_tool = PointerProperty(type=Categories)
bpy.utils.register_class(PreviewsExamplePanel)
def unregister():
from bpy.types import WindowManager
del WindowManager.my_previews
for pcoll in preview_collections.values():
bpy.utils.previews.remove(pcoll)
preview_collections.clear()
bpy.utils.unregister_class(Object_OT_AddButton)
bpy.utils.unregister_class(Categories)
del bpy.types.Scene.my_tool
bpy.utils.unregister_class(PreviewsExamplePanel)
if __name__ == "__main__":
register()
Issues I am facing –
RuntimeError: Error: ‘C:UsersADMINAppDataRoamingBlender FoundationBlender2.83scriptsaddonstest2BlendsObjects.blendObject’: nothing indicated
location: < unknown location >:-1
This is what my panel looks like –
when I click that add button I get that error, the reason of the error what I believe is some thing is wrong in importing icons as icons are not imported and without selecting any icon i am clicking add and that gives the error –
RuntimeError: Error: ‘C:UsersADMINAppDataRoamingBlender
FoundationBlender2.83scriptsaddonstest2BlendsObjects.blendObject’:
nothing indicated
I am trying to achieve this type of Panel, In this panel, a particle system is added but I don’t want any particle system I just want the object to be appended to the scene when the icon from the dynamic enum is clicked.
Reference Image –
Looks like it was your file path causing issues. One thing I noticed, it doesn't show under addons ,but didn't take time to figure out why.
bl_info = {
"name": "Add Object",
"author": "Rakesh",
"version": (1, 0, 0),
"blender": (2, 83, 0),
"location": "View3D > Add > Mesh > New Object",
"description": "Adds a new Mesh Object",
"warning": "",
"category": "Add Mesh",
}
import bpy, os
from bpy.types import (
Operator,
Panel,
PropertyGroup,
)
from bpy.props import *
import bpy.utils.previews
from bpy.types import WindowManager
class Object_OT_AddButton(Operator):
bl_idname = "add.object"
bl_label = "Add Object"
def execute(self, context):
selected_preview = context.window_manager.my_previews
category = context.scene.my_tool.cat
user = bpy.utils.user_resource('SCRIPTS', "addons\test2\")
preview_no_ext = selected_preview.split('.')[0]
blendpath = category + ".blend"
blenddir = os.path.join(user + "Blends" + os.sep + category + ".blend" + os.sep + "Object\")
bpy.ops.wm.append(directory=blenddir, filepath=blendpath, filename=preview_no_ext)
return{'FINISHED'}
def update_category(self, context):
enum_previews_from_directory_items(self, context)
class Categories(PropertyGroup):
mesh_options = [
("Objects", "Objects", '', 0),
]
cat: bpy.props.EnumProperty(
items=mesh_options,
description="Select a Category",
default="Objects",
update=update_category
)
def enum_previews_from_directory_items(self, context):
category = context.scene.my_tool.cat
#Extensions
extensions = ('.jpeg', '.jpg', '.png')
# Icons Directory
directory = bpy.utils.user_resource('SCRIPTS', "addons\test2\Icons\")
enum_items = []
if context is None:
return enum_items
pcoll = preview_collections["main"]
if directory == pcoll.my_previews_dir:
return pcoll.my_previews
if directory and os.path.exists(directory):
# Scan the directory for png files
image_paths = []
for fn in os.listdir(directory):
if fn.lower().endswith(extensions):
image_paths.append(fn)
for i, name in enumerate(image_paths):
# generates a thumbnail preview for a file.
filepath = os.path.join(directory, name)
icon = pcoll.get(name)
if filepath in pcoll:
enum_items.append((name, name, "", pcoll[filepath].icon_id, i))
else:
thumb = pcoll.load(filepath, filepath, 'IMAGE')
enum_items.append((name, name, "", thumb.icon_id, i))
pcoll.my_previews = enum_items
pcoll.my_previews_dir = directory
return pcoll.my_previews
class PreviewsExamplePanel(Panel):
"""Creates a Panel in the Object properties window"""
bl_label = "Add object Panel"
bl_idname = "OBJECT_PT_previews"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
layout = self.layout
wm = context.window_manager
scene = context.scene
mytool = scene.my_tool
col = layout.column()
col.prop(context.scene.my_tool, "cat", text="Category")
row = layout.row()
row.template_icon_view(wm, "my_previews", show_labels=True)
row = layout.row()
row.operator("add.object", icon="RESTRICT_RENDER_OFF", text="Add")
# We can store multiple preview collections here,
# however in this example we only store "main"
preview_collections = {}
def register():
WindowManager.my_previews_dir = StringProperty(
name="Folder Path",
subtype='DIR_PATH',
default=""
)
WindowManager.my_previews = EnumProperty(
items=enum_previews_from_directory_items,
)
pcoll = bpy.utils.previews.new()
pcoll.my_previews_dir = ""
pcoll.my_previews = ()
preview_collections["main"] = pcoll
bpy.utils.register_class(Object_OT_AddButton)
bpy.utils.register_class(Categories)
bpy.types.Scene.my_tool = PointerProperty(type=Categories)
bpy.utils.register_class(PreviewsExamplePanel)
def unregister():
del WindowManager.my_previews
for pcoll in preview_collections.values():
bpy.utils.previews.remove(pcoll)
preview_collections.clear()
bpy.utils.unregister_class(Object_OT_AddButton)
bpy.utils.unregister_class(Categories)
del bpy.types.Scene.my_tool
bpy.utils.unregister_class(PreviewsExamplePanel)
if __name__ == "__main__":
register()
Answered by AFWS on December 26, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP