Da sich in der Endanwendung ca. 50 Musiker bewegen sollen, wurde nach einem Weg gesucht Rechenleistung einzusparen. Denn 50 Tabellen mit über 40.000 Zeilen abzutasten und als Visualisierung auszugeben, kostet enorm Leistung. Dadurch würde eine Verzögerung entstehen, welche die Bewegungen und das Audio nicht mehr synchronisiert darstellen würden. Alle Musiker müssten also ein eine gebackene Animation umgewandelt werden, die bereits berechnet und gestaltet ist. Für die Animation von humanoiden Charakteren gibt es das .bvh Format. Dieses Format wird oft benutzt um Motioncapture Daten auf ein selbstdesigntes Model oder Mesh anzuwenden. Mit Blender gibt es per Python Script eine Möglichkeit die Daten der csv an ein vorgefertigtes Meta-Rig "anzuklemmen". Mit diesem Rig hat man deutlich mehr Gestaltungsspielraum und Mögklichkeiten mit der Bewegung zu arbeiten. Die Daten Hierarchie sieht folgendermaßen aus.

Das Blender Script lädt die csv datei ein und geht dabei die Spalten (Gelenke X, Y und Z) und die Zeilen (Frames) durch. Mit der Sortierung in ein Array werden die Werte dann in der bvh-Struktur an der entsprechenden Stelle eingesetzt.

import csv
import os
import bpy

objects = bpy.context.scene.objects

empties = []

for object in objects:
if object.type == 'EMPTY':
empties.append(object)

#Einladen der .csv-Datei

filename = '2_Geige_1_rounded_10.csv' #.CSV file name

fullpath = os.path.join(os.getcwd(), filename)

with open(fullpath, 'r', newline='') as csvfile:
ofile = csv.reader(csvfile, delimiter=',')

print(ofile)

#Hier werden per for-Schleife die einzelnen Koordiaten eingelesen

i = 0

for line in ofile:
frame_num = i
fpts = [float(p) for p in line]
coordinates = [fpts[18:21], fpts[15:18], fpts[12:15],
fpts[3:6], fpts[6:9], fpts[9:12],
fpts[39:42], fpts[36:39], fpts[33:36],
fpts[42:45], fpts[45:48], fpts[48:51],
fpts[24:27], fpts[30:33],fpts[30:33], fpts[30:33],
fpts[30:33], fpts[30:33], fpts[30:33], fpts[0:3]]

#Hier werden die Daten in die .bvh des Metarigs eingebettet

bpy.context.scene.frame_set(frame_num)
for ob, position in zip(empties, coordinates):
ob.location = position
ob.keyframe_insert(data_path="location", index=-1)
print(ob.name)

i += 1

bpy.data.objects['rig'].select = True

target_file = os.path.join(os.getcwd(), 'estimated_animation.bvh')

bpy.ops.export_anim.bvh(filepath=target_file)

 

Da über 40.000 Zeilen konvertiert werden, wird das Script in der Shell ausgeführt und nicht im Blender Interface. Wie auch im Post mit der Pipelineentwicklung haben wir per Bash Script eine Schleife erstellt die alle CSV Daten nacheinander umwandelt. In der Blender Datei muss allerdings noch voreingestellt werden, wie viele Frames konvertiert werden sollen. Die Einstellung dafür findet sich unten im Animationsarbeitsbereich. Der Rohbefehl ist dieser hier:

blender --background directory/csv_to_bvh.blend -noaudio -P directory/csv_to_bvh.py

An dieser Stelle vielen dank an Dene, auf dessen Script aufgebaut wurde und uns bei der Anpassung des Scripts geholfen hat.
https://github.com/Dene33