refactor: cleanup
feat: action dependency resolve fix: memory leak feat: children as dependency fix: missing 3dview
This commit is contained in:
@ -4,7 +4,7 @@ bl_info = {
|
|||||||
"description": "",
|
"description": "",
|
||||||
"blender": (2, 80, 0),
|
"blender": (2, 80, 0),
|
||||||
"location": "",
|
"location": "",
|
||||||
"warning": "",
|
"warning": "Unstable addon, use it at your own risks",
|
||||||
"category": "Collaboration"
|
"category": "Collaboration"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,8 +18,8 @@ import bpy
|
|||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
|
|
||||||
from . import environment, utils
|
from . import environment, utils
|
||||||
# from . import bl_types
|
|
||||||
|
|
||||||
|
# TODO: remove dependency as soon as replication will be installed as a module
|
||||||
DEPENDENCIES = {
|
DEPENDENCIES = {
|
||||||
("zmq","zmq"),
|
("zmq","zmq"),
|
||||||
("msgpack","msgpack"),
|
("msgpack","msgpack"),
|
||||||
@ -44,11 +44,12 @@ def generate_supported_types():
|
|||||||
props['icon'] = _type.bl_icon
|
props['icon'] = _type.bl_icon
|
||||||
props['auto_push']=_type.bl_automatic_push
|
props['auto_push']=_type.bl_automatic_push
|
||||||
props['bl_name']=_type.bl_id
|
props['bl_name']=_type.bl_id
|
||||||
# stype_dict[type]['bl_delay_apply']=_type.bl_delay_apply
|
|
||||||
stype_dict['supported_types'][_type.bl_rep_class.__name__] = props
|
stype_dict['supported_types'][_type.bl_rep_class.__name__] = props
|
||||||
|
|
||||||
return stype_dict
|
return stype_dict
|
||||||
|
|
||||||
|
|
||||||
def client_list_callback(scene, context):
|
def client_list_callback(scene, context):
|
||||||
from . import operators
|
from . import operators
|
||||||
from .bl_types.bl_user import BlUser
|
from .bl_types.bl_user import BlUser
|
||||||
@ -97,8 +98,6 @@ def save_session_config(self,context):
|
|||||||
config["supported_types"][bloc.type_name]['icon'] = bloc.icon
|
config["supported_types"][bloc.type_name]['icon'] = bloc.icon
|
||||||
config["supported_types"][bloc.type_name]['auto_push'] = bloc.auto_push
|
config["supported_types"][bloc.type_name]['auto_push'] = bloc.auto_push
|
||||||
config["supported_types"][bloc.type_name]['bl_name'] = bloc.bl_name
|
config["supported_types"][bloc.type_name]['bl_name'] = bloc.bl_name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Save out the configuration file
|
# Save out the configuration file
|
||||||
environment.save_config(config)
|
environment.save_config(config)
|
||||||
|
@ -11,7 +11,8 @@ __all__ = [
|
|||||||
'bl_scene',
|
'bl_scene',
|
||||||
'bl_material',
|
'bl_material',
|
||||||
'bl_library',
|
'bl_library',
|
||||||
'bl_armature'
|
'bl_armature',
|
||||||
|
'bl_action'
|
||||||
] # Order here defines execution order
|
] # Order here defines execution order
|
||||||
|
|
||||||
from . import *
|
from . import *
|
||||||
|
@ -12,6 +12,17 @@ class BlAction(BlDatablock):
|
|||||||
def construct(self, data):
|
def construct(self, data):
|
||||||
return bpy.data.actions.new(data["name"])
|
return bpy.data.actions.new(data["name"])
|
||||||
|
|
||||||
|
def load(self, data, target):
|
||||||
|
pass
|
||||||
|
# # find target object
|
||||||
|
# object_ = bpy.context.scene.objects.active
|
||||||
|
# if object_ is None:
|
||||||
|
# raise RuntimeError("Nothing is selected.")
|
||||||
|
# if object_.mode != 'POSE': # object must be in pose mode
|
||||||
|
# raise RuntimeError("Object must be in pose mode.")
|
||||||
|
# if object_.animation_data.action is None:
|
||||||
|
# raise RuntimeError("Object needs an active action.")
|
||||||
|
|
||||||
def dump(self, pointer=None):
|
def dump(self, pointer=None):
|
||||||
assert(pointer)
|
assert(pointer)
|
||||||
data = utils.dump_datablock(pointer, 1)
|
data = utils.dump_datablock(pointer, 1)
|
||||||
@ -50,4 +61,4 @@ bl_rep_class = BlAction
|
|||||||
bl_delay_refresh = 1
|
bl_delay_refresh = 1
|
||||||
bl_delay_apply = 1
|
bl_delay_apply = 1
|
||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_icon = 'ACTION_DATA'
|
bl_icon = 'ACTION_TWEAK'
|
@ -15,16 +15,12 @@ class BlDatablock(ReplicatedDatablock):
|
|||||||
# TODO: use is_library_indirect
|
# TODO: use is_library_indirect
|
||||||
self.is_library = (pointer and hasattr(pointer, 'library') and
|
self.is_library = (pointer and hasattr(pointer, 'library') and
|
||||||
pointer.library) or \
|
pointer.library) or \
|
||||||
(buffer and 'library' in buffer)
|
(buffer and 'library' in buffer)
|
||||||
# :
|
|
||||||
if self.is_library:
|
if self.is_library:
|
||||||
self.load = self.load_library
|
self.load = self.load_library
|
||||||
self.dump = self.dump_library
|
self.dump = self.dump_library
|
||||||
self.diff = self.diff_library
|
self.diff = self.diff_library
|
||||||
|
|
||||||
# self.construct = self.construct_library
|
|
||||||
# self.resolve_dependencies = self.resolve_dependencies_library
|
|
||||||
# self.apply = self.library_apply
|
|
||||||
|
|
||||||
if self.pointer and hasattr(self.pointer, 'uuid'):
|
if self.pointer and hasattr(self.pointer, 'uuid'):
|
||||||
self.pointer.uuid = self.uuid
|
self.pointer.uuid = self.uuid
|
||||||
@ -40,13 +36,10 @@ class BlDatablock(ReplicatedDatablock):
|
|||||||
return self.pointer.name != self.buffer['name']
|
return self.pointer.name != self.buffer['name']
|
||||||
|
|
||||||
def construct_library(self, data):
|
def construct_library(self, data):
|
||||||
with bpy.data.libraries.load(filepath=bpy.data.libraries[self.buffer['library']].filepath, link=True) as (sourceData, targetData):
|
|
||||||
# targetData[self.name] = sourceData
|
|
||||||
print("asd")
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def load_library(self, data, target):
|
def load_library(self, data, target):
|
||||||
print("asdasdas")
|
pass
|
||||||
|
|
||||||
def dump_library(self, pointer=None):
|
def dump_library(self, pointer=None):
|
||||||
return utils.dump_datablock(pointer, 1)
|
return utils.dump_datablock(pointer, 1)
|
||||||
@ -56,3 +49,11 @@ class BlDatablock(ReplicatedDatablock):
|
|||||||
|
|
||||||
def resolve_dependencies_library(self):
|
def resolve_dependencies_library(self):
|
||||||
return [self.pointer.library]
|
return [self.pointer.library]
|
||||||
|
|
||||||
|
def resolve_dependencies(self):
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
if hasattr(self.pointer,'animation_data') and self.pointer.animation_data:
|
||||||
|
dependencies.append(self.pointer.animation_data.action)
|
||||||
|
|
||||||
|
return dependencies
|
@ -18,6 +18,7 @@ def dump_image(image):
|
|||||||
image.save()
|
image.save()
|
||||||
file = open(image.filepath_raw, "rb")
|
file = open(image.filepath_raw, "rb")
|
||||||
pixels = file.read()
|
pixels = file.read()
|
||||||
|
file.close()
|
||||||
else:
|
else:
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
return pixels
|
return pixels
|
||||||
|
@ -44,13 +44,15 @@ class BlMaterial(BlDatablock):
|
|||||||
["nodes"][node]['image']['name']]
|
["nodes"][node]['image']['name']]
|
||||||
|
|
||||||
for input in data["node_tree"]["nodes"][node]["inputs"]:
|
for input in data["node_tree"]["nodes"][node]["inputs"]:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if hasattr(target.node_tree.nodes[index].inputs[input], "default_value"):
|
if hasattr(target.node_tree.nodes[index].inputs[input], "default_value"):
|
||||||
target.node_tree.nodes[index].inputs[input].default_value = data[
|
target.node_tree.nodes[index].inputs[input].default_value = data[
|
||||||
"node_tree"]["nodes"][node]["inputs"][input]["default_value"]
|
"node_tree"]["nodes"][node]["inputs"][input]["default_value"]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
print("loading error {}".format(e))
|
||||||
continue
|
continue
|
||||||
|
# utils.dump_anything.load(
|
||||||
|
# target.node_tree.nodes[index],data["node_tree"]["nodes"][node])
|
||||||
|
|
||||||
# Load nodes links
|
# Load nodes links
|
||||||
target.node_tree.links.clear()
|
target.node_tree.links.clear()
|
||||||
@ -68,8 +70,19 @@ class BlMaterial(BlDatablock):
|
|||||||
assert(pointer)
|
assert(pointer)
|
||||||
data = utils.dump_datablock(pointer, 2)
|
data = utils.dump_datablock(pointer, 2)
|
||||||
if pointer.use_nodes:
|
if pointer.use_nodes:
|
||||||
|
# nodes inputs
|
||||||
|
nodes = {}
|
||||||
|
for node in pointer.node_tree.nodes:
|
||||||
|
dumper = utils.dump_anything.Dumper()
|
||||||
|
if node.type == 'TEX_IMAGE':
|
||||||
|
dumper.depth = 2
|
||||||
|
else:
|
||||||
|
dumper.depth = 4
|
||||||
|
|
||||||
|
nodes[node.name] = dumper.dump(node)
|
||||||
|
data["node_tree"]['nodes']= nodes
|
||||||
utils.dump_datablock_attibutes(
|
utils.dump_datablock_attibutes(
|
||||||
pointer.node_tree, ["nodes", "links"], 3, data['node_tree'])
|
pointer.node_tree, ["links"], 3, data['node_tree'])
|
||||||
elif pointer.is_grease_pencil:
|
elif pointer.is_grease_pencil:
|
||||||
utils.dump_datablock_attibutes(pointer, ["grease_pencil"], 3, data)
|
utils.dump_datablock_attibutes(pointer, ["grease_pencil"], 3, data)
|
||||||
return data
|
return data
|
||||||
@ -81,7 +94,7 @@ class BlMaterial(BlDatablock):
|
|||||||
def diff(self):
|
def diff(self):
|
||||||
diff_rev = diff(self.dump(pointer=self.pointer), self.buffer)
|
diff_rev = diff(self.dump(pointer=self.pointer), self.buffer)
|
||||||
return (self.bl_diff() or
|
return (self.bl_diff() or
|
||||||
len(diff_rev.keys()) > 1)
|
len(diff_rev.keys()) > 0)
|
||||||
|
|
||||||
def resolve_dependencies(self):
|
def resolve_dependencies(self):
|
||||||
deps = []
|
deps = []
|
||||||
|
@ -145,8 +145,9 @@ class BlMesh(BlDatablock):
|
|||||||
data = dump_mesh(pointer, data)
|
data = dump_mesh(pointer, data)
|
||||||
# Fix material index
|
# Fix material index
|
||||||
m_list = []
|
m_list = []
|
||||||
for m in pointer.materials:
|
for material in pointer.materials:
|
||||||
m_list.append(m.name)
|
if material:
|
||||||
|
m_list.append(material.name)
|
||||||
|
|
||||||
data['material_list'] = m_list
|
data['material_list'] = m_list
|
||||||
|
|
||||||
|
@ -81,10 +81,13 @@ class BlObject(BlDatablock):
|
|||||||
self.dump(pointer=self.pointer)['matrix_world'] != self.buffer['matrix_world'])
|
self.dump(pointer=self.pointer)['matrix_world'] != self.buffer['matrix_world'])
|
||||||
|
|
||||||
def resolve_dependencies(self):
|
def resolve_dependencies(self):
|
||||||
deps = []
|
deps = super().resolve_dependencies()
|
||||||
|
|
||||||
# Avoid Empty case
|
# Avoid Empty case
|
||||||
if self.pointer.data:
|
if self.pointer.data:
|
||||||
deps.append(self.pointer.data)
|
deps.append(self.pointer.data)
|
||||||
|
if len(self.pointer.children)>0:
|
||||||
|
deps.extend(list(self.pointer.children))
|
||||||
|
|
||||||
if self.is_library:
|
if self.is_library:
|
||||||
deps.append(self.pointer.library)
|
deps.append(self.pointer.library)
|
||||||
|
@ -31,7 +31,8 @@ class BlUser(BlDatablock):
|
|||||||
|
|
||||||
self.state = UP
|
self.state = UP
|
||||||
#TODO: refactor in order to redraw in cleaner ways
|
#TODO: refactor in order to redraw in cleaner ways
|
||||||
if presence.renderer:
|
area, region, rv3d = presence.view3d_find()
|
||||||
|
if presence.renderer and area and region and rv3d :
|
||||||
presence.renderer.draw_client_camera(self.buffer['name'], self.buffer['location'],self.buffer['color'])
|
presence.renderer.draw_client_camera(self.buffer['name'], self.buffer['location'],self.buffer['color'])
|
||||||
presence.renderer.draw_client_selection(self.buffer['name'], self.buffer['color'],self.buffer['selected_objects'])
|
presence.renderer.draw_client_selection(self.buffer['name'], self.buffer['color'],self.buffer['selected_objects'])
|
||||||
presence.refresh_3d_view()
|
presence.refresh_3d_view()
|
||||||
|
Submodule libs/replication updated: 84d7460c85...f0a80fa847
29
operators.py
29
operators.py
@ -75,7 +75,10 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
for type in bl_types.types_to_register():
|
for type in bl_types.types_to_register():
|
||||||
_type = getattr(bl_types, type)
|
_type = getattr(bl_types, type)
|
||||||
supported_bl_types.append(_type.bl_id)
|
supported_bl_types.append(_type.bl_id)
|
||||||
|
|
||||||
|
# Retreive local replicated types settings
|
||||||
type_local_config = settings.supported_datablock[_type.bl_rep_class.__name__]
|
type_local_config = settings.supported_datablock[_type.bl_rep_class.__name__]
|
||||||
|
|
||||||
bpy_factory.register_type(
|
bpy_factory.register_type(
|
||||||
_type.bl_class,
|
_type.bl_class,
|
||||||
_type.bl_rep_class,
|
_type.bl_rep_class,
|
||||||
@ -100,7 +103,6 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
port=settings.port
|
port=settings.port
|
||||||
)
|
)
|
||||||
settings.is_admin = True
|
settings.is_admin = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
utils.clean_scene()
|
utils.clean_scene()
|
||||||
|
|
||||||
@ -109,7 +111,9 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
address=settings.ip,
|
address=settings.ip,
|
||||||
port=settings.port
|
port=settings.port
|
||||||
)
|
)
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
if client.state == 0:
|
if client.state == 0:
|
||||||
settings.is_admin = False
|
settings.is_admin = False
|
||||||
self.report(
|
self.report(
|
||||||
@ -131,12 +135,13 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
settings.user_uuid = client.add(usr)
|
settings.user_uuid = client.add(usr)
|
||||||
delayables.append(delayable.ClientUpdate(
|
delayables.append(delayable.ClientUpdate(
|
||||||
client_uuid=settings.user_uuid))
|
client_uuid=settings.user_uuid))
|
||||||
# delayables.append(delayable.RedrawTimer(timout=0.5))
|
|
||||||
for node in client.list():
|
for node in client.list():
|
||||||
try:
|
try:
|
||||||
client.commit(node)
|
client.commit(node)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
# Push all added values
|
# Push all added values
|
||||||
client.push()
|
client.push()
|
||||||
|
|
||||||
@ -144,8 +149,10 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
if settings.enable_presence:
|
if settings.enable_presence:
|
||||||
presence.renderer.run()
|
presence.renderer.run()
|
||||||
|
|
||||||
|
# Register blender main thread tools
|
||||||
for d in delayables:
|
for d in delayables:
|
||||||
d.register()
|
d.register()
|
||||||
|
|
||||||
self.report(
|
self.report(
|
||||||
{'INFO'},
|
{'INFO'},
|
||||||
"connexion on tcp://{}:{}".format(settings.ip, settings.port))
|
"connexion on tcp://{}:{}".format(settings.ip, settings.port))
|
||||||
@ -155,7 +162,7 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
class SessionStopOperator(bpy.types.Operator):
|
class SessionStopOperator(bpy.types.Operator):
|
||||||
bl_idname = "session.stop"
|
bl_idname = "session.stop"
|
||||||
bl_label = "close"
|
bl_label = "close"
|
||||||
bl_description = "stop net service"
|
bl_description = "Exit current session"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -207,7 +214,7 @@ class SessionPropertyRemoveOperator(bpy.types.Operator):
|
|||||||
class SessionPropertyRightOperator(bpy.types.Operator):
|
class SessionPropertyRightOperator(bpy.types.Operator):
|
||||||
bl_idname = "session.right"
|
bl_idname = "session.right"
|
||||||
bl_label = "Change owner to"
|
bl_label = "Change owner to"
|
||||||
bl_description = "stop net service"
|
bl_description = "Change owner of specified datablock"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
key: bpy.props.StringProperty(default="None")
|
key: bpy.props.StringProperty(default="None")
|
||||||
@ -239,8 +246,8 @@ class SessionPropertyRightOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
class SessionSnapUserOperator(bpy.types.Operator):
|
class SessionSnapUserOperator(bpy.types.Operator):
|
||||||
bl_idname = "session.snapview"
|
bl_idname = "session.snapview"
|
||||||
bl_label = "draw client_instances"
|
bl_label = "snap to user"
|
||||||
bl_description = "Description that shows in blender tooltips"
|
bl_description = "Snap 3d view to selected user"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
target_client: bpy.props.StringProperty(default="None")
|
target_client: bpy.props.StringProperty(default="None")
|
||||||
@ -265,8 +272,8 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
class SessionApply(bpy.types.Operator):
|
class SessionApply(bpy.types.Operator):
|
||||||
bl_idname = "session.apply"
|
bl_idname = "session.apply"
|
||||||
bl_label = "apply the target item into the blender data"
|
bl_label = "apply selected block into blender"
|
||||||
bl_description = "Apply target object into blender data"
|
bl_description = "Apply selected block into blender"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
target = bpy.props.StringProperty()
|
target = bpy.props.StringProperty()
|
||||||
@ -285,8 +292,8 @@ class SessionApply(bpy.types.Operator):
|
|||||||
|
|
||||||
class SessionCommit(bpy.types.Operator):
|
class SessionCommit(bpy.types.Operator):
|
||||||
bl_idname = "session.commit"
|
bl_idname = "session.commit"
|
||||||
bl_label = "commit and push the target to other clients"
|
bl_label = "commit and push selected datablock to server"
|
||||||
bl_description = "commit and push the target to other clients"
|
bl_description = "commit and push selected datablock to server"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
target = bpy.props.StringProperty()
|
target = bpy.props.StringProperty()
|
||||||
@ -305,6 +312,8 @@ class SessionCommit(bpy.types.Operator):
|
|||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def redresh_handler(dummy):
|
def redresh_handler(dummy):
|
||||||
|
"""force to refresh client renderer
|
||||||
|
"""
|
||||||
global client
|
global client
|
||||||
|
|
||||||
if client:
|
if client:
|
||||||
|
Reference in New Issue
Block a user