feat(rcf): uuid test
This commit is contained in:
43
client.py
43
client.py
@ -187,10 +187,10 @@ class RCFClientAgent(object):
|
|||||||
|
|
||||||
if value == 'None':
|
if value == 'None':
|
||||||
value = helpers.dump(key)
|
value = helpers.dump(key)
|
||||||
|
|
||||||
if value:
|
if value:
|
||||||
rcfmsg = message.RCFMessage(
|
rcfmsg = message.RCFMessage(
|
||||||
key=key, id=self.id, mtype="", body=value)
|
key=key, id=self.id,uuid=value['uuid'], mtype="", body=value)
|
||||||
|
|
||||||
rcfmsg.store(self.property_map)
|
rcfmsg.store(self.property_map)
|
||||||
rcfmsg.send(self.publisher)
|
rcfmsg.send(self.publisher)
|
||||||
@ -345,3 +345,42 @@ def serialization_agent(ctx, pipe):
|
|||||||
|
|
||||||
if agent.pipe in items:
|
if agent.pipe in items:
|
||||||
agent.control_message()
|
agent.control_message()
|
||||||
|
|
||||||
|
|
||||||
|
class SyncAgent(object):
|
||||||
|
ctx = None
|
||||||
|
pipe = None
|
||||||
|
|
||||||
|
def __init__(self, ctx, pipe):
|
||||||
|
self.ctx = ctx
|
||||||
|
self.pipe = pipe
|
||||||
|
logger.info("serialisation service launched")
|
||||||
|
|
||||||
|
def control_message(self):
|
||||||
|
msg = self.pipe.recv_multipart()
|
||||||
|
command = msg.pop(0)
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def sync_agent(ctx, pipe):
|
||||||
|
agent = SyncAgent(ctx, pipe)
|
||||||
|
|
||||||
|
global stop
|
||||||
|
while True:
|
||||||
|
if stop:
|
||||||
|
break
|
||||||
|
|
||||||
|
poller = zmq.Poller()
|
||||||
|
poller.register(agent.pipe, zmq.POLLIN)
|
||||||
|
|
||||||
|
try:
|
||||||
|
items = dict(poller.poll(1))
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
break
|
||||||
|
|
||||||
|
if agent.pipe in items:
|
||||||
|
agent.control_message()
|
||||||
|
|
||||||
|
# Synchronisation
|
||||||
|
|
9
draw.py
9
draw.py
@ -137,7 +137,14 @@ class HUD(object):
|
|||||||
self.d3d_items["{}/{}".format(client[0],
|
self.d3d_items["{}/{}".format(client[0],
|
||||||
select_ob)] = (shader, batch, color)
|
select_ob)] = (shader, batch, color)
|
||||||
else:
|
else:
|
||||||
self.d3d_items.clear()
|
key_to_remove = []
|
||||||
|
for k in self.d3d_items.keys():
|
||||||
|
if "{}/".format(client[0]) in k:
|
||||||
|
key_to_remove.append(k)
|
||||||
|
|
||||||
|
for k in key_to_remove:
|
||||||
|
del self.d3d_items[k]
|
||||||
|
|
||||||
def draw_clients(self):
|
def draw_clients(self):
|
||||||
clients = self.client.get("Client")
|
clients = self.client.get("Client")
|
||||||
|
|
||||||
|
63
helpers.py
63
helpers.py
@ -1,10 +1,13 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import mathutils
|
import mathutils
|
||||||
from .libs import dump_anything
|
from .libs import dump_anything
|
||||||
|
from uuid import uuid4
|
||||||
|
import logging
|
||||||
|
|
||||||
CORRESPONDANCE = {'Collection': 'collections', 'Mesh': 'meshes', 'Object': 'objects', 'Material': 'materials',
|
CORRESPONDANCE = {'Collection': 'collections', 'Mesh': 'meshes', 'Object': 'objects', 'Material': 'materials',
|
||||||
'Texture': 'textures', 'Scene': 'scenes', 'Light': 'lights', 'Camera': 'cameras', 'Action': 'actions', 'Armature': 'armatures', 'Grease Pencil': 'grease_pencils'}
|
'Texture': 'textures', 'Scene': 'scenes', 'Light': 'lights', 'Camera': 'cameras', 'Action': 'actions', 'Armature': 'armatures', 'Grease Pencil': 'grease_pencils'}
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# UTILITY FUNCTIONS
|
# UTILITY FUNCTIONS
|
||||||
def refresh_window():
|
def refresh_window():
|
||||||
@ -27,6 +30,10 @@ def load(key, value):
|
|||||||
target = resolve_bpy_path(key)
|
target = resolve_bpy_path(key)
|
||||||
target_type = key.split('/')[0]
|
target_type = key.split('/')[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
target.uuid = value['uuid']
|
||||||
|
except:
|
||||||
|
pass
|
||||||
if target_type == 'Object':
|
if target_type == 'Object':
|
||||||
load_object(target=target, data=value,
|
load_object(target=target, data=value,
|
||||||
create=True)
|
create=True)
|
||||||
@ -92,35 +99,38 @@ def load_client(client=None, data=None):
|
|||||||
def load_mesh(target=None, data=None, create=False):
|
def load_mesh(target=None, data=None, create=False):
|
||||||
import bmesh
|
import bmesh
|
||||||
|
|
||||||
# TODO: handle error
|
if not target or not target.is_editmode:
|
||||||
mesh_buffer = bmesh.new()
|
# TODO: handle error
|
||||||
|
mesh_buffer = bmesh.new()
|
||||||
|
|
||||||
for i in data["vertices"]:
|
for i in data["vertices"]:
|
||||||
mesh_buffer.verts.new(data["vertices"][i]["co"])
|
mesh_buffer.verts.new(data["vertices"][i]["co"])
|
||||||
|
|
||||||
mesh_buffer.verts.ensure_lookup_table()
|
mesh_buffer.verts.ensure_lookup_table()
|
||||||
|
|
||||||
for i in data["edges"]:
|
for i in data["edges"]:
|
||||||
verts = mesh_buffer.verts
|
verts = mesh_buffer.verts
|
||||||
v1 = data["edges"][i]["vertices"][0]
|
v1 = data["edges"][i]["vertices"][0]
|
||||||
v2 = data["edges"][i]["vertices"][1]
|
v2 = data["edges"][i]["vertices"][1]
|
||||||
mesh_buffer.edges.new([verts[v1], verts[v2]])
|
mesh_buffer.edges.new([verts[v1], verts[v2]])
|
||||||
|
|
||||||
for p in data["polygons"]:
|
for p in data["polygons"]:
|
||||||
verts = []
|
verts = []
|
||||||
for v in data["polygons"][p]["vertices"]:
|
for v in data["polygons"][p]["vertices"]:
|
||||||
verts.append(mesh_buffer.verts[v])
|
verts.append(mesh_buffer.verts[v])
|
||||||
|
|
||||||
if len(verts) > 0:
|
if len(verts) > 0:
|
||||||
mesh_buffer.faces.new(verts)
|
mesh_buffer.faces.new(verts)
|
||||||
|
|
||||||
if target is None and create:
|
if target is None and create:
|
||||||
target = bpy.data.meshes.new(data["name"])
|
target = bpy.data.meshes.new(data["name"])
|
||||||
|
|
||||||
mesh_buffer.to_mesh(target)
|
mesh_buffer.to_mesh(target)
|
||||||
|
|
||||||
# Load other meshes metadata
|
# Load other meshes metadata
|
||||||
dump_anything.load(target, data)
|
dump_anything.load(target, data)
|
||||||
|
else:
|
||||||
|
logger.info("Mesh can't be loaded")
|
||||||
|
|
||||||
|
|
||||||
def load_object(target=None, data=None, create=False):
|
def load_object(target=None, data=None, create=False):
|
||||||
@ -320,18 +330,21 @@ def dump(key):
|
|||||||
target_type = key.split('/')[0]
|
target_type = key.split('/')[0]
|
||||||
data = None
|
data = None
|
||||||
|
|
||||||
|
|
||||||
|
target.uuid = str(uuid4)
|
||||||
|
|
||||||
if target_type == 'Material':
|
if target_type == 'Material':
|
||||||
data = dump_datablock_attibute(target, ['name', 'node_tree'], 7)
|
data = dump_datablock_attibute(target, ['name', 'node_tree','uuid'], 7)
|
||||||
elif target_type == 'Grease Pencil':
|
elif target_type == 'Grease Pencil':
|
||||||
data = dump_datablock_attibute(
|
data = dump_datablock_attibute(
|
||||||
target, ['name', 'layers', 'materials'], 9)
|
target, ['name', 'layers', 'materials','uuid'], 9)
|
||||||
elif target_type == 'Camera':
|
elif target_type == 'Camera':
|
||||||
data = dump_datablock(target, 1)
|
data = dump_datablock(target, 1)
|
||||||
elif target_type == 'Light':
|
elif target_type == 'Light':
|
||||||
data = dump_datablock(target, 1)
|
data = dump_datablock(target, 1)
|
||||||
elif target_type == 'Mesh':
|
elif target_type == 'Mesh':
|
||||||
data = dump_datablock_attibute(
|
data = dump_datablock_attibute(
|
||||||
target, ['name', 'polygons', 'edges', 'vertices'], 6)
|
target, ['name', 'polygons', 'edges', 'vertices','uuid'], 6)
|
||||||
elif target_type == 'Object':
|
elif target_type == 'Object':
|
||||||
data = dump_datablock(target, 1)
|
data = dump_datablock(target, 1)
|
||||||
elif target_type == 'Collection':
|
elif target_type == 'Collection':
|
||||||
@ -379,7 +392,7 @@ def init_client(key=None):
|
|||||||
|
|
||||||
C = bpy.context
|
C = bpy.context
|
||||||
Net = C.scene.session_settings
|
Net = C.scene.session_settings
|
||||||
|
client_dict['uuid'] = str(uuid4())
|
||||||
client_dict['location'] = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
|
client_dict['location'] = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
|
||||||
client_dict['color'] = [Net.client_color.r,
|
client_dict['color'] = [Net.client_color.r,
|
||||||
Net.client_color.g, Net.client_color.b, 1]
|
Net.client_color.g, Net.client_color.b, 1]
|
||||||
|
56
operators.py
56
operators.py
@ -15,6 +15,7 @@ import gpu
|
|||||||
import mathutils
|
import mathutils
|
||||||
from bpy_extras import view3d_utils
|
from bpy_extras import view3d_utils
|
||||||
from gpu_extras.batch import batch_for_shader
|
from gpu_extras.batch import batch_for_shader
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
from . import client, ui, draw, helpers
|
from . import client, ui, draw, helpers
|
||||||
from .libs import umsgpack
|
from .libs import umsgpack
|
||||||
@ -86,21 +87,28 @@ def update_selected_object(context):
|
|||||||
|
|
||||||
username = bpy.context.scene.session_settings.username
|
username = bpy.context.scene.session_settings.username
|
||||||
client_key = "Client/{}".format(username)
|
client_key = "Client/{}".format(username)
|
||||||
client_data = client_instance.get(client_key)
|
client_data = client_instance.get(client_key)
|
||||||
|
|
||||||
selected_objects = helpers.get_selected_objects(context.scene)
|
selected_objects = helpers.get_selected_objects(context.scene)
|
||||||
# Active object bounding box
|
|
||||||
if len(selected_objects) > 0:
|
if len(selected_objects) > 0:
|
||||||
|
|
||||||
for obj in context.selected_objects:
|
for obj in context.selected_objects:
|
||||||
if obj.name not in client_data[0][1]['active_objects']:
|
if obj.name not in client_data[0][1]['active_objects']:
|
||||||
client_data[0][1]['active_objects'] = selected_objects
|
client_data[0][1]['active_objects'] = selected_objects
|
||||||
|
|
||||||
client_instance.set(client_key,client_data[0][1])
|
client_instance.set(client_key,client_data[0][1])
|
||||||
break
|
break
|
||||||
|
|
||||||
elif client_data[0][1]['active_objects']:
|
elif client_data[0][1]['active_objects']:
|
||||||
client_data[0][1]['active_objects'] = []
|
client_data[0][1]['active_objects'] = []
|
||||||
client_instance.set(client_key,client_data[0][1])
|
client_instance.set(client_key,client_data[0][1])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# for update in local_updates:
|
||||||
|
|
||||||
|
# client_instance.get('')
|
||||||
# if session.active_object is not context.selected_objects[0] or session.active_object.is_evaluated:
|
# if session.active_object is not context.selected_objects[0] or session.active_object.is_evaluated:
|
||||||
# session.active_object = context.selected_objects[0]
|
# session.active_object = context.selected_objects[0]
|
||||||
# key = "net/objects/{}".format(client_instance.id.decode())
|
# key = "net/objects/{}".format(client_instance.id.decode())
|
||||||
@ -131,6 +139,7 @@ def init_datablocks():
|
|||||||
|
|
||||||
for datatype in SUPPORTED_TYPES:
|
for datatype in SUPPORTED_TYPES:
|
||||||
for item in getattr(bpy.data, helpers.CORRESPONDANCE[datatype]):
|
for item in getattr(bpy.data, helpers.CORRESPONDANCE[datatype]):
|
||||||
|
item.uuid = str(uuid4())
|
||||||
key = "{}/{}".format(datatype, item.name)
|
key = "{}/{}".format(datatype, item.name)
|
||||||
print(key)
|
print(key)
|
||||||
client_instance.set(key)
|
client_instance.set(key)
|
||||||
@ -461,24 +470,36 @@ def depsgraph_update(scene):
|
|||||||
|
|
||||||
if client_instance and client_instance.agent.is_alive():
|
if client_instance and client_instance.agent.is_alive():
|
||||||
updates = bpy.context.depsgraph.updates
|
updates = bpy.context.depsgraph.updates
|
||||||
|
username = bpy.context.scene.session_settings.username
|
||||||
update_selected_object(bpy.context)
|
update_selected_object(bpy.context)
|
||||||
|
|
||||||
if is_dirty(updates):
|
|
||||||
for update in ordered(updates):
|
|
||||||
if update[2] == "Master Collection":
|
|
||||||
pass
|
|
||||||
elif update[1] in SUPPORTED_TYPES:
|
|
||||||
client_instance.set("{}/{}".format(update[1], update[2]))
|
|
||||||
|
|
||||||
# if hasattr(bpy.context, 'selected_objects'):
|
|
||||||
selected_objects = helpers.get_selected_objects(scene)
|
selected_objects = helpers.get_selected_objects(scene)
|
||||||
if len(selected_objects) > 0:
|
if len(selected_objects) > 0:
|
||||||
for updated_data in updates:
|
for update in updates:
|
||||||
if updated_data.id.name in selected_objects:
|
update_key = "{}/{}".format(update.id.bl_rna.name, update.id.name)
|
||||||
if updated_data.is_updated_transform or updated_data.is_updated_geometry:
|
remote_update = client_instance.get(update_key)
|
||||||
client_instance.set(
|
|
||||||
"{}/{}".format(updated_data.id.bl_rna.name, updated_data.id.name))
|
if remote_update and remote_update[0][1]["uuid"] == update.id.uuid:
|
||||||
|
print("{} sending update".format(username))
|
||||||
|
client_instance.set(
|
||||||
|
"{}/{}".format(update.id.bl_rna.name, update.id.name))
|
||||||
|
else:
|
||||||
|
print("{} applying update".format(username))
|
||||||
|
# if is_dirty(updates):
|
||||||
|
# for update in ordered(updates):
|
||||||
|
# if update[2] == "Master Collection":
|
||||||
|
# pass
|
||||||
|
# elif update[1] in SUPPORTED_TYPES:
|
||||||
|
# client_instance.set("{}/{}".format(update[1], update[2]))
|
||||||
|
|
||||||
|
# if hasattr(bpy.context, 'selected_objects'):
|
||||||
|
# selected_objects = helpers.get_selected_objects(scene)
|
||||||
|
# if len(selected_objects) > 0:
|
||||||
|
# for updated_data in updates:
|
||||||
|
# if updated_data.id.name in selected_objects:
|
||||||
|
# if updated_data.is_updated_transform or updated_data.is_updated_geometry:
|
||||||
|
# client_instance.set(
|
||||||
|
# "{}/{}".format(updated_data.id.bl_rna.name, updated_data.id.name))
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
@ -486,6 +507,7 @@ def register():
|
|||||||
for cls in classes:
|
for cls in classes:
|
||||||
register_class(cls)
|
register_class(cls)
|
||||||
bpy.types.ID.is_dirty = bpy.props.BoolProperty(default=False)
|
bpy.types.ID.is_dirty = bpy.props.BoolProperty(default=False)
|
||||||
|
bpy.types.ID.uuid = bpy.props.StringProperty(default="None")
|
||||||
bpy.types.Scene.session_settings = bpy.props.PointerProperty(
|
bpy.types.Scene.session_settings = bpy.props.PointerProperty(
|
||||||
type=session_settings)
|
type=session_settings)
|
||||||
bpy.app.handlers.depsgraph_update_post.append(depsgraph_update)
|
bpy.app.handlers.depsgraph_update_post.append(depsgraph_update)
|
||||||
|
Reference in New Issue
Block a user