From c3828e7d063efe62d0d7f0ca6528c53cfab9d660 Mon Sep 17 00:00:00 2001
From: Maurice Raybaud <mauriceraybaud@hotmail.fr>
Date: Wed, 27 Oct 2010 20:09:50 +0000
Subject: [PATCH] first commit ever!

---
 render_povray/__init__.py | 113 +++++-
 render_povray/render.py   | 800 +++++++++++++++++++++++++++++++++++---
 render_povray/ui.py       | 179 ++++++++-
 3 files changed, 1019 insertions(+), 73 deletions(-)

diff --git a/render_povray/__init__.py b/render_povray/__init__.py
index 4adcbf07e..155ea07d4 100644
--- a/render_povray/__init__.py
+++ b/render_povray/__init__.py
@@ -17,31 +17,30 @@
 # ##### END GPL LICENSE BLOCK #####
 
 bl_addon_info = {
-    "name": "PovRay",
-    "author": "Campbell Barton",
-    "version": (0,1),
+    "name": "PovRay 3.7",
+    "author": "Campbell Barton, Silvio Falcinelli, Maurice Raybaud",
+    "version": (0, 0, 3),
     "blender": (2, 5, 4),
     "api": 31667,
     "location": "Info Header (engine dropdown)",
-    "description": "Basic povray integration for blender",
-    "warning": "",
+    "description": "Basic povray 3.7 integration for blender",
+    "warning": "both povray 3.7 and this script are beta",
     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
         "Scripts/Render/PovRay",
     "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"}
 
 
 if "bpy" in locals():
-    reload(render)
     reload(ui)
+    reload(render)
 
 else:
     import bpy
     from bpy.props import *
-    from render_povray import render
-    from render_povray import ui
-
+    from render_povray_37 import ui
+    from render_povray_37 import render
 
 def register():
     Scene = bpy.types.Scene
@@ -106,11 +105,88 @@ def register():
             name="Recursion Limit", description="how many recursion levels are used to calculate the diffuse inter-reflection",
             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():
     import bpy
     Scene = bpy.types.Scene
-
+    Mat = bpy.types.Material#MR
     del Scene.pov_radio_enable
     del Scene.pov_radio_display_advanced
     del Scene.pov_radio_adc_bailout
@@ -125,7 +201,20 @@ def unregister():
     del Scene.pov_radio_nearest_count
     del Scene.pov_radio_normal
     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__":
     register()
diff --git a/render_povray/render.py b/render_povray/render.py
index 755e12c4b..5daef60bd 100644
--- a/render_povray/render.py
+++ b/render_povray/render.py
@@ -22,6 +22,7 @@ import os
 import sys
 import time
 import math
+from math import atan, pi, degrees, sqrt
 
 import platform as pltfrm
 if pltfrm.architecture()[0] == '64bit':
@@ -29,6 +30,119 @@ if pltfrm.architecture()[0] == '64bit':
 else:
     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):
     file = open(filename, 'w')
@@ -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]))
 
     def writeObjectMaterial(material):
-        if material and material.transparency_method == 'RAYTRACE':
-            file.write('\tinterior { ior %.6f }\n' % material.raytrace_transparency.ior)
+        if material: #and material.transparency_method == 'RAYTRACE':#Commented out: always write IOR to be able to use it for SSS, Fresnel reflections...
+            #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
             # fade_distance 2
             # fade_power [Value]
             # fade_color
 
-            # dispersion
-            # dispersion_samples
-
+            # (variable) dispersion_samples (constant count for now)
+            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 = {}
     DEF_MAT_NAME = 'Default'
 
@@ -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)
 
-        file.write('#declare %s = finish {\n' % name)
+        file.write('#declare %s = finish {\n' % safety0(name))
 
         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)
-            #file.write('\tambient rgb <%.3g, %.3g, %.3g>\n' % tuple(c*material.ambient for c in world.ambient_color)) # povray blends the global value
+            #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
+            ## scale from 0.0 to 0.1
             roughness *= 0.1
             # add a small value because 0.0 is invalid
             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 '
 
@@ -107,11 +386,111 @@ def write_pov(filename, scene=None, info_callback=None):
                 if raytrace_mirror.reflect_factor:
                     file.write('\treflection {\n')
                     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:
             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
