refactor: add back armature lightprobes, sound and speaker

This commit is contained in:
Swann 2021-05-19 15:05:54 +02:00
parent 2e261cd66b
commit 28e83a38e6
No known key found for this signature in database
GPG Key ID: E1D3641A7C43AACB
4 changed files with 108 additions and 34 deletions

View File

@ -23,7 +23,8 @@ import mathutils
from .dump_anything import Loader, Dumper from .dump_anything import Loader, Dumper
from .. import presence, operators, utils from .. import presence, operators, utils
from replication.protocol import ReplicatedDatablock 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: def get_roll(bone: bpy.types.Bone) -> float:
""" Compute the actuall roll of a pose bone """ Compute the actuall roll of a pose bone
@ -42,9 +43,11 @@ class BlArmature(ReplicatedDatablock):
bl_icon = 'ARMATURE_DATA' bl_icon = 'ARMATURE_DATA'
bl_reload_parent = False bl_reload_parent = False
@staticmethod
def construct(data: dict) -> object: def construct(data: dict) -> object:
return bpy.data.armatures.new(data["name"]) return bpy.data.armatures.new(data["name"])
@staticmethod
def load(data: dict, datablock: object): def load(data: dict, datablock: object):
# Load parent object # Load parent object
parent_object = utils.find_from_attr( parent_object = utils.find_from_attr(
@ -55,7 +58,7 @@ class BlArmature(ReplicatedDatablock):
if parent_object is None: if parent_object is None:
parent_object = bpy.data.objects.new( parent_object = bpy.data.objects.new(
data['user_name'], target) data['user_name'], datablock)
parent_object.uuid = data['user'] parent_object.uuid = data['user']
is_object_in_master = ( is_object_in_master = (
@ -90,10 +93,10 @@ class BlArmature(ReplicatedDatablock):
bpy.ops.object.mode_set(mode='EDIT') bpy.ops.object.mode_set(mode='EDIT')
for bone in data['bones']: for bone in data['bones']:
if bone not in target.edit_bones: if bone not in datablock.edit_bones:
new_bone = target.edit_bones.new(bone) new_bone = datablock.edit_bones.new(bone)
else: else:
new_bone = target.edit_bones[bone] new_bone = datablock.edit_bones[bone]
bone_data = data['bones'].get(bone) bone_data = data['bones'].get(bone)
@ -104,7 +107,7 @@ class BlArmature(ReplicatedDatablock):
new_bone.roll = bone_data['roll'] new_bone.roll = bone_data['roll']
if 'parent' in bone_data: if 'parent' in bone_data:
new_bone.parent = target.edit_bones[data['bones'] new_bone.parent = datablock.edit_bones[data['bones']
[bone]['parent']] [bone]['parent']]
new_bone.use_connect = bone_data['use_connect'] new_bone.use_connect = bone_data['use_connect']
@ -119,9 +122,10 @@ class BlArmature(ReplicatedDatablock):
if 'EDIT' in current_mode: if 'EDIT' in current_mode:
bpy.ops.object.mode_set(mode='EDIT') bpy.ops.object.mode_set(mode='EDIT')
def dump(datablock: object) -> dict: load_animation_data(datablock.get('animation_data'), datablock)
assert(instance)
@staticmethod
def dump(datablock: object) -> dict:
dumper = Dumper() dumper = Dumper()
dumper.depth = 4 dumper.depth = 4
dumper.include_filter = [ dumper.include_filter = [
@ -135,14 +139,14 @@ class BlArmature(ReplicatedDatablock):
'name', 'name',
'layers', 'layers',
] ]
data = dumper.dump(instance) data = dumper.dump(datablock)
for bone in instance.bones: for bone in datablock.bones:
if bone.parent: if bone.parent:
data['bones'][bone.name]['parent'] = bone.parent.name data['bones'][bone.name]['parent'] = bone.parent.name
# get the parent Object # get the parent Object
# TODO: Use id_data instead # 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'] = object_users.uuid
data['user_name'] = object_users.name data['user_name'] = object_users.name
@ -153,7 +157,25 @@ class BlArmature(ReplicatedDatablock):
data['user_scene'] = [ data['user_scene'] = [
item.name for item in container_users if isinstance(item, bpy.types.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['bones'][bone.name]['roll'] = get_roll(bone)
data['animation_data'] = dump_animation_data(datablock)
return data 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

View File

@ -22,7 +22,7 @@ import logging
from .dump_anything import Loader, Dumper from .dump_anything import Loader, Dumper
from replication.protocol import ReplicatedDatablock from replication.protocol import ReplicatedDatablock
from .bl_datablock import resolve_datablock_from_uuid
class BlLightprobe(ReplicatedDatablock): class BlLightprobe(ReplicatedDatablock):
bl_id = "lightprobes" bl_id = "lightprobes"
@ -31,6 +31,7 @@ class BlLightprobe(ReplicatedDatablock):
bl_icon = 'LIGHTPROBE_GRID' bl_icon = 'LIGHTPROBE_GRID'
bl_reload_parent = False bl_reload_parent = False
@staticmethod
def construct(data: dict) -> object: def construct(data: dict) -> object:
type = 'CUBE' if data['type'] == 'CUBEMAP' else data['type'] type = 'CUBE' if data['type'] == 'CUBEMAP' else data['type']
# See https://developer.blender.org/D6396 # See https://developer.blender.org/D6396
@ -39,12 +40,13 @@ class BlLightprobe(ReplicatedDatablock):
else: else:
logging.warning("Lightprobe replication only supported since 2.83. See https://developer.blender.org/D6396") logging.warning("Lightprobe replication only supported since 2.83. See https://developer.blender.org/D6396")
@staticmethod
def load(data: dict, datablock: object): def load(data: dict, datablock: object):
loader = Loader() loader = Loader()
loader.load(target, data) loader.load(datablock, data)
@staticmethod
def dump(datablock: object) -> dict: def dump(datablock: object) -> dict:
assert(instance)
if bpy.app.version[1] < 83: if bpy.app.version[1] < 83:
logging.warning("Lightprobe replication only supported since 2.83. See https://developer.blender.org/D6396") logging.warning("Lightprobe replication only supported since 2.83. See https://developer.blender.org/D6396")
@ -71,7 +73,21 @@ class BlLightprobe(ReplicatedDatablock):
'visibility_blur' '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

View File

@ -25,6 +25,7 @@ import bpy
from .bl_file import get_filepath, ensure_unpacked from .bl_file import get_filepath, ensure_unpacked
from replication.protocol import ReplicatedDatablock from replication.protocol import ReplicatedDatablock
from .dump_anything import Dumper, Loader from .dump_anything import Dumper, Loader
from .bl_datablock import resolve_datablock_from_uuid
class BlSound(ReplicatedDatablock): class BlSound(ReplicatedDatablock):
@ -34,34 +35,51 @@ class BlSound(ReplicatedDatablock):
bl_icon = 'SOUND' bl_icon = 'SOUND'
bl_reload_parent = False bl_reload_parent = False
@staticmethod
def construct(data: dict) -> object: def construct(data: dict) -> object:
filename = data.get('filename') filename = data.get('filename')
return bpy.data.sounds.load(get_filepath(filename)) return bpy.data.sounds.load(get_filepath(filename))
def _load(self, data, target): @staticmethod
def load(data: dict, datablock: object):
loader = Loader() loader = Loader()
loader.load(target, data) loader.load(datablock, data)
def diff(self): def diff(self):
return False return False
def _dump(self, instance=None): @staticmethod
filename = Path(instance.filepath).name def dump(datablock: object) -> dict:
filename = Path(datablock.filepath).name
if not filename: if not filename:
raise FileExistsError(instance.filepath) raise FileExistsError(datablock.filepath)
return { return {
'filename': filename, 'filename': filename,
'name': instance.name 'name': datablock.name
} }
@staticmethod
def resolve_deps(datablock: object) -> [object]: def resolve_deps(datablock: object) -> [object]:
deps = [] deps = []
if self.instance.filepath and self.instance.filepath != '<builtin>': if datablock.filepath and datablock.filepath != '<builtin>':
ensure_unpacked(self.instance) ensure_unpacked(datablock)
deps.append(Path(bpy.path.abspath(self.instance.filepath))) deps.append(Path(bpy.path.abspath(datablock.filepath)))
return deps 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

View File

@ -21,7 +21,8 @@ import mathutils
from .dump_anything import Loader, Dumper from .dump_anything import Loader, Dumper
from replication.protocol import ReplicatedDatablock 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): class BlSpeaker(ReplicatedDatablock):
bl_id = "speakers" bl_id = "speakers"
@ -30,16 +31,18 @@ class BlSpeaker(ReplicatedDatablock):
bl_icon = 'SPEAKER' bl_icon = 'SPEAKER'
bl_reload_parent = False bl_reload_parent = False
@staticmethod
def load(data: dict, datablock: object): def load(data: dict, datablock: object):
loader = Loader() loader = Loader()
loader.load(target, data) loader.load(datablock, data)
load_animation_data(datablock.get('animation_data'), datablock)
@staticmethod
def construct(data: dict) -> object: def construct(data: dict) -> object:
return bpy.data.speakers.new(data["name"]) return bpy.data.speakers.new(data["name"])
@staticmethod
def dump(datablock: object) -> dict: def dump(datablock: object) -> dict:
assert(instance)
dumper = Dumper() dumper = Dumper()
dumper.depth = 1 dumper.depth = 1
dumper.include_filter = [ dumper.include_filter = [
@ -58,17 +61,32 @@ class BlSpeaker(ReplicatedDatablock):
'cone_volume_outer' '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]: def resolve_deps(datablock: object) -> [object]:
# TODO: resolve material # TODO: resolve material
deps = [] deps = []
sound = self.instance.sound sound = datablock.sound
if sound: if sound:
deps.append(sound) deps.append(sound)
deps.extend(resolve_animation_dependencies(datablock))
return deps return deps
_type = bpy.types.Speaker
_class = BlSpeaker