Fix T71100: Node Wrangler creates nodes on linked node trees
[blender-addons.git] / io_mesh_uv_layout / export_uv_png.py
blobad1b2284fcd0a954c84d51169b59b8498058f850
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 import bpy
4 import gpu
5 from mathutils import Vector, Matrix
6 from mathutils.geometry import tessellate_polygon
7 from gpu_extras.batch import batch_for_shader
10 def export(filepath, face_data, colors, width, height, opacity):
11 offscreen = gpu.types.GPUOffScreen(width, height)
12 offscreen.bind()
14 try:
15 fb = gpu.state.active_framebuffer_get()
16 fb.clear(color=(0.0, 0.0, 0.0, 0.0))
17 draw_image(face_data, opacity)
19 pixel_data = fb.read_color(0, 0, width, height, 4, 0, 'UBYTE')
20 pixel_data.dimensions = width * height * 4
21 save_pixels(filepath, pixel_data, width, height)
22 finally:
23 offscreen.unbind()
24 offscreen.free()
27 def draw_image(face_data, opacity):
28 gpu.state.blend_set('ALPHA')
30 with gpu.matrix.push_pop():
31 gpu.matrix.load_matrix(get_normalize_uvs_matrix())
32 gpu.matrix.load_projection_matrix(Matrix.Identity(4))
34 draw_background_colors(face_data, opacity)
35 draw_lines(face_data)
37 gpu.state.blend_set('NONE')
40 def get_normalize_uvs_matrix():
41 '''matrix maps x and y coordinates from [0, 1] to [-1, 1]'''
42 matrix = Matrix.Identity(4)
43 matrix.col[3][0] = -1
44 matrix.col[3][1] = -1
45 matrix[0][0] = 2
46 matrix[1][1] = 2
47 return matrix
50 def draw_background_colors(face_data, opacity):
51 coords = [uv for uvs, _ in face_data for uv in uvs]
52 colors = [(*color, opacity) for uvs, color in face_data for _ in range(len(uvs))]
54 indices = []
55 offset = 0
56 for uvs, _ in face_data:
57 triangles = tessellate_uvs(uvs)
58 indices.extend([index + offset for index in triangle] for triangle in triangles)
59 offset += len(uvs)
61 shader = gpu.shader.from_builtin('2D_FLAT_COLOR')
62 batch = batch_for_shader(
63 shader, 'TRIS',
64 {"pos": coords, "color": colors},
65 indices=indices,
67 batch.draw(shader)
70 def tessellate_uvs(uvs):
71 return tessellate_polygon([uvs])
74 def draw_lines(face_data):
75 coords = []
76 for uvs, _ in face_data:
77 for i in range(len(uvs)):
78 start = uvs[i]
79 end = uvs[(i + 1) % len(uvs)]
80 coords.append((start[0], start[1]))
81 coords.append((end[0], end[1]))
83 shader = gpu.shader.from_builtin('POLYLINE_UNIFORM_COLOR')
84 shader.uniform_float("viewportSize", gpu.state.viewport_get()[2:])
85 shader.uniform_float("lineWidth", 1.0)
86 shader.uniform_float("color", (0.0, 0.0, 0.0, 1.0))
88 batch = batch_for_shader(shader, 'LINES', {"pos": coords})
89 batch.draw(shader)
92 def save_pixels(filepath, pixel_data, width, height):
93 image = bpy.data.images.new("temp", width, height, alpha=True)
94 image.filepath = filepath
95 image.pixels = [v / 255 for v in pixel_data]
96 image.save()
97 bpy.data.images.remove(image)