refactor: move clean to operator.py
feat: timeline action mapping for replay feat: persistent collection fix: draw users in the right scene according to the snapshot
This commit is contained in:
@ -67,10 +67,49 @@ deleyables = []
|
|||||||
stop_modal_executor = False
|
stop_modal_executor = False
|
||||||
|
|
||||||
|
|
||||||
|
CLEARED_DATABLOCKS = ['actions', 'armatures', 'cache_files', 'cameras',
|
||||||
|
'collections', 'curves', 'filepath', 'fonts',
|
||||||
|
'grease_pencils', 'images', 'lattices', 'libraries',
|
||||||
|
'lightprobes', 'lights', 'linestyles', 'masks',
|
||||||
|
'materials', 'meshes', 'metaballs', 'movieclips',
|
||||||
|
'node_groups', 'objects', 'paint_curves', 'particles',
|
||||||
|
'scenes', 'shape_keys', 'sounds', 'speakers', 'texts',
|
||||||
|
'textures', 'volumes', 'worlds']
|
||||||
|
|
||||||
|
PERSISTENT_DATABLOCKS = ['LineStyle', 'Dots Stroke', 'replay_action']
|
||||||
|
|
||||||
|
def clean_scene(ignored_datablocks: list = None):
|
||||||
|
"""
|
||||||
|
Delete all datablock of the scene except PERSISTENT_DATABLOCKS and ignored
|
||||||
|
ones in ignored_datablocks.
|
||||||
|
"""
|
||||||
|
PERSISTENT_DATABLOCKS.extend(ignored_datablocks)
|
||||||
|
# Avoid to trigger a runtime error by keeping the last scene
|
||||||
|
PERSISTENT_DATABLOCKS.append(bpy.data.scenes[0].name)
|
||||||
|
|
||||||
|
for type_name in CLEARED_DATABLOCKS:
|
||||||
|
type_collection = getattr(bpy.data, type_name)
|
||||||
|
for datablock in type_collection:
|
||||||
|
if datablock.name in PERSISTENT_DATABLOCKS:
|
||||||
|
logging.debug(f"Skipping {datablock.name}")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
logging.debug(f"Removing {datablock.name}")
|
||||||
|
type_collection.remove(datablock)
|
||||||
|
|
||||||
|
# Clear sequencer
|
||||||
|
bpy.context.scene.sequence_editor_clear()
|
||||||
|
|
||||||
|
|
||||||
def draw_user(username, metadata, radius=0.01, intensity=10.0):
|
def draw_user(username, metadata, radius=0.01, intensity=10.0):
|
||||||
|
"""
|
||||||
|
Generate a mesh representation of a given user frustum and
|
||||||
|
sight of view.
|
||||||
|
"""
|
||||||
view_corners = metadata.get('view_corners')
|
view_corners = metadata.get('view_corners')
|
||||||
color = metadata.get('color', (1,1,1,0))
|
color = metadata.get('color', (1,1,1,0))
|
||||||
objects = metadata.get('selected_objects', None)
|
objects = metadata.get('selected_objects', None)
|
||||||
|
scene = metadata.get('scene_current', bpy.context.scene.name)
|
||||||
|
|
||||||
user_collection = bpy.data.collections.new(username)
|
user_collection = bpy.data.collections.new(username)
|
||||||
|
|
||||||
@ -176,7 +215,7 @@ def draw_user(username, metadata, radius=0.01, intensity=10.0):
|
|||||||
|
|
||||||
bbox_mesh.materials.append(user_mat)
|
bbox_mesh.materials.append(user_mat)
|
||||||
|
|
||||||
bpy.context.scene.collection.children.link(user_collection)
|
bpy.data.scenes[scene].collection.children.link(user_collection)
|
||||||
|
|
||||||
|
|
||||||
def session_callback(name):
|
def session_callback(name):
|
||||||
@ -363,7 +402,7 @@ class SessionConnectOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
# Join a session
|
# Join a session
|
||||||
if not active_server.use_admin_password:
|
if not active_server.use_admin_password:
|
||||||
utils.clean_scene()
|
clean_scene()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
porcelain.remote_add(
|
porcelain.remote_add(
|
||||||
@ -434,7 +473,7 @@ class SessionHostOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
# Host a session
|
# Host a session
|
||||||
if settings.init_method == 'EMPTY':
|
if settings.init_method == 'EMPTY':
|
||||||
utils.clean_scene()
|
clean_scene()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Init repository
|
# Init repository
|
||||||
@ -498,7 +537,7 @@ class SessionInitOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
if self.init_method == 'EMPTY':
|
if self.init_method == 'EMPTY':
|
||||||
utils.clean_scene()
|
clean_scene()
|
||||||
|
|
||||||
for scene in bpy.data.scenes:
|
for scene in bpy.data.scenes:
|
||||||
porcelain.add(session.repository, scene)
|
porcelain.add(session.repository, scene)
|
||||||
@ -982,6 +1021,13 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
description="Draw users in the scene",
|
description="Draw users in the scene",
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replay: bpy.props.BoolProperty(
|
||||||
|
name="Replay mode",
|
||||||
|
description="Enable replay functions",
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
|
||||||
user_skin_radius: bpy.props.FloatProperty(
|
user_skin_radius: bpy.props.FloatProperty(
|
||||||
name="Wireframe radius",
|
name="Wireframe radius",
|
||||||
description="Wireframe radius",
|
description="Wireframe radius",
|
||||||
@ -995,7 +1041,10 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
|
|
||||||
files: bpy.props.CollectionProperty(
|
files: bpy.props.CollectionProperty(
|
||||||
name='File paths',
|
name='File paths',
|
||||||
type=bpy.types.OperatorFileListElement)
|
type=bpy.types.OperatorFileListElement
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
pass
|
pass
|
||||||
@ -1007,7 +1056,23 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
bpy_protocol = bl_types.get_data_translation_protocol()
|
bpy_protocol = bl_types.get_data_translation_protocol()
|
||||||
repo = Repository(bpy_protocol)
|
repo = Repository(bpy_protocol)
|
||||||
repo.loads(self.filepath)
|
repo.loads(self.filepath)
|
||||||
utils.clean_scene()
|
|
||||||
|
# Persitstent collection
|
||||||
|
ignored_datablocks = []
|
||||||
|
|
||||||
|
persistent_collection = bpy.data.collections.get("multiuser_timelapse")
|
||||||
|
if self.replay and \
|
||||||
|
context.window_manager.session.replay_persistent_collection and \
|
||||||
|
persistent_collection:
|
||||||
|
collection_repo = Repository(
|
||||||
|
rdp=bpy_protocol,
|
||||||
|
username="None")
|
||||||
|
porcelain.add(collection_repo, persistent_collection)
|
||||||
|
porcelain.commit(collection_repo, persistent_collection.uuid)
|
||||||
|
for node in collection_repo.graph.values():
|
||||||
|
ignored_datablocks.append(node.data.get('name'))
|
||||||
|
|
||||||
|
clean_scene(ignored_datablocks=ignored_datablocks)
|
||||||
|
|
||||||
nodes = [repo.graph.get(n) for n in repo.index_sorted]
|
nodes = [repo.graph.get(n) for n in repo.index_sorted]
|
||||||
|
|
||||||
@ -1030,6 +1095,23 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
snap = context.window_manager.session.replay_files.add()
|
snap = context.window_manager.session.replay_files.add()
|
||||||
snap.name = str(Path(directory, f['name']))
|
snap.name = str(Path(directory, f['name']))
|
||||||
|
|
||||||
|
if context.window_manager.session.replay_mode == 'TIMELINE':
|
||||||
|
replay_action = bpy.data.actions.get('replay_action', bpy.data.actions.new('replay_action'))
|
||||||
|
|
||||||
|
bpy.context.scene.animation_data_create()
|
||||||
|
bpy.context.scene.animation_data.action = replay_action
|
||||||
|
if len(replay_action.fcurves) > 0 and replay_action.fcurves[0].data_path == 'active_replay_file':
|
||||||
|
replay_fcurve = replay_action.fcurves[0]
|
||||||
|
else:
|
||||||
|
replay_fcurve = replay_action.fcurves.new('active_replay_file')
|
||||||
|
|
||||||
|
for p in reversed(replay_fcurve.keyframe_points):
|
||||||
|
replay_fcurve.keyframe_points.remove(p, fast=True)
|
||||||
|
|
||||||
|
intrv = context.window_manager.session.replay_interval
|
||||||
|
for frame in range(0, len(self.files)-1):
|
||||||
|
replay_fcurve.keyframe_points.insert(frame * intrv, frame)
|
||||||
|
|
||||||
if self.draw_users:
|
if self.draw_users:
|
||||||
f = gzip.open(self.filepath, "rb")
|
f = gzip.open(self.filepath, "rb")
|
||||||
db = pickle.load(f)
|
db = pickle.load(f)
|
||||||
@ -1042,6 +1124,15 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
if metadata:
|
if metadata:
|
||||||
draw_user(username, metadata, radius=self.user_skin_radius, intensity=self.user_color_intensity)
|
draw_user(username, metadata, radius=self.user_skin_radius, intensity=self.user_color_intensity)
|
||||||
|
|
||||||
|
if self.replay and persistent_collection:
|
||||||
|
logging.info(f"Relinking {persistent_collection.name}")
|
||||||
|
bpy.context.scene.collection.children.link(persistent_collection)
|
||||||
|
|
||||||
|
if self.replay and \
|
||||||
|
context.window_manager.session.replay_mode == 'TIMELINE' and \
|
||||||
|
not bpy.context.scene.animation_data :
|
||||||
|
bpy.context.scene.animation_data_create()
|
||||||
|
bpy.context.scene.animation_data.action = bpy.data.actions.get('replay_action')
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
Reference in New Issue
Block a user