Esempio n. 1
0
def remove_datablock(collection: T.bpy_prop_collection, datablock: T.ID):
    """Delete a datablock from its bpy.data collection"""
    if isinstance(datablock, T.Scene):
        from mixer.blender_client.scene import delete_scene

        delete_scene(datablock)
    elif isinstance(datablock, T.Key):
        # the doc labels it unsafe, use sparingly
        bpy.data.batch_remove([datablock])
    elif isinstance(datablock, T.Library):
        # TODO 2.91 has BlendDatalibraries.remove()
        logger.warning(f"remove_datablock({datablock}): ignored (library)")
    else:
        collection.remove(datablock)
    def create_datablock(
            self, incoming_proxy: DatablockProxy, context: Context
    ) -> Tuple[Optional[T.ID], Optional[RenameChangeset]]:
        """Create a bpy.data datablock from a received DatablockProxy and update the proxy structures accordingly

        Args:
            incoming_proxy : this proxy contents is used to update the bpy.data collection item
        """

        datablock, renames = incoming_proxy.create_standalone_datablock(
            context)
        # returned datablock is None for ShapeKey and Library. Datablock creation is deferred until :
        # - ShapeKey : Object update
        # - Library : creation of a link datablock

        if incoming_proxy.collection_name == "scenes":
            logger.info(
                f"Creating scene '{incoming_proxy.data('name')}' uuid: '{incoming_proxy.mixer_uuid}'"
            )

            # One existing scene from the document loaded at join time could not be removed during clear_scene_conten().
            # Remove it now
            scenes = bpy.data.scenes
            if len(scenes) == 2 and ("_mixer_to_be_removed_" in scenes):
                from mixer.blender_client.scene import delete_scene

                scene_to_remove = scenes["_mixer_to_be_removed_"]
                logger.info(
                    f"After create scene '{incoming_proxy.data('name_full')}' uuid: '{incoming_proxy.mixer_uuid}''"
                )
                logger.info(
                    f"... delete {scene_to_remove} uuid '{scene_to_remove.mixer_uuid}'"
                )
                delete_scene(scene_to_remove)

        uuid = incoming_proxy.mixer_uuid
        self._data[uuid] = incoming_proxy

        # TODO code placement is inconsistent with BpyDataProxy.remove_datablock()
        context.proxy_state.add_datablock(uuid, datablock)
        context.proxy_state.proxies[uuid] = incoming_proxy
        if datablock is not None:
            context.proxy_state.unresolved_refs.resolve(uuid, datablock)

        return datablock, renames
Esempio n. 3
0
    def remove_datablock(self, proxy: DatablockProxy, datablock: T.ID):
        """Remove a bpy.data collection item and update the proxy state"""
        logger.info("Perform removal for %s", proxy)
        try:
            if isinstance(datablock, T.Scene):
                from mixer.blender_client.scene import delete_scene

                delete_scene(datablock)
            else:
                proxy.collection.remove(datablock)
        except ReferenceError as e:
            # We probably have processed previously the deletion of a datablock referenced by Object.data (e.g. Light).
            # On both sides it deletes the Object as well. So the sender issues a message for object deletion
            # but deleting the light on this side has already deleted the object.
            # Alternatively we could try to sort messages on the sender side
            logger.warning(f"Exception during remove_datablock for {proxy}")
            logger.warning(f"... {e!r}")
        uuid = proxy.mixer_uuid()
        del self._data[uuid]
Esempio n. 4
0
    def create_datablock(
            self, incoming_proxy: DatablockProxy, context: Context
    ) -> Tuple[Optional[T.ID], Optional[RenameChangeset]]:
        """Create a bpy.data datablock from a received DatablockProxy and update the proxy structures accordingly

        Args:
            incoming_proxy : this proxy contents is used to update the bpy.data collection item
        """

        datablock, renames = incoming_proxy.create_standalone_datablock(
            context)

        if incoming_proxy.collection_name == "scenes":
            logger.warning(
                f"Creating scene '{incoming_proxy.data('name')}' uuid: '{incoming_proxy.mixer_uuid()}'"
            )

            # One existing scene from the document loaded at join time could not be removed during clear_scene_conten().
            # Remove it now
            scenes = bpy.data.scenes
            if len(scenes) == 2 and ("_mixer_to_be_removed_" in scenes):
                from mixer.blender_client.scene import delete_scene

                scene_to_remove = scenes["_mixer_to_be_removed_"]
                logger.warning(
                    f"After create scene '{incoming_proxy.data('name')}' uuid: '{incoming_proxy.mixer_uuid()}''"
                )
                logger.warning(
                    f"... delete {scene_to_remove} uuid '{scene_to_remove.mixer_uuid}'"
                )
                delete_scene(scene_to_remove)

        if not datablock:
            return None, None

        uuid = incoming_proxy.mixer_uuid()
        self._data[uuid] = incoming_proxy
        context.proxy_state.datablocks[uuid] = datablock
        context.proxy_state.proxies[uuid] = incoming_proxy

        context.proxy_state.unresolved_refs.resolve(uuid, datablock)
        return datablock, renames
Esempio n. 5
0
def clear_scene_content():
    """
    Clear data before joining a room.
    """

    from mixer.handlers import HandlerManager

    with HandlerManager(False):

        data = [
            "cameras",
            "collections",
            "curves",
            "grease_pencils",
            "images",
            "lights",
            "objects",
            "materials",
            "metaballs",
            "meshes",
            "textures",
            "worlds",
            "sounds",
        ]

        for name in data:
            collection = getattr(bpy.data, name)
            for obj in collection:
                collection.remove(obj)

        # Cannot remove the last scene at this point, treat it differently
        for scene in bpy.data.scenes[:-1]:
            scene_api.delete_scene(scene)

        share_data.clear_before_state()

        if len(bpy.data.scenes) == 1:
            scene = bpy.data.scenes[0]
            scene.name = "__last_scene_to_be_removed__"