From 227fafdfcf4fb441ba1b8477331d543d2cf087af Mon Sep 17 00:00:00 2001
From: Brecht Van Lommel <brechtvanlommel@gmail.com>
Date: Tue, 9 Oct 2018 19:08:04 +0200
Subject: [PATCH] Update for removal of tessfaces.

This ports the already working addons. The disabled x3d, psk, lwo, 3ds,
raw, dxf addons still need to be converted.
---
 io_export_pc2.py                             |   4 +-
 io_mesh_ply/export_ply.py                    |  26 +-
 io_mesh_ply/import_ply.py                    |  62 +--
 io_mesh_stl/blender_utils.py                 |  23 +-
 io_scene_obj/export_obj.py                   |   3 +-
 io_scene_vrml2/export_vrml2.py               |   2 +-
 mesh_extra_tools/mesh_extrude_and_reshape.py |   4 +-
 mesh_extra_tools/mesh_filletplus.py          |   2 +-
 mesh_extra_tools/mesh_vertex_chamfer.py      |   2 +-
 mesh_looptools.py                            |   6 +-
 mesh_snap_utilities_line.py                  |  10 +-
 modules/snap_context/mesh_drawing.py         |  21 +-
 object_print3d_utils/mesh_helpers.py         |   4 +-
 oscurart_tools/oscurart_meshes.py            |   4 +-
 render_povray/render.py                      | 373 ++++++++-----------
 15 files changed, 225 insertions(+), 321 deletions(-)

diff --git a/io_export_pc2.py b/io_export_pc2.py
index cc1f8d788..2f916d3bb 100644
--- a/io_export_pc2.py
+++ b/io_export_pc2.py
@@ -63,7 +63,7 @@ def do_export(context, props, filepath):
     end = props.range_end
     sampling = float(props.sampling)
     apply_modifiers = props.apply_modifiers
-    me = ob.to_mesh(context.depsgraph, apply_modifiers, calc_tessface=False)
+    me = ob.to_mesh(context.depsgraph, apply_modifiers, calc_loop_triangles=False)
     vertCount = len(me.vertices)
     sampletimes = get_sampled_frames(start, end, sampling)
     sampleCount = len(sampletimes)
@@ -80,7 +80,7 @@ def do_export(context, props, filepath):
         # stupid modf() gives decimal part first!
         sc.frame_set(int(frame[1]), subframe=frame[0])
         me = ob.to_mesh(context.depsgraph, apply_modifiers,
-                        calc_tessface=False)
+                        calc_loop_triangles=False)
 
         if len(me.vertices) != vertCount:
             bpy.data.meshes.remove(me, do_unlink=True)
