{"id":156,"date":"2019-03-30T13:40:38","date_gmt":"2019-03-30T13:40:38","guid":{"rendered":"http:\/\/symotiv.de\/?p=156"},"modified":"2019-05-06T15:50:09","modified_gmt":"2019-05-06T15:50:09","slug":"10-transfer-der-daten-auf-biomechanisches-modell","status":"publish","type":"post","link":"https:\/\/symotiv.de\/10-transfer-der-daten-auf-biomechanisches-modell","title":{"rendered":"10 – Transfer der Daten auf biomechanisches Modell"},"content":{"rendered":"

Da sich in der Endanwendung ca. 50 Musiker bewegen sollen, wurde nach einem Weg gesucht Rechenleistung einzusparen. Denn 50 Tabellen mit \u00fcber 40.000 Zeilen abzutasten und als Visualisierung auszugeben, kostet enorm Leistung. Dadurch w\u00fcrde eine Verz\u00f6gerung entstehen, welche die Bewegungen und das Audio nicht mehr synchronisiert darstellen w\u00fcrden. Alle Musiker m\u00fcssten also ein eine gebackene Animation umgewandelt werden, die bereits berechnet und gestaltet ist. F\u00fcr 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\u00f6glichkeit die Daten der csv an ein vorgefertigtes Meta-Rig \"anzuklemmen\". Mit diesem Rig hat man deutlich mehr Gestaltungsspielraum und M\u00f6gklichkeiten mit der Bewegung zu arbeiten. Die Daten Hierarchie sieht folgenderma\u00dfen aus.<\/p>\n

\"\"<\/p>\n

Das Blender Script l\u00e4dt 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.<\/p>\n

import csv
\nimport os
\nimport bpy<\/p>\n

objects = bpy.context.scene.objects<\/p>\n

empties = []<\/p>\n

for object in objects:
\nif object.type == 'EMPTY':
\nempties.append(object)<\/p>\n

#Einladen der .csv-Datei<\/p>\n

filename = '2_Geige_1_rounded_10.csv' #.CSV file name<\/p>\n

fullpath = os.path.join(os.getcwd(), filename)<\/p>\n

with open(fullpath, 'r', newline='') as csvfile:
\nofile = csv.reader(csvfile, delimiter=',')<\/p>\n

print(ofile)<\/p>\n

#Hier werden per for-Schleife die einzelnen Koordiaten eingelesen<\/p>\n

i = 0<\/p>\n

for line in ofile:
\nframe_num = i
\nfpts = [float(p) for p in line]
\ncoordinates = [fpts[18:21], fpts[15:18], fpts[12:15],
\nfpts[3:6], fpts[6:9], fpts[9:12],
\nfpts[39:42], fpts[36:39], fpts[33:36],
\nfpts[42:45], fpts[45:48], fpts[48:51],
\nfpts[24:27], fpts[30:33],fpts[30:33], fpts[30:33],
\nfpts[30:33], fpts[30:33], fpts[30:33], fpts[0:3]]<\/p>\n

#Hier werden die Daten in die .bvh des Metarigs eingebettet<\/p>\n

bpy.context.scene.frame_set(frame_num)
\nfor ob, position in zip(empties, coordinates):
\nob.location = position
\nob.keyframe_insert(data_path=\"location\", index=-1)
\nprint(ob.name)<\/p>\n

i += 1<\/p>\n

bpy.data.objects['rig'].select = True<\/p>\n

target_file = os.path.join(os.getcwd(), 'estimated_animation.bvh')<\/p>\n

bpy.ops.export_anim.bvh(filepath=target_file)<\/p><\/blockquote>\n

 <\/p>\n

Da \u00fcber 40.000 Zeilen konvertiert werden, wird das Script in der Shell ausgef\u00fchrt 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\u00fcr findet sich unten im Animationsarbeitsbereich. Der Rohbefehl ist dieser hier:<\/p>\n

blender<\/span> --<\/span>background<\/span> directory<\/span>\/<\/span>csv_to_bvh<\/span>.<\/span>blend<\/span> -<\/span>noaudio<\/span> -<\/span>P<\/span> directory<\/span>\/<\/span>csv_to_bvh<\/span>.<\/span>py<\/span><\/pre>\n
\n