Spaces:
Build error
Build error
| import csv | |
| import bpy | |
| from mathutils import * | |
| import sys | |
| argv = sys.argv | |
| argv = argv[argv.index("--") + 1:] # get all args after "--" | |
| D = bpy.data | |
| C = bpy.context | |
| def copy_armature_animation( | |
| source_armature_name, | |
| destination_armature_name, | |
| start_frame_source, | |
| end_frame_source, | |
| start_frame_target, | |
| ): | |
| # Get the source and destination armature objects | |
| source_armature = bpy.data.objects[source_armature_name] | |
| destination_armature = bpy.data.objects[destination_armature_name] | |
| # Copy the animation data from the source armature to the destination armature | |
| #print(f"copying animation {start_frame_source}-{end_frame_source} to {start_frame_target} ") | |
| for i, frame in enumerate(range(start_frame_source, end_frame_source + 1)): | |
| bpy.context.scene.frame_set(frame) | |
| # Set the location and rotation of the destination bone at the given frame | |
| for bone in source_armature.pose.bones: | |
| destination_bone = destination_armature.pose.bones.get(bone.name) | |
| destination_bone.location = bone.location | |
| destination_bone.rotation_quaternion = bone.rotation_quaternion | |
| destination_bone.keyframe_insert( | |
| data_path="location", frame=start_frame_target + i | |
| ) | |
| destination_bone.keyframe_insert( | |
| data_path="rotation_quaternion", frame=start_frame_target + i | |
| ) | |
| # Copy the bone's animation data for each frame in the range | |
| def adjust_armature_animation_timing( | |
| armature_name, old_start, old_end, new_start, new_end | |
| ): | |
| # Get the armature object by name | |
| armature = bpy.data.objects[armature_name] | |
| # Calculate the ratio between the old and new keyframe ranges | |
| old_range = old_end - old_start | |
| new_range = new_end - new_start | |
| ratio = new_range / old_range | |
| #print(f"Adjsuting timming from {old_start}-{old_end} to {new_start}-{new_end} with ratio: {ratio}") | |
| # Iterate through all the armature bones and modify their animation keyframes | |
| for fcurve in armature.animation_data.action.fcurves: | |
| if fcurve.array_index < 4: | |
| for keyframe in fcurve.keyframe_points: | |
| # Adjust the keyframe position based on the ratio | |
| if keyframe.co.x in range (old_start, old_end): | |
| #print(f"keyframe move from {keyframe.co.x}") | |
| keyframe.co.x = (keyframe.co.x - old_start) * ratio + new_start | |
| #print(f"to {keyframe.co.x}") | |
| else: | |
| continue | |
| def calculate_new_frame_range(frame_rate, timestamp, start_frame): | |
| adjusted_end_frame = int(timestamp / 1000 * frame_rate + start_frame) | |
| return adjusted_end_frame | |
| def change_material_property( | |
| material_name, node_name, new_value, start_frame, end_frame | |
| ): | |
| value = bpy.data.materials[material_name].node_tree.nodes[node_name].outputs[0] | |
| value.default_value = new_value | |
| value.keyframe_insert(data_path="default_value", frame=start_frame+1) | |
| value.keyframe_insert(data_path="default_value", frame=end_frame-1) | |
| def set_cues_state( | |
| global_state, | |
| global_color, | |
| c1_state, | |
| c1_color, | |
| c2_state, | |
| c2_color, | |
| c3_state, | |
| c3_color, | |
| c4_state, | |
| c4_color, | |
| start_frame, | |
| end_frame, | |
| ): | |
| # cue 1 noise | |
| change_material_property( | |
| "CUE_MAT_1", "Distortion", float(c1_state), start_frame, end_frame | |
| ) | |
| # cue 2 noise | |
| change_material_property( | |
| "CUE_MAT_2", "Distortion", float(c2_state), start_frame, end_frame | |
| ) | |
| # cue 3 noise | |
| change_material_property( | |
| "CUE_MAT_3", "Distortion", float(c3_state), start_frame, end_frame | |
| ) | |
| # cue 4 noise | |
| change_material_property( | |
| "CUE_MAT_4", "Distortion", float(c4_state), start_frame, end_frame | |
| ) | |
| # cue 1 color | |
| change_material_property( | |
| "CUE_MAT_1", "Color", float(c1_color), start_frame, end_frame | |
| ) | |
| # cue 2 color | |
| change_material_property( | |
| "CUE_MAT_2", "Color", float(c2_color), start_frame, end_frame | |
| ) | |
| # cue 3 color | |
| change_material_property( | |
| "CUE_MAT_3", "Color", float(c3_color), start_frame, end_frame | |
| ) | |
| # cue 4 color | |
| change_material_property( | |
| "CUE_MAT_4", "Color", float(c4_color), start_frame, end_frame | |
| ) | |
| # global cue on | |
| change_material_property( | |
| "GLOBAL_CUE_MAT", "MixFactor", float(global_state), start_frame, end_frame | |
| ) | |
| # global cue color | |
| change_material_property( | |
| "GLOBAL_CUE_MAT", "Color", float(global_color), start_frame, end_frame | |
| ) | |
| def animate_cycle(source_armature, target_armature, csv_file): | |
| # Get the current scene | |
| scene = bpy.context.scene | |
| # Get the frame rate of the current scene | |
| frame_rate = scene.render.fps / scene.render.fps_base | |
| gait_to_keyframe_start = {0: 10, 1: 80, 2: 60, 3: 250} | |
| gait_to_keyframe_end = {0: 49, 1: 99, 2: 74, 3: 310} | |
| # column_names = ["Gait", "TS", "State", "Condition", "Shape1", "Shape2", "Shape3", "Shape4", "Color1", "Color2", "Color3", "Color4", "Danger1", "Danger2", "Danger3", "Danger4"] | |
| previous_end_frame = 0 | |
| with open(csv_file, "r") as csvfile: | |
| datareader = csv.reader(csvfile) | |
| for i, row in enumerate(datareader): | |
| if i == 0 or row[0] is None: | |
| continue | |
| copy_armature_animation( | |
| source_armature, | |
| target_armature, | |
| gait_to_keyframe_start[int(row[0])], | |
| gait_to_keyframe_end[int(row[0])], | |
| previous_end_frame + 1, | |
| ) | |
| adjusted_end_frame = calculate_new_frame_range( | |
| frame_rate=frame_rate, | |
| timestamp=int(float(row[1])), | |
| start_frame=previous_end_frame + 1, | |
| ) | |
| adjust_armature_animation_timing( | |
| target_armature, | |
| previous_end_frame + 1, | |
| previous_end_frame + 1 + gait_to_keyframe_end[int(row[0])] - gait_to_keyframe_start[int(row[0])], | |
| previous_end_frame + 1, | |
| adjusted_end_frame, | |
| ) | |
| set_cues_state( | |
| row[3], | |
| row[4], | |
| row[8], | |
| row[5], | |
| row[9], | |
| row[6], | |
| row[10], | |
| row[7], | |
| row[11], | |
| row[2], | |
| previous_end_frame, | |
| adjusted_end_frame, | |
| ) | |
| #print(previous_end_frame, adjusted_end_frame) | |
| previous_end_frame = adjusted_end_frame | |
| print(f"Animated row {i}") | |
| bpy.context.scene.frame_end = previous_end_frame | |
| bpy.ops.render.render(animation=True) | |
| print("Cycle_device:") | |
| print(bpy.context.preferences.addons["cycles"].preferences.has_active_device()) | |
| animate_cycle("Deformation", "Deformation.001", str(argv[0])) | |