Skip to content
Snippets Groups Projects
render.py 188 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 if info_callback:
                        info_callback("Object %2.d of %2.d (%s)" % (ob_num, len(sel), ob.name))
    
                    #if ob.type != 'MESH':
                    #    continue
                    # me = ob.data
    
                    matrix = global_matrix * ob.matrix_world
                    povdataname = store(scene, ob, name, dataname, matrix)
                    if povdataname is None:
                        print("This is an instance")
                        continue
    
                    print("Writing Down First Occurence")
    
                                        
    ############################################Povray Primitives
                    # special exportCurves() function takes care of writing
                    # lathe, sphere_sweep, birail, and loft
                    if ob.type == 'CURVE' and (ob.pov.curveshape in 
                                    {'lathe', 'sphere_sweep', 'loft'}):
                        continue #Don't render proxy mesh, skip to next object
    
                    if ob.pov.object_as == 'ISOSURFACE':
                        tabWrite("#declare %s = isosurface{ \n"% povdataname)
                        tabWrite("function{ \n")
                        textName = ob.pov.iso_function_text
                        if textName:
                            node_tree = bpy.context.scene.node_tree
                            for node in node_tree.nodes:
                                if node.bl_idname == "IsoPropsNode" and node.label == ob.name:
                                    for inp in node.inputs:
                                        if inp:
                                            tabWrite("#declare %s = %.6g;\n"%(inp.name,inp.default_value))
    
                            text = bpy.data.texts[textName]
                            for line in text.lines:
                                split = line.body.split()
                                if split[0] != "#declare":
                                    tabWrite("%s\n"%line.body)
                        else:
                            tabWrite("abs(x) - 2 + y")
                        tabWrite("}\n")
                        tabWrite("threshold %.6g\n"%ob.pov.threshold)
                        tabWrite("max_gradient %.6g\n"%ob.pov.max_gradient)
                        tabWrite("accuracy  %.6g\n"%ob.pov.accuracy)
                        tabWrite("contained_by { ")
                        if ob.pov.contained_by == "sphere":
                            tabWrite("sphere {0,%.6g}}\n"%ob.pov.container_scale)
                        else:
                            tabWrite("box {-%.6g,%.6g}}\n"%(ob.pov.container_scale,ob.pov.container_scale))
                        if ob.pov.all_intersections:
                            tabWrite("all_intersections\n")
                        else:
                            if ob.pov.max_trace > 1:
                                tabWrite("max_trace %.6g\n"%ob.pov.max_trace)
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
                        tabWrite("scale %.6g\n"%(1/ob.pov.container_scale))
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
                    if ob.pov.object_as == 'SUPERELLIPSOID':
                        tabWrite("#declare %s = superellipsoid{ <%.4f,%.4f>\n"%(povdataname,ob.pov.se_n2,ob.pov.se_n1))
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
                        write_object_modifiers(scene,ob,file)
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
    
                    if ob.pov.object_as == 'SUPERTORUS':
                        rMajor = ob.pov.st_major_radius
                        rMinor = ob.pov.st_minor_radius
                        ring = ob.pov.st_ring
                        cross = ob.pov.st_cross
                        accuracy=ob.pov.st_accuracy
                        gradient=ob.pov.st_max_gradient
                        ############Inline Supertorus macro
                        file.write("#macro Supertorus(RMj, RMn, MajorControl, MinorControl, Accuracy, MaxGradient)\n")
                        file.write("   #local CP = 2/MinorControl;\n")
                        file.write("   #local RP = 2/MajorControl;\n")
                        file.write("   isosurface {\n")
                        file.write("      function { pow( pow(abs(pow(pow(abs(x),RP) + pow(abs(z),RP), 1/RP) - RMj),CP) + pow(abs(y),CP) ,1/CP) - RMn }\n")
                        file.write("      threshold 0\n")
                        file.write("      contained_by {box {<-RMj-RMn,-RMn,-RMj-RMn>, < RMj+RMn, RMn, RMj+RMn>}}\n")
                        file.write("      #if(MaxGradient >= 1)\n")
                        file.write("         max_gradient MaxGradient\n")
                        file.write("      #else\n")
                        file.write("         evaluate 1, 10, 0.1\n")
                        file.write("      #end\n")
                        file.write("      accuracy Accuracy\n")
                        file.write("   }\n")
                        file.write("#end\n")
                        ############
                        tabWrite("#declare %s = object{ Supertorus( %.4g,%.4g,%.4g,%.4g,%.4g,%.4g)\n"%(povdataname,rMajor,rMinor,ring,cross,accuracy,gradient))
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
                        write_object_modifiers(scene,ob,file)
                        tabWrite("rotate x*90\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
                        
    
                    if ob.pov.object_as == 'PLANE':
                        tabWrite("#declare %s = plane{ <0,0,1>,1\n"%povdataname)
                        povMatName = "Default_texture"
                        if ob.active_material:
                             #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me) 
                        #tabWrite("texture {%s}\n"%povMatName)
                        write_object_modifiers(scene,ob,file)
                        #tabWrite("rotate x*90\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
                    if ob.pov.object_as == 'BOX':
                        tabWrite("#declare %s = box { -1,1\n"%povdataname)
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
                        write_object_modifiers(scene,ob,file)
                        #tabWrite("rotate x*90\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
    
                    if ob.pov.object_as == 'CONE':
                        br = ob.pov.cone_base_radius
                        cr = ob.pov.cone_cap_radius
                        bz = ob.pov.cone_base_z
                        cz = ob.pov.cone_cap_z
                        tabWrite("#declare %s = cone { <0,0,%.4f>,%.4f,<0,0,%.4f>,%.4f\n"%(povdataname,bz,br,cz,cr))
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
                        write_object_modifiers(scene,ob,file)
                        #tabWrite("rotate x*90\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
                    if ob.pov.object_as == 'CYLINDER':
    
                        r = ob.pov.cylinder_radius
                        x2 = ob.pov.cylinder_location_cap[0]
                        y2 = ob.pov.cylinder_location_cap[1]
                        z2 = ob.pov.cylinder_location_cap[2]
                        tabWrite("#declare %s = cylinder { <0,0,0>,<%6f,%6f,%6f>,%6f\n"%(
                                povdataname,
                                x2,
                                y2,
                                z2,
                                r))
    
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
    
                        #cylinders written at origin, translated below
    
                        write_object_modifiers(scene,ob,file)
                        #tabWrite("rotate x*90\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
    
                    if ob.pov.object_as == 'HEIGHT_FIELD':
                        data = ""
                        filename = ob.pov.hf_filename
                        data += '"%s"'%filename
                        gamma = ' gamma %.4f'%ob.pov.hf_gamma
                        data += gamma
                        if ob.pov.hf_premultiplied:
                            data += ' premultiplied on'
                        if ob.pov.hf_smooth:
                            data += ' smooth'
                        if ob.pov.hf_water > 0:
                            data += ' water_level %.4f'%ob.pov.hf_water
                        #hierarchy = ob.pov.hf_hierarchy
                        tabWrite('#declare %s = height_field { %s\n'%(povdataname,data))
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
                        write_object_modifiers(scene,ob,file)
                        tabWrite("rotate x*90\n")
                        tabWrite("translate <-0.5,0.5,0>\n")
                        tabWrite("scale <0,-1,0>\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
                    if ob.pov.object_as == 'SPHERE':
    
                        tabWrite("#declare %s = sphere { 0,%6f\n"%(povdataname,ob.pov.sphere_radius))
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
                        write_object_modifiers(scene,ob,file)
                        #tabWrite("rotate x*90\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
                    if ob.pov.object_as == 'TORUS':
                        tabWrite("#declare %s = torus { %.4f,%.4f\n"%(povdataname,ob.pov.torus_major_radius,ob.pov.torus_minor_radius))
                        povMatName = "Default_texture"
                        if ob.active_material:
                            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                            try:
                                material = ob.active_material
                                writeObjectMaterial(material, ob)
                            except IndexError:
                                print(me)
                        #tabWrite("texture {%s}\n"%povMatName)
                        write_object_modifiers(scene,ob,file)
                        tabWrite("rotate x*90\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
                        
                    if ob.pov.object_as == 'PARAMETRIC':
                        tabWrite("#declare %s = parametric {\n"%povdataname)
                        tabWrite("function { %s }\n"%ob.pov.x_eq)
                        tabWrite("function { %s }\n"%ob.pov.y_eq)
                        tabWrite("function { %s }\n"%ob.pov.z_eq)
                        tabWrite("<%.4f,%.4f>, <%.4f,%.4f>\n"%(ob.pov.u_min,ob.pov.v_min,ob.pov.u_max,ob.pov.v_max))
                        if ob.pov.contained_by == "sphere":
                            tabWrite("contained_by { sphere{0, 2} }\n")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                        else:
    
                            tabWrite("contained_by { box{-2, 2} }\n")
                        tabWrite("max_gradient %.6f\n"%ob.pov.max_gradient)
                        tabWrite("accuracy %.6f\n"%ob.pov.accuracy)
                        tabWrite("precompute 10 x,y,z\n")
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
                        
                    if ob.pov.object_as == 'POLYCIRCLE':
                        #TODO write below macro Once:
                        #if write_polytocircle_macro_once == 0:
                        file.write("/****************************\n")
                        file.write("This macro was written by 'And'.\n")
                        file.write("Link:(http://news.povray.org/povray.binaries.scene-files/)\n")
                        file.write("****************************/\n")
                        file.write("//from math.inc:\n")
                        file.write("#macro VPerp_Adjust(V, Axis)\n")
                        file.write("   vnormalize(vcross(vcross(Axis, V), Axis))\n")
                        file.write("#end\n")
                        file.write("//Then for the actual macro\n")
                        file.write("#macro Shape_Slice_Plane_2P_1V(point1, point2, clip_direct)\n")
                        file.write("#local p1 = point1 + <0,0,0>;\n")
                        file.write("#local p2 = point2 + <0,0,0>;\n")
                        file.write("#local clip_v = vnormalize(clip_direct + <0,0,0>);\n")
                        file.write("#local direct_v1 = vnormalize(p2 - p1);\n")
                        file.write("#if(vdot(direct_v1, clip_v) = 1)\n")
                        file.write('    #error "Shape_Slice_Plane_2P_1V error: Can\'t decide plane"\n')
                        file.write("#end\n\n")
                        file.write("#local norm = -vnormalize(clip_v - direct_v1*vdot(direct_v1,clip_v));\n")
                        file.write("#local d = vdot(norm, p1);\n")
                        file.write("plane{\n")
                        file.write("norm, d\n")
                        file.write("}\n")
                        file.write("#end\n\n")
                        file.write("//polygon to circle\n")
                        file.write("#macro Shape_Polygon_To_Circle_Blending(_polygon_n, _side_face, _polygon_circumscribed_radius, _circle_radius, _height)\n")
                        file.write("#local n = int(_polygon_n);\n")
                        file.write("#if(n < 3)\n")
                        file.write("    #error ""\n")
                        file.write("#end\n\n")
                        file.write("#local front_v = VPerp_Adjust(_side_face, z);\n")
                        file.write("#if(vdot(front_v, x) >= 0)\n")
                        file.write("    #local face_ang = acos(vdot(-y, front_v));\n")
                        file.write("#else\n")
                        file.write("    #local face_ang = -acos(vdot(-y, front_v));\n")
                        file.write("#end\n")
                        file.write("#local polyg_ext_ang = 2*pi/n;\n")
                        file.write("#local polyg_outer_r = _polygon_circumscribed_radius;\n")
                        file.write("#local polyg_inner_r = polyg_outer_r*cos(polyg_ext_ang/2);\n")
                        file.write("#local cycle_r = _circle_radius;\n")
                        file.write("#local h = _height;\n")
                        file.write("#if(polyg_outer_r < 0 | cycle_r < 0 | h <= 0)\n")
                        file.write('    #error "error: each side length must be positive"\n')
                        file.write("#end\n\n")
                        file.write("#local multi = 1000;\n")
                        file.write("#local poly_obj =\n")
                        file.write("polynomial{\n")
                        file.write("4,\n")
                        file.write("xyz(0,2,2): multi*1,\n")
                        file.write("xyz(2,0,1): multi*2*h,\n")
                        file.write("xyz(1,0,2): multi*2*(polyg_inner_r-cycle_r),\n")
                        file.write("xyz(2,0,0): multi*(-h*h),\n")
                        file.write("xyz(0,0,2): multi*(-pow(cycle_r - polyg_inner_r, 2)),\n")
                        file.write("xyz(1,0,1): multi*2*h*(-2*polyg_inner_r + cycle_r),\n")
                        file.write("xyz(1,0,0): multi*2*h*h*polyg_inner_r,\n")
                        file.write("xyz(0,0,1): multi*2*h*polyg_inner_r*(polyg_inner_r - cycle_r),\n")
                        file.write("xyz(0,0,0): multi*(-pow(polyg_inner_r*h, 2))\n")
                        file.write("sturm\n")
                        file.write("}\n\n")
                        file.write("#local mockup1 =\n")
                        file.write("difference{\n")
                        file.write("    cylinder{\n")
                        file.write("    <0,0,0.0>,<0,0,h>, max(polyg_outer_r, cycle_r)\n")
                        file.write("    }\n\n")
                        file.write("    #for(i, 0, n-1)\n")
                        file.write("        object{\n")
                        file.write("        poly_obj\n")
                        file.write("        inverse\n")
                        file.write("        rotate <0, 0, -90 + degrees(polyg_ext_ang*i)>\n")
                        file.write("        }\n")
                        file.write("        object{\n")
                        file.write("        Shape_Slice_Plane_2P_1V(<polyg_inner_r,0,0>,<cycle_r,0,h>,x)\n")
                        file.write("        rotate <0, 0, -90 + degrees(polyg_ext_ang*i)>\n")
                        file.write("        }\n")
                        file.write("    #end\n")
                        file.write("}\n\n")
                        file.write("object{\n")
                        file.write("mockup1\n")
                        file.write("rotate <0, 0, degrees(face_ang)>\n")
                        file.write("}\n")
                        file.write("#end\n")
                        #Use the macro
                        ngon = ob.pov.polytocircle_ngon
                        ngonR = ob.pov.polytocircle_ngonR
                        circleR = ob.pov.polytocircle_circleR
                        tabWrite("#declare %s = object { Shape_Polygon_To_Circle_Blending(%s, z, %.4f, %.4f, 2) rotate x*180 translate z*1\n"%(povdataname,ngon,ngonR,circleR))
                        tabWrite("}\n")
                        continue #Don't render proxy mesh, skip to next object
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                       
    ############################################else try to export mesh
                    else:
                        try:
                            me = ob.to_mesh(scene, True, 'RENDER')
                        except:
                            # happens when curves cant be made into meshes because of no-data
                            continue
    
                        importance = ob.pov.importance_value
                        me_materials = me.materials
                        me_faces = me.tessfaces[:]
                        
                        if not me or not me_faces:
                            continue
    
                        uv_textures = me.tessface_uv_textures
                        if len(uv_textures) > 0:
                            if me.uv_textures.active and uv_textures.active.data:
                                uv_layer = uv_textures.active.data
    
                            uv_layer = None
    
                        try:
                            #vcol_layer = me.vertex_colors.active.data
                            vcol_layer = me.tessface_vertex_colors.active.data
                        except AttributeError:
                            vcol_layer = None
    
                        faces_verts = [f.vertices[:] for f in me_faces]
                        faces_normals = [f.normal[:] for f in me_faces]
                        verts_normals = [v.normal[:] for v in me.vertices]
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                        # quads incur an extra face
                        quadCount = sum(1 for f in faces_verts if len(f) == 4)
    
                        # Use named declaration to allow reference e.g. for baking. MR
                        file.write("\n")
                        tabWrite("#declare %s =\n" % povdataname)
                        tabWrite("mesh2 {\n")
                        tabWrite("vertex_vectors {\n")
                        tabWrite("%d" % len(me.vertices))  # vert count
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                        tabStr = tab * tabLevel
                        for v in me.vertices:
                            if linebreaksinlists:
                                file.write(",\n")
                                file.write(tabStr + "<%.6f, %.6f, %.6f>" % v.co[:])  # vert count
    
    Luca Bonavita's avatar
    Luca Bonavita committed
                            else:
    
                                file.write(", ")
                                file.write("<%.6f, %.6f, %.6f>" % v.co[:])  # vert count
                            #tabWrite("<%.6f, %.6f, %.6f>" % v.co[:])  # vert count
                        file.write("\n")
                        tabWrite("}\n")
    
                        # Build unique Normal list
                        uniqueNormals = {}
                        for fi, f in enumerate(me_faces):
                            fv = faces_verts[fi]
                            # [-1] is a dummy index, use a list so we can modify in place
                            if f.use_smooth:  # Use vertex normals
                                for v in fv:
                                    key = verts_normals[v]
                                    uniqueNormals[key] = [-1]
                            else:  # Use face normal
                                key = faces_normals[fi]
                                uniqueNormals[key] = [-1]
    
                        tabWrite("normal_vectors {\n")
                        tabWrite("%d" % len(uniqueNormals))  # vert count
    
                        idx = 0
                        tabStr = tab * tabLevel
    
                        for no, index in uniqueNormals.items():
    
                            if linebreaksinlists:
                                file.write(",\n")
    
                                file.write(tabStr + "<%.6f, %.6f, %.6f>" % no)  # vert count
    
                                file.write(", ")
    
                                file.write("<%.6f, %.6f, %.6f>" % no)  # vert count
    
                            index[0] = idx
                            idx += 1
                        file.write("\n")
                        tabWrite("}\n")
    
                        # Vertex colors
                        vertCols = {}  # Use for material colors also.
    
                        if uv_layer:
                            # Generate unique UV's
                            uniqueUVs = {}
                            #n = 0
                            for fi, uv in enumerate(uv_layer):
    
    
                                if len(faces_verts[fi]) == 4:
    
                                    uvs = uv_layer[fi].uv[0], uv_layer[fi].uv[1], uv_layer[fi].uv[2], uv_layer[fi].uv[3]
    
                                    uvs = uv_layer[fi].uv[0], uv_layer[fi].uv[1], uv_layer[fi].uv[2]
    
                                for uv in uvs:
                                    uniqueUVs[uv[:]] = [-1]
    
                            tabWrite("uv_vectors {\n")
                            #print unique_uvs
                            tabWrite("%d" % len(uniqueUVs))  # vert count
                            idx = 0
                            tabStr = tab * tabLevel
                            for uv, index in uniqueUVs.items():
                                if linebreaksinlists:
                                    file.write(",\n")
                                    file.write(tabStr + "<%.6f, %.6f>" % uv)
    
                                    file.write(", ")
                                    file.write("<%.6f, %.6f>" % uv)
                                index[0] = idx
                                idx += 1
                            '''
    
                                # Just add 1 dummy vector, no real UV's
                                tabWrite('1') # vert count
                                file.write(',\n\t\t<0.0, 0.0>')
                            '''
                            file.write("\n")
                            tabWrite("}\n")
    
                        if me.vertex_colors:
                            #Write down vertex colors as a texture for each vertex
                            tabWrite("texture_list {\n")
                            tabWrite("%d\n" % (((len(me_faces)-quadCount) * 3 )+ quadCount * 4)) # works only with tris and quad mesh for now
                            VcolIdx=0
                            if comments:
                                file.write("\n  //Vertex colors: one simple pigment texture per vertex\n")
                            for fi, f in enumerate(me_faces):
                                # annoying, index may be invalid
                                material_index = f.material_index
                                try:
                                    material = me_materials[material_index]
                                except:
                                    material = None
                                if material: #and material.use_vertex_color_paint: #Always use vertex color when there is some for now
                                 
                                    col = vcol_layer[fi]
    
                                    if len(faces_verts[fi]) == 4:
                                        cols = col.color1, col.color2, col.color3, col.color4
    
                                        cols = col.color1, col.color2, col.color3
    
                                    for col in cols:
                                        key = col[0], col[1], col[2], material_index  # Material index!
                                        VcolIdx+=1
                                        vertCols[key] = [VcolIdx]
                                        if linebreaksinlists:
                                            tabWrite("texture {pigment{ color rgb <%6f,%6f,%6f> }}\n" % (col[0], col[1], col[2]))
                                        else:
                                            tabWrite("texture {pigment{ color rgb <%6f,%6f,%6f> }}" % (col[0], col[1], col[2]))
                                            tabStr = tab * tabLevel
                                else:
                                    if material:
                                        # Multiply diffuse with SSS Color
    
                                        if material.subsurface_scattering.use:
                                            diffuse_color = [i * j for i, j in zip(material.subsurface_scattering.color[:], material.diffuse_color[:])]
    
                                            key = diffuse_color[0], diffuse_color[1], diffuse_color[2], \
                                                  material_index
                                            vertCols[key] = [-1]
    
                                        else:
                                            diffuse_color = material.diffuse_color[:]
    
                                            key = diffuse_color[0], diffuse_color[1], diffuse_color[2], \
                                                  material_index
                                            vertCols[key] = [-1]
    
                            tabWrite("\n}\n")                
                            # Face indices
                            tabWrite("\nface_indices {\n")
                            tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
                            tabStr = tab * tabLevel
    
                            for fi, f in enumerate(me_faces):
                                fv = faces_verts[fi]
                                material_index = f.material_index
                                if len(fv) == 4:
                                    indices = (0, 1, 2), (0, 2, 3)
                                else:
                                    indices = ((0, 1, 2),)
    
                                if vcol_layer:
                                    col = vcol_layer[fi]
    
                                    if len(fv) == 4:
                                        cols = col.color1, col.color2, col.color3, col.color4
    
                                        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 linebreaksinlists:
                                            file.write(",\n")
                                            # vert count
                                            file.write(tabStr + "<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))
                                        else:
                                            file.write(", ")
                                            file.write("<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))  # vert count
    
                                    material = me_materials[material_index]
                                    for i1, i2, i3 in indices:
                                        if me.vertex_colors: #and material.use_vertex_color_paint:
                                            # Color per vertex - vertex color
    
                                            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:
                                            # Color per material - flat material color
                                            if material.subsurface_scattering.use:
                                                diffuse_color = [i * j for i, j in zip(material.subsurface_scattering.color[:], material.diffuse_color[:])]
                                            else:
                                                diffuse_color = material.diffuse_color[:]
                                            ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \
                                                              diffuse_color[2], f.material_index][0]
                                            # ci are zero based index so we'll subtract 1 from them
                                        if linebreaksinlists:
                                            file.write(",\n")
                                            file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \
                                                       (fv[i1], fv[i2], fv[i3], ci1-1, ci2-1, ci3-1))  # vert count 
                                        else:
                                            file.write(", ")
                                            file.write("<%d,%d,%d>, %d,%d,%d" % \
                                                       (fv[i1], fv[i2], fv[i3], ci1-1, ci2-1, ci3-1))  # vert count
    
                            file.write("\n")
                            tabWrite("}\n")
    
                            # normal_indices indices
                            tabWrite("normal_indices {\n")
    
                            tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
                            tabStr = tab * tabLevel
                            for fi, fv in enumerate(faces_verts):
    
                                if len(fv) == 4:
                                    indices = (0, 1, 2), (0, 2, 3)
                                else:
                                    indices = ((0, 1, 2),)
    
                                for i1, i2, i3 in indices:
    
                                    if me_faces[fi].use_smooth:
                                        if linebreaksinlists:
                                            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
    
                                        idx = uniqueNormals[faces_normals[fi]][0]
                                        if linebreaksinlists:
                                            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
    
    
                            file.write("\n")
                            tabWrite("}\n")
    
    
                            if uv_layer:
                                tabWrite("uv_indices {\n")
                                tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
                                tabStr = tab * tabLevel
                                for fi, fv in enumerate(faces_verts):
    
                                    if len(fv) == 4:
                                        indices = (0, 1, 2), (0, 2, 3)
                                    else:
                                        indices = ((0, 1, 2),)
    
                                    uv = uv_layer[fi]
                                    if len(faces_verts[fi]) == 4:
                                        uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:], uv.uv[3][:]
    
                                        uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:]
    
                                    for i1, i2, i3 in indices:
                                        if linebreaksinlists:
                                            file.write(",\n")
                                            file.write(tabStr + "<%d,%d,%d>" % (
                                                     uniqueUVs[uvs[i1]][0],\
                                                     uniqueUVs[uvs[i2]][0],\
                                                     uniqueUVs[uvs[i3]][0]))
    
                                            file.write(", ")
                                            file.write("<%d,%d,%d>" % (
                                                     uniqueUVs[uvs[i1]][0],\
                                                     uniqueUVs[uvs[i2]][0],\
                                                     uniqueUVs[uvs[i3]][0]))
    
                                file.write("\n")
                                tabWrite("}\n")
    
                            if me.materials:
                                try:
                                    material = me.materials[0]  # dodgy
                                    writeObjectMaterial(material, ob)
                                except IndexError:
                                    print(me)
    
                            #Importance for radiosity sampling added here:
                            tabWrite("radiosity { \n")
                            tabWrite("importance %3g \n" % importance)
                            tabWrite("}\n")
    
                            tabWrite("}\n")  # End of mesh block
                        else:
                            # No vertex colors, so write material colors as vertex colors
                            for i, material in enumerate(me_materials):
    
                                if material:
                                    # Multiply diffuse with SSS Color
                                    if material.subsurface_scattering.use:
                                        diffuse_color = [i * j for i, j in zip(material.subsurface_scattering.color[:], material.diffuse_color[:])]
                                        key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i  # i == f.mat
                                        vertCols[key] = [-1]
                                    else:
                                        diffuse_color = material.diffuse_color[:]
                                        key = diffuse_color[0], diffuse_color[1], diffuse_color[2], i  # i == f.mat
                                        vertCols[key] = [-1]
    
                                    idx = 0
                                    LocalMaterialNames = []                       
                                    for col, index in vertCols.items():
                                        #if me_materials:
                                        mater = me_materials[col[3]]
                                        if me_materials is None: #XXX working?
                                            material_finish = DEF_MAT_NAME  # not working properly,
                                            trans = 0.0
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                            shading.writeTextureInfluence(mater, materialNames, 
                                                                            LocalMaterialNames,
                                                                            path_image, imageFormat,
                                                                            imgMap, imgMapTransforms,
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                                                            string_strip_hyphen,
    
                                                                            safety, col, os, preview_dir,  unpacked_images)
    
                                        ###################################################################
                                        index[0] = idx
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                                        idx += 1                                    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                                
                            # Vert Colors
                            tabWrite("texture_list {\n")
                            # In case there's is no material slot, give at least one texture 
                            #(an empty one so it uses pov default)
                            if len(vertCols)==0:
                                file.write(tabStr + "1")
    
                                file.write(tabStr + "%s" % (len(vertCols)))  # vert count
                                
                            # below "material" alias, changed to ob.active_material 
                            # because variable referenced before assignment                                  
                            if ob.active_material is not None:
                                if material.pov.replacement_text != "":
                                    file.write("\n")
                                    file.write(" texture{%s}\n" % material.pov.replacement_text)
    
                                else:
                                    # Loop through declared materials list
                                    for cMN in LocalMaterialNames:
                                        if material != "Default":
                                            file.write("\n texture{MAT_%s}\n" % cMN)
                                            #use string_strip_hyphen(materialNames[material])) 
                                            #or Something like that to clean up the above?
    
                                file.write(" texture{}\n")                
                            tabWrite("}\n")
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                            # Face indices
                            tabWrite("face_indices {\n")
                            tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
                            tabStr = tab * tabLevel
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                            for fi, f in enumerate(me_faces):
                                fv = faces_verts[fi]
                                material_index = f.material_index
    
                                if len(fv) == 4:
    
                                    indices = (0, 1, 2), (0, 2, 3)
    
                                    indices = ((0, 1, 2),)
    
                                if vcol_layer:
                                    col = vcol_layer[fi]
    
                                    if len(fv) == 4:
                                        cols = col.color1, col.color2, col.color3, col.color4
    
                                        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 linebreaksinlists:
                                            file.write(",\n")
                                            # vert count
                                            file.write(tabStr + "<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))
    
                                            file.write(", ")
                                            file.write("<%d,%d,%d>" % (fv[i1], fv[i2], fv[i3]))  # vert count
    
                                    material = me_materials[material_index]
                                    for i1, i2, i3 in indices:
                                        if me.vertex_colors: #and material.use_vertex_color_paint:
                                            # Color per vertex - vertex color
    
                                            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:
                                            # Color per material - flat material color
                                            if material.subsurface_scattering.use:
                                                diffuse_color = [i * j for i, j in
                                                    zip(material.subsurface_scattering.color[:],
                                                        material.diffuse_color[:])]
                                            else:
                                                diffuse_color = material.diffuse_color[:]
                                            ci1 = ci2 = ci3 = vertCols[diffuse_color[0], diffuse_color[1], \
                                                              diffuse_color[2], f.material_index][0]
    
                                        if linebreaksinlists:
                                            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
    
                            file.write("\n")
                            tabWrite("}\n")
    
                            # normal_indices indices
                            tabWrite("normal_indices {\n")
    
                            tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
                            tabStr = tab * tabLevel
                            for fi, fv in enumerate(faces_verts):
    
                                if len(fv) == 4:
                                    indices = (0, 1, 2), (0, 2, 3)
                                else:
                                    indices = ((0, 1, 2),)
    
                                for i1, i2, i3 in indices:
    
                                    if me_faces[fi].use_smooth:
                                        if linebreaksinlists:
                                            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
    
                                        idx = uniqueNormals[faces_normals[fi]][0]
                                        if linebreaksinlists:
                                            file.write(",\n")
                                            file.write(tabStr + "<%d,%d,%d>" % (idx, idx, idx)) # vertcount
                                        else:
                                            file.write(", ")
                                            file.write("<%d,%d,%d>" % (idx, idx, idx))  # vert count
    
    
                            file.write("\n")
                            tabWrite("}\n")
    
    
                            if uv_layer:
                                tabWrite("uv_indices {\n")
                                tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
                                tabStr = tab * tabLevel
                                for fi, fv in enumerate(faces_verts):
    
                                    if len(fv) == 4:
                                        indices = (0, 1, 2), (0, 2, 3)
                                    else:
                                        indices = ((0, 1, 2),)
    
                                    uv = uv_layer[fi]
                                    if len(faces_verts[fi]) == 4:
                                        uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:], uv.uv[3][:]
                                    else:
                                        uvs = uv.uv[0][:], uv.uv[1][:], uv.uv[2][:]
    
                                    for i1, i2, i3 in indices:
                                        if linebreaksinlists:
                                            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]))
    
                                file.write("\n")
                                tabWrite("}\n")
    
                            if me.materials:
                                try:
                                    material = me.materials[0]  # dodgy
                                    writeObjectMaterial(material, ob)
                                except IndexError:
                                    print(me)
    
                            #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
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
                        bpy.data.meshes.remove(me)
    
    Luca Bonavita's avatar
    Luca Bonavita committed
    
    
            for data_name, inst in data_ref.items():
                for ob_name, matrix_str in inst:
                    tabWrite("//----Blender Object Name:%s----\n" % ob_name)
                    tabWrite("object { \n")
                    tabWrite("%s\n" % data_name)
                    tabWrite("%s\n" % matrix_str)
                    tabWrite("}\n")
    
    
    Luca Bonavita's avatar
    Luca Bonavita committed
        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:
    
                    if render.alpha_mode == 'TRANSPARENT':
    
                        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[:]))
    
                    # XXX Does not exists anymore
                    #else:
                        #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
    
                    # XXX No enable checkbox for world textures yet (report it?)
                    #if t and t.texture.type == 'IMAGE' and t.use:
                    if t and t.texture.type == 'IMAGE':
    
    Campbell Barton's avatar
    Campbell Barton committed
                        image_filename = path_image(t.texture.image)
    
                        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.pov.org/pov.newusers/thread/%3Cweb.4a5cddf4e9c9822ba2f93e20@news.pov.org%3E/
    
                        # Replace 4/3 by the ratio of each image found by some custom or existing
                        # function
                        #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))
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
                        #using camera rotation valuesdirectly from blender seems much easier
    
                        if t_blend.texture_coords == 'ANGMAP':
                            mappingBlend = ""
    
                            # POV-Ray "scale" is not a number of repetitions factor, but its
                            # inverse, a standard scale factor.
                            # 0.5 Offset is needed relatively to scale because center of the
                            # UV scale is 0.5,0.5 in blender and 0,0 in POV
                            # Further Scale by 2 and translate by -1 are 
                            # required for the sky_sphere not to repeat
                      
    
                            mappingBlend = "scale 2 scale <%.4g,%.4g,%.4g> translate -1 " \
                                           "translate <%.4g,%.4g,%.4g> rotate<0,0,0> " % \
    
                                           ((1.0 / t_blend.scale.x), 
                                           (1.0 / t_blend.scale.y),
                                           (1.0 / t_blend.scale.z), 
                                           0.5-(0.5/t_blend.scale.x)- t_blend.offset.x,
                                           0.5-(0.5/t_blend.scale.y)- t_blend.offset.y,
                                           t_blend.offset.z)
    
    
                            # 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.
                        # Putting the map on a plane would not introduce the skysphere distortion and