Beispiel #1
0
    def _make_lamp_emissive(self, obj: MeshObject, light: list):
        """ Adds an emission shader to the object materials which are specified in the light list

        :param obj: The blender object.
        :param light: A list of two lists. The first list specifies all materials which should act as a lightbulb, the second one lists all materials corresponding to lampshades.
        """
        for i, m in enumerate(obj.get_materials()):
            mat_name = m.get_name()
            if "." in mat_name:
                mat_name = mat_name[:mat_name.find(".")]
            if mat_name in light[0] or mat_name in light[1]:
                old_mat_name = m.get_name()
                if old_mat_name in self._collection_of_mats["lamp"]:
                    # this material was used as a ceiling before use that one
                    obj.set_material(i, self._collection_of_mats["lamp"][old_mat_name])
                    continue
                # copy the material if more than one users is using it
                if m.get_users() > 1:
                    m = m.duplicate()
                    obj.set_material(i, m)
                # rename the material
                m.set_name(m.get_name() + "_emission")

                emission = m.get_nodes_with_type("Emission")
                if not emission:
                    if mat_name in light[0]:
                        # If the material corresponds to light bulb
                        emission_strength = self.config.get_float("lightbulb_emission_strength", 15)
                    else:
                        # If the material corresponds to a lampshade
                        emission_strength = self.config.get_float("lampshade_emission_strength", 7)

                    m.make_emissive(emission_strength, keep_using_base_color=False, emission_color=m.blender_obj.diffuse_color)
                    self._collection_of_mats["lamp"][old_mat_name] = m
Beispiel #2
0
    def _make_window_emissive(self, obj: MeshObject):
        """ Makes the given window object emissive.

        For each material with alpha < 1.
        Uses a light path node to make it emit light, but at the same time look like a principle material.
        Otherwise windows would be completely white.

        :param obj: A window object.
        """
        for i, m in enumerate(obj.get_materials()):

            # All parameters imported from the .mtl file are stored inside the principled bsdf node
            principled_node = m.get_the_one_node_with_type("BsdfPrincipled")
            alpha = principled_node.inputs['Alpha'].default_value

            if alpha < 1:
                mat_name = m.get_name()
                if mat_name in self._collection_of_mats["window"]:
                    # this material was used as a ceiling before use that one
                    obj.set_material(i, self._collection_of_mats["window"][mat_name])
                    continue
                # copy the material if more than one users is using it
                if m.get_users() > 1:
                    m = m.duplicate()
                    obj.set_material(i, m)
                # rename the material
                m.set_name(m.get_name() + "_emission")
                if not m.get_nodes_with_type('Emission'):
                    transparent_node = m.new_node('ShaderNodeBsdfDiffuse')
                    transparent_node.inputs['Color'].default_value[:3] = (0.285, 0.5, 0.48)

                    m.make_emissive(emission_strength=10, keep_using_base_color=False, emission_color=(1, 1, 1, 1), non_emissive_color_socket=transparent_node.outputs['BSDF'])

                self._collection_of_mats["window"][mat_name] = m
    def _make_ceiling_emissive(obj: MeshObject,
                               collection_of_mats: dict[dict[Material]],
                               ceiling_emission_strength: float = 1.5):
        """ Makes the given ceiling object emissive, s.t. there is always a little bit ambient light.

        :param obj: The ceiling object.
        :param collection_of_mats: A dictionary that contains materials for lamps, windows and ceilings.
        :param ceiling_emission_strength: The emission strength that should be used for the ceiling. Default: 1.5
        """
        for i, m in enumerate(obj.get_materials()):
            mat_name = m.get_name()
            if mat_name in collection_of_mats["ceiling"]:
                # this material was used as a ceiling before use that one
                obj.set_material(i, collection_of_mats["ceiling"][mat_name])
                continue
            # copy the material if more than one users is using it
            if m.get_users() > 1:
                m = m.duplicate()
                obj.set_material(i, m)
            # rename the material
            m.set_name(m.get_name() + "_emission")

            if not m.get_nodes_with_type("Emission") and m.get_nodes_with_type(
                    "BsdfPrincipled"):
                m.make_emissive(emission_strength=ceiling_emission_strength,
                                emission_color=(1, 1, 1, 1),
                                keep_using_base_color=False)
                collection_of_mats["ceiling"][mat_name] = m
    def _make_lamp_emissive(obj: MeshObject,
                            light: dict[list[str], list[str]],
                            collection_of_mats: dict[dict[Material]],
                            lightbulb_emission_strength: float = 15,
                            lampshade_emission_strength: float = 7):
        """ Adds an emission shader to the object materials which are specified in the light dictionary

        :param obj: The blender object.
        :param light: A dictionary of two lists. The first list specifies all materials which should act as a lightbulb, the second one lists all materials corresponding to lampshades.
        :param collection_of_mats: A dictionary that contains materials for lamps, windows and ceilings.
        :param lightbulb_emission_strength: The emission strength that should be used for light bulbs. Default: 15
        :param lampshade_emission_strength: The emission strength that should be used for lamp shades. Default: 7
        """
        for i, m in enumerate(obj.get_materials()):
            mat_name = m.get_name()
            if "." in mat_name:
                mat_name = mat_name[:mat_name.find(".")]
            if mat_name in light[0] or mat_name in light[1]:
                old_mat_name = m.get_name()
                if old_mat_name in collection_of_mats["lamp"]:
                    # this material was used as a ceiling before use that one
                    obj.set_material(i,
                                     collection_of_mats["lamp"][old_mat_name])
                    continue
                # copy the material if more than one users is using it
                if m.get_users() > 1:
                    m = m.duplicate()
                    obj.set_material(i, m)
                # rename the material
                m.set_name(m.get_name() + "_emission")

                emission = m.get_nodes_with_type("Emission")
                if not emission:
                    if mat_name in light[0]:
                        # If the material corresponds to light bulb
                        emission_strength = lightbulb_emission_strength
                    else:
                        # If the material corresponds to a lampshade
                        emission_strength = lampshade_emission_strength

                    m.make_emissive(emission_strength,
                                    keep_using_base_color=False,
                                    emission_color=m.blender_obj.diffuse_color)
                    collection_of_mats["lamp"][old_mat_name] = m