@@ -134,15 +513,17 @@ def write_pov(filename, scene=None, info_callback=None):
 
         # compute resolution
         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('\tlocation  <0, 0, 0>\n')
         file.write('\tlook_at  <0, 0, -1>\n')
         file.write('\tright <%s, 0, 0>\n' % - Qsize)
         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('}\n')
 
@@ -153,7 +534,7 @@ def write_pov(filename, scene=None, info_callback=None):
 
             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('\t< 0,0,0 >\n')
@@ -165,8 +546,8 @@ def write_pov(filename, scene=None, info_callback=None):
                 file.write('\tspotlight\n')
 
                 # 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('\tradius %.6f\n' % ((math.degrees(lamp.spot_size) / 2.0) * (1.0 - lamp.spot_blend)))
+                file.write('\tfalloff %.2f\n' % (degrees(lamp.spot_size) / 2.0)) # 1 TO 179 FOR BOTH
+                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.
                 file.write('\ttightness 0\n') # 0:10f
@@ -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'
 
             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
                 samples_x = lamp.shadow_ray_samples_x
                 if lamp.shape == 'SQUARE':
@@ -188,7 +570,7 @@ def write_pov(filename, scene=None, info_callback=None):
                     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))
-                if lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED':
+                if lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED':
                     if lamp.jitter:
                         file.write('\tjitter\n')
                 else:
@@ -198,11 +580,55 @@ def write_pov(filename, scene=None, info_callback=None):
             if lamp.shadow_method == 'NOSHADOW':
                 file.write('\tshadowless\n')
 
-            file.write('\tfade_distance %.6f\n' % lamp.distance)
-            file.write('\tfade_power %d\n' % 1) # Could use blenders lamp quad?
+            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_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)
 
             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):
 
@@ -426,14 +852,204 @@ def write_pov(filename, scene=None, info_callback=None):
                     material_finish = DEF_MAT_NAME # not working properly,
                     trans = 0.0
 
-                #print material.apl
-                file.write(',\n\t\ttexture { pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} finish {%s}}' %
-                            (col[0], col[1], col[2], 1.0 - material.alpha, trans, material_finish))
+                ##############SF
+                texturesDif=''
+                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
                 idx += 1
 
-            file.write('\n  }\n')
+            file.write('\n\t}\n')
 
             # Face indicies
             file.write('\tface_indices {\n')
@@ -523,12 +1139,15 @@ def write_pov(filename, scene=None, info_callback=None):
                         file.write(',\n\t\t<%d,%d,%d>' %\
                         (uniqueUVs[uvs[i1]][0],\
                          uniqueUVs[uvs[i2]][0],\
-                         uniqueUVs[uvs[i2]][0])) # vert count
+                         uniqueUVs[uvs[i3]][0]))
                 file.write('\n  }\n')
 
             if me.materials:
-                material = me.materials[0] # dodgy
-                writeObjectMaterial(material)
+                try:
+                    material = me.materials[0] # dodgy
+                    writeObjectMaterial(material)
+                except IndexError:
+                    print(me)
 
             writeMatrix(matrix)
             file.write('}\n')
@@ -536,8 +1155,60 @@ def write_pov(filename, scene=None, info_callback=None):
             bpy.data.meshes.remove(me)
 
     def exportWorld(world):
+        camera = scene.camera
+        matrix = camera.matrix_world
         if not world:
             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
 
@@ -555,6 +1226,7 @@ def write_pov(filename, scene=None, info_callback=None):
     def exportGlobalSettings(scene):
 
         file.write('global_settings {\n')
+        file.write('\tmax_trace_level 7\n')
 
         if scene.pov_radio_enable:
             file.write('\tradiosity {\n')
@@ -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\trecursion_limit %d\n" % scene.pov_radio_recursion_limit)
             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))
 
+        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')
 
 
@@ -587,8 +1274,8 @@ def write_pov(filename, scene=None, info_callback=None):
     exportCamera()
     #exportMaterials()
     sel = scene.objects
