mirror of
https://github.com/blender/blender-addons.git
synced 2025-07-29 12:05:36 +00:00
1762 lines
87 KiB
Python
1762 lines
87 KiB
Python
"""Translate complex shaders to exported POV textures."""
|
|
|
|
import bpy
|
|
|
|
def writeMaterial(using_uberpov, DEF_MAT_NAME, scene, tabWrite, safety, comments, uniqueName, materialNames, material):
|
|
"""Translate Blender material POV texture{} block and write to exported file."""
|
|
# Assumes only called once on each material
|
|
if material:
|
|
name_orig = material.name
|
|
name = materialNames[name_orig] = uniqueName(bpy.path.clean_name(name_orig), materialNames)
|
|
else:
|
|
name = name_orig = DEF_MAT_NAME
|
|
|
|
|
|
if material:
|
|
# If saturation(.s) is not zero, then color is not grey, and has a tint
|
|
colored_specular_found = ((material.pov.specular_color.s > 0.0) and (material.pov.diffuse_shader != 'MINNAERT'))
|
|
|
|
##################
|
|
# Several versions of the finish: Level conditions are variations for specular/Mirror
|
|
# texture channel map with alternative finish of 0 specular and no mirror reflection.
|
|
# Level=1 Means No specular nor Mirror reflection
|
|
# Level=2 Means translation of spec and mir levels for when no map influences them
|
|
# Level=3 Means Maximum Spec and Mirror
|
|
|
|
def povHasnoSpecularMaps(Level):
|
|
"""Translate Blender specular map influence to POV finish map trick and write to file."""
|
|
if Level == 1:
|
|
if comments:
|
|
tabWrite("//--No specular nor Mirror reflection--\n")
|
|
else:
|
|
tabWrite("\n")
|
|
tabWrite("#declare %s = finish {\n" % safety(name, Level=1))
|
|
|
|
elif Level == 2:
|
|
if comments:
|
|
tabWrite("//--translation of spec and mir levels for when no map " \
|
|
"influences them--\n")
|
|
else:
|
|
tabWrite("\n")
|
|
tabWrite("#declare %s = finish {\n" % safety(name, Level=2))
|
|
|
|
elif Level == 3:
|
|
if comments:
|
|
tabWrite("//--Maximum Spec and Mirror--\n")
|
|
else:
|
|
tabWrite("\n")
|
|
tabWrite("#declare %s = finish {\n" % safety(name, Level=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)
|
|
frontDiffuse = material.pov.diffuse_intensity
|
|
backDiffuse = material.pov.translucency
|
|
|
|
if material.pov.conserve_energy:
|
|
|
|
#Total should not go above one
|
|
if (frontDiffuse + backDiffuse) <= 1.0:
|
|
pass
|
|
elif frontDiffuse == backDiffuse:
|
|
# Try to respect the user's 'intention' by comparing the two values but
|
|
# bringing the total back to one.
|
|
frontDiffuse = backDiffuse = 0.5
|
|
# Let the highest value stay the highest value.
|
|
elif frontDiffuse > backDiffuse:
|
|
# clamps the sum below 1
|
|
backDiffuse = min(backDiffuse, (1.0 - frontDiffuse))
|
|
else:
|
|
frontDiffuse = min(frontDiffuse, (1.0 - backDiffuse))
|
|
|
|
# map hardness between 0.0 and 1.0
|
|
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.
|
|
roughness += (1.0 / 511.0)
|
|
|
|
################################Diffuse Shader######################################
|
|
# Not used for Full spec (Level=3) of the shader.
|
|
if material.pov.diffuse_shader == 'OREN_NAYAR' and Level != 3:
|
|
# Blender roughness is what is generally called oren nayar Sigma,
|
|
# and brilliance in POV-Ray.
|
|
tabWrite("brilliance %.3g\n" % (0.9 + material.roughness))
|
|
|
|
if material.pov.diffuse_shader == 'TOON' and Level != 3:
|
|
tabWrite("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.
|
|
frontDiffuse *= 0.5
|
|
|
|
if material.pov.diffuse_shader == 'MINNAERT' and Level != 3:
|
|
#tabWrite("aoi %.3g\n" % material.darkness)
|
|
pass # let's keep things simple for now
|
|
if material.pov.diffuse_shader == 'FRESNEL' and Level != 3:
|
|
#tabWrite("aoi %.3g\n" % material.diffuse_fresnel_factor)
|
|
pass # let's keep things simple for now
|
|
if material.pov.diffuse_shader == 'LAMBERT' and Level != 3:
|
|
# trying to best match lambert attenuation by that constant brilliance value
|
|
tabWrite("brilliance 1\n")
|
|
|
|
if Level == 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'):
|
|
tabWrite("phong %.3g\n" % (material.pov.specular_intensity))
|
|
tabWrite("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
|
|
tabWrite("specular %.3g\n" % (material.pov.specular_intensity *
|
|
(material.pov.specular_ior / 4.0)))
|
|
tabWrite("roughness %.3g\n" % roughness)
|
|
#Could use brilliance 2(or varying around 2 depending on ior or factor) too.
|
|
|
|
elif material.pov.specular_shader == 'TOON':
|
|
tabWrite("phong %.3g\n" % (material.pov.specular_intensity * 2.0))
|
|
# use extreme phong_size
|
|
tabWrite("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.
|
|
tabWrite("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.
|
|
tabWrite("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.
|
|
tabWrite("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8))
|
|
|
|
####################################################################################
|
|
elif Level == 1:
|
|
if (material.pov.specular_shader == 'COOKTORR' or
|
|
material.pov.specular_shader == 'PHONG'):
|
|
tabWrite("phong %.3g\n" % (material.pov.specular_intensity/5))
|
|
tabWrite("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
|
|
tabWrite("specular %.3g\n" % (material.pov.specular_intensity *
|
|
(material.pov.specular_ior / 4.0)))
|
|
tabWrite("roughness %.3g\n" % roughness)
|
|
#Could use brilliance 2(or varying around 2 depending on ior or factor) too.
|
|
|
|
elif material.pov.specular_shader == 'TOON':
|
|
tabWrite("phong %.3g\n" % (material.pov.specular_intensity * 2.0))
|
|
# use extreme phong_size
|
|
tabWrite("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.
|
|
tabWrite("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.
|
|
tabWrite("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.
|
|
tabWrite("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8))
|
|
elif Level == 3:
|
|
tabWrite("specular %.3g\n" % ((material.pov.specular_intensity*material.pov.specular_color.v)*5))
|
|
tabWrite("roughness %.3g\n" % (1.1/material.pov.specular_hardness))
|
|
tabWrite("diffuse %.3g %.3g\n" % (frontDiffuse, backDiffuse))
|
|
|
|
tabWrite("ambient %.3g\n" % material.pov.ambient)
|
|
# POV-Ray blends the global value
|
|
#tabWrite("ambient rgb <%.3g, %.3g, %.3g>\n" % \
|
|
# tuple([c*material.pov.ambient for c in world.ambient_color]))
|
|
tabWrite("emission %.3g\n" % material.pov.emit) # New in POV-Ray 3.7
|
|
|
|
#POV-Ray just ignores roughness if there's no specular keyword
|
|
#tabWrite("roughness %.3g\n" % roughness)
|
|
|
|
if material.pov.conserve_energy:
|
|
# added for more realistic shading. Needs some checking to see if it
|
|
# really works. --Maurice.
|
|
tabWrite("conserve_energy\n")
|
|
|
|
if colored_specular_found == True:
|
|
tabWrite("metallic\n")
|
|
|
|
# 'phong 70.0 '
|
|
if Level != 1:
|
|
if material.pov_raytrace_mirror.use:
|
|
raytrace_mirror = material.pov_raytrace_mirror
|
|
if raytrace_mirror.reflect_factor:
|
|
tabWrite("reflection {\n")
|
|
tabWrite("rgb <%.3g, %.3g, %.3g>\n" % material.pov.mirror_color[:])
|
|
if material.pov.mirror_metallic:
|
|
tabWrite("metallic %.3g\n" % (raytrace_mirror.reflect_factor))
|
|
# Blurry reflections for UberPOV
|
|
if using_uberpov and raytrace_mirror.gloss_factor < 1.0:
|
|
#tabWrite("#ifdef(unofficial) #if(unofficial = \"patch\") #if(patch(\"upov-reflection-roughness\") > 0)\n")
|
|
tabWrite("roughness %.6f\n" % \
|
|
(0.000001/raytrace_mirror.gloss_factor))
|
|
#tabWrite("#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
|
|
tabWrite("fresnel 1 ")
|
|
tabWrite("falloff %.3g exponent %.3g} " % \
|
|
(raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor))
|
|
|
|
if material.pov_subsurface_scattering.use:
|
|
subsurface_scattering = material.pov_subsurface_scattering
|
|
tabWrite("subsurface { translucency <%.3g, %.3g, %.3g> }\n" % (
|
|
(subsurface_scattering.radius[0]),
|
|
(subsurface_scattering.radius[1]),
|
|
(subsurface_scattering.radius[2]),
|
|
)
|
|
)
|
|
|
|
if material.pov.irid_enable:
|
|
tabWrite("irid { %.4g thickness %.4g turbulence %.4g }" % \
|
|
(material.pov.irid_amount, material.pov.irid_thickness,
|
|
material.pov.irid_turbulence))
|
|
|
|
else:
|
|
tabWrite("diffuse 0.8\n")
|
|
tabWrite("phong 70.0\n")
|
|
|
|
#tabWrite("specular 0.2\n")
|
|
|
|
# This is written into the object
|
|
'''
|
|
if material and material.pov.transparency_method=='RAYTRACE':
|
|
'interior { ior %.3g} ' % material.raytrace_transparency.ior
|
|
'''
|
|
|
|
#tabWrite("crand 1.0\n") # Sand granyness
|
|
#tabWrite("metallic %.6f\n" % material.spec)
|
|
#tabWrite("phong %.6f\n" % material.spec)
|
|
#tabWrite("phong_size %.6f\n" % material.spec)
|
|
#tabWrite("brilliance %.6f " % (material.pov.specular_hardness/256.0) # Like hardness
|
|
|
|
tabWrite("}\n\n")
|
|
|
|
# Level=2 Means translation of spec and mir levels for when no map influences them
|
|
povHasnoSpecularMaps(Level=2)
|
|
|
|
if material:
|
|
special_texture_found = False
|
|
idx = -1
|
|
for t in material.pov_texture_slots:
|
|
idx += 1
|
|
# index = material.pov.active_texture_index
|
|
slot = material.pov_texture_slots[idx] # [index]
|
|
povtex = slot.name
|
|
tex = bpy.data.textures[povtex]
|
|
|
|
if t and t.use and tex is not None:
|
|
|
|
|
|
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:
|
|
# Level=1 Means No specular nor Mirror reflection
|
|
povHasnoSpecularMaps(Level=1)
|
|
|
|
# Level=3 Means Maximum Spec and Mirror
|
|
povHasnoSpecularMaps(Level=3)
|
|
|
|
def exportPattern(texture, string_strip_hyphen):
|
|
"""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
|
|
PATname = "PAT_%s"%string_strip_hyphen(bpy.path.clean_name(tex.name))
|
|
mappingDif = ("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))
|
|
texStrg=""
|
|
def exportColorRamp(texture):
|
|
tex=texture
|
|
pat = tex.pov
|
|
colRampStrg="color_map {\n"
|
|
numColor=0
|
|
for el in tex.color_ramp.elements:
|
|
numColor+=1
|
|
pos = el.position
|
|
col=el.color
|
|
colR,colG,colB,colA = col[0],col[1],col[2],1-col[3]
|
|
if pat.tex_pattern_type not in {'checker', 'hexagon', 'square', 'triangular', 'brick'} :
|
|
colRampStrg+="[%.4g color rgbf<%.4g,%.4g,%.4g,%.4g>] \n"%(pos,colR,colG,colB,colA)
|
|
if pat.tex_pattern_type in {'brick','checker'} and numColor < 3:
|
|
colRampStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA)
|
|
if pat.tex_pattern_type == 'hexagon' and numColor < 4 :
|
|
colRampStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA)
|
|
if pat.tex_pattern_type == 'square' and numColor < 5 :
|
|
colRampStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA)
|
|
if pat.tex_pattern_type == 'triangular' and numColor < 7 :
|
|
colRampStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA)
|
|
|
|
colRampStrg+="} \n"
|
|
#end color map
|
|
return colRampStrg
|
|
#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':
|
|
texStrg+="pigment {\n"
|
|
####################### EMULATE BLENDER VORONOI TEXTURE ####################
|
|
if tex.type == 'VORONOI':
|
|
texStrg+="crackle\n"
|
|
texStrg+=" offset %.4g\n"%tex.nabla
|
|
texStrg+=" form <%.4g,%.4g,%.4g>\n"%(tex.weight_1, tex.weight_2, tex.weight_3)
|
|
if tex.distance_metric == 'DISTANCE':
|
|
texStrg+=" metric 2.5\n"
|
|
if tex.distance_metric == 'DISTANCE_SQUARED':
|
|
texStrg+=" metric 2.5\n"
|
|
texStrg+=" poly_wave 2\n"
|
|
if tex.distance_metric == 'MINKOVSKY':
|
|
texStrg+=" metric %s\n"%tex.minkovsky_exponent
|
|
if tex.distance_metric == 'MINKOVSKY_FOUR':
|
|
texStrg+=" metric 4\n"
|
|
if tex.distance_metric == 'MINKOVSKY_HALF':
|
|
texStrg+=" metric 0.5\n"
|
|
if tex.distance_metric == 'CHEBYCHEV':
|
|
texStrg+=" metric 10\n"
|
|
if tex.distance_metric == 'MANHATTAN':
|
|
texStrg+=" metric 1\n"
|
|
|
|
if tex.color_mode == 'POSITION':
|
|
texStrg+="solid\n"
|
|
texStrg+="scale 0.25\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<0,0,0,1>]\n"
|
|
texStrg+="[1 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="}\n"
|
|
|
|
####################### EMULATE BLENDER CLOUDS TEXTURE ####################
|
|
if tex.type == 'CLOUDS':
|
|
if tex.noise_type == 'SOFT_NOISE':
|
|
texStrg+="wrinkles\n"
|
|
texStrg+="scale 0.25\n"
|
|
else:
|
|
texStrg+="granite\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<0,0,0,1>]\n"
|
|
texStrg+="[1 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="}\n"
|
|
|
|
####################### EMULATE BLENDER WOOD TEXTURE ####################
|
|
if tex.type == 'WOOD':
|
|
if tex.wood_type == 'RINGS':
|
|
texStrg+="wood\n"
|
|
texStrg+="scale 0.25\n"
|
|
if tex.wood_type == 'RINGNOISE':
|
|
texStrg+="wood\n"
|
|
texStrg+="scale 0.25\n"
|
|
texStrg+="turbulence %.4g\n"%(tex.turbulence/100)
|
|
if tex.wood_type == 'BANDS':
|
|
texStrg+="marble\n"
|
|
texStrg+="scale 0.25\n"
|
|
texStrg+="rotate <45,-45,45>\n"
|
|
if tex.wood_type == 'BANDNOISE':
|
|
texStrg+="marble\n"
|
|
texStrg+="scale 0.25\n"
|
|
texStrg+="rotate <45,-45,45>\n"
|
|
texStrg+="turbulence %.4g\n"%(tex.turbulence/10)
|
|
|
|
if tex.noise_basis_2 == 'SIN':
|
|
texStrg+="sine_wave\n"
|
|
if tex.noise_basis_2 == 'TRI':
|
|
texStrg+="triangle_wave\n"
|
|
if tex.noise_basis_2 == 'SAW':
|
|
texStrg+="ramp_wave\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<0,0,0,0>]\n"
|
|
texStrg+="[1 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="}\n"
|
|
|
|
####################### EMULATE BLENDER STUCCI TEXTURE ####################
|
|
if tex.type == 'STUCCI':
|
|
texStrg+="bozo\n"
|
|
texStrg+="scale 0.25\n"
|
|
if tex.noise_type == 'HARD_NOISE':
|
|
texStrg+="triangle_wave\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbf<1,1,1,0>]\n"
|
|
texStrg+="[1 color rgbt<0,0,0,1>]\n"
|
|
texStrg+="}\n"
|
|
else:
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbf<0,0,0,1>]\n"
|
|
texStrg+="[1 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="}\n"
|
|
|
|
####################### EMULATE BLENDER MAGIC TEXTURE ####################
|
|
if tex.type == 'MAGIC':
|
|
texStrg+="leopard\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<1,1,1,0.5>]\n"
|
|
texStrg+="[0.25 color rgbf<0,1,0,0.75>]\n"
|
|
texStrg+="[0.5 color rgbf<0,0,1,0.75>]\n"
|
|
texStrg+="[0.75 color rgbf<1,0,1,0.75>]\n"
|
|
texStrg+="[1 color rgbf<0,1,0,0.75>]\n"
|
|
texStrg+="}\n"
|
|
texStrg+="scale 0.1\n"
|
|
|
|
####################### EMULATE BLENDER MARBLE TEXTURE ####################
|
|
if tex.type == 'MARBLE':
|
|
texStrg+="marble\n"
|
|
texStrg+="turbulence 0.5\n"
|
|
texStrg+="noise_generator 3\n"
|
|
texStrg+="scale 0.75\n"
|
|
texStrg+="rotate <45,-45,45>\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
if tex.marble_type == 'SOFT':
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<0,0,0,0>]\n"
|
|
texStrg+="[0.05 color rgbt<0,0,0,0>]\n"
|
|
texStrg+="[1 color rgbt<0.9,0.9,0.9,0>]\n"
|
|
texStrg+="}\n"
|
|
elif tex.marble_type == 'SHARP':
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<0,0,0,0>]\n"
|
|
texStrg+="[0.025 color rgbt<0,0,0,0>]\n"
|
|
texStrg+="[1 color rgbt<0.9,0.9,0.9,0>]\n"
|
|
texStrg+="}\n"
|
|
else:
|
|
texStrg+="[0 color rgbt<0,0,0,0>]\n"
|
|
texStrg+="[1 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="}\n"
|
|
if tex.noise_basis_2 == 'SIN':
|
|
texStrg+="sine_wave\n"
|
|
if tex.noise_basis_2 == 'TRI':
|
|
texStrg+="triangle_wave\n"
|
|
if tex.noise_basis_2 == 'SAW':
|
|
texStrg+="ramp_wave\n"
|
|
|
|
####################### EMULATE BLENDER BLEND TEXTURE ####################
|
|
if tex.type == 'BLEND':
|
|
if tex.progression=='RADIAL':
|
|
texStrg+="radial\n"
|
|
if tex.use_flip_axis=='HORIZONTAL':
|
|
texStrg+="rotate x*90\n"
|
|
else:
|
|
texStrg+="rotate <-90,0,90>\n"
|
|
texStrg+="ramp_wave\n"
|
|
elif tex.progression=='SPHERICAL':
|
|
texStrg+="spherical\n"
|
|
texStrg+="scale 3\n"
|
|
texStrg+="poly_wave 1\n"
|
|
elif tex.progression=='QUADRATIC_SPHERE':
|
|
texStrg+="spherical\n"
|
|
texStrg+="scale 3\n"
|
|
texStrg+=" poly_wave 2\n"
|
|
elif tex.progression=='DIAGONAL':
|
|
texStrg+="gradient <1,1,0>\n"
|
|
texStrg+="scale 3\n"
|
|
elif tex.use_flip_axis=='HORIZONTAL':
|
|
texStrg+="gradient x\n"
|
|
texStrg+="scale 2.01\n"
|
|
elif tex.use_flip_axis=='VERTICAL':
|
|
texStrg+="gradient y\n"
|
|
texStrg+="scale 2.01\n"
|
|
#texStrg+="ramp_wave\n"
|
|
#texStrg+="frequency 0.5\n"
|
|
texStrg+="phase 0.5\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="[1 color rgbf<0,0,0,1>]\n"
|
|
texStrg+="}\n"
|
|
if tex.progression == 'LINEAR':
|
|
texStrg+=" poly_wave 1\n"
|
|
if tex.progression == 'QUADRATIC':
|
|
texStrg+=" poly_wave 2\n"
|
|
if tex.progression == 'EASING':
|
|
texStrg+=" poly_wave 1.5\n"
|
|
|
|
|
|
####################### EMULATE BLENDER MUSGRAVE TEXTURE ####################
|
|
# if tex.type == 'MUSGRAVE':
|
|
# texStrg+="function{ f_ridged_mf( x, y, 0, 1, 2, 9, -0.5, 3,3 )*0.5}\n"
|
|
# texStrg+="color_map {\n"
|
|
# texStrg+="[0 color rgbf<0,0,0,1>]\n"
|
|
# texStrg+="[1 color rgbf<1,1,1,0>]\n"
|
|
# texStrg+="}\n"
|
|
# simplified for now:
|
|
|
|
if tex.type == 'MUSGRAVE':
|
|
texStrg+="bozo scale 0.25 \n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="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':
|
|
texStrg+="average\n"
|
|
texStrg+=" pigment_map {\n"
|
|
texStrg+=" [1 bozo scale 0.25 turbulence %.4g\n" %tex.distortion
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="[1 color rgbf<0,0,0,1>]\n"
|
|
texStrg+="}\n"
|
|
texStrg+="]\n"
|
|
|
|
if tex.noise_distortion == 'CELL_NOISE':
|
|
texStrg+=" [1 cells scale 0.1\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="[1 color rgbf<0,0,0,1>]\n"
|
|
texStrg+="}\n"
|
|
texStrg+="]\n"
|
|
if tex.noise_distortion=='VORONOI_CRACKLE':
|
|
texStrg+=" [1 crackle scale 0.25\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="[1 color rgbf<0,0,0,1>]\n"
|
|
texStrg+="}\n"
|
|
texStrg+="]\n"
|
|
if tex.noise_distortion in ['VORONOI_F1','VORONOI_F2','VORONOI_F3','VORONOI_F4','VORONOI_F2_F1']:
|
|
texStrg+=" [1 crackle metric 2.5 scale 0.25 turbulence %.4g\n" %(tex.distortion/2)
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="[1 color rgbf<0,0,0,1>]\n"
|
|
texStrg+="}\n"
|
|
texStrg+="]\n"
|
|
else:
|
|
texStrg+=" [1 wrinkles scale 0.25\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0 color rgbt<1,1,1,0>]\n"
|
|
texStrg+="[1 color rgbf<0,0,0,1>]\n"
|
|
texStrg+="}\n"
|
|
texStrg+="]\n"
|
|
texStrg+=" }\n"
|
|
|
|
####################### EMULATE BLENDER NOISE TEXTURE ####################
|
|
if tex.type == 'NOISE':
|
|
texStrg+="cells\n"
|
|
texStrg+="turbulence 3\n"
|
|
texStrg+="omega 3\n"
|
|
if tex.use_color_ramp == True:
|
|
texStrg+=exportColorRamp(tex)
|
|
else:
|
|
texStrg+="color_map {\n"
|
|
texStrg+="[0.75 color rgb<0,0,0,>]\n"
|
|
texStrg+="[1 color rgb<1,1,1,>]\n"
|
|
texStrg+="}\n"
|
|
|
|
####################### IGNORE OTHER BLENDER TEXTURE ####################
|
|
else: #non translated textures
|
|
pass
|
|
texStrg+="}\n\n"
|
|
|
|
texStrg+="#declare f%s=\n"%PATname
|
|
texStrg+="function{pigment{%s}}\n"%PATname
|
|
texStrg+="\n"
|
|
|
|
elif pat.tex_pattern_type != 'emulator':
|
|
texStrg+="pigment {\n"
|
|
texStrg+="%s\n"%pat.tex_pattern_type
|
|
if pat.tex_pattern_type == 'agate':
|
|
texStrg+="agate_turb %.4g\n"%pat.modifier_turbulence
|
|
if pat.tex_pattern_type in {'spiral1', 'spiral2', 'tiling'}:
|
|
texStrg+="%s\n"%pat.modifier_numbers
|
|
if pat.tex_pattern_type == 'quilted':
|
|
texStrg+="control0 %s control1 %s\n"%(pat.modifier_control0, pat.modifier_control1)
|
|
if pat.tex_pattern_type == 'mandel':
|
|
texStrg+="%s exponent %s \n"%(pat.f_iter, pat.f_exponent)
|
|
if pat.tex_pattern_type == 'julia':
|
|
texStrg+="<%.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':
|
|
texStrg+="%s mandel %s \n"%(pat.magnet_type, pat.f_iter)
|
|
if pat.tex_pattern_type == 'magnet' and pat.magnet_style == 'julia':
|
|
texStrg+="%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'}:
|
|
texStrg+="interior %s, %.4g\n"%(pat.f_ior, pat.f_ior_fac)
|
|
texStrg+="exterior %s, %.4g\n"%(pat.f_eor, pat.f_eor_fac)
|
|
if pat.tex_pattern_type == 'gradient':
|
|
texStrg+="<%s, %s, %s> \n"%(pat.grad_orient_x, pat.grad_orient_y, pat.grad_orient_z)
|
|
if pat.tex_pattern_type == 'pavement':
|
|
numTiles=pat.pave_tiles
|
|
numPattern=1
|
|
if pat.pave_sides == '4' and pat.pave_tiles == 3:
|
|
numPattern = pat.pave_pat_2
|
|
if pat.pave_sides == '6' and pat.pave_tiles == 3:
|
|
numPattern = pat.pave_pat_3
|
|
if pat.pave_sides == '3' and pat.pave_tiles == 4:
|
|
numPattern = pat.pave_pat_3
|
|
if pat.pave_sides == '3' and pat.pave_tiles == 5:
|
|
numPattern = pat.pave_pat_4
|
|
if pat.pave_sides == '4' and pat.pave_tiles == 4:
|
|
numPattern = pat.pave_pat_5
|
|
if pat.pave_sides == '6' and pat.pave_tiles == 4:
|
|
numPattern = pat.pave_pat_7
|
|
if pat.pave_sides == '4' and pat.pave_tiles == 5:
|
|
numPattern = pat.pave_pat_12
|
|
if pat.pave_sides == '3' and pat.pave_tiles == 6:
|
|
numPattern = pat.pave_pat_12
|
|
if pat.pave_sides == '6' and pat.pave_tiles == 5:
|
|
numPattern = pat.pave_pat_22
|
|
if pat.pave_sides == '4' and pat.pave_tiles == 6:
|
|
numPattern = pat.pave_pat_35
|
|
if pat.pave_sides == '6' and pat.pave_tiles == 6:
|
|
numTiles = 5
|
|
texStrg+="number_of_sides %s number_of_tiles %s pattern %s form %s \n"%(pat.pave_sides, numTiles, numPattern, pat.pave_form)
|
|
################ functions #####################################################################################################
|
|
if pat.tex_pattern_type == 'function':
|
|
texStrg+="{ %s"%pat.func_list
|
|
texStrg+="(x"
|
|
if pat.func_plus_x != "NONE":
|
|
if pat.func_plus_x =='increase':
|
|
texStrg+="*"
|
|
if pat.func_plus_x =='plus':
|
|
texStrg+="+"
|
|
texStrg+="%.4g"%pat.func_x
|
|
texStrg+=",y"
|
|
if pat.func_plus_y != "NONE":
|
|
if pat.func_plus_y =='increase':
|
|
texStrg+="*"
|
|
if pat.func_plus_y =='plus':
|
|
texStrg+="+"
|
|
texStrg+="%.4g"%pat.func_y
|
|
texStrg+=",z"
|
|
if pat.func_plus_z != "NONE":
|
|
if pat.func_plus_z =='increase':
|
|
texStrg+="*"
|
|
if pat.func_plus_z =='plus':
|
|
texStrg+="+"
|
|
texStrg+="%.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:
|
|
texStrg+=",%.4g"%pat.func_P0
|
|
if sort > 0:
|
|
texStrg+=",%.4g"%pat.func_P1
|
|
if sort > 1:
|
|
texStrg+=",%.4g"%pat.func_P2
|
|
if sort > 2:
|
|
texStrg+=",%.4g"%pat.func_P3
|
|
if sort > 3:
|
|
texStrg+=",%.4g"%pat.func_P4
|
|
if sort > 4:
|
|
texStrg+=",%.4g"%pat.func_P5
|
|
if sort > 5:
|
|
texStrg+=",%.4g"%pat.func_P6
|
|
if sort > 6:
|
|
texStrg+=",%.4g"%pat.func_P7
|
|
texStrg+=",%.4g"%pat.func_P8
|
|
texStrg+=",%.4g"%pat.func_P9
|
|
texStrg+=")}\n"
|
|
############## end functions ###############################################################
|
|
if pat.tex_pattern_type not in {'checker', 'hexagon', 'square', 'triangular', 'brick'}:
|
|
texStrg+="color_map {\n"
|
|
numColor=0
|
|
if tex.use_color_ramp == True:
|
|
for el in tex.color_ramp.elements:
|
|
numColor+=1
|
|
pos = el.position
|
|
col=el.color
|
|
colR,colG,colB,colA = col[0],col[1],col[2],1-col[3]
|
|
if pat.tex_pattern_type not in {'checker', 'hexagon', 'square', 'triangular', 'brick'} :
|
|
texStrg+="[%.4g color rgbf<%.4g,%.4g,%.4g,%.4g>] \n"%(pos,colR,colG,colB,colA)
|
|
if pat.tex_pattern_type in {'brick','checker'} and numColor < 3:
|
|
texStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA)
|
|
if pat.tex_pattern_type == 'hexagon' and numColor < 4 :
|
|
texStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA)
|
|
if pat.tex_pattern_type == 'square' and numColor < 5 :
|
|
texStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA)
|
|
if pat.tex_pattern_type == 'triangular' and numColor < 7 :
|
|
texStrg+="color rgbf<%.4g,%.4g,%.4g,%.4g> \n"%(colR,colG,colB,colA)
|
|
else:
|
|
texStrg+="[0 color rgbf<0,0,0,1>]\n"
|
|
texStrg+="[1 color rgbf<1,1,1,0>]\n"
|
|
if pat.tex_pattern_type not in {'checker', 'hexagon', 'square', 'triangular', 'brick'} :
|
|
texStrg+="} \n"
|
|
if pat.tex_pattern_type == 'brick':
|
|
texStrg+="brick_size <%.4g, %.4g, %.4g> mortar %.4g \n"%(pat.brick_size_x, pat.brick_size_y, pat.brick_size_z, pat.brick_mortar)
|
|
texStrg+="%s \n"%mappingDif
|
|
texStrg+="rotate <%.4g,%.4g,%.4g> \n"%(pat.tex_rot_x, pat.tex_rot_y, pat.tex_rot_z)
|
|
texStrg+="turbulence <%.4g,%.4g,%.4g> \n"%(pat.warp_turbulence_x, pat.warp_turbulence_y, pat.warp_turbulence_z)
|
|
texStrg+="octaves %s \n"%pat.modifier_octaves
|
|
texStrg+="lambda %.4g \n"%pat.modifier_lambda
|
|
texStrg+="omega %.4g \n"%pat.modifier_omega
|
|
texStrg+="frequency %.4g \n"%pat.modifier_frequency
|
|
texStrg+="phase %.4g \n"%pat.modifier_phase
|
|
texStrg+="}\n\n"
|
|
texStrg+="#declare f%s=\n"%PATname
|
|
texStrg+="function{pigment{%s}}\n"%PATname
|
|
texStrg+="\n"
|
|
return(texStrg)
|
|
|
|
|
|
def writeTextureInfluence(mater, materialNames, LocalMaterialNames, path_image, lampCount,
|
|
imageFormat, imgMap, imgMapTransforms, tabWrite, comments,
|
|
string_strip_hyphen, safety, col, os, preview_dir, unpacked_images):
|
|
"""Translate Blender texture influences to various POV texture tricks and write to pov file."""
|
|
|
|
material_finish = materialNames[mater.name]
|
|
if mater.pov.use_transparency:
|
|
trans = 1.0 - mater.pov.alpha
|
|
else:
|
|
trans = 0.0
|
|
if ((mater.specular_color.s == 0.0) or (mater.pov.diffuse_shader == 'MINNAERT')):
|
|
# No layered texture because of aoi pattern used for minnaert and pov can't layer patterned
|
|
colored_specular_found = False
|
|
else:
|
|
colored_specular_found = True
|
|
|
|
if mater.pov.use_transparency and mater.pov.transparency_method == 'RAYTRACE':
|
|
povFilter = mater.pov_raytrace_transparency.filter * (1.0 - mater.pov.alpha)
|
|
trans = (1.0 - mater.pov.alpha) - povFilter
|
|
else:
|
|
povFilter = 0.0
|
|
|
|
##############SF
|
|
texturesDif = ""
|
|
texturesSpec = ""
|
|
texturesNorm = ""
|
|
texturesAlpha = ""
|
|
#proceduralFlag=False
|
|
for t in mater.pov_texture_slots:
|
|
idx = -1
|
|
for t in mater.pov_texture_slots:
|
|
idx += 1
|
|
# index = mater.pov.active_texture_index
|
|
slot = mater.pov_texture_slots[idx] # [index]
|
|
povtex = slot.name
|
|
tex = bpy.data.textures[povtex]
|
|
|
|
if t and (t.use and (tex is not None)):
|
|
# 'NONE' ('NONE' type texture is different from no texture covered above)
|
|
if (tex.type == 'NONE' and tex.pov.tex_pattern_type == 'emulator'):
|
|
continue # move to next slot
|
|
# PROCEDURAL
|
|
elif (tex.type != 'IMAGE' and tex.type != 'NONE'):
|
|
proceduralFlag=True
|
|
image_filename = "PAT_%s"%string_strip_hyphen(bpy.path.clean_name(tex.name))
|
|
if image_filename:
|
|
if t.use_map_color_diffuse:
|
|
texturesDif = image_filename
|
|
# colvalue = t.default_value # UNUSED
|
|
t_dif = t
|
|
if t_dif.texture.pov.tex_gamma_enable:
|
|
imgGamma = (" gamma %.3g " % t_dif.texture.pov.tex_gamma_value)
|
|
if t.use_map_specular or t.use_map_raymir:
|
|
texturesSpec = image_filename
|
|
# colvalue = t.default_value # UNUSED
|
|
t_spec = t
|
|
if t.use_map_normal:
|
|
texturesNorm = image_filename
|
|
# colvalue = t.normal_factor/10 # UNUSED
|
|
#textNormName=tex.image.name + ".normal"
|
|
#was the above used? --MR
|
|
t_nor = t
|
|
if t.use_map_alpha:
|
|
texturesAlpha = image_filename
|
|
# colvalue = t.alpha_factor * 10.0 # UNUSED
|
|
#textDispName=tex.image.name + ".displ"
|
|
#was the above used? --MR
|
|
t_alpha = t
|
|
|
|
# RASTER IMAGE
|
|
elif (tex.type == 'IMAGE' and tex.image and tex.pov.tex_pattern_type == 'emulator'):
|
|
proceduralFlag=False
|
|
#PACKED
|
|
if tex.image.packed_file:
|
|
orig_image_filename=tex.image.filepath_raw
|
|
unpackedfilename= os.path.join(preview_dir,("unpacked_img_"+(string_strip_hyphen(bpy.path.clean_name(tex.name)))))
|
|
if not os.path.exists(unpackedfilename):
|
|
# record which images that were newly copied and can be safely
|
|
# cleaned up
|
|
unpacked_images.append(unpackedfilename)
|
|
tex.image.filepath_raw=unpackedfilename
|
|
tex.image.save()
|
|
image_filename = unpackedfilename.replace("\\","/")
|
|
# .replace("\\","/") to get only forward slashes as it's what POV prefers,
|
|
# even on windows
|
|
tex.image.filepath_raw=orig_image_filename
|
|
#FILE
|
|
else:
|
|
image_filename = path_image(tex.image)
|
|
# IMAGE SEQUENCE BEGINS
|
|
if image_filename:
|
|
if bpy.data.images[tex.image.name].source == 'SEQUENCE':
|
|
korvaa = "." + str(tex.image_user.frame_offset + 1).zfill(3) + "."
|
|
image_filename = image_filename.replace(".001.", korvaa)
|
|
print(" seq debug ")
|
|
print(image_filename)
|
|
# IMAGE SEQUENCE ENDS
|
|
imgGamma = ""
|
|
if image_filename:
|
|
if t.use_map_color_diffuse:
|
|
texturesDif = image_filename
|
|
# colvalue = t.default_value # UNUSED
|
|
t_dif = t
|
|
if t_dif.texture.pov.tex_gamma_enable:
|
|
imgGamma = (" gamma %.3g " % t_dif.texture.pov.tex_gamma_value)
|
|
if t.use_map_specular or t.use_map_raymir:
|
|
texturesSpec = image_filename
|
|
# colvalue = t.default_value # UNUSED
|
|
t_spec = t
|
|
if t.use_map_normal:
|
|
texturesNorm = image_filename
|
|
# colvalue = t.normal_factor/10 # UNUSED
|
|
#textNormName=tex.image.name + ".normal"
|
|
#was the above used? --MR
|
|
t_nor = t
|
|
if t.use_map_alpha:
|
|
texturesAlpha = image_filename
|
|
# colvalue = t.alpha_factor * 10.0 # UNUSED
|
|
#textDispName=tex.image.name + ".displ"
|
|
#was the above used? --MR
|
|
t_alpha = t
|
|
|
|
####################################################################################
|
|
|
|
|
|
tabWrite("\n")
|
|
# THIS AREA NEEDS TO LEAVE THE TEXTURE OPEN UNTIL ALL MAPS ARE WRITTEN DOWN.
|
|
# --MR
|
|
currentMatName = string_strip_hyphen(materialNames[mater.name])
|
|
LocalMaterialNames.append(currentMatName)
|
|
tabWrite("\n#declare MAT_%s = \ntexture{\n" % currentMatName)
|
|
################################################################################
|
|
|
|
if mater.pov.replacement_text != "":
|
|
tabWrite("%s\n" % mater.pov.replacement_text)
|
|
#################################################################################
|
|
if mater.pov.diffuse_shader == 'MINNAERT':
|
|
tabWrite("\n")
|
|
tabWrite("aoi\n")
|
|
tabWrite("texture_map {\n")
|
|
tabWrite("[%.3g finish {diffuse %.3g}]\n" % \
|
|
(mater.darkness / 2.0, 2.0 - mater.darkness))
|
|
tabWrite("[%.3g\n" % (1.0 - (mater.darkness / 2.0)))
|
|
|
|
if mater.pov.diffuse_shader == 'FRESNEL':
|
|
# For FRESNEL diffuse in POV, we'll layer slope patterned textures
|
|
# with lamp vector as the slope vector and nest one slope per lamp
|
|
# into each texture map's entry.
|
|
|
|
c = 1
|
|
while (c <= lampCount):
|
|
tabWrite("slope { lampTarget%s }\n" % (c))
|
|
tabWrite("texture_map {\n")
|
|
# Diffuse Fresnel value and factor go up to five,
|
|
# other kind of values needed: used the number 5 below to remap
|
|
tabWrite("[%.3g finish {diffuse %.3g}]\n" % \
|
|
((5.0 - mater.diffuse_fresnel) / 5,
|
|
(mater.diffuse_intensity *
|
|
((5.0 - mater.diffuse_fresnel_factor) / 5))))
|
|
tabWrite("[%.3g\n" % ((mater.diffuse_fresnel_factor / 5) *
|
|
(mater.diffuse_fresnel / 5.0)))
|
|
c += 1
|
|
|
|
# if shader is a 'FRESNEL' or 'MINNAERT': slope pigment pattern or aoi
|
|
# and texture map above, the rest below as one of its entry
|
|
|
|
if texturesSpec != "" or texturesAlpha != "":
|
|
if texturesSpec != "":
|
|
# tabWrite("\n")
|
|
tabWrite("pigment_pattern {\n")
|
|
|
|
mappingSpec =imgMapTransforms(t_spec)
|
|
if texturesSpec and texturesSpec.startswith("PAT_"):
|
|
tabWrite("function{f%s(x,y,z).grey}\n" %texturesSpec)
|
|
tabWrite("%s\n" % mappingSpec)
|
|
else:
|
|
|
|
tabWrite("uv_mapping image_map{%s \"%s\" %s}\n" % \
|
|
(imageFormat(texturesSpec), texturesSpec, imgMap(t_spec)))
|
|
tabWrite("%s\n" % mappingSpec)
|
|
tabWrite("}\n")
|
|
tabWrite("texture_map {\n")
|
|
tabWrite("[0 \n")
|
|
|
|
if texturesDif == "":
|
|
if texturesAlpha != "":
|
|
tabWrite("\n")
|
|
|
|
mappingAlpha = imgMapTransforms(t_alpha)
|
|
|
|
if texturesAlpha and texturesAlpha.startswith("PAT_"):
|
|
tabWrite("function{f%s(x,y,z).transmit}%s\n" %(texturesAlpha, mappingAlpha))
|
|
else:
|
|
|
|
tabWrite("pigment {pigment_pattern {uv_mapping image_map" \
|
|
"{%s \"%s\" %s}%s" % \
|
|
(imageFormat(texturesAlpha), texturesAlpha,
|
|
imgMap(t_alpha), mappingAlpha))
|
|
tabWrite("}\n")
|
|
tabWrite("pigment_map {\n")
|
|
tabWrite("[0 color rgbft<0,0,0,1,1>]\n")
|
|
tabWrite("[1 color rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>]\n" % \
|
|
(col[0], col[1], col[2], povFilter, trans))
|
|
tabWrite("}\n")
|
|
tabWrite("}\n")
|
|
|
|
else:
|
|
|
|
tabWrite("pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>}\n" % \
|
|
(col[0], col[1], col[2], povFilter, trans))
|
|
|
|
if texturesSpec != "":
|
|
# Level 1 is no specular
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=1)))
|
|
|
|
else:
|
|
# Level 2 is translated spec
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=2)))
|
|
|
|
else:
|
|
mappingDif = imgMapTransforms(t_dif)
|
|
|
|
if texturesAlpha != "":
|
|
mappingAlpha = imgMapTransforms(t_alpha)
|
|
|
|
tabWrite("pigment {\n")
|
|
tabWrite("pigment_pattern {\n")
|
|
if texturesAlpha and texturesAlpha.startswith("PAT_"):
|
|
tabWrite("function{f%s(x,y,z).transmit}%s\n" %(texturesAlpha, mappingAlpha))
|
|
else:
|
|
tabWrite("uv_mapping image_map{%s \"%s\" %s}%s}\n" % \
|
|
(imageFormat(texturesAlpha), texturesAlpha,
|
|
imgMap(t_alpha), mappingAlpha))
|
|
tabWrite("pigment_map {\n")
|
|
tabWrite("[0 color rgbft<0,0,0,1,1>]\n")
|
|
#if texturesAlpha and texturesAlpha.startswith("PAT_"):
|
|
#tabWrite("[1 pigment{%s}]\n" %texturesDif)
|
|
if texturesDif and not texturesDif.startswith("PAT_"):
|
|
tabWrite("[1 uv_mapping image_map {%s \"%s\" %s} %s]\n" % \
|
|
(imageFormat(texturesDif), texturesDif,
|
|
(imgGamma + imgMap(t_dif)), mappingDif))
|
|
elif texturesDif and texturesDif.startswith("PAT_"):
|
|
tabWrite("[1 %s]\n" %texturesDif)
|
|
tabWrite("}\n")
|
|
tabWrite("}\n")
|
|
if texturesAlpha and texturesAlpha.startswith("PAT_"):
|
|
tabWrite("}\n")
|
|
|
|
else:
|
|
if texturesDif and texturesDif.startswith("PAT_"):
|
|
tabWrite("pigment{%s}\n" %texturesDif)
|
|
else:
|
|
tabWrite("pigment {uv_mapping image_map {%s \"%s\" %s}%s}\n" % \
|
|
(imageFormat(texturesDif), texturesDif,
|
|
(imgGamma + imgMap(t_dif)), mappingDif))
|
|
|
|
if texturesSpec != "":
|
|
# Level 1 is no specular
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=1)))
|
|
|
|
else:
|
|
# Level 2 is translated specular
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=2)))
|
|
|
|
## scale 1 rotate y*0
|
|
#imageMap = ("{image_map {%s \"%s\" %s }\n" % \
|
|
# (imageFormat(textures),textures,imgMap(t_dif)))
|
|
#tabWrite("uv_mapping pigment %s} %s finish {%s}\n" % \
|
|
# (imageMap,mapping,safety(material_finish)))
|
|
#tabWrite("pigment {uv_mapping image_map {%s \"%s\" %s}%s} " \
|
|
# "finish {%s}\n" % \
|
|
# (imageFormat(texturesDif), texturesDif, imgMap(t_dif),
|
|
# mappingDif, safety(material_finish)))
|
|
if texturesNorm != "":
|
|
## scale 1 rotate y*0
|
|
|
|
mappingNor =imgMapTransforms(t_nor)
|
|
|
|
if texturesNorm and texturesNorm.startswith("PAT_"):
|
|
tabWrite("normal{function{f%s(x,y,z).grey} bump_size %.4g %s}\n" %(texturesNorm, t_nor.normal_factor, mappingNor))
|
|
else:
|
|
tabWrite("normal {uv_mapping bump_map " \
|
|
"{%s \"%s\" %s bump_size %.4g }%s}\n" % \
|
|
(imageFormat(texturesNorm), texturesNorm, imgMap(t_nor),
|
|
t_nor.normal_factor, mappingNor))
|
|
if texturesSpec != "":
|
|
tabWrite("]\n")
|
|
##################Second index for mapping specular max value###############
|
|
tabWrite("[1 \n")
|
|
|
|
if texturesDif == "" and mater.pov.replacement_text == "":
|
|
if texturesAlpha != "":
|
|
mappingAlpha = imgMapTransforms(t_alpha)
|
|
|
|
if texturesAlpha and texturesAlpha.startswith("PAT_"):
|
|
tabWrite("function{f%s(x,y,z).transmit %s}\n" %(texturesAlpha, mappingAlpha))
|
|
else:
|
|
tabWrite("pigment {pigment_pattern {uv_mapping image_map" \
|
|
"{%s \"%s\" %s}%s}\n" % \
|
|
(imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha),
|
|
mappingAlpha))
|
|
tabWrite("pigment_map {\n")
|
|
tabWrite("[0 color rgbft<0,0,0,1,1>]\n")
|
|
tabWrite("[1 color rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>]\n" % \
|
|
(col[0], col[1], col[2], povFilter, trans))
|
|
tabWrite("}\n")
|
|
tabWrite("}\n")
|
|
|
|
else:
|
|
tabWrite("pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>}\n" % \
|
|
(col[0], col[1], col[2], povFilter, trans))
|
|
|
|
|
|
if texturesSpec != "":
|
|
# Level 3 is full specular
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=3)))
|
|
|
|
elif colored_specular_found:
|
|
# Level 1 is no specular
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=1)))
|
|
|
|
else:
|
|
# Level 2 is translated specular
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=2)))
|
|
|
|
elif mater.pov.replacement_text == "":
|
|
mappingDif = imgMapTransforms(t_dif)
|
|
|
|
if texturesAlpha != "":
|
|
|
|
mappingAlpha = imgMapTransforms(t_alpha)
|
|
|
|
if texturesAlpha and texturesAlpha.startswith("PAT_"):
|
|
tabWrite("pigment{pigment_pattern {function{f%s(x,y,z).transmit}%s}\n" %(texturesAlpha, mappingAlpha))
|
|
else:
|
|
tabWrite("pigment {pigment_pattern {uv_mapping image_map" \
|
|
"{%s \"%s\" %s}%s}\n" % \
|
|
(imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha),
|
|
mappingAlpha))
|
|
tabWrite("pigment_map {\n")
|
|
tabWrite("[0 color rgbft<0,0,0,1,1>]\n")
|
|
if texturesAlpha and texturesAlpha.startswith("PAT_"):
|
|
tabWrite("[1 function{f%s(x,y,z).transmit}%s]\n" %(texturesAlpha, mappingAlpha))
|
|
elif texturesDif and not texturesDif.startswith("PAT_"):
|
|
tabWrite("[1 uv_mapping image_map {%s \"%s\" %s} %s]\n" % \
|
|
(imageFormat(texturesDif), texturesDif,
|
|
(imgMap(t_dif) + imgGamma), mappingDif))
|
|
elif texturesDif and texturesDif.startswith("PAT_"):
|
|
tabWrite("[1 %s %s]\n" %(texturesDif, mappingDif))
|
|
tabWrite("}\n")
|
|
tabWrite("}\n")
|
|
|
|
else:
|
|
if texturesDif and texturesDif.startswith("PAT_"):
|
|
tabWrite("pigment{%s %s}\n" %(texturesDif, mappingDif))
|
|
else:
|
|
tabWrite("pigment {\n")
|
|
tabWrite("uv_mapping image_map {\n")
|
|
#tabWrite("%s \"%s\" %s}%s\n" % \
|
|
# (imageFormat(texturesDif), texturesDif,
|
|
# (imgGamma + imgMap(t_dif)),mappingDif))
|
|
tabWrite("%s \"%s\" \n" % (imageFormat(texturesDif), texturesDif))
|
|
tabWrite("%s\n" % (imgGamma + imgMap(t_dif)))
|
|
tabWrite("}\n")
|
|
tabWrite("%s\n" % mappingDif)
|
|
tabWrite("}\n")
|
|
|
|
if texturesSpec != "":
|
|
# Level 3 is full specular
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=3)))
|
|
else:
|
|
# Level 2 is translated specular
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=2)))
|
|
|
|
## scale 1 rotate y*0
|
|
#imageMap = ("{image_map {%s \"%s\" %s }" % \
|
|
# (imageFormat(textures), textures,imgMap(t_dif)))
|
|
#tabWrite("\n\t\t\tuv_mapping pigment %s} %s finish {%s}" % \
|
|
# (imageMap, mapping, safety(material_finish)))
|
|
#tabWrite("\n\t\t\tpigment {uv_mapping image_map " \
|
|
# "{%s \"%s\" %s}%s} finish {%s}" % \
|
|
# (imageFormat(texturesDif), texturesDif,imgMap(t_dif),
|
|
# mappingDif, safety(material_finish)))
|
|
if texturesNorm != "" and mater.pov.replacement_text == "":
|
|
|
|
|
|
mappingNor =imgMapTransforms(t_nor)
|
|
|
|
if texturesNorm and texturesNorm.startswith("PAT_"):
|
|
tabWrite("normal{function{f%s(x,y,z).grey} bump_size %.4g %s}\n" %(texturesNorm, t_nor.normal_factor, mappingNor))
|
|
else:
|
|
tabWrite("normal {uv_mapping bump_map {%s \"%s\" %s bump_size %.4g }%s}\n" % \
|
|
(imageFormat(texturesNorm), texturesNorm, imgMap(t_nor),
|
|
t_nor.normal_factor, mappingNor))
|
|
if texturesSpec != "" and mater.pov.replacement_text == "":
|
|
tabWrite("]\n")
|
|
|
|
tabWrite("}\n")
|
|
|
|
#End of slope/ior texture_map
|
|
if mater.pov.diffuse_shader == 'MINNAERT' and mater.pov.replacement_text == "":
|
|
tabWrite("]\n")
|
|
tabWrite("}\n")
|
|
if mater.pov.diffuse_shader == 'FRESNEL' and mater.pov.replacement_text == "":
|
|
c = 1
|
|
while (c <= lampCount):
|
|
tabWrite("]\n")
|
|
tabWrite("}\n")
|
|
c += 1
|
|
|
|
|
|
|
|
# Close first layer of POV "texture" (Blender material)
|
|
tabWrite("}\n")
|
|
|
|
if ((mater.specular_color.s > 0.0) and (mater.pov.diffuse_shader != 'MINNAERT')):
|
|
|
|
colored_specular_found = True
|
|
else:
|
|
colored_specular_found = False
|
|
|
|
# Write another layered texture using invisible diffuse and metallic trick
|
|
# to emulate colored specular highlights
|
|
special_texture_found = False
|
|
idx = -1
|
|
for t in mater.pov_texture_slots:
|
|
idx += 1
|
|
# index = mater.pov.active_texture_index
|
|
slot = mater.pov_texture_slots[idx] # [index]
|
|
povtex = slot.name
|
|
tex = bpy.data.textures[povtex]
|
|
if(t and t.use and ((tex.type == 'IMAGE' and tex.image) or tex.type != 'IMAGE') and
|
|
(t.use_map_specular or t.use_map_raymir)):
|
|
# Specular mapped textures would conflict with colored specular
|
|
# because POV can't layer over or under pigment patterned textures
|
|
special_texture_found = True
|
|
|
|
if colored_specular_found and not special_texture_found:
|
|
if comments:
|
|
tabWrite(" // colored highlights with a stransparent metallic layer\n")
|
|
else:
|
|
tabWrite("\n")
|
|
|
|
tabWrite("texture {\n")
|
|
tabWrite("pigment {rgbft<%.3g, %.3g, %.3g, 0, 1>}\n" % \
|
|
(mater.specular_color[0], mater.specular_color[1], mater.specular_color[2]))
|
|
tabWrite("finish {%s}\n" % (safety(material_finish, Level=2))) # Level 2 is translated spec
|
|
|
|
texturesNorm = ""
|
|
for t in mater.pov_texture_slots:
|
|
|
|
if t and tex.pov.tex_pattern_type != 'emulator':
|
|
proceduralFlag=True
|
|
image_filename = string_strip_hyphen(bpy.path.clean_name(tex.name))
|
|
if (t and tex.type == 'IMAGE' and
|
|
t.use and tex.image and
|
|
tex.pov.tex_pattern_type == 'emulator'):
|
|
proceduralFlag=False
|
|
image_filename = path_image(tex.image)
|
|
imgGamma = ""
|
|
if image_filename:
|
|
if t.use_map_normal:
|
|
texturesNorm = image_filename
|
|
# colvalue = t.normal_factor/10 # UNUSED
|
|
#textNormName=tex.image.name + ".normal"
|
|
#was the above used? --MR
|
|
t_nor = t
|
|
if proceduralFlag:
|
|
tabWrite("normal{function" \
|
|
"{f%s(x,y,z).grey} bump_size %.4g}\n" % \
|
|
(texturesNorm,
|
|
t_nor.normal_factor))
|
|
else:
|
|
tabWrite("normal {uv_mapping bump_map " \
|
|
"{%s \"%s\" %s bump_size %.4g }%s}\n" % \
|
|
(imageFormat(texturesNorm),
|
|
texturesNorm, imgMap(t_nor),
|
|
t_nor.normal_factor,
|
|
mappingNor))
|
|
|
|
tabWrite("}\n") # THEN IT CAN CLOSE LAST LAYER OF TEXTURE
|
|
|
|
def string_strip_hyphen(name):
|
|
return name.replace("-", "")
|
|
# WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
def write_nodes(scene,povMatName,ntree,file):
|
|
"""translate Blender node trees to pov and write them to file"""
|
|
declareNodes=[]
|
|
scene=bpy.context.scene
|
|
for node in ntree.nodes:
|
|
povNodeName=string_strip_hyphen(bpy.path.clean_name(node.name))+"_%s"%povMatName
|
|
if node.bl_idname == "PovrayFinishNode" and node.outputs["Finish"].is_linked:
|
|
file.write('#declare %s = finish {\n'%povNodeName)
|
|
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 == True:
|
|
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 == True:
|
|
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)
|
|
|
|
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==True:
|
|
fresnel="fresnel"
|
|
|
|
if link.from_node.inputs["Conserve energy"].is_linked:
|
|
pass
|
|
else:
|
|
if link.from_node.inputs["Conserve energy"].default_value==True:
|
|
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:
|
|
povNodeName=string_strip_hyphen(bpy.path.clean_name(node.name))+"_%s"%povMatName
|
|
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'%(povNodeName,tx,ty,tz,rx,ry,rz,sx,sy,sz))
|
|
|
|
for node in ntree.nodes:
|
|
povNodeName=string_strip_hyphen(bpy.path.clean_name(node.name))+"_%s"%povMatName
|
|
if node.bl_idname == "PovrayColorImageNode" and node.outputs["Pigment"].is_linked:
|
|
declareNodes.append(node.name)
|
|
if node.image == "":
|
|
file.write('#declare %s = pigment { color rgb 0.8}\n'%(povNodeName))
|
|
else:
|
|
im=bpy.data.images[node.image]
|
|
if im.filepath and os.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:
|
|
povTransName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
transform="transform {%s}"%povTransName
|
|
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'%(povNodeName,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:
|
|
povNodeName=string_strip_hyphen(bpy.path.clean_name(node.name))+"_%s"%povMatName
|
|
if node.bl_idname == "PovrayImagePatternNode" and node.outputs["Pattern"].is_linked:
|
|
declareNodes.append(node.name)
|
|
if node.image != "":
|
|
im=bpy.data.images[node.image]
|
|
if im.filepath and os.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:
|
|
povTransName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
transform="transform {%s}"%povTransName
|
|
uv=""
|
|
if node.map_type=="uv_mapping":
|
|
uv="uv_mapping"
|
|
filepath=bpy.path.abspath(im.filepath)
|
|
file.write('#macro %s() %s image_pattern {\n'%(povNodeName,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:
|
|
povNodeName=string_strip_hyphen(bpy.path.clean_name(node.name))+"_%s"%povMatName
|
|
if node.bl_idname == "PovrayBumpMapNode" and node.outputs["Normal"].is_linked:
|
|
if node.image != "":
|
|
im=bpy.data.images[node.image]
|
|
if im.filepath and os.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:
|
|
povTransName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
transform="transform {%s}"%povTransName
|
|
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'%(povNodeName,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')
|
|
declareNodes.append(node.name)
|
|
|
|
|
|
|
|
for node in ntree.nodes:
|
|
povNodeName=string_strip_hyphen(bpy.path.clean_name(node.name))+"_%s"%povMatName
|
|
if node.bl_idname == "PovrayPigmentNode" and node.outputs["Pigment"].is_linked:
|
|
declareNodes.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'%(povNodeName,r,g,b,f,t))
|
|
|
|
|
|
for node in ntree.nodes:
|
|
povNodeName=string_strip_hyphen(bpy.path.clean_name(node.name))+"_%s"%povMatName
|
|
if node.bl_idname == "PovrayTextureNode" and node.outputs["Texture"].is_linked:
|
|
declareNodes.append(node.name)
|
|
r,g,b=node.inputs["Pigment"].default_value[:]
|
|
povColName="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":
|
|
povColName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
file.write('#declare %s = texture{\n pigment{%s}\n'%(povNodeName,povColName))
|
|
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 declareNodes:
|
|
povNorName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
file.write(' normal{%s}\n'%povNorName)
|
|
if node.inputs["Finish"].is_linked:
|
|
for link in ntree.links:
|
|
if link.to_node==node and link.to_socket.name=="Finish":
|
|
povFinName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
file.write(' finish{%s}\n'%povFinName)
|
|
file.write('}\n')
|
|
declareNodes.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 declareNodes):
|
|
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 declareNodes:
|
|
declare=False
|
|
if declare:
|
|
povNodeName=string_strip_hyphen(bpy.path.clean_name(node.name))+"_%s"%povMatName
|
|
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'%(povNodeName,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':
|
|
povMacroName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
pattern = "%s()"%povMacroName
|
|
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':
|
|
povTransName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
transform="transform {%s}"%povTransName
|
|
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
|
|
povInMatName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s_%s"%(n,povMatName)
|
|
default=True
|
|
for ilink in ntree.links:
|
|
if ilink.to_node==node and ilink.to_socket.name == str(n):
|
|
default=False
|
|
povInMatName=string_strip_hyphen(bpy.path.clean_name(ilink.from_node.name))+"_%s"%povMatName
|
|
if default:
|
|
r,g,b,a=el.color[:]
|
|
file.write(' #declare %s = texture{pigment{color srgbt <%.4g,%.4g,%.4g,%.4g>}};\n'%(povInMatName,r,g,b,1-a))
|
|
file.write(' [%s %s]\n'%(el.position,povInMatName))
|
|
else:
|
|
els=[[0,0,0,0],[1,1,1,1]]
|
|
for i in range(0,2):
|
|
povInMatName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s_%s"%(i,povMatName)
|
|
default=True
|
|
for ilink in ntree.links:
|
|
if ilink.to_node==node and ilink.to_socket.name == str(i):
|
|
default=False
|
|
povInMatName=string_strip_hyphen(bpy.path.clean_name(ilink.from_node.name))+"_%s"%povMatName
|
|
if default:
|
|
r,g,b=els[i][1],els[i][2],els[i][3]
|
|
if pattern not in {'checker', 'hexagon', 'square', 'triangular', 'brick'}:
|
|
file.write(' #declare %s = texture{pigment{color rgb <%.4g,%.4g,%.4g>}};\n'%(povInMatName,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[i][0],povInMatName))
|
|
else:
|
|
if default==False:
|
|
file.write(' texture{%s}\n'%povInMatName)
|
|
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')
|
|
declareNodes.append(node.name)
|
|
|
|
for link in ntree.links:
|
|
if link.to_node.bl_idname == "PovrayOutputNode" and link.from_node.name in declareNodes:
|
|
povMatNodeName=string_strip_hyphen(bpy.path.clean_name(link.from_node.name))+"_%s"%povMatName
|
|
file.write('#declare %s = %s\n'%(povMatName,povMatNodeName))
|