예제 #1
0
def bpy_data_ctor_lights(collection_name: str, proxy: DatablockProxy,
                         context: Context) -> Optional[T.ID]:
    collection = getattr(bpy.data, collection_name)
    name = proxy.data("name")
    light_type = proxy.data("type")
    light = collection.new(name, light_type)
    return light
예제 #2
0
def bpy_data_ctor_sounds(collection_name: str, proxy: DatablockProxy,
                         context: Context) -> Optional[T.ID]:
    collection = getattr(bpy.data, collection_name)
    filepath = proxy.data("filepath")
    # TODO what about "check_existing" ?
    id_ = collection.load(filepath)
    # we may have received an ID named xxx.001 although filepath is xxx, so fix it now
    id_.name = proxy.data("name")
    return id_
예제 #3
0
def pre_save_datablock(proxy: DatablockProxy, target: T.ID,
                       context: Context) -> T.ID:
    """Process attributes that must be saved first and return a possibly updated reference to the target"""

    # WARNING this is called from save() and from apply()
    # When called from save, the proxy has  all the synchronized properties
    # WHen called from apply, the proxy only contains the updated properties

    if target.library:
        return target

    #  animation_data is handled in StructProxy (parent class of DatablockProxy)

    if isinstance(target, T.Mesh):
        from mixer.blender_data.mesh_proxy import MeshProxy

        assert isinstance(proxy, MeshProxy)
        if proxy.requires_clear_geometry(target):
            target.clear_geometry()
    elif isinstance(target, T.Material):
        is_grease_pencil = proxy.data("is_grease_pencil")
        # will be None for a DeltaUpdate that does not modify "is_grease_pencil"
        if is_grease_pencil is not None:
            # Seems to be write once as no depsgraph update is fired
            if is_grease_pencil and not target.grease_pencil:
                bpy.data.materials.create_gpencil_data(target)
            elif not is_grease_pencil and target.grease_pencil:
                bpy.data.materials.remove_gpencil_data(target)
    elif isinstance(target, T.Scene):
        from mixer.blender_data.misc_proxies import NonePtrProxy

        sequence_editor = proxy.data("sequence_editor")
        if sequence_editor is not None:
            # NonePtrProxy or StructProxy
            if not isinstance(sequence_editor,
                              NonePtrProxy) and target.sequence_editor is None:
                target.sequence_editor_create()
            elif isinstance(
                    sequence_editor,
                    NonePtrProxy) and target.sequence_editor is not None:
                target.sequence_editor_clear()
    elif isinstance(target, _morphable_types):
        # required first to have access to new datablock attributes
        type_ = proxy.data("type")
        if type_ is not None and type_ != target.type:
            target.type = type_
            # must reload the reference
            target = target.type_recast()
            uuid = proxy.mixer_uuid
            context.proxy_state.remove_datablock(uuid)
            context.proxy_state.add_datablock(uuid, target)
    elif isinstance(target, T.Action):
        groups = proxy.data("groups")
        if groups:
            groups.save(target.groups, target, "groups", context)

    return target
예제 #4
0
파일: specifics.py 프로젝트: pypingyi/mixer
def _(collection_name: str, proxy: DatablockProxy,
      context: Context) -> T.VectorFont:
    name = proxy.data("name")
    filepath = proxy.data("filepath")

    if filepath != "<builtin>":
        raise NotImplementedError(f"non builtin font: {name}")

    dummy_text = bpy.data.curves.new("_mixer_tmp_text", "FONT")
    font = dummy_text.font
    bpy.data.curves.remove(dummy_text)
    return font
