コード例 #1
0
    def _infuse_texture(material: Material, config: Config):
        """
        Overlays the selected material with a texture, this can be either a color texture like for example dirt or
        it can be a texture, which is used as an input to the Principled BSDF of the given material.

        :param material: Material, which will be changed
        :param config: containing the config information
        """
        used_mode = config.get_string("mode", "overlay")
        used_textures = config.get_list("used_texture")
        invert_texture = config.get_bool("invert_texture", False)
        used_connector = config.get_string("connection", "Base Color")
        texture_scale = config.get_float("texture_scale", 0.05)
        strength = config.get_float("strength", 0.5)

        if config.has_param("strength") and used_mode == "set":
            raise Exception(
                "The strength can only be used if the mode is not \"set\"!")

        if len(used_textures) == 0:
            raise Exception(
                f"You have to select a texture, which is {used_mode} over the material!"
            )
        texture = random.choice(used_textures)

        material.infuse_texture(texture=texture,
                                mode=used_mode,
                                invert_texture=invert_texture,
                                connection=used_connector,
                                texture_scale=texture_scale,
                                strength=strength)
コード例 #2
0
    def run(self):
        """ Loads rocks."""

        rocks_settings = self.config.get_list("batches", [])
        for subsec_num, subsec_settings in enumerate(rocks_settings):
            subsec_config = Config(subsec_settings)

            subsec_objects = RockEssentialsRockLoader.load_rocks(
                path=subsec_config.get_string("path"),
                subsec_num=subsec_num,
                objects=subsec_config.get_list("objects", []),
                sample_objects=subsec_config.get_bool("sample_objects", False),
                amount=subsec_config.get_int("amount", None)
            )

            RockEssentialsRockLoader.set_rocks_properties(
                objects=subsec_objects,
                physics=subsec_config.get_bool("physics", False),
                render_levels=subsec_config.get_int("render_levels", 3),
                high_detail_mode=subsec_config.get_bool("high_detail_mode", False),
                scale=subsec_config.get_vector3d("scale", [1, 1, 1]),
                reflection_amount=subsec_config.get_float("reflection_amount", None),
                reflection_roughness=subsec_config.get_float("reflection_roughness", None),
                hsv=subsec_config.get_list("HSV", None)
            )
コード例 #3
0
    def _infuse_material(material: Material, config: Config):
        """
        Infuse a material inside of another material. The given material, will be adapted and the used material, will
        be added, depending on the mode either as add or as mix. This change is applied to all outputs of the material,
        this include the Surface (Color) and also the displacement and volume. For displacement mix means multiply.

        :param material: Used material
        :param config: Used config
        """
        # determine the mode
        used_mode = config.get_string("mode", "mix")

        mix_strength = 0.0
        if used_mode == "mix":
            mix_strength = config.get_float("mix_strength", 0.5)
        elif used_mode == "add" and config.has_param("mix_strength"):
            raise Exception(
                "The mix_strength only works in the mix mode not in the add mode!"
            )

        # get the material, which will be used to infuse the given material
        used_materials = config.get_list("used_material")
        used_material = random.choice(used_materials)

        material.infuse_material(material=Material(used_material),
                                 mode=used_mode,
                                 mix_strength=mix_strength)
コード例 #4
0
    def run(self):
        """ Adds specified basic empty objects to the scene and sets at least their names to the user-defined ones.
            1. Get configuration parameters' values.
            2. Add an object.
            3. Set attribute values.
        """
        empties_to_add = self.config.get_list("empties_to_add")
        for empty in empties_to_add:
            empty_conf = Config(empty)
            obj_name = empty_conf.get_string("name")
            obj_type = empty_conf.get_string("type", "plain_axes")

            entity = create_empty(obj_name, obj_type)
            entity.set_location(empty_conf.get_vector3d("location", [0, 0, 0]))
            entity.set_rotation_euler(
                empty_conf.get_vector3d("rotation", [0, 0, 0]))
            entity.set_scale(empty_conf.get_vector3d("scale", [1, 1, 1]))
