Update for API change: scene.cursor_location -> scene.cursor.location
[blender-addons.git] / mesh_tissue / uv_to_mesh.py
bloba544ff64cc1355bdbe65cfea969df37fadfcd135
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 bl_info = {
32 "name": "UV to Mesh",
33 "author": "Alessandro Zomparelli (Co-de-iT)",
34 "version": (0, 1, 1),
35 "blender": (2, 79, 0),
36 "location": "",
37 "description": "Create a new Mesh based on active UV",
38 "warning": "",
39 "wiki_url": "",
40 "category": "Mesh"}
43 import bpy
44 import math
45 from bpy.types import Operator
46 from bpy.props import BoolProperty
47 from mathutils import Vector
50 class uv_to_mesh(Operator):
51 bl_idname = "object.uv_to_mesh"
52 bl_label = "UV to Mesh"
53 bl_description = ("Create a new Mesh based on active UV")
54 bl_options = {'REGISTER', 'UNDO'}
56 apply_modifiers: BoolProperty(
57 name="Apply Modifiers",
58 default=False,
59 description="Apply object's modifiers"
61 vertex_groups: BoolProperty(
62 name="Keep Vertex Groups",
63 default=False,
64 description="Transfer all the Vertex Groups"
66 materials: BoolProperty(
67 name="Keep Materials",
68 default=True,
69 description="Transfer all the Materials"
71 auto_scale: BoolProperty(
72 name="Resize",
73 default=True,
74 description="Scale the new object in order to preserve the average surface area"
77 def execute(self, context):
78 bpy.ops.object.mode_set(mode='OBJECT')
79 for o in bpy.data.objects:
80 o.select_set(False)
81 bpy.context.object.select_set(True)
83 if self.apply_modifiers:
84 bpy.ops.object.duplicate_move()
85 bpy.ops.object.convert(target='MESH')
86 ob0 = bpy.context.object
88 me0 = ob0.to_mesh(bpy.context.scene,
89 apply_modifiers=self.apply_modifiers, settings='PREVIEW')
90 area = 0
92 verts = []
93 faces = []
94 face_materials = []
95 for face in me0.polygons:
96 area += face.area
97 uv_face = []
98 store = False
99 try:
100 for loop in face.loop_indices:
101 uv = me0.uv_layers.active.data[loop].uv
102 if uv.x != 0 and uv.y != 0:
103 store = True
104 new_vert = Vector((uv.x, uv.y, 0))
105 verts.append(new_vert)
106 uv_face.append(loop)
107 if store:
108 faces.append(uv_face)
109 face_materials.append(face.material_index)
110 except:
111 self.report({'ERROR'}, "Missing UV Map")
113 return {'CANCELLED'}
115 name = ob0.name + 'UV'
116 # Create mesh and object
117 me = bpy.data.meshes.new(name + 'Mesh')
118 ob = bpy.data.objects.new(name, me)
120 # Link object to scene and make active
121 scn = bpy.context.scene
122 scn.objects.link(ob)
123 scn.objects.active = ob
124 ob.select_set(True)
126 # Create mesh from given verts, faces.
127 me.from_pydata(verts, [], faces)
128 # Update mesh with new data
129 me.update()
130 if self.auto_scale:
131 new_area = 0
132 for p in me.polygons:
133 new_area += p.area
134 if new_area == 0:
135 self.report({'ERROR'}, "Impossible to generate mesh from UV")
137 return {'CANCELLED'}
139 # VERTEX GROUPS
140 if self.vertex_groups:
141 try:
142 for group in ob0.vertex_groups:
143 index = group.index
144 ob.vertex_groups.new(name=group.name)
145 for p in me0.polygons:
146 for vert, loop in zip(p.vertices, p.loop_indices):
147 ob.vertex_groups[index].add([loop], group.weight(vert), "ADD")
148 except:
149 pass
151 ob0.select_set(False)
152 if self.auto_scale:
153 scaleFactor = math.pow(area / new_area, 1 / 2)
154 ob.scale = Vector((scaleFactor, scaleFactor, scaleFactor))
156 bpy.ops.object.mode_set(mode='EDIT', toggle=False)
157 bpy.ops.mesh.remove_doubles(threshold=1e-06)
158 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
159 bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
161 # MATERIALS
162 if self.materials:
163 try:
164 # assign old material
165 uv_materials = [slot.material for slot in ob0.material_slots]
166 for i in range(len(uv_materials)):
167 bpy.ops.object.material_slot_add()
168 bpy.context.object.material_slots[i].material = uv_materials[i]
169 for i in range(len(ob.data.polygons)):
170 ob.data.polygons[i].material_index = face_materials[i]
171 except:
172 pass
174 if self.apply_modifiers:
175 bpy.ops.object.mode_set(mode='OBJECT')
176 ob.select_set(False)
177 ob0.select_set(True)
178 bpy.ops.object.delete(use_global=False)
179 ob.select_set(True)
180 bpy.context.view_layer.objects.active = ob
182 return {'FINISHED'}
185 def register():
186 bpy.utils.register_class(uv_to_mesh)
189 def unregister():
190 bpy.utils.unregister_class(uv_to_mesh)
193 if __name__ == "__main__":
194 register()