UV_TO_MESH.PY 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the terms of the GNU General Public License
  5. # as published by the Free Software Foundation; either version 2
  6. # of the License, or (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software Foundation,
  15. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. # --------------------------------- UV to MESH ------------------------------- #
  19. # -------------------------------- version 0.1.1 ----------------------------- #
  20. # #
  21. # Create a new Mesh based on active UV #
  22. # #
  23. # (c) Alessandro Zomparelli #
  24. # (2017) #
  25. # #
  26. # http://www.co-de-it.com/ #
  27. # #
  28. # ############################################################################ #
  29. import bpy
  30. import math
  31. from bpy.types import Operator
  32. from bpy.props import BoolProperty
  33. from mathutils import Vector
  34. from .utils import *
  35. class uv_to_mesh(Operator):
  36. bl_idname = "object.uv_to_mesh"
  37. bl_label = "UV to Mesh"
  38. bl_description = ("Create a new Mesh based on active UV")
  39. bl_options = {'REGISTER', 'UNDO'}
  40. apply_modifiers : BoolProperty(
  41. name="Apply Modifiers",
  42. default=True,
  43. description="Apply object's modifiers"
  44. )
  45. vertex_groups : BoolProperty(
  46. name="Keep Vertex Groups",
  47. default=True,
  48. description="Transfer all the Vertex Groups"
  49. )
  50. materials : BoolProperty(
  51. name="Keep Materials",
  52. default=True,
  53. description="Transfer all the Materials"
  54. )
  55. auto_scale : BoolProperty(
  56. name="Resize",
  57. default=True,
  58. description="Scale the new object in order to preserve the average surface area"
  59. )
  60. def execute(self, context):
  61. bpy.ops.object.mode_set(mode='OBJECT')
  62. ob0 = bpy.context.object
  63. for o in bpy.context.view_layer.objects: o.select_set(False)
  64. ob0.select_set(True)
  65. #if self.apply_modifiers:
  66. # bpy.ops.object.duplicate_move()
  67. # bpy.ops.object.convert(target='MESH')
  68. # me0 = ob0.to_mesh(bpy.context.depsgraph, apply_modifiers=self.apply_modifiers)
  69. #if self.apply_modifiers: me0 = simple_to_mesh(ob0)
  70. #else: me0 = ob0.data.copy()
  71. name0 = ob0.name
  72. ob0 = convert_object_to_mesh(ob0, apply_modifiers=self.apply_modifiers, preserve_status=False)
  73. me0 = ob0.data
  74. area = 0
  75. verts = []
  76. faces = []
  77. face_materials = []
  78. for face in me0.polygons:
  79. area += face.area
  80. uv_face = []
  81. store = False
  82. try:
  83. for loop in face.loop_indices:
  84. uv = me0.uv_layers.active.data[loop].uv
  85. if uv.x != 0 and uv.y != 0:
  86. store = True
  87. new_vert = Vector((uv.x, uv.y, 0))
  88. verts.append(new_vert)
  89. uv_face.append(loop)
  90. if store:
  91. faces.append(uv_face)
  92. face_materials.append(face.material_index)
  93. except:
  94. self.report({'ERROR'}, "Missing UV Map")
  95. return {'CANCELLED'}
  96. name = name0 + '_UV'
  97. # Create mesh and object
  98. me = bpy.data.meshes.new(name + 'Mesh')
  99. ob = bpy.data.objects.new(name, me)
  100. # Link object to scene and make active
  101. scn = bpy.context.scene
  102. bpy.context.collection.objects.link(ob)
  103. bpy.context.view_layer.objects.active = ob
  104. ob.select_set(True)
  105. # Create mesh from given verts, faces.
  106. me.from_pydata(verts, [], faces)
  107. # Update mesh with new data
  108. me.update()
  109. if self.auto_scale:
  110. new_area = 0
  111. for p in me.polygons:
  112. new_area += p.area
  113. if new_area == 0:
  114. self.report({'ERROR'}, "Impossible to generate mesh from UV")
  115. bpy.data.objects.remove(ob0)
  116. return {'CANCELLED'}
  117. # VERTEX GROUPS
  118. if self.vertex_groups:
  119. for group in ob0.vertex_groups:
  120. index = group.index
  121. ob.vertex_groups.new(name=group.name)
  122. for p in me0.polygons:
  123. for vert, loop in zip(p.vertices, p.loop_indices):
  124. try:
  125. ob.vertex_groups[index].add([loop], group.weight(vert), 'REPLACE')
  126. except:
  127. pass
  128. ob0.select_set(False)
  129. if self.auto_scale:
  130. scaleFactor = math.pow(area / new_area, 1 / 2)
  131. ob.scale = Vector((scaleFactor, scaleFactor, scaleFactor))
  132. bpy.ops.object.mode_set(mode='EDIT', toggle=False)
  133. bpy.ops.mesh.remove_doubles(threshold=1e-06)
  134. bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
  135. bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
  136. # MATERIALS
  137. if self.materials:
  138. try:
  139. # assign old material
  140. uv_materials = [slot.material for slot in ob0.material_slots]
  141. for i in range(len(uv_materials)):
  142. bpy.ops.object.material_slot_add()
  143. bpy.context.object.material_slots[i].material = uv_materials[i]
  144. for i in range(len(ob.data.polygons)):
  145. ob.data.polygons[i].material_index = face_materials[i]
  146. except:
  147. pass
  148. '''
  149. if self.apply_modifiers:
  150. bpy.ops.object.mode_set(mode='OBJECT')
  151. ob.select_set(False)
  152. ob0.select_set(True)
  153. bpy.ops.object.delete(use_global=False)
  154. ob.select_set(True)
  155. bpy.context.view_layer.objects.active = ob
  156. '''
  157. bpy.data.objects.remove(ob0)
  158. bpy.data.meshes.remove(me0)
  159. return {'FINISHED'}