Esempio n. 1
0
    def run(self):
        """
        Uses the loaded .obj files and picks one randomly and loads it
        """
        selected_obj = random.choice(self._files_with_fitting_synset)    
        loaded_obj = Utility.import_objects(selected_obj)
        
        for obj in loaded_obj:
            obj["used_synset_id"] = self._used_synset_id
            obj["used_source_id"] = pathlib.PurePath(selected_obj).parts[-3]
        
        self._correct_materials(loaded_obj)

        self._set_properties(loaded_obj)

        if "void" in LabelIdMapping.label_id_map:  # Check if using an id map
            for obj in loaded_obj:
                obj["category_id"] = LabelIdMapping.label_id_map["void"]

        # removes the x axis rotation found in all ShapeNet objects, this is caused by importing .obj files
        # the object has the same pose as before, just that the rotation_euler is now [0, 0, 0]
        LoaderInterface.remove_x_axis_rotation(loaded_obj)

        # move the origin of the object to the world origin and on top of the X-Y plane
        # makes it easier to place them later on, this does not change the `.location`
        LoaderInterface.move_obj_origin_to_bottom_mean_point(loaded_obj)
        bpy.ops.object.select_all(action='DESELECT')
Esempio n. 2
0
    def run(self):
        """
        use the pose parameters to generate the mesh and loads it to the scene.
        """
        # selected_obj = self._files_with_fitting_ids
        pose_body, betas = self._get_pose_parameters()
        # load parametric Model
        body_model, faces = self._load_parametric_body_model()
        # Generate Body representations using SMPL model
        body_repr = body_model(pose_body=pose_body, betas=betas)
        # Generate .obj file represents the selected pose
        generated_obj = self._write_body_mesh_to_obj_file(body_repr, faces)

        loaded_obj = Utility.import_objects(generated_obj)

        self._correct_materials(loaded_obj)

        self._set_properties(loaded_obj)
        # set the shading mode explicitly to smooth
        self.change_shading_mode(loaded_obj, "SMOOTH")

        if "void" in LabelIdMapping.label_id_map:  # Check if using an id map
            for obj in loaded_obj:
                obj['category_id'] = LabelIdMapping.label_id_map["void"]

        # removes the x axis rotation found in all ShapeNet objects, this is caused by importing .obj files
        # the object has the same pose as before, just that the rotation_euler is now [0, 0, 0]
        LoaderInterface.remove_x_axis_rotation(loaded_obj)

        # move the origin of the object to the world origin and on top of the X-Y plane
        # makes it easier to place them later on, this does not change the `.location`
        LoaderInterface.move_obj_origin_to_bottom_mean_point(loaded_obj)
        bpy.ops.object.select_all(action='DESELECT')
Esempio n. 3
0
    def run(self):
        """
        Chooses objects based on selected type and style.
        If there are multiple options it picks one randomly or if style or type is None it picks one randomly.
        Loads the selected object via file path.
        """
        if self._obj_categories is not None and self._obj_style is not None:
            object_lst = []
            for obj_category in self._obj_categories:
                object_lst.extend([obj[0] for (key, obj) in self._obj_dict.items() \
                                  if self._obj_style in key.lower() and obj_category in key])
            if not object_lst:
                selected_obj = random.choice(
                    self._obj_dict.get(
                        random.choice(list(self._obj_dict.keys()))))
                warnings.warn(
                    "Could not find object of type: {}, and style: {}. Selecting random object..."
                    .format(self._obj_categories, self._obj_style),
                    category=Warning)
            else:
                # Multiple objects with same type and style are possible: select randomly from list.
                selected_obj = random.choice(object_lst)
        elif self._obj_categories is not None:
            object_lst = []
            for obj_category in self._obj_categories:
                object_lst.extend(self._get_object_by_type(obj_category))
            selected_obj = random.choice(object_lst)
        elif self._obj_style is not None:
            object_lst = self._get_object_by_style(self._obj_style)
            selected_obj = random.choice(object_lst)
        else:
            random_key = random.choice(list(self._obj_dict.keys()))
            # One key can have multiple object files as value: select randomly from list.
            selected_obj = random.choice(self._obj_dict.get(random_key))

        print("Selected object: ", os.path.basename(selected_obj))
        loaded_obj = Utility.import_objects(selected_obj)
        self._set_properties(loaded_obj)

        # extract the name from the path:
        selected_dir_name = os.path.dirname(selected_obj)
        selected_name = ""
        if os.path.basename(selected_dir_name).startswith("IKEA_"):
            selected_name = os.path.basename(selected_dir_name)
        else:
            selected_dir_name = os.path.dirname(selected_dir_name)
            if os.path.basename(selected_dir_name).startswith("IKEA_"):
                selected_name = os.path.basename(selected_dir_name)
        if selected_name:
            for obj in loaded_obj:
                obj.name = selected_name

        # extract the file unit from the .obj file to convert every object to meters
        file_unit = ""
        with open(selected_obj, "r") as file:
            first_lines = [next(file) for x in range(5)]
            for line in first_lines:
                if "File units" in line:
                    file_unit = line.strip().split(" ")[-1]
                    if file_unit not in [
                            "inches", "meters", "centimeters", "millimeters"
                    ]:
                        raise Exception(
                            "The file unit type could not be found, check the selected "
                            "file: {}".format(selected_obj))
                    break

        for obj in loaded_obj:
            # convert all objects to meters
            if file_unit == "inches":
                scale = 0.0254
            elif file_unit == "centimeters":
                scale = 0.01
            elif file_unit == "millimeters":
                scale = 0.001
            elif file_unit == "meters":
                scale = 1.0
            else:
                raise Exception(
                    "The file unit type: {} is not defined".format(file_unit))
            if scale != 1.0:
                # move all object centers to the world origin and set the bounding box correctly
                bpy.ops.object.select_all(action='DESELECT')
                obj.select_set(True)
                bpy.context.view_layer.objects.active = obj
                # scale object down
                bpy.ops.object.mode_set(mode='EDIT')
                bpy.ops.transform.resize(value=(scale, scale, scale))
                bpy.ops.object.mode_set(mode='OBJECT')
                bpy.context.view_layer.update()
                bpy.ops.object.select_all(action='DESELECT')

        # removes the x axis rotation found in all ShapeNet objects, this is caused by importing .obj files
        # the object has the same pose as before, just that the rotation_euler is now [0, 0, 0]
        LoaderInterface.remove_x_axis_rotation(loaded_obj)

        # move the origin of the object to the world origin and on top of the X-Y plane
        # makes it easier to place them later on, this does not change the `.location`
        LoaderInterface.move_obj_origin_to_bottom_mean_point(loaded_obj)
        bpy.ops.object.select_all(action='DESELECT')