235 lines
9.7 KiB
Python
235 lines
9.7 KiB
Python
import json
|
|
import bpy
|
|
from bpy.props import StringProperty, EnumProperty
|
|
from bpy_types import Operator
|
|
from ...core.helpers_collections import set_active_collection
|
|
from .constants import HIDDEN_COMPONENTS
|
|
|
|
def select_area(context, area_name):
|
|
for area in context.screen.areas:
|
|
#if area.type == 'PROPERTIES' and context.object is not None and context.object.type not in ('LIGHT_PROBE', 'CAMERA', 'LIGHT', 'SPEAKER'):
|
|
# Set it the active space
|
|
#print("SELECT AREA", area_name)
|
|
try:
|
|
area.spaces.active.context = area_name #'MATERIAL' # 'VIEW_LAYER', 'SCENE' etc.
|
|
except Exception as error:
|
|
print(f"failed to switch to area {area_name}: {error}")
|
|
break # OPTIONAL
|
|
|
|
def get_collection_scene(collection):
|
|
for scene in bpy.data.scenes:
|
|
if scene.user_of_id(collection):
|
|
return scene
|
|
return None
|
|
|
|
def get_object_by_name(name):
|
|
object = bpy.data.objects.get(name, None)
|
|
return object
|
|
|
|
def get_object_scene(object):
|
|
object = bpy.data.objects.get(object.name, None)
|
|
if object is not None:
|
|
scenes_of_object = list(object.users_scene)
|
|
if len(scenes_of_object) > 0:
|
|
return scenes_of_object[0]
|
|
return None
|
|
|
|
def get_mesh_object(mesh):
|
|
for object in bpy.data.objects:
|
|
if isinstance(object.data, bpy.types.Mesh) and mesh.name == object.data.name:
|
|
return object
|
|
|
|
def get_material_object(material):
|
|
for object in bpy.data.objects:
|
|
if isinstance(object.data, bpy.types.Mesh) and material.name in object.data.materials:
|
|
return object
|
|
|
|
|
|
class BLENVY_OT_item_select(Operator):
|
|
"""Select object by name"""
|
|
bl_idname = "blenvy.select_item"
|
|
bl_label = "Select item (object or collection)"
|
|
bl_options = {"UNDO"}
|
|
|
|
item_type : EnumProperty(
|
|
name="item type",
|
|
description="type of the item to select: object or collection",
|
|
items=(
|
|
('OBJECT', "Object", ""),
|
|
('COLLECTION', "Collection", ""),
|
|
('MESH', "Mesh", ""),
|
|
('MATERIAL', "Material", ""),
|
|
),
|
|
default="OBJECT"
|
|
) # type: ignore
|
|
|
|
target_name: StringProperty(
|
|
name="target name",
|
|
description="target to select's name ",
|
|
) # type: ignore
|
|
|
|
override_scene_name: StringProperty(
|
|
name="override scene name",
|
|
description="use this to override the scene selection mecanism",
|
|
default=""
|
|
) # type: ignore
|
|
|
|
|
|
@classmethod
|
|
def register(cls):
|
|
bpy.types.WindowManager.blenvy_item_selected_ids = StringProperty(default="{}")
|
|
|
|
|
|
@classmethod
|
|
def unregister(cls):
|
|
del bpy.types.WindowManager.blenvy_item_selected_ids
|
|
|
|
|
|
def execute(self, context):
|
|
|
|
if self.target_name:
|
|
if self.item_type == 'OBJECT':
|
|
object = bpy.data.objects[self.target_name]
|
|
scenes_of_object = list(object.users_scene)
|
|
if len(scenes_of_object) > 0:
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
bpy.context.window.scene = scenes_of_object[0]
|
|
object.select_set(True)
|
|
context.window_manager.blenvy_item_selected_ids = json.dumps({"name": object.name, "type": self.item_type})
|
|
|
|
bpy.context.view_layer.objects.active = object
|
|
select_area(context=context, area_name="OBJECT")
|
|
|
|
elif self.item_type == 'COLLECTION':
|
|
collection = bpy.data.collections[self.target_name]
|
|
scene_of_collection = get_collection_scene(collection) if self.override_scene_name == "" else bpy.data.scenes.get(self.override_scene_name, None)
|
|
if scene_of_collection is not None:
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
bpy.context.window.scene = scene_of_collection
|
|
#bpy.context.view_layer.objects.active = None
|
|
context.window_manager.blenvy_item_selected_ids = json.dumps({"name": collection.name, "type": self.item_type})
|
|
set_active_collection(bpy.context.window.scene, collection.name)
|
|
|
|
#select_area(context=context, area_name="COLLECTION")
|
|
|
|
elif self.item_type == 'MESH':
|
|
mesh = bpy.data.meshes[self.target_name]
|
|
mesh_object = get_mesh_object(mesh)
|
|
scene_of_item = get_object_scene(mesh_object)
|
|
if scene_of_item is not None:
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
bpy.context.window.scene = scene_of_item
|
|
bpy.context.view_layer.objects.active = mesh_object
|
|
|
|
context.window_manager.blenvy_item_selected_ids = json.dumps({"name": mesh.name, "type": self.item_type})
|
|
select_area(context=context, area_name="DATA")
|
|
|
|
elif self.item_type == 'MATERIAL':
|
|
# find object that uses material
|
|
material = bpy.data.materials[self.target_name]
|
|
material_object = get_material_object(material)
|
|
scene_of_item = get_object_scene(material_object)
|
|
select_area(context=context, area_name="MATERIAL")
|
|
if scene_of_item is not None:
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
bpy.context.window.scene = scene_of_item
|
|
bpy.context.view_layer.objects.active = material_object
|
|
|
|
context.window_manager.blenvy_item_selected_ids = json.dumps({"name": material.name, "type": self.item_type})
|
|
|
|
select_area(context=context, area_name="MATERIAL")
|
|
|
|
return {'FINISHED'}
|
|
|
|
def get_selected_item(context):
|
|
selection = None
|
|
|
|
def get_outliner_area():
|
|
if bpy.context.area.type!='OUTLINER':
|
|
for area in bpy.context.screen.areas:
|
|
if area.type == 'OUTLINER':
|
|
return area
|
|
return None
|
|
#print("original context", context)
|
|
|
|
|
|
|
|
if selection is None:
|
|
area = get_outliner_area()
|
|
if area is not None:
|
|
region = next(region for region in area.regions if region.type == "WINDOW")
|
|
with bpy.context.temp_override(area=area, region=region):
|
|
#print("overriden context", bpy.context)
|
|
"""for obj in bpy.context.selected_ids:
|
|
print(f"Selected: {obj.name} - {type(obj)}")"""
|
|
number_of_selections = len(bpy.context.selected_ids)
|
|
selection = bpy.context.selected_ids[number_of_selections - 1] if number_of_selections > 0 else None #next(iter(bpy.context.selected_ids), None)
|
|
|
|
|
|
|
|
if selection is None:
|
|
number_of_selections = len(context.selected_objects)
|
|
selection = context.selected_objects[number_of_selections - 1] if number_of_selections > 0 else None
|
|
|
|
if selection is None:
|
|
try:
|
|
selection_overrides = json.loads(context.window_manager.blenvy_item_selected_ids)
|
|
#print("selection_overrides", selection_overrides)
|
|
if selection_overrides["type"] == "OBJECT":
|
|
selection = bpy.data.objects[selection_overrides["name"]]
|
|
elif selection_overrides["type"] == "COLLECTION":
|
|
selection = bpy.data.collections[selection_overrides["name"]]
|
|
if selection_overrides["type"] == "MESH":
|
|
selection = bpy.data.meshes[selection_overrides["name"]]
|
|
elif selection_overrides["type"] == "MATERIAL":
|
|
selection = bpy.data.materials[selection_overrides["name"]]
|
|
#print("SELECTION", selection)
|
|
#context.window_manager.blenvy_item_selected_ids = "{}"
|
|
except: pass
|
|
return selection
|
|
|
|
|
|
def get_selection_type(selection):
|
|
#print("bla mesh", isinstance(selection, bpy.types.Mesh), "bli bli", selection.type)
|
|
if isinstance(selection, bpy.types.Material):
|
|
return 'MATERIAL'
|
|
if isinstance(selection, bpy.types.Mesh):
|
|
return 'MESH'
|
|
if isinstance(selection, bpy.types.Object):
|
|
return 'OBJECT'
|
|
if isinstance(selection, bpy.types.Collection):
|
|
return 'COLLECTION'
|
|
|
|
def get_item_by_type(item_type, item_name):
|
|
item = None
|
|
if item_type == 'OBJECT':
|
|
item = bpy.data.objects[item_name]
|
|
elif item_type == 'COLLECTION':
|
|
item = bpy.data.collections[item_name]
|
|
elif item_type == "MESH":
|
|
item = bpy.data.meshes[item_name]
|
|
elif item_type == 'MATERIAL':
|
|
item = bpy.data.materials[item_name]
|
|
return item
|
|
|
|
def add_component_to_ui_list(self, context, _):
|
|
items = []
|
|
type_infos = context.window_manager.components_registry.type_infos
|
|
for long_name in type_infos.keys():
|
|
definition = type_infos[long_name]
|
|
short_name = definition["short_name"]
|
|
is_component = definition['isComponent'] if "isComponent" in definition else False
|
|
"""if self.filter.lower() in short_name.lower() and is_component:"""
|
|
if is_component and not 'Handle' in short_name and not "Cow" in short_name and not "AssetId" in short_name and short_name not in HIDDEN_COMPONENTS: # FIXME: hard coded, seems wrong
|
|
items.append((long_name, short_name))
|
|
items.sort(key=lambda a: a[1])
|
|
return items
|
|
|
|
|
|
def is_component_valid_and_enabled(object, component_name):
|
|
if "components_meta" in object or hasattr(object, "components_meta"):
|
|
target_components_metadata = object.components_meta.components
|
|
component_meta = next(filter(lambda component: component["long_name"] == component_name, target_components_metadata), None)
|
|
if component_meta is not None:
|
|
return component_meta.enabled and not component_meta.invalid
|
|
return True |