File headers: use SPDX license identifiers
[blender-addons.git] / archimesh / achm_gltools.py
blob0ee8f94100aa786befdd0d0ce8892c8f6dc334f0
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # <pep8 compliant>
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 bgl
22 import gpu
23 from gpu_extras.batch import batch_for_shader
25 shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') if not bpy.app.background else None
27 # -------------------------------------------------------------
28 # Handle all draw routines (OpenGL main entry point)
30 # -------------------------------------------------------------
31 def draw_main(context):
32 region = context.region
33 rv3d = context.space_data.region_3d
34 scene = context.scene
36 rgba = scene.archimesh_text_color
37 rgbaw = scene.archimesh_walltext_color
38 fsize = scene.archimesh_font_size
39 wfsize = scene.archimesh_wfont_size
40 space = scene.archimesh_hint_space
41 measure = scene.archimesh_gl_measure
42 dspname = scene.archimesh_gl_name
44 bgl.glEnable(bgl.GL_BLEND)
45 # Display selected or all
46 if scene.archimesh_gl_ghost is False:
47 objlist = context.selected_objects
48 else:
49 objlist = context.view_layer.objects
50 # ---------------------------------------
51 # Generate all OpenGL calls
52 # ---------------------------------------
53 for myobj in objlist:
54 if myobj.visible_get() is True:
55 # -----------------------------------------------------
56 # Rooms
57 # -----------------------------------------------------
58 if 'RoomGenerator' in myobj:
59 op = myobj.RoomGenerator[0]
60 draw_room_data(myobj, op, region, rv3d, rgba, rgbaw, fsize, wfsize, space, measure, dspname)
62 # -----------------------------------------------------
63 # Doors
64 # -----------------------------------------------------
65 if 'DoorObjectGenerator' in myobj:
66 op = myobj.DoorObjectGenerator[0]
67 draw_door_data(myobj, op, region, rv3d, rgba, fsize, space, measure)
69 # -----------------------------------------------------
70 # Window (Rail)
71 # -----------------------------------------------------
72 if 'WindowObjectGenerator' in myobj:
73 op = myobj.WindowObjectGenerator[0]
74 draw_window_rail_data(myobj, op, region, rv3d, rgba, fsize, space, measure)
76 # -----------------------------------------------------
77 # Window (Panel)
78 # -----------------------------------------------------
79 if 'WindowPanelGenerator' in myobj:
80 op = myobj.WindowPanelGenerator[0]
81 draw_window_panel_data(myobj, op, region, rv3d, rgba, fsize, space, measure)
83 # -----------------------
84 # restore opengl defaults
85 # -----------------------
86 bgl.glLineWidth(1)
87 bgl.glDisable(bgl.GL_BLEND)
90 # -------------------------------------------------------------
91 # Create OpenGL text
93 # right: Align to right
94 # -------------------------------------------------------------
95 def draw_text(x_pos, y_pos, display_text, rgba, fsize, right=False):
96 gap = 12
97 font_id = 0
98 blf.size(font_id, fsize, 72)
100 text_width, text_height = blf.dimensions(font_id, display_text)
101 if right is True:
102 newx = x_pos - text_width - gap
103 else:
104 newx = x_pos
105 blf.position(font_id, newx, y_pos, 0)
106 blf.color(font_id, rgba[0], rgba[1], rgba[2], rgba[3])
107 blf.draw(font_id, display_text)
108 return
111 # -------------------------------------------------------------
112 # Draw an OpenGL line
114 # -------------------------------------------------------------
115 def draw_line(v1, v2, rgba):
116 coords = [(v1[0], v1[1]), (v2[0], v2[1])]
117 batch = batch_for_shader(shader, 'LINES', {"pos": coords})
119 # noinspection PyBroadException
120 try:
121 if v1 is not None and v2 is not None:
122 shader.bind()
123 shader.uniform_float("color", rgba)
124 batch.draw(shader)
125 except:
126 pass
128 # -------------------------------------------------------------
129 # Draw room information
131 # rgba: Color
132 # fsize: Font size
133 # -------------------------------------------------------------
134 def draw_room_data(myobj, op, region, rv3d, rgba, rgbaw, fsize, wfsize, space, measure, dspname):
136 verts, activefaces, activenormals = get_wall_points(myobj)
138 # --------------------------
139 # Get line points and draw
140 # --------------------------
141 for face in activefaces:
142 a1 = None
143 b1 = None
144 a2 = None
145 b2 = None
146 # Bottom
147 for e in face:
148 if verts[e][2] == 0:
149 if a1 is None:
150 a1 = e
151 else:
152 b1 = e
153 # Top
154 for e in face:
155 if verts[e][2] != 0:
156 if round(verts[a1][0], 5) == round(verts[e][0], 5) and round(verts[a1][1], 5) == round(verts[e][1], 5):
157 a2 = e
158 else:
159 b2 = e
160 # Points
161 # a1_p = get_point((verts[a1][0], verts[a1][1], verts[a1][2]), myobj) # bottom
162 a2_p = get_point((verts[a2][0], verts[a2][1], verts[a2][2] + space), myobj) # top
163 a2_s1 = get_point((verts[a2][0], verts[a2][1], verts[a2][2]), myobj) # vertical line
164 a2_s2 = get_point((verts[a2][0], verts[a2][1], verts[a2][2] + space + fsize / 200), myobj) # vertical line
166 # b1_p = get_point((verts[b1][0], verts[b1][1], verts[b1][2]), myobj) # bottom
167 b2_p = get_point((verts[b2][0], verts[b2][1], verts[b2][2] + space), myobj) # top
168 b2_s1 = get_point((verts[b2][0], verts[b2][1], verts[b2][2]), myobj) # vertical line
169 b2_s2 = get_point((verts[b2][0], verts[b2][1], verts[b2][2] + space + fsize / 200), myobj) # vertical line
171 # converting to screen coordinates
172 screen_point_a = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_p)
173 screen_point_b = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_p)
174 screen_point_a1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_s1)
175 screen_point_b1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_s1)
176 screen_point_a2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_s2)
177 screen_point_b2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_s2)
179 # colour + line setup
180 bgl.glEnable(bgl.GL_BLEND)
181 bgl.glLineWidth(1)
182 # --------------------------------
183 # Measures
184 # --------------------------------
185 if measure is True:
186 # Draw text
187 dist = distance(a2_p, b2_p)
188 txtpoint3d = interpolate3d(a2_p, b2_p, fabs(dist / 2))
189 # add a gap
190 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05)
192 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
194 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
196 # Draw horizontal line
197 draw_line(screen_point_a, screen_point_b, rgba)
198 # Draw vertical line 1 (upper vertical)
199 draw_line(screen_point_a1, screen_point_a2, rgba)
200 # Draw vertical line 2 (upper vertical)
201 draw_line(screen_point_b1, screen_point_b2, rgba)
202 # Draw vertical line 1
203 draw_line(screen_point_a, screen_point_a1, rgba)
204 # Draw vertical line 2
205 draw_line(screen_point_b, screen_point_b1, rgba)
207 # --------------------------------
208 # Wall Number
209 # --------------------------------
210 if dspname is True:
211 for i in range(0, op.wall_num):
212 ap = get_point((op.walls[i].glpoint_a[0], op.walls[i].glpoint_a[1], op.walls[i].glpoint_a[2]), myobj)
213 bp = get_point((op.walls[i].glpoint_b[0], op.walls[i].glpoint_b[1], op.walls[i].glpoint_b[2]), myobj)
215 dist = distance(ap, bp)
216 txtpoint3d = interpolate3d(ap, bp, fabs(dist / 2))
217 # add a gap
218 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2]) # + op.room_height / 2)
219 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
220 txt = "Wall: "
221 if op.walls[i].a is True:
222 txt = "Advance: "
223 if op.walls[i].curved is True:
224 txt = "Curved: "
226 draw_text(txtpoint2d[0], txtpoint2d[1], txt + str(i + 1), rgbaw, wfsize)
228 return
231 # -------------------------------------------------------------
232 # Draw door information
234 # rgba: Color
235 # fsize: Font size
236 # -------------------------------------------------------------
237 def draw_door_data(myobj, op, region, rv3d, rgba, fsize, space, measure):
239 # Points
240 a_p1 = get_point(op.glpoint_a, myobj)
241 a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj)
242 a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj)
244 t_p1 = get_point(op.glpoint_b, myobj)
245 t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj)
246 t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj)
248 b_p1 = get_point(op.glpoint_b, myobj)
249 b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj)
250 b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj)
252 c_p1 = get_point(op.glpoint_c, myobj)
253 c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj)
254 c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj)
256 d_p1 = get_point(op.glpoint_d, myobj)
257 d_p2 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_b[2] + space + fsize / 300), myobj)
258 d_p3 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] - fsize / 250), myobj)
260 e_p1 = get_point(op.glpoint_e, myobj)
261 e_p2 = get_point((op.glpoint_e[0], op.glpoint_e[1], op.glpoint_b[2] + space + fsize / 300), myobj)
262 e_p3 = get_point((op.glpoint_e[0], op.glpoint_e[1], op.glpoint_e[2] - fsize / 250), myobj)
264 # converting to screen coordinates
265 screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1)
266 screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1)
267 screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1)
268 screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1)
270 screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2)
271 screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2)
272 screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2)
273 screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2)
275 screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3)
276 screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3)
277 screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3)
278 screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3)
280 screen_point_dp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p1)
281 screen_point_dp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p2)
282 screen_point_dp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p3)
284 screen_point_ep1 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p1)
285 screen_point_ep2 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p2)
286 screen_point_ep3 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p3)
288 # colour + line setup
289 bgl.glEnable(bgl.GL_BLEND)
290 bgl.glLineWidth(1)
292 # --------------------------------
293 # Measures
294 # --------------------------------
295 if measure is True:
296 # Vertical
297 dist = distance(a_p1, t_p1)
298 txtpoint3d = interpolate3d(a_p1, t_p1, fabs(dist / 2))
299 gap3d = (a_p2[0], txtpoint3d[1], txtpoint3d[2])
300 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
301 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True)
303 draw_line(screen_point_ap2, screen_point_tp2, rgba)
304 draw_line(screen_point_ap3, screen_point_ap1, rgba)
305 draw_line(screen_point_tp3, screen_point_tp1, rgba)
307 # Horizontal
308 dist = distance(b_p1, c_p1)
309 txtpoint3d = interpolate3d(b_p1, c_p1, fabs(dist / 2))
310 gap3d = (txtpoint3d[0], txtpoint3d[1], b_p2[2] + 0.02)
311 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
312 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
314 draw_line(screen_point_bp2, screen_point_cp2, rgba)
315 draw_line(screen_point_bp3, screen_point_bp1, rgba)
316 draw_line(screen_point_cp3, screen_point_cp1, rgba)
318 # Door size
319 dist = distance(d_p1, e_p1)
320 txtpoint3d = interpolate3d(d_p1, e_p1, fabs(dist / 2))
321 gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.02)
322 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
323 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
325 draw_line(screen_point_dp1, screen_point_ep1, rgba)
326 draw_line(screen_point_dp2, screen_point_dp3, rgba)
327 draw_line(screen_point_ep2, screen_point_ep3, rgba)
328 return
331 # -------------------------------------------------------------
332 # Draw window rail information
334 # rgba: Color
335 # fsize: Font size
336 # -------------------------------------------------------------
337 def draw_window_rail_data(myobj, op, region, rv3d, rgba, fsize, space, measure):
339 # Points
340 a_p1 = get_point(op.glpoint_a, myobj)
341 a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj)
342 a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj)
344 t_p1 = get_point(op.glpoint_b, myobj)
345 t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj)
346 t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj)
348 b_p1 = get_point(op.glpoint_b, myobj)
349 b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj)
350 b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj)
352 c_p1 = get_point(op.glpoint_c, myobj)
353 c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj)
354 c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj)
356 # converting to screen coordinates
357 screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1)
358 screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1)
359 screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1)
360 screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1)
362 screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2)
363 screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2)
364 screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2)
365 screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2)
367 screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3)
368 screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3)
369 screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3)
370 screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3)
372 # colour + line setup
373 bgl.glEnable(bgl.GL_BLEND)
374 bgl.glLineWidth(1)
376 # --------------------------------
377 # Measures
378 # --------------------------------
379 if measure is True:
380 # Vertical
381 dist = distance(a_p1, t_p1)
382 txtpoint3d = interpolate3d(a_p1, t_p1, fabs(dist / 2))
383 gap3d = (a_p2[0], txtpoint3d[1], txtpoint3d[2])
384 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
385 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True)
387 draw_line(screen_point_ap2, screen_point_tp2, rgba)
388 draw_line(screen_point_ap3, screen_point_ap1, rgba)
389 draw_line(screen_point_tp3, screen_point_tp1, rgba)
391 # Horizontal
392 dist = distance(b_p1, c_p1)
393 txtpoint3d = interpolate3d(b_p1, c_p1, fabs(dist / 2))
394 gap3d = (txtpoint3d[0], txtpoint3d[1], b_p2[2] + 0.02)
395 txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d)
396 draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize)
398 draw_line(screen_point_bp2, screen_point_cp2, rgba)
399 draw_line(screen_point_bp3, screen_point_bp1, rgba)
400 draw_line(screen_point_cp3, screen_point_cp1, rgba)
402 return
405 # -------------------------------------------------------------
406 # Draw window panel information
408 # rgba: Color
409 # fsize: Font size
410 # -------------------------------------------------------------
411 def draw_window_panel_data(myobj, op, region, rv3d, rgba, fsize, space, measure):
413 # Points
414 a_p1 = get_point(op.glpoint_a, myobj)
415 a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj)
416 a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj)
418 f_p1 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_a[2]), myobj)
419 f_p2 = get_point((op.glpoint_c[0] + space, op.glpoint_c[1], op.glpoint_a[2]), myobj)
420 f_p3 = get_point((op.glpoint_c[0] + space + fsize / 200, op.glpoint_c[1], op.glpoint_a[2]), myobj)
422 t_p1 = get_point(op.glpoint_b, myobj)
423 t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj)
424 t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj)
426 b_p1 = get_point(op.glpoint_b, myobj)
427 b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj)
428 b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj)
430 c_p1 = get_point(op.glpoint_c, myobj)
431 c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj)
432 c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj)
434 d_p1 = get_point(op.glpoint_c, myobj)
435 d_p2 = get_point((op.glpoint_c[0] + space, op.glpoint_c[1], op.glpoint_c[2]), myobj)
436 d_p3 = get_point((op.glpoint_c[0] + space + fsize / 200, op.glpoint_c[1], op.glpoint_c[2]), myobj)
438 g_p2 = get_point((op.glpoint_d[0], op.glpoint_d[1], 0), myobj)
439 g_p3 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2]), myobj)
440 g_p4 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] + space), myobj)
441 g_p5 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] + space + fsize / 200), myobj)
443 h_p1 = get_point((op.glpoint_a[0], op.glpoint_a[1], op.glpoint_a[2] - space), myobj)
444 h_p2 = get_point((op.glpoint_a[0], op.glpoint_a[1], op.glpoint_a[2] - space - fsize / 200), myobj)
446 h_p3 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2]), myobj)
447 h_p4 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2] - space), myobj)
448 h_p5 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2] - space - fsize / 200), myobj)
450 # converting to screen coordinates
451 screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1)
452 screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1)
453 screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1)
454 screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1)
456 screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2)
457 screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2)
458 screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2)
459 screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2)
461 screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3)
462 screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3)
463 screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3)
464 screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3)
466 screen_point_dp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p1)
467 screen_point_dp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p2)
468 screen_point_dp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p3)
470 screen_point_fp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p1)
471 screen_point_fp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p2)
472 screen_point_fp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p3)
474 screen_point_gp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p2)
475 screen_point_gp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p3)
476 screen_point_gp4 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p4)
477 screen_point_gp5 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p5)
478 # colour + line setup
479 bgl.glEnable(bgl.GL_BLEND)
480 bgl.glLineWidth(1)
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