Skip to content
Snippets Groups Projects
Commit c3828e7d authored by Maurice Raybaud's avatar Maurice Raybaud
Browse files

first commit ever!

parent 52551aa2
No related branches found
No related tags found
No related merge requests found
...@@ -17,31 +17,30 @@ ...@@ -17,31 +17,30 @@
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
bl_addon_info = { bl_addon_info = {
"name": "PovRay", "name": "PovRay 3.7",
"author": "Campbell Barton", "author": "Campbell Barton, Silvio Falcinelli, Maurice Raybaud",
"version": (0,1), "version": (0, 0, 3),
"blender": (2, 5, 4), "blender": (2, 5, 4),
"api": 31667, "api": 31667,
"location": "Info Header (engine dropdown)", "location": "Info Header (engine dropdown)",
"description": "Basic povray integration for blender", "description": "Basic povray 3.7 integration for blender",
"warning": "", "warning": "both povray 3.7 and this script are beta",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
"Scripts/Render/PovRay", "Scripts/Render/PovRay",
"tracker_url": "https://projects.blender.org/tracker/index.php?"\ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
"func=detail&aid=23145&group_id=153&atid=469", "func=detail&atid=468&aid=22717&group_id=153",
"category": "Render"} "category": "Render"}
if "bpy" in locals(): if "bpy" in locals():
reload(render)
reload(ui) reload(ui)
reload(render)
else: else:
import bpy import bpy
from bpy.props import * from bpy.props import *
from render_povray import render from render_povray_37 import ui
from render_povray import ui from render_povray_37 import render
def register(): def register():
Scene = bpy.types.Scene Scene = bpy.types.Scene
...@@ -106,11 +105,88 @@ def register(): ...@@ -106,11 +105,88 @@ def register():
name="Recursion Limit", description="how many recursion levels are used to calculate the diffuse inter-reflection", name="Recursion Limit", description="how many recursion levels are used to calculate the diffuse inter-reflection",
min=1, max=20, default=3) min=1, max=20, default=3)
########################################MR######################################
Mat = bpy.types.Material
Mat.pov_irid_enable = BoolProperty(
name="Enable Iridescence",
description="Newton's thin film interference (like an oil slick on a puddle of water or the rainbow hues of a soap bubble.)",
default=False)
Mat.pov_mirror_use_IOR = BoolProperty(
name="Correct Reflection",
description="Use same IOR as raytrace transparency to calculate mirror reflections. More physically correct",
default=False)
Mat.pov_mirror_metallic = BoolProperty(
name="Metallic Reflection",
description="mirror reflections get colored as diffuse (for metallic materials)",
default=False)
Mat.pov_conserve_energy = BoolProperty(
name="Conserve Energy",
description="Light transmitted is more correctly reduced by mirror reflections, also the sum of diffuse and translucency gets reduced below one ",
default=True)
Mat.pov_irid_amount = FloatProperty(
name="amount",
description="Contribution of the iridescence effect to the overall surface color. As a rule of thumb keep to around 0.25 (25% contribution) or less, but experiment. If the surface is coming out too white, try lowering the diffuse and possibly the ambient values of the surface.",
min=0.0, max=1.0, soft_min=0.01, soft_max=1.0, default=0.25)
Mat.pov_irid_thickness = FloatProperty(
name="thickness",
description="A very thin film will have a high frequency of color changes while a thick film will have large areas of color.",
min=0.0, max=1000.0, soft_min=0.1, soft_max=10.0, default=1)
Mat.pov_irid_turbulence = FloatProperty(
name="turbulence",
description="This parameter varies the thickness.",
min=0.0, max=10.0, soft_min=0.000, soft_max=1.0, default=0)
Mat.pov_caustics_enable = BoolProperty(
name="Caustics",
description="use only fake refractive caustics (default) or photon based reflective/refractive caustics",
default=True)
Mat.pov_fake_caustics = BoolProperty(
name="Fake Caustics",
description="use only (Fast) fake refractive caustics",
default=True)
Mat.pov_fake_caustics_power = FloatProperty(
name="Fake caustics power",
description="Values typically range from 0.0 to 1.0 or higher. Zero is no caustics. Low, non-zero values give broad hot-spots while higher values give tighter, smaller simulated focal points",
min=0.00, max=10.0, soft_min=0.00, soft_max=1.10, default=0.1)
Mat.pov_photons_refraction = BoolProperty(
name="Refractive Photon Caustics",
description="more physically correct",
default=False)
Mat.pov_photons_dispersion = FloatProperty(
name="chromatic dispersion",
description="Light passing through will be separated according to wavelength. This ratio of refractive indices for violet to red controls how much the colors are spread out 1 = no dispersion, good values are 1.01 to 1.1",
min=1.00, max=10.0, soft_min=1.00, soft_max=1.10, default=1.00)
Mat.pov_photons_reflection = BoolProperty(
name="Reflective Photon Caustics",
description="Use this to make your Sauron's ring ;-P",
default=False)
Mat.pov_refraction_type = EnumProperty(
items=[("0","None","use only reflective caustics"),
("1","Fake Caustics","use fake caustics"),
("2","Photons Caustics","use photons for refractive caustics"),
],
name="Refractive",
description="use fake caustics (fast) or true photons for refractive Caustics",
default="1")#ui.py has to be loaded before render.py with this.
######################################EndMR#####################################
def unregister(): def unregister():
import bpy import bpy
Scene = bpy.types.Scene Scene = bpy.types.Scene
Mat = bpy.types.Material#MR
del Scene.pov_radio_enable del Scene.pov_radio_enable
del Scene.pov_radio_display_advanced del Scene.pov_radio_display_advanced
del Scene.pov_radio_adc_bailout del Scene.pov_radio_adc_bailout
...@@ -125,7 +201,20 @@ def unregister(): ...@@ -125,7 +201,20 @@ def unregister():
del Scene.pov_radio_nearest_count del Scene.pov_radio_nearest_count
del Scene.pov_radio_normal del Scene.pov_radio_normal
del Scene.pov_radio_recursion_limit del Scene.pov_radio_recursion_limit
del Mat.pov_irid_enable#MR
del Mat.pov_mirror_use_IOR#MR
del Mat.pov_mirror_metallic#MR
del Mat.pov_conserve_energy#MR
del Mat.pov_irid_amount#MR
del Mat.pov_irid_thickness#MR
del Mat.pov_irid_turbulence#MR
del Mat.pov_caustics_enable#MR
del Mat.pov_fake_caustics#MR
del Mat.pov_fake_caustics_power#MR
del Mat.pov_photons_refraction#MR
del Mat.pov_photons_dispersion#MR
del Mat.pov_photons_reflection#MR
del Mat.pov_refraction_type#MR
if __name__ == "__main__": if __name__ == "__main__":
register() register()
...@@ -22,6 +22,7 @@ import os ...@@ -22,6 +22,7 @@ import os
import sys import sys
import time import time
import math import math
from math import atan, pi, degrees, sqrt
import platform as pltfrm import platform as pltfrm
if pltfrm.architecture()[0] == '64bit': if pltfrm.architecture()[0] == '64bit':
...@@ -29,6 +30,119 @@ if pltfrm.architecture()[0] == '64bit': ...@@ -29,6 +30,119 @@ if pltfrm.architecture()[0] == '64bit':
else: else:
bitness = 32 bitness = 32
##############################SF###########################
##############find image texture
def splitExt(path):
dotidx = path.rfind('.')
if dotidx == -1:
return path, ''
else:
return (path[dotidx:]).upper().replace('.','')
def imageFormat(imgF):
ext = ""
ext_orig = splitExt(imgF)
if ext_orig == 'JPG' or ext_orig == 'JPEG': ext='jpeg'
if ext_orig == 'GIF': ext = 'gif'
if ext_orig == 'TGA': ext = 'tga'
if ext_orig == 'IFF': ext = 'iff'
if ext_orig == 'PPM': ext = 'ppm'
if ext_orig == 'PNG': ext = 'png'
if ext_orig == 'SYS': ext = 'sys'
if ext_orig in ('TIFF', 'TIF'): ext = 'tiff'
if ext_orig == 'EXR': ext = 'exr'#POV3.7 Only!
if ext_orig == 'HDR': ext = 'hdr'#POV3.7 Only! --MR
print(imgF)
if not ext: print(' WARNING: texture image format not supported ') # % (imgF , '')) #(ext_orig)))
return ext
def imgMap(ts):
image_map=''
if ts.mapping=='FLAT':image_map= ' map_type 0 '
if ts.mapping=='SPHERE':image_map= ' map_type 1 '# map_type 7 in megapov
if ts.mapping=='TUBE':image_map= ' map_type 2 '
#if ts.mapping=='?':image_map= ' map_type 3 '# map_type 3 and 4 in development (?) for Povray, currently they just seem to default back to Flat (type 0)
#if ts.mapping=='?':image_map= ' map_type 4 '# map_type 3 and 4 in development (?) for Povray, currently they just seem to default back to Flat (type 0)
if ts.texture.use_interpolation: image_map+= " interpolate 2 "
if ts.texture.extension == 'CLIP': image_map+=' once '
#image_map+='}'
#if ts.mapping=='CUBE':image_map+= 'warp { cubic } rotate <-90,0,180>' #no direct cube type mapping. Though this should work in POV 3.7 it doesn't give that good results(best suited to environment maps?)
#if image_map=='': print(' No texture image found ')
return image_map
def imgMapBG(wts):
image_mapBG=''
if wts.texture_coords== 'VIEW':image_mapBG= ' map_type 0 ' #texture_coords refers to the mapping of world textures
if wts.texture_coords=='ANGMAP':image_mapBG= ' map_type 1 '
if wts.texture_coords=='TUBE':image_mapBG= ' map_type 2 '
if wts.texture.use_interpolation: image_mapBG+= " interpolate 2 "
if wts.texture.extension == 'CLIP': image_mapBG+=' once '
#image_mapBG+='}'
#if wts.mapping=='CUBE':image_mapBG+= 'warp { cubic } rotate <-90,0,180>' #no direct cube type mapping. Though this should work in POV 3.7 it doesn't give that good results(best suited to environment maps?)
#if image_mapBG=='': print(' No background texture image found ')
return image_mapBG
def splitFile(path):
idx = path.rfind('/')
if idx == -1:
idx = path.rfind('\\')
return path[idx:].replace("/", "").replace("\\", "")
def splitPath(path):
idx = path.rfind('/')
if idx == -1:
return path, ''
else:
return path[:idx]
def findInSubDir(filename, subdirectory=''):
pahFile=''
if subdirectory:
path = subdirectory
else:
path = os.getcwd()
try:
for root, dirs, names in os.walk(path):
if filename in names:
pahFile = os.path.join(root, filename)
return pahFile
except: return ''
def path_image(image):
import os
fn = bpy.path.abspath(image)
fn_strip = os.path.basename(fn)
if not os.path.isfile(fn):
fn=(findInSubDir(splitFile(fn),splitPath(bpy.data.filepath)))
()
return fn
##############end find image texture
##############safety string name material
def safety(name):
try:
if int(name) > 0: prefix='shader'
except: prefix=''
prefix='shader_'
return prefix+name
def safety0(name): #used for 0 of specular map
try:
if int(name) > 0: prefix='shader'
except: prefix=''
prefix='shader_'
return prefix+name+'0'
def safety1(name): #used for 1 of specular map
try:
if int(name) > 0: prefix='shader'
except: prefix=''
prefix='shader_'
return prefix+name+'1'
##############end safety string name material
##############################EndSF###########################
def write_pov(filename, scene=None, info_callback=None): def write_pov(filename, scene=None, info_callback=None):
file = open(filename, 'w') file = open(filename, 'w')
...@@ -58,17 +172,46 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -58,17 +172,46 @@ def write_pov(filename, scene=None, info_callback=None):
(matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], matrix[3][1], matrix[3][2])) (matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], matrix[3][1], matrix[3][2]))
def writeObjectMaterial(material): def writeObjectMaterial(material):
if material and material.transparency_method == 'RAYTRACE': if material: #and material.transparency_method == 'RAYTRACE':#Commented out: always write IOR to be able to use it for SSS, Fresnel reflections...
file.write('\tinterior { ior %.6f }\n' % material.raytrace_transparency.ior) #But there can be only one!
if material.subsurface_scattering.use:#SSS IOR get highest priority
file.write('\tinterior { ior %.6f\n' % material.subsurface_scattering.ior)
elif material.pov_mirror_use_IOR:#Then the raytrace IOR taken from raytrace transparency properties and used for reflections if IOR Mirror option is checked
file.write('\tinterior { ior %.6f\n' % material.raytrace_transparency.ior)
else:
file.write('\tinterior { ior %.6f\n' % material.raytrace_transparency.ior)
#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 material.pov_fake_caustics:
file.write('\tcaustics %.3g\n' % material.pov_fake_caustics_power)
#material.pov_photons_refraction=0
if material.pov_photons_refraction:
material.pov_fake_caustics=0 #How to deactivate fake caustics when refr photons on?
file.write('\tdispersion %.3g\n' % material.pov_photons_dispersion) #Default of 1 means no dispersion
#bpy.types.MATERIAL_PT_povray_caustics.Display = 1 - bpy.types.MATERIAL_PT_povray_caustics.Display
#mat = context.material
# Other interior args # Other interior args
# fade_distance 2 # fade_distance 2
# fade_power [Value] # fade_power [Value]
# fade_color # fade_color
# dispersion # (variable) dispersion_samples (constant count for now)
# dispersion_samples file.write('\t}\n')
if material.pov_photons_refraction or material.pov_photons_reflection:
file.write('\tphotons{\n')
file.write('\t\ttarget\n')
if material.pov_photons_refraction:
file.write('\t\trefraction on\n')
if material.pov_photons_reflection:
file.write('\t\treflection on\n')
file.write('\t}\n')
materialNames = {} materialNames = {}
DEF_MAT_NAME = 'Default' DEF_MAT_NAME = 'Default'
...@@ -82,23 +225,159 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -82,23 +225,159 @@ def write_pov(filename, scene=None, info_callback=None):
name = materialNames[name_orig] = uniqueName(bpy.path.clean_name(name_orig), materialNames) name = materialNames[name_orig] = uniqueName(bpy.path.clean_name(name_orig), materialNames)
file.write('#declare %s = finish {\n' % name) file.write('#declare %s = finish {\n' % safety0(name))
if material: if material:
file.write('\tdiffuse %.3g\n' % material.diffuse_intensity)
file.write('\tspecular %.3g\n' % material.specular_intensity)
file.write('\tambient %.3g\n' % material.ambient) #Povray 3.7 now uses two diffuse values respectively for front and back shading (the back diffuse is like blender translucency)
#file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple(c*material.ambient for c in world.ambient_color)) # povray blends the global value frontDiffuse=material.diffuse_intensity
backDiffuse=material.translucency
if material.pov_conserve_energy:
#Total should not go above one
if (frontDiffuse + backDiffuse) <= 1.0:
pass
elif frontDiffuse==backDiffuse:
frontDiffuse = backDiffuse = 0.5 # Try to respect the user's "intention" by comparing the two values but bringing the total back to one
elif frontDiffuse>backDiffuse: # Let the highest value stay the highest value
backDiffuse = 1-(1-frontDiffuse)
else:
frontDiffuse = 1-(1-backDiffuse)
# map hardness between 0.0 and 1.0 # map hardness between 0.0 and 1.0
roughness = ((1.0 - ((material.specular_hardness - 1.0) / 510.0))) roughness = ((1.0 - ((material.specular_hardness - 1.0) / 510.0)))
# scale from 0.0 to 0.1 ## scale from 0.0 to 0.1
roughness *= 0.1 roughness *= 0.1
# add a small value because 0.0 is invalid # add a small value because 0.0 is invalid
roughness += (1 / 511.0) roughness += (1 / 511.0)
file.write('\troughness %.3g\n' % roughness) #####################################Diffuse Shader######################################
if material.diffuse_shader == 'OREN_NAYAR':
file.write('\tbrilliance %.3g\n' % (0.9+material.roughness))#blender roughness is what is generally called oren nayar Sigma, and brilliance in povray
if material.diffuse_shader == 'TOON':
file.write('\tbrilliance %.3g\n' % (0.01+material.diffuse_toon_smooth*0.25))
frontDiffuse*=0.5 #Lower diffuse and increase specular for toon effect seems to look better in povray
if material.diffuse_shader == 'MINNAERT':
#file.write('\taoi %.3g\n' % material.darkness) #not real syntax, aoi is a pattern.
pass # Have to put this in texture since AOI and slope map are patterns
if material.diffuse_shader == 'FRESNEL':
#file.write('\taoi %.3g\n' % material.diffuse_fresnel_factor) #not real syntax, aoi is a pattern.
pass # Have to put this in texture since AOI and slope map are patterns
if material.diffuse_shader == 'LAMBERT':
file.write('\tbrilliance 1.8\n') #trying to best match lambert attenuation by that constant brilliance value
#########################################################################################
file.write('\tdiffuse %.3g %.3g\n' % (frontDiffuse, backDiffuse))
file.write('\tspecular 0\n')
file.write('\tambient %.3g\n' % material.ambient)
#file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple([c*material.ambient for c in world.ambient_color])) # povray blends the global value
file.write('\temission %.3g\n' % material.emit) #New in povray 3.7
if material.pov_conserve_energy:
file.write('\tconserve_energy\n')#added for more realistic shading. Needs some checking to see if it really works. --Maurice.
# 'phong 70.0 '
if material.subsurface_scattering.use:
subsurface_scattering = material.subsurface_scattering
file.write('\tsubsurface { <%.3g, %.3g, %.3g>, <%.3g, %.3g, %.3g> }\n' % (sqrt(subsurface_scattering.radius[0])*1.5, sqrt(subsurface_scattering.radius[1])*1.5, sqrt(subsurface_scattering.radius[2])*1.5, 1-subsurface_scattering.color[0], 1-subsurface_scattering.color[1], 1-subsurface_scattering.color[2]))
if material.pov_irid_enable:
file.write('\tirid { %.4g thickness %.4g turbulence %.4g }' % (material.pov_irid_amount, material.pov_irid_thickness, material.pov_irid_turbulence))
file.write('}\n')
##################Plain version of the finish (previous ones are variations for specular/Mirror texture channel map with alternative finish of 0 specular and no mirror reflection###
file.write('#declare %s = finish {\n' % safety(name))
if material:
#Povray 3.7 now uses two diffuse values respectively for front and back shading (the back diffuse is like blender translucency)
frontDiffuse=material.diffuse_intensity
backDiffuse=material.translucency
if material.pov_conserve_energy:
#Total should not go above one
if (frontDiffuse + backDiffuse) <= 1.0:
pass
elif frontDiffuse==backDiffuse:
frontDiffuse = backDiffuse = 0.5 # Try to respect the user's "intention" by comparing the two values but bringing the total back to one
elif frontDiffuse>backDiffuse: # Let the highest value stay the highest value
backDiffuse = 1-(1-frontDiffuse)
else:
frontDiffuse = 1-(1-backDiffuse)
# map hardness between 0.0 and 1.0
roughness = ((1.0 - ((material.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 / 511.0)
#####################################Diffuse Shader######################################
if material.diffuse_shader == 'OREN_NAYAR':
file.write('\tbrilliance %.3g\n' % (0.9+material.roughness))#blender roughness is what is generally called oren nayar Sigma, and brilliance in povray
if material.diffuse_shader == 'TOON':
file.write('\tbrilliance %.3g\n' % (0.01+material.diffuse_toon_smooth*0.25))
frontDiffuse*=0.5 #Lower diffuse and increase specular for toon effect seems to look better in povray
if material.diffuse_shader == 'MINNAERT':
#file.write('\taoi %.3g\n' % material.darkness)
pass #let's keep things simple for now
if material.diffuse_shader == 'FRESNEL':
#file.write('\taoi %.3g\n' % material.diffuse_fresnel_factor)
pass #let's keep things simple for now
if material.diffuse_shader == 'LAMBERT':
file.write('\tbrilliance 1.8\n') #trying to best match lambert attenuation by that constant brilliance value
####################################Specular Shader######################################
if material.specular_shader == 'COOKTORR' or material.specular_shader == 'PHONG':#No difference between phong and cook torrence in blender HaHa!
file.write('\tphong %.3g\n' % (material.specular_intensity))
file.write('\tphong_size %.3g\n'% (material.specular_hardness / 2 + 0.25))
if material.specular_shader == 'BLINN':#Povray "specular" keyword corresponds to a Blinn model, without the ior.
file.write('\tspecular %.3g\n' % (material.specular_intensity * (material.specular_ior/4))) #Use blender Blinn's IOR just as some factor for spec intensity
file.write('\troughness %.3g\n' % roughness)
#Could use brilliance 2(or varying around 2 depending on ior or factor) too.
if material.specular_shader == 'TOON':
file.write('\tphong %.3g\n' % (material.specular_intensity * 2))
file.write('\tphong_size %.3g\n' % (0.1+material.specular_toon_smooth / 2)) #use extreme phong_size
if material.specular_shader == 'WARDISO':
file.write('\tspecular %.3g\n' % (material.specular_intensity / (material.specular_slope+0.0005))) #find best suited default constant for brilliance Use both phong and specular for some values.
file.write('\troughness %.4g\n' % (0.0005+material.specular_slope/10)) #find best suited default constant for brilliance Use both phong and specular for some values.
file.write('\tbrilliance %.4g\n' % (1.8-material.specular_slope*1.8)) #find best suited default constant for brilliance Use both phong and specular for some values.
#########################################################################################
file.write('\tdiffuse %.3g %.3g\n' % (frontDiffuse, backDiffuse))
file.write('\tambient %.3g\n' % material.ambient)
#file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple([c*material.ambient for c in world.ambient_color])) # povray blends the global value
file.write('\temission %.3g\n' % material.emit) #New in povray 3.7
#file.write('\troughness %.3g\n' % roughness) #povray just ignores roughness if there's no specular keyword
if material.pov_conserve_energy:
file.write('\tconserve_energy\n')#added for more realistic shading. Needs some checking to see if it really works. --Maurice.
# 'phong 70.0 ' # 'phong 70.0 '
...@@ -107,11 +386,111 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -107,11 +386,111 @@ def write_pov(filename, scene=None, info_callback=None):
if raytrace_mirror.reflect_factor: if raytrace_mirror.reflect_factor:
file.write('\treflection {\n') file.write('\treflection {\n')
file.write('\t\trgb <%.3g, %.3g, %.3g>' % tuple(material.mirror_color)) file.write('\t\trgb <%.3g, %.3g, %.3g>' % tuple(material.mirror_color))
file.write('\t\tfresnel 1 falloff %.3g exponent %.3g metallic %.3g} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor, raytrace_mirror.reflect_factor)) if material.pov_mirror_metallic:
file.write('\t\tmetallic %.3g' % (raytrace_mirror.reflect_factor))
if material.pov_mirror_use_IOR: #WORKING ?
file.write('\t\tfresnel 1 ')#Removed from the line below: gives a more physically correct material but needs proper IOR. --Maurice
file.write('\t\tfalloff %.3g exponent %.3g} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor))
if material.subsurface_scattering.use:
subsurface_scattering = material.subsurface_scattering
file.write('\tsubsurface { <%.3g, %.3g, %.3g>, <%.3g, %.3g, %.3g> }\n' % (sqrt(subsurface_scattering.radius[0])*1.5, sqrt(subsurface_scattering.radius[1])*1.5, sqrt(subsurface_scattering.radius[2])*1.5, 1-subsurface_scattering.color[0], 1-subsurface_scattering.color[1], 1-subsurface_scattering.color[2]))
if material.pov_irid_enable:
file.write('\tirid { %.4g thickness %.4g turbulence %.4g }' % (material.pov_irid_amount, material.pov_irid_thickness, material.pov_irid_turbulence))
file.write('}\n')
##################Full specular version of the finish an increased roughness seems necessary here to perceive anything###
file.write('#declare %s = finish {\n' % safety1(name))
if material:
#Povray 3.7 now uses two diffuse values respectively for front and back shading (the back diffuse is like blender translucency)
frontDiffuse=material.diffuse_intensity
backDiffuse=material.translucency
if material.pov_conserve_energy:
#Total should not go above one
if (frontDiffuse + backDiffuse) <= 1.0:
pass
elif frontDiffuse==backDiffuse:
frontDiffuse = backDiffuse = 0.5 # Try to respect the user's "intention" by comparing the two values but bringing the total back to one
elif frontDiffuse>backDiffuse: # Let the highest value stay the highest value
backDiffuse = 1-(1-frontDiffuse)
else:
frontDiffuse = 1-(1-backDiffuse)
# map hardness between 0.0 and 1.0
roughness = ((1.0 - ((material.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 / 511.0)
####################################Specular Shader######################################
if material.specular_shader == 'COOKTORR' or material.specular_shader == 'PHONG':#No difference between phong and cook torrence in blender HaHa!
file.write('\tphong %.3g\n' % (material.specular_intensity*3))#Multiplied for max value of Textured Spec.
file.write('\tphong_size %.3g\n'% (material.specular_hardness /100 + 0.0005)) # /2-->/500; 0.25-->0.0025 Larger highlight for max value of Textured Spec.
if material.specular_shader == 'BLINN':#Povray "specular" keyword corresponds to a Blinn model, hmhmmmm...
file.write('\tspecular %.3g\n' % (material.specular_intensity * 5)) #Multiplied for max value of Textured Spec.
file.write('\troughness %.3g\n' % (roughness*10)) #Multiplied for max value of Textured Spec.
if material.specular_shader == 'TOON':
file.write('\tphong %.3g\n' % (material.specular_intensity*3))#Multiplied for max value of Textured Spec.
file.write('\tphong_size %.3g\n' % (0.1+material.specular_toon_smooth / 10)) #use extreme phong_size
if material.specular_shader == 'WARDISO':
file.write('\tspecular %.3g\n' % (material.specular_intensity / (material.specular_slope+0.0005))) #find best suited default constant for brilliance Use both phong and specular for some values.
file.write('\troughness %.4g\n' % (0.0005+material.specular_slope*5)) #Multiplied for max value of Textured Spec.
file.write('\tbrilliance %.4g\n' % (1.8-material.specular_slope*1.8)) #find best suited default constant for brilliance Use both phong and specular for some values.
#########################################################################################
file.write('\tdiffuse %.3g %.3g\n' % (frontDiffuse, backDiffuse))
file.write('\tambient %.3g\n' % material.ambient)
#file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple([c*material.ambient for c in world.ambient_color])) # povray blends the global value
file.write('\temission %.3g\n' % material.emit) #New in povray 3.7
if material.pov_conserve_energy:
file.write('\tconserve_energy\n')#added for more realistic shading. Needs some checking to see if it really works. --Maurice.
# 'phong 70.0 '
if material.raytrace_mirror.use:
raytrace_mirror = material.raytrace_mirror
if raytrace_mirror.reflect_factor:
file.write('\treflection {\n')
file.write('\t\trgb <%.3g, %.3g, %.3g>' % tuple(material.mirror_color))
if material.pov_mirror_metallic:
file.write('\t\tmetallic %.3g' % (raytrace_mirror.reflect_factor))
if material.pov_mirror_use_IOR: #WORKING ?
file.write('\t\tfresnel 1 ')#Removed from the line below: gives a more physically correct material but needs proper IOR. --Maurice
file.write('\t\tfalloff %.3g exponent %.3g} ' % (raytrace_mirror.fresnel, raytrace_mirror.fresnel_factor))
if material.subsurface_scattering.use:
subsurface_scattering = material.subsurface_scattering
file.write('\tsubsurface { <%.3g, %.3g, %.3g>, <%.3g, %.3g, %.3g> }\n' % (sqrt(subsurface_scattering.radius[0])*1.5, sqrt(subsurface_scattering.radius[1])*1.5, sqrt(subsurface_scattering.radius[2])*1.5, 1-subsurface_scattering.color[0], 1-subsurface_scattering.color[1], 1-subsurface_scattering.color[2]))
##sqrt(subsurface_scattering.radius[1] above is just some non linear relation to keep "proportions" between blender presets values and povray. The following paper has samples of sigma numbers we can put directly into pov to get good results:
##http://graphics.stanford.edu/papers/bssrdf/bssrdf.pdf
##Whereas Blender probably uses That:
##http://graphics.stanford.edu/papers/fast_bssrdf/fast_bssrdf.pdf
if material.pov_irid_enable:
file.write('\tirid { %.4g thickness %.4g turbulence %.4g }' % (material.pov_irid_amount, material.pov_irid_thickness, material.pov_irid_turbulence))
else: else:
file.write('\tdiffuse 0.8\n') file.write('\tdiffuse 0.8\n')
file.write('\tspecular 0.2\n') file.write('\tphong 70.0\n')
#file.write('\tspecular 0.2\n')
# This is written into the object # This is written into the object
...@@ -134,15 +513,17 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -134,15 +513,17 @@ def write_pov(filename, scene=None, info_callback=None):
# compute resolution # compute resolution
Qsize = float(render.resolution_x) / float(render.resolution_y) Qsize = float(render.resolution_x) / float(render.resolution_y)
file.write('#declare camLocation = <%.6f, %.6f, %.6f>;\n' % (matrix[3][0], matrix[3][1], matrix[3][2]))
file.write('#declare camLookAt = <%.6f, %.6f, %.6f>;\n' % tuple([degrees(e) for e in matrix.rotation_part().to_euler()]))
file.write('camera {\n') file.write('camera {\n')
file.write('\tlocation <0, 0, 0>\n') file.write('\tlocation <0, 0, 0>\n')
file.write('\tlook_at <0, 0, -1>\n') file.write('\tlook_at <0, 0, -1>\n')
file.write('\tright <%s, 0, 0>\n' % - Qsize) file.write('\tright <%s, 0, 0>\n' % - Qsize)
file.write('\tup <0, 1, 0>\n') file.write('\tup <0, 1, 0>\n')
file.write('\tangle %f \n' % (360.0 * math.atan(16.0 / camera.data.lens) / math.pi)) file.write('\tangle %f \n' % (360.0 * atan(16.0 / camera.data.lens) / pi))
file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple(math.degrees(e) for e in matrix.rotation_part().to_euler())) file.write('\trotate <%.6f, %.6f, %.6f>\n' % tuple([degrees(e) for e in matrix.rotation_part().to_euler()]))
file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2])) file.write('\ttranslate <%.6f, %.6f, %.6f>\n' % (matrix[3][0], matrix[3][1], matrix[3][2]))
file.write('}\n') file.write('}\n')
...@@ -153,7 +534,7 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -153,7 +534,7 @@ def write_pov(filename, scene=None, info_callback=None):
matrix = ob.matrix_world matrix = ob.matrix_world
color = tuple(c * lamp.energy for c in lamp.color) # Colour is modified by energy color = tuple([c * lamp.energy *2 for c in lamp.color]) # Colour is modified by energy #muiltiplie by 2 for a better match --Maurice
file.write('light_source {\n') file.write('light_source {\n')
file.write('\t< 0,0,0 >\n') file.write('\t< 0,0,0 >\n')
...@@ -165,8 +546,8 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -165,8 +546,8 @@ def write_pov(filename, scene=None, info_callback=None):
file.write('\tspotlight\n') file.write('\tspotlight\n')
# Falloff is the main radius from the centre line # Falloff is the main radius from the centre line
file.write('\tfalloff %.2f\n' % (math.degrees(lamp.spot_size) / 2.0)) # 1 TO 179 FOR BOTH file.write('\tfalloff %.2f\n' % (degrees(lamp.spot_size) / 2.0)) # 1 TO 179 FOR BOTH
file.write('\tradius %.6f\n' % ((math.degrees(lamp.spot_size) / 2.0) * (1.0 - lamp.spot_blend))) file.write('\tradius %.6f\n' % ((degrees(lamp.spot_size) / 2.0) * (1.0 - lamp.spot_blend)))
# Blender does not have a tightness equivilent, 0 is most like blender default. # Blender does not have a tightness equivilent, 0 is most like blender default.
file.write('\ttightness 0\n') # 0:10f file.write('\ttightness 0\n') # 0:10f
...@@ -177,7 +558,8 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -177,7 +558,8 @@ def write_pov(filename, scene=None, info_callback=None):
file.write('\tpoint_at <0, 0, -1>\n') # *must* be after 'parallel' file.write('\tpoint_at <0, 0, -1>\n') # *must* be after 'parallel'
elif lamp.type == 'AREA': elif lamp.type == 'AREA':
file.write('\tfade_distance %.6f\n' % (lamp.distance / 5) )
file.write('\tfade_power %d\n' % 2) # Area lights have no falloff type, so always use blenders lamp quad equivalent for those?
size_x = lamp.size size_x = lamp.size
samples_x = lamp.shadow_ray_samples_x samples_x = lamp.shadow_ray_samples_x
if lamp.shape == 'SQUARE': if lamp.shape == 'SQUARE':
...@@ -188,7 +570,7 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -188,7 +570,7 @@ def write_pov(filename, scene=None, info_callback=None):
samples_y = lamp.shadow_ray_samples_y samples_y = lamp.shadow_ray_samples_y
file.write('\tarea_light <%d,0,0>,<0,0,%d> %d, %d\n' % (size_x, size_y, samples_x, samples_y)) file.write('\tarea_light <%d,0,0>,<0,0,%d> %d, %d\n' % (size_x, size_y, samples_x, samples_y))
if lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED': if lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED':
if lamp.jitter: if lamp.jitter:
file.write('\tjitter\n') file.write('\tjitter\n')
else: else:
...@@ -198,11 +580,55 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -198,11 +580,55 @@ def write_pov(filename, scene=None, info_callback=None):
if lamp.shadow_method == 'NOSHADOW': if lamp.shadow_method == 'NOSHADOW':
file.write('\tshadowless\n') file.write('\tshadowless\n')
file.write('\tfade_distance %.6f\n' % lamp.distance) if lamp.type != 'SUN' and lamp.type!='AREA':#Sun shouldn't be attenuated. and area lights have no falloff attribute so they are put to type 2 attenuation a little higher above.
file.write('\tfade_power %d\n' % 1) # Could use blenders lamp quad? file.write('\tfade_distance %.6f\n' % (lamp.distance / 5) )
if lamp.falloff_type == 'INVERSE_SQUARE':
file.write('\tfade_power %d\n' % 2) # Use blenders lamp quad equivalent
elif lamp.falloff_type == 'INVERSE_LINEAR':
file.write('\tfade_power %d\n' % 1) # Use blenders lamp linear
elif lamp.falloff_type == 'CONSTANT': #Supposing using no fade power keyword would default to constant, no attenuation.
pass
elif lamp.falloff_type == 'CUSTOM_CURVE': #Using Custom curve for fade power 3 for now.
file.write('\tfade_power %d\n' % 4)
writeMatrix(matrix) writeMatrix(matrix)
file.write('}\n') file.write('}\n')
##################################################################################################################################
#Wip to be Used for fresnel, but not tested yet.
##################################################################################################################################
## lampLocation=[0,0,0]
## lampRotation=[0,0,0]
## lampDistance=0.00
## averageLampLocation=[0,0,0]
## averageLampRotation=[0,0,0]
## averageLampDistance=0.00
## lamps=[]
## for l in scene.objects:
## if l.type == 'LAMP':#get all lamps
## lamps += [l]
## for ob in lamps:
## lamp = ob.data
## lampLocation[0]+=ob.location[0]
## lampLocation[1]+=ob.location[1]
## lampLocation[2]+=ob.location[2]
## lampRotation[0]+=ob.rotation_euler[0]
## lampRotation[1]+=ob.rotation_euler[1]
## lampRotation[2]+=ob.rotation_euler[2]
## lampDistance+=ob.data.distance
## averageLampRotation[0]=lampRotation[0] / len(lamps)#create an average direction for all lamps.
## averageLampRotation[1]=lampRotation[1] / len(lamps)#create an average direction for all lamps.
## averageLampRotation[2]=lampRotation[2] / len(lamps)#create an average direction for all lamps.
##
## averageLampLocation[0]=lampLocation[0] / len(lamps)#create an average position for all lamps.
## averageLampLocation[1]=lampLocation[1] / len(lamps)#create an average position for all lamps.
## averageLampLocation[2]=lampLocation[2] / len(lamps)#create an average position for all lamps.
##
## averageLampDistance=lampDistance / len(lamps)#create an average distance for all lamps.
## file.write('\n#declare lampTarget= vrotate(<%.4g,%.4g,%.4g>,<%.4g,%.4g,%.4g>);' % (-(averageLampLocation[0]-averageLampDistance), -(averageLampLocation[1]-averageLampDistance), -(averageLampLocation[2]-averageLampDistance), averageLampRotation[0], averageLampRotation[1], averageLampRotation[2]))
## #v(A,B) rotates vector A about origin by vector B.
##
####################################################################################################################################
def exportMeta(metas): def exportMeta(metas):
...@@ -426,14 +852,204 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -426,14 +852,204 @@ def write_pov(filename, scene=None, info_callback=None):
material_finish = DEF_MAT_NAME # not working properly, material_finish = DEF_MAT_NAME # not working properly,
trans = 0.0 trans = 0.0
#print material.apl ##############SF
file.write(',\n\t\ttexture { pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} finish {%s}}' % texturesDif=''
(col[0], col[1], col[2], 1.0 - material.alpha, trans, material_finish)) texturesSpec=''
texturesNorm=''
texturesAlpha=''
for t in material.texture_slots:
if t and t.texture.type == 'IMAGE' and t.use:
image_filename = path_image(t.texture.image.filepath)
if t.texture.image.filepath != image_filename: t.texture.image.filepath = image_filename
if image_filename != '' and t.use_map_color_diffuse:
texturesDif = image_filename
colvalue = t.default_value
t_dif = t
if image_filename != '' and (t.use_map_specular or t.use_map_raymir):
texturesSpec = image_filename
colvalue = t.default_value
t_spec = t
if image_filename != '' and t.use_map_normal:
texturesNorm = image_filename
colvalue = t.normal_factor * 10
#textNormName=t.texture.image.name + '.normal'
#was the above used? --MR
t_nor = t
if image_filename != '' and t.use_map_alpha:
texturesAlpha = image_filename
colvalue = t.alpha_factor * 10
#textDispName=t.texture.image.name + '.displ'
#was the above used? --MR
t_alpha = t
##############################################################################################################
file.write('\n\t\ttexture {') #THIS AREA NEEDS TO LEAVE THE TEXTURE OPEN UNTIL ALL MAPS ARE WRITTEN DOWN. --MR
##############################################################################################################
if material.diffuse_shader == 'MINNAERT':
file.write('\n\t\t\taoi')
file.write('\n\t\t\ttexture_map {')
file.write('\n\t\t\t\t[%.3g finish {diffuse %.3g}]' % ((material.darkness/2), (2-material.darkness)))
file.write('\n\t\t\t\t[%.3g' % (1-(material.darkness/2)))
######TO OPTIMIZE? or present a more elegant way? At least make it work!##################################################################
#If Fresnel gets removed from 2.5, why bother?
if material.diffuse_shader == 'FRESNEL':
######END of part TO OPTIMIZE? or present a more elegant way?##################################################################
## #lampLocation=lamp.position
## lampRotation=
## a=lamp.Rotation[0]
## b=lamp.Rotation[1]
## c=lamp.Rotation[2]
## lampLookAt=tuple (x,y,z)
## lampLookAt[3]= 0.0 #Put "target" of the lamp on the floor plane to elimianate one unknown value
## degrees(atan((lampLocation - lampLookAt).y/(lampLocation - lampLookAt).z))=lamp.rotation[0]
## degrees(atan((lampLocation - lampLookAt).z/(lampLocation - lampLookAt).x))=lamp.rotation[1]
## degrees(atan((lampLocation - lampLookAt).x/(lampLocation - lampLookAt).y))=lamp.rotation[2]
## degrees(atan((lampLocation - lampLookAt).y/(lampLocation.z))=lamp.rotation[0]
## degrees(atan((lampLocation.z/(lampLocation - lampLookAt).x))=lamp.rotation[1]
## degrees(atan((lampLocation - lampLookAt).x/(lampLocation - lampLookAt).y))=lamp.rotation[2]
#color = tuple([c * lamp.energy for c in lamp.color]) # Colour is modified by energy
file.write('\n\t\t\tslope { lampTarget }')
file.write('\n\t\t\ttexture_map {')
file.write('\n\t\t\t\t[%.3g finish {diffuse %.3g}]' % ((material.diffuse_fresnel/2), (2-material.diffuse_fresnel_factor)))
file.write('\n\t\t\t\t[%.3g' % (1-(material.diffuse_fresnel/2)))
#if material.diffuse_shader == 'FRESNEL': pigment pattern aoi pigment and texture map above, the rest below as one of its entry
##########################################################################################################################
if texturesSpec !='':
file.write('\n\t\t\t\tpigment_pattern {')
mappingSpec = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_spec.offset.x / 10 ,t_spec.offset.y / 10 ,t_spec.offset.z / 10, t_spec.scale.x / 2.25, t_spec.scale.y / 2.25, t_spec.scale.z / 2.25)) #strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
file.write('\n\t\t\t\t\tuv_mapping image_map{%s \"%s\" %s}%s}' % (imageFormat(texturesSpec) ,texturesSpec ,imgMap(t_spec),mappingSpec))
file.write('\n\t\t\t\t\t\ttexture_map {')
file.write('\n\t\t\t\t\t\t\t[0 ')
if texturesDif == '':
if texturesAlpha !='':
mappingAlpha = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_alpha.offset.x / 10 ,t_alpha.offset.y / 10 ,t_alpha.offset.z / 10, t_alpha.scale.x / 2.25, t_alpha.scale.y / 2.25, t_alpha.scale.z / 2.25)) #strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
file.write('\n\t\t\t\tpigment {pigment_pattern {uv_mapping image_map{%s \"%s\" %s}%s}' % (imageFormat(texturesAlpha) ,texturesAlpha ,imgMap(t_alpha),mappingAlpha))
file.write('\n\t\t\t\t\tpigment_map {')
file.write('\n\t\t\t\t\t\t[0 color rgbft<0,0,0,1,1>]')
file.write('\n\t\t\t\t\t\t[1 color rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>]\n\t\t\t\t\t}' % (col[0], col[1], col[2], 1.0 - material.alpha, trans))
file.write('\n\t\t\t\t}')
else:
file.write('\n\t\t\t\tpigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>}' % (col[0], col[1], col[2], 1.0 - material.alpha, trans))
if texturesSpec !='':
file.write('finish {%s}' % (safety0(material_finish)))
else:
file.write('finish {%s}' % (safety(material_finish)))
else:
mappingDif = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_dif.offset.x / 10 ,t_dif.offset.y / 10 ,t_dif.offset.z / 10, t_dif.scale.x / 2.25, t_dif.scale.y / 2.25, t_dif.scale.z / 2.25)) #strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
if texturesAlpha !='':
mappingAlpha = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_alpha.offset.x / 10 ,t_alpha.offset.y / 10 ,t_alpha.offset.z / 10, t_alpha.scale.x / 2.25, t_alpha.scale.y / 2.25, t_alpha.scale.z / 2.25)) #strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
file.write('\n\t\t\t\tpigment {pigment_pattern {uv_mapping image_map{%s \"%s\" %s}%s}' % (imageFormat(texturesAlpha),texturesAlpha,imgMap(t_alpha),mappingAlpha))
file.write('\n\t\t\t\t\tpigment_map {\n\t\t\t\t\t\t[0 color rgbft<0,0,0,1,1>]')
file.write('\n\t\t\t\t\t\t[1 uv_mapping image_map {%s \"%s\" %s}%s]\n\t\t\t\t}' % (imageFormat(texturesDif),texturesDif,imgMap(t_dif),mappingDif))
file.write('\n\t\t\t\t}')
else:
file.write("\n\t\t\t\tpigment {uv_mapping image_map {%s \"%s\" %s}%s}" % (imageFormat(texturesDif),texturesDif,imgMap(t_dif),mappingDif))
if texturesSpec !='':
file.write('finish {%s}' % (safety0(material_finish)))
else:
file.write('finish {%s}' % (safety(material_finish)))
## scale 1 rotate y*0
#imageMap = ("{image_map {%s \"%s\" %s }" % (imageFormat(textures),textures,imgMap(t_dif)))
#file.write("\n\t\t\tuv_mapping pigment %s} %s finish {%s}" % (imageMap,mapping,safety(material_finish)))
#file.write("\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 !='':
## scale 1 rotate y*0
mappingNor = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_nor.offset.x / 10 ,t_nor.offset.y / 10 ,t_nor.offset.z / 10, t_nor.scale.x / 2.25, t_nor.scale.y / 2.25, t_nor.scale.z / 2.25))
#imageMapNor = ("{bump_map {%s \"%s\" %s mapping}" % (imageFormat(texturesNorm),texturesNorm,imgMap(t_nor)))
#We were not using the above maybe we should?
file.write("\n\t\t\t\tnormal {uv_mapping bump_map {%s \"%s\" %s bump_size %.4g }%s}" % (imageFormat(texturesNorm),texturesNorm,imgMap(t_nor),(t_nor.normal_factor * 10),mappingNor))
if texturesSpec !='':
file.write('\n\t\t\t\t\t\t\t]')
################################Second index for mapping specular max value##################################################################################################
file.write('\n\t\t\t\t\t\t\t[1 ')
if texturesDif == '':
if texturesAlpha !='':
mappingAlpha = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_alpha.offset.x / 10 ,t_alpha.offset.y / 10 ,t_alpha.offset.z / 10, t_alpha.scale.x / 2.25, t_alpha.scale.y / 2.25, t_alpha.scale.z / 2.25)) #strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
file.write('\n\t\t\t\tpigment {pigment_pattern {uv_mapping image_map{%s \"%s\" %s}%s}' % (imageFormat(texturesAlpha) ,texturesAlpha ,imgMap(t_alpha),mappingAlpha))
file.write('\n\t\t\t\t\tpigment_map {')
file.write('\n\t\t\t\t\t\t[0 color rgbft<0,0,0,1,1>]')
file.write('\n\t\t\t\t\t\t[1 color rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>]\n\t\t\t\t\t}' % (col[0], col[1], col[2], 1.0 - material.alpha, trans))
file.write('\n\t\t\t\t}')
else:
file.write('\n\t\t\t\tpigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>}' % (col[0], col[1], col[2], 1.0 - material.alpha, trans))
if texturesSpec !='':
file.write('finish {%s}' % (safety1(material_finish)))
else:
file.write('finish {%s}' % (safety(material_finish)))
else:
mappingDif = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_dif.offset.x / 10 ,t_dif.offset.y / 10 ,t_dif.offset.z / 10, t_dif.scale.x / 2.25, t_dif.scale.y / 2.25, t_dif.scale.z / 2.25)) #strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
if texturesAlpha !='':
mappingAlpha = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_alpha.offset.x / 10 ,t_alpha.offset.y / 10 ,t_alpha.offset.z / 10, t_alpha.scale.x / 2.25, t_alpha.scale.y / 2.25, t_alpha.scale.z / 2.25)) #strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
file.write('\n\t\t\t\tpigment {pigment_pattern {uv_mapping image_map{%s \"%s\" %s}%s}' % (imageFormat(texturesAlpha),texturesAlpha,imgMap(t_alpha),mappingAlpha))
file.write('\n\t\t\t\tpigment_map {\n\t\t\t\t\t[0 color rgbft<0,0,0,1,1>]')
file.write('\n\t\t\t\t\t\t[1 uv_mapping image_map {%s \"%s\" %s}%s]\n\t\t\t\t\t}' % (imageFormat(texturesDif),texturesDif,imgMap(t_dif),mappingDif))
file.write('\n\t\t\t\t}')
else:
file.write("\n\t\t\tpigment {uv_mapping image_map {%s \"%s\" %s}%s}" % (imageFormat(texturesDif),texturesDif,imgMap(t_dif),mappingDif))
if texturesSpec !='':
file.write('finish {%s}' % (safety1(material_finish)))
else:
file.write('finish {%s}' % (safety(material_finish)))
## scale 1 rotate y*0
#imageMap = ("{image_map {%s \"%s\" %s }" % (imageFormat(textures),textures,imgMap(t_dif)))
#file.write("\n\t\t\tuv_mapping pigment %s} %s finish {%s}" % (imageMap,mapping,safety(material_finish)))
#file.write("\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 !='':
## scale 1 rotate y*0
mappingNor = (" translate <%.4g-0.75,%.4g-0.75,%.4g-0.75> scale <%.4g,%.4g,%.4g>" % (t_nor.offset.x / 10 ,t_nor.offset.y / 10 ,t_nor.offset.z / 10, t_nor.scale.x / 2.25, t_nor.scale.y / 2.25, t_nor.scale.z / 2.25))
#imageMapNor = ("{bump_map {%s \"%s\" %s mapping}" % (imageFormat(texturesNorm),texturesNorm,imgMap(t_nor)))
#We were not using the above maybe we should?
file.write("\n\t\t\t\tnormal {uv_mapping bump_map {%s \"%s\" %s bump_size %.4g }%s}" % (imageFormat(texturesNorm),texturesNorm,imgMap(t_nor),(t_nor.normal_factor * 10),mappingNor))
if texturesSpec !='':
file.write('\n\t\t\t\t\t\t\t]')
file.write('\n\t\t\t\t}')
#End of slope/ior texture_map
if material.diffuse_shader == 'MINNAERT' or material.diffuse_shader == 'FRESNEL':
file.write('\n\t\t\t\t]')
file.write('\n\t\t\t}')
file.write('\n\t\t}') #THEN IT CAN CLOSE IT --MR
############################################################################################################
index[0] = idx index[0] = idx
idx += 1 idx += 1
file.write('\n }\n') file.write('\n\t}\n')
# Face indicies # Face indicies
file.write('\tface_indices {\n') file.write('\tface_indices {\n')
...@@ -523,12 +1139,15 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -523,12 +1139,15 @@ def write_pov(filename, scene=None, info_callback=None):
file.write(',\n\t\t<%d,%d,%d>' %\ file.write(',\n\t\t<%d,%d,%d>' %\
(uniqueUVs[uvs[i1]][0],\ (uniqueUVs[uvs[i1]][0],\
uniqueUVs[uvs[i2]][0],\ uniqueUVs[uvs[i2]][0],\
uniqueUVs[uvs[i2]][0])) # vert count uniqueUVs[uvs[i3]][0]))
file.write('\n }\n') file.write('\n }\n')
if me.materials: if me.materials:
material = me.materials[0] # dodgy try:
writeObjectMaterial(material) material = me.materials[0] # dodgy
writeObjectMaterial(material)
except IndexError:
print(me)
writeMatrix(matrix) writeMatrix(matrix)
file.write('}\n') file.write('}\n')
...@@ -536,8 +1155,60 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -536,8 +1155,60 @@ def write_pov(filename, scene=None, info_callback=None):
bpy.data.meshes.remove(me) bpy.data.meshes.remove(me)
def exportWorld(world): def exportWorld(world):
camera = scene.camera
matrix = camera.matrix_world
if not world: if not world:
return return
#############Maurice####################################
#These lines added to get sky gradient (visible with PNG output)
if world:
#For simple flat background:
if not world.use_sky_blend:
file.write('background {rgbt<%.3g, %.3g, %.3g, 1>}\n' % (tuple(world.horizon_color)))#Non fully transparent background could premultiply alpha and avoid anti-aliasing problem. Put transmit to 1 reveals pov problem with nonpremult antialiased.
#For Background image textures
for t in world.texture_slots: #risk to write several sky_spheres but maybe ok.
if t and t.texture.type == 'IMAGE': #and t.use: #No enable checkbox for world textures yet (report it?)
image_filename = path_image(t.texture.image.filepath)
if t.texture.image.filepath != image_filename: t.texture.image.filepath = image_filename
if image_filename != '' and t.use_map_blend:
texturesBlend = image_filename
#colvalue = t.default_value
t_blend = t
#commented below was an idea to make the Background image oriented as camera taken here: http://news.povray.org/povray.newusers/thread/%3Cweb.4a5cddf4e9c9822ba2f93e20@news.povray.org%3E/
#mappingBlend = (" translate <%.4g,%.4g,%.4g> rotate z*degrees(atan((camLocation - camLookAt).x/(camLocation - camLookAt).y)) rotate x*degrees(atan((camLocation - camLookAt).y/(camLocation - camLookAt).z)) rotate y*degrees(atan((camLocation - camLookAt).z/(camLocation - camLookAt).x)) scale <%.4g,%.4g,%.4g>b" % (t_blend.offset.x / 10 ,t_blend.offset.y / 10 ,t_blend.offset.z / 10, t_blend.scale.x ,t_blend.scale.y ,t_blend.scale.z))#replace 4/3 by the ratio of each image found by some custom or existing function
#using camera rotation valuesdirectly from blender seems much easier
mappingBlend = (" translate <%.4g-0.5,%.4g-0.5,%.4g-0.5> rotate<%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (t_blend.offset.x / 10 ,t_blend.offset.y / 10 ,t_blend.offset.z / 10, degrees(camera.rotation_euler[0]), degrees(camera.rotation_euler[1]), degrees(camera.rotation_euler[2]), t_blend.scale.x*0.85 , t_blend.scale.y*0.85 , t_blend.scale.z*0.85 ))
#Putting the map on a plane would not introduce the skysphere distortion and allow for better image scale matching but also some waay to chose depth and size of the plane relative to camera.
file.write('sky_sphere {\n')
file.write('\tpigment {\n')
file.write("\t\timage_map{%s \"%s\" %s}\n\t}\n\t%s\n" % (imageFormat(texturesBlend),texturesBlend,imgMapBG(t_blend),mappingBlend))
file.write('}\n')
#file.write('\t\tscale 2\n')
#file.write('\t\ttranslate -1\n')
#For only Background gradient
if not t:
if world.use_sky_blend:
file.write('sky_sphere {\n')
file.write('\tpigment {\n')
file.write('\t\tgradient z\n')#maybe Should follow the advice of POV doc about replacing gradient for skysphere..5.5
file.write('\t\tcolor_map {\n')
file.write('\t\t\t[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n' % (tuple(world.zenith_color)))
file.write('\t\t\t[1.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n' % (tuple(world.horizon_color))) #aa premult not solved with transmit 1
file.write('\t\t}\n')
file.write('\t}\n')
file.write('}\n')
#problem with sky_sphere alpha (transmit) not translating into image alpha as well as "background" replace 0.75 by 1 when solved and later by some variable linked to background alpha state
if world.light_settings.use_indirect_light:
scene.pov_radio_enable=1
###############################################################
mist = world.mist_settings mist = world.mist_settings
...@@ -555,6 +1226,7 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -555,6 +1226,7 @@ def write_pov(filename, scene=None, info_callback=None):
def exportGlobalSettings(scene): def exportGlobalSettings(scene):
file.write('global_settings {\n') file.write('global_settings {\n')
file.write('\tmax_trace_level 7\n')
if scene.pov_radio_enable: if scene.pov_radio_enable:
file.write('\tradiosity {\n') file.write('\tradiosity {\n')
...@@ -571,10 +1243,25 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -571,10 +1243,25 @@ def write_pov(filename, scene=None, info_callback=None):
file.write("\t\tnormal %d\n" % scene.pov_radio_normal) file.write("\t\tnormal %d\n" % scene.pov_radio_normal)
file.write("\t\trecursion_limit %d\n" % scene.pov_radio_recursion_limit) file.write("\t\trecursion_limit %d\n" % scene.pov_radio_recursion_limit)
file.write('\t}\n') file.write('\t}\n')
once=1
for material in bpy.data.materials:
if material.subsurface_scattering.use and once:
file.write("\tmm_per_unit %.6f\n" % (material.subsurface_scattering.scale * (-100) + 15))#In pov, the scale has reversed influence compared to blender. these number should correct that
once=0 #In povray, the scale factor for all subsurface shaders needs to be the same
if world: if world:
file.write("\tambient_light rgb<%.3g, %.3g, %.3g>\n" % tuple(world.ambient_color)) file.write("\tambient_light rgb<%.3g, %.3g, %.3g>\n" % tuple(world.ambient_color))
if material.pov_photons_refraction or material.pov_photons_reflection:
file.write("\tphotons {\n")
file.write("\t\tspacing 0.003\n")
file.write("\t\tmax_trace_level 4\n")
file.write("\t\tadc_bailout 0.1\n")
file.write("\t\tgather 30, 150\n")
file.write("\t}\n")
file.write('}\n') file.write('}\n')
...@@ -587,8 +1274,8 @@ def write_pov(filename, scene=None, info_callback=None): ...@@ -587,8 +1274,8 @@ def write_pov(filename, scene=None, info_callback=None):
exportCamera() exportCamera()
#exportMaterials() #exportMaterials()
sel = scene.objects sel = scene.objects
exportLamps(l for l in sel if l.type == 'LAMP') exportLamps([l for l in sel if l.type == 'LAMP'])
exportMeta(l for l in sel if l.type == 'META') exportMeta([l for l in sel if l.type == 'META'])
exportMeshs(scene, sel) exportMeshs(scene, sel)
exportWorld(scene.world) exportWorld(scene.world)
exportGlobalSettings(scene) exportGlobalSettings(scene)
...@@ -621,15 +1308,22 @@ def write_pov_ini(filename_ini, filename_pov, filename_image): ...@@ -621,15 +1308,22 @@ def write_pov_ini(filename_ini, filename_pov, filename_image):
file.write('End_Row=%d\n' % (part.y+part.h)) file.write('End_Row=%d\n' % (part.y+part.h))
''' '''
file.write('Display=0\n') file.write('Bounding_method=2\n')#The new automatic BSP is faster in most scenes
file.write('Display=1\n')#Activated (turn this back off when better live exchange is done between the two programs (see next comment)
file.write('Pause_When_Done=0\n') file.write('Pause_When_Done=0\n')
file.write('Output_File_Type=T\n') # TGA, best progressive loading file.write('Output_File_Type=N\n') # PNG, with POV 3.7, can show background color with alpha. In the long run using the Povray interactive preview like bishop 3D could solve the preview for all formats.
#file.write('Output_File_Type=T\n') # TGA, best progressive loading
file.write('Output_Alpha=1\n') file.write('Output_Alpha=1\n')
if render.use_antialiasing: if render.use_antialiasing:
aa_mapping = {'5': 2, '8': 3, '11': 4, '16': 5} # method 1 assumed aa_mapping = {'5': 2, '8': 3, '11': 4, '16': 5} # method 2 (recursive) with higher max subdiv forced because no mipmapping in povray needs higher sampling.
file.write('Antialias=1\n') file.write('Antialias=1\n')
file.write('Sampling_Method=2n')
file.write('Antialias_Depth=%d\n' % aa_mapping[render.antialiasing_samples]) file.write('Antialias_Depth=%d\n' % aa_mapping[render.antialiasing_samples])
file.write('Antialias_Threshold=0.1\n')#rather high settings but necessary.
file.write('Jitter=off\n')#prevent animation flicker
else: else:
file.write('Antialias=0\n') file.write('Antialias=0\n')
...@@ -637,24 +1331,26 @@ def write_pov_ini(filename_ini, filename_pov, filename_image): ...@@ -637,24 +1331,26 @@ def write_pov_ini(filename_ini, filename_pov, filename_image):
class PovrayRender(bpy.types.RenderEngine): class PovrayRender(bpy.types.RenderEngine):
bl_idname = 'POVRAY_RENDER' bl_idname = 'POVRAY_37_RENDER'
bl_label = "Povray" bl_label = "Povray 3.7"
DELAY = 0.02 DELAY = 0.02
def _export(self, scene): def _export(self, scene):
import tempfile import tempfile
self._temp_file_in = tempfile.mktemp(suffix='.pov') self._temp_file_in = tempfile.mktemp(suffix='.pov')
self._temp_file_out = tempfile.mktemp(suffix='.tga') self._temp_file_out = tempfile.mktemp(suffix='.png')#PNG with POV 3.7, can show the background color with alpha. In the long run using the Povray interactive preview like bishop 3D could solve the preview for all formats.
#self._temp_file_out = tempfile.mktemp(suffix='.tga')
self._temp_file_ini = tempfile.mktemp(suffix='.ini') self._temp_file_ini = tempfile.mktemp(suffix='.ini')
''' '''
self._temp_file_in = '/test.pov' self._temp_file_in = '/test.pov'
self._temp_file_out = '/test.tga' self._temp_file_out = '/test.png'#PNG with POV 3.7, can show the background color with alpha. In the long run using the Povray interactive preview like bishop 3D could solve the preview for all formats.
#self._temp_file_out = '/test.tga'
self._temp_file_ini = '/test.ini' self._temp_file_ini = '/test.ini'
''' '''
def info_callback(txt): def info_callback(txt):
self.update_stats("", "POVRAY: " + txt) self.update_stats("", "POVRAY 3.7: " + txt)
write_pov(self._temp_file_in, scene, info_callback) write_pov(self._temp_file_in, scene, info_callback)
...@@ -673,7 +1369,7 @@ class PovrayRender(bpy.types.RenderEngine): ...@@ -673,7 +1369,7 @@ class PovrayRender(bpy.types.RenderEngine):
if sys.platform == 'win32': if sys.platform == 'win32':
import winreg import winreg
regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.6\\Windows') regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.7\\Windows')
if bitness == 64: if bitness == 64:
pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64' pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64'
...@@ -686,7 +1382,7 @@ class PovrayRender(bpy.types.RenderEngine): ...@@ -686,7 +1382,7 @@ class PovrayRender(bpy.types.RenderEngine):
self._process = subprocess.Popen([pov_binary, self._temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE self._process = subprocess.Popen([pov_binary, self._temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE
except OSError: except OSError:
# TODO, report api # TODO, report api
print("POVRAY: could not execute '%s', possibly povray isn't installed" % pov_binary) print("POVRAY 3.7: could not execute '%s', possibly povray isn't installed" % pov_binary)
import traceback import traceback
traceback.print_exc() traceback.print_exc()
print ("***-DONE-***") print ("***-DONE-***")
...@@ -710,15 +1406,23 @@ class PovrayRender(bpy.types.RenderEngine): ...@@ -710,15 +1406,23 @@ class PovrayRender(bpy.types.RenderEngine):
def render(self, scene): def render(self, scene):
self.update_stats("", "POVRAY: Exporting data from Blender") self.update_stats("", "POVRAY 3.7: Exporting data from Blender")
self._export(scene) self._export(scene)
self.update_stats("", "POVRAY: Parsing File") self.update_stats("", "POVRAY 3.7: Parsing File")
if not self._render(): if not self._render():
self.update_stats("", "POVRAY: Not found") self.update_stats("", "POVRAY 3.7: Not found")
return return
r = scene.render r = scene.render
##WIP output format
## if r.file_format == 'OPENEXR':
## fformat = 'EXR'
## render.color_mode = 'RGBA'
## else:
## fformat = 'TGA'
## r.file_format = 'TARGA'
## r.color_mode = 'RGBA'
# compute resolution # compute resolution
x = int(r.resolution_x * r.resolution_percentage * 0.01) x = int(r.resolution_x * r.resolution_percentage * 0.01)
...@@ -734,14 +1438,14 @@ class PovrayRender(bpy.types.RenderEngine): ...@@ -734,14 +1438,14 @@ class PovrayRender(bpy.types.RenderEngine):
break break
if self._process.poll() != None: if self._process.poll() != None:
self.update_stats("", "POVRAY: Failed") self.update_stats("", "POVRAY 3.7: Failed")
break break
time.sleep(self.DELAY) time.sleep(self.DELAY)
if os.path.exists(self._temp_file_out): if os.path.exists(self._temp_file_out):
self.update_stats("", "POVRAY: Rendering") self.update_stats("", "POVRAY 3.7: Rendering")
prev_size = -1 prev_size = -1
......
...@@ -20,18 +20,18 @@ import bpy ...@@ -20,18 +20,18 @@ import bpy
# Use some of the existing buttons. # Use some of the existing buttons.
import properties_render import properties_render
properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_37_RENDER')
properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_37_RENDER')
properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_37_RENDER')
properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_37_RENDER')
del properties_render del properties_render
# Use only a subset of the world panels # Use only a subset of the world panels
import properties_world import properties_world
properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER') properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_37_RENDER')
properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER') properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_37_RENDER')
properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER') properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_37_RENDER')
properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER') properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_37_RENDER')
del properties_world del properties_world
# Example of wrapping every class 'as is' # Example of wrapping every class 'as is'
...@@ -39,7 +39,7 @@ import properties_material ...@@ -39,7 +39,7 @@ import properties_material
for member in dir(properties_material): for member in dir(properties_material):
subclass = getattr(properties_material, member) subclass = getattr(properties_material, member)
try: try:
subclass.COMPAT_ENGINES.add('POVRAY_RENDER') subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
except: except:
pass pass
del properties_material del properties_material
...@@ -48,7 +48,7 @@ import properties_data_mesh ...@@ -48,7 +48,7 @@ import properties_data_mesh
for member in dir(properties_data_mesh): for member in dir(properties_data_mesh):
subclass = getattr(properties_data_mesh, member) subclass = getattr(properties_data_mesh, member)
try: try:
subclass.COMPAT_ENGINES.add('POVRAY_RENDER') subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
except: except:
pass pass
del properties_data_mesh del properties_data_mesh
...@@ -57,7 +57,7 @@ import properties_texture ...@@ -57,7 +57,7 @@ import properties_texture
for member in dir(properties_texture): for member in dir(properties_texture):
subclass = getattr(properties_texture, member) subclass = getattr(properties_texture, member)
try: try:
subclass.COMPAT_ENGINES.add('POVRAY_RENDER') subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
except: except:
pass pass
del properties_texture del properties_texture
...@@ -66,11 +66,20 @@ import properties_data_camera ...@@ -66,11 +66,20 @@ import properties_data_camera
for member in dir(properties_data_camera): for member in dir(properties_data_camera):
subclass = getattr(properties_data_camera, member) subclass = getattr(properties_data_camera, member)
try: try:
subclass.COMPAT_ENGINES.add('POVRAY_RENDER') subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
except: except:
pass pass
del properties_data_camera del properties_data_camera
import properties_data_lamp
for member in dir(properties_data_lamp):
subclass = getattr(properties_data_lamp, member)
try:
subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
except:
pass
del properties_data_lamp
class RenderButtonsPanel(): class RenderButtonsPanel():
...@@ -84,10 +93,154 @@ class RenderButtonsPanel(): ...@@ -84,10 +93,154 @@ class RenderButtonsPanel():
rd = context.scene.render rd = context.scene.render
return (rd.use_game_engine == False) and (rd.engine in cls.COMPAT_ENGINES) return (rd.use_game_engine == False) and (rd.engine in cls.COMPAT_ENGINES)
class MaterialButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "material"
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
@classmethod
def poll(cls, context):
mat = context.material
rd = context.scene.render
return (rd.use_game_engine == False) and (rd.engine in cls.COMPAT_ENGINES)
########################################MR######################################
class MATERIAL_PT_povray_mirrorIOR(MaterialButtonsPanel, bpy.types.Panel):
bl_label = "IOR Mirror"
COMPAT_ENGINES = {'POVRAY_37_RENDER'}
def draw_header(self, context):
scene = context.material
self.layout.prop(scene, "pov_mirror_use_IOR", text="")
def draw(self, context):
layout = self.layout
mat = context.material
layout.active = mat.pov_mirror_use_IOR
if mat.pov_mirror_use_IOR:
split = layout.split()
col = split.column()
row = col.row()
row.alignment = 'CENTER'
row.label(text="The current Raytrace ")
row = col.row()
row.alignment = 'CENTER'
row.label(text="Transparency IOR is: "+str(mat.raytrace_transparency.ior))
class MATERIAL_PT_povray_metallic(MaterialButtonsPanel, bpy.types.Panel):
bl_label = "metallic Mirror"
COMPAT_ENGINES = {'POVRAY_37_RENDER'}
def draw_header(self, context):
scene = context.material
self.layout.prop(scene, "pov_mirror_metallic", text="")
def draw(self, context):
layout = self.layout
mat = context.material
layout.active = mat.pov_mirror_metallic
class MATERIAL_PT_povray_conserve_energy(MaterialButtonsPanel, bpy.types.Panel):
bl_label = "conserve energy"
COMPAT_ENGINES = {'POVRAY_37_RENDER'}
def draw_header(self, context):
mat = context.material
self.layout.prop(mat, "pov_conserve_energy", text="")
def draw(self, context):
layout = self.layout
mat = context.material
layout.active = mat.pov_conserve_energy
class MATERIAL_PT_povray_iridescence(MaterialButtonsPanel, bpy.types.Panel):
bl_label = "iridescence"
COMPAT_ENGINES = {'POVRAY_37_RENDER'}
def draw_header(self, context):
mat = context.material
self.layout.prop(mat, "pov_irid_enable", text="")
def draw(self, context):
layout = self.layout
mat = context.material
layout.active = mat.pov_irid_enable
if mat.pov_irid_enable:
split = layout.split()
col = split.column()
col.prop(mat, "pov_irid_amount", slider=True)
col.prop(mat, "pov_irid_thickness", slider=True)
col.prop(mat, "pov_irid_turbulence", slider=True)
class MATERIAL_PT_povray_caustics(MaterialButtonsPanel, bpy.types.Panel):
bl_label = "Caustics"
COMPAT_ENGINES = {'POVRAY_37_RENDER'}
def draw_header(self, context):
mat = context.material
self.layout.prop(mat, "pov_caustics_enable", text="")
def draw(self, context):
layout = self.layout
mat = context.material
layout.active = mat.pov_caustics_enable
Radio = 1
if mat.pov_caustics_enable:
split = layout.split()
col = split.column()
col.prop(mat, "pov_refraction_type")
if mat.pov_refraction_type=="0":
mat.pov_fake_caustics = False
mat.pov_photons_refraction = False
mat.pov_photons_reflection = True
elif mat.pov_refraction_type=="1":
mat.pov_fake_caustics = True
mat.pov_photons_refraction = False
col.prop(mat, "pov_fake_caustics_power", slider=True)
elif mat.pov_refraction_type=="2":
mat.pov_fake_caustics = False
mat.pov_photons_refraction = True
col.prop(mat, "pov_photons_dispersion", slider=True)
col.prop(mat, "pov_photons_reflection")
## col.prop(mat, "pov_fake_caustics")
## if mat.pov_fake_caustics:
## col.prop(mat, "pov_fake_caustics_power", slider=True)
## mat.pov_photons_refraction=0
## else:
## col.prop(mat, "pov_photons_refraction")
## if mat.pov_photons_refraction:
## col.prop(mat, "pov_photons_dispersion", slider=True)
## Radio = 0
## mat.pov_fake_caustics=Radio
## col.prop(mat, "pov_photons_reflection")
####TODO : MAKE THIS A real RADIO BUTTON (using EnumProperty?)
######################################EndMR#####################################
class RENDER_PT_povray_radiosity(RenderButtonsPanel, bpy.types.Panel): class RENDER_PT_povray_radiosity(RenderButtonsPanel, bpy.types.Panel):
bl_label = "Radiosity" bl_label = "Radiosity"
COMPAT_ENGINES = {'POVRAY_RENDER'} COMPAT_ENGINES = {'POVRAY_37_RENDER'}
def draw_header(self, context): def draw_header(self, context):
scene = context.scene scene = context.scene
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment