1 # SPDX-FileCopyrightText: 2016-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # ----------------------------------------------------------
6 # support routines for render measures in final image
7 # Author: Antonio Vazquez (antonioya)
9 # ----------------------------------------------------------
10 # noinspection PyUnresolvedReferences
13 # noinspection PyUnresolvedReferences
15 from os
import path
, remove
16 from sys
import exc_info
17 # noinspection PyUnresolvedReferences
18 import bpy_extras
.image_utils
as img_utils
19 # noinspection PyUnresolvedReferences
20 import bpy_extras
.object_utils
as object_utils
21 # noinspection PyUnresolvedReferences
22 from bpy_extras
import view3d_utils
24 from .measureit_geometry
import *
27 # -------------------------------------------------------------
28 # Render image main entry point
30 # -------------------------------------------------------------
31 def render_main(self
, context
, animation
=False):
33 settings
= bpy
.context
.scene
.render
.image_settings
34 depth
= settings
.color_depth
35 settings
.color_depth
= '8'
39 objlist
= context
.scene
.objects
40 # --------------------
42 # --------------------
43 render_scale
= scene
.render
.resolution_percentage
/ 100
44 width
= int(scene
.render
.resolution_x
* render_scale
)
45 height
= int(scene
.render
.resolution_y
* render_scale
)
47 # --------------------------------------
48 # Loop to draw all lines in Offsecreen
49 # --------------------------------------
50 offscreen
= gpu
.types
.GPUOffScreen(width
, height
)
51 view_matrix
= Matrix([
52 [2 / width
, 0, 0, -1],
53 [0, 2 / height
, 0, -1],
57 with offscreen
.bind():
58 fb
= gpu
.state
.active_framebuffer_get()
59 fb
.clear(color
=(0.0, 0.0, 0.0, 0.0))
61 gpu
.matrix
.load_matrix(view_matrix
)
62 gpu
.matrix
.load_projection_matrix(Matrix
.Identity(4))
64 # -----------------------------
65 # Loop to draw all objects
66 # -----------------------------
68 if myobj
.visible_get() is True:
69 if 'MeasureGenerator' in myobj
:
70 op
= myobj
.MeasureGenerator
[0]
71 draw_segments(context
, myobj
, op
, None, None)
72 # -----------------------------
73 # Loop to draw all debug
74 # -----------------------------
75 if scene
.measureit_debug
is True:
76 selobj
= bpy
.context
.selected_objects
78 if scene
.measureit_debug_objects
is True:
79 draw_object(context
, myobj
, None, None)
80 elif scene
.measureit_debug_object_loc
is True:
81 draw_object(context
, myobj
, None, None)
82 if scene
.measureit_debug_vertices
is True:
83 draw_vertices(context
, myobj
, None, None)
84 elif scene
.measureit_debug_vert_loc
is True:
85 draw_vertices(context
, myobj
, None, None)
86 if scene
.measureit_debug_edges
is True:
87 draw_edges(context
, myobj
, None, None)
88 if scene
.measureit_debug_faces
is True or scene
.measureit_debug_normals
is True:
89 draw_faces(context
, myobj
, None, None)
90 # -----------------------------
91 # Draw a rectangle frame
92 # -----------------------------
93 if scene
.measureit_rf
is True:
94 rfcolor
= scene
.measureit_rf_color
95 rfborder
= scene
.measureit_rf_border
96 rfline
= scene
.measureit_rf_line
98 imm_set_line_width(rfline
)
100 x2
= width
- rfborder
101 y1
= int(ceil(rfborder
/ (width
/ height
)))
103 draw_rectangle((x1
, y1
), (x2
, y2
), rfcolor
)
105 buffer = fb
.read_color(0, 0, width
, height
, 4, 0, 'UBYTE')
106 buffer.dimensions
= width
* height
* 4
110 # -----------------------------
112 # -----------------------------
113 image_name
= "measureit_output"
114 if not image_name
in bpy
.data
.images
:
115 bpy
.data
.images
.new(image_name
, width
, height
)
117 image
= bpy
.data
.images
[image_name
]
118 image
.scale(width
, height
)
119 image
.pixels
= [v
/ 255 for v
in buffer]
122 if image
is not None and (scene
.measureit_render
is True or animation
is True):
123 ren_path
= bpy
.context
.scene
.render
.filepath
124 filename
= "mit_frame"
125 if len(ren_path
) > 0:
126 if ren_path
.endswith(path
.sep
):
127 initpath
= path
.realpath(ren_path
) + path
.sep
129 (initpath
, filename
) = path
.split(ren_path
)
131 ftxt
= "%04d" % scene
.frame_current
132 outpath
= path
.realpath(path
.join(initpath
, filename
+ ftxt
+ ".png"))
133 save_image(self
, outpath
, image
)
135 # restore default value
136 settings
.color_depth
= depth
139 # -------------------------------------
141 # -------------------------------------
142 def save_image(self
, filepath
, myimage
):
143 # noinspection PyBroadException
147 settings
= bpy
.context
.scene
.render
.image_settings
148 myformat
= settings
.file_format
149 mode
= settings
.color_mode
150 depth
= settings
.color_depth
152 # Apply new info and save
153 settings
.file_format
= 'PNG'
154 settings
.color_mode
= "RGBA"
155 settings
.color_depth
= '8'
156 myimage
.save_render(filepath
)
157 print("MeasureIt: Image " + filepath
+ " saved")
160 settings
.file_format
= myformat
161 settings
.color_mode
= mode
162 settings
.color_depth
= depth
164 print("Unexpected error:" + str(exc_info()))
165 self
.report({'ERROR'}, "MeasureIt: Unable to save render image")