pookiefoof's picture
Update hf
ff0340e
raw
history blame
8.16 kB
import bpy, random
import os
import sys
import pdb
import math
from mathutils import Vector
def gc():
for i in range(10): bpy.ops.outliner.orphans_purge()
def clear():
[bpy.data.objects.remove(bpy.data.objects[x]) for x in list(bpy.data.objects.keys())]
gc()
def importVrm(importVrmPath):
old_objs = set(bpy.context.scene.objects)
result = bpy.ops.import_scene.vrm(filepath=importVrmPath)
return [x for x in set(bpy.context.scene.objects)-old_objs if x.type=="ARMATURE"][0]
def importFbx(importFbxPath):
old_objs = set(bpy.context.scene.objects)
result = bpy.ops.import_scene.fbx(filepath=importFbxPath)
return list(set(bpy.context.scene.objects)-old_objs)[0]
def get_keyframes(obj_list):
keyframes = []
for obj in obj_list:
anim = obj.animation_data
if anim is not None and anim.action is not None:
for fcu in anim.action.fcurves:
for keyframe in fcu.keyframe_points:
x, y = keyframe.co
if x not in keyframes:
keyframes.append(int(x))
return keyframes
def retarget(source_armature,target_armature):
bpy.context.view_layer.objects.active = source_armature
bpy.context.scene.source_rig=source_armature.name
bpy.context.scene.target_rig=target_armature.name
bpy.ops.arp.build_bones_list()
bpy.ops.arp.import_config(filepath=os.path.abspath("remap_mixamo.bmap"))
bpy.ops.arp.auto_scale()
keyframes=get_keyframes([source_armature])
bpy.ops.arp.retarget(frame_end=int(max(keyframes)))
def look_at(obj_camera, point):
direction = point - obj_camera.location
rot_quat = direction.to_track_quat('-Z', 'Y')
obj_camera.rotation_euler = rot_quat.to_euler()
def render_4_views(folder, origin = (0, 0, 0)):
bpy.context.scene.render.film_transparent = True
bpy.context.scene.render.resolution_x = 768
bpy.context.scene.render.resolution_y = 768
camera_positions = {
'front': (0, -2.5, 0.5),
'back': (0, 2.5, 0.5),
'left': (-2.5, 0, 0.5),
'right': (2.5, 0, 0.5),
}
camera_data = bpy.data.cameras.new(name='MyCamera')
camera_data.angle = math.radians(40)
camera_object = bpy.data.objects.new('MyCamera', camera_data)
bpy.context.collection.objects.link(camera_object)
bpy.context.scene.camera = camera_object
camera = bpy.data.objects['MyCamera']
for angle, position in camera_positions.items():
camera.location = Vector(position) + Vector(origin)
look_at(camera, Vector(origin))
bpy.context.scene.render.filepath = f'{folder}/{angle}.png'
bpy.ops.render.render(write_still=True)
def changeApose(armature):
bones = armature.pose.bones
if "J_Bip_L_UpperArm" in bones:
L_arm_name = "J_Bip_L_UpperArm"
R_arm_name = "J_Bip_R_UpperArm"
L_leg_name = "J_Bip_L_UpperLeg"
R_leg_name = "J_Bip_R_UpperLeg"
elif "θ…•δΈŠ_L.002" in bones:
L_arm_name = "θ…•δΈŠ_L.002"
R_arm_name = "θ…•δΈŠ_R.002"
L_leg_name = "ε€ͺγ‚‚γ‚‚_L.001"
R_leg_name = "ε€ͺγ‚‚γ‚‚_R.001"
elif "Left arm" in bones:
L_arm_name = "Left arm"
R_arm_name = "Right arm"
L_leg_name = "Left leg"
R_leg_name = "Right leg"
elif "upper_arm.L" in bones:
L_arm_name = "upper_arm.L"
R_arm_name = "upper_arm.R"
L_leg_name = "upper_leg.L"
R_leg_name = "upper_leg.R"
elif "LeftArm" in bones:
L_arm_name = "LeftArm"
R_arm_name = "RightArm"
L_leg_name = "LeftUpLeg"
R_leg_name = "RightUpLeg"
elif "Arm_L" in bones:
L_arm_name = "Arm_L"
R_arm_name = "Arm_R"
L_leg_name = "UpLeg_L"
R_leg_name = "UpLeg_R"
elif "mixamorig:LeftArm" in bones:
L_arm_name = "mixamorig:LeftArm"
R_arm_name = "mixamorig:RightArm"
L_leg_name = "mixamorig:LeftUpLeg"
R_leg_name = "mixamorig:RightUpLeg"
elif "UpperArm_L" in bones:
L_arm_name = "UpperArm_L"
R_arm_name = "UpperArm_R"
L_leg_name = "UpperLeg_L"
R_leg_name = "UpperLeg_R"
else:
import pdb; pdb.set_trace()
if L_arm_name in bones:
bones[L_arm_name].rotation_mode = "XYZ"
bones[L_arm_name].rotation_euler = (-math.pi / 4, 0.0, 0.0)
bones[L_arm_name].keyframe_insert(data_path="rotation_euler",frame=0)
if R_arm_name in bones:
bones[R_arm_name].rotation_mode = "XYZ"
bones[R_arm_name].rotation_euler = (-math.pi / 4, 0.0, 0.0)
bones[R_arm_name].keyframe_insert(data_path="rotation_euler",frame=0)
if L_leg_name in bones:
bones[L_leg_name].rotation_mode = "XYZ"
bones[L_leg_name].rotation_euler = (-math.pi / 30, 0.0, 0.0)
bones[L_leg_name].keyframe_insert(data_path="rotation_euler",frame=0)
if R_leg_name in bones:
bones[R_leg_name].rotation_mode = "XYZ"
bones[R_leg_name].rotation_euler = (-math.pi / 30, 0.0, 0.0)
bones[R_leg_name].keyframe_insert(data_path="rotation_euler",frame=0)
def move_origin_to_center(obj):
local_bbox_center = 0.125 * sum((Vector(b) for b in obj.bound_box), Vector())
scale_factor = max(obj.dimensions)
return local_bbox_center
#print(local_bbox_center)
#local_bbox_center = 0.125 * sum((Vector(b) for b in obj.bound_box), Vector())
#global_bbox_center = obj.matrix_world @ local_bbox_center
# for cur_obj in bpy.context.scene.objects:
# if cur_obj.type != "MESH":
# continue
# print(cur_obj.name, cur_obj.type)
# import pdb; pdb.set_trace()
# global_bbox_center = local_bbox_center @ cur_obj.matrix_world
# cur_obj.location -= global_bbox_center
#cur_obj.scale /= scale_factor
#obj.scale /= max(obj.dimensions)
# # bpy.ops.object.select_all(action='DESELECT')
# # cur_obj.select_set(True)
# # bpy.context.view_layer.objects.active = cur_obj
# # bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='BOUNDS')
def export(armature,exportFileNamePattern,apose=False,origin=None):
bpy.ops.object.select_all(action='DESELECT')
[x.select_set(True) for x in armature.children if(x.type=="MESH")]
if apose:
changeApose(armature)
os.makedirs(folder + "/apose",exist_ok=True)
bpy.ops.wm.obj_export(filepath=folder + "/apose.obj",export_animation=True,start_frame=0,end_frame=0,
export_selected_objects=True,export_materials=False,export_colors=False,export_uv=False,export_normals=False)
render_4_views(folder + "/apose", origin)
else:
keyframes = get_keyframes([armature])
#rand_frame = int(random.choice(keyframes))
os.makedirs(folder + "/pose",exist_ok=True)
bpy.ops.wm.obj_export(filepath=folder + "/pose.obj",export_animation=True,start_frame=0,end_frame=0,
export_selected_objects=True,export_materials=False,export_colors=False,export_uv=False,export_normals=False)
render_4_views(folder + "/pose", origin)
def exportAnimatedMesh(importVrmPath,importFbxPath,folder,apose):
clear()
human=importVrm(importVrmPath)
# resize human
if apose:
origin = move_origin_to_center(human)
export(human, folder, True, origin)
else:
anim = importFbx(importFbxPath)
retarget(anim, human)
origin = move_origin_to_center(human)
export(human, folder, False, origin)
#bpy.data.objects.remove(anim)
#gc()
#bpy.data.objects.remove(human)
#gc()
if(__name__=="__main__"):
argv = sys.argv
if("--" in argv):
argv = argv[argv.index("--") + 1:]
importVrmPath, importFbxPath, folder, apose=argv
else:
raise Exception("no args")
print("importVrmPath:", importVrmPath)
exportAnimatedMesh(importVrmPath, importFbxPath, folder, int(apose))