diff options
Diffstat (limited to 'render_povray/shading.py')
-rwxr-xr-x | render_povray/shading.py | 1663 |
1 files changed, 175 insertions, 1488 deletions
diff --git a/render_povray/shading.py b/render_povray/shading.py index 67ee8e51..cc61c5b8 100755 --- a/render_povray/shading.py +++ b/render_povray/shading.py @@ -7,102 +7,101 @@ import bpy -def write_object_material_interior(material, ob, tab_write): +def write_object_material_interior(file, material, ob, tab_write): """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 + This is called in model_all.objects_loop """ # 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) + # if material and material.pov.transparency_method == 'RAYTRACE': + if not material: + return + # implicit if material: + # But there can be only one ior! + if material.pov_subsurface_scattering.use: # SSS IOR get highest priority + tab_write(file, "interior {\n") + tab_write(file, "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 or material.pov.transparency_method != "Z_TRANSPARENCY": + tab_write(file, "interior {\n") + tab_write(file, "ior %.6f\n" % material.pov_raytrace_transparency.ior) + else: + tab_write(file, "interior {\n") + tab_write(file, "ior 1.0\n") + pov_fake_caustics = False + pov_photons_refraction = False + pov_photons_reflection = bool(material.pov.photons_reflection) + if not material.pov.refraction_caustics: 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") + 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(file, "caustics %.3g\n" % material.pov.fake_caustics_power) + if pov_photons_refraction: + # Default of 1 means no dispersion + tab_write(file, "dispersion %.6f\n" % material.pov.photons_dispersion) + tab_write(file, "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( + file, "fade_distance %.3g\n" % (100.001 - material.pov_raytrace_transparency.depth_max) + ) + # fade_power + tab_write(file, "fade_power %.3g\n" % material.pov_raytrace_transparency.falloff) + # fade_color + tab_write(file, "fade_color <%.3g, %.3g, %.3g>\n" % material.pov.interior_fade_color[:]) + + # (variable) dispersion_samples (constant count for now) + tab_write(file, "}\n") + if material.pov.photons_reflection or material.pov.refraction_type == "2": + tab_write(file, "photons{") + tab_write(file, "target %.3g\n" % ob.pov.spacing_multiplier) + if not ob.pov.collect_photons: + tab_write(file, "collect off\n") + if pov_photons_refraction: + tab_write(file, "refraction on\n") + if pov_photons_reflection: + tab_write(file, "reflection on\n") + tab_write(file, "}\n") def write_material( + file, using_uberpov, DEF_MAT_NAME, tab_write, - safety, comments, unique_name, material_names_dictionary, - material + material, ): """Translate Blender material to POV texture{} block and write in exported file.""" # Assumes only called once on each material + + from .render import safety + if material: name_orig = material.name name = material_names_dictionary[name_orig] = unique_name( @@ -122,30 +121,31 @@ def write_material( # 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 - def pov_has_no_specular_maps(ref_level_bound): + def pov_has_no_specular_maps(file, ref_level_bound): """Translate Blender specular map influence to POV finish map trick and write to file.""" if ref_level_bound == 1: if comments: - tab_write("//--No specular nor Mirror reflection--\n") + tab_write(file, "//--No specular nor Mirror reflection--\n") else: - tab_write("\n") - tab_write("#declare %s = finish {\n" % safety(name, ref_level_bound=1)) + tab_write(file, "\n") + tab_write(file, "#declare %s = finish {\n" % safety(name, ref_level_bound=1)) elif ref_level_bound == 2: if comments: tab_write( - "//--translation of spec and mir levels for when no map " "influences them--\n" + file, + "//--translation of spec and mir levels for when no map " "influences them--\n", ) else: - tab_write("\n") - tab_write("#declare %s = finish {\n" % safety(name, ref_level_bound=2)) + tab_write(file, "\n") + tab_write(file, "#declare %s = finish {\n" % safety(name, ref_level_bound=2)) elif ref_level_bound == 3: if comments: - tab_write("//--Maximum Spec and Mirror--\n") + tab_write(file, "//--Maximum Spec and Mirror--\n") else: - tab_write("\n") - tab_write("#declare %s = finish {\n" % safety(name, ref_level_bound=3)) + tab_write(file, "\n") + tab_write(file, "#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) @@ -180,188 +180,198 @@ def write_material( 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. - tab_write("brilliance %.3g\n" % (0.9 + material.roughness)) + tab_write(file, "brilliance %.3g\n" % (0.9 + material.roughness)) if material.pov.diffuse_shader == "TOON" and ref_level_bound != 3: - tab_write("brilliance %.3g\n" % (0.01 + material.diffuse_toon_smooth * 0.25)) + tab_write(file, "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. front_diffuse *= 0.5 if material.pov.diffuse_shader == "MINNAERT" and ref_level_bound != 3: - # tab_write("aoi %.3g\n" % material.darkness) + # tab_write(file, "aoi %.3g\n" % material.pov.darkness) pass # let's keep things simple for now if material.pov.diffuse_shader == "FRESNEL" and ref_level_bound != 3: - # tab_write("aoi %.3g\n" % material.diffuse_fresnel_factor) + # tab_write(file, "aoi %.3g\n" % material.pov.diffuse_fresnel_factor) pass # let's keep things simple for now if material.pov.diffuse_shader == "LAMBERT" and ref_level_bound != 3: # trying to best match lambert attenuation by that constant brilliance value - tab_write("brilliance 1\n") + tab_write(file, "brilliance 1\n") if ref_level_bound == 2: # ------------------------------ Specular Shader ------------------------------ # # No difference between phong and cook torrence in blender HaHa! - if ( - material.pov.specular_shader == "COOKTORR" - or material.pov.specular_shader == "PHONG" - ): - tab_write("phong %.3g\n" % material.pov.specular_intensity) - tab_write("phong_size %.3g\n" % (material.pov.specular_hardness / 3.14)) + if material.pov.specular_shader in ["COOKTORR", "PHONG"]: + tab_write(file, "phong %.3g\n" % material.pov.specular_intensity) + tab_write(file, "phong_size %.3g\n" % (material.pov.specular_hardness / 3.14)) # POV-Ray 'specular' keyword corresponds to a Blinn model, without the ior. elif material.pov.specular_shader == "BLINN": # Use blender Blinn's IOR just as some factor for spec intensity tab_write( + file, "specular %.3g\n" - % (material.pov.specular_intensity * (material.pov.specular_ior / 4.0)) + % (material.pov.specular_intensity * (material.pov.specular_ior / 4.0)), ) - tab_write("roughness %.3g\n" % roughness) + tab_write(file, "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)) + tab_write(file, "phong %.3g\n" % (material.pov.specular_intensity * 2.0)) # use extreme phong_size - tab_write("phong_size %.3g\n" % (0.1 + material.pov.specular_toon_smooth / 2.0)) + tab_write( + file, "phong_size %.3g\n" % (0.1 + material.pov.specular_toon_smooth / 2.0) + ) elif material.pov.specular_shader == "WARDISO": # find best suited default constant for brilliance Use both phong and # specular for some values. tab_write( + file, "specular %.3g\n" - % (material.pov.specular_intensity / (material.pov.specular_slope + 0.0005)) + % ( + 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. - tab_write("roughness %.4g\n" % (0.0005 + material.pov.specular_slope / 10.0)) + tab_write( + file, "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. - tab_write("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8)) + tab_write(file, "brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8)) # -------------------------------------------------------------------------------- # 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)) - tab_write("phong_size %.3g\n" % (material.pov.specular_hardness / 3.14)) + if material.pov.specular_shader in ["COOKTORR", "PHONG"]: + tab_write(file, "phong 0\n") # %.3g\n" % (material.pov.specular_intensity/5)) + tab_write(file, "phong_size %.3g\n" % (material.pov.specular_hardness / 3.14)) # POV-Ray 'specular' keyword corresponds to a Blinn model, without the ior. elif material.pov.specular_shader == "BLINN": # Use blender Blinn's IOR just as some factor for spec intensity tab_write( + file, "specular %.3g\n" - % (material.pov.specular_intensity * (material.pov.specular_ior / 4.0)) + % (material.pov.specular_intensity * (material.pov.specular_ior / 4.0)), ) - tab_write("roughness %.3g\n" % roughness) + tab_write(file, "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)) + tab_write(file, "phong %.3g\n" % (material.pov.specular_intensity * 2.0)) # use extreme phong_size - tab_write("phong_size %.3g\n" % (0.1 + material.pov.specular_toon_smooth / 2.0)) + tab_write( + file, "phong_size %.3g\n" % (0.1 + material.pov.specular_toon_smooth / 2.0) + ) elif material.pov.specular_shader == "WARDISO": # find best suited default constant for brilliance Use both phong and # specular for some values. tab_write( + file, "specular %.3g\n" - % (material.pov.specular_intensity / (material.pov.specular_slope + 0.0005)) + % ( + 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. - tab_write("roughness %.4g\n" % (0.0005 + material.pov.specular_slope / 10.0)) + tab_write( + file, "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. - tab_write("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8)) + tab_write(file, "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 + 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 + material.pov.specular_intensity * material.pov.specular_color.v * 255 ) - tab_write("specular %.3g\n" % max_spec_factor) - tab_write("roughness %.3g\n" % (1 / material.pov.specular_hardness)) - tab_write("diffuse %.3g %.3g\n" % (front_diffuse, back_diffuse)) + tab_write(file, "specular %.3g\n" % max_spec_factor) + tab_write(file, "roughness %.3g\n" % (1 / material.pov.specular_hardness)) + tab_write(file, "diffuse %.3g, %.3g\n" % (front_diffuse, back_diffuse)) - tab_write("ambient %.3g\n" % material.pov.ambient) + tab_write(file, "ambient %.3g\n" % material.pov.ambient) # POV-Ray blends the global value - # tab_write("ambient rgb <%.3g, %.3g, %.3g>\n" % \ + # tab_write(file, "ambient rgb <%.3g, %.3g, %.3g>\n" % \ # tuple([c*material.pov.ambient for c in world.ambient_color])) - tab_write("emission %.3g\n" % material.pov.emit) # New in POV-Ray 3.7 + tab_write(file, "emission %.3g\n" % material.pov.emit) # New in POV-Ray 3.7 # POV-Ray just ignores roughness if there's no specular keyword - # tab_write("roughness %.3g\n" % roughness) + # tab_write(file, "roughness %.3g\n" % roughness) if material.pov.conserve_energy: # added for more realistic shading. Needs some checking to see if it # really works. --Maurice. - tab_write("conserve_energy\n") + tab_write(file, "conserve_energy\n") if colored_specular_found: - tab_write("metallic\n") + tab_write(file, "metallic\n") # 'phong 70.0 ' - if ref_level_bound != 1: - if material.pov_raytrace_mirror.use: - raytrace_mirror = material.pov_raytrace_mirror - if raytrace_mirror.reflect_factor: - 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: - # 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 - tab_write("fresnel 1 ") + if ref_level_bound != 1 and material.pov_raytrace_mirror.use: + raytrace_mirror = material.pov_raytrace_mirror + if raytrace_mirror.reflect_factor: + tab_write(file, "reflection {\n") + tab_write(file, "rgb <%.3g, %.3g, %.3g>\n" % material.pov.mirror_color[:]) + if material.metallic: + tab_write(file, "metallic %.3g\n" % material.metallic) + # Blurry reflections for UberPOV + if using_uberpov and raytrace_mirror.gloss_factor < 1.0: + # tab_write(file, "#ifdef(unofficial) #if(unofficial = \"patch\") #if(patch(\"upov-reflection-roughness\") > 0)\n") tab_write( - "falloff %.3g exponent %.3g} " - % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor) + file, "roughness %.6f\n" % (0.000001 / raytrace_mirror.gloss_factor) ) + # tab_write(file, "#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 + tab_write(file, "fresnel 1 ") + tab_write( + file, + "falloff %.3g exponent %.3g} " + % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor), + ) if material.pov_subsurface_scattering.use: subsurface_scattering = material.pov_subsurface_scattering tab_write( + file, "subsurface { translucency <%.3g, %.3g, %.3g> }\n" % ( (subsurface_scattering.radius[0]), (subsurface_scattering.radius[1]), (subsurface_scattering.radius[2]), - ) + ), ) if material.pov.irid_enable: tab_write( + file, "irid { %.4g thickness %.4g turbulence %.4g }" % ( material.pov.irid_amount, material.pov.irid_thickness, material.pov.irid_turbulence, - ) + ), ) else: - tab_write("diffuse 0.8\n") - tab_write("phong 70.0\n") + tab_write(file, "diffuse 0.8\n") + tab_write(file, "phong 70.0\n") - # tab_write("specular 0.2\n") + # tab_write(file, "specular 0.2\n") # This is written into the object """ @@ -369,16 +379,16 @@ def write_material( 'interior { ior %.3g} ' % material.raytrace_transparency.ior """ - # 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 + # tab_write(file, "crand 1.0\n") # Sand granyness + # tab_write(file, "metallic %.6f\n" % material.metallic) + # tab_write(file, "phong %.6f\n" % material.spec) + # tab_write(file, "phong_size %.6f\n" % material.spec) + # tab_write(file, "brilliance %.6f " % (material.pov.specular_hardness/256.0) # Like hardness - tab_write("}\n\n") + tab_write(file, "}\n\n") # 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) + pov_has_no_specular_maps(file, ref_level_bound=2) if material: special_texture_found = False @@ -411,1330 +421,7 @@ def write_material( if special_texture_found or colored_specular_found: # ref_level_bound=1 Means No specular nor Mirror reflection - pov_has_no_specular_maps(ref_level_bound=1) + pov_has_no_specular_maps(file, ref_level_bound=1) # ref_level_bound=3 Means Maximum Spec and Mirror - pov_has_no_specular_maps(ref_level_bound=3) - - -def export_pattern(texture): - """Translate Blender procedural textures to POV patterns and write to pov file. - - Function Patterns can be used to better access sub components of a pattern like - grey values for influence mapping - """ - tex = texture - pat = tex.pov - 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 - col_ramp_strg = "color_map {\n" - num_color = 0 - for el in tex.color_ramp.elements: - num_color += 1 - pos = el.position - 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 ------------------------- # - 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) - else: - 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 ------------------------- # - if tex.type == "CLOUDS": - if tex.noise_type == "SOFT_NOISE": - text_strg += "wrinkles\n" - text_strg += "scale 0.25\n" - else: - text_strg += "granite\n" - if tex.use_color_ramp: - text_strg += export_color_ramp(tex) - else: - 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 ------------------------- # - 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) - else: - 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 ------------------------- # - 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) - else: - 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" - else: - if tex.use_color_ramp: - text_strg += export_color_ramp(tex) - else: - 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 ------------------------- # - if tex.type == "MAGIC": - text_strg += "leopard\n" - if tex.use_color_ramp: - text_strg += export_color_ramp(tex) - else: - 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 ------------------------- # - 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) - else: - 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" - else: - 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 ------------------------- # - if tex.type == "BLEND": - if tex.progression == "RADIAL": - text_strg += "radial\n" - if tex.use_flip_axis == "HORIZONTAL": - text_strg += "rotate x*90\n" - else: - 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) - else: - 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': - # 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" - # simplified for now: - - if tex.type == "MUSGRAVE": - text_strg += "bozo scale 0.25 \n" - if tex.use_color_ramp: - text_strg += export_color_ramp(tex) - else: - 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 ------------------------- # - 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: - 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: - 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: - 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: - 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" - else: - text_strg += " [1 wrinkles scale 0.25\n" - if tex.use_color_ramp: - text_strg += export_color_ramp(tex) - else: - 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 ------------------------- # - 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: - 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" - - # ------------------------- IGNORE OTHER BLENDER TEXTURE ------------------------- # - else: # non translated textures - pass - 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 ------------------------- # - if pat.tex_pattern_type == "function": - text_strg += "{ %s" % pat.func_list - text_strg += "(x" - if pat.func_plus_x != "NONE": - 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" - if pat.func_plus_y != "NONE": - 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" - if pat.func_plus_z != "NONE": - if pat.func_plus_z == "increase": - text_strg += "*" - if pat.func_plus_z == "plus": - text_strg += "+" - text_strg += "%.4g" % pat.func_z - sort = -1 - 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", - }: - sort = 0 - if pat.func_list in { - "f_bicorn", - "f_bifolia", - "f_boy_surface", - "f_superellipsoid", - "f_torus", - }: - sort = 1 - 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", - }: - sort = 2 - 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", - }: - sort = 3 - 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", - }: - sort = 4 - 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", - }: - sort = 5 - if pat.func_list in {"f_helix1", "f_helix2", "f_piriform_2d", "f_strophoid_2d"}: - sort = 6 - if pat.func_list == "f_helical_torus": - sort = 7 - if sort > -1: - text_strg += ",%.4g" % pat.func_P0 - if sort > 0: - text_strg += ",%.4g" % pat.func_P1 - if sort > 1: - text_strg += ",%.4g" % pat.func_P2 - if sort > 2: - text_strg += ",%.4g" % pat.func_P3 - if sort > 3: - text_strg += ",%.4g" % pat.func_P4 - if sort > 4: - text_strg += ",%.4g" % pat.func_P5 - if sort > 5: - text_strg += ",%.4g" % pat.func_P6 - if sort > 6: - text_strg += ",%.4g" % pat.func_P7 - text_strg += ",%.4g" % pat.func_P8 - text_strg += ",%.4g" % pat.func_P9 - text_strg += ")}\n" - # ------------------------- end functions ------------------------- # - 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: - for el in tex.color_ramp.elements: - num_color += 1 - pos = el.position - 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) - if pat.tex_pattern_type == "hexagon" and num_color < 4: - text_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: - text_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: - text_strg += "color rgbf<%.4g,%.4g,%.4g,%.4g> \n" % (col_r, col_g, col_b, col_a) - else: - text_strg += "[0 color rgbf<0,0,0,1>]\n" - text_strg += "[1 color rgbf<1,1,1,0>]\n" - if pat.tex_pattern_type not in {"checker", "hexagon", "square", "triangular", "brick"}: - text_strg += "} \n" - if pat.tex_pattern_type == "brick": - text_strg += "brick_size <%.4g, %.4g, %.4g> mortar %.4g \n" % ( - pat.brick_size_x, - pat.brick_size_y, - pat.brick_size_z, - pat.brick_mortar, - ) - text_strg += "%s \n" % mapping_dif - text_strg += "rotate <%.4g,%.4g,%.4g> \n" % (pat.tex_rot_x, pat.tex_rot_y, pat.tex_rot_z) - text_strg += "turbulence <%.4g,%.4g,%.4g> \n" % ( - pat.warp_turbulence_x, - pat.warp_turbulence_y, - pat.warp_turbulence_z, - ) - text_strg += "octaves %s \n" % pat.modifier_octaves - text_strg += "lambda %.4g \n" % pat.modifier_lambda - text_strg += "omega %.4g \n" % pat.modifier_omega - text_strg += "frequency %.4g \n" % pat.modifier_frequency - text_strg += "phase %.4g \n" % pat.modifier_phase - text_strg += "}\n\n" - text_strg += "#declare f%s=\n" % pat_name - text_strg += "function{pigment{%s}}\n" % pat_name - text_strg += "\n" - return text_strg - - -def string_strip_hyphen(name): - """POV naming schemes like to conform to most restrictive charsets.""" - return name.replace("-", "") - - -# WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -def write_nodes(pov_mat_name, ntree, file): - """Translate Blender node trees to pov and write them to file.""" - # such function local inlined import are official guidelines - # of Blender Foundation to lighten addons footprint at startup - from os import path - - declare_nodes = [] - scene = bpy.context.scene - for node in ntree.nodes: - pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name - if node.bl_idname == "PovrayFinishNode" and node.outputs["Finish"].is_linked: - file.write("#declare %s = finish {\n" % pov_node_name) - emission = node.inputs["Emission"].default_value - if node.inputs["Emission"].is_linked: - pass - file.write(" emission %.4g\n" % emission) - for link in ntree.links: - if link.to_node == node: - - if link.from_node.bl_idname == "PovrayDiffuseNode": - intensity = 0 - albedo = "" - brilliance = 0 - crand = 0 - if link.from_node.inputs["Intensity"].is_linked: - pass - else: - intensity = link.from_node.inputs["Intensity"].default_value - if link.from_node.inputs["Albedo"].is_linked: - pass - else: - if link.from_node.inputs["Albedo"].default_value: - albedo = "albedo" - file.write(" diffuse %s %.4g\n" % (albedo, intensity)) - if link.from_node.inputs["Brilliance"].is_linked: - pass - else: - brilliance = link.from_node.inputs["Brilliance"].default_value - file.write(" brilliance %.4g\n" % brilliance) - if link.from_node.inputs["Crand"].is_linked: - pass - else: - crand = link.from_node.inputs["Crand"].default_value - if crand > 0: - file.write(" crand %.4g\n" % crand) - - if link.from_node.bl_idname == "PovraySubsurfaceNode": - if scene.povray.sslt_enable: - energy = 0 - r = g = b = 0 - if link.from_node.inputs["Translucency"].is_linked: - pass - else: - r, g, b, a = link.from_node.inputs["Translucency"].default_value[:] - if link.from_node.inputs["Energy"].is_linked: - pass - else: - energy = link.from_node.inputs["Energy"].default_value - file.write( - " subsurface { translucency <%.4g,%.4g,%.4g>*%s }\n" - % (r, g, b, energy) - ) - - if link.from_node.bl_idname in {"PovraySpecularNode", "PovrayPhongNode"}: - intensity = 0 - albedo = "" - roughness = 0 - metallic = 0 - phong_size = 0 - highlight = "specular" - if link.from_node.inputs["Intensity"].is_linked: - pass - else: - intensity = link.from_node.inputs["Intensity"].default_value - - if link.from_node.inputs["Albedo"].is_linked: - pass - else: - if link.from_node.inputs["Albedo"].default_value: - albedo = "albedo" - if link.from_node.bl_idname in {"PovrayPhongNode"}: - highlight = "phong" - file.write(" %s %s %.4g\n" % (highlight, albedo, intensity)) - - if link.from_node.bl_idname in {"PovraySpecularNode"}: - if link.from_node.inputs["Roughness"].is_linked: - pass - else: - roughness = link.from_node.inputs["Roughness"].default_value - file.write(" roughness %.6g\n" % roughness) - - if link.from_node.bl_idname in {"PovrayPhongNode"}: - if link.from_node.inputs["Size"].is_linked: - pass - else: - phong_size = link.from_node.inputs["Size"].default_value - file.write(" phong_size %s\n" % phong_size) - - if link.from_node.inputs["Metallic"].is_linked: - pass - else: - metallic = link.from_node.inputs["Metallic"].default_value - file.write(" metallic %.4g\n" % metallic) - - if link.from_node.bl_idname in {"PovrayMirrorNode"}: - file.write(" reflection {\n") - color = None - exponent = 0 - metallic = 0 - falloff = 0 - fresnel = "" - conserve = "" - if link.from_node.inputs["Color"].is_linked: - pass - else: - color = link.from_node.inputs["Color"].default_value[:] - file.write( - " <%.4g,%.4g,%.4g>\n" - % (color[0], color[1], color[2]) - ) - - if link.from_node.inputs["Exponent"].is_linked: - pass - else: - exponent = link.from_node.inputs["Exponent"].default_value - file.write(" exponent %.4g\n" % exponent) - - if link.from_node.inputs["Falloff"].is_linked: - pass - else: - falloff = link.from_node.inputs["Falloff"].default_value - file.write(" falloff %.4g\n" % falloff) - - if link.from_node.inputs["Metallic"].is_linked: - pass - else: - metallic = link.from_node.inputs["Metallic"].default_value - file.write(" metallic %.4g" % metallic) - - if link.from_node.inputs["Fresnel"].is_linked: - pass - else: - if link.from_node.inputs["Fresnel"].default_value: - fresnel = "fresnel" - - if link.from_node.inputs["Conserve energy"].is_linked: - pass - else: - if link.from_node.inputs["Conserve energy"].default_value: - conserve = "conserve_energy" - - file.write(" %s}\n %s\n" % (fresnel, conserve)) - - if link.from_node.bl_idname == "PovrayAmbientNode": - ambient = (0, 0, 0) - if link.from_node.inputs["Ambient"].is_linked: - pass - else: - ambient = link.from_node.inputs["Ambient"].default_value[:] - file.write(" ambient <%.4g,%.4g,%.4g>\n" % ambient) - - if link.from_node.bl_idname in {"PovrayIridescenceNode"}: - file.write(" irid {\n") - amount = 0 - thickness = 0 - turbulence = 0 - if link.from_node.inputs["Amount"].is_linked: - pass - else: - amount = link.from_node.inputs["Amount"].default_value - file.write(" %.4g\n" % amount) - - if link.from_node.inputs["Thickness"].is_linked: - pass - else: - exponent = link.from_node.inputs["Thickness"].default_value - file.write(" thickness %.4g\n" % thickness) - - if link.from_node.inputs["Turbulence"].is_linked: - pass - else: - falloff = link.from_node.inputs["Turbulence"].default_value - file.write(" turbulence %.4g}\n" % turbulence) - - file.write("}\n") - - for node in ntree.nodes: - pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name - if node.bl_idname == "PovrayTransformNode" and node.outputs["Transform"].is_linked: - tx = node.inputs["Translate x"].default_value - ty = node.inputs["Translate y"].default_value - tz = node.inputs["Translate z"].default_value - rx = node.inputs["Rotate x"].default_value - ry = node.inputs["Rotate y"].default_value - rz = node.inputs["Rotate z"].default_value - sx = node.inputs["Scale x"].default_value - sy = node.inputs["Scale y"].default_value - sz = node.inputs["Scale z"].default_value - file.write( - "#declare %s = transform {\n" - " translate<%.4g,%.4g,%.4g>\n" - " rotate<%.4g,%.4g,%.4g>\n" - " scale<%.4g,%.4g,%.4g>}\n" % (pov_node_name, tx, ty, tz, rx, ry, rz, sx, sy, sz) - ) - - for node in ntree.nodes: - pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name - if node.bl_idname == "PovrayColorImageNode" and node.outputs["Pigment"].is_linked: - declare_nodes.append(node.name) - if node.image == "": - file.write("#declare %s = pigment { color rgb 0.8}\n" % pov_node_name) - else: - im = bpy.data.images[node.image] - if im.filepath and path.exists(bpy.path.abspath(im.filepath)): # (os.path) - transform = "" - for link in ntree.links: - if ( - link.from_node.bl_idname == "PovrayTransformNode" - and link.to_node == node - ): - pov_trans_name = ( - string_strip_hyphen(bpy.path.clean_name(link.from_node.name)) - + "_%s" % pov_mat_name - ) - transform = "transform {%s}" % pov_trans_name - uv = "" - if node.map_type == "uv_mapping": - uv = "uv_mapping" - filepath = bpy.path.abspath(im.filepath) - file.write("#declare %s = pigment {%s image_map {\n" % (pov_node_name, uv)) - premul = "off" - if node.premultiplied: - premul = "on" - once = "" - if node.once: - once = "once" - file.write( - ' "%s"\n gamma %.6g\n premultiplied %s\n' - % (filepath, node.inputs["Gamma"].default_value, premul) - ) - file.write(" %s\n" % once) - if node.map_type != "uv_mapping": - file.write(" map_type %s\n" % node.map_type) - file.write( - " interpolate %s\n filter all %.4g\n transmit all %.4g\n" - % ( - node.interpolate, - node.inputs["Filter"].default_value, - node.inputs["Transmit"].default_value, - ) - ) - file.write(" }\n") - file.write(" %s\n" % transform) - file.write(" }\n") - - for node in ntree.nodes: - pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name - if node.bl_idname == "PovrayImagePatternNode" and node.outputs["Pattern"].is_linked: - declare_nodes.append(node.name) - if node.image != "": - im = bpy.data.images[node.image] - if im.filepath and path.exists(bpy.path.abspath(im.filepath)): - transform = "" - for link in ntree.links: - if ( - link.from_node.bl_idname == "PovrayTransformNode" - and link.to_node == node - ): - pov_trans_name = ( - string_strip_hyphen(bpy.path.clean_name(link.from_node.name)) - + "_%s" % pov_mat_name - ) - transform = "transform {%s}" % pov_trans_name - uv = "" - if node.map_type == "uv_mapping": - uv = "uv_mapping" - filepath = bpy.path.abspath(im.filepath) - file.write("#macro %s() %s image_pattern {\n" % (pov_node_name, uv)) - premul = "off" - if node.premultiplied: - premul = "on" - once = "" - if node.once: - once = "once" - file.write( - ' "%s"\n gamma %.6g\n premultiplied %s\n' - % (filepath, node.inputs["Gamma"].default_value, premul) - ) - file.write(" %s\n" % once) - if node.map_type != "uv_mapping": - file.write(" map_type %s\n" % node.map_type) - file.write(" interpolate %s\n" % node.interpolate) - file.write(" }\n") - file.write(" %s\n" % transform) - file.write("#end\n") - - for node in ntree.nodes: - pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name - if node.bl_idname == "PovrayBumpMapNode" and node.outputs["Normal"].is_linked: - if node.image != "": - im = bpy.data.images[node.image] - if im.filepath and path.exists(bpy.path.abspath(im.filepath)): - transform = "" - for link in ntree.links: - if ( - link.from_node.bl_idname == "PovrayTransformNode" - and link.to_node == node - ): - pov_trans_name = ( - string_strip_hyphen(bpy.path.clean_name(link.from_node.name)) - + "_%s" % pov_mat_name - ) - transform = "transform {%s}" % pov_trans_name - uv = "" - if node.map_type == "uv_mapping": - uv = "uv_mapping" - filepath = bpy.path.abspath(im.filepath) - file.write("#declare %s = normal {%s bump_map {\n" % (pov_node_name, uv)) - once = "" - if node.once: - once = "once" - file.write(' "%s"\n' % filepath) - file.write(" %s\n" % once) - if node.map_type != "uv_mapping": - file.write(" map_type %s\n" % node.map_type) - bump_size = node.inputs["Normal"].default_value - if node.inputs["Normal"].is_linked: - pass - file.write( - " interpolate %s\n bump_size %.4g\n" % (node.interpolate, bump_size) - ) - file.write(" }\n") - file.write(" %s\n" % transform) - file.write(" }\n") - declare_nodes.append(node.name) - - for node in ntree.nodes: - pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name - if node.bl_idname == "PovrayPigmentNode" and node.outputs["Pigment"].is_linked: - declare_nodes.append(node.name) - r, g, b = node.inputs["Color"].default_value[:] - f = node.inputs["Filter"].default_value - t = node.inputs["Transmit"].default_value - if node.inputs["Color"].is_linked: - pass - file.write( - "#declare %s = pigment{color srgbft <%.4g,%.4g,%.4g,%.4g,%.4g>}\n" - % (pov_node_name, r, g, b, f, t) - ) - - for node in ntree.nodes: - pov_node_name = string_strip_hyphen(bpy.path.clean_name(node.name)) + "_%s" % pov_mat_name - if node.bl_idname == "PovrayTextureNode" and node.outputs["Texture"].is_linked: - declare_nodes.append(node.name) - r, g, b = node.inputs["Pigment"].default_value[:] - pov_col_name = "color rgb <%.4g,%.4g,%.4g>" % (r, g, b) - if node.inputs["Pigment"].is_linked: - for link in ntree.links: - if link.to_node == node and link.to_socket.name == "Pigment": - pov_col_name = ( - string_strip_hyphen(bpy.path.clean_name(link.from_node.name)) - + "_%s" % pov_mat_name - ) - file.write("#declare %s = texture{\n pigment{%s}\n" % (pov_node_name, pov_col_name)) - if node.inputs["Normal"].is_linked: - for link in ntree.links: - if ( - link.to_node == node - and link.to_socket.name == "Normal" - and link.from_node.name in declare_nodes - ): - pov_nor_name = ( - string_strip_hyphen(bpy.path.clean_name(link.from_node.name)) - + "_%s" % pov_mat_name - ) - file.write(" normal{%s}\n" % pov_nor_name) - if node.inputs["Finish"].is_linked: - for link in ntree.links: - if link.to_node == node and link.to_socket.name == "Finish": - pov_fin_name = ( - string_strip_hyphen(bpy.path.clean_name(link.from_node.name)) - + "_%s" % pov_mat_name - ) - file.write(" finish{%s}\n" % pov_fin_name) - file.write("}\n") - declare_nodes.append(node.name) - - for i in range(0, len(ntree.nodes)): - for node in ntree.nodes: - if node.bl_idname in {"ShaderNodeGroup", "ShaderTextureMapNode"}: - for output in node.outputs: - if ( - output.name == "Texture" - and output.is_linked - and (node.name not in declare_nodes) - ): - declare = True - for link in ntree.links: - if link.to_node == node and link.to_socket.name not in { - "", - "Color ramp", - "Mapping", - "Transform", - "Modifier", - }: - if link.from_node.name not in declare_nodes: - declare = False - if declare: - pov_node_name = ( - string_strip_hyphen(bpy.path.clean_name(node.name)) - + "_%s" % pov_mat_name - ) - uv = "" - warp = "" - for link in ntree.links: - if ( - link.to_node == node - and link.from_node.bl_idname == "PovrayMappingNode" - and link.from_node.warp_type != "NONE" - ): - w_type = link.from_node.warp_type - if w_type == "uv_mapping": - uv = "uv_mapping" - else: - tor = "" - if w_type == "toroidal": - tor = ( - "major_radius %.4g" - % link.from_node.warp_tor_major_radius - ) - orient = link.from_node.warp_orientation - exp = link.from_node.warp_dist_exp - warp = "warp{%s orientation %s dist_exp %.4g %s}" % ( - w_type, - orient, - exp, - tor, - ) - if link.from_node.warp_type == "planar": - warp = "warp{%s %s %.4g}" % (w_type, orient, exp) - if link.from_node.warp_type == "cubic": - warp = "warp{%s}" % w_type - file.write("#declare %s = texture {%s\n" % (pov_node_name, uv)) - pattern = node.inputs[0].default_value - advanced = "" - if node.inputs[0].is_linked: - for link in ntree.links: - if ( - link.to_node == node - and link.from_node.bl_idname == "ShaderPatternNode" - ): - # ------------ advanced ------------------------- # - lfn = link.from_node - pattern = lfn.pattern - if pattern == "agate": - advanced = "agate_turb %.4g" % lfn.agate_turb - if pattern == "crackle": - advanced = "form <%.4g,%.4g,%.4g>" % ( - lfn.crackle_form_x, - lfn.crackle_form_y, - lfn.crackle_form_z, - ) - advanced += " metric %.4g" % lfn.crackle_metric - if lfn.crackle_solid: - advanced += " solid" - if pattern in {"spiral1", "spiral2"}: - advanced = "%.4g" % lfn.spiral_arms - if pattern in {"tiling"}: - advanced = "%.4g" % lfn.tiling_number - if pattern in {"gradient"}: - advanced = "%s" % lfn.gradient_orient - if ( - link.to_node == node - and link.from_node.bl_idname == "PovrayImagePatternNode" - ): - pov_macro_name = ( - string_strip_hyphen( - bpy.path.clean_name(link.from_node.name) - ) - + "_%s" % pov_mat_name - ) - pattern = "%s()" % pov_macro_name - file.write(" %s %s %s\n" % (pattern, advanced, warp)) - - repeat = "" - for link in ntree.links: - if ( - link.to_node == node - and link.from_node.bl_idname == "PovrayMultiplyNode" - ): - if link.from_node.amount_x > 1: - repeat += "warp{repeat %.4g * x}" % link.from_node.amount_x - if link.from_node.amount_y > 1: - repeat += " warp{repeat %.4g * y}" % link.from_node.amount_y - if link.from_node.amount_z > 1: - repeat += " warp{repeat %.4g * z}" % link.from_node.amount_z - - transform = "" - for link in ntree.links: - if ( - link.to_node == node - and link.from_node.bl_idname == "PovrayTransformNode" - ): - pov_trans_name = ( - string_strip_hyphen( - bpy.path.clean_name(link.from_node.name) - ) - + "_%s" % pov_mat_name - ) - transform = "transform {%s}" % pov_trans_name - x = 0 - y = 0 - z = 0 - d = 0 - e = 0 - f = 0 - g = 0 - h = 0 - modifier = False - for link in ntree.links: - if ( - link.to_node == node - and link.from_node.bl_idname == "PovrayModifierNode" - ): - modifier = True - if link.from_node.inputs["Turb X"].is_linked: - pass - else: - x = link.from_node.inputs["Turb X"].default_value - - if link.from_node.inputs["Turb Y"].is_linked: - pass - else: - y = link.from_node.inputs["Turb Y"].default_value - - if link.from_node.inputs["Turb Z"].is_linked: - pass - else: - z = link.from_node.inputs["Turb Z"].default_value - - if link.from_node.inputs["Octaves"].is_linked: - pass - else: - d = link.from_node.inputs["Octaves"].default_value - - if link.from_node.inputs["Lambda"].is_linked: - pass - else: - e = link.from_node.inputs["Lambda"].default_value - - if link.from_node.inputs["Omega"].is_linked: - pass - else: - f = link.from_node.inputs["Omega"].default_value - - if link.from_node.inputs["Frequency"].is_linked: - pass - else: - g = link.from_node.inputs["Frequency"].default_value - - if link.from_node.inputs["Phase"].is_linked: - pass - else: - h = link.from_node.inputs["Phase"].default_value - - turb = "turbulence <%.4g,%.4g,%.4g>" % (x, y, z) - octv = "octaves %s" % d - lmbd = "lambda %.4g" % e - omg = "omega %.4g" % f - freq = "frequency %.4g" % g - pha = "phase %.4g" % h - - file.write("\n") - if pattern not in { - "checker", - "hexagon", - "square", - "triangular", - "brick", - }: - file.write(" texture_map {\n") - if node.inputs["Color ramp"].is_linked: - for link in ntree.links: - if ( - link.to_node == node - and link.from_node.bl_idname == "ShaderNodeValToRGB" - ): - els = link.from_node.color_ramp.elements - n = -1 - for el in els: - n += 1 - pov_in_mat_name = string_strip_hyphen( - bpy.path.clean_name(link.from_node.name) - ) + "_%s_%s" % (n, pov_mat_name) - default = True - for ilink in ntree.links: - if ( - ilink.to_node == node - and ilink.to_socket.name == str(n) - ): - default = False - pov_in_mat_name = ( - string_strip_hyphen( - bpy.path.clean_name( - ilink.from_node.name - ) - ) - + "_%s" % pov_mat_name - ) - if default: - r, g, b, a = el.color[:] - file.write( - " #declare %s = texture{" - "pigment{" - "color srgbt <%.4g,%.4g,%.4g,%.4g>}};\n" - % (pov_in_mat_name, r, g, b, 1 - a) - ) - file.write( - " [%s %s]\n" % (el.position, pov_in_mat_name) - ) - else: - els = [[0, 0, 0, 0], [1, 1, 1, 1]] - for t in range(0, 2): - pov_in_mat_name = string_strip_hyphen( - bpy.path.clean_name(link.from_node.name) - ) + "_%s_%s" % (t, pov_mat_name) - default = True - for ilink in ntree.links: - if ilink.to_node == node and ilink.to_socket.name == str(t): - default = False - pov_in_mat_name = ( - string_strip_hyphen( - bpy.path.clean_name(ilink.from_node.name) - ) - + "_%s" % pov_mat_name - ) - if default: - r, g, b = els[t][1], els[t][2], els[t][3] - if pattern not in { - "checker", - "hexagon", - "square", - "triangular", - "brick", - }: - file.write( - " #declare %s = texture{pigment{color rgb <%.4g,%.4g,%.4g>}};\n" - % (pov_in_mat_name, r, g, b) - ) - else: - file.write( - " texture{pigment{color rgb <%.4g,%.4g,%.4g>}}\n" - % (r, g, b) - ) - if pattern not in { - "checker", - "hexagon", - "square", - "triangular", - "brick", - }: - file.write(" [%s %s]\n" % (els[t][0], pov_in_mat_name)) - else: - if not default: - file.write(" texture{%s}\n" % pov_in_mat_name) - if pattern not in { - "checker", - "hexagon", - "square", - "triangular", - "brick", - }: - file.write("}\n") - if pattern == "brick": - file.write( - "brick_size <%.4g, %.4g, %.4g> mortar %.4g \n" - % ( - node.brick_size_x, - node.brick_size_y, - node.brick_size_z, - node.brick_mortar, - ) - ) - file.write(" %s %s" % (repeat, transform)) - if modifier: - file.write( - " %s %s %s %s %s %s" % (turb, octv, lmbd, omg, freq, pha) - ) - file.write("}\n") - declare_nodes.append(node.name) - - for link in ntree.links: - if link.to_node.bl_idname == "PovrayOutputNode" and link.from_node.name in declare_nodes: - pov_mat_node_name = ( - string_strip_hyphen(bpy.path.clean_name(link.from_node.name)) + "_%s" % pov_mat_name - ) - file.write("#declare %s = %s\n" % (pov_mat_name, pov_mat_node_name)) + pov_has_no_specular_maps(file, ref_level_bound=3) |