Skip to content
Snippets Groups Projects
render.py 71.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 if not me_materials or me_materials[material_index] is None: # No materials
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                        for i1, i2, i3 in indicies:
                            file.write(',\n\t\t<%d,%d,%d>' % (fv[i1], fv[i2], fv[i3])) # vert count
                    else:
                        material = me_materials[material_index]
                        for i1, i2, i3 in indicies:
    
                            if me.vertex_colors and material.use_vertex_color_paint:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                                # Colour per vertex - vertex colour
    
                                col1 = cols[i1]
                                col2 = cols[i2]
                                col3 = cols[i3]
    
                                ci1 = vertCols[col1[0], col1[1], col1[2], material_index][0]
                                ci2 = vertCols[col2[0], col2[1], col2[2], material_index][0]
                                ci3 = vertCols[col3[0], col3[1], col3[2], material_index][0]
                            else:
                                # Colour per material - flat material colour
                                diffuse_color = material.diffuse_color
                                ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], diffuse_color[2], f.material_index][0]
    
                            file.write(',\n\t\t<%d,%d,%d>, %d,%d,%d' % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3)) # vert count
    
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                # normal_indices indicies
                file.write('\tnormal_indices {\n')
                file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
                for fi, fv in enumerate(faces_verts):
    
                    if len(fv) == 4:
                        indicies = (0, 1, 2), (0, 2, 3)
                    else:
                        indicies = ((0, 1, 2),)
    
                    for i1, i2, i3 in indicies:
    
                        if f.use_smooth:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                            file.write(',\n\t\t<%d,%d,%d>' %\
                            (uniqueNormals[verts_normals[fv[i1]]][0],\
                             uniqueNormals[verts_normals[fv[i2]]][0],\
                             uniqueNormals[verts_normals[fv[i3]]][0])) # vert count
                        else:
                            idx = uniqueNormals[faces_normals[fi]][0]
                            file.write(',\n\t\t<%d,%d,%d>' % (idx, idx, idx)) # vert count
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                if uv_layer:
                    file.write('\tuv_indices {\n')
                    file.write('\t\t%d' % (len(me.faces) + quadCount)) # faces count
                    for fi, fv in enumerate(faces_verts):
    
                        if len(fv) == 4:
                            indicies = (0, 1, 2), (0, 2, 3)
                        else:
                            indicies = ((0, 1, 2),)
    
                        uv = uv_layer[fi]
                        if len(faces_verts[fi]) == 4:
                            uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3), tuple(uv.uv4)
                        else:
                            uvs = tuple(uv.uv1), tuple(uv.uv2), tuple(uv.uv3)
    
                        for i1, i2, i3 in indicies:
                            file.write(',\n\t\t<%d,%d,%d>' %\
                            (uniqueUVs[uvs[i1]][0],\
                             uniqueUVs[uvs[i2]][0],\
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                             uniqueUVs[uvs[i3]][0]))
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    file.write('\n  }\n')
    
                if me.materials:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    try:
                        material = me.materials[0] # dodgy
                        writeObjectMaterial(material)
                    except IndexError:
                        print(me)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                writeMatrix(matrix)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                
                #Importance for radiosity sampling added here: 
                file.write('\tradiosity { importance %3g }\n' % importance) 
    
                file.write('}\n') # End of mesh block
    
                file.write('%s\n' % name) # Use named declaration to allow reference e.g. for baking. MR
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                bpy.data.meshes.remove(me)
    
        def exportWorld(world):
    
            render = scene.render
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            camera = scene.camera
    
            matrix = global_matrix * camera.matrix_world
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            if not world:
                return
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            #############Maurice#################################### 
            #These lines added to get sky gradient (visible with PNG output)
            if world:
                #For simple flat background:
                if not world.use_sky_blend:
    
                    #Non fully transparent background could premultiply alpha and avoid anti-aliasing display issue: 
                    if render.alpha_mode == 'PREMUL' or render.alpha_mode == 'PREMUL' :
    
                        file.write('background {rgbt<%.3g, %.3g, %.3g, 0.75>}\n' % (tuple(world.horizon_color)))
    
                    #Currently using no alpha with Sky option:
                    elif render.alpha_mode == 'SKY':
                        file.write('background {rgbt<%.3g, %.3g, %.3g, 0>}\n' % (tuple(world.horizon_color)))
                    #StraightAlpha:
    
                    else:
                        file.write('background {rgbt<%.3g, %.3g, %.3g, 1>}\n' % (tuple(world.horizon_color)))
    
                        
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                worldTexCount=0
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                #For Background image textures
                for t in world.texture_slots: #risk to write several sky_spheres but maybe ok.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    worldTexCount+=1
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    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
    
                        if t_blend.texture_coords=='ANGMAP':
                            mappingBlend = ("")
                        else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                            mappingBlend = (" translate <%.4g-0.5,%.4g-0.5,%.4g-0.5> rotate<0,0,0>  scale <%.4g,%.4g,%.4g>" % (t_blend.offset.x / 10 ,t_blend.offset.y / 10 ,t_blend.offset.z / 10, t_blend.scale.x*0.85 , t_blend.scale.y*0.85 , t_blend.scale.z*0.85 ))
                            #The initial position and rotation of the pov camera is probably creating the rotation offset should look into it someday but at least background won't rotate with the camera now. 
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        #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        
            
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                if worldTexCount==0:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if world.use_sky_blend:
                        file.write('sky_sphere {\n')            
                        file.write('\tpigment {\n')
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        file.write('\t\tgradient y\n')#maybe Should follow the advice of POV doc about replacing gradient for skysphere..5.5
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        file.write('\t\tcolor_map {\n')
    
                        if render.alpha_mode == 'STRAIGHT':
    
                            file.write('\t\t\t[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n' % (tuple(world.horizon_color)))
                            file.write('\t\t\t[1.0 rgbt<%.3g, %.3g, %.3g, 1>]\n' % (tuple(world.zenith_color)))
    
                        elif render.alpha_mode == 'PREMUL':
    
                            file.write('\t\t\t[0.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n' % (tuple(world.horizon_color)))
                            file.write('\t\t\t[1.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n' % (tuple(world.zenith_color))) #aa premult not solved with transmit 1
    
                            file.write('\t\t\t[0.0 rgbt<%.3g, %.3g, %.3g, 0>]\n' % (tuple(world.horizon_color)))
                            file.write('\t\t\t[1.0 rgbt<%.3g, %.3g, %.3g, 0>]\n' % (tuple(world.zenith_color)))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        file.write('\t\t}\n')
                        file.write('\t}\n')
                        file.write('}\n')
    
                        #sky_sphere alpha (transmit) is not translating into image alpha the same way as "background"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                if world.light_settings.use_indirect_light:
    
                    scene.pov_radio_enable=1 
    
                #Maybe change the above to scene.pov_radio_enable = world.light_settings.use_indirect_light ?
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    
            ###############################################################
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Campbell Barton's avatar
    Campbell Barton committed
            mist = world.mist_settings
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            if mist.use_mist:
                file.write('fog {\n')
                file.write('\tdistance %.6f\n' % mist.depth)
                file.write('\tcolor rgbt<%.3g, %.3g, %.3g, %.3g>\n' % (tuple(world.horizon_color) + (1 - mist.intensity,)))
                #file.write('\tfog_offset %.6f\n' % mist.start)
                #file.write('\tfog_alt 5\n')
                #file.write('\tturbulence 0.2\n')
                #file.write('\tturb_depth 0.3\n')
                file.write('\tfog_type 1\n')
                file.write('}\n')
    
            if scene.pov_media_enable:
                file.write('media {\n')
                file.write('\tscattering { 1, rgb %.3g}\n' % scene.pov_media_color)
                file.write('\tsamples %.d\n' % scene.pov_media_samples)
                file.write('}\n')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
        def exportGlobalSettings(scene):
    
            file.write('global_settings {\n')
    
            file.write('\tassumed_gamma 1.0\n')
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            file.write('\tmax_trace_level %d\n' % scene.pov_max_trace_level)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            if scene.pov_radio_enable:
                file.write('\tradiosity {\n')
                file.write("\t\tadc_bailout %.4g\n" % scene.pov_radio_adc_bailout)
                file.write("\t\talways_sample %d\n" % scene.pov_radio_always_sample)
                file.write("\t\tbrightness %.4g\n" % scene.pov_radio_brightness)
                file.write("\t\tcount %d\n" % scene.pov_radio_count)
                file.write("\t\terror_bound %.4g\n" % scene.pov_radio_error_bound)
                file.write("\t\tgray_threshold %.4g\n" % scene.pov_radio_gray_threshold)
                file.write("\t\tlow_error_factor %.4g\n" % scene.pov_radio_low_error_factor)
                file.write("\t\tmedia %d\n" % scene.pov_radio_media)
                file.write("\t\tminimum_reuse %.4g\n" % scene.pov_radio_minimum_reuse)
                file.write("\t\tnearest_count %d\n" % scene.pov_radio_nearest_count)
                file.write("\t\tnormal %d\n" % scene.pov_radio_normal)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                file.write("\t\tpretrace_start %.3g\n" % scene.pov_radio_pretrace_start)
                file.write("\t\tpretrace_end %.3g\n" % scene.pov_radio_pretrace_end)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                file.write("\t\trecursion_limit %d\n" % scene.pov_radio_recursion_limit)
                file.write('\t}\n')
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            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
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if world: 
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                file.write("\tambient_light rgb<%.3g, %.3g, %.3g>\n" % tuple(world.ambient_color))
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if material.pov_photons_refraction or material.pov_photons_reflection:
                file.write("\tphotons {\n")
                file.write("\t\tspacing 0.003\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                file.write("\t\tmax_trace_level 5\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                file.write("\t\tadc_bailout 0.1\n")
                file.write("\t\tgather 30, 150\n")
    
                
                file.write("\t}\n")
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            file.write('}\n')
    
    
        # Convert all materials to strings we can access directly per vertex.
        writeMaterial(None) # default material
    
        for material in bpy.data.materials:
            writeMaterial(material)
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        #exportMaterials()
        sel = scene.objects
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        exportLamps([l for l in sel if l.type == 'LAMP'])
        exportMeta([l for l in sel if l.type == 'META'])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        exportMeshs(scene, sel)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        exportCamera()
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        exportWorld(scene.world)
        exportGlobalSettings(scene)
    
        file.close()
        
    
    
    def write_pov_ini(filename_ini, filename_pov, filename_image):
        scene = bpy.data.scenes[0]
        render = scene.render
    
        x = int(render.resolution_x * render.resolution_percentage * 0.01)
        y = int(render.resolution_y * render.resolution_percentage * 0.01)
    
        file = open(filename_ini, 'w')
        file.write('Input_File_Name="%s"\n' % filename_pov)
        file.write('Output_File_Name="%s"\n' % filename_image)
    
        file.write('Width=%d\n' % x)
        file.write('Height=%d\n' % y)
    
        # Needed for border render.
        '''
        file.write('Start_Column=%d\n' % part.x)
        file.write('End_Column=%d\n' % (part.x+part.w))
    
        file.write('Start_Row=%d\n' % (part.y))
        file.write('End_Row=%d\n' % (part.y+part.h))
        '''
    
    
        file.write('Bounding_Method=2\n')#The new automatic BSP is faster in most scenes
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
        file.write('Display=1\n')#Activated (turn this back off when better live exchange is done between the two programs (see next comment)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        file.write('Pause_When_Done=0\n')
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        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
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        file.write('Output_Alpha=1\n')
    
    
        if render.use_antialiasing:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            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.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            file.write('Antialias=on\n')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            file.write('Antialias_Depth=%d\n' % aa_mapping[render.antialiasing_samples])
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            file.write('Antialias_Threshold=0.1\n')#rather high settings but necessary.
            file.write('Jitter=off\n')#prevent animation flicker
     
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        else:
            file.write('Antialias=0\n')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        file.close()
    
    
    class PovrayRender(bpy.types.RenderEngine):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        bl_idname = 'POVRAY_RENDER'
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        bl_label = "Povray 3.7"
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
        def _export(self, scene):
            import tempfile
    
            self._temp_file_in = tempfile.mktemp(suffix='.pov')
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            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')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            self._temp_file_ini = tempfile.mktemp(suffix='.ini')
            '''
            self._temp_file_in = '/test.pov'
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            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'
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            self._temp_file_ini = '/test.ini'
            '''
    
            def info_callback(txt):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                self.update_stats("", "POVRAY 3.7: " + txt)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            write_pov(self._temp_file_in, scene, info_callback)
    
        def _render(self):
    
            try:
                os.remove(self._temp_file_out) # so as not to load the old file
    
    Campbell Barton's avatar
    Campbell Barton committed
            except OSError:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                pass
    
            write_pov_ini(self._temp_file_ini, self._temp_file_in, self._temp_file_out)
    
            print ("***-STARTING-***")
    
            pov_binary = "povray"
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            if sys.platform == 'win32':
                import winreg
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\POV-Ray\\v3.7\\Windows')
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                if bitness == 64:
                    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")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            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] + extra_args) # stdout=subprocess.PIPE, stderr=subprocess.PIPE
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                except OSError:
                    # TODO, report api
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    print("POVRAY 3.7: could not execute '%s', possibly povray isn't installed" % pov_binary)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    import traceback
                    traceback.print_exc()
                    print ("***-DONE-***")
                    return False
    
            else:
                # This works too but means we have to wait until its done
                os.system('%s %s' % (pov_binary, self._temp_file_ini))
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            return True
    
        def _cleanup(self):
            for f in (self._temp_file_in, self._temp_file_ini, self._temp_file_out):
                try:
                    os.remove(f)
    
                except OSError:  #was that the proper error type?
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    pass
    
            self.update_stats("", "")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        def render(self, scene):
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            self.update_stats("", "POVRAY 3.7: Exporting data from Blender")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            self._export(scene)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            self.update_stats("", "POVRAY 3.7: Parsing File")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            if not self._render():
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                self.update_stats("", "POVRAY 3.7: Not found")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                return
    
            r = scene.render
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    ##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'
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            # compute resolution
            x = int(r.resolution_x * r.resolution_percentage * 0.01)
            y = int(r.resolution_y * r.resolution_percentage * 0.01)
    
            # Wait for the file to be created
            while not os.path.exists(self._temp_file_out):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                if self.test_break():
                    try:
    
    Campbell Barton's avatar
    Campbell Barton committed
                        self._process.terminate()
    
    Campbell Barton's avatar
    Campbell Barton committed
                    except OSError:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                        pass
                    break
    
    Campbell Barton's avatar
    Campbell Barton committed
                if poll_result is not None:
    
                    print("***POV PROCESS FAILED : %s ***" % poll_result)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    self.update_stats("", "POVRAY 3.7: Failed")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    break
    
                time.sleep(self.DELAY)
    
            if os.path.exists(self._temp_file_out):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                self.update_stats("", "POVRAY 3.7: Rendering")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                prev_size = -1
    
                def update_image():
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    result = self.begin_result(0, 0, x, y)
                    lay = result.layers[0]
                    # possible the image wont load early on.
                    try:
                        lay.load_from_file(self._temp_file_out)
    
    Campbell Barton's avatar
    Campbell Barton committed
                    except SystemError:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                        pass
                    self.end_result(result)
    
                # Update while povray renders
                while True:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                    # test if povray exists
    
    Campbell Barton's avatar
    Campbell Barton committed
                    if self._process.poll() is not None:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                        update_image()
                        break
    
                    # user exit
                    if self.test_break():
                        try:
    
    Campbell Barton's avatar
    Campbell Barton committed
                            self._process.terminate()
    
                            print("***POV PROCESS INTERRUPTED***")
    
    Campbell Barton's avatar
    Campbell Barton committed
                        except OSError:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                            pass
    
                        break
    
                    # Would be nice to redirect the output
                    # stdout_value, stderr_value = self._process.communicate() # locks
    
    
                    # check if the file updated
                    new_size = os.path.getsize(self._temp_file_out)
    
                    if new_size != prev_size:
                        update_image()
                        prev_size = new_size
    
                    time.sleep(self.DELAY)
    
            else:
                print("***POV FILE NOT FOUND***")
            
            print("***POV FINISHED***")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            self._cleanup()