diff --git a/.gitignore b/.gitignore index 3ce84ab10886353e8c26818a740daca6da81279e..df6b5643c646a031e0184c2e181efcfe60e4fb5a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ car_models/* output/* output*/* + mh_models/* +!mh_models/blender.* backgrounds/* !default_green.png diff --git a/global_script.py b/global_script.py index ebed668b617a09f8d5c395685c889cbcc3d23546..b2950c4e9d915e4b8ff0e504a7f4af13a4e1d88e 100644 --- a/global_script.py +++ b/global_script.py @@ -106,8 +106,8 @@ def main(): camera_data.lens_unit = 'FOV' camera_data.angle = utils.r(68) - C.scene.render.resolution_x = 256 - C.scene.render.resolution_y = int(480 / 640 * 256) + C.scene.render.resolution_x = 320 + C.scene.render.resolution_y = int(0.75 * C.scene.render.resolution_x) camera_object = D.objects.new('Camera', camera_data) C.scene.collection.objects.link(camera_object) @@ -204,8 +204,8 @@ def main(): os.mkdir(fp_ann_3D) frame_rate = 25 - nb_scene = 1 - nb_pose = 1 + nb_scene = 25 + nb_pose = 2 human_loader.max_len = min(human_loader.max_len, nb_scene) ratio_conf_man = int(nb_scene / len(human_loader.human_paths)) C.scene.frame_end = int(frame_rate * (nb_pose - 0.5)) @@ -234,9 +234,12 @@ def main(): if not sc % ratio_conf_man: man = human_loader.next(car=car) else: - human.set_bounds(man, car) + # human.set_bounds(man, car) + man = man(car=car) - human_path = human_loader.paths[man] + man_model = man.model + + human_path = human_loader.paths[man_model] scenes_ids.setdefault(human_path, -1) scenes_ids[human_path] += 1 @@ -289,11 +292,11 @@ def main(): } json.dump(previous_cameras, f_cam, indent=4) - man.animation_data_clear() + man_model.animation_data_clear() # Exemple: 150k / 200 / 2 = 1500 poses 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: - bone_lbls = list(man.pose.bones.keys()) + bone_lbls = list(man_model.pose.bones.keys()) bone_lbls = [ lbl for bone in bone_lbls for lbl in [bone + k for k in ['_head', '_tail']] if '_IK' not in lbl ] @@ -311,22 +314,22 @@ def main(): use_targets = nb_pose - po - 1 < nb_targets # use_targets = False - human.switch_constraints(man, enable=not use_targets) + human.switch_constraints(man_model, enable=not use_targets) if nb_pose < nb_targets or not use_targets: id_targets = None else: id_targets = {'l': (nb_pose - po - 1) % len(car_targets['l']), 'r': (nb_pose - po - 1) // len(car_targets['l'])} - random_pose.random_pose_ik(man, targets=car_targets if use_targets else None, id_targets=id_targets) + random_pose.random_pose_ik(man_model, targets=car_targets if use_targets else None, id_targets=id_targets) bpy.ops.object.mode_set(mode='OBJECT') - man.keyframe_insert(data_path="location", index=-1) - man.keyframe_insert(data_path="rotation_euler", index=-1) + man_model.keyframe_insert(data_path="location", index=-1) + man_model.keyframe_insert(data_path="rotation_euler", index=-1) bpy.ops.object.mode_set(mode='POSE') - for bone in man.pose.bones: + for bone in man_model.pose.bones: bone.keyframe_insert(data_path="rotation_euler", index=-1) if bone.name[-3:] == '_IK': bone.keyframe_insert(data_path="location", index=-1) @@ -342,16 +345,16 @@ def main(): annotations_3D = [] for lbl in bone_lbls: if '_tail' in lbl: - bone_3d = utils.get_tail_pose(lbl[:-5], man) + bone_3d = utils.get_tail_pose(lbl[:-5], man_model) else: - bone_3d = utils.get_head_pose(lbl[:-5], man) + bone_3d = utils.get_head_pose(lbl[:-5], man_model) annotations_3D.append(f"{bone_3d[0]:.3f};{bone_3d[1]:.3f};{bone_3d[2]:.3f}") bone_2d = P @ bone_3d bone_2d /= bone_2d[-1] annotations_2D.append(f"{bone_2d[0]:.2f};{bone_2d[1]:.2f}") - for lbl, bone_3d in human.get_face(man).items(): + for lbl, bone_3d in human.get_face(man_model).items(): annotations_3D.append(f"{bone_3d[0]:.3f};{bone_3d[1]:.3f};{bone_3d[2]:.3f}") bone_2d = P @ bone_3d @@ -370,7 +373,7 @@ def main(): if sc * nb_pose % 4000 == 3999: time.sleep(150) - utils.select_only(man) + utils.select_only(man_model) bpy.ops.object.mode_set(mode='POSE') print('Done', '#' * 25) diff --git a/scripts/human.py b/scripts/human.py index a369438c21146e43f9982d52e8eb76eed452c224..821698b4641827ac07be95ae9494fc65a0c3431f 100644 --- a/scripts/human.py +++ b/scripts/human.py @@ -64,6 +64,9 @@ class Human: node_ramp.color_ramp.color_mode = 'HSV' input_links = nodes['Principled BSDF'].inputs[0].links + nodes["Principled BSDF"].inputs["Roughness"].default_value = max( + nodes["Principled BSDF"].inputs["Roughness"].default_value, 0.35) + if len(input_links): img_node = nodes['Principled BSDF'].inputs[0].links[0].from_node @@ -98,6 +101,9 @@ class Human: nodes = mat.node_tree.nodes input_links = nodes['Principled BSDF'].inputs[0].links + nodes["Principled BSDF"].inputs["Roughness"].default_value = max( + nodes["Principled BSDF"].inputs["Roughness"].default_value, 0.5) + if len(input_links): img_node = nodes['Principled BSDF'].inputs[0].links[0].from_node @@ -191,7 +197,7 @@ class Human: except AttributeError: continue - def __call__(self, car=None): + def refresh(self, car=None): for cloth, name in ((self.top, 'Top'), (self.bot, 'Bot')): if cloth is not None: cloth.node_tree.nodes["ColorRamp"].color_ramp.elements[0].color = random_HSV() @@ -203,11 +209,9 @@ class Human: self.hairs.node_tree.nodes["Mix"].inputs[2].default_value = random_color_hair() else: self.hairs.node_tree.nodes["Principled BSDF"].inputs[0].default_value = random_color_hair() - + print(car) set_bounds(self.model, car) - return self.model - def get_face(model): # Compute approximate coordinates of face markers @@ -329,6 +333,7 @@ class HumanLoader: if self.max_len >= len(self.human_paths): # If asked too much self.start_loaded = 0 + self.max_len = len(self.human_paths) if len(self.paths) == len(self.human_paths): # If everything already loaded return @@ -361,12 +366,14 @@ class HumanLoader: self.picker = utils.Randomizer(list(self.humans.values())) self.start_loaded = end_loaded % len(self.human_paths) - def next(self, *args, **kwargs): + def next(self, car=None): self.current_idx += 1 if not self.current_idx % self.max_len: self.load_next() self.current_idx = 0 - return self.picker.get(self.current_idx, *args, **kwargs) + choice = self.picker.get(self.current_idx) + choice.refresh(car=car) + return choice def move_human(self, obj): for ch in obj.children: @@ -380,8 +387,10 @@ class HumanLoader: utils.select_only(obj) - def __call__(self, *args, **kwargs): - return self.picker(*args, **kwargs) + def __call__(self, car=None): + choice = self.picker() + choice.refresh(car=car) + return choice def clear_humans(exceptions=[]): diff --git a/scripts/utils.py b/scripts/utils.py index 78a90ab7007a4a7c8b53e410618b4acc944bf298..d135644013af1e31f23692dd1bad3cde9f8c4560 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -141,15 +141,15 @@ class Randomizer: def __len__(self): return len(self.objects) - def get(self, pick_idx, *args, **kwargs): + def get(self, pick_idx): pick = self.objects[pick_idx] - pick = pick if isinstance(pick, bpy.types.Object) else pick(*args, **kwargs) + # pick = pick if isinstance(pick, bpy.types.Object) else pick(*args, **kwargs) self.swap_object(self[pick_idx]) return pick - def __call__(self, *args, **kwargs): + def __call__(self): pick_idx = random.randint(0, len(self) - 1) - return self.get(pick_idx, *args, **kwargs) + return self.get(pick_idx) def swap_object(self, obj=None): for o in self: