From 28e83a38e6359894ad2edf56348c50202ef0c21c Mon Sep 17 00:00:00 2001 From: Swann Date: Wed, 19 May 2021 15:05:54 +0200 Subject: [PATCH] refactor: add back armature lightprobes, sound and speaker --- multi_user/bl_types/bl_armature.py | 46 ++++++++++++++++++++-------- multi_user/bl_types/bl_lightprobe.py | 24 ++++++++++++--- multi_user/bl_types/bl_sound.py | 40 +++++++++++++++++------- multi_user/bl_types/bl_speaker.py | 32 ++++++++++++++----- 4 files changed, 108 insertions(+), 34 deletions(-) diff --git a/multi_user/bl_types/bl_armature.py b/multi_user/bl_types/bl_armature.py index 5c1d29d..2cc79a9 100644 --- a/multi_user/bl_types/bl_armature.py +++ b/multi_user/bl_types/bl_armature.py @@ -23,7 +23,8 @@ import mathutils from .dump_anything import Loader, Dumper from .. import presence, operators, utils from replication.protocol import ReplicatedDatablock - +from .bl_datablock import resolve_datablock_from_uuid +from .bl_action import dump_animation_data, load_animation_data, resolve_animation_dependencies def get_roll(bone: bpy.types.Bone) -> float: """ Compute the actuall roll of a pose bone @@ -42,9 +43,11 @@ class BlArmature(ReplicatedDatablock): bl_icon = 'ARMATURE_DATA' bl_reload_parent = False + @staticmethod def construct(data: dict) -> object: return bpy.data.armatures.new(data["name"]) + @staticmethod def load(data: dict, datablock: object): # Load parent object parent_object = utils.find_from_attr( @@ -55,7 +58,7 @@ class BlArmature(ReplicatedDatablock): if parent_object is None: parent_object = bpy.data.objects.new( - data['user_name'], target) + data['user_name'], datablock) parent_object.uuid = data['user'] is_object_in_master = ( @@ -90,10 +93,10 @@ class BlArmature(ReplicatedDatablock): bpy.ops.object.mode_set(mode='EDIT') for bone in data['bones']: - if bone not in target.edit_bones: - new_bone = target.edit_bones.new(bone) + if bone not in datablock.edit_bones: + new_bone = datablock.edit_bones.new(bone) else: - new_bone = target.edit_bones[bone] + new_bone = datablock.edit_bones[bone] bone_data = data['bones'].get(bone) @@ -104,7 +107,7 @@ class BlArmature(ReplicatedDatablock): new_bone.roll = bone_data['roll'] if 'parent' in bone_data: - new_bone.parent = target.edit_bones[data['bones'] + new_bone.parent = datablock.edit_bones[data['bones'] [bone]['parent']] new_bone.use_connect = bone_data['use_connect'] @@ -119,9 +122,10 @@ class BlArmature(ReplicatedDatablock): if 'EDIT' in current_mode: bpy.ops.object.mode_set(mode='EDIT') - def dump(datablock: object) -> dict: - assert(instance) + load_animation_data(datablock.get('animation_data'), datablock) + @staticmethod + def dump(datablock: object) -> dict: dumper = Dumper() dumper.depth = 4 dumper.include_filter = [ @@ -135,14 +139,14 @@ class BlArmature(ReplicatedDatablock): 'name', 'layers', ] - data = dumper.dump(instance) + data = dumper.dump(datablock) - for bone in instance.bones: + for bone in datablock.bones: if bone.parent: data['bones'][bone.name]['parent'] = bone.parent.name # get the parent Object # TODO: Use id_data instead - object_users = utils.get_datablock_users(instance)[0] + object_users = utils.get_datablock_users(datablock)[0] data['user'] = object_users.uuid data['user_name'] = object_users.name @@ -153,7 +157,25 @@ class BlArmature(ReplicatedDatablock): data['user_scene'] = [ item.name for item in container_users if isinstance(item, bpy.types.Scene)] - for bone in instance.bones: + for bone in datablock.bones: data['bones'][bone.name]['roll'] = get_roll(bone) + data['animation_data'] = dump_animation_data(datablock) return data + + @staticmethod + def resolve(data: dict) -> object: + uuid = data.get('uuid') + name = data.get('name') + datablock = resolve_datablock_from_uuid(uuid, bpy.data.armatures) + if datablock is None: + datablock = bpy.data.armatures.get(name) + + return datablock + + @staticmethod + def resolve_deps(datablock: object) -> [object]: + return resolve_animation_dependencies(datablock) + +_type = bpy.types.Armature +_class = BlArmature \ No newline at end of file diff --git a/multi_user/bl_types/bl_lightprobe.py b/multi_user/bl_types/bl_lightprobe.py index 28956ec..b21d57a 100644 --- a/multi_user/bl_types/bl_lightprobe.py +++ b/multi_user/bl_types/bl_lightprobe.py @@ -22,7 +22,7 @@ import logging from .dump_anything import Loader, Dumper from replication.protocol import ReplicatedDatablock - +from .bl_datablock import resolve_datablock_from_uuid class BlLightprobe(ReplicatedDatablock): bl_id = "lightprobes" @@ -31,6 +31,7 @@ class BlLightprobe(ReplicatedDatablock): bl_icon = 'LIGHTPROBE_GRID' bl_reload_parent = False + @staticmethod def construct(data: dict) -> object: type = 'CUBE' if data['type'] == 'CUBEMAP' else data['type'] # See https://developer.blender.org/D6396 @@ -39,12 +40,13 @@ class BlLightprobe(ReplicatedDatablock): else: logging.warning("Lightprobe replication only supported since 2.83. See https://developer.blender.org/D6396") + @staticmethod def load(data: dict, datablock: object): loader = Loader() - loader.load(target, data) + loader.load(datablock, data) + @staticmethod def dump(datablock: object) -> dict: - assert(instance) if bpy.app.version[1] < 83: logging.warning("Lightprobe replication only supported since 2.83. See https://developer.blender.org/D6396") @@ -71,7 +73,21 @@ class BlLightprobe(ReplicatedDatablock): 'visibility_blur' ] - return dumper.dump(instance) + return dumper.dump(datablock) + @staticmethod + def resolve(data: dict) -> object: + uuid = data.get('uuid') + name = data.get('name') + datablock = resolve_datablock_from_uuid(uuid, bpy.data.lightprobes) + if datablock is None: + datablock = bpy.data.lightprobes.get(name) + return datablock + @staticmethod + def resolve_deps(datablock: object) -> [object]: + return [] + +_type = bpy.types.LightProbe +_class = BlLightprobe \ No newline at end of file diff --git a/multi_user/bl_types/bl_sound.py b/multi_user/bl_types/bl_sound.py index e8b6724..e2c7c26 100644 --- a/multi_user/bl_types/bl_sound.py +++ b/multi_user/bl_types/bl_sound.py @@ -25,6 +25,7 @@ import bpy from .bl_file import get_filepath, ensure_unpacked from replication.protocol import ReplicatedDatablock from .dump_anything import Dumper, Loader +from .bl_datablock import resolve_datablock_from_uuid class BlSound(ReplicatedDatablock): @@ -34,34 +35,51 @@ class BlSound(ReplicatedDatablock): bl_icon = 'SOUND' bl_reload_parent = False + @staticmethod def construct(data: dict) -> object: filename = data.get('filename') return bpy.data.sounds.load(get_filepath(filename)) - def _load(self, data, target): + @staticmethod + def load(data: dict, datablock: object): loader = Loader() - loader.load(target, data) + loader.load(datablock, data) def diff(self): return False - def _dump(self, instance=None): - filename = Path(instance.filepath).name + @staticmethod + def dump(datablock: object) -> dict: + filename = Path(datablock.filepath).name if not filename: - raise FileExistsError(instance.filepath) - + raise FileExistsError(datablock.filepath) + return { 'filename': filename, - 'name': instance.name + 'name': datablock.name } + @staticmethod def resolve_deps(datablock: object) -> [object]: deps = [] - if self.instance.filepath and self.instance.filepath != '': - ensure_unpacked(self.instance) - - deps.append(Path(bpy.path.abspath(self.instance.filepath))) + if datablock.filepath and datablock.filepath != '': + ensure_unpacked(datablock) + + deps.append(Path(bpy.path.abspath(datablock.filepath))) return deps + + @staticmethod + def resolve(data: dict) -> object: + uuid = data.get('uuid') + name = data.get('name') + datablock = resolve_datablock_from_uuid(uuid, bpy.data.sounds) + if datablock is None: + datablock = bpy.data.sounds.get(name) + + return datablock + +_type = bpy.types.Sound +_class = BlSound \ No newline at end of file diff --git a/multi_user/bl_types/bl_speaker.py b/multi_user/bl_types/bl_speaker.py index 03edf95..4b6d72a 100644 --- a/multi_user/bl_types/bl_speaker.py +++ b/multi_user/bl_types/bl_speaker.py @@ -21,7 +21,8 @@ import mathutils from .dump_anything import Loader, Dumper from replication.protocol import ReplicatedDatablock - +from .bl_datablock import resolve_datablock_from_uuid +from .bl_action import dump_animation_data, load_animation_data, resolve_animation_dependencies class BlSpeaker(ReplicatedDatablock): bl_id = "speakers" @@ -30,16 +31,18 @@ class BlSpeaker(ReplicatedDatablock): bl_icon = 'SPEAKER' bl_reload_parent = False + @staticmethod def load(data: dict, datablock: object): loader = Loader() - loader.load(target, data) + loader.load(datablock, data) + load_animation_data(datablock.get('animation_data'), datablock) + @staticmethod def construct(data: dict) -> object: return bpy.data.speakers.new(data["name"]) + @staticmethod def dump(datablock: object) -> dict: - assert(instance) - dumper = Dumper() dumper.depth = 1 dumper.include_filter = [ @@ -58,17 +61,32 @@ class BlSpeaker(ReplicatedDatablock): 'cone_volume_outer' ] - return dumper.dump(instance) + data = dumper.dump(datablock) + data['animation_data'] = dump_animation_data(datablock) + return data + @staticmethod + def resolve(data: dict) -> object: + uuid = data.get('uuid') + name = data.get('name') + datablock = resolve_datablock_from_uuid(uuid, bpy.data.speakers) + if datablock is None: + datablock = bpy.data.speakers.get(name) + + return datablock + + @staticmethod def resolve_deps(datablock: object) -> [object]: # TODO: resolve material deps = [] - sound = self.instance.sound + sound = datablock.sound if sound: deps.append(sound) + deps.extend(resolve_animation_dependencies(datablock)) return deps - +_type = bpy.types.Speaker +_class = BlSpeaker