Merge branch 'blender-v2.92-release'
[blender-addons.git] / mesh_tissue / uv_to_mesh.py
blob2e9d69289e76d8584a12b3d4d2bdcdc3551a07bd
1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
19 # --------------------------------- UV to MESH ------------------------------- #
20 # -------------------------------- version 0.1.1 ----------------------------- #
21 # #
22 # Create a new Mesh based on active UV #
23 # #
24 # (c) Alessandro Zomparelli #
25 # (2017) #
26 # #
27 # http://www.co-de-it.com/ #
28 # #
29 # ############################################################################ #
31 import bpy
32 import math
33 from bpy.types import Operator
34 from bpy.props import BoolProperty
35 from mathutils import Vector
36 from .utils import *
39 class uv_to_mesh(Operator):
40 bl_idname = "object.uv_to_mesh"
41 bl_label = "UV to Mesh"
42 bl_description = ("Create a new Mesh based on active UV")
43 bl_options = {'REGISTER', 'UNDO'}
45 apply_modifiers : BoolProperty(
46 name="Apply Modifiers",
47 default=True,
48 description="Apply object's modifiers"
50 vertex_groups : BoolProperty(
51 name="Keep Vertex Groups",
52 default=True,
53 description="Transfer all the Vertex Groups"
55 materials : BoolProperty(
56 name="Keep Materials",
57 default=True,
58 description="Transfer all the Materials"
60 auto_scale : BoolProperty(
61 name="Resize",
62 default=True,
63 description="Scale the new object in order to preserve the average surface area"
66 def execute(self, context):
67 bpy.ops.object.mode_set(mode='OBJECT')
68 for o in bpy.data.objects and bpy.context.view_layer.objects:
69 o.select_set(False)
70 bpy.context.object.select_set(True)
72 if self.apply_modifiers:
73 bpy.ops.object.duplicate_move()
74 bpy.ops.object.convert(target='MESH')
75 ob0 = bpy.context.object
77 # me0 = ob0.to_mesh(bpy.context.depsgraph, apply_modifiers=self.apply_modifiers)
78 #if self.apply_modifiers: me0 = simple_to_mesh(ob0)
79 #else: me0 = ob0.data.copy()
80 name0 = ob0.name
81 ob0 = convert_object_to_mesh(ob0, apply_modifiers=self.apply_modifiers, preserve_status=False)
82 me0 = ob0.data
83 area = 0
85 verts = []
86 faces = []
87 face_materials = []
88 for face in me0.polygons:
89 area += face.area
90 uv_face = []
91 store = False
92 try:
93 for loop in face.loop_indices:
94 uv = me0.uv_layers.active.data[loop].uv
95 if uv.x != 0 and uv.y != 0:
96 store = True
97 new_vert = Vector((uv.x, uv.y, 0))
98 verts.append(new_vert)
99 uv_face.append(loop)
100 if store:
101 faces.append(uv_face)
102 face_materials.append(face.material_index)
103 except:
104 self.report({'ERROR'}, "Missing UV Map")
106 return {'CANCELLED'}
108 name = name0 + 'UV'
109 # Create mesh and object
110 me = bpy.data.meshes.new(name + 'Mesh')
111 ob = bpy.data.objects.new(name, me)
113 # Link object to scene and make active
114 scn = bpy.context.scene
115 bpy.context.collection.objects.link(ob)
116 bpy.context.view_layer.objects.active = ob
117 ob.select_set(True)
119 # Create mesh from given verts, faces.
120 me.from_pydata(verts, [], faces)
121 # Update mesh with new data
122 me.update()
123 if self.auto_scale:
124 new_area = 0
125 for p in me.polygons:
126 new_area += p.area
127 if new_area == 0:
128 self.report({'ERROR'}, "Impossible to generate mesh from UV")
129 bpy.data.objects.remove(ob0)
131 return {'CANCELLED'}
133 # VERTEX GROUPS
134 if self.vertex_groups:
135 for group in ob0.vertex_groups:
136 index = group.index
137 ob.vertex_groups.new(name=group.name)
138 for p in me0.polygons:
139 for vert, loop in zip(p.vertices, p.loop_indices):
140 try:
141 ob.vertex_groups[index].add([loop], group.weight(vert), 'REPLACE')
142 except:
143 pass
145 ob0.select_set(False)
146 if self.auto_scale:
147 scaleFactor = math.pow(area / new_area, 1 / 2)
148 ob.scale = Vector((scaleFactor, scaleFactor, scaleFactor))
150 bpy.ops.object.mode_set(mode='EDIT', toggle=False)
151 bpy.ops.mesh.remove_doubles(threshold=1e-06)
152 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
153 bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
155 # MATERIALS
156 if self.materials:
157 try:
158 # assign old material
159 uv_materials = [slot.material for slot in ob0.material_slots]
160 for i in range(len(uv_materials)):
161 bpy.ops.object.material_slot_add()
162 bpy.context.object.material_slots[i].material = uv_materials[i]
163 for i in range(len(ob.data.polygons)):
164 ob.data.polygons[i].material_index = face_materials[i]
165 except:
166 pass
168 if self.apply_modifiers:
169 bpy.ops.object.mode_set(mode='OBJECT')
170 ob.select_set(False)
171 ob0.select_set(True)
172 bpy.ops.object.delete(use_global=False)
173 ob.select_set(True)
174 bpy.context.view_layer.objects.active = ob
177 bpy.data.objects.remove(ob0)
178 bpy.data.meshes.remove(me0)
179 return {'FINISHED'}