Commit 1385ac8c authored by Bruno Laurencich's avatar Bruno Laurencich

manage_notochord option

parent d50c53cc
......@@ -29,25 +29,38 @@ C = bpy.context
# = GLOBAL PROPERTIES =
# =========================================
class Chord_Properties(bpy.types.PropertyGroup):
def check_local_ip(self, context):
chord_global = context.user_preferences.addons[__package__].preferences
if chord_global.trans_method != "Multicast":
chord_global.local_ip_addr = u.get_local_ip()
class Chord_Properties(bpy.types.AddonPreferences):
"""A collection to hold all the global chordata properties.
can be retrived at bpy.context.window_manager.chordata"""
can be retrived at:
bpy.context.user_preferences.addons['<addon_name>'].preferences"""
bl_idname = __package__
state = props.EnumProperty(\
items=u.possible_states(),\
options={'SKIP_SAVE'})
options={'SKIP_SAVE'}
)
trans_method = props.EnumProperty(\
items= u.transmition_methods(),
default="Unicast")
default="Unicast",
update=check_local_ip)
net_submask = props.StringProperty( default = "255.255.255.0" )
notochord_msg = props.StringProperty( default = "" )
notochord_hostname = props.StringProperty( default = "notochord" )
notochord_hostname = props.StringProperty( name="Notochord hostname",
description="The hostname to be used for the ip resolution", default = "notochord" )
#TODO: find a way to get the local addr
notochord_dest_addr = props.StringProperty( default = "192.168.1.30" )
multicast_grp_addr = props.StringProperty( default = "239.0.0.1" )
local_ip_addr = props.StringProperty( default = u.get_local_ip() )
notochord_dest_port = props.IntProperty( default = 6565 )
......@@ -55,24 +68,30 @@ class Chord_Properties(bpy.types.PropertyGroup):
notochord_ip = props.StringProperty( default = "" )
last_check = props.IntProperty( default = 0 )
last_check = props.IntProperty( default = 0 , options={'SKIP_SAVE'})
max_ip_discover_attempts = props.IntProperty( default = 3 )
receiving = props.BoolProperty(default = False , options={'SKIP_SAVE'})
manage_notochord = props.BoolProperty( name="Manage notochord",
description="Start the notochord when receiving, and finish it on close", default = False )
show_advanced = props.BoolProperty( name="Show advanced panel", default = False )
# ====== End of GLOBAL PROPERTIES =======
def register():
# bpy.utils.register_class(Chord_Get_Ip)
bpy.utils.register_class(Chord_Properties)
WindowManager.chordata = \
bpy.props.PointerProperty(type=Chord_Properties, options={'SKIP_SAVE'})
# bpy.utils.register_class(Chord_Properties)
# WindowManager.chordata = \
# bpy.props.PointerProperty(type=Chord_Properties)
bpy.utils.register_module(__name__)
def unregister():
# bpy.utils.unregister_class(Chord_Get_Ip)
bpy.utils.unregister_module(__name__)
del WindowManager.chordata
# del WindowManager.chordata
if __name__ == "__main__":
register()
......
No preview for this file type
......@@ -31,6 +31,10 @@ class Chord_Get_Ip(bpy.types.Operator):
if event.type in {'RIGHTMOUSE', 'ESC'}:
self.report({"WARNING"}, "Connection canceled")
self.cancel(context)
with self.query_lock:
if not self.found_ip:
self.chord_global.state = u.possible_states()[0][0]
return {'CANCELLED'}
if event.type == 'TIMER':
......@@ -87,7 +91,7 @@ class Chord_Get_Ip(bpy.types.Operator):
# ----------- EXECUTE -----------
def execute(self, context):
self.chord_global = context.window_manager.chordata
self.chord_global = context.user_preferences.addons[__package__].preferences
self.chord_global.state = u.possible_states()[0][0]
self.chord_global.notochord_ip = ""
self.report({"INFO"},"ip query ongoing..")
......@@ -115,3 +119,25 @@ class Chord_Get_Ip(bpy.types.Operator):
print("thread joined..")
# ====== End of OPERATOR: GET THE NOTOCHORD IP =======
# ==============================================
# = OPERATOR: GET LOCAL IP =
# ==============================================
class Chord_Local_Ip(bpy.types.Operator):
bl_idname = "chordata.get_local_ip"
bl_label = "Chordata: get local ip"
bl_options = {'REGISTER'}
@classmethod
def poll(cls, context):
chord_global = context.user_preferences.addons[__package__].preferences
return chord_global.trans_method is not "Multicast"
def execute(self, context):
chord_global = context.user_preferences.addons[__package__].preferences
chord_global.local_ip_addr = u.get_local_ip()
return {"FINISHED"}
# ====== End of OPERATOR: GET LOCAL IP =======
......@@ -9,7 +9,7 @@ from requests.exceptions import RequestException as Http_Error
CHECK_PERIOD = 5
def get_conn_state_attr(context, attr = "name"):
current = context.window_manager.chordata.state
current = context.user_preferences.addons[__package__].preferences.state
return getattr(bpy.types.Chord_Properties\
.bl_rna.properties['state']\
.enum_items[current], attr )
......@@ -41,7 +41,7 @@ class Chord_tools_panel(bpy.types.Panel):
def draw(self, context):
self.chord_global = context.window_manager.chordata
self.chord_global = context.user_preferences.addons[__package__].preferences
layout = self.layout
if time() - self.chord_global.last_check > CHECK_PERIOD:
......@@ -54,30 +54,70 @@ class Chord_tools_panel(bpy.types.Panel):
layout.label(self.chord_global.state,\
icon= get_conn_state_attr(context, "icon"))
layout.operator("chordata.start_notochord", "Start")
layout.operator("chordata.close_notochord", "Stop")
layout.operator("chordata.receive", "Receive", icon='RADIO')
layout.prop(self.chord_global, "manage_notochord", expand=True)
recv_icon = "POSE_HLT", "ARMATURE_DATA"
if self.chord_global.manage_notochord: recv_icon = "RADIO", "CANCEL"
row = layout.row(align=True)
row.operator("chordata.receive", "Receive", icon=recv_icon[0])
row.operator("chordata.stop_receive", "Stop", icon=recv_icon[1])
layout.label("Transmision method")
layout.prop(self.chord_global, "trans_method", expand=True)
### PROPS BOX
### BOX
layout.separator()
box = layout.box()
box.label("Ip")
box.prop(self.chord_global, "notochord_dest_addr", text="")
box.label("Port")
box.prop(self.chord_global, "notochord_dest_port", text="")
box.label("Parameters")
box.prop(self.chord_global, "notochord_parameters", text="")
box.label("Transmision method")
row = box.row()
row.prop(self.chord_global, "trans_method", expand=True)
row = box.row()
split = row.split()#percentage=0.25
col = split.column()
# col.operator("my.button", text="21").loc="5 21"
if self.chord_global.trans_method == "Multicast":
col.label("Multicast group")
col.prop(self.chord_global, "multicast_grp_addr", text="")
else:
col.label("Local address")
col.prop(self.chord_global, "local_ip_addr", text="")
split = row.split()#percentage=0.25
col = split.column()
col.label("Port")
col.prop(self.chord_global, "notochord_dest_port", text="")
layout.prop(self.chord_global, "notochord_hostname")
layout.prop(self.chord_global, "show_advanced")
# conn_state = get_conn_state_attr(context, "name")
# print(conn_state)
class Chord_advanced_panel(bpy.types.Panel):
"""Main panel for the chordata client addon"""
bl_label = "Chordata Advanced"
bl_category = "Chordata"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
@classmethod
def poll(cls, context):
chord_global = context.user_preferences.addons[__package__].preferences
return chord_global.show_advanced
def draw(self, context):
self.chord_global = context.user_preferences.addons[__package__].preferences
layout = self.layout
layout.label("Control notochord")
row = layout.row(align=True)
row.alignment = 'EXPAND'
row.operator("chordata.start_notochord", "Start")
row.operator("chordata.close_notochord", "Stop")
layout.label("Parameters")
layout.prop(self.chord_global, "notochord_parameters", text="")
layout.prop(self.chord_global, "notochord_hostname")
\ No newline at end of file
......@@ -16,7 +16,15 @@ else:
D = bpy.data
class Chord_Stop_Receive_OSC(bpy.types.Operator):
"""Tries to get the ip of the notochord"""
bl_idname = "chordata.stop_receive"
bl_label = "Chordata: Cancel Pose Data reception"
bl_options = {'REGISTER'}
def execute(self, context):
context.user_preferences.addons[__package__].preferences.receiving = False
return {"FINISHED"}
class Chord_Receive_OSC(bpy.types.Operator):
......@@ -36,32 +44,35 @@ class Chord_Receive_OSC(bpy.types.Operator):
# ----------- MODAL -----------
def modal(self, context, event):
if event.type in {'RIGHTMOUSE', 'ESC'}:
bpy.ops.chordata.close_notochord("EXEC_DEFAULT")
if event.type in {'RIGHTMOUSE', 'ESC'} or not self.chord_global.receiving:
if self.chord_global.manage_notochord:
bpy.ops.chordata.close_notochord("EXEC_DEFAULT")
self.report({"WARNING"}, "Connection canceled")
self.cancel(context)
return {'CANCELLED'}
if event.type == 'TIMER':
for r in context.area.regions:
r.tag_redraw()
osc_process()
#receive
return {'PASS_THROUGH'}
# ----------- INVOKE -----------
def invoke(self, context, event):
bpy.ops.chordata.start_notochord("INVOKE_DEFAULT")
self.chord_global = context.user_preferences.addons[__package__].preferences
if self.chord_global.manage_notochord:
bpy.ops.chordata.start_notochord("INVOKE_DEFAULT")
return self.execute(context)
# ----------- EXECUTE -----------
def execute(self, context):
self.chord_global = context.window_manager.chordata
self.chord_global = context.user_preferences.addons[__package__].preferences
self.chord_global.receiving = True
wm = context.window_manager
self._timer = wm.event_timer_add( \
1 / context.scene.render.fps,\
......@@ -73,12 +84,10 @@ class Chord_Receive_OSC(bpy.types.Operator):
server = u.transmition_methods(False)[self.chord_global.trans_method][2]
addr = "0.0.0.0"
if self.chord_global.trans_method == "Multicast":
addr = self.chord_global.notochord_dest_addr
addr = self.chord_global.local_ip_addr
port= self.chord_global.notochord_dest_port
print(server, addr, port)
try:
server(addr, port, "chordata_armature_server")
except Exception as e:
......@@ -105,5 +114,7 @@ class Chord_Receive_OSC(bpy.types.Operator):
wm = context.window_manager
wm.event_timer_remove(self._timer)
osch.get_channel("chordata_armature_server").terminate()
self.chord_global.receiving = False
osc_terminate()
......@@ -30,7 +30,7 @@ class Chord_Runner_Base(bpy.types.Operator):
bl_label = "Chordata: runner_base"
bl_options = {'INTERNAL'}
m_no_ip = """Imposible to resolve notochord address"""
m_no_ip = """Imposible to resolve notochord address, please add the notochord's ip address manually """
m_not_connected = """Notochord is not connected"""
m_error = """There was an error with the notochord program"""
......@@ -59,22 +59,33 @@ class Chord_Start_Notochord(Chord_Runner_Base):
self.layout.separator()
self.layout.label("Press OK to start the notochord, might take some seconds")
def check_local_ip(self):
if self.chord_global.local_ip_addr:
return True
bpy.ops.chordata.get_local_ip()
if self.chord_global.local_ip_addr:
return True
return False
def invoke(self, context, event):
self.chord_global = context.window_manager.chordata
if not self.chord_global.notochord_ip:
self.chord_global = context.user_preferences.addons[__package__].preferences
if not self.check_local_ip():
self.report({"WARNING"}, self.m_no_ip)
bpy.context.window_manager.popup_menu(popup_message,
title=self.m_no_ip, icon='ERROR')
return {"FINISHED"}
return {"CANCELLED"}
try:
params = "?"
for p in self.chord_global.notochord_parameters.split():
params += "p=%s&" % p
addr = self.chord_global.notochord_dest_addr
addr = self.chord_global.local_ip_addr
if self.chord_global.trans_method == "Broadcast":
addr = self.chord_global.notochord_dest_addr
addr = self.chord_global.local_ip_addr
subm = self.chord_global.net_submask
addr = u.get_broadcast_addr(addr, subm)
......@@ -99,13 +110,12 @@ class Chord_Start_Notochord(Chord_Runner_Base):
if notochord_response["mode"] != "normal":
return self.remote_error()
print("START DIALOG")
return context.window_manager.invoke_props_dialog(self)
# ----------- EXECUTE -----------
def execute(self, context):
self.chord_global = context.window_manager.chordata
self.chord_global = context.user_preferences.addons[__package__].preferences
self.report({"INFO"},"Starting notochord..")
try:
......@@ -154,7 +164,7 @@ class Chord_Close_Notochord(Chord_Runner_Base):
# ----------- EXECUTE -----------
def execute(self, context):
self.chord_global = context.window_manager.chordata
self.chord_global = context.user_preferences.addons[__package__].preferences
self.report({"INFO"},"Closing notochord..")
try:
......
......@@ -4,6 +4,25 @@ from os.path import join, abspath, dirname
path.append(join(dirname(abspath(__file__)), "osc4py3-1.0.4"))
from osc4py3.as_comthreads import osc_udp_server, osc_multicast_server, osc_broadcast_server
import ipaddress
import socket
def get_local_ip():
"""Get local ip, from https://stackoverflow.com/a/28950776 """
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except:
IP = ""
finally:
s.close()
return IP
def transmition_methods(as_tuples = True):
"""Transmision method to be used"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment