Skip to content
Snippets Groups Projects
Commit c75f2718 authored by Romain Guesdon's avatar Romain Guesdon
Browse files

Add hand targets

parent c6602c0f
No related branches found
No related tags found
No related merge requests found
...@@ -27,7 +27,7 @@ importlib.reload(utils) ...@@ -27,7 +27,7 @@ importlib.reload(utils)
importlib.reload(camera_proj) importlib.reload(camera_proj)
importlib.reload(human) importlib.reload(human)
from scripts.human import Human, HumanLoader, set_shrinkwraps from scripts.human import HumanLoader
def abs_path(rel_path): def abs_path(rel_path):
...@@ -39,6 +39,8 @@ random.seed() ...@@ -39,6 +39,8 @@ random.seed()
C = bpy.context C = bpy.context
D = bpy.data D = bpy.data
CONTINUE = False
# Clean scene # Clean scene
try: try:
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
...@@ -71,11 +73,11 @@ cars = [] ...@@ -71,11 +73,11 @@ cars = []
for src_path, name in { for src_path, name in {
r"car_models\suv_car\car.blend": 'SUV', r"car_models\suv_car\car.blend": 'SUV',
r"car_models\red_car\red.blend": 'Red', # r"car_models\red_car\red.blend": 'Red',
r"car_models\pickup_car\pickup.blend": 'PickUp', # r"car_models\pickup_car\pickup.blend": 'PickUp',
r"car_models\family_car\family_car.blend": 'Family', # r"car_models\family_car\family_car.blend": 'Family',
r"car_models\coupe_car\coupe_car.blend": 'Coupe', # r"car_models\coupe_car\coupe_car.blend": 'Coupe',
r"car_models\truck\truck_open.blend": 'Truck', # r"car_models\truck\truck_open.blend": 'Truck',
}.items(): }.items():
with D.libraries.load(abs_path(src_path)) as (data_from, data_to): with D.libraries.load(abs_path(src_path)) as (data_from, data_to):
...@@ -98,7 +100,6 @@ C.scene.render.engine = 'BLENDER_EEVEE' ...@@ -98,7 +100,6 @@ C.scene.render.engine = 'BLENDER_EEVEE'
camera_data = D.cameras.new(name='Camera') camera_data = D.cameras.new(name='Camera')
camera_data.type = 'PERSP' camera_data.type = 'PERSP'
camera_data.lens_unit = 'FOV' camera_data.lens_unit = 'FOV'
# camera_data.angle = utils.r(68)
camera_data.angle = utils.r(68) camera_data.angle = utils.r(68)
C.scene.render.resolution_x = 640 C.scene.render.resolution_x = 640
...@@ -107,8 +108,6 @@ C.scene.render.resolution_y = 480 ...@@ -107,8 +108,6 @@ C.scene.render.resolution_y = 480
camera_object = D.objects.new('Camera', camera_data) camera_object = D.objects.new('Camera', camera_data)
C.scene.collection.objects.link(camera_object) C.scene.collection.objects.link(camera_object)
# camera_object.location = [-1.1, -0.21, 0.54]
# camera_object.rotation_euler = utils.r([76, 12, -76])
camera_object.location = [-.97, -0.11, 0.68] camera_object.location = [-.97, -0.11, 0.68]
camera_object.rotation_euler = utils.r([72, 8, -82]) camera_object.rotation_euler = utils.r([72, 8, -82])
...@@ -141,8 +140,6 @@ image_holder.location = (4, 1.5, 1.3) ...@@ -141,8 +140,6 @@ image_holder.location = (4, 1.5, 1.3)
image_holder.rotation_euler.z = utils.r(-100) image_holder.rotation_euler.z = utils.r(-100)
image_holder.active_material.shadow_method = 'NONE' image_holder.active_material.shadow_method = 'NONE'
# C.scene.node_tree.nodes["Rotate"].inputs[1].default_value = camera_object.rotation_euler[1] - utils.r(5)
# add light # add light
sun_collection = D.collections.new("Sun") sun_collection = D.collections.new("Sun")
C.scene.collection.children.link(sun_collection) C.scene.collection.children.link(sun_collection)
...@@ -180,29 +177,39 @@ C.scene.sun_pos_properties.year = 2022 ...@@ -180,29 +177,39 @@ C.scene.sun_pos_properties.year = 2022
C.scene.sun_pos_properties.day_of_year = 182 C.scene.sun_pos_properties.day_of_year = 182
fp = abs_path(r"output") fp = abs_path(r"output")
if os.path.isdir(fp):
shutil.rmtree(fp)
os.mkdir(fp)
fp_img = os.path.join(fp, 'images') fp_img = os.path.join(fp, 'images')
fp_ann_2D = os.path.join(fp, 'annots_2D') fp_ann_2D = os.path.join(fp, 'annots_2D')
fp_ann_3D = os.path.join(fp, 'annots_3D') fp_ann_3D = os.path.join(fp, 'annots_3D')
os.mkdir(fp_img)
os.mkdir(fp_ann_2D) info_path = os.path.join(fp, 'infos.json')
os.mkdir(fp_ann_3D) scenes_ids = OrderedDict()
if not CONTINUE or not os.path.isfile(info_path):
if os.path.isdir(fp):
shutil.rmtree(fp)
os.mkdir(fp)
os.mkdir(fp_img)
os.mkdir(fp_ann_2D)
os.mkdir(fp_ann_3D)
frame_rate = 25 frame_rate = 25
nb_scene = 2 nb_scene = 1
nb_pose = 1 nb_pose = 10
human_loader.max_len = min(human_loader.max_len, nb_scene) human_loader.max_len = min(human_loader.max_len, nb_scene)
ratio_conf_man = int(nb_scene / len(human_loader.human_paths)) ratio_conf_man = int(nb_scene / len(human_loader.human_paths))
if CONTINUE:
with open(info_path) as f_info:
scene_ids = json.load(f_info, object_pairs_hook=OrderedDict)['id_max_scenes']
scenes_ids = OrderedDict() human_loader.human_paths = [hp for hp in human_loader.human_paths if hp not in scene_ids]
man = None
for sc in range(nb_scene): for sc in range(nb_scene):
## Random car # Random car
car = car_picker() car = car_picker()
## Random personne car_targets = {side: [ch for ch in car.children if f'Target_{side.upper()}' in ch.name] for side in 'lr'}
nb_targets = sum([len(v) for v in car_targets.values()])
# Random personne
if ratio_conf_man < 1: if ratio_conf_man < 1:
if not sc % 10: if not sc % 10:
human_loader.load_next() human_loader.load_next()
...@@ -217,7 +224,7 @@ for sc in range(nb_scene): ...@@ -217,7 +224,7 @@ for sc in range(nb_scene):
scenes_ids.setdefault(human_path, -1) scenes_ids.setdefault(human_path, -1)
scenes_ids[human_path] += 1 scenes_ids[human_path] += 1
## Random time # Random time
C.scene.sun_pos_properties.north_offset = utils.r(random.randint(-179, 180)) C.scene.sun_pos_properties.north_offset = utils.r(random.randint(-179, 180))
time_day = random.randint(0, 23) time_day = random.randint(0, 23)
if 6 <= time_day <= 21: if 6 <= time_day <= 21:
...@@ -234,16 +241,16 @@ for sc in range(nb_scene): ...@@ -234,16 +241,16 @@ for sc in range(nb_scene):
bpy.data.worlds["World"].node_tree.nodes["Background.001"].inputs[0].default_value = \ bpy.data.worlds["World"].node_tree.nodes["Background.001"].inputs[0].default_value = \
(back_val, back_val, back_val, 1) (back_val, back_val, back_val, 1)
## Random background # Random background
back_img = random.choice(back_imgs[day_night]) back_img = random.choice(back_imgs[day_night])
# C.scene.node_tree.nodes["Image"].image = D.images[back_img]
image_holder.active_material.node_tree.nodes['Image Texture'].image = D.images[back_img] image_holder.active_material.node_tree.nodes['Image Texture'].image = D.images[back_img]
image_holder.location.y = 1.5 + random.uniform(-0.3, 0.3)
# Camera movement # Camera movement
camera_object.rotation_euler = utils.r([72 + random.randint(-2, 2), 8, -82]) camera_object.rotation_euler = utils.r([72 + random.randint(-2, 2), 8, -82])
C.scene.render.filepath = fp C.scene.render.filepath = fp
C.scene.render.image_settings.file_format = 'PNG' # set output format to .png C.scene.render.image_settings.file_format = 'PNG'
C.scene.camera = camera_object C.scene.camera = camera_object
P, K, RT = camera_proj.get_3x4_P_matrix_from_blender(camera_object) P, K, RT = camera_proj.get_3x4_P_matrix_from_blender(camera_object)
...@@ -265,8 +272,7 @@ for sc in range(nb_scene): ...@@ -265,8 +272,7 @@ for sc in range(nb_scene):
man.animation_data_clear() man.animation_data_clear()
## Pour chaque paire, on veut NbTotalFrames / NbPersonnes / NbCar poses # Exemple: 150k / 200 / 2 = 1500 poses
## Exemple: 150k / 200 / 2 = 1500 pose
with open(os.path.join(fp_ann_2D, f'annotations_{file_root_name}.csv'), 'w') as annot_file_2D, \ with open(os.path.join(fp_ann_2D, f'annotations_{file_root_name}.csv'), 'w') as annot_file_2D, \
open(os.path.join(fp_ann_3D, f'annotations_{file_root_name}.csv'), 'w') as annot_file_3D: open(os.path.join(fp_ann_3D, f'annotations_{file_root_name}.csv'), 'w') as annot_file_3D:
bone_lbls = list(man.pose.bones.keys()) bone_lbls = list(man.pose.bones.keys())
...@@ -276,10 +282,11 @@ for sc in range(nb_scene): ...@@ -276,10 +282,11 @@ for sc in range(nb_scene):
for po in range(nb_pose): for po in range(nb_pose):
C.scene.frame_set(po * frame_rate) C.scene.frame_set(po * frame_rate)
### On random une pose à chaque fois use_targets = nb_pose - po <= (nb_targets // 2) ** 2
random_pose.random_pose_ik(man) # use_targets = False
human.switch_constraints(man, enable=not use_targets)
random_pose.random_pose_ik(man, targets=car_targets if use_targets else None)
### On crée une frame
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
man.keyframe_insert(data_path="location", index=-1) man.keyframe_insert(data_path="location", index=-1)
...@@ -294,12 +301,8 @@ for sc in range(nb_scene): ...@@ -294,12 +301,8 @@ for sc in range(nb_scene):
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
### Random caméra et lumières (Blender proc)
### On génère les images au bon FPS
### On sauvegarde les poses 3D + paramètres caméra (extra et intra)
# set output path so render won't get overwritten # set output path so render won't get overwritten
C.scene.render.filepath = os.path.join(fp_img, f"{file_root_name}_{po}") C.scene.render.filepath = os.path.join(fp_img, f"{file_root_name}_{po}" + f'_drive' if use_targets else '')
bpy.ops.render.render(write_still=True) # render still bpy.ops.render.render(write_still=True) # render still
annotations_2D = [] annotations_2D = []
...@@ -318,7 +321,7 @@ C.scene.frame_end = int(frame_rate * (nb_pose - 0.5)) ...@@ -318,7 +321,7 @@ C.scene.frame_end = int(frame_rate * (nb_pose - 0.5))
utils.select_only(man) utils.select_only(man)
bpy.ops.object.mode_set(mode='POSE') bpy.ops.object.mode_set(mode='POSE')
with open(os.path.join(fp, 'infos.json'), 'w') as f: with open(info_path, 'w') as f:
json.dump({ json.dump({
'models': list(scenes_ids), 'models': list(scenes_ids),
'id_max_scenes': scenes_ids 'id_max_scenes': scenes_ids
......
...@@ -9,7 +9,7 @@ from mathutils import Vector ...@@ -9,7 +9,7 @@ from mathutils import Vector
# --------------------------------------------------------------- # ---------------------------------------------------------------
# Build intrinsic camera parameters from Blender camera data # Build intrinsic camera parameters from Blender camera data
# # From https://blender.stackexchange.com/a/38210/153600
# See notes on this in # See notes on this in
# blender.stackexchange.com/questions/15102/what-is-blenders-camera-projection-matrix-model # blender.stackexchange.com/questions/15102/what-is-blenders-camera-projection-matrix-model
def get_calibration_matrix_K_from_blender(camd): def get_calibration_matrix_K_from_blender(camd):
......
...@@ -17,7 +17,6 @@ from scripts.utils import * ...@@ -17,7 +17,6 @@ from scripts.utils import *
D = bpy.data D = bpy.data
# Load clothes list # Load clothes list
with open(r"mh_models\mh_mass_produce.json") as f: with open(r"mh_models\mh_mass_produce.json") as f:
data = json.load(f) data = json.load(f)
...@@ -97,7 +96,8 @@ class Human: ...@@ -97,7 +96,8 @@ class Human:
bpy.ops.object.mode_set(mode='POSE') bpy.ops.object.mode_set(mode='POSE')
ik_constraints = { ik_constraints = {
'upperarm': [(-45, 120), (-90, 90), (-80, 80)], 'upperarm': [(-45, 120), (-90, 90), (-80, 80)],
'lowerarm': [(-30, 120), None, None] 'lowerarm': [(-30, 120), None, None],
'clavicle': [None, None, None]
} }
for s in ('l', 'r'): for s in ('l', 'r'):
lowerarm = self.model.pose.bones[f'lowerarm_{s}'] lowerarm = self.model.pose.bones[f'lowerarm_{s}']
...@@ -106,6 +106,12 @@ class Human: ...@@ -106,6 +106,12 @@ class Human:
lowerarm.constraints['IK'].subtarget = f'hand_{s}_IK' lowerarm.constraints['IK'].subtarget = f'hand_{s}_IK'
lowerarm.constraints['IK'].chain_count = 2 lowerarm.constraints['IK'].chain_count = 2
hand = self.model.pose.bones[f'hand_{s}']
hand.constraints.new("COPY_ROTATION")
hand.constraints['Copy Rotation'].target = self.model
hand.constraints['Copy Rotation'].enabled = False
hand.constraints['Copy Rotation'].subtarget = f'hand_{s}_IK'
for name, consts in ik_constraints.items(): for name, consts in ik_constraints.items():
bone = self.model.pose.bones[f'{name}_{s}'] bone = self.model.pose.bones[f'{name}_{s}']
for axe, const in zip(('x', 'y', 'z'), consts): for axe, const in zip(('x', 'y', 'z'), consts):
...@@ -120,6 +126,9 @@ class Human: ...@@ -120,6 +126,9 @@ class Human:
# self.model.pose.bones[f'hand_{s}_IK'].location = Vector((-15, 10, 0)) # self.model.pose.bones[f'hand_{s}_IK'].location = Vector((-15, 10, 0))
self.model.pose.bones[f'hand_{s}_IK'].location = Vector((0, 5, -10)) self.model.pose.bones[f'hand_{s}_IK'].location = Vector((0, 5, -10))
for i in '123':
self.model.pose.bones[f'spine_0{i}'].lock_ik_z = True
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
def init_textures(self): def init_textures(self):
...@@ -155,6 +164,15 @@ class Human: ...@@ -155,6 +164,15 @@ class Human:
return self.model return self.model
def switch_constraints(model, enable=False):
for s in 'lr':
hand_ik = model.pose.bones[f'hand_{s}_IK']
for constr in hand_ik.constraints:
constr.enabled = enable
model.pose.bones[f'hand_{s}'].constraints['Copy Rotation'].enabled = not enable
model.pose.bones[f'lowerarm_{s}'].constraints['IK'].chain_count = 2
def set_bounds(model, car=None): def set_bounds(model, car=None):
# set_floors(model, car) # set_floors(model, car)
set_shrinkwraps(model, car) set_shrinkwraps(model, car)
...@@ -165,6 +183,7 @@ def set_floors(model, car=None): ...@@ -165,6 +183,7 @@ def set_floors(model, car=None):
utils.select_only(model) utils.select_only(model)
bpy.ops.object.mode_set(mode='POSE') bpy.ops.object.mode_set(mode='POSE')
planes = None
if car is not None: if car is not None:
planes = [ch for ch in car.children_recursive if ch.name[:5] == 'Plane'] planes = [ch for ch in car.children_recursive if ch.name[:5] == 'Plane']
...@@ -188,8 +207,9 @@ def set_shrinkwraps(model, car=None): ...@@ -188,8 +207,9 @@ def set_shrinkwraps(model, car=None):
utils.select_only(model) utils.select_only(model)
bpy.ops.object.mode_set(mode='POSE') bpy.ops.object.mode_set(mode='POSE')
out_objects = None
if car is not None: if car is not None:
out_objects = [ch for ch in car.children_recursive if ch.name[:4] == 'OUT_'] out_objects = [ch for ch in car.children_recursive if (ch.name[:4] == 'OUT_' or ch.name[:3] == 'IN_')]
for s in 'lr': for s in 'lr':
bone = model.pose.bones[f'hand_{s}_IK'] bone = model.pose.bones[f'hand_{s}_IK']
...@@ -199,7 +219,7 @@ def set_shrinkwraps(model, car=None): ...@@ -199,7 +219,7 @@ def set_shrinkwraps(model, car=None):
for obj in out_objects: for obj in out_objects:
constr = bone.constraints.new('SHRINKWRAP') constr = bone.constraints.new('SHRINKWRAP')
constr.target = obj constr.target = obj
constr.wrap_mode = 'OUTSIDE' constr.wrap_mode = 'OUTSIDE' if obj.name[:4] == 'OUT_' else 'INSIDE'
if 'Back' in obj.name: if 'Back' in obj.name:
constr.distance = model.pose.bones['lowerarm_l'].length * model.scale.x / obj.scale.y * 1 constr.distance = model.pose.bones['lowerarm_l'].length * model.scale.x / obj.scale.y * 1
if 'Side' in obj.name: if 'Side' in obj.name:
......
...@@ -88,17 +88,25 @@ def reset_subject(subject): ...@@ -88,17 +88,25 @@ def reset_subject(subject):
subject.rotation_euler = r([65, 0, 0]) subject.rotation_euler = r([65, 0, 0])
def hand_pose(pose): def hand_pose(pose, side, grasp=None):
for s in ['l', 'r']: if grasp is None:
hand_ratio = random.uniform(0.1, 0.8) hand_ratio = random.uniform(0.1, 0.8)
for finger in ['thumb', 'index', 'middle', 'ring', 'pinky']: elif grasp is True:
angles = r([40, 40, 40]) if finger == 'thumb' else r([70, 90, 40]) hand_ratio = random.uniform(0.5, 0.8)
solo_ratio = random.uniform(0.7, 1) * hand_ratio elif grasp is False:
for i in range(3): hand_ratio = random.uniform(0.05, 0.15)
pose.bones[f'{finger}_{i + 1:02}_{s}'].rotation_euler.x = angles[i] * solo_ratio
print(grasp)
print(hand_ratio)
for finger in ['thumb', 'index', 'middle', 'ring', 'pinky']:
angles = r([40, 40, 40]) if finger == 'thumb' else r([70, 90, 40])
solo_ratio = random.uniform(0.7, 1) * hand_ratio
for i in range(3):
pose.bones[f'{finger}_{i + 1:02}_{side}'].rotation_euler.x = angles[i] * solo_ratio
def random_pose_ik(subject, auto_ik=False):
def random_pose_ik(subject, auto_ik=False, targets=None):
""" """
1- reset and fix legs 1- reset and fix legs
2- randomize back 2- randomize back
...@@ -106,6 +114,8 @@ def random_pose_ik(subject, auto_ik=False): ...@@ -106,6 +114,8 @@ def random_pose_ik(subject, auto_ik=False):
3- randomize neck (backward proportional to back bending) 3- randomize neck (backward proportional to back bending)
4- move arms with IK 4- move arms with IK
:param subject: subject Object :param subject: subject Object
:param auto_ik: use auto_ik option
:param targets: choose among fixed wrist targets
:return: :return:
""" """
# 1 # 1
...@@ -128,27 +138,30 @@ def random_pose_ik(subject, auto_ik=False): ...@@ -128,27 +138,30 @@ def random_pose_ik(subject, auto_ik=False):
for bone, angles in base_rots.items(): for bone, angles in base_rots.items():
pose.bones[bone].rotation_euler = angles pose.bones[bone].rotation_euler = angles
# 2 if targets is None:
pose.bones['spine_03'].rotation_euler = get_angles(bounds_vals['spine_03']) # 2
pose.bones['spine_03'].rotation_euler = get_angles(bounds_vals['spine_03'])
# 2b Compensate for shoulder in seat by bending back to front # 2b Compensate for shoulder in seat by bending back to front
pose.bones['spine_01'].rotation_euler = r( pose.bones['spine_01'].rotation_euler = r(
Vector((random.randint(0, 10) + max(d(abs(rota('spine_03').y)) - 20, 0) / 2, 0, Vector((random.randint(0, 10) + max(d(abs(rota('spine_03').y)) - 20, 0) / 2, 0,
0))) + rota('spine_01') 0))) + rota('spine_01')
# 3 # 3
pose.bones['neck_01'].rotation_euler = ( pose.bones['neck_01'].rotation_euler = (
get_angles(bounds_vals['neck_01']) + get_angles(bounds_vals['neck_01']) +
get_angles( get_angles(
[[d((rota('spine_01').x + rota('spine_03').x) * -0.5), 0], None, None]) + [[d((rota('spine_01').x + rota('spine_03').x) * -0.5), 0], None, None]) +
Vector((0, random.uniform(0, 0.5) * rota('spine_03').y, 0)) Vector((0, random.uniform(0, 0.5) * rota('spine_03').y, 0))
) )
hand_pose(pose) else:
pose.bones['spine_03'].rotation_euler = get_angles([[5, 20], 15, None])
pose.bones['neck_01'].rotation_euler = get_angles(bounds_vals['neck_01'])
pose.use_auto_ik = auto_ik pose.use_auto_ik = auto_ik
targets = { targets_test = {
'l': Vector((0.3, -0.1, 0.4)), 'l': Vector((0.3, -0.1, 0.4)),
'r': Vector((-0.4, -0.1, 0.2)) 'r': Vector((-0.4, -0.1, 0.2))
} }
...@@ -166,124 +179,11 @@ def random_pose_ik(subject, auto_ik=False): ...@@ -166,124 +179,11 @@ def random_pose_ik(subject, auto_ik=False):
bone = pose_bone.bone bone = pose_bone.bone
select_only_bone(armature, bone) select_only_bone(armature, bone)
target = Vector() if targets is None:
min_arm_factor = 0.2 target = Vector()
if False:
# target.x = random.random() * (0.4 if s == 'l' else -0.7)
target.x = random.uniform(max(-0.5, back_rota_fact * 0.4 + 0.4 if s == 'l' else 0),
min(0.4, back_rota_fact * 0.4 + 0 if s == 'l' else -0.4))
target.z = random.uniform(0.05, 0.7)
if abs(target.x) < 0.2:
target.y = random.uniform(-0.04, 0.02)
else:
target.y = random.uniform(-0.24, 0.02)
# sloap
target.y -= random.random() * (target.z * 0.1)
elif False:
phi = random.uniform(r(-180 + 45), 0) - (r(45) if s == 'r' else 0) + rota('spine_03').y
costheta = random.uniform(-1, 1)
u = random.uniform(0.1, 1)
theta = acos(costheta)
# u = arm_length * (u ** 1 / 3)
target.x = u * sin(theta) * cos(phi)
target.y = u * sin(theta) * sin(phi)
target.z = u * cos(theta)
shoulder_pose = get_head_pose(f'upperarm_{s}', subject)
target *= arm_length
target += shoulder_pose
# target.x = max(min(target.x, 0.32), -0.55)
# target.y = max(min(target.y, 0.02), -0.04 if abs(target.x) < 0.2 else -0.24)
# target.z = max(min(target.z, 0.7), 0.15)
bounded_width = Vector(((0.32 if s == 'l' else 0.55) + 0.35,
2 * arm_length,
0.7 - 0.15))
target = (
(target - shoulder_pose) *
(bounded_width / (2 * arm_length)) +
shoulder_pose + 0.5 * (bounded_width - Vector([2 * arm_length, ] * 3))
)
# y done afterward because of the wheel
bounded_width_y = 0.02 - (- 0.04 if abs(target.x) < 0.2 else -0.24)
target.y = (
(target.y - shoulder_pose.y) *
(bounded_width_y / (0.9 * arm_length)) +
shoulder_pose.y + 0.5 * (bounded_width_y - 0.9 * arm_length)
)
elif False:
phi = random.uniform(
r(-180) + rota('spine_03').y if s == 'r' else r(-120) + rota('spine_03').y,
r(-60) + rota('spine_03').y if s == 'r' else r(-60) + rota('spine_03').y
)
costheta = random.uniform(max(-0.8, 0.2 - cos(rota('spine_03').x + rota('spine_01').x)),
min(0.8, -0.2 + cos(rota('spine_03').x - rota('spine_01').x)))
theta = acos(costheta)
bounds_u = []
shoulder_pose = get_head_pose(f'upperarm_{s}', subject) shoulder_pose = get_head_pose(f'upperarm_{s}', subject)
if not sin(theta) * cos(phi): min_arm_factor = 0.2
min_u_x = 0
max_u_x = arm_length
else:
bounds_u_x = (
(-0.55 - shoulder_pose.x) / (sin(theta) * cos(phi)),
(0.32 - shoulder_pose.x) / (sin(theta) * cos(phi))
)
min_u_x = (-0.55 - shoulder_pose.x) / (sin(theta) * cos(phi))
max_u_x = (0.32 - shoulder_pose.x) / (sin(theta) * cos(phi))
bounds_u += [min_u_x, max_u_x]
if not cos(theta):
min_u_z = 0
max_u_z = arm_length
else:
bounds_u_z = (
(0.15 - shoulder_pose.z) / cos(theta),
(0.7 - shoulder_pose.z) / cos(theta)
)
min_u_z = (0.15 - shoulder_pose.z) / cos(theta)
max_u_z = (0.7 - shoulder_pose.z) / cos(theta)
bounds_u += [min_u_z, max_u_z]
max_u_xz = min([m for m in bounds_u + [arm_length] if m > min_arm_factor * arm_length])
max_x = max_u_xz * sin(theta) * cos(phi) + shoulder_pose.x
if not sin(theta) * sin(phi):
min_u_y = 0
max_u_y = arm_length
else:
bounds_u_y = (
((-0.04 if abs(max_x) < 0.2 else -0.24) - shoulder_pose.y) / (sin(theta) * sin(phi)),
(0.02 - shoulder_pose.y) / (sin(theta) * sin(phi))
)
min_u_y = ((-0.04 if abs(max_x) < 0.2 else -0.24) - shoulder_pose.y) / (sin(theta) * sin(phi))
max_u_y = (0.02 - shoulder_pose.y) / (sin(theta) * sin(phi))
bounds_u += [min_u_y, max_u_y]
max_u = min([m for m in bounds_u + [arm_length] if m > min_arm_factor * arm_length])
# print(d(phi), d(theta))
# print(min_u_x, min_u_y, min_u_z)
# print(max_u_x, max_u_y, max_u_z, max_u / arm_length)
# u = random.uniform((min_arm_factor) ** 1/2, (max_u / arm_length) ** 1/2) ** 2 * arm_length
u = random.uniform(min_arm_factor * arm_length, max_u)
# print(u / arm_length)
target.x = u * sin(theta) * cos(phi)
target.y = u * sin(theta) * sin(phi)
target.z = u * cos(theta)
target += shoulder_pose
else:
back_forward_angle = rota('spine_03').x + rota('spine_01').x - r(30) # 0 = straight back_forward_angle = rota('spine_03').x + rota('spine_01').x - r(30) # 0 = straight
phi = random.uniform( phi = random.uniform(
...@@ -295,10 +195,7 @@ def random_pose_ik(subject, auto_ik=False): ...@@ -295,10 +195,7 @@ def random_pose_ik(subject, auto_ik=False):
min(0.8, cos(theta_bound + back_forward_angle + rota('neck_01').x))) min(0.8, cos(theta_bound + back_forward_angle + rota('neck_01').x)))
theta = acos(costheta) theta = acos(costheta)
bounds_u = []
shoulder_pose = get_head_pose(f'upperarm_{s}', subject)
# u = random.uniform((min_arm_factor) ** 1/2, (max_u / arm_length) ** 1/2) ** 2 * arm_length
min_arm_factor = 0.2 + max(sin(back_forward_angle), 0) min_arm_factor = 0.2 + max(sin(back_forward_angle), 0)
# print(min_arm_factor, d(phi), d(theta)) # print(min_arm_factor, d(phi), d(theta))
u = random.uniform(min_arm_factor, 1) * arm_length u = random.uniform(min_arm_factor, 1) * arm_length
...@@ -309,14 +206,29 @@ def random_pose_ik(subject, auto_ik=False): ...@@ -309,14 +206,29 @@ def random_pose_ik(subject, auto_ik=False):
target += shoulder_pose target += shoulder_pose
temp_rota = rota(f'upperarm_{s}') + rota(f'lowerarm_{s}') hand_pose(pose, side=s)
# target = targets[s]
temp_rota = rota(f'upperarm_{s}') + rota(f'lowerarm_{s}')
# target = targets_test[s]
else:
target = random.choice(targets[s])
pose.bones[f'hand_{s}_IK'].rotation_euler = Vector((0, 0, 0))
pose.bones[f'hand_{s}_IK'].rotation_euler = (
((matrix_world @ pose.bones[f'hand_{s}_IK'].matrix).inverted() @ target.matrix_world).to_euler())
print("_close" in target.name)
hand_pose(pose, side=s, grasp="_close" in target.name)
target = target.location
location = get_head_pose(bone.name, subject) location = get_head_pose(bone.name, subject)
# print(location) # print(location)
# print(target) # print(target)
bpy.ops.transform.translate(value=target - location) bpy.ops.transform.translate(value=target - location)
if targets is not None:
for s in 'lr':
subject.pose.bones[f'lowerarm_{s}'].constraints['IK'].chain_count = 6
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
......
...@@ -43,7 +43,7 @@ def hide_object(obj, hide=True): ...@@ -43,7 +43,7 @@ def hide_object(obj, hide=True):
hide_object(o, hide=hide) hide_object(o, hide=hide)
obj.hide_set(hide) obj.hide_set(hide)
obj.hide_select = hide obj.hide_select = hide
if 'Plane' in obj.name or 'OUT_' in obj.name: if 'Plane' in obj.name or 'OUT_' in obj.name or 'IN_' in obj.name:
obj.hide_render = True obj.hide_render = True
obj.hide_set(True) obj.hide_set(True)
else: else:
...@@ -136,7 +136,7 @@ class Randomizer: ...@@ -136,7 +136,7 @@ class Randomizer:
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
pick_idx = random.randint(0, len(self) - 1) pick_idx = random.randint(0, len(self) - 1)
return self.get(pick_idx) return self.get(pick_idx, *args, **kwargs)
def swap_object(self, obj=None): def swap_object(self, obj=None):
for o in self: for o in self:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment