Skip to content
Snippets Groups Projects
shading.py 82 KiB
Newer Older
  • Learn to ignore specific revisions
  • # SPDX-License-Identifier: GPL-2.0-or-later
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    """Translate complex shaders to exported POV textures."""
    
    
    def write_object_material_interior(material, ob, tab_write):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Translate some object level material from Blender UI (VS data level)
    
        to POV interior{} syntax and write it to exported file.
    
        This is called in object_mesh_topology.export_meshes
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """
        # DH - modified some variables to be function local, avoiding RNA write
        # this should be checked to see if it is functionally correct
    
        # Commented out: always write IOR to be able to use it for SSS, Fresnel reflections...
        # if material and material.transparency_method == 'RAYTRACE':
        if material:
            # But there can be only one!
            if material.pov_subsurface_scattering.use:  # SSS IOR get highest priority
                tab_write("interior {\n")
                tab_write("ior %.6f\n" % material.pov_subsurface_scattering.ior)
            # Then the raytrace IOR taken from raytrace transparency properties and used for
            # reflections if IOR Mirror option is checked.
            elif material.pov.mirror_use_IOR:
                tab_write("interior {\n")
                tab_write("ior %.6f\n" % material.pov_raytrace_transparency.ior)
            elif material.pov.transparency_method == 'Z_TRANSPARENCY':
                tab_write("interior {\n")
                tab_write("ior 1.0\n")
            else:
                tab_write("interior {\n")
                tab_write("ior %.6f\n" % material.pov_raytrace_transparency.ior)
    
            pov_fake_caustics = False
            pov_photons_refraction = False
            pov_photons_reflection = False
    
            if material.pov.photons_reflection:
                pov_photons_reflection = True
            if not material.pov.refraction_caustics:
                pov_fake_caustics = False
                pov_photons_refraction = False
            elif material.pov.refraction_type == "1":
                pov_fake_caustics = True
                pov_photons_refraction = False
            elif material.pov.refraction_type == "2":
                pov_fake_caustics = False
                pov_photons_refraction = True
    
            # If only Raytrace transparency is set, its IOR will be used for refraction, but user
            # can set up 'un-physical' fresnel reflections in raytrace mirror parameters.
            # Last, if none of the above is specified, user can set up 'un-physical' fresnel
            # reflections in raytrace mirror parameters. And pov IOR defaults to 1.
            if material.pov.caustics_enable:
                if pov_fake_caustics:
                    tab_write("caustics %.3g\n" % material.pov.fake_caustics_power)
                if pov_photons_refraction:
                    # Default of 1 means no dispersion
                    tab_write("dispersion %.6f\n" % material.pov.photons_dispersion)
                    tab_write("dispersion_samples %.d\n" % material.pov.photons_dispersion_samples)
            # TODO
            # Other interior args
            if material.pov.use_transparency and material.pov.transparency_method == 'RAYTRACE':
                # fade_distance
                # In Blender this value has always been reversed compared to what tooltip says.
                # 100.001 rather than 100 so that it does not get to 0
                # which deactivates the feature in POV
                tab_write(
                    "fade_distance %.3g\n" % (100.001 - material.pov_raytrace_transparency.depth_max)
                )
                # fade_power
                tab_write("fade_power %.3g\n" % material.pov_raytrace_transparency.falloff)
                # fade_color
                tab_write("fade_color <%.3g, %.3g, %.3g>\n" % material.pov.interior_fade_color[:])
    
            # (variable) dispersion_samples (constant count for now)
            tab_write("}\n")
            if material.pov.photons_reflection or material.pov.refraction_type == "2":
                tab_write("photons{")
                tab_write("target %.3g\n" % ob.pov.spacing_multiplier)
                if not ob.pov.collect_photons:
                    tab_write("collect off\n")
                if pov_photons_refraction:
                    tab_write("refraction on\n")
                if pov_photons_reflection:
                    tab_write("reflection on\n")
                tab_write("}\n")
    
    
    def write_material(
    
        using_uberpov,
        DEF_MAT_NAME,
        tab_write,
        safety,
        comments,
        unique_name,
        material_names_dictionary,
        material
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    ):
    
        """Translate Blender material to POV texture{} block and write in exported file."""
    
        # Assumes only called once on each material
        if material:
            name_orig = material.name
    
            name = material_names_dictionary[name_orig] = unique_name(
                bpy.path.clean_name(name_orig), material_names_dictionary
    
            # If saturation(.s) is not zero, then color is not grey, and has a tint
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            colored_specular_found = (material.pov.specular_color.s > 0.0) and (
                material.pov.diffuse_shader != "MINNAERT"
            )
    
        else:
            name = name_orig = DEF_MAT_NAME
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        # Several versions of the finish: ref_level_bound conditions are variations for specular/Mirror
    
        # texture channel map with alternative finish of 0 specular and no mirror reflection.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        # ref_level_bound=1 Means No specular nor Mirror reflection
        # ref_level_bound=2 Means translation of spec and mir levels for when no map influences them
        # ref_level_bound=3 Means Maximum Spec and Mirror
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        def pov_has_no_specular_maps(ref_level_bound):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            """Translate Blender specular map influence to POV finish map trick and write to file."""
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if ref_level_bound == 1:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("//--No specular nor Mirror reflection--\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("\n")
                tab_write("#declare %s = finish {\n" % safety(name, ref_level_bound=1))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            elif ref_level_bound == 2:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write(
                        "//--translation of spec and mir levels for when no map " "influences them--\n"
                    )
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("\n")
                tab_write("#declare %s = finish {\n" % safety(name, ref_level_bound=2))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            elif ref_level_bound == 3:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("//--Maximum Spec and Mirror--\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("\n")
                tab_write("#declare %s = finish {\n" % safety(name, ref_level_bound=3))
    
            if material:
                # POV-Ray 3.7 now uses two diffuse values respectively for front and back shading
                # (the back diffuse is like blender translucency)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                front_diffuse = material.pov.diffuse_intensity
                back_diffuse = material.pov.translucency
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    # Total should not go above one
                    if (front_diffuse + back_diffuse) <= 1.0:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    elif front_diffuse == back_diffuse:
    
                        # Try to respect the user's 'intention' by comparing the two values but
                        # bringing the total back to one.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        front_diffuse = back_diffuse = 0.5
    
                    # Let the highest value stay the highest value.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    elif front_diffuse > back_diffuse:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        back_diffuse = min(back_diffuse, (1.0 - front_diffuse))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        front_diffuse = min(front_diffuse, (1.0 - back_diffuse))
    
    
                # map hardness between 0.0 and 1.0
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                roughness = 1.0 - ((material.pov.specular_hardness - 1.0) / 510.0)
    
                ## scale from 0.0 to 0.1
                roughness *= 0.1
                # add a small value because 0.0 is invalid.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                roughness += 1.0 / 511.0
    
                # ------------------------------ Diffuse Shader ------------------------------ #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # Not used for Full spec (ref_level_bound=3) of the shader.
                if material.pov.diffuse_shader == "OREN_NAYAR" and ref_level_bound != 3:
    
                    # Blender roughness is what is generally called oren nayar Sigma,
                    # and brilliance in POV-Ray.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("brilliance %.3g\n" % (0.9 + material.roughness))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if material.pov.diffuse_shader == "TOON" and ref_level_bound != 3:
                    tab_write("brilliance %.3g\n" % (0.01 + material.diffuse_toon_smooth * 0.25))
    
                    # Lower diffuse and increase specular for toon effect seems to look better
                    # in POV-Ray.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    front_diffuse *= 0.5
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if material.pov.diffuse_shader == "MINNAERT" and ref_level_bound != 3:
                    # tab_write("aoi %.3g\n" % material.darkness)
    
                    pass  # let's keep things simple for now
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if material.pov.diffuse_shader == "FRESNEL" and ref_level_bound != 3:
                    # tab_write("aoi %.3g\n" % material.diffuse_fresnel_factor)
    
                    pass  # let's keep things simple for now
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if material.pov.diffuse_shader == "LAMBERT" and ref_level_bound != 3:
    
                    # trying to best match lambert attenuation by that constant brilliance value
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("brilliance 1\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if ref_level_bound == 2:
    
                    # ------------------------------ Specular Shader ------------------------------ #
    
                    # No difference between phong and cook torrence in blender HaHa!
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if (
                        material.pov.specular_shader == "COOKTORR"
                        or material.pov.specular_shader == "PHONG"
                    ):
    
                        tab_write("phong %.3g\n" % material.pov.specular_intensity)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write("phong_size %.3g\n" % (material.pov.specular_hardness / 3.14))
    
    
                    # POV-Ray 'specular' keyword corresponds to a Blinn model, without the ior.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    elif material.pov.specular_shader == "BLINN":
    
                        # Use blender Blinn's IOR just as some factor for spec intensity
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write(
                            "specular %.3g\n"
                            % (material.pov.specular_intensity * (material.pov.specular_ior / 4.0))
                        )
                        tab_write("roughness %.3g\n" % roughness)
                        # Could use brilliance 2(or varying around 2 depending on ior or factor) too.
    
                    elif material.pov.specular_shader == "TOON":
                        tab_write("phong %.3g\n" % (material.pov.specular_intensity * 2.0))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write("phong_size %.3g\n" % (0.1 + material.pov.specular_toon_smooth / 2.0))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    elif material.pov.specular_shader == "WARDISO":
    
                        # find best suited default constant for brilliance Use both phong and
                        # specular for some values.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write(
                            "specular %.3g\n"
                            % (material.pov.specular_intensity / (material.pov.specular_slope + 0.0005))
                        )
    
                        # find best suited default constant for brilliance Use both phong and
                        # specular for some values.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write("roughness %.4g\n" % (0.0005 + material.pov.specular_slope / 10.0))
    
                        # find best suited default constant for brilliance Use both phong and
                        # specular for some values.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8))
    
                # -------------------------------------------------------------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                elif ref_level_bound == 1:
                    if (
                        material.pov.specular_shader == "COOKTORR"
                        or material.pov.specular_shader == "PHONG"
                    ):
    
                        tab_write("phong 0\n")  # %.3g\n" % (material.pov.specular_intensity/5))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write("phong_size %.3g\n" % (material.pov.specular_hardness / 3.14))
    
    
                    # POV-Ray 'specular' keyword corresponds to a Blinn model, without the ior.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    elif material.pov.specular_shader == "BLINN":
    
                        # Use blender Blinn's IOR just as some factor for spec intensity
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write(
                            "specular %.3g\n"
                            % (material.pov.specular_intensity * (material.pov.specular_ior / 4.0))
                        )
                        tab_write("roughness %.3g\n" % roughness)
                        # Could use brilliance 2(or varying around 2 depending on ior or factor) too.
    
                    elif material.pov.specular_shader == "TOON":
                        tab_write("phong %.3g\n" % (material.pov.specular_intensity * 2.0))
    
                        # use extreme phong_size
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write("phong_size %.3g\n" % (0.1 + material.pov.specular_toon_smooth / 2.0))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    elif material.pov.specular_shader == "WARDISO":
    
                        # find best suited default constant for brilliance Use both phong and
                        # specular for some values.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write(
                            "specular %.3g\n"
                            % (material.pov.specular_intensity / (material.pov.specular_slope + 0.0005))
                        )
    
                        # find best suited default constant for brilliance Use both phong and
                        # specular for some values.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write("roughness %.4g\n" % (0.0005 + material.pov.specular_slope / 10.0))
    
                        # find best suited default constant for brilliance Use both phong and
                        # specular for some values.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        tab_write("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8))
                elif ref_level_bound == 3:
                    # Spec must be Max at ref_level_bound 3 so that white of mixing texture always shows specularity
    
                    # That's why it's multiplied by 255. maybe replace by texture's brightest pixel value?
    
                    if material.pov_texture_slots:
                        max_spec_factor = (
                                material.pov.specular_intensity
                                * material.pov.specular_color.v
                                * 255
                                * slot.specular_factor
    
                    else:
                        max_spec_factor = (
                                material.pov.specular_intensity
                                * material.pov.specular_color.v
                                * 255
                        )
                    tab_write("specular %.3g\n" % max_spec_factor)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("roughness %.3g\n" % (1 / material.pov.specular_hardness))
                tab_write("diffuse %.3g %.3g\n" % (front_diffuse, back_diffuse))
    
                tab_write("ambient %.3g\n" % material.pov.ambient)
    
                # POV-Ray blends the global value
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # tab_write("ambient rgb <%.3g, %.3g, %.3g>\n" % \
    
                #         tuple([c*material.pov.ambient for c in world.ambient_color]))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                tab_write("emission %.3g\n" % material.pov.emit)  # New in POV-Ray 3.7
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # POV-Ray just ignores roughness if there's no specular keyword
                # tab_write("roughness %.3g\n" % roughness)
    
    
                if material.pov.conserve_energy:
                    # added for more realistic shading. Needs some checking to see if it
                    # really works. --Maurice.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write("conserve_energy\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if colored_specular_found:
                    tab_write("metallic\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if ref_level_bound != 1:
    
                    if material.pov_raytrace_mirror.use:
                        raytrace_mirror = material.pov_raytrace_mirror
    
                        if raytrace_mirror.reflect_factor:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                            tab_write("reflection {\n")
                            tab_write("rgb <%.3g, %.3g, %.3g>\n" % material.pov.mirror_color[:])
    
                            if material.pov.mirror_metallic:
    
                                tab_write("metallic %.3g\n" % raytrace_mirror.reflect_factor)
    
                            # Blurry reflections for UberPOV
                            if using_uberpov and raytrace_mirror.gloss_factor < 1.0:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                # tab_write("#ifdef(unofficial) #if(unofficial = \"patch\") #if(patch(\"upov-reflection-roughness\") > 0)\n")
                                tab_write(
                                    "roughness %.6f\n" % (0.000001 / raytrace_mirror.gloss_factor)
                                )
                                # tab_write("#end #end #end\n") # This and previous comment for backward compatibility, messier pov code
    
                            if material.pov.mirror_use_IOR:  # WORKING ?
                                # Removed from the line below: gives a more physically correct
                                # material but needs proper IOR. --Maurice
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                tab_write("fresnel 1 ")
                            tab_write(
                                "falloff %.3g exponent %.3g} "
                                % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor)
                            )
    
                if material.pov_subsurface_scattering.use:
                    subsurface_scattering = material.pov_subsurface_scattering
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write(
                        "subsurface { translucency <%.3g, %.3g, %.3g> }\n"
                        % (
                            (subsurface_scattering.radius[0]),
                            (subsurface_scattering.radius[1]),
                            (subsurface_scattering.radius[2]),
                        )
                    )
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    tab_write(
                        "irid { %.4g thickness %.4g turbulence %.4g }"
                        % (
                            material.pov.irid_amount,
                            material.pov.irid_thickness,
                            material.pov.irid_turbulence,
                        )
                    )
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                tab_write("diffuse 0.8\n")
                tab_write("phong 70.0\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # tab_write("specular 0.2\n")
    
    
            # This is written into the object
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            """
    
            if material and material.pov.transparency_method=='RAYTRACE':
    
                'interior { ior %.3g} ' % material.raytrace_transparency.ior
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            """
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            # tab_write("crand 1.0\n") # Sand granyness
            # tab_write("metallic %.6f\n" % material.spec)
            # tab_write("phong %.6f\n" % material.spec)
            # tab_write("phong_size %.6f\n" % material.spec)
            # tab_write("brilliance %.6f " % (material.pov.specular_hardness/256.0) # Like hardness
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            tab_write("}\n\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        # ref_level_bound=2 Means translation of spec and mir levels for when no map influences them
        pov_has_no_specular_maps(ref_level_bound=2)
    
    
        if material:
            special_texture_found = False
    
            for t in material.pov_texture_slots:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # index = material.pov.active_texture_index
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                slot = material.pov_texture_slots[tmpidx]  # [index]
                povtex = slot.texture  # slot.name
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                tex = bpy.data.textures[povtex]
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if t and t.use and tex is not None:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if (tex.type == "IMAGE" and tex.image) or tex.type != "IMAGE":
                        # validPath
                        if (
                            t
                            and t.use
                            and (
                                t.use_map_specular
                                or t.use_map_raymir
                                or t.use_map_normal
                                or t.use_map_alpha
                            )
                        ):
    
                            special_texture_found = True
    
                            continue  # Some texture found
    
    
            if special_texture_found or colored_specular_found:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                # ref_level_bound=1 Means No specular nor Mirror reflection
                pov_has_no_specular_maps(ref_level_bound=1)
    
                # ref_level_bound=3 Means Maximum Spec and Mirror
                pov_has_no_specular_maps(ref_level_bound=3)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    def export_pattern(texture):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Translate Blender procedural textures to POV patterns and write to pov file.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        Function Patterns can be used to better access sub components of a pattern like
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        grey values for influence mapping
        """
        tex = texture
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        pat = tex.pov
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        pat_name = "PAT_%s" % string_strip_hyphen(bpy.path.clean_name(tex.name))
        mapping_dif = "translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (
            pat.tex_mov_x,
            pat.tex_mov_y,
            pat.tex_mov_z,
            1.0 / pat.tex_scale_x,
            1.0 / pat.tex_scale_y,
            1.0 / pat.tex_scale_z,
        )
        text_strg = ""
    
        def export_color_ramp(texture):
            tex = texture
    
            pat = tex.pov
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            col_ramp_strg = "color_map {\n"
            num_color = 0
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            for el in tex.color_ramp.elements:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                num_color += 1
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                pos = el.position
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                col = el.color
                col_r, col_g, col_b, col_a = col[0], col[1], col[2], 1 - col[3]
                if pat.tex_pattern_type not in {"checker", "hexagon", "square", "triangular", "brick"}:
                    col_ramp_strg += "[%.4g color rgbf<%.4g,%.4g,%.4g,%.4g>] \n" % (
                        pos,
                        col_r,
                        col_g,
                        col_b,
                        col_a,
                    )
                if pat.tex_pattern_type in {"brick", "checker"} and num_color < 3:
                    col_ramp_strg += "color rgbf<%.4g,%.4g,%.4g,%.4g> \n" % (col_r, col_g, col_b, col_a)
                if pat.tex_pattern_type == "hexagon" and num_color < 4:
                    col_ramp_strg += "color rgbf<%.4g,%.4g,%.4g,%.4g> \n" % (col_r, col_g, col_b, col_a)
                if pat.tex_pattern_type == "square" and num_color < 5:
                    col_ramp_strg += "color rgbf<%.4g,%.4g,%.4g,%.4g> \n" % (col_r, col_g, col_b, col_a)
                if pat.tex_pattern_type == "triangular" and num_color < 7:
                    col_ramp_strg += "color rgbf<%.4g,%.4g,%.4g,%.4g> \n" % (col_r, col_g, col_b, col_a)
    
            col_ramp_strg += "} \n"
            # end color map
            return col_ramp_strg
    
        # much work to be done here only defaults translated for now:
        # pov noise_generator 3 means perlin noise
        if tex.type not in {"NONE", "IMAGE"} and pat.tex_pattern_type == "emulator":
            text_strg += "pigment {\n"
    
            # ------------------------- EMULATE BLENDER VORONOI TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "VORONOI":
                text_strg += "crackle\n"
                text_strg += "    offset %.4g\n" % tex.nabla
                text_strg += "    form <%.4g,%.4g,%.4g>\n" % (tex.weight_1, tex.weight_2, tex.weight_3)
                if tex.distance_metric == "DISTANCE":
                    text_strg += "    metric 2.5\n"
                if tex.distance_metric == "DISTANCE_SQUARED":
                    text_strg += "    metric 2.5\n"
                    text_strg += "    poly_wave 2\n"
                if tex.distance_metric == "MINKOVSKY":
                    text_strg += "    metric %s\n" % tex.minkovsky_exponent
                if tex.distance_metric == "MINKOVSKY_FOUR":
                    text_strg += "    metric 4\n"
                if tex.distance_metric == "MINKOVSKY_HALF":
                    text_strg += "    metric 0.5\n"
                if tex.distance_metric == "CHEBYCHEV":
                    text_strg += "    metric 10\n"
                if tex.distance_metric == "MANHATTAN":
                    text_strg += "    metric 1\n"
    
                if tex.color_mode == "POSITION":
                    text_strg += "solid\n"
                text_strg += "scale 0.25\n"
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "color_map {\n"
                    text_strg += "[0 color rgbt<0,0,0,1>]\n"
                    text_strg += "[1 color rgbt<1,1,1,0>]\n"
                    text_strg += "}\n"
    
            # ------------------------- EMULATE BLENDER CLOUDS TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "CLOUDS":
                if tex.noise_type == "SOFT_NOISE":
                    text_strg += "wrinkles\n"
                    text_strg += "scale 0.25\n"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "granite\n"
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "color_map {\n"
                    text_strg += "[0 color rgbt<0,0,0,1>]\n"
                    text_strg += "[1 color rgbt<1,1,1,0>]\n"
                    text_strg += "}\n"
    
            # ------------------------- EMULATE BLENDER WOOD TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "WOOD":
                if tex.wood_type == "RINGS":
                    text_strg += "wood\n"
                    text_strg += "scale 0.25\n"
                if tex.wood_type == "RINGNOISE":
                    text_strg += "wood\n"
                    text_strg += "scale 0.25\n"
                    text_strg += "turbulence %.4g\n" % (tex.turbulence / 100)
                if tex.wood_type == "BANDS":
                    text_strg += "marble\n"
                    text_strg += "scale 0.25\n"
                    text_strg += "rotate <45,-45,45>\n"
                if tex.wood_type == "BANDNOISE":
                    text_strg += "marble\n"
                    text_strg += "scale 0.25\n"
                    text_strg += "rotate <45,-45,45>\n"
                    text_strg += "turbulence %.4g\n" % (tex.turbulence / 10)
    
                if tex.noise_basis_2 == "SIN":
                    text_strg += "sine_wave\n"
                if tex.noise_basis_2 == "TRI":
                    text_strg += "triangle_wave\n"
                if tex.noise_basis_2 == "SAW":
                    text_strg += "ramp_wave\n"
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "color_map {\n"
                    text_strg += "[0 color rgbt<0,0,0,0>]\n"
                    text_strg += "[1 color rgbt<1,1,1,0>]\n"
                    text_strg += "}\n"
    
            # ------------------------- EMULATE BLENDER STUCCI TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "STUCCI":
                text_strg += "bozo\n"
                text_strg += "scale 0.25\n"
                if tex.noise_type == "HARD_NOISE":
                    text_strg += "triangle_wave\n"
                    if tex.use_color_ramp:
                        text_strg += export_color_ramp(tex)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        text_strg += "color_map {\n"
                        text_strg += "[0 color rgbf<1,1,1,0>]\n"
                        text_strg += "[1 color rgbt<0,0,0,1>]\n"
                        text_strg += "}\n"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if tex.use_color_ramp:
                        text_strg += export_color_ramp(tex)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        text_strg += "color_map {\n"
                        text_strg += "[0 color rgbf<0,0,0,1>]\n"
                        text_strg += "[1 color rgbt<1,1,1,0>]\n"
                        text_strg += "}\n"
    
            # ------------------------- EMULATE BLENDER MAGIC TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "MAGIC":
                text_strg += "leopard\n"
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "color_map {\n"
                    text_strg += "[0 color rgbt<1,1,1,0.5>]\n"
                    text_strg += "[0.25 color rgbf<0,1,0,0.75>]\n"
                    text_strg += "[0.5 color rgbf<0,0,1,0.75>]\n"
                    text_strg += "[0.75 color rgbf<1,0,1,0.75>]\n"
                    text_strg += "[1 color rgbf<0,1,0,0.75>]\n"
                    text_strg += "}\n"
                text_strg += "scale 0.1\n"
    
            # ------------------------- EMULATE BLENDER MARBLE TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "MARBLE":
                text_strg += "marble\n"
                text_strg += "turbulence 0.5\n"
                text_strg += "noise_generator 3\n"
                text_strg += "scale 0.75\n"
                text_strg += "rotate <45,-45,45>\n"
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if tex.marble_type == "SOFT":
                        text_strg += "color_map {\n"
                        text_strg += "[0 color rgbt<0,0,0,0>]\n"
                        text_strg += "[0.05 color rgbt<0,0,0,0>]\n"
                        text_strg += "[1 color rgbt<0.9,0.9,0.9,0>]\n"
                        text_strg += "}\n"
                    elif tex.marble_type == "SHARP":
                        text_strg += "color_map {\n"
                        text_strg += "[0 color rgbt<0,0,0,0>]\n"
                        text_strg += "[0.025 color rgbt<0,0,0,0>]\n"
                        text_strg += "[1 color rgbt<0.9,0.9,0.9,0>]\n"
                        text_strg += "}\n"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        text_strg += "[0 color rgbt<0,0,0,0>]\n"
                        text_strg += "[1 color rgbt<1,1,1,0>]\n"
                        text_strg += "}\n"
                if tex.noise_basis_2 == "SIN":
                    text_strg += "sine_wave\n"
                if tex.noise_basis_2 == "TRI":
                    text_strg += "triangle_wave\n"
                if tex.noise_basis_2 == "SAW":
                    text_strg += "ramp_wave\n"
    
            # ------------------------- EMULATE BLENDER BLEND TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "BLEND":
                if tex.progression == "RADIAL":
                    text_strg += "radial\n"
                    if tex.use_flip_axis == "HORIZONTAL":
                        text_strg += "rotate x*90\n"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        text_strg += "rotate <-90,0,90>\n"
                    text_strg += "ramp_wave\n"
                elif tex.progression == "SPHERICAL":
                    text_strg += "spherical\n"
                    text_strg += "scale 3\n"
                    text_strg += "poly_wave 1\n"
                elif tex.progression == "QUADRATIC_SPHERE":
                    text_strg += "spherical\n"
                    text_strg += "scale 3\n"
                    text_strg += "    poly_wave 2\n"
                elif tex.progression == "DIAGONAL":
                    text_strg += "gradient <1,1,0>\n"
                    text_strg += "scale 3\n"
                elif tex.use_flip_axis == "HORIZONTAL":
                    text_strg += "gradient x\n"
                    text_strg += "scale 2.01\n"
                elif tex.use_flip_axis == "VERTICAL":
                    text_strg += "gradient y\n"
                    text_strg += "scale 2.01\n"
                # text_strg+="ramp_wave\n"
                # text_strg+="frequency 0.5\n"
                text_strg += "phase 0.5\n"
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "color_map {\n"
                    text_strg += "[0 color rgbt<1,1,1,0>]\n"
                    text_strg += "[1 color rgbf<0,0,0,1>]\n"
                    text_strg += "}\n"
                if tex.progression == "LINEAR":
                    text_strg += "    poly_wave 1\n"
                if tex.progression == "QUADRATIC":
                    text_strg += "    poly_wave 2\n"
                if tex.progression == "EASING":
                    text_strg += "    poly_wave 1.5\n"
    
            # ------------------------- EMULATE BLENDER MUSGRAVE TEXTURE ------------------------- #
    
            # if tex.type == 'MUSGRAVE':
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            # text_strg+="function{ f_ridged_mf( x, y, 0, 1, 2, 9, -0.5, 3,3 )*0.5}\n"
            # text_strg+="color_map {\n"
            # text_strg+="[0 color rgbf<0,0,0,1>]\n"
            # text_strg+="[1 color rgbf<1,1,1,0>]\n"
            # text_strg+="}\n"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            # simplified for now:
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "MUSGRAVE":
                text_strg += "bozo scale 0.25 \n"
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += (
                        "color_map {[0.5 color rgbf<0,0,0,1>][1 color rgbt<1,1,1,0>]}ramp_wave \n"
                    )
    
            # ------------------------- EMULATE BLENDER DISTORTED NOISE TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "DISTORTED_NOISE":
                text_strg += "average\n"
                text_strg += "  pigment_map {\n"
                text_strg += "  [1 bozo scale 0.25 turbulence %.4g\n" % tex.distortion
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "color_map {\n"
                    text_strg += "[0 color rgbt<1,1,1,0>]\n"
                    text_strg += "[1 color rgbf<0,0,0,1>]\n"
                    text_strg += "}\n"
                text_strg += "]\n"
    
                if tex.noise_distortion == "CELL_NOISE":
                    text_strg += "  [1 cells scale 0.1\n"
                    if tex.use_color_ramp:
                        text_strg += export_color_ramp(tex)
    
                    else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        text_strg += "color_map {\n"
                        text_strg += "[0 color rgbt<1,1,1,0>]\n"
                        text_strg += "[1 color rgbf<0,0,0,1>]\n"
                        text_strg += "}\n"
                    text_strg += "]\n"
                if tex.noise_distortion == "VORONOI_CRACKLE":
                    text_strg += "  [1 crackle scale 0.25\n"
                    if tex.use_color_ramp:
                        text_strg += export_color_ramp(tex)
    
                    else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        text_strg += "color_map {\n"
                        text_strg += "[0 color rgbt<1,1,1,0>]\n"
                        text_strg += "[1 color rgbf<0,0,0,1>]\n"
                        text_strg += "}\n"
                    text_strg += "]\n"
                if tex.noise_distortion in [
                    "VORONOI_F1",
                    "VORONOI_F2",
                    "VORONOI_F3",
                    "VORONOI_F4",
                    "VORONOI_F2_F1",
                ]:
                    text_strg += "  [1 crackle metric 2.5 scale 0.25 turbulence %.4g\n" % (
                        tex.distortion / 2
                    )
                    if tex.use_color_ramp:
                        text_strg += export_color_ramp(tex)
    
                    else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        text_strg += "color_map {\n"
                        text_strg += "[0 color rgbt<1,1,1,0>]\n"
                        text_strg += "[1 color rgbf<0,0,0,1>]\n"
                        text_strg += "}\n"
                    text_strg += "]\n"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "  [1 wrinkles scale 0.25\n"
                    if tex.use_color_ramp:
                        text_strg += export_color_ramp(tex)
    
                    else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        text_strg += "color_map {\n"
                        text_strg += "[0 color rgbt<1,1,1,0>]\n"
                        text_strg += "[1 color rgbf<0,0,0,1>]\n"
                        text_strg += "}\n"
                    text_strg += "]\n"
                text_strg += "  }\n"
    
            # ------------------------- EMULATE BLENDER NOISE TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if tex.type == "NOISE":
                text_strg += "cells\n"
                text_strg += "turbulence 3\n"
                text_strg += "omega 3\n"
                if tex.use_color_ramp:
                    text_strg += export_color_ramp(tex)
    
                else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += "color_map {\n"
                    text_strg += "[0.75 color rgb<0,0,0,>]\n"
                    text_strg += "[1 color rgb<1,1,1,>]\n"
                    text_strg += "}\n"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    
            # ------------------------- IGNORE OTHER BLENDER TEXTURE ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            else:  # non translated textures
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                pass
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            text_strg += "}\n\n"
    
            text_strg += "#declare f%s=\n" % pat_name
            text_strg += "function{pigment{%s}}\n" % pat_name
            text_strg += "\n"
    
        elif pat.tex_pattern_type != "emulator":
            text_strg += "pigment {\n"
            text_strg += "%s\n" % pat.tex_pattern_type
            if pat.tex_pattern_type == "agate":
                text_strg += "agate_turb %.4g\n" % pat.modifier_turbulence
            if pat.tex_pattern_type in {"spiral1", "spiral2", "tiling"}:
                text_strg += "%s\n" % pat.modifier_numbers
            if pat.tex_pattern_type == "quilted":
                text_strg += "control0 %s control1 %s\n" % (
                    pat.modifier_control0,
                    pat.modifier_control1,
                )
            if pat.tex_pattern_type == "mandel":
                text_strg += "%s exponent %s \n" % (pat.f_iter, pat.f_exponent)
            if pat.tex_pattern_type == "julia":
                text_strg += "<%.4g, %.4g> %s exponent %s \n" % (
                    pat.julia_complex_1,
                    pat.julia_complex_2,
                    pat.f_iter,
                    pat.f_exponent,
                )
            if pat.tex_pattern_type == "magnet" and pat.magnet_style == "mandel":
                text_strg += "%s mandel %s \n" % (pat.magnet_type, pat.f_iter)
            if pat.tex_pattern_type == "magnet" and pat.magnet_style == "julia":
                text_strg += "%s julia <%.4g, %.4g> %s\n" % (
                    pat.magnet_type,
                    pat.julia_complex_1,
                    pat.julia_complex_2,
                    pat.f_iter,
                )
            if pat.tex_pattern_type in {"mandel", "julia", "magnet"}:
                text_strg += "interior %s, %.4g\n" % (pat.f_ior, pat.f_ior_fac)
                text_strg += "exterior %s, %.4g\n" % (pat.f_eor, pat.f_eor_fac)
            if pat.tex_pattern_type == "gradient":
                text_strg += "<%s, %s, %s> \n" % (
                    pat.grad_orient_x,
                    pat.grad_orient_y,
                    pat.grad_orient_z,
                )
            if pat.tex_pattern_type == "pavement":
                num_tiles = pat.pave_tiles
                num_pattern = 1
                if pat.pave_sides == "4" and pat.pave_tiles == 3:
                    num_pattern = pat.pave_pat_2
                if pat.pave_sides == "6" and pat.pave_tiles == 3:
                    num_pattern = pat.pave_pat_3
                if pat.pave_sides == "3" and pat.pave_tiles == 4:
                    num_pattern = pat.pave_pat_3
                if pat.pave_sides == "3" and pat.pave_tiles == 5:
                    num_pattern = pat.pave_pat_4
                if pat.pave_sides == "4" and pat.pave_tiles == 4:
                    num_pattern = pat.pave_pat_5
                if pat.pave_sides == "6" and pat.pave_tiles == 4:
                    num_pattern = pat.pave_pat_7
                if pat.pave_sides == "4" and pat.pave_tiles == 5:
                    num_pattern = pat.pave_pat_12
                if pat.pave_sides == "3" and pat.pave_tiles == 6:
                    num_pattern = pat.pave_pat_12
                if pat.pave_sides == "6" and pat.pave_tiles == 5:
                    num_pattern = pat.pave_pat_22
                if pat.pave_sides == "4" and pat.pave_tiles == 6:
                    num_pattern = pat.pave_pat_35
                if pat.pave_sides == "6" and pat.pave_tiles == 6:
                    num_tiles = 5
                text_strg += "number_of_sides %s number_of_tiles %s pattern %s form %s \n" % (
                    pat.pave_sides,
                    num_tiles,
                    num_pattern,
                    pat.pave_form,
                )
    
            # ------------------------- functions ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if pat.tex_pattern_type == "function":
                text_strg += "{ %s" % pat.func_list
                text_strg += "(x"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_plus_x != "NONE":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if pat.func_plus_x == "increase":
                        text_strg += "*"
                    if pat.func_plus_x == "plus":
                        text_strg += "+"
                    text_strg += "%.4g" % pat.func_x
                text_strg += ",y"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_plus_y != "NONE":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if pat.func_plus_y == "increase":
                        text_strg += "*"
                    if pat.func_plus_y == "plus":
                        text_strg += "+"
                    text_strg += "%.4g" % pat.func_y
                text_strg += ",z"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_plus_z != "NONE":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if pat.func_plus_z == "increase":
                        text_strg += "*"
                    if pat.func_plus_z == "plus":
                        text_strg += "+"
                    text_strg += "%.4g" % pat.func_z
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                sort = -1
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_list in {
                    "f_comma",
                    "f_crossed_trough",
                    "f_cubic_saddle",
                    "f_cushion",
                    "f_devils_curve",
                    "f_enneper",
                    "f_glob",
                    "f_heart",
                    "f_hex_x",
                    "f_hex_y",
                    "f_hunt_surface",
                    "f_klein_bottle",
                    "f_kummer_surface_v1",
                    "f_lemniscate_of_gerono",
                    "f_mitre",
                    "f_nodal_cubic",
                    "f_noise_generator",
                    "f_odd",
                    "f_paraboloid",
                    "f_pillow",
                    "f_piriform",
                    "f_quantum",
                    "f_quartic_paraboloid",
                    "f_quartic_saddle",
                    "f_sphere",
                    "f_steiners_roman",
                    "f_torus_gumdrop",
                    "f_umbrella",
                }:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    sort = 0
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_list in {
                    "f_bicorn",
                    "f_bifolia",
                    "f_boy_surface",
                    "f_superellipsoid",
                    "f_torus",
                }:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    sort = 1
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_list in {
                    "f_ellipsoid",
                    "f_folium_surface",
                    "f_hyperbolic_torus",
                    "f_kampyle_of_eudoxus",
                    "f_parabolic_torus",
                    "f_quartic_cylinder",
                    "f_torus2",
                }:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    sort = 2
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_list in {
                    "f_blob2",
                    "f_cross_ellipsoids",
                    "f_flange_cover",
                    "f_isect_ellipsoids",
                    "f_kummer_surface_v2",
                    "f_ovals_of_cassini",
                    "f_rounded_box",
                    "f_spikes_2d",
                    "f_strophoid",
                }:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    sort = 3
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_list in {
                    "f_algbr_cyl1",
                    "f_algbr_cyl2",
                    "f_algbr_cyl3",
                    "f_algbr_cyl4",
                    "f_blob",
                    "f_mesh1",
                    "f_poly4",
                    "f_spikes",
                }:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    sort = 4
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_list in {
                    "f_devils_curve_2d",
                    "f_dupin_cyclid",
                    "f_folium_surface_2d",
                    "f_hetero_mf",
                    "f_kampyle_of_eudoxus_2d",
                    "f_lemniscate_of_gerono_2d",
                    "f_polytubes",
                    "f_ridge",
                    "f_ridged_mf",
                    "f_spiral",
                    "f_witch_of_agnesi",
                }:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    sort = 5
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if pat.func_list in {"f_helix1", "f_helix2", "f_piriform_2d", "f_strophoid_2d"}:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    sort = 6
                if pat.func_list == "f_helical_torus":
                    sort = 7
                if sort > -1:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += ",%.4g" % pat.func_P0
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if sort > 0:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += ",%.4g" % pat.func_P1
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if sort > 1:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += ",%.4g" % pat.func_P2
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if sort > 2:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += ",%.4g" % pat.func_P3
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if sort > 3:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += ",%.4g" % pat.func_P4
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if sort > 4:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += ",%.4g" % pat.func_P5
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if sort > 5:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += ",%.4g" % pat.func_P6
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if sort > 6:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    text_strg += ",%.4g" % pat.func_P7
                    text_strg += ",%.4g" % pat.func_P8
                    text_strg += ",%.4g" % pat.func_P9
                text_strg += ")}\n"
    
            # ------------------------- end functions ------------------------- #
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if pat.tex_pattern_type not in {"checker", "hexagon", "square", "triangular", "brick"}:
                text_strg += "color_map {\n"
            num_color = 0
            if tex.use_color_ramp:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                for el in tex.color_ramp.elements:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    num_color += 1
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    pos = el.position
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    col = el.color
                    col_r, col_g, col_b, col_a = col[0], col[1], col[2], 1 - col[3]
                    if pat.tex_pattern_type not in {
                        "checker",
                        "hexagon",
                        "square",
                        "triangular",
                        "brick",
                    }:
                        text_strg += "[%.4g color rgbf<%.4g,%.4g,%.4g,%.4g>] \n" % (
                            pos,
                            col_r,
                            col_g,
                            col_b,
                            col_a,
                        )
                    if pat.tex_pattern_type in {"brick", "checker"} and num_color < 3:
                        text_strg += "color rgbf<%.4g,%.4g,%.4g,%.4g> \n" % (col_r, col_g, col_b, col_a)