import bpy
from mathutils import Quaternion
from chordata.nodes.basenode import ChordataBaseNode, set_dirty_flag
from chordata.ops import engine
from chordata.utils import gui
from chordata.copp_server.osc4py3_buildparse import oscbuildparse as oscparse
from chordata.copp_server.COPP_server import COPP_Message, COPP_Base_packet
import socket
class CustomSettings(bpy.types.PropertyGroup):
"""Property group for the custom node settings"""
do_transmit: bpy.props.BoolProperty(
name="forward incoming msgs", default=False, update=set_dirty_flag)
forward_ip: bpy.props.StringProperty(
name="Forward IP", default="127.0.0.1")
forward_port: bpy.props.IntProperty(name="Forward Port", default=7000)
# =========================================
# = CUSTOM NODE CLASS =
# =========================================
class CustomNode(ChordataBaseNode):
'''Modify this class to create a node with custom behaviour'''
bl_idname = 'CustomNodeType'
bl_label = "Custom Node"
# === Property Group Pointer ===================================================
# the settings in this property group will be exposed to the Chordata engine
# through the property `id_settings`
settings: bpy.props.PointerProperty(type=CustomSettings)
# ==============================================================================
def init(self, context):
"""This function is executed on node creation"""
self.width = 350.0
self.inputs.new('DataStreamSocketType', "data_in")
# self.outputs.new('DataStreamSocketType', "data_out")
def draw_buttons(self, context, layout):
"""Here you can draw the GUI of the node"""
layout.prop(self.settings, "forward_ip", text="Forward IP")
layout.prop(self.settings, "forward_port", text="Forward Port")
layout.prop(self.settings, "do_transmit", icon="RIGHTARROW_THIN", expand=True)
def draw_label(self):
return "Custom Node (forward RAW)"
@engine.datatarget_handler(engine.DataTarget.RAW)
def out_raw(self, packet):
"""Each Chordata Node can handle one or more DataTargets coming from the capture stream.
Node methods should be decorated with one or more engine.datatarget_handler to made them
available to the Chordata engine."""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = (self.id_settings.forward_ip, self.id_settings.forward_port)
raw_pkt = bytearray()
if isinstance(packet, COPP_Base_packet):
bun = oscparse.OSCBundle(oscparse.OSC_IMMEDIATELY, packet._get_elements())
oscparse._encode_bundle(bun, raw_pkt, {})
elif isinstance(packet, COPP_Message):
oscparse._encode_message(packet, raw_pkt, {})
sock.sendto(raw_pkt, server_address)
# @engine.helper_method
# def _output(self, label, msg):
# """If you need to create subroutines, to call from the main datatarget_handlers
# they should be decorated as engine.helper_method"""
# #Print the contents of the msg
# print(label, msg.payload, "with subtarget", msg.subtarget )
# ====== End of CUSTOM NODE CLASS =======
# the following lines tell blender to apply the modifications on the custom node
to_register = (CustomSettings, CustomNode)
if __name__ == '__main__':
from bpy.utils import register_class
for cls in to_register:
register_class(cls)