Revert "space_view3d_pie_menus: Fix unreported Workspace: Addons Filter: failure...
[blender-addons.git] / measureit / measureit_render.py
blobdd7826a46096e33b0ab32ede609cc390d94765bc
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 # <pep8 compliant>
21 # ----------------------------------------------------------
22 # support routines for render measures in final image
23 # Author: Antonio Vazquez (antonioya)
25 # ----------------------------------------------------------
26 # noinspection PyUnresolvedReferences
27 import bpy
28 import gpu
29 import bgl
30 # noinspection PyUnresolvedReferences
31 import blf
32 from os import path, remove
33 from sys import exc_info
34 # noinspection PyUnresolvedReferences
35 import bpy_extras.image_utils as img_utils
36 # noinspection PyUnresolvedReferences
37 import bpy_extras.object_utils as object_utils
38 # noinspection PyUnresolvedReferences
39 from bpy_extras import view3d_utils
40 from math import ceil
41 from .measureit_geometry import *
44 # -------------------------------------------------------------
45 # Render image main entry point
47 # -------------------------------------------------------------
48 def render_main(self, context, animation=False):
49 # Save old info
50 settings = bpy.context.scene.render.image_settings
51 depth = settings.color_depth
52 settings.color_depth = '8'
54 # Get object list
55 scene = context.scene
56 objlist = context.scene.objects
57 # --------------------
58 # Get resolution
59 # --------------------
60 render_scale = scene.render.resolution_percentage / 100
61 width = int(scene.render.resolution_x * render_scale)
62 height = int(scene.render.resolution_y * render_scale)
64 # --------------------------------------
65 # Loop to draw all lines in Offsecreen
66 # --------------------------------------
67 offscreen = gpu.types.GPUOffScreen(width, height)
68 view_matrix = Matrix([
69 [2 / width, 0, 0, -1],
70 [0, 2 / height, 0, -1],
71 [0, 0, 1, 0],
72 [0, 0, 0, 1]])
74 with offscreen.bind():
75 bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
76 gpu.matrix.reset()
77 gpu.matrix.load_matrix(view_matrix)
78 gpu.matrix.load_projection_matrix(Matrix.Identity(4))
80 # -----------------------------
81 # Loop to draw all objects
82 # -----------------------------
83 for myobj in objlist:
84 if myobj.visible_get() is True:
85 if 'MeasureGenerator' in myobj:
86 op = myobj.MeasureGenerator[0]
87 draw_segments(context, myobj, op, None, None)
88 # -----------------------------
89 # Loop to draw all debug
90 # -----------------------------
91 if scene.measureit_debug is True:
92 selobj = bpy.context.selected_objects
93 for myobj in selobj:
94 if scene.measureit_debug_objects is True:
95 draw_object(context, myobj, None, None)
96 elif scene.measureit_debug_object_loc is True:
97 draw_object(context, myobj, None, None)
98 if scene.measureit_debug_vertices is True:
99 draw_vertices(context, myobj, None, None)
100 elif scene.measureit_debug_vert_loc is True:
101 draw_vertices(context, myobj, None, None)
102 if scene.measureit_debug_edges is True:
103 draw_edges(context, myobj, None, None)
104 if scene.measureit_debug_faces is True or scene.measureit_debug_normals is True:
105 draw_faces(context, myobj, None, None)
106 # -----------------------------
107 # Draw a rectangle frame
108 # -----------------------------
109 if scene.measureit_rf is True:
110 rfcolor = scene.measureit_rf_color
111 rfborder = scene.measureit_rf_border
112 rfline = scene.measureit_rf_line
114 bgl.glLineWidth(rfline)
115 x1 = rfborder
116 x2 = width - rfborder
117 y1 = int(ceil(rfborder / (width / height)))
118 y2 = height - y1
119 draw_rectangle((x1, y1), (x2, y2), rfcolor)
121 buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4)
122 bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0)
123 bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
125 offscreen.free()
127 # -----------------------------
128 # Create image
129 # -----------------------------
130 image_name = "measureit_output"
131 if not image_name in bpy.data.images:
132 bpy.data.images.new(image_name, width, height)
134 image = bpy.data.images[image_name]
135 image.scale(width, height)
136 image.pixels = [v / 255 for v in buffer]
138 # Saves image
139 if image is not None and (scene.measureit_render is True or animation is True):
140 ren_path = bpy.context.scene.render.filepath
141 filename = "mit_frame"
142 if len(ren_path) > 0:
143 if ren_path.endswith(path.sep):
144 initpath = path.realpath(ren_path) + path.sep
145 else:
146 (initpath, filename) = path.split(ren_path)
148 ftxt = "%04d" % scene.frame_current
149 outpath = path.realpath(path.join(initpath, filename + ftxt + ".png"))
150 save_image(self, outpath, image)
152 # restore default value
153 settings.color_depth = depth
156 # -------------------------------------
157 # Save image to file
158 # -------------------------------------
159 def save_image(self, filepath, myimage):
160 # noinspection PyBroadException
161 try:
163 # Save old info
164 settings = bpy.context.scene.render.image_settings
165 myformat = settings.file_format
166 mode = settings.color_mode
167 depth = settings.color_depth
169 # Apply new info and save
170 settings.file_format = 'PNG'
171 settings.color_mode = "RGBA"
172 settings.color_depth = '8'
173 myimage.save_render(filepath)
174 print("MeasureIt: Image " + filepath + " saved")
176 # Restore old info
177 settings.file_format = myformat
178 settings.color_mode = mode
179 settings.color_depth = depth
180 except:
181 print("Unexpected error:" + str(exc_info()))
182 self.report({'ERROR'}, "MeasureIt: Unable to save render image")
183 return