def read_attribute(attr: Any, key: Union[int, str], attr_property: T.Property, parent: T.bpy_struct, context: Context): """ Load a property into a python object of the appropriate type, be it a Proxy or a native python object """ try: return _read_builtin(attr) except _NotBuiltin: pass if isinstance(attr, set): from mixer.blender_data.misc_proxies import SetProxy return SetProxy().load(attr) context.visit_state.push(attr_property, key) try: from mixer.blender_data.misc_proxies import PtrToCollectionItemProxy attr_type = type(attr) if attr_type == T.bpy_prop_collection: if hasattr(attr, "bl_rna") and isinstance( attr.bl_rna, (type(T.CollectionObjects.bl_rna), type(T.CollectionChildren.bl_rna))): from mixer.blender_data.datablock_collection_proxy import DatablockRefCollectionProxy return DatablockRefCollectionProxy().load(attr, context) elif is_soable_collection(attr_property): from mixer.blender_data.aos_proxy import AosProxy return AosProxy().load(attr, attr_property, context) else: # This code path is taken for collections that have an rna and collections that do not # There should probably be different proxies for collection with and without rna. # See comment in add_element() from mixer.blender_data.struct_collection_proxy import StructCollectionProxy return StructCollectionProxy.make(attr_property).load( attr, context) # TODO merge with previous case if isinstance(attr_property, T.CollectionProperty): from mixer.blender_data.struct_collection_proxy import StructCollectionProxy return StructCollectionProxy().load(attr, context) bl_rna = attr_property.bl_rna if bl_rna is None: logger.error("read_attribute: no implementation for ...") logger.error( f"... {context.visit_state.display_path()}.{key} (type: {type(attr)})" ) return None if issubclass(attr_type, T.PropertyGroup): from mixer.blender_data.struct_proxy import StructProxy return StructProxy.make(attr).load(attr, context) if issubclass(attr_type, T.ID): if attr.is_embedded_data: # Embedded datablocks are loaded as StructProxy and DatablockProxy is reserved # for standalone datablocks from mixer.blender_data.struct_proxy import StructProxy return StructProxy.make(attr).load(attr, context) else: # Standalone databocks are loaded from DatablockCollectionProxy, so we can only encounter # datablock references here from mixer.blender_data.datablock_ref_proxy import DatablockRefProxy return DatablockRefProxy().load(attr, context) proxy = PtrToCollectionItemProxy.make(type(parent), key) if proxy is not None: return proxy.load(attr) if issubclass(attr_type, T.bpy_struct): from mixer.blender_data.struct_proxy import StructProxy return StructProxy.make(attr).load(attr, context) if attr is None: from mixer.blender_data.misc_proxies import NonePtrProxy return NonePtrProxy() logger.error("read_attribute: no implementation for ...") logger.error( f"... {context.visit_state.display_path()}.{key} (type: {type(attr)})" ) finally: context.visit_state.pop()
def read_attribute(attr: Any, key: Union[int, str], attr_property: T.Property, context: Context): """ Load a property into a python object of the appropriate type, be it a Proxy or a native python object """ attr_type = type(attr) if is_builtin(attr_type): return attr if is_vector(attr_type): return list(attr) if is_matrix(attr_type): return [list(col) for col in attr.col] # We have tested the types that are usefully reported by the python binding, now harder work. # These were implemented first and may be better implemented with the bl_rna property of the parent struct # TODO flatten if attr_type == T.bpy_prop_array: return list(attr) try: context.visit_state.recursion_guard.push(attr_property.identifier) if attr_type == T.bpy_prop_collection: if isinstance(attr_property.fixed_type, bpy.types.ID): from mixer.blender_data.datablock_collection_proxy import DatablockRefCollectionProxy return DatablockRefCollectionProxy().load(attr, key, context) elif is_soable_collection(attr_property): from mixer.blender_data.aos_proxy import AosProxy return AosProxy().load(attr, key, attr_property, context) else: from mixer.blender_data.struct_collection_proxy import StructCollectionProxy return StructCollectionProxy.make(attr_property).load( attr, key, attr_property, context) # TODO merge with previous case if isinstance(attr_property, T.CollectionProperty): from mixer.blender_data.struct_collection_proxy import StructCollectionProxy return StructCollectionProxy().load(attr, key, attr_property, context) bl_rna = attr_property.bl_rna if bl_rna is None: logger.warning("Not implemented: attribute %s", attr) return None if issubclass(attr_type, T.PropertyGroup): from mixer.blender_data.struct_proxy import StructProxy return StructProxy().load(attr, key, context) if issubclass(attr_type, T.ID): if attr.is_embedded_data: from mixer.blender_data.datablock_proxy import DatablockProxy return DatablockProxy.make(attr_property).load( attr, key, context) else: from mixer.blender_data.datablock_ref_proxy import DatablockRefProxy return DatablockRefProxy().load(attr, key, context) if issubclass(attr_type, T.bpy_struct): from mixer.blender_data.struct_proxy import StructProxy return StructProxy().load(attr, key, context) if attr is None and isinstance(attr_property, T.PointerProperty): from mixer.blender_data.misc_proxies import NonePtrProxy return NonePtrProxy() logger.error( f"Unsupported attribute {attr_type} {attr_property} {attr_property.fixed_type} at {context.visit_state.datablock_proxy._class_name}.{context.visit_state.path}.{attr_property.identifier}" ) finally: context.visit_state.recursion_guard.pop()
def read_attribute(attr: Any, key: Union[int, str], attr_property: T.Property, context: Context): """ Load a property into a python object of the appropriate type, be it a Proxy or a native python object """ if isinstance(attr, _builtin_types): return attr attr_type = type(attr) if is_vector(attr_type): return list(attr) if is_matrix(attr_type): return [list(col) for col in attr.col] if isinstance(attr, set): from mixer.blender_data.misc_proxies import SetProxy return SetProxy().load(attr) # We have tested the types that are usefully reported by the python binding, now harder work. # These were implemented first and may be better implemented with the bl_rna property of the parent struct # TODO flatten if attr_type == T.bpy_prop_array: return list(attr) context.visit_state.recursion_guard.push(attr_property.identifier) try: from mixer.blender_data.misc_proxies import PtrToCollectionItemProxy if attr_type == T.bpy_prop_collection: if hasattr(attr, "bl_rna") and isinstance( attr.bl_rna, (type(T.CollectionObjects.bl_rna), type(T.CollectionChildren.bl_rna))): from mixer.blender_data.datablock_collection_proxy import DatablockRefCollectionProxy return DatablockRefCollectionProxy().load(attr, key, context) elif is_soable_collection(attr_property): from mixer.blender_data.aos_proxy import AosProxy return AosProxy().load(attr, key, attr_property, context) else: from mixer.blender_data.struct_collection_proxy import StructCollectionProxy return StructCollectionProxy.make(attr_property).load( attr, key, attr_property, context) # TODO merge with previous case if isinstance(attr_property, T.CollectionProperty): from mixer.blender_data.struct_collection_proxy import StructCollectionProxy return StructCollectionProxy().load(attr, key, attr_property, context) bl_rna = attr_property.bl_rna if bl_rna is None: logger.error("read_attribute: no implementation for ...") logger.error( f"... {context.visit_state.display_path()}.{key} (type: {type(attr)})" ) return None if issubclass(attr_type, T.PropertyGroup): from mixer.blender_data.struct_proxy import StructProxy return StructProxy().load(attr, key, context) if issubclass(attr_type, T.ID): if attr.is_embedded_data: # Embedded datablocks are loaded as StructProxy and DatablockProxy is reserved # for standalone datablocks from mixer.blender_data.struct_proxy import StructProxy return StructProxy().load(attr, key, context) else: # Standalone databocks are loaded from DatablockCollectionProxy, so we can only encounter # datablock references here from mixer.blender_data.datablock_ref_proxy import DatablockRefProxy return DatablockRefProxy().load(attr, key, context) proxy = PtrToCollectionItemProxy.make(attr_type, key) if proxy: return proxy.load(attr) if issubclass(attr_type, T.bpy_struct): from mixer.blender_data.struct_proxy import StructProxy return StructProxy().load(attr, key, context) if attr is None: from mixer.blender_data.misc_proxies import NonePtrProxy return NonePtrProxy() logger.error("read_attribute: no implementation for ...") logger.error( f"... {context.visit_state.display_path()}.{key} (type: {type(attr)})" ) finally: context.visit_state.recursion_guard.pop()