2019-08-28 18:57:09 +08:00
|
|
|
import logging
|
2019-08-23 18:28:57 +08:00
|
|
|
|
2019-09-30 19:35:50 +08:00
|
|
|
import bpy
|
|
|
|
|
|
|
|
from . import operators, presence, utils
|
2019-08-14 03:32:15 +08:00
|
|
|
from .bl_types.bl_user import BlUser
|
2019-09-24 20:42:59 +08:00
|
|
|
from .libs.replication.replication.constants import FETCHED, RP_COMMON
|
2019-08-23 18:28:57 +08:00
|
|
|
|
2019-08-28 18:57:09 +08:00
|
|
|
logger = logging.getLogger(__name__)
|
2019-08-14 00:00:54 +08:00
|
|
|
|
2019-09-27 20:50:00 +08:00
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
class Delayable():
|
2019-08-14 21:01:30 +08:00
|
|
|
"""Delayable task interface
|
|
|
|
"""
|
2019-08-23 18:28:57 +08:00
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
def register(self):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def execute(self):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def unregister(self):
|
|
|
|
raise NotImplementedError
|
|
|
|
|
2019-08-23 18:28:57 +08:00
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
class Timer(Delayable):
|
|
|
|
"""Timer binder interface for blender
|
|
|
|
|
|
|
|
Run a bpy.app.Timer in the background looping at the given rate
|
|
|
|
"""
|
2019-08-23 18:28:57 +08:00
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
def __init__(self, duration=1):
|
|
|
|
self._timeout = duration
|
2019-09-27 20:50:00 +08:00
|
|
|
self._running = True
|
2019-08-14 00:00:54 +08:00
|
|
|
|
|
|
|
def register(self):
|
|
|
|
"""Register the timer into the blender timer system
|
|
|
|
"""
|
2019-09-27 20:50:00 +08:00
|
|
|
bpy.app.timers.register(self.main)
|
|
|
|
|
|
|
|
def main(self):
|
|
|
|
self.execute()
|
2019-08-14 00:00:54 +08:00
|
|
|
|
2019-09-27 20:50:00 +08:00
|
|
|
if self._running:
|
|
|
|
return self._timeout
|
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
def execute(self):
|
|
|
|
"""Main timer loop
|
|
|
|
"""
|
2019-09-27 20:50:00 +08:00
|
|
|
raise NotImplementedError
|
2019-08-14 00:00:54 +08:00
|
|
|
|
|
|
|
def unregister(self):
|
|
|
|
"""Unnegister the timer of the blender timer system
|
|
|
|
"""
|
2019-09-27 20:50:00 +08:00
|
|
|
if bpy.app.timers.is_registered(self.main):
|
|
|
|
bpy.app.timers.unregister(self.main)
|
2019-08-14 00:00:54 +08:00
|
|
|
|
2019-09-27 20:50:00 +08:00
|
|
|
self._running = False
|
2019-08-23 18:28:57 +08:00
|
|
|
|
2019-09-30 19:35:50 +08:00
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
class ApplyTimer(Timer):
|
2019-08-23 18:28:57 +08:00
|
|
|
def __init__(self, timout=1, target_type=None):
|
2019-08-14 00:00:54 +08:00
|
|
|
self._type = target_type
|
|
|
|
super().__init__(timout)
|
|
|
|
|
|
|
|
def execute(self):
|
|
|
|
if operators.client:
|
|
|
|
nodes = operators.client.list(filter=self._type)
|
|
|
|
|
|
|
|
for node in nodes:
|
2019-08-26 23:27:12 +08:00
|
|
|
node_ref = operators.client.get(uuid=node)
|
2019-08-14 00:00:54 +08:00
|
|
|
|
|
|
|
if node_ref.state == FETCHED:
|
2019-10-04 00:30:46 +08:00
|
|
|
try:
|
|
|
|
operators.client.apply(node)
|
|
|
|
except Exception:
|
2019-10-09 20:09:11 +08:00
|
|
|
logger.error("fail to apply {}".format(node_ref.uuid))
|
2019-08-14 00:00:54 +08:00
|
|
|
|
|
|
|
|
2019-09-19 05:55:30 +08:00
|
|
|
class DynamicRightSelectTimer(Timer):
|
2019-10-02 20:01:45 +08:00
|
|
|
def __init__(self, timout=.1):
|
2019-09-19 05:55:30 +08:00
|
|
|
super().__init__(timout)
|
2019-09-30 19:35:50 +08:00
|
|
|
self.last_selection = []
|
2019-09-19 05:55:30 +08:00
|
|
|
|
|
|
|
def execute(self):
|
|
|
|
if operators.client:
|
|
|
|
users = operators.client.list(filter=BlUser)
|
|
|
|
|
|
|
|
for user in users:
|
|
|
|
user_ref = operators.client.get(uuid=user)
|
|
|
|
settings = bpy.context.window_manager.session
|
2019-09-30 19:35:50 +08:00
|
|
|
|
|
|
|
# Local user
|
2019-10-02 20:01:45 +08:00
|
|
|
if user_ref.pointer:
|
2019-09-30 19:35:50 +08:00
|
|
|
current_selection = utils.get_selected_objects(
|
|
|
|
bpy.context.scene)
|
2019-09-19 15:57:14 +08:00
|
|
|
if current_selection != self.last_selection:
|
2019-09-30 19:35:50 +08:00
|
|
|
right_strategy = operators.client.get_config()[
|
|
|
|
'right_strategy']
|
|
|
|
if right_strategy == RP_COMMON:
|
|
|
|
obj_common = [
|
|
|
|
o for o in self.last_selection if o not in current_selection]
|
|
|
|
obj_ours = [
|
|
|
|
o for o in current_selection if o not in self.last_selection]
|
2019-09-21 05:58:57 +08:00
|
|
|
|
2019-09-27 23:54:52 +08:00
|
|
|
# change new selection to our
|
2019-09-21 05:58:57 +08:00
|
|
|
for obj in obj_ours:
|
2019-10-09 03:48:45 +08:00
|
|
|
node = operators.client.get(uuid=obj)
|
2019-09-27 23:54:52 +08:00
|
|
|
if node and node.owner == RP_COMMON:
|
2019-09-30 19:35:50 +08:00
|
|
|
operators.client.change_owner(
|
|
|
|
node.uuid, settings.username)
|
2019-10-02 20:01:45 +08:00
|
|
|
else:
|
|
|
|
return
|
2019-09-27 23:54:52 +08:00
|
|
|
|
2019-10-02 20:01:45 +08:00
|
|
|
self.last_selection = current_selection
|
|
|
|
user_ref.pointer.update_selected_objects(
|
|
|
|
bpy.context)
|
|
|
|
user_ref.update()
|
2019-08-26 23:27:12 +08:00
|
|
|
|
2019-10-02 20:01:45 +08:00
|
|
|
# change old selection right to common
|
|
|
|
for obj in obj_common:
|
2019-10-09 03:48:45 +08:00
|
|
|
node = operators.client.get(uuid=obj)
|
2019-10-02 20:01:45 +08:00
|
|
|
if node and (node.owner == settings.username or node.owner == RP_COMMON):
|
|
|
|
operators.client.change_owner(
|
|
|
|
node.uuid, RP_COMMON)
|
2019-10-03 19:23:59 +08:00
|
|
|
else:
|
|
|
|
for obj in bpy.data.objects:
|
2019-10-09 03:48:45 +08:00
|
|
|
if obj.hide_select and obj.uuid not in user_ref.data['selected_objects']:
|
2019-10-03 19:23:59 +08:00
|
|
|
obj.hide_select = False
|
2019-10-09 03:48:45 +08:00
|
|
|
elif not obj.hide_select and obj.uuid in user_ref.data['selected_objects']:
|
2019-10-03 19:23:59 +08:00
|
|
|
obj.hide_select = True
|
2019-08-23 18:28:57 +08:00
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
class Draw(Delayable):
|
|
|
|
def __init__(self):
|
|
|
|
self._handler = None
|
|
|
|
|
|
|
|
def register(self):
|
|
|
|
self._handler = bpy.types.SpaceView3D.draw_handler_add(
|
2019-08-23 18:28:57 +08:00
|
|
|
self.execute, (), 'WINDOW', 'POST_VIEW')
|
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
def execute(self):
|
|
|
|
raise NotImplementedError()
|
2019-08-23 18:28:57 +08:00
|
|
|
|
2019-08-14 00:00:54 +08:00
|
|
|
def unregister(self):
|
2019-08-14 03:32:15 +08:00
|
|
|
try:
|
|
|
|
bpy.types.SpaceView3D.draw_handler_remove(
|
2019-08-23 18:28:57 +08:00
|
|
|
self._handler, "WINDOW")
|
2019-08-14 03:32:15 +08:00
|
|
|
except:
|
2019-08-28 18:57:09 +08:00
|
|
|
logger.error("draw already unregistered")
|
2019-08-23 18:28:57 +08:00
|
|
|
|
|
|
|
|
2019-10-02 20:01:45 +08:00
|
|
|
class DrawClient(Draw):
|
|
|
|
def execute(self):
|
|
|
|
repo = operators.client
|
|
|
|
if repo and presence.renderer:
|
|
|
|
settings = bpy.context.window_manager.session
|
|
|
|
client_list = [key for key in repo.list(filter=BlUser) if
|
|
|
|
key != settings.user_uuid]
|
|
|
|
|
|
|
|
for cli in client_list:
|
|
|
|
cli_ref = repo.get(uuid=cli)
|
2019-10-09 00:45:46 +08:00
|
|
|
if cli_ref.data.get('name'):
|
|
|
|
if settings.presence_show_selected:
|
|
|
|
presence.renderer.draw_client_selection(
|
|
|
|
cli_ref.data['name'], cli_ref.data['color'], cli_ref.data['selected_objects'])
|
|
|
|
if settings.presence_show_user:
|
|
|
|
presence.renderer.draw_client_camera(
|
|
|
|
cli_ref.data['name'], cli_ref.data['location'], cli_ref.data['color'])
|
2019-10-02 20:01:45 +08:00
|
|
|
|
|
|
|
|
2019-10-03 19:23:59 +08:00
|
|
|
class ClientUpdate(Timer):
|
|
|
|
def __init__(self, timout=1, client_uuid=None):
|
2019-08-14 00:00:54 +08:00
|
|
|
assert(client_uuid)
|
|
|
|
self._client_uuid = client_uuid
|
2019-10-03 19:23:59 +08:00
|
|
|
super().__init__(timout)
|
2019-08-14 00:00:54 +08:00
|
|
|
|
|
|
|
def execute(self):
|
2019-08-26 23:59:36 +08:00
|
|
|
if self._client_uuid and operators.client:
|
2019-08-26 23:27:12 +08:00
|
|
|
client = operators.client.get(uuid=self._client_uuid)
|
2019-08-14 03:32:15 +08:00
|
|
|
|
|
|
|
if client:
|
|
|
|
client.pointer.update_location()
|