Files
blender-portable-repo/scripts/addons/rokoko-studio-live-blender-master/core/receiver.py
T
2026-03-17 14:58:51 -06:00

162 lines
5.1 KiB
Python

import bpy
import time
import socket
import traceback
from . import animations, utils
error_temp = ''
show_error = []
# Starts UPD server and handles data received from Rokoko Studio
class Receiver:
sock = None
# Redraw counters
i = -1 # Number of continuous received packets
i_np = 0 # Number of continuous no packets
# Error counters
error_temp = []
error_count = 0
def run(self):
data_raw = None
received = True
error = []
force_error = False
# Try to receive a packet
try:
data_raw, address = self.sock.recvfrom(81920) # Prev 65536
except BlockingIOError as e:
print('Blocking error:', e)
error = ['Receiving no data!']
except OSError as e:
print('Packet error:', e.strerror)
error = ['Packets too big!']
force_error = True
except AttributeError as e:
print('Socket error:', e)
error = ['Socket not running!']
force_error = True
# start_time = time.time()
# Process the packet
if data_raw:
# print('SIZE:', len(data_raw))
# print('DATA:', data_raw)
# Process animation data
error, force_error = self.process_data(data_raw)
# print(round((time.time() - start_time) * 1000, 4), 'ms')
self.handle_ui_updates(received)
self.handle_error(error, force_error)
def process_data(self, data_raw) -> ([str], bool):
"""
Processes the received data. If there was an error it returns a list of strings creating the error message
and if the error should be forced to show immediately instead of after a couple of packages
:param data_raw:
:return:
"""
try:
animations.live_data.init(data_raw)
except ValueError as e:
print('Packet contained no data')
print(e)
return ['Packets contain no data!'], False
except (UnicodeDecodeError, TypeError) as e:
print('Wrong live data format! Use JSON v2 or higher!')
print(e)
print(traceback.format_exc())
return ['Wrong data format!', 'Use JSON v2 or higher!'], True
except KeyError as e:
print('KeyError:', e)
return ['Incompatible JSON version!', 'Use the latest Studio', 'and plugin versions.'], True
except ImportError as e:
# This error occurs specifically when LZ4 isn't supported by the operating system
if "os" in e.msg:
print('LZ4 unsupported by OS!', 'Use "Json" in the', 'Custom panel in Studio.')
return ['LZ4 unsupported by OS!', 'Use "Json" in the', 'Custom panel in Studio.'], True
# This error occurs, when the LZ4 package could not be loaded while it was needed
print('LZ4 unsupported by OS or', 'Blender! Use "Json" in the', 'Custom panel in Studio.')
return ['LZ4 unsupported by OS or', 'Blender! Use "Json" in the', 'Custom panel in Studio.'], True
animations.animate()
return None, False
def handle_ui_updates(self, received):
# Update UI every 5 seconds when packets are received continuously
if received:
self.i += 1
self.i_np = 0
if self.i % (bpy.context.scene.rsl_receiver_fps * 5) == 0:
utils.ui_refresh_properties()
utils.ui_refresh_view_3d()
return
# If receiving a packet after one second of no packets, update UI with next packet
self.i_np += 1
if self.i_np == bpy.context.scene.rsl_receiver_fps:
self.i = -1
def handle_error(self, error, force_error):
global show_error
if not error:
self.error_count = 0
if not show_error:
return
self.error_temp = []
show_error = []
utils.ui_refresh_view_3d()
print('REFRESH')
return
if not self.error_temp:
self.error_temp = error
if force_error:
self.error_count = bpy.context.scene.rsl_receiver_fps - 1
return
if error == self.error_temp:
self.error_count += 1
else:
self.error_temp = error
if force_error:
self.error_count = bpy.context.scene.rsl_receiver_fps
else:
self.error_count = 0
if self.error_count == bpy.context.scene.rsl_receiver_fps:
show_error = self.error_temp
utils.ui_refresh_view_3d()
print('REFRESH')
def start(self, port):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.setblocking(False)
self.sock.bind(('', port))
self.i = -1
self.i_np = 0
self.error_temp = []
self.error_count = 0
global show_error
show_error = False
print("Rokoko Studio Live started listening on port " + str(port))
def stop(self):
self.sock.close()
print("Rokoko Studio Live stopped listening")