-    exportLamps(l for l in sel if l.type == 'LAMP')
-    exportMeta(l for l in sel if l.type == 'META')
+    exportLamps([l for l in sel if l.type == 'LAMP'])
+    exportMeta([l for l in sel if l.type == 'META'])
     exportMeshs(scene, sel)
     exportWorld(scene.world)
     exportGlobalSettings(scene)
@@ -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('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('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')
 
     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('Sampling_Method=2n')
         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:
         file.write('Antialias=0\n')
 
@@ -637,24 +1331,26 @@ def write_pov_ini(filename_ini, filename_pov, filename_image):
 
 
 class PovrayRender(bpy.types.RenderEngine):
-    bl_idname = 'POVRAY_RENDER'
-    bl_label = "Povray"
+    bl_idname = 'POVRAY_37_RENDER'
+    bl_label = "Povray 3.7"
     DELAY = 0.02
 
     def _export(self, scene):
         import tempfile
 
         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_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'
         '''
 
         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)
 
@@ -673,7 +1369,7 @@ class PovrayRender(bpy.types.RenderEngine):
 
         if sys.platform == 'win32':
             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:
                 pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64'
@@ -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
             except OSError:
                 # 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
                 traceback.print_exc()
                 print ("***-DONE-***")
@@ -710,15 +1406,23 @@ class PovrayRender(bpy.types.RenderEngine):
 
     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.update_stats("", "POVRAY: Parsing File")
+        self.update_stats("", "POVRAY 3.7: Parsing File")
 
         if not self._render():
-            self.update_stats("", "POVRAY: Not found")
+            self.update_stats("", "POVRAY 3.7: Not found")
             return
 
         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
         x = int(r.resolution_x * r.resolution_percentage * 0.01)
@@ -734,14 +1438,14 @@ class PovrayRender(bpy.types.RenderEngine):
                 break
 
             if self._process.poll() != None:
-                self.update_stats("", "POVRAY: Failed")
+                self.update_stats("", "POVRAY 3.7: Failed")
                 break
 
             time.sleep(self.DELAY)
 
         if os.path.exists(self._temp_file_out):
 
-            self.update_stats("", "POVRAY: Rendering")
+            self.update_stats("", "POVRAY 3.7: Rendering")
 
             prev_size = -1
 
diff --git a/render_povray/ui.py b/render_povray/ui.py
index 2d2a6d627..e48c038ee 100644
--- a/render_povray/ui.py
+++ b/render_povray/ui.py
@@ -20,18 +20,18 @@ import bpy
 
 # Use some of the existing buttons.
 import properties_render
-properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_render.RENDER_PT_output.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_37_RENDER')
+properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_37_RENDER')
+properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_37_RENDER')
 del properties_render
 
 # Use only a subset of the world panels
 import properties_world
-properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
-properties_world.WORLD_PT_mist.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_37_RENDER')
+properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_37_RENDER')
+properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_37_RENDER')
 del properties_world
 
 # Example of wrapping every class 'as is'
@@ -39,7 +39,7 @@ import properties_material
 for member in dir(properties_material):
     subclass = getattr(properties_material, member)
     try:
-        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
+        subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
     except:
         pass
 del properties_material
@@ -48,7 +48,7 @@ import properties_data_mesh
 for member in dir(properties_data_mesh):
     subclass = getattr(properties_data_mesh, member)
     try:
-        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
+        subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
     except:
         pass
 del properties_data_mesh
@@ -57,7 +57,7 @@ import properties_texture
 for member in dir(properties_texture):
     subclass = getattr(properties_texture, member)
     try:
-        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
+        subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
     except:
         pass
 del properties_texture
@@ -66,11 +66,20 @@ import properties_data_camera
 for member in dir(properties_data_camera):
     subclass = getattr(properties_data_camera, member)
     try:
-        subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
+        subclass.COMPAT_ENGINES.add('POVRAY_37_RENDER')
     except:
         pass
 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():
@@ -84,10 +93,154 @@ class RenderButtonsPanel():
         rd = context.scene.render
         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):
     bl_label = "Radiosity"
-    COMPAT_ENGINES = {'POVRAY_RENDER'}
+    COMPAT_ENGINES = {'POVRAY_37_RENDER'}
 
     def draw_header(self, context):
         scene = context.scene
-- 
GitLab