diff --git a/render_povray/render.py b/render_povray/render.py index 28a09a1586622a7c3a28c6a166ba3a6ce687832c..2010628007e1e1298c8a029e12e6b962d96273ce 100644 --- a/render_povray/render.py +++ b/render_povray/render.py @@ -168,6 +168,10 @@ 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): + + # DH - modified some variables to be function local, avoiding RNA write + # this should be checked to see if it is functionally correct + 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 @@ -176,22 +180,26 @@ def write_pov(filename, scene=None, info_callback=None): file.write('\tinterior { ior %.6f\n' % material.raytrace_transparency.ior) else: file.write('\tinterior { ior %.6f\n' % material.raytrace_transparency.ior) - + + pov_fake_caustics = False + pov_photons_refraction = False + pov_photons_reflection = False + if material.pov_refraction_type=="0": - material.pov_fake_caustics = False - material.pov_photons_refraction = False - material.pov_photons_reflection = True + pov_fake_caustics = False + pov_photons_refraction = False + pov_photons_reflection = True elif material.pov_refraction_type=="1": - material.pov_fake_caustics = True - material.pov_photons_refraction = False + pov_fake_caustics = True + pov_photons_refraction = False elif material.pov_refraction_type=="2": - material.pov_fake_caustics = False - material.pov_photons_refraction = True + pov_fake_caustics = False + pov_photons_refraction = True #If only Raytrace transparency is set, its IOR will be used for refraction, but user can set up "un-physical" fresnel reflections in raytrace mirror parameters. #Last, if none of the above is specified, user can set up "un-physical" fresnel reflections in raytrace mirror parameters. And pov IOR defaults to 1. if material.pov_caustics_enable: - if material.pov_fake_caustics: + if pov_fake_caustics: file.write('\tcaustics %.3g\n' % material.pov_fake_caustics_power) if material.pov_photons_refraction: file.write('\tdispersion %.3g\n' % material.pov_photons_dispersion) #Default of 1 means no dispersion @@ -204,12 +212,12 @@ def write_pov(filename, scene=None, info_callback=None): # (variable) dispersion_samples (constant count for now) file.write('\t}\n') - if material.pov_photons_refraction or material.pov_photons_reflection: + if pov_photons_refraction or pov_photons_reflection: file.write('\tphotons{\n') file.write('\t\ttarget\n') - if material.pov_photons_refraction: + if pov_photons_refraction: file.write('\t\trefraction on\n') - if material.pov_photons_reflection: + if pov_photons_reflection: file.write('\t\treflection on\n') file.write('\t}\n') @@ -377,7 +385,9 @@ def write_pov(filename, scene=None, info_callback=None): def exportCamera(): camera = scene.camera - active_object = bpy.context.active_object # MR + + # DH disabled for now, this isn't the correct context + active_object = None #bpy.context.active_object # MR matrix = camera.matrix_world focal_point = camera.data.dof_distance @@ -387,7 +397,7 @@ def write_pov(filename, scene=None, info_callback=None): file.write('#declare camLookAt = <%.6f, %.6f, %.6f>;\n' % tuple([degrees(e) for e in matrix.rotation_part().to_euler()])) file.write('camera {\n') - if scene.pov_baking_enable and active_object.type=='MESH': + if scene.pov_baking_enable and active_object and active_object.type=='MESH': file.write('\tmesh_camera{ 1 3\n') # distribution 3 is what we want here file.write('\t\tmesh{%s}\n' % active_object.name) file.write('\t}\n') @@ -1240,7 +1250,7 @@ def write_pov_ini(filename_ini, filename_pov, filename_image): class PovrayRender(bpy.types.RenderEngine): bl_idname = 'POVRAY_RENDER' bl_label = "Povray 3.7" - DELAY = 0.02 + DELAY = 0.05 def _export(self, scene): import tempfile @@ -1273,7 +1283,9 @@ class PovrayRender(bpy.types.RenderEngine): print ("***-STARTING-***") pov_binary = "povray" - + + extra_args = [] + if sys.platform == 'win32': import winreg regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.7\\Windows') @@ -1282,11 +1294,14 @@ class PovrayRender(bpy.types.RenderEngine): pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine64' else: pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine' + else: + # DH - added -d option to prevent render window popup which leads to segfault on linux + extra_args.append("-d") if 1: # TODO, when povray isnt found this gives a cryptic error, would be nice to be able to detect if it exists try: - 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] + extra_args) # stdout=subprocess.PIPE, stderr=subprocess.PIPE except OSError: # TODO, report api print("POVRAY 3.7: could not execute '%s', possibly povray isn't installed" % pov_binary) @@ -1299,18 +1314,21 @@ class PovrayRender(bpy.types.RenderEngine): # This works too but means we have to wait until its done os.system('%s %s' % (pov_binary, self._temp_file_ini)) - print ("***-DONE-***") + # print ("***-DONE-***") return True def _cleanup(self): for f in (self._temp_file_in, self._temp_file_ini, self._temp_file_out): try: os.remove(f) + pass except OSError: #was that the proper error type? pass self.update_stats("", "") - + + _process = None + def render(self, scene): self.update_stats("", "POVRAY 3.7: Exporting data from Blender") @@ -1337,26 +1355,32 @@ class PovrayRender(bpy.types.RenderEngine): # Wait for the file to be created while not os.path.exists(self._temp_file_out): + # print("***POV WAITING FOR FILE***") if self.test_break(): try: - self._process.terminate() + # DH - added various checks for _process and some debug output print()s + if self._process: self._process.terminate() + print("***POV INTERRUPTED***") except: #OSError: #was that the proper error type? pass break - - if self._process.poll() != None: + + poll_result = self._process.poll() + if self._process and poll_result != None: + print("***POV PROCESS FAILED : %s ***" % poll_result) self.update_stats("", "POVRAY 3.7: Failed") break time.sleep(self.DELAY) if os.path.exists(self._temp_file_out): - + # print("***POV FILE OK***") self.update_stats("", "POVRAY 3.7: Rendering") prev_size = -1 def update_image(): + # print("***POV UPDATING IMAGE***") result = self.begin_result(0, 0, x, y) lay = result.layers[0] # possible the image wont load early on. @@ -1368,16 +1392,19 @@ class PovrayRender(bpy.types.RenderEngine): # Update while povray renders while True: + # print("***POV RENDER LOOP***") # test if povray exists - if self._process.poll() is not None: + if self._process and self._process.poll() != None: + print("***POV PROCESS FINISHED***") update_image() break # user exit if self.test_break(): try: - self._process.terminate() + if self._process: self._process.terminate() + print("***POV PROCESS INTERRUPTED***") except: #OSError: #was that the proper error type? pass @@ -1395,7 +1422,10 @@ class PovrayRender(bpy.types.RenderEngine): prev_size = new_size time.sleep(self.DELAY) - + else: + print("***POV FILE NOT FOUND***") + + print("***POV FINISHED***") self._cleanup()