예제 #5
0
def pre_save_datablock(proxy: DatablockProxy, target: T.ID,
                       context: Context) -> T.ID:
    """Process attributes that must be saved first and return a possibly updated reference to the target"""

    # WARNING this is called from save() and from apply()
    # When called from save, the proxy has  all the synchronized properties
    # WHen called from apply, the proxy only contains the updated properties

    if target.library:
        return target

    if isinstance(target, T.Mesh) and proxy.requires_clear_geometry(target):
        target.clear_geometry()
    elif isinstance(target, T.Material):
        is_grease_pencil = proxy.data("is_grease_pencil")
        # will be None for a DeltaUpdate that does not modify "is_grease_pencil"
        if is_grease_pencil is not None:
            # Seems to be write once as no depsgraph update is fired
            if is_grease_pencil and not target.grease_pencil:
                bpy.data.materials.create_gpencil_data(target)
            elif not is_grease_pencil and target.grease_pencil:
                bpy.data.materials.remove_gpencil_data(target)
    elif isinstance(target, T.Scene):
        from mixer.blender_data.misc_proxies import NonePtrProxy

        sequence_editor = proxy.data("sequence_editor")
        if sequence_editor is not None:
            # NonePtrProxy or StructProxy
            if not isinstance(sequence_editor,
                              NonePtrProxy) and target.sequence_editor is None:
                target.sequence_editor_create()
            elif isinstance(
                    sequence_editor,
                    NonePtrProxy) and target.sequence_editor is not None:
                target.sequence_editor_clear()
    elif isinstance(target, T.Light):
        # required first to have access to new light type attributes
        light_type = proxy.data("type")
        if light_type is not None and light_type != target.type:
            target.type = light_type
            # must reload the reference
            target = proxy.target(context)

    return target
예제 #6
0
파일: specifics.py 프로젝트: pypingyi/mixer
def _(collection_name: str, proxy: DatablockProxy,
      context: Context) -> Optional[T.ID]:
    collection = getattr(bpy.data, collection_name)
    media = None
    media_name = proxy.data("name")
    filepath = proxy.data("filepath")

    resolved_filepath = proxy.resolved_filepath(context)
    if resolved_filepath is None:
        return None

    packed_files = proxy.data("packed_files")
    if packed_files is not None and packed_files.length:
        if collection_name == "images":
            width, height = proxy.data("size")
            try:
                with open(resolved_filepath, "rb") as file_:
                    buffer = file_.read()
                media = collection.new(media_name, width, height)
                media.pack(data=buffer, data_len=len(buffer))
            except RuntimeError as e:
                logger.warning(
                    f'Cannot load packed file original "{filepath}"", resolved "{resolved_filepath}". Exception: '
                )
                logger.warning(f"... {e}")
                raise ExternalFileFailed from e

    else:
        try:
            media = collection.load(resolved_filepath)
            media.name = media_name
        except RuntimeError as e:
            logger.warning(
                f'Cannot load file original "{filepath}"", resolved "{resolved_filepath}". Exception: '
            )
            logger.warning(f"... {e}")
            raise ExternalFileFailed from e

    # prevent filepath to be overwritten by the incoming proxy value as it would attempt to reload the file
    # from the incoming path that may not exist
    proxy._data["filepath"] = resolved_filepath
    proxy._data["filepath_raw"] = resolved_filepath
    return media
예제 #7
0
파일: specifics.py 프로젝트: pypingyi/mixer
def _(collection_name: str, proxy: DatablockProxy,
      context: Context) -> Optional[T.ID]:
    from mixer.blender_data.datablock_ref_proxy import DatablockRefProxy
    from mixer.blender_data.misc_proxies import NonePtrProxy

    collection = getattr(bpy.data, collection_name)
    name = proxy.data("name")
    data_datablock = None
    data_proxy = proxy.data("data")
    if isinstance(data_proxy, DatablockRefProxy):
        data_datablock = data_proxy.target(context)
    elif isinstance(data_proxy, NonePtrProxy):
        data_datablock = None
    else:
        # error on the sender side
        logger.warning(
            f"bpy.data.objects[{name}].data proxy is a {data_proxy.__class__}."
        )
        logger.warning("... loaded as Empty")
        data_datablock = None

    return collection.new(name, data_datablock)
예제 #8
0
파일: specifics.py 프로젝트: pypingyi/mixer
def bpy_data_ctor(collection_name: str, proxy: DatablockProxy,
                  context: Any) -> Optional[T.ID]:
    """
    Create an element in a bpy.data collection.

    Contains collection-specific code is the mathod to add an element is not new(name: str)
    """
    collection = getattr(bpy.data, collection_name)
    name = proxy.data("name")
    try:
        id_ = collection.new(name)
    except Exception as e:
        logger.error(
            f"Exception while calling : bpy.data.{collection_name}.new({name})"
        )
        logger.error(f"... {e!r}")
        return None

    return id_