Beispiel #5
0
    def _transform_and_colorize_object(object: MeshObject,
                                       material_adjustments: list,
                                       transform: Matrix = None,
                                       parent: MeshObject = None):
        """ Applies the given transformation to the object and refactors its materials.

        Material is replaced with an existing material if possible or is changed according to the material_adjustments

        :param object: The object to use.
        :param material_adjustments: A list of adjustments to make. (Each element i corresponds to material_i)
        :param transform: The transformation matrix to apply
        :param parent: The parent object to which the object should be linked
        """
        if parent is not None:
            object.set_parent(parent)

        if transform is not None:
            # Apply transformation
            object.apply_T(transform)

        for i, mat in enumerate(object.get_materials()):
            # the material name of an object contains a nr, which is mentioned in the material_adjustments
            index = mat.get_name()[mat.get_name().find("_") + 1:]
            if "." in index:
                index = index[:index.find(".")]
            index = int(index)

            # check if this index is mentioned in material_adjustments and if a texture is necessary
            force_texture = index < len(
                material_adjustments
            ) and "texture" in material_adjustments[index]
            SuncgLoader._recreate_material_nodes(mat, force_texture)

            if index < len(material_adjustments):
                SuncgLoader._adjust_material_nodes(mat,
                                                   material_adjustments[index])
            mat_type, value = SuncgLoader._get_type_and_value_from_mat(mat)
            current_mats = SuncgLoader._collection_of_loaded_mats[mat_type]
            if value in current_mats:
                object.set_material(i, current_mats[value])
            else:
                # save the current material for later
                current_mats[value] = mat
Beispiel #6
0
    def _make_ceiling_emissive(self, obj: MeshObject):
        """ Makes the given ceiling object emissive, s.t. there is always a little bit ambient light.

        :param obj: The ceiling object.
        """
        for i, m in enumerate(obj.get_materials()):
            mat_name = m.get_name()
            if mat_name in self._collection_of_mats["ceiling"]:
                # this material was used as a ceiling before use that one
                obj.set_material(i, self._collection_of_mats["ceiling"][mat_name])
                continue
            # copy the material if more than one users is using it
            if m.get_users() > 1:
                m = m.duplicate()
                obj.set_material(i, m)
            # rename the material
            m.set_name(m.get_name() + "_emission")

            if not m.get_nodes_with_type("Emission") and m.get_nodes_with_type("BsdfPrincipled"):
                m.make_emissive(emission_strength=self.config.get_float("ceiling_emission_strength", 1.5), emission_color=(1, 1, 1, 1), keep_using_base_color=False)
                self._collection_of_mats["ceiling"][mat_name] = m