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
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]
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
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__"