text: # ##### BEGIN GPL LICENSE BLOCK #####
  #
  #  This program is free software; you can redistribute it and/or
  #  modify it under the terms of the GNU General Public License
  #  as published by the Free Software Foundation; either version 2
  #  of the License, or (at your option) any later version.
  #
  #  This program is distributed in the hope that it will be useful,
  #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  #  GNU General Public License for more details.
  #
  #  You should have received a copy of the GNU General Public License
  #  along with this program; if not, write to the Free Software Foundation,
  #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  #
  # ##### END GPL LICENSE BLOCK #####
  
  # --------------------------------- UV to MESH ------------------------------- #
  # -------------------------------- version 0.1.1 ----------------------------- #
  #                                                                              #
  # Create a new Mesh based on active UV                                         #
  #                                                                              #
  #                        (c)   Alessandro Zomparelli                           #
  #                                    (2017)                                    #
  #                                                                              #
  # http://www.co-de-it.com/                                                     #
  #                                                                              #
  # ############################################################################ #
  
  import bpy
  import math
  from bpy.types import Operator
  from bpy.props import BoolProperty
  from mathutils import Vector
  from .utils import *
  
  
  class uv_to_mesh(Operator):
      bl_idname = "object.uv_to_mesh"
      bl_label = "UV to Mesh"
      bl_description = ("Create a new Mesh based on active UV")
      bl_options = {'REGISTER', 'UNDO'}
  
      apply_modifiers : BoolProperty(
              name="Apply Modifiers",
              default=True,
              description="Apply object's modifiers"
              )
      vertex_groups : BoolProperty(
              name="Keep Vertex Groups",
              default=True,
              description="Transfer all the Vertex Groups"
              )
      materials : BoolProperty(
              name="Keep Materials",
              default=True,
              description="Transfer all the Materials"
              )
      auto_scale : BoolProperty(
              name="Resize",
              default=True,
              description="Scale the new object in order to preserve the average surface area"
              )
  
      def execute(self, context):
          bpy.ops.object.mode_set(mode='OBJECT')
          for o in bpy.data.objects and bpy.context.view_layer.objects:
              o.select_set(False)
          bpy.context.object.select_set(True)
  
          if self.apply_modifiers:
              bpy.ops.object.duplicate_move()
              bpy.ops.object.convert(target='MESH')
          ob0 = bpy.context.object
  
  #        me0 = ob0.to_mesh(bpy.context.depsgraph, apply_modifiers=self.apply_modifiers)
          #if self.apply_modifiers: me0 = simple_to_mesh(ob0)
          #else: me0 = ob0.data.copy()
          name0 = ob0.name
          ob0 = convert_object_to_mesh(ob0, apply_modifiers=self.apply_modifiers, preserve_status=False)
          me0 = ob0.data
          area = 0
  
          verts = []
          faces = []
          face_materials = []
          for face in me0.polygons:
              area += face.area
              uv_face = []
              store = False
              try:
                  for loop in face.loop_indices:
                      uv = me0.uv_layers.active.data[loop].uv
                      if uv.x != 0 and uv.y != 0:
                          store = True
                      new_vert = Vector((uv.x, uv.y, 0))
                      verts.append(new_vert)
                      uv_face.append(loop)
                  if store:
                      faces.append(uv_face)
                      face_materials.append(face.material_index)
              except:
                  self.report({'ERROR'}, "Missing UV Map")
  
                  return {'CANCELLED'}
  
          name = name0 + 'UV'
          # Create mesh and object
          me = bpy.data.meshes.new(name + 'Mesh')
          ob = bpy.data.objects.new(name, me)
  
          # Link object to scene and make active
          scn = bpy.context.scene
          bpy.context.collection.objects.link(ob)
          bpy.context.view_layer.objects.active = ob
          ob.select_set(True)
  
          # Create mesh from given verts, faces.
          me.from_pydata(verts, [], faces)
          # Update mesh with new data
          me.update()
          if self.auto_scale:
              new_area = 0
              for p in me.polygons:
                  new_area += p.area
              if new_area == 0:
                  self.report({'ERROR'}, "Impossible to generate mesh from UV")
                  bpy.data.objects.remove(ob0)
  
                  return {'CANCELLED'}
  
          # VERTEX GROUPS
          if self.vertex_groups:
              for group in ob0.vertex_groups:
                  index = group.index
                  ob.vertex_groups.new(name=group.name)
                  for p in me0.polygons:
                      for vert, loop in zip(p.vertices, p.loop_indices):
                          try:
                              ob.vertex_groups[index].add([loop], group.weight(vert), 'REPLACE')
                          except:
                              pass
  
          ob0.select_set(False)
          if self.auto_scale:
              scaleFactor = math.pow(area / new_area, 1 / 2)
              ob.scale = Vector((scaleFactor, scaleFactor, scaleFactor))
  
          bpy.ops.object.mode_set(mode='EDIT', toggle=False)
          bpy.ops.mesh.remove_doubles(threshold=1e-06)
          bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
          bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
  
          # MATERIALS
          if self.materials:
              try:
                  # assign old material
                  uv_materials = [slot.material for slot in ob0.material_slots]
                  for i in range(len(uv_materials)):
                      bpy.ops.object.material_slot_add()
                      bpy.context.object.material_slots[i].material = uv_materials[i]
                  for i in range(len(ob.data.polygons)):
                      ob.data.polygons[i].material_index = face_materials[i]
              except:
                  pass
          '''
          if self.apply_modifiers:
              bpy.ops.object.mode_set(mode='OBJECT')
              ob.select_set(False)
              ob0.select_set(True)
              bpy.ops.object.delete(use_global=False)
              ob.select_set(True)
              bpy.context.view_layer.objects.active = ob
          '''
  
          bpy.data.objects.remove(ob0)
          bpy.data.meshes.remove(me0)
          return {'FINISHED'}
  