diff --git a/io_mesh_ply/export_ply.py b/io_mesh_ply/export_ply.py
index b6ab88102..b50b6544e 100644
--- a/io_mesh_ply/export_ply.py
+++ b/io_mesh_ply/export_ply.py
@@ -44,12 +44,12 @@ def save_mesh(filepath,
     file = open(filepath, "w", encoding="utf8", newline="\n")
     fw = file.write
 
-    # Be sure tessface & co are available!
-    if not mesh.tessfaces and mesh.polygons:
-        mesh.calc_tessface()
+    # Be sure tessellated loop trianlges are available!
+    if not mesh.loop_triangles and mesh.polygons:
+        mesh.calc_loop_triangles()
 
-    has_uv = bool(mesh.tessface_uv_textures)
-    has_vcol = bool(mesh.tessface_vertex_colors)
+    has_uv = bool(mesh.uv_layers)
+    has_vcol = bool(mesh.vertex_colors)
 
     if not has_uv:
         use_uv_coords = False
@@ -62,7 +62,7 @@ def save_mesh(filepath,
         has_vcol = False
 
     if has_uv:
-        active_uv_layer = mesh.tessface_uv_textures.active
+        active_uv_layer = mesh.uv_layers.active
         if not active_uv_layer:
             use_uv_coords = False
             has_uv = False
@@ -70,7 +70,7 @@ def save_mesh(filepath,
             active_uv_layer = active_uv_layer.data
 
     if has_vcol:
-        active_col_layer = mesh.tessface_vertex_colors.active
+        active_col_layer = mesh.vertex_colors.active
         if not active_col_layer:
             use_colors = False
             has_vcol = False
@@ -84,9 +84,9 @@ def save_mesh(filepath,
     ply_verts = []  # list of dictionaries
     # vdict = {} # (index, normal, uv) -> new index
     vdict = [{} for i in range(len(mesh_verts))]
-    ply_faces = [[] for f in range(len(mesh.tessfaces))]
+    ply_faces = [[] for f in range(len(mesh.loop_triangles))]
     vert_count = 0
-    for i, f in enumerate(mesh.tessfaces):
+    for i, f in enumerate(mesh.loop_triangles):
 
         smooth = not use_normals or f.use_smooth
         if not smooth:
@@ -94,11 +94,9 @@ def save_mesh(filepath,
             normal_key = rvec3d(normal)
 
         if has_uv:
-            uv = active_uv_layer[i]
-            uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4
+            uv = [active_uv_layer[l].uv[:] for l in f.loops]
         if has_vcol:
-            col = active_col_layer[i]
-            col = col.color1[:], col.color2[:], col.color3[:], col.color4[:]
+            col = [active_col_layer[l].color[:] for l in f.loops]
 
         pf = ply_faces[i]
         for j, vidx in enumerate(f.vertices):
@@ -156,7 +154,7 @@ def save_mesh(filepath,
            "property uchar blue\n"
            "property uchar alpha\n")
 
-    fw("element face %d\n" % len(mesh.tessfaces))
+    fw("element face %d\n" % len(mesh.loop_triangles))
     fw("property list uchar uint vertex_indices\n")
     fw("end_header\n")
 
diff --git a/io_mesh_ply/import_ply.py b/io_mesh_ply/import_ply.py
index a106f6e40..f05e1caac 100644
--- a/io_mesh_ply/import_ply.py
+++ b/io_mesh_ply/import_ply.py
@@ -263,9 +263,9 @@ def load_ply_mesh(filepath, ply_name):
     def add_face(vertices, indices, uvindices, colindices):
         mesh_faces.append(indices)
         if uvindices:
-            mesh_uvs.append([(vertices[index][uvindices[0]], vertices[index][uvindices[1]]) for index in indices])
+            mesh_uvs.extend([(vertices[index][uvindices[0]], vertices[index][uvindices[1]]) for index in indices])
         if colindices:
-            mesh_colors.append([(vertices[index][colindices[0]] * colmultiply[0],
+            mesh_colors.extend([(vertices[index][colindices[0]] * colmultiply[0],
                                  vertices[index][colindices[1]] * colmultiply[1],
                                  vertices[index][colindices[2]] * colmultiply[2],
                                  vertices[index][colindices[3]] * colmultiply[3],
@@ -317,35 +317,37 @@ def load_ply_mesh(filepath, ply_name):
         mesh.edges.foreach_set("vertices", [a for e in obj[b'edge'] for a in (e[eindex1], e[eindex2])])
 
     if mesh_faces:
-        mesh.tessfaces.add(len(mesh_faces))
-        mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(mesh_faces))
-
-        if uvindices or colindices:
-            if uvindices:
-                uvlay = mesh.tessface_uv_textures.new()
-            if colindices:
-                vcol_lay = mesh.tessface_vertex_colors.new()
-
-            if uvindices:
-                for i, f in enumerate(uvlay.data):
-                    ply_uv = mesh_uvs[i]
-                    for j, uv in enumerate(f.uv):
-                        uv[0], uv[1] = ply_uv[j]
-
-            if colindices:
-                for i, f in enumerate(vcol_lay.data):
-                    # XXX, colors dont come in right, needs further investigation.
-                    ply_col = mesh_colors[i]
-                    if len(ply_col) == 4:
-                        f_col = f.color1, f.color2, f.color3, f.color4
-                    else:
-                        f_col = f.color1, f.color2, f.color3
+        loops_vert_idx = []
+        faces_loop_start = []
+        faces_loop_total = []
+        lidx = 0
+        for f in mesh_faces:
+            nbr_vidx = len(f)
+            loops_vert_idx.extend(f)
+            faces_loop_start.append(lidx)
+            faces_loop_total.append(nbr_vidx)
+            lidx += nbr_vidx
+
+        mesh.loops.add(len(loops_vert_idx))
+        mesh.polygons.add(len(mesh_faces))
+
+        mesh.loops.foreach_set("vertex_index", loops_vert_idx)
+        mesh.polygons.foreach_set("loop_start", faces_loop_start)
+        mesh.polygons.foreach_set("loop_total", faces_loop_total)
+
+        if uvindices:
+            uv_layer = mesh.uv_layers.new()
+            for i, uv in enumerate(uv_layer.data):
+                uv.uv = mesh_uvs[i]
+
+        if colindices:
+            vcol_lay = mesh.vertex_colors.new()
 
-                    for j, col in enumerate(f_col):
-                        col[0] = ply_col[j][0]
-                        col[1] = ply_col[j][1]
-                        col[2] = ply_col[j][2]
-                        col[3] = ply_col[j][3]
+            for i, col in enumerate(vcol_lay.data):
+                col.color[0] = mesh_colors[i][0]
+                col.color[1] = mesh_colors[i][1]
+                col.color[2] = mesh_colors[i][2]
+                col.color[3] = mesh_colors[i][3]
 
     mesh.update()
     mesh.validate()
diff --git a/io_mesh_stl/blender_utils.py b/io_mesh_stl/blender_utils.py
index 3c895560c..ee5cb0985 100644
--- a/io_mesh_stl/blender_utils.py
+++ b/io_mesh_stl/blender_utils.py
@@ -63,7 +63,7 @@ def create_and_link_mesh(name, faces, face_nors, points, global_matrix):
     obj.select_set("SELECT")
 
 
-def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False, triangulate=True):
+def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False):
     """
     From an object, return a generator over a list of faces.
 
@@ -90,26 +90,11 @@ def faces_from_mesh(ob, global_matrix, use_mesh_modifiers=False, triangulate=Tru
     mesh.transform(mat)
     if mat.is_negative:
         mesh.flip_normals()
-        mesh.calc_tessface()
-
-    if triangulate:
-        # From a list of faces, return the face triangulated if needed.
-        def iter_face_index():
-            for face in mesh.tessfaces:
-                vertices = face.vertices[:]
-                if len(vertices) == 4:
-                    yield vertices[0], vertices[1], vertices[2]
-                    yield vertices[2], vertices[3], vertices[0]
-                else:
-                    yield vertices
-    else:
-        def iter_face_index():
-            for face in mesh.tessfaces:
-                yield face.vertices[:]
+    mesh.calc_loop_triangles()
 
     vertices = mesh.vertices
 
-    for indexes in iter_face_index():
-        yield [vertices[index].co.copy() for index in indexes]
+    for tri in mesh.loop_triangles:
+        yield [vertices[index].co.copy() for index in tri.vertices]
 
     bpy.data.meshes.remove(mesh)
diff --git a/io_scene_obj/export_obj.py b/io_scene_obj/export_obj.py
index 417a54c37..a0f64abf0 100644
--- a/io_scene_obj/export_obj.py
+++ b/io_scene_obj/export_obj.py
@@ -349,7 +349,7 @@ def write_file(filepath, objects, depsgraph, scene,
                         # END NURBS
 
                         try:
-                            me = ob.to_mesh(depsgraph, EXPORT_APPLY_MODIFIERS, calc_tessface=False)
+                            me = ob.to_mesh(depsgraph, EXPORT_APPLY_MODIFIERS, calc_loop_triangles=False)
                         except RuntimeError:
                             me = None
 
@@ -377,7 +377,6 @@ def write_file(filepath, objects, depsgraph, scene,
 
                         # Make our own list so it can be sorted to reduce context switching
                         face_index_pairs = [(face, index) for index, face in enumerate(me.polygons)]
-                        # faces = [ f for f in me.tessfaces ]
 
                         if EXPORT_EDGES:
                             edges = me.edges
diff --git a/io_scene_vrml2/export_vrml2.py b/io_scene_vrml2/export_vrml2.py
index 06f79fc17..da09fcbd8 100644
--- a/io_scene_vrml2/export_vrml2.py
+++ b/io_scene_vrml2/export_vrml2.py
@@ -163,7 +163,7 @@ def save_object(fw, global_matrix,
         if is_editmode:
             bpy.ops.object.editmode_toggle()
 
-        me = obj.to_mesh(scene, True, 'PREVIEW', calc_tessface=False)
+        me = obj.to_mesh(scene, True, 'PREVIEW', calc_loop_triangles=False)
         bm = bmesh.new()
         bm.from_mesh(me)
 
diff --git a/mesh_extra_tools/mesh_extrude_and_reshape.py b/mesh_extra_tools/mesh_extrude_and_reshape.py
index 8716bfb1b..696e775d6 100644
--- a/mesh_extra_tools/mesh_extrude_and_reshape.py
+++ b/mesh_extra_tools/mesh_extrude_and_reshape.py
@@ -304,7 +304,7 @@ class Extrude_and_Reshape(Operator):
                     nf = bmesh.utils.face_split(f, v1, v2)
                     # sp_faces2.update({f, nf[0]})
 
-            bmesh.update_edit_mesh(self.mesh, tessface=True, destructive=True)
+            bmesh.update_edit_mesh(self.mesh, loop_triangles=True, destructive=True)
             return {'FINISHED'}
         if self.cancel:
             return {'FINISHED'}
@@ -345,7 +345,7 @@ class Extrude_and_Reshape(Operator):
             dfaces = bmesh.ops.dissolve_edges(
                         self.bm, edges=geom, use_verts=True, use_face_split=False
                         )
-            bmesh.update_edit_mesh(self.mesh, tessface=True, destructive=True)
+            bmesh.update_edit_mesh(self.mesh, loop_triangles=True, destructive=True)
             bpy.ops.transform.translate(
                         'INVOKE_DEFAULT', constraint_axis=(False, False, True),
                         constraint_orientation='NORMAL', release_confirm=True
diff --git a/mesh_extra_tools/mesh_filletplus.py b/mesh_extra_tools/mesh_filletplus.py
index 442adb543..f3c9cbdfa 100644
--- a/mesh_extra_tools/mesh_filletplus.py
+++ b/mesh_extra_tools/mesh_filletplus.py
@@ -201,7 +201,7 @@ def fillets(list_0, startv, vertlist, face, adj, n, out, flip, radius):
         bm.edges.index_update()
         bm.faces.index_update()
 
-        me.update(calc_edges=True, calc_tessface=True)
+        me.update(calc_edges=True, calc_loop_triangles=True)
         bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
 
     except Exception as e:
diff --git a/mesh_extra_tools/mesh_vertex_chamfer.py b/mesh_extra_tools/mesh_vertex_chamfer.py
index d6fd8080b..880b1eb29 100644
--- a/mesh_extra_tools/mesh_vertex_chamfer.py
+++ b/mesh_extra_tools/mesh_vertex_chamfer.py
@@ -144,7 +144,7 @@ class VertexChamfer(Operator):
             else:
                 v.co += displace * v.normal
 
-        me.calc_tessface()
+        me.calc_loop_triangles()
 
         return {'FINISHED'}
 
diff --git a/mesh_looptools.py b/mesh_looptools.py
index 62417f218..9c2943f62 100644
--- a/mesh_looptools.py
+++ b/mesh_looptools.py
@@ -831,7 +831,7 @@ def terminate(global_undo):
     # update editmesh cached data
     obj = bpy.context.active_object
     if obj.mode == 'EDIT':
-        bmesh.update_edit_mesh(obj.data, tessface=True, destructive=True)
+        bmesh.update_edit_mesh(obj.data, loop_triangles=True, destructive=True)
 
     bpy.context.user_preferences.edit.use_global_undo = global_undo
 
@@ -3367,7 +3367,7 @@ class Bridge(Operator):
             if self.remove_faces and old_selected_faces:
                 bridge_remove_internal_faces(bm, old_selected_faces)
             # make sure normals are facing outside
-            bmesh.update_edit_mesh(object.data, tessface=False,
+            bmesh.update_edit_mesh(object.data, loop_triangles=False,
                 destructive=True)
             bpy.ops.mesh.normals_make_consistent()
 
@@ -4086,7 +4086,7 @@ class GStretch(Operator):
             lock = [self.lock_x, self.lock_y, self.lock_z]
         else:
             lock = False
-        bmesh.update_edit_mesh(object.data, tessface=True, destructive=True)
+        bmesh.update_edit_mesh(object.data, loop_triangles=True, destructive=True)
         move_verts(object, bm, mapping, move, lock, self.influence)
 
         # cleaning up
diff --git a/mesh_snap_utilities_line.py b/mesh_snap_utilities_line.py
index 8f2f2a945..e70e8b52e 100644
--- a/mesh_snap_utilities_line.py
+++ b/mesh_snap_utilities_line.py
@@ -355,7 +355,7 @@ def draw_line(self, obj, bm, bm_geom, location):
 
     drawing_is_dirt = False
     update_edit_mesh = False
-    tessface = False
+    loop_triangles = False
 
     if bm_geom is None:
         vert = bm.verts.new(location)
@@ -437,7 +437,7 @@ def draw_line(self, obj, bm, bm_geom, location):
                         facesp = bmesh.utils.face_split_edgenet(face, ed_list)
                     del split_faces
                     update_edit_mesh = True
-                    tessface = True
+                    loop_triangles = True
                 else:
                     if self.intersect:
                         facesp = bmesh.ops.connect_vert_pair(bm, verts=[v1, v2], verts_exclude=bm.verts)
@@ -450,7 +450,7 @@ def draw_line(self, obj, bm, bm_geom, location):
                         for edge in facesp['edges']:
                             self.list_edges.append(edge)
                             update_edit_mesh = True
-                            tessface = True
+                            loop_triangles = True
 
         # create face
         if self.create_face:
@@ -469,10 +469,10 @@ def draw_line(self, obj, bm, bm_geom, location):
 
             bmesh.ops.edgenet_fill(bm, edges=list(ed_list))
             update_edit_mesh = True
-            tessface = True
+            loop_triangles = True
             # print('face created')
     if update_edit_mesh:
-        bmesh.update_edit_mesh(obj.data, tessface = tessface)
+        bmesh.update_edit_mesh(obj.data, loop_triangles = loop_triangles)
         self.sctx.update_drawn_snap_object(self.snap_obj)
         #bm.verts.index_update()
     elif drawing_is_dirt:
diff --git a/modules/snap_context/mesh_drawing.py b/modules/snap_context/mesh_drawing.py
index bdfca4d36..956606221 100644
--- a/modules/snap_context/mesh_drawing.py
+++ b/modules/snap_context/mesh_drawing.py
@@ -52,26 +52,15 @@ def get_bmesh_vert_co_array(bm):
 
 
 def get_mesh_tri_verts_array(me):
-    me.calc_tessface()
-    len_tessfaces = len(me.tessfaces)
-    if len_tessfaces:
-        tessfaces = np.empty(len_tessfaces * 4, 'i4')
-        me.tessfaces.foreach_get("vertices_raw", tessfaces)
-        tessfaces.shape = (-1, 4)
-
-        quad_indices = tessfaces[:, 3].nonzero()[0]
-        tris = np.empty(((len_tessfaces + len(quad_indices)), 3), 'i4')
-
-        tris[:len_tessfaces] = tessfaces[:, :3]
-        tris[len_tessfaces:] = tessfaces[quad_indices][:, (0, 2, 3)]
-
-        del tessfaces
-        return tris
+    me.calc_loop_triangles()
+    tris = [tri.vertices[:] for tri in me.loop_triangles]
+    if tris:
+        return np.array(tris, 'i4')
     return None
 
 
 def get_bmesh_tri_verts_array(bm):
-    ltris = bm.calc_tessface()
+    ltris = bm.calc_loop_triangles()
     tris = [[ltri[0].vert.index, ltri[1].vert.index, ltri[2].vert.index] for ltri in ltris if not ltri[0].face.hide]
     if tris:
         return np.array(tris, 'i4')
diff --git a/object_print3d_utils/mesh_helpers.py b/object_print3d_utils/mesh_helpers.py
index 7f595c1bc..52d2f5c40 100644
--- a/object_print3d_utils/mesh_helpers.py
+++ b/object_print3d_utils/mesh_helpers.py
@@ -32,7 +32,7 @@ def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifier
 
     if apply_modifiers and obj.modifiers:
         import bpy
-        me = obj.to_mesh(bpy.context.scene, True, 'PREVIEW', calc_tessface=False)
+        me = obj.to_mesh(bpy.context.scene, True, 'PREVIEW', calc_loop_triangles=False)
         bm = bmesh.new()
         bm.from_mesh(me)
         bpy.data.meshes.remove(me)
@@ -268,7 +268,7 @@ def object_merge(context, objects):
         mesh_new = obj.to_mesh(
             depsgraph=context.depsgraph,
             apply_modifiers=True,
-            calc_tessface=False,
+            calc_loop_triangles=False,
         )
 
         # remove non-active uvs/vcols
diff --git a/oscurart_tools/oscurart_meshes.py b/oscurart_tools/oscurart_meshes.py
index 7de7e13af..deed80bc8 100644
--- a/oscurart_tools/oscurart_meshes.py
+++ b/oscurart_tools/oscurart_meshes.py
@@ -322,7 +322,7 @@ def DefOscObjectToMesh():
         scene=bpy.context.scene,
         apply_modifiers=True,
         settings="RENDER",
-        calc_tessface=True)
+        calc_loop_triangles=True)
     OBJECT = bpy.data.objects.new(("%s_Freeze") % (ACTOBJ.name), MESH)
     bpy.context.scene.objects.link(OBJECT)
 
@@ -601,7 +601,7 @@ def defPasteUvsIsland(self, uvOffset, rotateUv,context):
         bm = bmesh.from_edit_mesh(bpy.context.object.data)
         bmesh.ops.reverse_uvs(bm, faces=[f for f in bm.faces if f.select])
         bmesh.ops.rotate_uvs(bm, faces=[f for f in bm.faces if f.select])
-        #bmesh.update_edit_mesh(bpy.context.object.data, tessface=False, destructive=False)
+        #bmesh.update_edit_mesh(bpy.context.object.data, loop_triangles=False, destructive=False)
 
 
 
diff --git a/render_povray/render.py b/render_povray/render.py
index 543b639d3..76544e68b 100644
--- a/render_povray/render.py
+++ b/render_povray/render.py
@@ -2689,7 +2689,7 @@ def write_pov(filename, scene=None, info_callback=None):
                     importance = ob.pov.importance_value
                     if me:
                         me_materials = me.materials
-                        me_faces = me.tessfaces[:]
+                        me_faces = me.loop_triangles[:]
                     #if len(me_faces)==0:
                         #tabWrite("\n//dummy sphere to represent empty mesh location\n")
                         #tabWrite("#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" % povdataname)
@@ -2700,16 +2700,16 @@ def write_pov(filename, scene=None, info_callback=None):
                         tabWrite("#declare %s =sphere {<0, 0, 0>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n" % povdataname)
                         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_layers = me.uv_layers
+                    if len(uv_layers) > 0:
+                        if me.uv_layers.active and uv_layers.active.data:
+                            uv_layer = uv_layers.active.data
                     else:
                         uv_layer = None
 
                     try:
                         #vcol_layer = me.vertex_colors.active.data
-                        vcol_layer = me.tessface_vertex_colors.active.data
+                        vcol_layer = me.vertex_colors.active.data
                     except AttributeError:
                         vcol_layer = None
 
@@ -2717,9 +2717,6 @@ def write_pov(filename, scene=None, info_callback=None):
                     faces_normals = [f.normal[:] for f in me_faces]
                     verts_normals = [v.normal[:] for v in me.vertices]
 
-                    # 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)
@@ -2775,12 +2772,8 @@ def write_pov(filename, scene=None, info_callback=None):
                         # 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]
-                            else:
-                                uvs = uv_layer[fi].uv[0], uv_layer[fi].uv[1], uv_layer[fi].uv[2]
+                        for f in me.faces:
+                            uvs = [uv_layer[l].uv[:] for l in f.loops]
 
                             for uv in uvs:
                                 uniqueUVs[uv[:]] = [-1]
@@ -2811,7 +2804,7 @@ def write_pov(filename, scene=None, info_callback=None):
                     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
+                        tabWrite("%d\n" % (len(me_faces) * 3)) # assumes we have only triangles
                         VcolIdx=0
                         if comments:
                             file.write("\n  //Vertex colors: one simple pigment texture per vertex\n")
@@ -2824,12 +2817,7 @@ def write_pov(filename, scene=None, info_callback=None):
                                 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
-                                else:
-                                    cols = col.color1, col.color2, col.color3
+                                cols = [vcol_layer[l].color[:] for l in f.loops]
 
                                 for col in cols:
                                     key = col[0], col[1], col[2], material_index  # Material index!
@@ -2857,135 +2845,107 @@ def write_pov(filename, scene=None, info_callback=None):
                         tabWrite("\n}\n")
                         # Face indices
                         tabWrite("\nface_indices {\n")
-                        tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
+                        tabWrite("%d" % (len(me_faces)))  # 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
-                                else:
-                                    cols = col.color1, col.color2, col.color3
+                                cols = [vcol_layer[l].color[:] for l in f.loops]
 
                             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
+                                if linebreaksinlists:
+                                    file.write(",\n")
+                                    # vert count
+                                    file.write(tabStr + "<%d,%d,%d>" % (fv[0], fv[1], fv[2]))
+                                else:
+                                    file.write(", ")
+                                    file.write("<%d,%d,%d>" % (fv[0], fv[1], fv[2]))  # vert count
                             else:
                                 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
+                                if me.vertex_colors: #and material.use_vertex_color_paint:
+                                    # Color per vertex - vertex color
 
-                                        col1 = cols[i1]
-                                        col2 = cols[i2]
-                                        col3 = cols[i3]
+                                    col1 = cols[0]
+                                    col2 = cols[1]
+                                    col3 = cols[2]
 
-                                        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
+                                    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:
-                                        file.write(", ")
-                                        file.write("<%d,%d,%d>, %d,%d,%d" % \
-                                                   (fv[i1], fv[i2], fv[i3], ci1-1, ci2-1, ci3-1))  # vert count
+                                        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[0], fv[1], fv[2], ci1-1, ci2-1, ci3-1))  # vert count
+                                else:
+                                    file.write(", ")
+                                    file.write("<%d,%d,%d>, %d,%d,%d" % \
+                                               (fv[0], fv[1], fv[2], 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
+                        tabWrite("%d" % (len(me_faces)))  # faces count
                         tabStr = tab * tabLevel
                         for fi, fv in enumerate(faces_verts):
 
-                            if len(fv) == 4:
-                                indices = (0, 1, 2), (0, 2, 3)
+                            if me_faces[fi].use_smooth:
+                                if linebreaksinlists:
+                                    file.write(",\n")
+                                    file.write(tabStr + "<%d,%d,%d>" %\
+                                    (uniqueNormals[verts_normals[fv[0]]][0],\
+                                     uniqueNormals[verts_normals[fv[1]]][0],\
+                                     uniqueNormals[verts_normals[fv[2]]][0]))  # vert count
+                                else:
+                                    file.write(", ")
+                                    file.write("<%d,%d,%d>" %\
+                                    (uniqueNormals[verts_normals[fv[0]]][0],\
+                                     uniqueNormals[verts_normals[fv[1]]][0],\
+                                     uniqueNormals[verts_normals[fv[2]]][0]))  # vert count
                             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:
-                                    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(", ")
+                                    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
+                            tabWrite("%d" % (len(me_faces)))  # 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][:]
+                            for f in me_faces:
+                                uvs = [uv_layer[l].uv[:] for l in f.loops]
+
+                                if linebreaksinlists:
+                                    file.write(",\n")
+                                    file.write(tabStr + "<%d,%d,%d>" % (
+                                             uniqueUVs[uvs[0]][0],\
+                                             uniqueUVs[uvs[1]][0],\
+                                             uniqueUVs[uvs[2]][0]))
                                 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(", ")
+                                    file.write("<%d,%d,%d>" % (
+                                             uniqueUVs[uvs[0]][0],\
+                                             uniqueUVs[uvs[1]][0],\
+                                             uniqueUVs[uvs[2]][0]))
 
                             file.write("\n")
                             tabWrite("}\n")
@@ -3108,140 +3068,111 @@ def write_pov(filename, scene=None, info_callback=None):
 
                         # Face indices
                         tabWrite("face_indices {\n")
-                        tabWrite("%d" % (len(me_faces) + quadCount))  # faces count
+                        tabWrite("%d" % (len(me_faces)))  # 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
-                                else:
-                                    cols = col.color1, col.color2, col.color3
+                                cols = [vcol_layer[l].color[:] for l in f.loops]
 
                             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
+                                if linebreaksinlists:
+                                    file.write(",\n")
+                                    # vert count
+                                    file.write(tabStr + "<%d,%d,%d>" % (fv[0], fv[1], fv[2]))
+                                else:
+                                    file.write(", ")
+                                    file.write("<%d,%d,%d>" % (fv[0], fv[1], fv[2]))  # vert count
                             else:
                                 material = me_materials[material_index]
-                                for i1, i2, i3 in indices:
-                                    ci1 = ci2 = ci3 = f.material_index
-                                    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]
-                                    elif material.pov.material_use_nodes:
-                                        ci1 = ci2 = ci3 = 0
+                                ci1 = ci2 = ci3 = f.material_index
+                                if me.vertex_colors: #and material.use_vertex_color_paint:
+                                    # Color per vertex - vertex color
+
+                                    col1 = cols[0]
+                                    col2 = cols[1]
+                                    col3 = cols[2]
+
+                                    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]
+                                elif material.pov.material_use_nodes:
+                                    ci1 = ci2 = ci3 = 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:
-                                        # 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]
+                                        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
+                                if linebreaksinlists:
+                                    file.write(",\n")
+                                    file.write(tabStr + "<%d,%d,%d>, %d,%d,%d" % \
+                                               (fv[0], fv[1], fv[2], ci1, ci2, ci3))  # vert count
+                                else:
+                                    file.write(", ")
+                                    file.write("<%d,%d,%d>, %d,%d,%d" % \
+                                               (fv[0], fv[1], fv[2], 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
+                        tabWrite("%d" % (len(me_faces)))  # faces count
                         tabStr = tab * tabLevel
                         for fi, fv in enumerate(faces_verts):
-
-                            if len(fv) == 4:
-                                indices = (0, 1, 2), (0, 2, 3)
+                            if me_faces[fi].use_smooth:
+                                if linebreaksinlists:
+                                    file.write(",\n")
+                                    file.write(tabStr + "<%d,%d,%d>" %\
+                                    (uniqueNormals[verts_normals[fv[0]]][0],\
+                                     uniqueNormals[verts_normals[fv[1]]][0],\
+                                     uniqueNormals[verts_normals[fv[2]]][0]))  # vert count
+                                else:
+                                    file.write(", ")
+                                    file.write("<%d,%d,%d>" %\
+                                    (uniqueNormals[verts_normals[fv[0]]][0],\
+                                     uniqueNormals[verts_normals[fv[1]]][0],\
+                                     uniqueNormals[verts_normals[fv[2]]][0]))  # vert count
                             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:
-                                    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(", ")
+                                    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
+                            tabWrite("%d" % (len(me_faces)))  # 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][:]
+                            for f in me_faces:
+                                uvs = [uv_layer[l].uv[:] for l in f.loops]
+
+                                if linebreaksinlists:
+                                    file.write(",\n")
+                                    file.write(tabStr + "<%d,%d,%d>" % (
+                                             uniqueUVs[uvs[0]][0],\
+                                             uniqueUVs[uvs[1]][0],\
+                                             uniqueUVs[uvs[2]][0]))
                                 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(", ")
+                                    file.write("<%d,%d,%d>" % (
+                                             uniqueUVs[uvs[0]][0],\
+                                             uniqueUVs[uvs[1]][0],\
+                                             uniqueUVs[uvs[2]][0]))
 
                             file.write("\n")
                             tabWrite("}\n")
-- 
GitLab