Fix #105009: AnimAll: Error when inserting key on string attribute
[blender-addons.git] / archimesh / achm_gltools.py
blob4401c8a01f4edaa9b6c407377a1e67cf9e05f195
1 # SPDX-FileCopyrightText: 2016-2023 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # ----------------------------------------------------------
6 # support routines for OpenGL
7 # Author: Antonio Vazquez (antonioya)
9 # ----------------------------------------------------------
10 # noinspection PyUnresolvedReferences
11 import bpy
12 # noinspection PyUnresolvedReferences
13 import blf
14 from math import fabs, sqrt, sin, cos
15 # noinspection PyUnresolvedReferences
16 from mathutils import Vector
17 # noinspection PyUnresolvedReferences
18 from bpy_extras import view3d_utils
19 from .achm_room_maker import get_wall_points
20 # GPU
21 import gpu
22 from gpu_extras.batch import batch_for_shader
24 shader = gpu.shader.from_builtin('UNIFORM_COLOR') if not bpy.app.background else None
26 # -------------------------------------------------------------
27 # Handle all draw routines (OpenGL main entry point)
29 # -------------------------------------------------------------
30 def draw_main(context):
31 region = context.region
32 rv3d = context.space_data.region_3d
33 scene = context.scene
35 rgba = scene.archimesh_text_color
36 rgbaw = scene.archimesh_walltext_color
37 fsize = scene.archimesh_font_size
38 wfsize = scene.archimesh_wfont_size
39 space = scene.archimesh_hint_space
40 measure = scene.archimesh_gl_measure
41 dspname = scene.archimesh_gl_name
43 gpu.state.blend_set('ALPHA')
44 # Display selected or all
45 if scene.archimesh_gl_ghost is False:
46 objlist = context.selected_objects
47 else:
48 objlist = context.view_layer.objects
49 # ---------------------------------------
50 # Generate all OpenGL calls
51 # ---------------------------------------
52 for myobj in objlist:
53 if myobj.visible_get() is True:
54 # -----------------------------------------------------
55 # Rooms
56 # -----------------------------------------------------
57 if 'RoomGenerator' in myobj:
58 op = myobj.RoomGenerator[0]
59 draw_room_data(myobj, op, region, rv3d, rgba, rgbaw, fsize, wfsize, space, measure, dspname)
61 # -----------------------------------------------------
62 # Doors
63 # -----------------------------------------------------
64 if 'DoorObjectGenerator' in myobj:
65 op = myobj.DoorObjectGenerator[0]
66 draw_door_data(myobj, op, region, rv3d, rgba, fsize, space, measure)
68 # -----------------------------------------------------
69 # Window (Rail)
70 # -----------------------------------------------------
71 if 'WindowObjectGenerator' in myobj:
72 op = myobj.WindowObjectGenerator[0]
73 draw_window_rail_data(myobj, op, region, rv3d, rgba, fsize, space, measure)
75 # -----------------------------------------------------
76 # Window (Panel)
77 # -----------------------------------------------------
78 if 'WindowPanelGenerator' in myobj:
79 op = myobj.WindowPanelGenerator[0]
80 draw_window_panel_data(myobj, op, region, rv3d, rgba, fsize, space, measure)
82 # -----------------------
83 # restore opengl defaults
84 # -----------------------
85 gpu.state.line_width_set(1.0)
86 gpu.state.blend_set('NONE')
89 # -------------------------------------------------------------
90 # Create OpenGL text
92 # right: Align to right
93 # -------------------------------------------------------------
94 def draw_text(x_pos, y_pos, display_text, rgba, fsize, right=False):
95 gap = 12
96 font_id = 0
97 blf.size(font_id, fsize)
99 text_width, text_height = blf.dimensions(font_id, display_text)
100 if right is True:
101 newx = x_pos - text_width - gap
102 else:
103 newx = x_pos
104 blf.position(font_id, newx, y_pos, 0)
105 blf.color(font_id, rgba[0], rgba[1], rgba[2], rgba[3])
106 blf.draw(font_id, display_text)
107 return
110 # -------------------------------------------------------------
111 # Draw an OpenGL line
113 # -------------------------------------------------------------
114 def draw_line(v1, v2, rgba):
115 coords = [(v1[0], v1[1]), (v2[0], v2[1])]
116 batch = batch_for_shader(shader, 'LINES', {"pos": coords})
118 # noinspection PyBroadException
119 try:
120 if v1 is not None and v2 is not None:
121 shader.bind()
122 shader.uniform_float("color", rgba)
123 batch.draw(shader)
124 except:
125 pass
127 # -------------------------------------------------------------
128 # Draw room information
130 # rgba: Color
131 # fsize: Font size
132 # -------------------------------------------------------------
133 def draw_room_data(myobj, op, region, rv3d, rgba, rgbaw, fsize, wfsize, space, measure, dspname):
135 verts, activefaces, activenormals = get_wall_points(myobj)
137 # --------------------------
138 # Get line points and draw
139 # --------------------------
140 for face in activefaces:
141 a1 = None
142 b1 = None
143 a2 = None
144 b2 = None
145 # Bottom
146 for e in face:
147 if verts[e][2] == 0:
148 if a1 is None:
149 a1 = e
150 else:
151 b1 = e
152 # Top
153 for e in face:
154 if verts[e][2] != 0:
155 if round(verts[a1][0], 5) == round(verts[e][0], 5) and round(verts[a1][1], 5) == round(verts[e][1], 5):
156 a2 = e
157 else:
158 b2 = e
159 # Points
160 # a1_p = get_point((verts[a1][0], verts[a1][1], verts[a1][2]), myobj) # bottom
161 a2_p = get_point((verts[a2][0], verts[a2][1], verts[a2][2] + space), myobj) # top
162 a2_s1 = get_point((verts[a2][0], verts[a2][1], verts[a2][2]), myobj) # vertical line
163 a2_s2 = get_point((verts[a2][0], verts[a2][1], verts[a2][2] + space + fsize / 200), myobj) # vertical line
165 # b1_p = get_point((verts[b1][0], verts[b1][1], verts[b1][2]), myobj) # bottom
166 b2_p = get_point((verts[b2][0], verts[b2][1], verts[b2][2] + space), myobj) # top
167 b2_s1 = get_point((verts[b2][0], verts[b2][1], verts[b2][2]), myobj) # vertical line
168 b2_s2 = get_point((verts[b2][0], verts[b2][1], verts[b2][2] + space + fsize / 200), myobj) # vertical line
170 # converting to screen coordinates
171 screen_point_a = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_p)
172 screen_point_b = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_p)
173 screen_point_a1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_s1)
174 screen_point_b1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_s1)
175 screen_point_a2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_s2)
176 screen_point_b2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_s2)
178 # colour + line setup
179 gpu.state.blend_set('ALPHA')
180 gpu.state.line_width_set(1.0)
181 # --------------------------------
182 # Measures
183 # --------------------------------
184 if measure is True:
185 # Draw text
186 dist = distance(a2_p, b2_p)
187 txtpoint3d = interpolate3d(a2_p, b2_p, fabs(dist / 2))
188 # add a gap
189 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05)
191 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
193 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
195 # Draw horizontal line
196 draw_line(screen_point_a, screen_point_b, rgba)
197 # Draw vertical line 1 (upper vertical)
198 draw_line(screen_point_a1, screen_point_a2, rgba)
199 # Draw vertical line 2 (upper vertical)
200 draw_line(screen_point_b1, screen_point_b2, rgba)
201 # Draw vertical line 1
202 draw_line(screen_point_a, screen_point_a1, rgba)
203 # Draw vertical line 2
204 draw_line(screen_point_b, screen_point_b1, rgba)
206 # --------------------------------
207 # Wall Number
208 # --------------------------------
209 if dspname is True:
210 for i in range(0, op.wall_num):
211 ap = get_point((op.walls[i].glpoint_a[0], op.walls[i].glpoint_a[1], op.walls[i].glpoint_a[2]), myobj)
212 bp = get_point((op.walls[i].glpoint_b[0], op.walls[i].glpoint_b[1], op.walls[i].glpoint_b[2]), myobj)
214 dist = distance(ap, bp)
215 txtpoint3d = interpolate3d(ap, bp, fabs(dist / 2))
216 # add a gap
217 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2]) # + op.room_height / 2)
218 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
219 txt = "Wall: "
220 if op.walls[i].a is True:
221 txt = "Advance: "
222 if op.walls[i].curved is True:
223 txt = "Curved: "
225 draw_text(txtpoint2d[0], txtpoint2d[1], txt + str(i + 1), rgbaw, wfsize)
227 return
230 # -------------------------------------------------------------
231 # Draw door information
233 # rgba: Color
234 # fsize: Font size
235 # -------------------------------------------------------------
236 def draw_door_data(myobj, op, region, rv3d, rgba, fsize, space, measure):
238 # Points
239 a_p1 = get_point(op.glpoint_a, myobj)
240 a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj)
241 a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj)
243 t_p1 = get_point(op.glpoint_b, myobj)
244 t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj)
245 t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj)
247 b_p1 = get_point(op.glpoint_b, myobj)
248 b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj)
249 b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj)
251 c_p1 = get_point(op.glpoint_c, myobj)
252 c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj)
253 c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj)
255 d_p1 = get_point(op.glpoint_d, myobj)
256 d_p2 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_b[2] + space + fsize / 300), myobj)
257 d_p3 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] - fsize / 250), myobj)
259 e_p1 = get_point(op.glpoint_e, myobj)
260 e_p2 = get_point((op.glpoint_e[0], op.glpoint_e[1], op.glpoint_b[2] + space + fsize / 300), myobj)
261 e_p3 = get_point((op.glpoint_e[0], op.glpoint_e[1], op.glpoint_e[2] - fsize / 250), myobj)
263 # converting to screen coordinates
264 screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1)
265 screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1)
266 screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1)
267 screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1)
269 screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2)
270 screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2)
271 screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2)
272 screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2)
274 screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3)
275 screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3)
276 screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3)
277 screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3)
279 screen_point_dp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p1)
280 screen_point_dp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p2)
281 screen_point_dp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p3)
283 screen_point_ep1 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p1)
284 screen_point_ep2 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p2)
285 screen_point_ep3 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p3)
287 # colour + line setup
288 gpu.state.blend_set('ALPHA')
289 gpu.state.line_width_set(1.0)
291 # --------------------------------
292 # Measures
293 # --------------------------------
294 if measure is True:
295 # Vertical
296 dist = distance(a_p1, t_p1)
297 txtpoint3d = interpolate3d(a_p1, t_p1, fabs(dist / 2))
298 gap3d = (a_p2[0], txtpoint3d[1], txtpoint3d[2])
299 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
300 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True)
302 draw_line(screen_point_ap2, screen_point_tp2, rgba)
303 draw_line(screen_point_ap3, screen_point_ap1, rgba)
304 draw_line(screen_point_tp3, screen_point_tp1, rgba)
306 # Horizontal
307 dist = distance(b_p1, c_p1)
308 txtpoint3d = interpolate3d(b_p1, c_p1, fabs(dist / 2))
309 gap3d = (txtpoint3d[0], txtpoint3d[1], b_p2[2] + 0.02)
310 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
311 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
313 draw_line(screen_point_bp2, screen_point_cp2, rgba)
314 draw_line(screen_point_bp3, screen_point_bp1, rgba)
315 draw_line(screen_point_cp3, screen_point_cp1, rgba)
317 # Door size
318 dist = distance(d_p1, e_p1)
319 txtpoint3d = interpolate3d(d_p1, e_p1, fabs(dist / 2))
320 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.02)
321 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
322 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
324 draw_line(screen_point_dp1, screen_point_ep1, rgba)
325 draw_line(screen_point_dp2, screen_point_dp3, rgba)
326 draw_line(screen_point_ep2, screen_point_ep3, rgba)
327 return
330 # -------------------------------------------------------------
331 # Draw window rail information
333 # rgba: Color
334 # fsize: Font size
335 # -------------------------------------------------------------
336 def draw_window_rail_data(myobj, op, region, rv3d, rgba, fsize, space, measure):
338 # Points
339 a_p1 = get_point(op.glpoint_a, myobj)
340 a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj)
341 a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj)
343 t_p1 = get_point(op.glpoint_b, myobj)
344 t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj)
345 t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj)
347 b_p1 = get_point(op.glpoint_b, myobj)
348 b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj)
349 b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj)
351 c_p1 = get_point(op.glpoint_c, myobj)
352 c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj)
353 c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj)
355 # converting to screen coordinates
356 screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1)
357 screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1)
358 screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1)
359 screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1)
361 screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2)
362 screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2)
363 screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2)
364 screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2)
366 screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3)
367 screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3)
368 screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3)
369 screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3)
371 # colour + line setup
372 gpu.state.blend_set('ALPHA')
373 gpu.state.line_width_set(1.0)
375 # --------------------------------
376 # Measures
377 # --------------------------------
378 if measure is True:
379 # Vertical
380 dist = distance(a_p1, t_p1)
381 txtpoint3d = interpolate3d(a_p1, t_p1, fabs(dist / 2))
382 gap3d = (a_p2[0], txtpoint3d[1], txtpoint3d[2])
383 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
384 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True)
386 draw_line(screen_point_ap2, screen_point_tp2, rgba)
387 draw_line(screen_point_ap3, screen_point_ap1, rgba)
388 draw_line(screen_point_tp3, screen_point_tp1, rgba)
390 # Horizontal
391 dist = distance(b_p1, c_p1)
392 txtpoint3d = interpolate3d(b_p1, c_p1, fabs(dist / 2))
393 gap3d = (txtpoint3d[0], txtpoint3d[1], b_p2[2] + 0.02)
394 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
395 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
397 draw_line(screen_point_bp2, screen_point_cp2, rgba)
398 draw_line(screen_point_bp3, screen_point_bp1, rgba)
399 draw_line(screen_point_cp3, screen_point_cp1, rgba)
401 return
404 # -------------------------------------------------------------
405 # Draw window panel information
407 # rgba: Color
408 # fsize: Font size
409 # -------------------------------------------------------------
410 def draw_window_panel_data(myobj, op, region, rv3d, rgba, fsize, space, measure):
412 # Points
413 a_p1 = get_point(op.glpoint_a, myobj)
414 a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj)
415 a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj)
417 f_p1 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_a[2]), myobj)
418 f_p2 = get_point((op.glpoint_c[0] + space, op.glpoint_c[1], op.glpoint_a[2]), myobj)
419 f_p3 = get_point((op.glpoint_c[0] + space + fsize / 200, op.glpoint_c[1], op.glpoint_a[2]), myobj)
421 t_p1 = get_point(op.glpoint_b, myobj)
422 t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj)
423 t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj)
425 b_p1 = get_point(op.glpoint_b, myobj)
426 b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj)
427 b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj)
429 c_p1 = get_point(op.glpoint_c, myobj)
430 c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj)
431 c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj)
433 d_p1 = get_point(op.glpoint_c, myobj)
434 d_p2 = get_point((op.glpoint_c[0] + space, op.glpoint_c[1], op.glpoint_c[2]), myobj)
435 d_p3 = get_point((op.glpoint_c[0] + space + fsize / 200, op.glpoint_c[1], op.glpoint_c[2]), myobj)
437 g_p2 = get_point((op.glpoint_d[0], op.glpoint_d[1], 0), myobj)
438 g_p3 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2]), myobj)
439 g_p4 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] + space), myobj)
440 g_p5 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] + space + fsize / 200), myobj)
442 h_p1 = get_point((op.glpoint_a[0], op.glpoint_a[1], op.glpoint_a[2] - space), myobj)
443 h_p2 = get_point((op.glpoint_a[0], op.glpoint_a[1], op.glpoint_a[2] - space - fsize / 200), myobj)
445 h_p3 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2]), myobj)
446 h_p4 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2] - space), myobj)
447 h_p5 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2] - space - fsize / 200), myobj)
449 # converting to screen coordinates
450 screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1)
451 screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1)
452 screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1)
453 screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1)
455 screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2)
456 screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2)
457 screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2)
458 screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2)
460 screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3)
461 screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3)
462 screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3)
463 screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3)
465 screen_point_dp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p1)
466 screen_point_dp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p2)
467 screen_point_dp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p3)
469 screen_point_fp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p1)
470 screen_point_fp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p2)
471 screen_point_fp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p3)
473 screen_point_gp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p2)
474 screen_point_gp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p3)
475 screen_point_gp4 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p4)
476 screen_point_gp5 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p5)
478 # colour + line setup
479 gpu.state.blend_set('ALPHA')
480 gpu.state.line_width_set(1.0)
482 # --------------------------------
483 # Measures
484 # --------------------------------
485 if measure is True:
486 # Vertical (right)
487 dist = distance(a_p1, t_p1)
488 txtpoint3d = interpolate3d(a_p1, t_p1, fabs(dist / 2))
489 gap3d = (a_p2[0], txtpoint3d[1], txtpoint3d[2])
490 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
491 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True)
493 draw_line(screen_point_ap2, screen_point_tp2, rgba)
494 draw_line(screen_point_ap3, screen_point_ap1, rgba)
495 draw_line(screen_point_tp3, screen_point_tp1, rgba)
497 # Vertical (Left)
498 dist = distance(f_p1, d_p1)
499 txtpoint3d = interpolate3d(f_p1, d_p1, fabs(dist / 2))
500 gap3d = (f_p2[0], txtpoint3d[1], txtpoint3d[2])
501 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
502 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
504 draw_line(screen_point_fp2, screen_point_dp2, rgba)
505 draw_line(screen_point_fp1, screen_point_fp3, rgba)
506 draw_line(screen_point_dp1, screen_point_dp3, rgba)
508 # Horizontal (not triangle nor arch)
509 if op.UST != "4" and op.UST != "2":
510 dist = distance(b_p1, c_p1)
511 txtpoint3d = interpolate3d(b_p2, c_p2, fabs(dist / 2))
512 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05)
513 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
514 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
516 draw_line(screen_point_bp2, screen_point_cp2, rgba)
517 draw_line(screen_point_bp3, screen_point_bp1, rgba)
518 draw_line(screen_point_cp3, screen_point_cp1, rgba)
519 else:
520 dist = distance(b_p1, g_p3)
521 txtpoint3d = interpolate3d(b_p2, g_p4, fabs(dist / 2))
522 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05)
523 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
524 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True)
526 dist = distance(g_p3, c_p1)
527 txtpoint3d = interpolate3d(g_p4, c_p2, fabs(dist / 2))
528 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05)
529 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
530 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
532 draw_line(screen_point_bp2, screen_point_gp4, rgba)
533 draw_line(screen_point_gp4, screen_point_cp2, rgba)
534 draw_line(screen_point_bp3, screen_point_bp1, rgba)
535 draw_line(screen_point_cp3, screen_point_cp1, rgba)
536 draw_line(screen_point_gp3, screen_point_gp5, rgba)
538 # Only for Triangle or arch
539 if op.UST == "2" or op.UST == "4":
540 dist = distance(g_p2, g_p3)
541 txtpoint3d = interpolate3d(g_p2, g_p3, fabs(dist / 2))
542 gap3d = (txtpoint3d[0] + 0.05, txtpoint3d[1], txtpoint3d[2])
543 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
544 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
546 draw_line(screen_point_gp2, screen_point_gp3, rgba)
548 # Only for Triangle and Inclines or arch
549 if op.UST == "3" or op.UST == "4" or op.UST == "2":
550 screen_point_hp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p1)
551 screen_point_hp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p2)
552 screen_point_hp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p3)
553 screen_point_hp4 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p4)
554 screen_point_hp5 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p5)
556 dist = distance(h_p1, h_p3)
557 txtpoint3d = interpolate3d(h_p1, h_p3, fabs(dist / 2))
558 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] - space - 0.05)
559 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
560 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
562 draw_line(screen_point_ap1, screen_point_hp2, rgba)
563 draw_line(screen_point_hp3, screen_point_hp5, rgba)
564 draw_line(screen_point_hp1, screen_point_hp4, rgba)
566 return
569 # --------------------------------------------------------------------
570 # Distance between 2 points in 3D space
571 # v1: first point
572 # v2: second point
573 # return: distance
574 # --------------------------------------------------------------------
575 def distance(v1, v2):
576 return sqrt((v2[0] - v1[0]) ** 2 + (v2[1] - v1[1]) ** 2 + (v2[2] - v1[2]) ** 2)
579 # --------------------------------------------------------------------
580 # Interpolate 2 points in 3D space
581 # v1: first point
582 # v2: second point
583 # d1: distance
584 # return: interpolate point
585 # --------------------------------------------------------------------
586 def interpolate3d(v1, v2, d1):
587 # calculate vector
588 v = (v2[0] - v1[0], v2[1] - v1[1], v2[2] - v1[2])
589 # calculate distance between points
590 d0 = distance(v1, v2)
591 # calculate interpolate factor (distance from origin / distance total)
592 # if d1 > d0, the point is projected in 3D space
593 if d0 > 0:
594 x = d1 / d0
595 else:
596 x = d1
598 final = (v1[0] + (v[0] * x), v1[1] + (v[1] * x), v1[2] + (v[2] * x))
599 return final
602 # --------------------------------------------------------------------
603 # Get point rotated and relative to parent
604 # v1: point
605 # mainobject
606 # --------------------------------------------------------------------
607 def get_point(v1, mainobject):
609 # Using World Matrix
610 vt = Vector((v1[0], v1[1], v1[2], 1))
611 m4 = mainobject.matrix_world
612 vt2 = m4 @ vt
613 v2 = [vt2[0], vt2[1], vt2[2]]
615 return v2
618 # --------------------------------------------------------------------
619 # rotate point EULER X
620 # v1: point
621 # rad: Angles of rotation in Radians
622 # --------------------------------------------------------------------
623 def rotate_x(v1, rot):
624 v2 = [0, 0, 0]
626 radx = rot[0]
628 # X axis
629 v2[0] = v1[0]
630 v2[1] = v1[1] * cos(radx) - v1[2] * sin(radx)
631 v2[2] = v1[1] * sin(radx) + v1[2] * cos(radx)
633 return v2
636 # --------------------------------------------------------------------
637 # rotate point EULER Y
638 # v1: point
639 # rad: Angles of rotation in Radians
640 # --------------------------------------------------------------------
641 def rotate_y(v1, rot):
642 v2 = [0, 0, 0]
644 rady = rot[1]
646 # Y axis
647 v2[0] = v1[0] * cos(rady) + v1[2] * sin(rady)
648 v2[1] = v1[1]
649 v2[2] = v1[2] * cos(rady) - v1[0] * sin(rady)
651 return v2
654 # --------------------------------------------------------------------
655 # rotate point EULER Z
656 # v1: point
657 # rad: Angles of rotation in Radians
658 # --------------------------------------------------------------------
659 def rotate_z(v1, rot):
660 v2 = [0, 0, 0]
662 radz = rot[2]
664 # Z axis
665 v2[0] = v1[0] * cos(radz) - v1[1] * sin(radz)
666 v2[1] = v1[0] * sin(radz) + v1[1] * cos(radz)
667 v2[2] = v1[2]
669 return v2