feat: replay duration
This commit is contained in:
parent
3a4f691b8f
commit
fe998214be
@ -35,6 +35,7 @@ from operator import itemgetter
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
from time import gmtime, strftime
|
from time import gmtime, strftime
|
||||||
|
from numpy import interp
|
||||||
|
|
||||||
from bpy.props import FloatProperty
|
from bpy.props import FloatProperty
|
||||||
import bmesh
|
import bmesh
|
||||||
@ -1052,6 +1053,8 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
from replication.repository import Repository
|
from replication.repository import Repository
|
||||||
|
|
||||||
|
runtime_settings = context.window_manager.session
|
||||||
|
|
||||||
# init the factory with supported types
|
# init the factory with supported types
|
||||||
bpy_protocol = bl_types.get_data_translation_protocol()
|
bpy_protocol = bl_types.get_data_translation_protocol()
|
||||||
repo = Repository(bpy_protocol)
|
repo = Repository(bpy_protocol)
|
||||||
@ -1062,7 +1065,7 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
|
|
||||||
persistent_collection = bpy.data.collections.get("multiuser_timelapse")
|
persistent_collection = bpy.data.collections.get("multiuser_timelapse")
|
||||||
if self.replay and \
|
if self.replay and \
|
||||||
context.window_manager.session.replay_persistent_collection and \
|
runtime_settings.replay_persistent_collection and \
|
||||||
persistent_collection:
|
persistent_collection:
|
||||||
collection_repo = Repository(
|
collection_repo = Repository(
|
||||||
rdp=bpy_protocol,
|
rdp=bpy_protocol,
|
||||||
@ -1088,14 +1091,17 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
porcelain.apply(repo, node.uuid)
|
porcelain.apply(repo, node.uuid)
|
||||||
|
|
||||||
if len(self.files) > 1:
|
if len(self.files) > 1:
|
||||||
context.window_manager.session.replay_files.clear()
|
runtime_settings.replay_files.clear()
|
||||||
context.scene.active_replay_file = len(self.files)-1
|
context.scene.active_replay_file = len(self.files)-1
|
||||||
directory = Path(self.filepath).parent
|
directory = Path(self.filepath).parent
|
||||||
for f in self.files:
|
file_list = [f['name'] for f in self.files]
|
||||||
snap = context.window_manager.session.replay_files.add()
|
file_list.sort()
|
||||||
snap.name = str(Path(directory, f['name']))
|
for f in file_list:
|
||||||
|
snap = runtime_settings.replay_files.add()
|
||||||
|
snap.name = str(Path(directory, f))
|
||||||
|
print(f)
|
||||||
|
|
||||||
if context.window_manager.session.replay_mode == 'TIMELINE':
|
if runtime_settings.replay_mode == 'TIMELINE':
|
||||||
replay_action = bpy.data.actions.get('replay_action', bpy.data.actions.new('replay_action'))
|
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_create()
|
||||||
@ -1108,9 +1114,12 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
for p in reversed(replay_fcurve.keyframe_points):
|
for p in reversed(replay_fcurve.keyframe_points):
|
||||||
replay_fcurve.keyframe_points.remove(p, fast=True)
|
replay_fcurve.keyframe_points.remove(p, fast=True)
|
||||||
|
|
||||||
intrv = context.window_manager.session.replay_interval
|
duration = runtime_settings.replay_duration
|
||||||
for frame in range(0, len(self.files)-1):
|
file_count = len(self.files)-1
|
||||||
replay_fcurve.keyframe_points.insert(frame * intrv, frame)
|
for index in range(0, file_count):
|
||||||
|
frame = interp(index, [0, file_count], [bpy.context.scene.frame_start, duration])
|
||||||
|
replay_fcurve.keyframe_points.insert(frame, index)
|
||||||
|
|
||||||
|
|
||||||
if self.draw_users:
|
if self.draw_users:
|
||||||
f = gzip.open(self.filepath, "rb")
|
f = gzip.open(self.filepath, "rb")
|
||||||
@ -1124,15 +1133,27 @@ 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)
|
||||||
|
|
||||||
|
# Relink the persistent collection
|
||||||
if self.replay and persistent_collection:
|
if self.replay and persistent_collection:
|
||||||
logging.info(f"Relinking {persistent_collection.name}")
|
logging.info(f"Relinking {persistent_collection.name}")
|
||||||
bpy.context.scene.collection.children.link(persistent_collection)
|
bpy.context.scene.collection.children.link(persistent_collection)
|
||||||
|
|
||||||
|
# Reasign scene action
|
||||||
if self.replay and \
|
if self.replay and \
|
||||||
context.window_manager.session.replay_mode == 'TIMELINE' and \
|
runtime_settings.replay_mode == 'TIMELINE' and \
|
||||||
not bpy.context.scene.animation_data :
|
not bpy.context.scene.animation_data :
|
||||||
bpy.context.scene.animation_data_create()
|
bpy.context.scene.animation_data_create()
|
||||||
bpy.context.scene.animation_data.action = bpy.data.actions.get('replay_action')
|
bpy.context.scene.animation_data.action = bpy.data.actions.get('replay_action')
|
||||||
|
bpy.context.scene.frame_end = runtime_settings.replay_duration
|
||||||
|
|
||||||
|
# Reasign the scene camera
|
||||||
|
if self.replay and \
|
||||||
|
runtime_settings.replay_persistent_collection and \
|
||||||
|
runtime_settings.replay_camera:
|
||||||
|
bpy.context.scene.camera = runtime_settings.replay_camera
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -22,6 +22,7 @@ import bpy
|
|||||||
import string
|
import string
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
from numpy import interp
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@ -144,11 +145,11 @@ def set_replay_persistent_collection(self, value):
|
|||||||
def get_replay_persistent_collection(self):
|
def get_replay_persistent_collection(self):
|
||||||
return self.get('replay_persistent_collection', False)
|
return self.get('replay_persistent_collection', False)
|
||||||
|
|
||||||
def set_replay_interval(self, value):
|
def set_replay_duration(self, value):
|
||||||
if hasattr(self, 'replay_interval'):
|
if hasattr(self, 'replay_duration'):
|
||||||
self["replay_interval"] = value
|
self["replay_duration"] = value
|
||||||
else:
|
else:
|
||||||
self.replay_interval = value
|
self.replay_duration = value
|
||||||
|
|
||||||
# Update the animation fcurve
|
# Update the animation fcurve
|
||||||
replay_action = bpy.data.actions.get('replay_action')
|
replay_action = bpy.data.actions.get('replay_action')
|
||||||
@ -162,12 +163,14 @@ def set_replay_interval(self, value):
|
|||||||
for p in reversed(replay_fcurve.keyframe_points):
|
for p in reversed(replay_fcurve.keyframe_points):
|
||||||
replay_fcurve.keyframe_points.remove(p, fast=True)
|
replay_fcurve.keyframe_points.remove(p, fast=True)
|
||||||
|
|
||||||
intrv = bpy.context.window_manager.session.replay_interval
|
bpy.context.scene.frame_end = value
|
||||||
for frame in range(0, len(bpy.context.window_manager.session.replay_files)):
|
files_count = len(bpy.context.window_manager.session.replay_files)-1
|
||||||
replay_fcurve.keyframe_points.insert((frame * intrv), frame)
|
for index in range(0, files_count):
|
||||||
|
frame = interp(index,[0, files_count],[bpy.context.scene.frame_start, value])
|
||||||
|
replay_fcurve.keyframe_points.insert(frame, index)
|
||||||
|
|
||||||
def get_replay_interval(self):
|
def get_replay_duration(self):
|
||||||
return self.get('replay_interval', 10)
|
return self.get('replay_duration', 10)
|
||||||
|
|
||||||
def get_log_level(self):
|
def get_log_level(self):
|
||||||
return logging.getLogger().level
|
return logging.getLogger().level
|
||||||
@ -773,17 +776,20 @@ class SessionProps(bpy.types.PropertyGroup):
|
|||||||
('TIMELINE', 'TIMELINE', 'Replay from the timeline.'),
|
('TIMELINE', 'TIMELINE', 'Replay from the timeline.'),
|
||||||
('MANUAL', 'MANUAL', 'Replay manually, from the replay frame widget.')},
|
('MANUAL', 'MANUAL', 'Replay manually, from the replay frame widget.')},
|
||||||
default='TIMELINE')
|
default='TIMELINE')
|
||||||
replay_interval: bpy.props.IntProperty(
|
replay_duration: bpy.props.IntProperty(
|
||||||
name='replay interval',
|
name='replay interval',
|
||||||
default=10,
|
default=250,
|
||||||
min=1,
|
min=10,
|
||||||
set=set_replay_interval,
|
set=set_replay_duration,
|
||||||
get=get_replay_interval,
|
get=get_replay_duration,
|
||||||
)
|
)
|
||||||
replay_frame_current: bpy.props.IntProperty(
|
replay_frame_current: bpy.props.IntProperty(
|
||||||
name='replay_frame_current',
|
name='replay_frame_current',
|
||||||
)
|
)
|
||||||
|
replay_camera: bpy.props.PointerProperty(
|
||||||
|
name='Replay camera',
|
||||||
|
type=bpy.types.Object
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
|
@ -588,10 +588,13 @@ class SESSION_PT_replay(bpy.types.Panel):
|
|||||||
if settings.replay_mode == 'MANUAL':
|
if settings.replay_mode == 'MANUAL':
|
||||||
row.prop(bpy.context.scene, 'active_replay_file', text="Snapshot index")
|
row.prop(bpy.context.scene, 'active_replay_file', text="Snapshot index")
|
||||||
else:
|
else:
|
||||||
row.prop(settings, 'replay_interval', text="interval (frame)")
|
row.prop(settings, 'replay_duration', text="Replay Duration")
|
||||||
row= layout.row()
|
row= layout.row()
|
||||||
row.prop(settings, 'replay_persistent_collection', text="persistent collection", toggle=True, icon='OUTLINER_COLLECTION')
|
row.prop(settings, 'replay_persistent_collection', text="persistent collection", toggle=True, icon='OUTLINER_COLLECTION')
|
||||||
|
|
||||||
|
if settings.replay_persistent_collection:
|
||||||
|
row= layout.row()
|
||||||
|
row.prop(settings, 'replay_camera', text="", icon='VIEW_CAMERA')
|
||||||
|
|
||||||
class SESSION_PT_repository(bpy.types.Panel):
|
class SESSION_PT_repository(bpy.types.Panel):
|
||||||
bl_idname = "MULTIUSER_PROPERTIES_PT_panel"
|
bl_idname = "MULTIUSER_PROPERTIES_PT_panel"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user