コード例 #5
0
    def _cam2world_matrix_from_cam_extrinsics(self,
                                              config: Config) -> np.ndarray:
        """ Determines camera extrinsics by using the given config and returns them in form of a cam to world frame transformation matrix.

        :param config: The configuration object.
        :return: The 4x4 cam to world transformation matrix.
        """
        if not config.has_param("cam2world_matrix"):
            # Print warning if local_frame_change is used with other attributes than cam2world_matrix
            if self.local_frame_change != ["X", "Y", "Z"]:
                print(
                    "Warning: The local_frame_change parameter is at the moment only supported when setting the cam2world_matrix attribute."
                )

            position = change_coordinate_frame_of_point(
                config.get_vector3d("location", [0, 0, 0]),
                self.world_frame_change)

            # Rotation
            rotation_format = config.get_string("rotation/format", "euler")
            value = config.get_vector3d("rotation/value", [0, 0, 0])
            # Transform to blender coord frame
            value = change_coordinate_frame_of_point(value,
                                                     self.world_frame_change)

            if rotation_format == "euler":
                # Rotation, specified as euler angles
                rotation_matrix = Euler(value, 'XYZ').to_matrix()
            elif rotation_format == "forward_vec":
                # Convert forward vector to euler angle (Assume Up = Z)
                rotation_matrix = CameraUtility.rotation_from_forward_vec(
                    value)
            elif rotation_format == "look_at":
                # Convert forward vector to euler angle (Assume Up = Z)
                rotation_matrix = CameraUtility.rotation_from_forward_vec(
                    value - position)
            else:
                raise Exception("No such rotation format:" +
                                str(rotation_format))

            if rotation_format == "look_at" or rotation_format == "forward_vec":
                inplane_rot = config.get_float("rotation/inplane_rot", 0.0)
                rotation_matrix = np.matmul(
                    rotation_matrix,
                    Euler((0.0, 0.0, inplane_rot)).to_matrix())

            cam2world_matrix = build_transformation_mat(
                position, rotation_matrix)
        else:
            cam2world_matrix = np.array(
                config.get_list("cam2world_matrix")).reshape(4, 4).astype(
                    np.float32)
            cam2world_matrix = change_source_coordinate_frame_of_transformation_matrix(
                cam2world_matrix, self.local_frame_change)
            cam2world_matrix = change_target_coordinate_frame_of_transformation_matrix(
                cam2world_matrix, self.world_frame_change)
        return cam2world_matrix
コード例 #6
0
    def _get_the_set_params(self, params_conf: Config) -> dict:
        """ Extracts actual values to set from a Config object.

        :param params_conf: Object with all user-defined data.
        :return: Parameters to set as {name of the parameter: it's value} pairs.
        """
        params = {}
        for key in params_conf.data.keys():
            result = None
            if key == "cf_color_link_to_displacement":
                result = params_conf.get_float(key)
            elif key == "cf_change_to_vertex_color":
                result = params_conf.get_string(key)
            elif key == "cf_textures":
                result = {}
                paths_conf = Config(params_conf.get_raw_dict(key))
                for text_key in paths_conf.data.keys():
                    text_path = paths_conf.get_string(text_key)
                    result.update({text_key: text_path})
            elif key == "cf_switch_to_emission_shader":
                result = {}
                emission_conf = Config(params_conf.get_raw_dict(key))
                for emission_key in emission_conf.data.keys():
                    if emission_key == "color":
                        attr_val = emission_conf.get_list(
                            "color", [1, 1, 1, 1])
                    elif emission_key == "strength":
                        attr_val = emission_conf.get_float("strength", 1.0)
                    result.update({emission_key: attr_val})
            elif key == "cf_infuse_texture":
                result = Config(params_conf.get_raw_dict(key))
            elif key == "cf_infuse_material":
                result = Config(params_conf.get_raw_dict(key))
            elif key == "cf_add_dust":
                result = params_conf.get_raw_dict(key)
            elif "cf_set_" in key or "cf_add_" in key:
                result = params_conf.get_raw_value(key)
            else:
                result = params_conf.get_raw_value(key)

            params.update({key: result})

        return params
