feat(rcf): scene init
This commit is contained in:
19
client.py
19
client.py
@ -103,6 +103,14 @@ class RCFClient(object):
|
||||
global stop
|
||||
stop = True
|
||||
|
||||
def list(self):
|
||||
self.pipe.send_multipart([b"LIST"])
|
||||
try:
|
||||
reply = self.pipe.recv_multipart()
|
||||
except KeyboardInterrupt:
|
||||
return
|
||||
else:
|
||||
return umsgpack.unpackb(reply[0])
|
||||
|
||||
class RCFServer(object):
|
||||
address = None # Server address
|
||||
@ -165,7 +173,6 @@ class RCFClientAgent(object):
|
||||
elif command == b"SET":
|
||||
key = umsgpack.unpackb(msg[0])
|
||||
value = None
|
||||
|
||||
value = helpers.dump(key)
|
||||
|
||||
if value:
|
||||
@ -182,7 +189,10 @@ class RCFClientAgent(object):
|
||||
key = umsgpack.unpackb(msg[0])
|
||||
value = self.property_map.get(key)
|
||||
self.pipe.send(umsgpack.packb(value.body) if value else b'')
|
||||
|
||||
|
||||
elif command == b"LIST":
|
||||
self.pipe.send(umsgpack.packb(list(self.property_map)))
|
||||
|
||||
|
||||
def rcf_client_agent(ctx, pipe):
|
||||
agent = RCFClientAgent(ctx, pipe)
|
||||
@ -228,14 +238,15 @@ def rcf_client_agent(ctx, pipe):
|
||||
logger.info("snapshot complete")
|
||||
agent.state = State.ACTIVE
|
||||
else:
|
||||
helpers.load(rcfmsg.key,rcfmsg.body)
|
||||
rcfmsg.store(agent.property_map)
|
||||
elif agent.state == State.ACTIVE:
|
||||
if rcfmsg.id != agent.id:
|
||||
helpers.load(rcfmsg.key,rcfmsg.body)
|
||||
rcfmsg.store(agent.property_map)
|
||||
action = "update" if rcfmsg.body else "delete"
|
||||
logging.info("{}: received from {}:{},{} {}".format(agent.id,
|
||||
server.address, rcfmsg.body.id, server.port, action))
|
||||
logging.info("{}: received from {}:{},{} {}".format(rcfmsg.key,
|
||||
server.address, rcfmsg.id, server.port, action))
|
||||
else:
|
||||
logger.info("{} nothing to do".format(agent.id))
|
||||
|
||||
|
19
helpers.py
19
helpers.py
@ -2,13 +2,18 @@ import bpy
|
||||
from .libs import dump_anything
|
||||
|
||||
CORRESPONDANCE = {'Collection': 'collections', 'Mesh': 'meshes', 'Object': 'objects', 'Material': 'materials',
|
||||
'Texture': 'textures', 'Scene': 'scenes', 'Light': 'lights', 'Camera': 'cameras', 'Action': 'actions', 'Armature': 'armatures', 'GreasePencil': 'grease_pencils'}
|
||||
'Texture': 'textures', 'Scene': 'scenes', 'Light': 'lights', 'Camera': 'cameras', 'Action': 'actions', 'Armature': 'armatures', 'Grease Pencil': 'grease_pencils'}
|
||||
|
||||
|
||||
def refresh_window():
|
||||
import bpy
|
||||
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
|
||||
|
||||
# LOAD HELPERS
|
||||
|
||||
def load(key, value):
|
||||
target = resolve_bpy_path(key)
|
||||
target_type = target.__class__.__name__
|
||||
target_type = key.split('/')[0]
|
||||
if target:
|
||||
target.is_updating = True
|
||||
|
||||
@ -33,10 +38,11 @@ def load(key, value):
|
||||
elif 'Light' in target_type:
|
||||
load_light(target=target, data=value,
|
||||
create=True)
|
||||
else:
|
||||
elif target_type == 'Camera':
|
||||
load_default(target=target, data=value,
|
||||
create=True, type=target_type)
|
||||
|
||||
|
||||
def resolve_bpy_path(path):
|
||||
"""
|
||||
Get bpy property value from path
|
||||
@ -52,6 +58,7 @@ def resolve_bpy_path(path):
|
||||
|
||||
return item
|
||||
|
||||
|
||||
def load_mesh(target=None, data=None, create=False):
|
||||
import bmesh
|
||||
|
||||
@ -157,8 +164,8 @@ def load_scene(target=None, data=None, create=False):
|
||||
bpy.data.collections[collection])
|
||||
|
||||
# Load annotation
|
||||
if data["grease_pencil"]:
|
||||
target.grease_pencil = bpy.data.grease_pencils[data["grease_pencil"]["name"]]
|
||||
# if data["grease_pencil"]:
|
||||
# target.grease_pencil = bpy.data.grease_pencils[data["grease_pencil"]["name"]]
|
||||
except:
|
||||
print("Scene loading error")
|
||||
|
||||
@ -278,7 +285,7 @@ def load_default(target=None, data=None, create=False, type=None):
|
||||
|
||||
def dump(key):
|
||||
target = resolve_bpy_path(key)
|
||||
target_type = target.__class__.__name__
|
||||
target_type = key.split('/')[0]
|
||||
data = None
|
||||
|
||||
if target_type == 'Material':
|
||||
|
70
operators.py
70
operators.py
@ -16,12 +16,13 @@ import mathutils
|
||||
from bpy_extras import view3d_utils
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
from . import client, ui, draw
|
||||
from . import client, ui, draw, helpers
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
client_instance = None
|
||||
client_keys = None
|
||||
server = None
|
||||
context = None
|
||||
drawer = None
|
||||
@ -51,8 +52,8 @@ def get_update(type):
|
||||
|
||||
SUPPORTED_DATABLOCKS = ['collections', 'meshes', 'objects',
|
||||
'materials', 'textures', 'lights', 'cameras', 'actions', 'armatures', 'grease_pencils']
|
||||
SUPPORTED_TYPES = ['Mesh', 'Grease Pencil', 'Material',
|
||||
'Texture', 'Light', 'Camera', 'Object', 'Action', 'Armature','Collection', 'Scene']
|
||||
SUPPORTED_TYPES = [ 'Material',
|
||||
'Texture', 'Light', 'Camera','Mesh', 'Grease Pencil', 'Object', 'Action', 'Armature','Collection', 'Scene']
|
||||
|
||||
# UTILITY FUNCTIONS
|
||||
|
||||
@ -132,23 +133,15 @@ def update_selected_object(context):
|
||||
|
||||
return False
|
||||
|
||||
def init_scene():
|
||||
for gp in bpy.data.grease_pencils:
|
||||
upload_gpencil(gp)
|
||||
for cam in bpy.data.cameras:
|
||||
dump_datablock(cam, 1)
|
||||
for light in bpy.data.lights:
|
||||
dump_datablock(light, 1)
|
||||
for mat in bpy.data.materials:
|
||||
dump_datablock(mat, 7)
|
||||
for mesh in bpy.data.meshes:
|
||||
upload_mesh(mesh)
|
||||
for object in bpy.data.objects:
|
||||
dump_datablock(object, 1)
|
||||
for collection in bpy.data.collections:
|
||||
dump_datablock(collection, 4)
|
||||
for scene in bpy.data.scenes:
|
||||
dump_datablock(scene, 4)
|
||||
|
||||
def init_datablocks():
|
||||
global client_instance
|
||||
|
||||
for datatype in SUPPORTED_TYPES:
|
||||
print(datatype)
|
||||
for item in getattr(bpy.data,helpers.CORRESPONDANCE[datatype]):
|
||||
key = "{}/{}".format(datatype,item.name)
|
||||
client_instance.set(key)
|
||||
|
||||
def update_scene(msg):
|
||||
global client_instance
|
||||
@ -409,6 +402,22 @@ class session_join(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class session_refresh(bpy.types.Operator):
|
||||
bl_idname = "session.refresh"
|
||||
bl_label = "refresh"
|
||||
bl_description = "refresh client ui keys "
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def execute(self, context):
|
||||
global client_instance, client_keys
|
||||
|
||||
client_keys = client_instance.list()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class session_add_property(bpy.types.Operator):
|
||||
bl_idname = "session.add_prop"
|
||||
@ -427,22 +436,6 @@ class session_add_property(bpy.types.Operator):
|
||||
global client_instance
|
||||
|
||||
client_instance.set(self.property_path)
|
||||
# print(client_instance.get('key'))
|
||||
# item = resolve_bpy_path(self.property_path)
|
||||
|
||||
# print(item)
|
||||
|
||||
# if item:
|
||||
# key = self.property_path
|
||||
|
||||
# dumper = dump_anything.Dumper()
|
||||
# dumper.type_subset = dumper.match_subset_all
|
||||
# dumper.depth = self.depth
|
||||
|
||||
# data = dumper.dump(item)
|
||||
# data_type = item.__class__.__name__
|
||||
|
||||
# client_instance.push_update(key, data_type, data)
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
@ -489,8 +482,8 @@ class session_create(bpy.types.Operator):
|
||||
|
||||
bpy.ops.session.join()
|
||||
|
||||
# if context.scene.session_settings.init_scene:
|
||||
# init_scene()
|
||||
if context.scene.session_settings.init_scene:
|
||||
init_datablocks()
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
@ -589,6 +582,7 @@ class session_snapview(bpy.types.Operator):
|
||||
# TODO: Rename to match official blender convention
|
||||
classes = (
|
||||
session_join,
|
||||
session_refresh,
|
||||
session_add_property,
|
||||
session_stop,
|
||||
session_create,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import logging
|
||||
import time
|
||||
from operator import itemgetter
|
||||
|
||||
from libs import zmq
|
||||
|
||||
@ -7,6 +8,9 @@ import message
|
||||
logger = logging.getLogger("Server")
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
SUPPORTED_TYPES = [ 'Material',
|
||||
'Texture', 'Light', 'Camera','Mesh', 'Grease Pencil', 'Object', 'Action', 'Armature','Collection', 'Scene']
|
||||
|
||||
class RCFServerAgent():
|
||||
def __init__(self, context=zmq.Context.instance(), id="admin"):
|
||||
self.context = context
|
||||
@ -67,7 +71,10 @@ class RCFServerAgent():
|
||||
logger.info("Bad snapshot request")
|
||||
break
|
||||
|
||||
for k, v in self.property_map.items():
|
||||
ordered_props = [(SUPPORTED_TYPES.index(k.split('/')[0]),k,v) for k, v in self.property_map.items()]
|
||||
ordered_props.sort(key=itemgetter(0))
|
||||
|
||||
for i, k, v in ordered_props:
|
||||
logger.info(
|
||||
"Sending {} snapshot to {}".format(k, identity))
|
||||
self.request_sock.send(identity, zmq.SNDMORE)
|
||||
|
47
ui.py
47
ui.py
@ -139,29 +139,30 @@ class SessionPropertiesPanel(bpy.types.Panel):
|
||||
# Create a simple row.
|
||||
row = layout.row()
|
||||
|
||||
if operators.client:
|
||||
row = layout.row(align=True)
|
||||
row.prop(net_settings, "buffer", text="")
|
||||
row.prop(net_settings, "add_property_depth", text="")
|
||||
add = row.operator("session.add_prop", text="",
|
||||
icon="ADD")
|
||||
add.property_path = net_settings.buffer
|
||||
add.depth = net_settings.add_property_depth
|
||||
row = layout.row()
|
||||
# Property area
|
||||
area_msg = row.box()
|
||||
# if len(operators.client.property_map) > 0:
|
||||
# for key, values in operators.client.property_map.items():
|
||||
# item_box = area_msg.box()
|
||||
# detail_item_box = item_box.row()
|
||||
# # detail_item_box = item_box.row()
|
||||
|
||||
# detail_item_box.label(text="{} ({}) {} ".format(
|
||||
# key, values.mtype, values.id.decode()))
|
||||
# detail_item_box.operator(
|
||||
# "session.remove_prop", text="", icon="X").property_path = key
|
||||
# else:
|
||||
# area_msg.label(text="Empty")
|
||||
row = layout.row(align=True)
|
||||
row.prop(net_settings, "buffer", text="")
|
||||
row.prop(net_settings, "add_property_depth", text="")
|
||||
add = row.operator("session.add_prop", text="",
|
||||
icon="ADD")
|
||||
add.property_path = net_settings.buffer
|
||||
add.depth = net_settings.add_property_depth
|
||||
row = layout.row()
|
||||
# Property area
|
||||
area_msg = row.box()
|
||||
area_msg.operator("session.refresh", text="",
|
||||
icon="UV_SYNC_SELECT")
|
||||
if operators.client_keys and len(operators.client_keys) > 0:
|
||||
for item in operators.client_keys:
|
||||
item_box = area_msg.box()
|
||||
detail_item_box = item_box.row()
|
||||
# detail_item_box = item_box.row()
|
||||
|
||||
detail_item_box.label(text="{}".format(item))
|
||||
# detail_item_box.operator(
|
||||
# "session.remove_prop", text="", icon="X").property_path = key
|
||||
else:
|
||||
area_msg.label(text="Empty")
|
||||
|
||||
|
||||
class SessionTaskPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the scene context of the properties editor"""
|
||||
|
Reference in New Issue
Block a user