def handler_on_undo_redo_post(scene, dummy): logger.info("on_undo_redo_post") share_data.set_dirty() share_data.clear_lists() # apply only in object mode if not is_in_object_mode(): return old_objects_name = dict([(k, None) for k in share_data.old_objects.keys() ]) # value not needed remap_objects_info() for k, v in share_data.old_objects.items(): if k in old_objects_name: old_objects_name[k] = v update_object_state(old_objects_name, share_data.old_objects) update_collections_state() update_scenes_state() remove_objects_from_scenes() remove_objects_from_collections() remove_collections_from_scenes() remove_collections_from_collections() remove_collections() remove_scenes() add_scenes() add_objects() add_collections() add_collections_to_scenes() add_collections_to_collections() add_objects_to_collections() add_objects_to_scenes() update_collections_parameters() create_vrtist_objects() delete_scene_objects() rename_objects() update_objects_visibility() update_objects_transforms() reparent_objects() # send selection content (including data) materials = set() for obj in bpy.context.selected_objects: update_transform(obj) if hasattr(obj, "data"): update_params(obj) if hasattr(obj, "material_slots"): for slot in obj.material_slots[:]: materials.add(slot.material) for material in materials: share_data.client.send_material(material) share_data.update_current_data()
def handler_on_undo_redo_post(scene, dummy): logger.error(f"Undo/redo post on {scene}") share_data.client.send_error( f"Undo/redo post from {get_mixer_prefs().user}") if not share_data.use_vrtist_protocol(): # Generic sync: reload all datablocks undone = share_data.bpy_data_proxy.snapshot_undo_post() logger.warning(f"undone uuids : {undone}") share_data.bpy_data_proxy.reload_datablocks() else: share_data.set_dirty() share_data.clear_lists() # apply only in object mode if not is_in_object_mode(): return old_objects_name = dict([ (k, None) for k in share_data.old_objects.keys() ]) # value not needed remap_objects_info() for k, v in share_data.old_objects.items(): if k in old_objects_name: old_objects_name[k] = v update_object_state(old_objects_name, share_data.old_objects) update_collections_state() update_scenes_state() remove_objects_from_scenes() remove_objects_from_collections() remove_collections_from_scenes() remove_collections_from_collections() remove_collections() add_scenes() add_objects() add_collections() add_collections_to_scenes() add_collections_to_collections() add_objects_to_collections() add_objects_to_scenes() update_collections_parameters() create_vrtist_objects() delete_scene_objects() rename_objects() update_objects_visibility() update_objects_constraints() update_objects_transforms() reparent_objects() # send selection content (including data) materials = set() for obj in bpy.context.selected_objects: update_transform(obj) if hasattr(obj, "data"): update_params(obj) if hasattr(obj, "material_slots"): for slot in obj.material_slots[:]: materials.add(slot.material) for material in materials: share_data.client.send_material(material) share_data.update_current_data()
def send_scene_data_to_server(scene, dummy): logger.debug( "send_scene_data_to_server(): skip_next_depsgraph_update %s, pending_test_update %s", share_data.client.skip_next_depsgraph_update, share_data.pending_test_update, ) if not share_data.client: logger.info("send_scene_data_to_server canceled (no client instance)") return share_data.set_dirty() share_data.clear_lists() depsgraph = bpy.context.evaluated_depsgraph_get() if depsgraph.updates: logger.debug("Current dg updates ...") for update in depsgraph.updates: logger.debug(" ......%s", update.id.original) # prevent processing self events, but always process test updates if not share_data.pending_test_update and share_data.client.skip_next_depsgraph_update: share_data.client.skip_next_depsgraph_update = False logger.debug( "send_scene_data_to_server canceled (skip_next_depsgraph_update = True) ..." ) return share_data.pending_test_update = False if not is_in_object_mode(): if depsgraph.updates: logger.info( "send_scene_data_to_server canceled (not is_in_object_mode). Skipping updates" ) for update in depsgraph.updates: logger.info(" ......%s", update.id.original) return update_object_state(share_data.old_objects, share_data.blender_objects) update_scenes_state() update_collections_state() changed = False changed |= remove_objects_from_collections() changed |= remove_objects_from_scenes() changed |= remove_collections_from_collections() changed |= remove_collections_from_scenes() changed |= remove_collections() changed |= add_scenes() changed |= add_collections() changed |= add_objects() changed |= update_transforms() changed |= add_collections_to_scenes() changed |= add_collections_to_collections() changed |= add_objects_to_collections() changed |= add_objects_to_scenes() changed |= update_collections_parameters() changed |= create_vrtist_objects() changed |= delete_scene_objects() changed |= rename_objects() changed |= update_objects_visibility() changed |= update_objects_constraints() changed |= update_objects_transforms() changed |= reparent_objects() changed |= shot_manager.check_montage_mode() if not changed: update_objects_data() # update for next change share_data.update_current_data() logger.debug("send_scene_data_to_server: end")
def send_scene_data_to_server(scene, dummy): logger.debug( "send_scene_data_to_server(): skip_next_depsgraph_update %s, pending_test_update %s", share_data.client.skip_next_depsgraph_update, share_data.pending_test_update, ) timer = share_data.current_stats_timer if not share_data.client: logger.info("send_scene_data_to_server canceled (no client instance)") return share_data.set_dirty() with timer.child("clear_lists"): share_data.clear_lists() depsgraph = bpy.context.evaluated_depsgraph_get() if depsgraph.updates: logger.debug("Current dg updates ...") for update in depsgraph.updates: logger.debug(" ......%s", update.id.original) # prevent processing self events, but always process test updates if not share_data.pending_test_update and share_data.client.skip_next_depsgraph_update: share_data.client.skip_next_depsgraph_update = False logger.debug("send_scene_data_to_server canceled (skip_next_depsgraph_update = True) ...") return share_data.pending_test_update = False if not is_in_object_mode(): logger.info("send_scene_data_to_server canceled (not is_in_object_mode)") return update_object_state(share_data.old_objects, share_data.blender_objects) with timer.child("update_scenes_state"): update_scenes_state() with timer.child("update_collections_state"): update_collections_state() changed = False with timer.child("checkForChangeAndSendUpdates"): changed |= remove_objects_from_collections() changed |= remove_objects_from_scenes() changed |= remove_collections_from_collections() changed |= remove_collections_from_scenes() changed |= remove_collections() changed |= remove_scenes() changed |= add_scenes() changed |= add_collections() changed |= add_objects() # Updates from the VRtist protocol and from the full Blender protocol must be cafully intermixed # This is an unfortunate requirements from the current coexistence status of # both protocols # After creation of meshes : meshes are not yet supported by full Blender protocol, # but needed to properly create objects # Before creation of objects : the VRtint protocol will implicitely create objects with # unappropriate default values (e.g. transform creates an object with no data) if share_data.use_experimental_sync(): # Compute the difference between the proxy state and the Blender state # It is a coarse difference at the ID level(created, removed, renamed) diff = BpyBlendDiff() diff.diff(share_data.proxy, safe_context) # Ask the proxy to compute the list of elements to synchronize and update itself depsgraph = bpy.context.evaluated_depsgraph_get() updates, removals = share_data.proxy.update(diff, safe_context, depsgraph.updates) # Send the data update messages (includes serialization) data_api.send_data_removals(removals) data_api.send_data_updates(updates) share_data.proxy.debug_check_id_proxies() # send the VRtist transforms after full Blender protocol has the opportunity to create the object data # that is not handled by VRtist protocol, otherwise the receiver creates an empty when it receives a transform changed |= update_transforms() changed |= add_collections_to_scenes() changed |= add_collections_to_collections() changed |= add_objects_to_collections() changed |= add_objects_to_scenes() changed |= update_collections_parameters() changed |= create_vrtist_objects() changed |= delete_scene_objects() changed |= rename_objects() changed |= update_objects_visibility() changed |= update_objects_transforms() changed |= reparent_objects() changed |= shot_manager.check_montage_mode() if not changed: with timer.child("update_objects_data"): update_objects_data() # update for next change with timer.child("update_current_data"): share_data.update_current_data() logger.debug("send_scene_data_to_server: end")