コード例 #7
0
 def run(self):
     """ Adds specified basic mesh objects to the scene and sets at least their names to the user-defined ones.
         1. Get configuration parameters' values.
         2. Add an object.
         3. Set attribute values.
         4. Initialize a material, if needed.
     """
     meshes_to_add = self.config.get_list("meshes_to_add")
     init_objs_mats = self.config.get_bool("init_materials", True)
     for mesh in meshes_to_add:
         mesh_conf = Config(mesh)
         obj_type = mesh_conf.get_string("type")
         obj_name = mesh_conf.get_string("name")
         obj_location = mesh_conf.get_vector3d("location", [0, 0, 0])
         obj_rotation = mesh_conf.get_vector3d("rotation", [0, 0, 0])
         obj_scale = mesh_conf.get_vector3d("scale", [1, 1, 1])
         new_obj = self._add_obj(obj_type)
         self._set_attrs(new_obj, obj_name, obj_location, obj_rotation,
                         obj_scale)
         if init_objs_mats:
             self._init_material(obj_name)
コード例 #8
0
    def _get_the_set_params(self, params_conf: Config):
        """ Extracts actual values to set from a Config object.

        :param params_conf: Object with all user-defined data. Type: Config.
        :return: Parameters to set as {name of the parameter: it's value} pairs. Type: dict.
        """
        params = {}
        for key in params_conf.data.keys():
            if key == "cf_add_modifier":
                modifier_config = Config(params_conf.get_raw_dict(key))
                # instruction about unpacking the data: key, corresponding Config method to extract the value,
                # it's default value and a postproc function
                instructions = {
                    "name": (Config.get_string, None, str.upper),
                    "thickness": (Config.get_float, None, None)
                }
                # unpack
                result = self._unpack_params(modifier_config, instructions)
            elif key == "cf_set_shading":
                result = {
                    "shading_mode":
                    params_conf.get_string("cf_set_shading"),
                    "angle_value":
                    params_conf.get_float(
                        "cf_shading_auto_smooth_angle_in_deg", 30)
                }
            elif key == "cf_add_displace_modifier_with_texture":
                displace_config = Config(params_conf.get_raw_dict(key))
                # instruction about unpacking the data: key, corresponding Config method to extract the value,
                # it's default value and a postproc function
                instructions = {
                    "texture": (Config.get_raw_value, [], None),
                    "mid_level": (Config.get_float, 0.5, None),
                    "subdiv_level": (Config.get_int, 2, None),
                    "strength": (Config.get_float, 0.1, None),
                    "min_vertices_for_subdiv": (Config.get_int, 10000, None)
                }
                # unpack
                result = self._unpack_params(displace_config, instructions)
            elif key == "cf_add_uv_mapping":
                uv_config = Config(params_conf.get_raw_dict(key))
                # instruction about unpacking the data: key, corresponding Config method to extract the value,
                # it's default value and a postproc function
                instructions = {
                    "projection": (Config.get_string, None, str.lower),
                    "forced_recalc_of_uv_maps": (Config.get_bool, False, None)
                }
                # unpack
                result = self._unpack_params(uv_config, instructions)
            elif key == "cf_randomize_materials":
                rand_config = Config(params_conf.get_raw_dict(key))
                # instruction about unpacking the data: key, corresponding Config method to extract the value,
                # it's default value and a postproc function
                instructions = {
                    "randomization_level": (Config.get_float, 0.2, None),
                    "add_to_objects_without_material":
                    (Config.get_bool, False, None),
                    "materials_to_replace_with":
                    (Config.get_list, BlenderUtility.get_all_materials(),
                     None),
                    "obj_materials_cond_to_be_replaced":
                    (Config.get_raw_dict, {}, None)
                }
                result = self._unpack_params(rand_config, instructions)
                result["material_to_replace_with"] = choice(
                    result["materials_to_replace_with"])
            else:
                result = params_conf.get_raw_value(key)

            params.update({key: result})

        return params