data, addr = sock.recvfrom(1024) # Buffer size is 1024 bytes
print(f"Received message: {data} from {addr}")
# Process the binary data (replace with actual parsing logic)
parsed_data = parse_binary_data(data)
# Update the blendshapes in Blender
if parsed_data:
bpy.app.timers.register(lambda: update_blendshapes(parsed_data))
except Exception as e:
print(f"Error in udp_listener: {e}")
def parse_binary_data(data):
Determine the number of blendshape weights expected
num_blendshapes = len(blendshape_names)
# Calculate the expected data size (num_blendshapes * 4 bytes per float)
expected_data_size = num_blendshapes * 4
# Check if the received data matches the expected size
if len(data) >= expected_data_size:
# Unpack the data into floats
weights = struct.unpack('f' * num_blendshapes, data[:expected_data_size])
return weights
else:
print(f"Received data size ({len(data)}) does not match expected size ({expected_data_size})")
return None
def update_blendshapes(weights):
This function updates the blendshapes of a Blender object based on received weights
obj = bpy.data.objects.get("Head_Mesh") # Replace with your mesh object name
if obj and obj.data.shape_keys:
for i, weight in enumerate(weights):
shape_key = obj.data.shape_keys.key_blocks.get(blendshape_names[i])
if shape_key:
shape_key.value = weight
Hi there, I have been trying to get this script to work with a new version of blender but to no avail.
I am wondering if you maybe have an up to date script that will work?
I can get faceshift to talk to blender, and the data received, the issue I am having is with the transfer of the data to the blendshapes.
here is my code so far, wondering if you could help please
import bpy import socket import threading import struct
Define the UDP IP address and port
UDP_IP = "127.0.0.1" # Localhost (change to the IP address Faceshift Studio is sending to) UDP_PORT = 5005 # The port Faceshift Studio is sending to
Create a socket to listen for UDP packets
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((UDP_IP, UDP_PORT))
List of blendshape names
blendshape_names = [ "EyeBlink_L", "EyeBlink_R", "EyeSquint_L", "EyeSquint_R", "EyeDown_L", "EyeDown_R", "EyeIn_L", "EyeIn_R", "EyeOpen_L", "EyeOpen_R", "EyeOut_L", "EyeOut_R", "EyeUp_L", "EyeUp_R", "BrowsD_L", "BrowsD_R", "BrowsU_C", "BrowsU_L", "BrowsU_R", "JawOpen", "LipsTogether", "JawLeft", "JawRight", "JawFwd", "LipsUpperUp_L", "LipsUpperUp_R", "LipsLowerDown_L", "LipsLowerDown_R", "LipsUpperClose", "LipsLowerClose", "MouthSmile_L", "MouthSmile_R", "MouthDimple_L", "MouthDimple_R", "LipsStretch_L", "LipsStretch_R", "MouthFrown_L", "MouthFrown_R", "MouthPress_L", "MouthPress_R", "LipsPucker", "LipsFunnel", "MouthLeft", "MouthRight", "ChinLowerRaise", "ChinUpperRaise", "Sneer_L", "Sneer_R", "Puff", "CheekSquint_L", "CheekSquint_R" ]
def udp_listener(): while True: try:
Receive data from Faceshift Studio
def parse_binary_data(data):
Determine the number of blendshape weights expected
def update_blendshapes(weights):
This function updates the blendshapes of a Blender object based on received weights
Start the UDP listener in a separate thread
thread = threading.Thread(target=udp_listener) thread.daemon = True thread.start()
print("Started UDP listener...")
Keep the script running
def keep_running(): pass
bpy.app.timers.register(keep_running)