GPencil Tools: Added mirror flip
[blender-addons.git] / mesh_tissue / uv_to_mesh.py
blob13cb09e72fdbc9cbd919d0d457d776a1ac58da57
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # --------------------------------- UV to MESH ------------------------------- #
4 # -------------------------------- version 0.1.1 ----------------------------- #
5 # #
6 # Create a new Mesh based on active UV #
7 # #
8 # (c) Alessandro Zomparelli #
9 # (2017) #
10 # #
11 # http://www.co-de-it.com/ #
12 # #
13 # ############################################################################ #
15 import bpy, bmesh
16 import math
17 from bpy.types import Operator
18 from bpy.props import BoolProperty
19 from mathutils import Vector
20 from .utils import *
23 class uv_to_mesh(Operator):
24 bl_idname = "object.uv_to_mesh"
25 bl_label = "UV to Mesh"
26 bl_description = ("Create a new Mesh based on active UV")
27 bl_options = {'REGISTER', 'UNDO'}
29 apply_modifiers : BoolProperty(
30 name="Apply Modifiers",
31 default=True,
32 description="Apply object's modifiers"
34 vertex_groups : BoolProperty(
35 name="Keep Vertex Groups",
36 default=True,
37 description="Transfer all the Vertex Groups"
39 materials : BoolProperty(
40 name="Keep Materials",
41 default=True,
42 description="Transfer all the Materials"
44 auto_scale : BoolProperty(
45 name="Resize",
46 default=True,
47 description="Scale the new object in order to preserve the average surface area"
50 def execute(self, context):
51 if context.mode == 'EDIT_MESH': on_selection = True
52 else: on_selection = False
54 bpy.ops.object.mode_set(mode='OBJECT')
55 ob0 = context.object
56 for o in bpy.context.view_layer.objects: o.select_set(False)
57 ob0.select_set(True)
59 name0 = ob0.name
60 ob0 = convert_object_to_mesh(ob0, apply_modifiers=self.apply_modifiers, preserve_status=False)
61 me0 = ob0.data
62 area = 0
63 verts = []
64 faces = []
65 face_materials = []
66 if on_selection: polygons = [f for f in me0.polygons if f.select]
67 else: polygons = me0.polygons
68 bm = bmesh.new()
70 for face in polygons:
71 area += face.area
72 uv_face = []
73 store = False
74 if len(me0.uv_layers) > 0:
75 verts = []
76 for loop in face.loop_indices:
77 uv = me0.uv_layers.active.data[loop].uv
78 if uv.x != 0 and uv.y != 0:
79 store = True
80 new_vert = bm.verts.new((uv.x, uv.y, 0))
81 verts.append(new_vert)
82 if store:
83 new_face = bm.faces.new(verts)
84 new_face.material_index = face.material_index
85 else:
86 self.report({'ERROR'}, "Missing UV Map")
87 return {'CANCELLED'}
89 name = name0 + '_UV'
90 # Create mesh and object
91 me = bpy.data.meshes.new(name + 'Mesh')
92 ob = bpy.data.objects.new(name, me)
94 # Link object to scene and make active
95 scn = bpy.context.scene
96 bpy.context.collection.objects.link(ob)
97 bpy.context.view_layer.objects.active = ob
98 ob.select_set(True)
100 # Create mesh from given verts, faces.
101 bm.to_mesh(me)
102 # Update mesh with new data
103 me.update()
105 if self.auto_scale:
106 new_area = 0
107 for p in me.polygons:
108 new_area += p.area
109 if new_area == 0:
110 self.report({'ERROR'}, "Impossible to generate mesh from UV")
111 bpy.data.objects.remove(ob0)
112 return {'CANCELLED'}
114 # VERTEX GROUPS
115 if self.vertex_groups:
116 for group in ob0.vertex_groups:
117 index = group.index
118 ob.vertex_groups.new(name=group.name)
119 for p in polygons:
120 for vert, loop in zip(p.vertices, p.loop_indices):
121 try:
122 ob.vertex_groups[index].add([loop], group.weight(vert), 'REPLACE')
123 except:
124 pass
126 ob0.select_set(False)
127 if self.auto_scale:
128 scaleFactor = math.pow(area / new_area, 1 / 2)
129 ob.scale = Vector((scaleFactor, scaleFactor, scaleFactor))
131 bpy.ops.object.mode_set(mode='EDIT', toggle=False)
132 bpy.ops.mesh.remove_doubles(threshold=1e-06)
133 bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
134 bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
136 # MATERIALS
137 if self.materials:
138 if len(ob0.material_slots) > 0:
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]
145 bpy.data.objects.remove(ob0)
146 bpy.data.meshes.remove(me0)
147 return {'FINISHED'}