예제 #9
0
파일: specifics.py 프로젝트: nondejus/mixer
def bpy_data_ctor(collection_name: str, proxy: DatablockProxy,
                  context: Any) -> Optional[T.ID]:
    """
    Create an element in a bpy.data collection.

    Contains collection-specific code is the mathod to add an element is not new(name: str)
    """
    collection = getattr(bpy.data, collection_name)
    if collection_name == "images":
        image = None
        image_name = proxy.data("name")
        filepath = proxy.data("filepath")
        resolved_filepath = get_resolved_file_path(filepath)
        packed_files = proxy.data("packed_files")
        if packed_files is not None and packed_files.length:
            name = proxy.data("name")
            width, height = proxy.data("size")
            try:
                with open(resolved_filepath, "rb") as image_file:
                    buffer = image_file.read()
                image = collection.new(name, width, height)
                image.pack(data=buffer, data_len=len(buffer))
            except RuntimeError as e:
                logger.warning(
                    f'Cannot load packed image original "{filepath}"", resolved "{resolved_filepath}". Exception: '
                )
                logger.warning(f"... {e}")
                return None

        else:
            try:
                image = collection.load(resolved_filepath)
                image.name = image_name
            except RuntimeError as e:
                logger.warning(
                    f'Cannot load image original "{filepath}"", resolved "{resolved_filepath}". Exception: '
                )
                logger.warning(f"... {e}")
                return None

        # prevent filepath to be overwritten by the incoming proxy value as it would attempt to reload the file
        # from the incoming path that may not exist
        proxy._data["filepath"] = resolved_filepath
        proxy._data["filepath_raw"] = resolved_filepath
        return image

    if collection_name == "objects":
        from mixer.blender_data.datablock_ref_proxy import DatablockRefProxy
        from mixer.blender_data.misc_proxies import NonePtrProxy

        name = proxy.data("name")
        target = None
        target_proxy = proxy.data("data")
        if isinstance(target_proxy, DatablockRefProxy):
            target = target_proxy.target(context)
        elif isinstance(target_proxy, NonePtrProxy):
            target = None
        else:
            # error on the sender side
            logger.warning(
                f"bpy.data.objects[{name}].data proxy is a {target_proxy.__class__}."
            )
            logger.warning("... loaded as Empty")
            target = None

        object_ = collection.new(name, target)
        return object_

    if collection_name == "lights":
        name = proxy.data("name")
        light_type = proxy.data("type")
        light = collection.new(name, light_type)
        return light

    if collection_name == "node_groups":
        name = proxy.data("name")
        type_ = node_tree_type[proxy.data("type")]
        return collection.new(name, type_)

    if collection_name == "sounds":
        filepath = proxy.data("filepath")
        # TODO what about "check_existing" ?
        id_ = collection.load(filepath)
        # we may have received an ID named xxx.001 although filepath is xxx, so fix it now
        id_.name = proxy.data("name")

        return id_

    if collection_name == "curves":
        name = proxy.data("name")
        return bpy.data.curves.new(name, "CURVE")

    name = proxy.data("name")
    try:
        id_ = collection.new(name)
    except TypeError as e:
        logger.error(
            f"Exception while calling : bpy.data.{collection_name}.new({name})"
        )
        logger.error(f"TypeError : {e!r}")
        return None

    return id_
예제 #10
0
파일: specifics.py 프로젝트: pypingyi/mixer
def _(collection_name: str, proxy: DatablockProxy,
      context: Context) -> Optional[T.ID]:
    collection = getattr(bpy.data, collection_name)
    name = proxy.data("name")
    curve_type = proxy._type_name
    return collection.new(name, _curve_ids[curve_type])
예제 #11
0
파일: specifics.py 프로젝트: pypingyi/mixer
def _(collection_name: str, proxy: DatablockProxy,
      context: Context) -> Optional[T.ID]:
    collection = getattr(bpy.data, collection_name)
    name = proxy.data("name")
    type_ = proxy.data("type")
    return collection.new(name, type_)
예제 #12
0
def bpy_data_ctor_curves(collection_name: str, proxy: DatablockProxy,
                         context: Context) -> Optional[T.ID]:
    collection = getattr(bpy.data, collection_name)
    name = proxy.data("name")
    return collection.new(name, "CURVE")
예제 #13
0
def bpy_data_ctor_node_groups(collection_name: str, proxy: DatablockProxy,
                              context: Context) -> Optional[T.ID]:
    collection = getattr(bpy.data, collection_name)
    name = proxy.data("name")
    type_ = node_tree_type[proxy.data("type")]
    return collection.new(name, type_)