Beispiel #1
0
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()
Beispiel #2
0
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()
Beispiel #3
0
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()