Skip to content
Snippets Groups Projects
render.py 92.8 KiB
Newer Older
  • Learn to ignore specific revisions
  •                                 tabWrite("pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>}\n" % (col[0], col[1], col[2], povFilter, trans))
    
                                if texturesSpec != "":
                                    tabWrite("finish {%s}\n" % (safety(material_finish, Level=1)))  # Level 1 is no specular
    
                                else:
                                    tabWrite("finish {%s}\n" % (safety(material_finish, Level=2)))  # Level 2 is translated spec
    
                                # POV-Ray "scale" is not a number of repetitions factor, but its inverse, a standard scale factor.
                                # Offset seems needed relatively to scale so probably center of the scale is not the same in blender and POV
                                mappingDif = ("translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (-t_dif.offset.x, -t_dif.offset.y, t_dif.offset.z, 1.0 / t_dif.scale.x, 1.0 / t_dif.scale.y, 1.0 / t_dif.scale.z))
                                if texturesAlpha != "":
                                    # POV-Ray "scale" is not a number of repetitions factor, but its inverse, a standard scale factor.
                                    # Offset seems needed relatively to scale so probably center of the scale is not the same in blender and POV
                                    mappingAlpha = " translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (-t_alpha.offset.x, -t_alpha.offset.y, t_alpha.offset.z, 1.0 / t_alpha.scale.x, 1.0 / t_alpha.scale.y, 1.0 / t_alpha.scale.z)
                                    tabWrite("pigment {\n")
                                    tabWrite("pigment_pattern {\n")
                                    tabWrite("uv_mapping image_map{%s \"%s\" %s}%s}\n" % (imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha), mappingAlpha))
                                    tabWrite("pigment_map {\n")
                                    tabWrite("[0 color rgbft<0,0,0,1,1>]\n")
                                    tabWrite("[1 uv_mapping image_map {%s \"%s\" %s} %s]\n" % (imageFormat(texturesDif), texturesDif, (imgGamma + imgMap(t_dif)), mappingDif))
                                    tabWrite("}\n")
                                    tabWrite("}\n")
    
                                else:
                                    tabWrite("pigment {uv_mapping image_map {%s \"%s\" %s}%s}\n" % (imageFormat(texturesDif), texturesDif, (imgGamma + imgMap(t_dif)), mappingDif))
    
                                if texturesSpec != "":
                                    tabWrite("finish {%s}\n" % (safety(material_finish, Level=1)))  # Level 1 is no specular
    
                                else:
                                    tabWrite("finish {%s}\n" % (safety(material_finish, Level=2)))  # Level 2 is translated specular
    
                                ## scale 1 rotate y*0
                                #imageMap = ("{image_map {%s \"%s\" %s }\n" % (imageFormat(textures),textures,imgMap(t_dif)))
                                #tabWrite("uv_mapping pigment %s} %s finish {%s}\n" % (imageMap,mapping,safety(material_finish)))
                                #tabWrite("pigment {uv_mapping image_map {%s \"%s\" %s}%s} finish {%s}\n" % (imageFormat(texturesDif),texturesDif,imgMap(t_dif),mappingDif,safety(material_finish)))
                            if texturesNorm != "":
                                ## scale 1 rotate y*0
                                # POV-Ray "scale" is not a number of repetitions factor, but its inverse, a standard scale factor.
                                # Offset seems needed relatively to scale so probably center of the scale is not the same in blender and POV
                                mappingNor = " translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (-t_nor.offset.x, -t_nor.offset.y, t_nor.offset.z, 1.0 / t_nor.scale.x, 1.0 / t_nor.scale.y, 1.0 / t_nor.scale.z)
                                #imageMapNor = ("{bump_map {%s \"%s\" %s mapping}" % (imageFormat(texturesNorm),texturesNorm,imgMap(t_nor)))
                                #We were not using the above maybe we should?
                                tabWrite("normal {uv_mapping bump_map {%s \"%s\" %s  bump_size %.4g }%s}\n" % (imageFormat(texturesNorm), texturesNorm, imgMap(t_nor), t_nor.normal_factor * 10, mappingNor))
    
                            if texturesSpec != "":
    
                                tabWrite("]\n")
                            ################################Second index for mapping specular max value##################################################################################################
                                tabWrite("[1 \n")
    
                    if texturesDif == "" and material.pov_replacement_text == "":
    
                        if texturesAlpha != "":
    
                            # POV-Ray "scale" is not a number of repetitions factor, but its inverse, a standard scale factor.
                            # Offset seems needed relatively to scale so probably center of the scale is not the same in blender and POV
    
                            mappingAlpha = " translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>\n" % (-t_alpha.offset.x, -t_alpha.offset.y, t_alpha.offset.z, 1.0 / t_alpha.scale.x, 1.0 / t_alpha.scale.y, 1.0 / t_alpha.scale.z)  # strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
    
                            tabWrite("pigment {pigment_pattern {uv_mapping image_map{%s \"%s\" %s}%s}\n" % (imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha), mappingAlpha))
                            tabWrite("pigment_map {\n")
                            tabWrite("[0 color rgbft<0,0,0,1,1>]\n")
    
                            tabWrite("[1 color rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>]\n" % (col[0], col[1], col[2], povFilter, trans))
    
                            tabWrite("pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>}\n" % (col[0], col[1], col[2], povFilter, trans))
    
                        if texturesSpec != "":
    
                            tabWrite("finish {%s}\n" % (safety(material_finish, Level=3)))  # Level 3 is full specular
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        else:
    
                            tabWrite("finish {%s}\n" % (safety(material_finish, Level=2)))  # Level 2 is translated specular
    
                        # POV-Ray "scale" is not a number of repetitions factor, but its inverse, a standard scale factor.
                        # Offset seems needed relatively to scale so probably center of the scale is not the same in blender and POV
    
                        mappingDif = ("translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (-t_dif.offset.x, -t_dif.offset.y, t_dif.offset.z, 1.0 / t_dif.scale.x, 1.0 / t_dif.scale.y, 1.0 / t_dif.scale.z))  # 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,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (-t_alpha.offset.x, -t_alpha.offset.y, t_alpha.offset.z, 1.0 / t_alpha.scale.x, 1.0 / t_alpha.scale.y, 1.0 / t_alpha.scale.z)  # strange that the translation factor for scale is not the same as for translate. ToDo: verify both matches with blender internal.
    
                            tabWrite("pigment {pigment_pattern {uv_mapping image_map{%s \"%s\" %s}%s}\n" % (imageFormat(texturesAlpha), texturesAlpha, imgMap(t_alpha), mappingAlpha))
                            tabWrite("pigment_map {\n")
                            tabWrite("[0 color rgbft<0,0,0,1,1>]\n")
                            tabWrite("[1 uv_mapping image_map {%s \"%s\" %s} %s]\n" % (imageFormat(texturesDif), texturesDif, (imgMap(t_dif) + imgGamma), mappingDif))
                            tabWrite("}\n")
                            tabWrite("}\n")
    
                            tabWrite("pigment {\n")
                            tabWrite("uv_mapping image_map {\n")
                            #tabWrite("%s \"%s\" %s}%s\n" % (imageFormat(texturesDif),texturesDif,(imgGamma + imgMap(t_dif)),mappingDif))
    
                            tabWrite("%s \"%s\" \n" % (imageFormat(texturesDif), texturesDif))
                            tabWrite("%s\n" % (imgGamma + imgMap(t_dif)))
    
                            tabWrite("}\n")
                            tabWrite("%s\n" % mappingDif)
                            tabWrite("}\n")
    
                        if texturesSpec != "":
    
                            tabWrite("finish {%s}\n" % (safety(material_finish, Level=3)))  # Level 3 is full specular
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        else:
    
                            tabWrite("finish {%s}\n" % (safety(material_finish, Level=2)))  # Level 2 is translated specular
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                        ## 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 != "" and material.pov_replacement_text == "":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        ## scale 1 rotate y*0
    
                        # POV-Ray "scale" is not a number of repetitions factor, but its inverse, a standard scale factor.
                        # Offset seems needed relatively to scale so probably center of the scale is not the same in blender and POV
    
                        mappingNor = (" translate <%.4g,%.4g,%.4g> scale <%.4g,%.4g,%.4g>" % (-t_nor.offset.x, -t_nor.offset.y, t_nor.offset.z, 1.0 / t_nor.scale.x, 1.0 / t_nor.scale.y, 1.0 / t_nor.scale.z))
    
                        #imageMapNor = ("{bump_map {%s \"%s\" %s mapping}" % (imageFormat(texturesNorm),texturesNorm,imgMap(t_nor)))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        #We were not using the above maybe we should?
    
                        tabWrite("normal {uv_mapping bump_map {%s \"%s\" %s  bump_size %.4g }%s}\n" % (imageFormat(texturesNorm), texturesNorm, imgMap(t_nor), t_nor.normal_factor * 10.0, mappingNor))
    
                    if texturesSpec != "" and material.pov_replacement_text == "":
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                    #End of slope/ior texture_map
    
                    if material.diffuse_shader == 'MINNAERT' and material.pov_replacement_text == "":
    
                        tabWrite("]\n")
                        tabWrite("}\n")
    
                    if material.diffuse_shader == 'FRESNEL' and material.pov_replacement_text == "":
                        c = 1
                        while (c <= lampCount):
                            tabWrite("]\n")
                            tabWrite("}\n")
                            c += 1
    
    
                    if material.pov_replacement_text == "":
                        tabWrite("}\n")  # THEN IT CAN CLOSE IT   --MR
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
                    ############################################################################################################
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    index[0] = idx
                    idx += 1
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                tabWrite("face_indices {\n")
                tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
    
                for fi, f in enumerate(me_faces):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    fv = faces_verts[fi]
                    material_index = f.material_index
                    if len(fv) == 4:
    
                        indices = (0, 1, 2), (0, 2, 3)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    else:
    
                        indices = ((0, 1, 2),)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                    if vcol_layer:
                        col = vcol_layer[fi]
    
                        if len(fv) == 4:
                            cols = col.color1, col.color2, col.color3, col.color4
                        else:
                            cols = col.color1, col.color2, col.color3
    
    
                    if not me_materials or me_materials[material_index] is None:  # No materials
    
                        for i1, i2, i3 in indices:
    
                            if not scene.pov_tempfiles_enable and scene.pov_list_lf_enable:
                                file.write(",\n")
                                file.write(tabStr + "<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))  # vert count
                            else:
                                file.write(", ")
                                file.write("<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))  # vert count
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    else:
                        material = me_materials[material_index]
    
                        for i1, i2, i3 in indices:
    
                            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]
    
    
                            if not scene.pov_tempfiles_enable and scene.pov_list_lf_enable:
                                file.write(",\n")
                                file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3))  # vert count
                            else:
                                file.write(", ")
                                file.write("<%d,%d,%d>, %d,%d,%d" % (fv[i1], fv[i2], fv[i3], ci1, ci2, ci3))  # vert count
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                # normal_indices indices
    
                tabWrite("normal_indices {\n")
                tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                for fi, fv in enumerate(faces_verts):
    
                    if len(fv) == 4:
    
                        indices = (0, 1, 2), (0, 2, 3)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    else:
    
                        indices = ((0, 1, 2),)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                    for i1, i2, i3 in indices:
    
                        if me_faces[fi].use_smooth:
    
                            if not scene.pov_tempfiles_enable and scene.pov_list_lf_enable:
                                file.write(",\n")
                                file.write(tabStr + "<%d,%d,%d>" %\
                                (uniqueNormals[verts_normals[fv[i1]]][0],\
                                 uniqueNormals[verts_normals[fv[i2]]][0],\
                                 uniqueNormals[verts_normals[fv[i3]]][0]))  # vert count
                            else:
                                file.write(", ")
                                file.write("<%d,%d,%d>" %\
                                (uniqueNormals[verts_normals[fv[i1]]][0],\
                                 uniqueNormals[verts_normals[fv[i2]]][0],\
                                 uniqueNormals[verts_normals[fv[i3]]][0]))  # vert count
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                        else:
                            idx = uniqueNormals[faces_normals[fi]][0]
    
                            if not scene.pov_tempfiles_enable and scene.pov_list_lf_enable:
                                file.write(",\n")
                                file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx))  # vert count
                            else:
                                file.write(", ")
                                file.write("<%d,%d,%d>" % (idx, idx, idx))  # vert count
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                if uv_layer:
    
                    tabWrite("uv_indices {\n")
                    tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                    for fi, fv in enumerate(faces_verts):
    
                        if len(fv) == 4:
    
                            indices = (0, 1, 2), (0, 2, 3)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                        else:
    
                            indices = ((0, 1, 2),)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                        uv = uv_layer[fi]
                        if len(faces_verts[fi]) == 4:
    
                            uvs = uv.uv1[:], uv.uv2[:], uv.uv3[:], uv.uv4[:]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                        else:
    
                            uvs = uv.uv1[:], uv.uv2[:], uv.uv3[:]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                        for i1, i2, i3 in indices:
    
                            if not scene.pov_tempfiles_enable and scene.pov_list_lf_enable:
                                file.write(",\n")
                                file.write(tabStr + "<%d,%d,%d>" % (
                                         uniqueUVs[uvs[i1]][0],\
                                         uniqueUVs[uvs[i2]][0],\
                                         uniqueUVs[uvs[i3]][0]))
                            else:
                                file.write(", ")
                                file.write("<%d,%d,%d>" % (
                                         uniqueUVs[uvs[i1]][0],\
                                         uniqueUVs[uvs[i2]][0],\
                                         uniqueUVs[uvs[i3]][0]))
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                if me.materials:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    try:
    
                        material = me.materials[0]  # dodgy
    
                        writeObjectMaterial(material, ob)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    except IndexError:
                        print(me)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
                writeMatrix(matrix)
    
    
                #Importance for radiosity sampling added here:
    
                tabWrite("radiosity { \n")
                tabWrite("importance %3g \n" % importance)
                tabWrite("}\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    
    
                tabWrite("}\n")  # End of mesh block
                tabWrite("%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####################################
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            #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:
    
    Maurice Raybaud's avatar
     
    Maurice Raybaud committed
                    if render.alpha_mode == 'PREMUL':
    
                        tabWrite("background {rgbt<%.3g, %.3g, %.3g, 0.75>}\n" % (world.horizon_color[:]))
    
                    #Currently using no alpha with Sky option:
                    elif render.alpha_mode == 'SKY':
    
                        tabWrite("background {rgbt<%.3g, %.3g, %.3g, 0>}\n" % (world.horizon_color[:]))
    
                        tabWrite("background {rgbt<%.3g, %.3g, %.3g, 1>}\n" % (world.horizon_color[:]))
    
                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.
    
                    if t and t.texture.type is not None:
    
                        worldTexCount += 1
                    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:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                            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
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        #using camera rotation valuesdirectly from blender seems much easier
    
                        if t_blend.texture_coords == 'ANGMAP':
                            mappingBlend = ""
    
                            mappingBlend = " translate <%.4g-0.5,%.4g-0.5,%.4g-0.5> rotate<0,0,0>  scale <%.4g,%.4g,%.4g>" % (
                                           t_blend.offset.x / 10.0, t_blend.offset.y / 10.0, t_blend.offset.z / 10.0,
                                           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.
    
                        tabWrite("sky_sphere {\n")
                        tabWrite("pigment {\n")
                        tabWrite("image_map{%s \"%s\" %s}\n" % (imageFormat(texturesBlend), texturesBlend, imgMapBG(t_blend)))
                        tabWrite("}\n")
                        tabWrite("%s\n" % (mappingBlend))
    
    Campbell Barton's avatar
    Campbell Barton committed
                        # The following layered pigment opacifies to black over the texture  for transmit below 1 or otherwise adds to itself
    
                        tabWrite("pigment {rgb 0 transmit %s}\n" % (t.texture.intensity))
    
                        tabWrite("}\n")
                        #tabWrite("scale 2\n")
                        #tabWrite("translate -1\n")
    
    
                #For only Background gradient
    
                if worldTexCount == 0:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                    if world.use_sky_blend:
    
                        tabWrite("sky_sphere {\n")
                        tabWrite("pigment {\n")
                        tabWrite("gradient y\n")  # maybe Should follow the advice of POV doc about replacing gradient for skysphere..5.5
                        tabWrite("color_map {\n")
    
                        if render.alpha_mode == 'STRAIGHT':
    
                            tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.horizon_color[:]))
                            tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 1>]\n" % (world.zenith_color[:]))
    
                        elif render.alpha_mode == 'PREMUL':
    
                            tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" % (world.horizon_color[:]))
                            tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 0.99>]\n" % (world.zenith_color[:]))  # aa premult not solved with transmit 1
    
                            tabWrite("[0.0 rgbt<%.3g, %.3g, %.3g, 0>]\n" % (world.horizon_color[:]))
                            tabWrite("[1.0 rgbt<%.3g, %.3g, %.3g, 0>]\n" % (world.zenith_color[:]))
                        tabWrite("}\n")
                        tabWrite("}\n")
                        tabWrite("}\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        #sky_sphere alpha (transmit) is not translating into image alpha the same way as 'background'
    
                #if world.light_settings.use_indirect_light:
    
                #    scene.pov_radio_enable=1
    
    
                #Maybe change the above to a funtion copyInternalRenderer settings when user pushes a button, then:
    
                #scene.pov_radio_enable = world.light_settings.use_indirect_light
    
                #and other such translations but maybe this would not be allowed either?
    
    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:
    
                tabWrite("fog {\n")
                tabWrite("distance %.6f\n" % mist.depth)
                tabWrite("color rgbt<%.3g, %.3g, %.3g, %.3g>\n" % (world.horizon_color[:] + (1.0 - mist.intensity,)))
                #tabWrite("fog_offset %.6f\n" % mist.start)
                #tabWrite("fog_alt 5\n")
                #tabWrite("turbulence 0.2\n")
                #tabWrite("turb_depth 0.3\n")
                tabWrite("fog_type 1\n")
                tabWrite("}\n")
    
            if scene.pov_media_enable:
    
                tabWrite("scattering { 1, rgb <%.4g, %.4g, %.4g>}\n" % scene.pov_media_color[:])
    
                tabWrite("samples %.d\n" % scene.pov_media_samples)
                tabWrite("}\n")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
        def exportGlobalSettings(scene):
    
    
            tabWrite("global_settings {\n")
            tabWrite("assumed_gamma 1.0\n")
            tabWrite("max_trace_level %d\n" % scene.pov_max_trace_level)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            if scene.pov_radio_enable:
    
                tabWrite("radiosity {\n")
                tabWrite("adc_bailout %.4g\n" % scene.pov_radio_adc_bailout)
                tabWrite("always_sample %d\n" % scene.pov_radio_always_sample)
                tabWrite("brightness %.4g\n" % scene.pov_radio_brightness)
                tabWrite("count %d\n" % scene.pov_radio_count)
                tabWrite("error_bound %.4g\n" % scene.pov_radio_error_bound)
                tabWrite("gray_threshold %.4g\n" % scene.pov_radio_gray_threshold)
                tabWrite("low_error_factor %.4g\n" % scene.pov_radio_low_error_factor)
                tabWrite("media %d\n" % scene.pov_radio_media)
                tabWrite("minimum_reuse %.4g\n" % scene.pov_radio_minimum_reuse)
                tabWrite("nearest_count %d\n" % scene.pov_radio_nearest_count)
                tabWrite("normal %d\n" % scene.pov_radio_normal)
                tabWrite("pretrace_start %.3g\n" % scene.pov_radio_pretrace_start)
                tabWrite("pretrace_end %.3g\n" % scene.pov_radio_pretrace_end)
                tabWrite("recursion_limit %d\n" % scene.pov_radio_recursion_limit)
                tabWrite("}\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            for material in bpy.data.materials:
                if material.subsurface_scattering.use and once:
    
                    tabWrite("mm_per_unit %.6f\n" % (material.subsurface_scattering.scale * (-100.0) + 15.0))  # In pov, the scale has reversed influence compared to blender. these number should correct that
    
                    once = 0  # In POV-Ray, the scale factor for all subsurface shaders needs to be the same
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                tabWrite("ambient_light rgb<%.3g, %.3g, %.3g>\n" % world.ambient_color[:])
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            if material.pov_photons_refraction or material.pov_photons_reflection:
    
                tabWrite("spacing %.6f\n" % scene.pov_photon_spacing)
                tabWrite("max_trace_level %d\n" % scene.pov_photon_max_trace_level)
                tabWrite("adc_bailout %.3g\n" % scene.pov_photon_adc_bailout)
                tabWrite("gather %d, %d\n" % (scene.pov_photon_gather_min, scene.pov_photon_gather_max))
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
            for txt in bpy.data.texts:
                if txt.pov_custom_code:
                    # Why are the newlines needed?
                    file.write("\n")
                    file.write(txt.as_string())
                    file.write("\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        sel = scene.objects
        comments = scene.pov_comments_enable
    
        if not scene.pov_tempfiles_enable and comments:
    
            file.write("//---------------------------------------------\n//--Exported with POV-Ray exporter for Blender--\n//---------------------------------------------\n\n")
        file.write("#version 3.7;\n")
    
        if not scene.pov_tempfiles_enable and comments:
            file.write("\n//--CUSTOM CODE--\n\n")
        exportCustomCode()
    
        if not scene.pov_tempfiles_enable and comments:
    
            file.write("\n//--Global settings and background--\n\n")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        exportGlobalSettings(scene)
    
        if not scene.pov_tempfiles_enable and comments:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        exportWorld(scene.world)
    
        if not scene.pov_tempfiles_enable and comments:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        exportCamera()
    
        if not scene.pov_tempfiles_enable and comments:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        exportLamps([l for l in sel if l.type == 'LAMP'])
    
        if not scene.pov_tempfiles_enable and comments:
    
            file.write("\n//--Material Definitions--\n\n")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        # Convert all materials to strings we can access directly per vertex.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        #exportMaterials()
    
        writeMaterial(None)  # default material
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        for material in bpy.data.materials:
    
            if material.users > 0:
    
        if not scene.pov_tempfiles_enable and comments:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        exportMeta([l for l in sel if l.type == 'META'])
    
        if not scene.pov_tempfiles_enable and comments:
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        exportMeshs(scene, sel)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        #What follow used to happen here:
        #exportCamera()
        #exportWorld(scene.world)
        #exportGlobalSettings(scene)
    
        # MR:..and the order was important for an attempt to implement pov 3.7 baking (mesh camera) comment for the record
        # CR: Baking should be a special case than. If "baking", than we could change the order.
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
        #print("pov file closed %s" % file.closed)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        file.close()
    
        #print("pov file closed %s" % file.closed)
    
    def write_pov_ini(scene, filename_ini, filename_pov, filename_image):
        #scene = bpy.data.scenes[0]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        render = scene.render
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
        file.write("Width=%d\n" % x)
        file.write("Height=%d\n" % y)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
        # Border render.
        if render.use_border:
            file.write("Start_Column=%4g\n" % render.border_min_x)
            file.write("End_Column=%4g\n" % (render.border_max_x))
    
    
    Campbell Barton's avatar
    Campbell Barton committed
            file.write("Start_Row=%4g\n" % (1.0 - render.border_max_y))
            file.write("End_Row=%4g\n" % (1.0 - render.border_min_y))
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
        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=N\n")  # PNG, with POV-Ray 3.7, can show background color with alpha. In the long run using the POV-Ray 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")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
        if scene.pov_antialias_enable:
    
            # aa_mapping = {"5": 2, "8": 3, "11": 4, "16": 5} # method 2 (recursive) with higher max subdiv forced because no mipmapping in POV-Ray needs higher sampling.
            method = {"0": 1, "1": 2}
            file.write("Antialias=on\n")
            file.write("Sampling_Method=%s\n" % method[scene.pov_antialias_method])
            file.write("Antialias_Depth=%d\n" % scene.pov_antialias_depth)
            file.write("Antialias_Threshold=%.3g\n" % scene.pov_antialias_threshold)
            file.write("Antialias_Gamma=%.3g\n" % scene.pov_antialias_gamma)
    
            if scene.pov_jitter_enable:
    
                file.write("Jitter=on\n")
                file.write("Jitter_Amount=%3g\n" % scene.pov_jitter_amount)
    
                file.write("Jitter=off\n")  # prevent animation flicker
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        else:
    
            file.write("Antialias=off\n")
        #print("ini file closed %s" % file.closed)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        file.close()
    
        #print("ini file closed %s" % file.closed)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    class PovrayRender(bpy.types.RenderEngine):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        bl_idname = 'POVRAY_RENDER'
    
        def _export(self, scene, povPath, renderImagePath):
    
    Luca Bonavita's avatar
    Luca Bonavita committed
            import tempfile
    
            if scene.pov_tempfiles_enable:
                self._temp_file_in = tempfile.NamedTemporaryFile(suffix=".pov", delete=False).name
                self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".png", delete=False).name  # PNG with POV 3.7, can show the background color with alpha. In the long run using the POV-Ray interactive preview like bishop 3D could solve the preview for all formats.
                #self._temp_file_out = tempfile.NamedTemporaryFile(suffix=".tga", delete=False).name
                self._temp_file_ini = tempfile.NamedTemporaryFile(suffix=".ini", delete=False).name
            else:
                self._temp_file_in = povPath + ".pov"
                self._temp_file_out = renderImagePath + ".png"  # PNG with POV-Ray 3.7, can show the background color with alpha. In the long run using the POV-Ray interactive preview like bishop 3D could solve the preview for all formats.
                #self._temp_file_out = renderImagePath + ".tga"
                self._temp_file_ini = povPath + ".ini"
                '''
                self._temp_file_in = "/test.pov"
                self._temp_file_out = "/test.png"  # PNG with POV-Ray 3.7, can show the background color with alpha. In the long run using the POV-Ray interactive preview like bishop 3D could solve the preview for all formats.
                #self._temp_file_out = "/test.tga"
                self._temp_file_ini = "/test.ini"
                '''
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            def info_callback(txt):
    
                self.update_stats("", "POV-Ray 3.7: " + txt)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            write_pov(self._temp_file_in, scene, info_callback)
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
            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(scene, self._temp_file_ini, self._temp_file_in, self._temp_file_out)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
            if scene.pov_command_line_switches != "":
    
                for newArg in scene.pov_command_line_switches.split(" "):
    
            if sys.platform[:3] == "win":
    
                self._is_windows = True
                #extra_args.append("/EXIT")
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                import winreg
    
                import platform as pltfrm
                if pltfrm.architecture()[0] == "64bit":
                    bitness = 64
                else:
                    bitness = 32
    
    
                regKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Software\\POV-Ray\\v3.7\\Windows")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                if bitness == 64:
    
                        pov_binary = winreg.QueryValueEx(regKey, "Home")[0] + "\\bin\\pvengine64"
    
                        self._process = subprocess.Popen([pov_binary, self._temp_file_ini] + extra_args,
                                                         stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    
                        # This would work too but means we have to wait until its done:
                        # os.system("%s %s" % (pov_binary, self._temp_file_ini))
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
                    except OSError:
                        # someone might run povray 32 bits on a 64 bits blender machine
                        try:
    
                            pov_binary = winreg.QueryValueEx(regKey, "Home")[0] + "\\bin\\pvengine"
    
                            self._process = subprocess.Popen([pov_binary, self._temp_file_ini] + extra_args,
                                                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
                            print("POV-Ray 3.7: could not execute '%s', possibly POV-Ray isn't installed" % pov_binary)
    
                            import traceback
                            traceback.print_exc()
                            print ("***-DONE-***")
                            return False
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
                        else:
                            print("POV-Ray 3.7 64 bits could not execute, running 32 bits instead")
    
                            print("Command line arguments passed: " + str(extra_args))
                            return True
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
                    else:
                        print("POV-Ray 3.7 64 bits found")
    
                        print("Command line arguments passed: " + str(extra_args))
                        return True
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                else:
    
                        pov_binary = winreg.QueryValueEx(regKey, "Home")[0] + "\\bin\\pvengine"
    
                        self._process = subprocess.Popen([pov_binary, self._temp_file_ini] + extra_args,
                                                         stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
                    # someone might also run povray 64 bits with a 32 bits build of blender.
    
                            pov_binary = winreg.QueryValueEx(regKey, "Home")[0] + "\\bin\\pvengine64"
    
                            self._process = subprocess.Popen([pov_binary, self._temp_file_ini] + extra_args,
                                                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
                            print("POV-Ray 3.7: could not execute '%s', possibly POV-Ray isn't installed" % pov_binary)
    
                            import traceback
                            traceback.print_exc()
                            print ("***-DONE-***")
                            return False
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
                        else:
                            print("Running POV-Ray 3.7 64 bits build with 32 bits Blender, \nYou might want to run Blender 64 bits as well.")
    
                            print("Command line arguments passed: " + str(extra_args))
                            return True
    
    Campbell Barton's avatar
    Campbell Barton committed
    
    
                    else:
                        print("POV-Ray 3.7 32 bits found")
    
                        print("Command line arguments passed: " + str(extra_args))
                        return True
    
            else:
                # DH - added -d option to prevent render window popup which leads to segfault on linux
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                isExists = False
                sysPathList = os.getenv("PATH").split(':')
                sysPathList.append("")
    
                for dirName in sysPathList:
                    if (os.path.exists(os.path.join(dirName, pov_binary))):
                        isExists = True
                        break
    
                if not isExists:
                    print("POV-Ray 3.7: could not found execute '%s' - not if PATH" % pov_binary)
                    import traceback
                    traceback.print_exc()
                    print ("***-DONE-***")
                    return False
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                    self._process = subprocess.Popen([pov_binary, self._temp_file_ini] + extra_args,
                                                     stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    
    
                except OSError:
                    # TODO, report api
                    print("POV-Ray 3.7: could not execute '%s'" % pov_binary)
                    import traceback
                    traceback.print_exc()
                    print ("***-DONE-***")
                    return False
    
                else:
                    print("POV-Ray 3.7 found")
                    print("Command line arguments passed: " + str(extra_args))
                    return True
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        def _cleanup(self):
            for f in (self._temp_file_in, self._temp_file_ini, self._temp_file_out):
    
                for i in range(5):
                    try:
                        os.unlink(f)
                        break
                    except OSError:
                        # Wait a bit before retrying file might be still in use by Blender,
                        # and Windows does not know how to delete a file in use!
                        time.sleep(self.DELAY)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        def render(self, scene):
    
            import tempfile
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
            print("***INITIALIZING***")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    ##WIP output format
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    ##        if r.file_format == 'OPENEXR':
    ##            fformat = 'EXR'
    ##            render.color_mode = 'RGBA'
    ##        else:
    ##            fformat = 'TGA'
    
    ##            r.file_format = 'TARGA'
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    ##            r.color_mode = 'RGBA'
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
            blendSceneName = bpy.data.filepath.split(os.path.sep)[-1].split(".")[0]
            povSceneName = ""
            povPath = ""
            renderImagePath = ""
    
    
            scene.frame_set(scene.frame_current)  # has to be called to update the frame on exporting animations
    
    
            if not scene.pov_tempfiles_enable:
    
                # check paths
                povPath = bpy.path.abspath(scene.pov_scene_path).replace('\\', '/')
                if povPath == "":
                    if bpy.path.abspath("//") != "":
                        povPath = bpy.path.abspath("//")
                    else:
                        povPath = tempfile.gettempdir()
                elif povPath.endswith("/"):
                    if povPath == "/":
                        povPath = bpy.path.abspath("//")
                    else:
                        povPath = bpy.path.abspath(scene.pov_scene_path)
    
                if not os.path.exists(povPath):
    
                    try:
                        os.makedirs(povPath)
                    except:
                        import traceback
                        traceback.print_exc()
    
                        print("POV-Ray 3.7: Cannot create scenes directory: %r" % povPath)
                        self.update_stats("", "POV-Ray 3.7: Cannot create scenes directory %r" % povPath)
                        time.sleep(2.0)
                        return
    
    
                '''
                # Bug in POV-Ray RC3
                renderImagePath = bpy.path.abspath(scene.pov_renderimage_path).replace('\\','/')
                if renderImagePath == "":
                    if bpy.path.abspath("//") != "":
                        renderImagePath = bpy.path.abspath("//")
                    else:
                        renderImagePath = tempfile.gettempdir()
                    #print("Path: " + renderImagePath)
                elif path.endswith("/"):
                    if renderImagePath == "/":
                        renderImagePath = bpy.path.abspath("//")
                    else:
                        renderImagePath = bpy.path.abspath(scene.pov_renderimage_path)
                if not os.path.exists(path):
                    print("POV-Ray 3.7: Cannot find render image directory")
                    self.update_stats("", "POV-Ray 3.7: Cannot find render image directory")
                    time.sleep(2.0)
                    return
                '''
    
                # check name
                if scene.pov_scene_name == "":
                    if blendSceneName != "":
                        povSceneName = blendSceneName
                    else:
                        povSceneName = "untitled"
                else:
                    povSceneName = scene.pov_scene_name
                    if os.path.isfile(povSceneName):
                        povSceneName = os.path.basename(povSceneName)
                    povSceneName = povSceneName.split('/')[-1].split('\\')[-1]
                    if not povSceneName:
                        print("POV-Ray 3.7: Invalid scene name")
                        self.update_stats("", "POV-Ray 3.7: Invalid scene name")
                        time.sleep(2.0)
                        return
                    povSceneName = os.path.splitext(povSceneName)[0]
    
                print("Scene name: " + povSceneName)
                print("Export path: " + povPath)
    
                povPath = os.path.join(povPath, povSceneName)
    
                povPath = os.path.realpath(povPath)
    
                # renderImagePath = renderImagePath + "\\" + povSceneName  # for now this has to be the same like the pov output. Bug in POV-Ray RC3.
                renderImagePath = povPath  # Bugfix for POV-Ray RC3 bug
    
                # renderImagePath = os.path.realpath(renderImagePath)  # Bugfix for POV-Ray RC3 bug
    
    
                #print("Export path: %s" % povPath)
                #print("Render Image path: %s" % renderImagePath)
    
            # start export
            self.update_stats("", "POV-Ray 3.7: Exporting data from Blender")
            self._export(scene, povPath, renderImagePath)
            self.update_stats("", "POV-Ray 3.7: Parsing File")
    
            if not self._render(scene):
                self.update_stats("", "POV-Ray 3.7: Not found")
                return
    
            r = scene.render
    
    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)
    
    
            # This makes some tests on the render, returning True if all goes good, and False if
            # it was finished one way or the other.
            # It also pauses the script (time.sleep())
            def _test_wait():
                time.sleep(self.DELAY)
    
                # User interrupts the rendering
    
    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
    
                # POV process is finisehd, one way or the other
    
    Campbell Barton's avatar
    Campbell Barton committed
                if poll_result is not None:
    
                    if poll_result < 0:
                        print("***POV PROCESS FAILED : %s ***" % poll_result)
                        self.update_stats("", "POV-Ray 3.7: Failed")
                    return False
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
            # Wait for the file to be created
            # XXX This is no more valid, as 3.7 always creates output file once render is finished!
            parsing = re.compile(br"= \[Parsing\.\.\.\] =")
            rendering = re.compile(br"= \[Rendering\.\.\.\] =")
            percent = re.compile(r"\(([0-9]{1,3})%\)")
            # print("***POV WAITING FOR FILE***")
    
            data = b""
            last_line = ""
            while _test_wait():
                # POV in Windows does not output its stdout/stderr, it displays them in its GUI
                if self._is_windows:
                    self.update_stats("", "POV-Ray 3.7: Rendering File")
                else:
                    t_data = self._process.stdout.read1(10000)
    
    Campbell Barton's avatar
    Campbell Barton committed
                    if not t_data:
                        continue
    
    
                    data += t_data
                    # XXX This is working for UNIX, not sure whether it might need adjustments for other OSs
    
    Campbell Barton's avatar
    Campbell Barton committed
                    t_data = str(t_data).replace('\\r\\n', '\\n').replace('\\r', '\r')  # First replace is for windows
    
                    lines = t_data.split('\\n')
                    last_line += lines[0]
                    lines[0] = last_line
                    print('\n'.join(lines), end="")
                    last_line = lines[-1]
    
                    if rendering.search(data):
                        _pov_rendering = True
                        match = percent.findall(str(data))
                        if match:
                            self.update_stats("", "POV-Ray 3.7: Rendering File (%s%%)" % match[-1])
                        else:
                            self.update_stats("", "POV-Ray 3.7: Rendering File")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                    elif parsing.search(data):
                        self.update_stats("", "POV-Ray 3.7: Parsing File")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
            if os.path.exists(self._temp_file_out):
                # print("***POV FILE OK***")
                #self.update_stats("", "POV-Ray 3.7: Rendering")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                xmin = int(r.border_min_x * x)
                ymin = int(r.border_min_y * y)
                xmax = int(r.border_max_x * x)
                ymax = int(r.border_max_y * y)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                # print("***POV UPDATING IMAGE***")
                result = self.begin_result(0, 0, x, y)
                #result = self.begin_result(xmin, ymin, xmax - xmin, ymax - ymin)  # XXX, test for border render.
                #result = self.begin_result(0, 0, xmax - xmin, ymax - ymin)  # XXX, test for border render.
                lay = result.layers[0]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                # This assumes the file has been fully written We wait a bit, just in case!
                time.sleep(self.DELAY)
                try:
                    lay.load_from_file(self._temp_file_out)
                    #lay.load_from_file(self._temp_file_out, xmin, ymin)  # XXX, test for border render.
                    #lay.load_from_file(self._temp_file_out, xmin, ymin)  # XXX, test for border render.
                except RuntimeError:
                    print("***POV ERROR WHILE READING OUTPUT FILE***")
    
                # Not needed right now, might only be useful if we find a way to use temp raw output of
                # pov 3.7 (in which case it might go under _test_wait()).
    #            def update_image():
    #                # possible the image wont load early on.
    #                try:
    #                    lay.load_from_file(self._temp_file_out)
    #                    #lay.load_from_file(self._temp_file_out, xmin, ymin)  # XXX, test for border render.
    #                    #lay.load_from_file(self._temp_file_out, xmin, ymin)  # XXX, test for border render.
    #                except RuntimeError:
    #                    pass
    
    #            # Update while POV-Ray renders
    #            while True:
    #                # print("***POV RENDER LOOP***")
    
    #                # test if POV-Ray exists
    #                if self._process.poll() is not None:
    #                    print("***POV PROCESS FINISHED***")
    #                    update_image()
    #                    break
    
    #                # user exit
    #                if self.test_break():
    #                    try:
    #                        self._process.terminate()
    #                        print("***POV PROCESS INTERRUPTED***")
    #                    except OSError:
    #                        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)
    
                self.end_result(result)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
            if scene.pov_tempfiles_enable or scene.pov_deletefiles_enable:
    
                self._cleanup()