# SPDX-License-Identifier: GPL-2.0-or-later # ---------------------------------------------------------- # support routines for OpenGL # Author: Antonio Vazquez (antonioya) # # ---------------------------------------------------------- # noinspection PyUnresolvedReferences import bpy # noinspection PyUnresolvedReferences import blf from math import fabs, sqrt, sin, cos # noinspection PyUnresolvedReferences from mathutils import Vector # noinspection PyUnresolvedReferences from bpy_extras import view3d_utils from .achm_room_maker import get_wall_points # GPU import bgl import gpu from gpu_extras.batch import batch_for_shader shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') if not bpy.app.background else None # ------------------------------------------------------------- # Handle all draw routines (OpenGL main entry point) # # ------------------------------------------------------------- def draw_main(context): region = context.region rv3d = context.space_data.region_3d scene = context.scene rgba = scene.archimesh_text_color rgbaw = scene.archimesh_walltext_color fsize = scene.archimesh_font_size wfsize = scene.archimesh_wfont_size space = scene.archimesh_hint_space measure = scene.archimesh_gl_measure dspname = scene.archimesh_gl_name bgl.glEnable(bgl.GL_BLEND) # Display selected or all if scene.archimesh_gl_ghost is False: objlist = context.selected_objects else: objlist = context.view_layer.objects # --------------------------------------- # Generate all OpenGL calls # --------------------------------------- for myobj in objlist: if myobj.visible_get() is True: # ----------------------------------------------------- # Rooms # ----------------------------------------------------- if 'RoomGenerator' in myobj: op = myobj.RoomGenerator[0] draw_room_data(myobj, op, region, rv3d, rgba, rgbaw, fsize, wfsize, space, measure, dspname) # ----------------------------------------------------- # Doors # ----------------------------------------------------- if 'DoorObjectGenerator' in myobj: op = myobj.DoorObjectGenerator[0] draw_door_data(myobj, op, region, rv3d, rgba, fsize, space, measure) # ----------------------------------------------------- # Window (Rail) # ----------------------------------------------------- if 'WindowObjectGenerator' in myobj: op = myobj.WindowObjectGenerator[0] draw_window_rail_data(myobj, op, region, rv3d, rgba, fsize, space, measure) # ----------------------------------------------------- # Window (Panel) # ----------------------------------------------------- if 'WindowPanelGenerator' in myobj: op = myobj.WindowPanelGenerator[0] draw_window_panel_data(myobj, op, region, rv3d, rgba, fsize, space, measure) # ----------------------- # restore opengl defaults # ----------------------- bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) # ------------------------------------------------------------- # Create OpenGL text # # right: Align to right # ------------------------------------------------------------- def draw_text(x_pos, y_pos, display_text, rgba, fsize, right=False): gap = 12 font_id = 0 blf.size(font_id, fsize, 72) text_width, text_height = blf.dimensions(font_id, display_text) if right is True: newx = x_pos - text_width - gap else: newx = x_pos blf.position(font_id, newx, y_pos, 0) blf.color(font_id, rgba[0], rgba[1], rgba[2], rgba[3]) blf.draw(font_id, display_text) return # ------------------------------------------------------------- # Draw an OpenGL line # # ------------------------------------------------------------- def draw_line(v1, v2, rgba): coords = [(v1[0], v1[1]), (v2[0], v2[1])] batch = batch_for_shader(shader, 'LINES', {"pos": coords}) # noinspection PyBroadException try: if v1 is not None and v2 is not None: shader.bind() shader.uniform_float("color", rgba) batch.draw(shader) except: pass # ------------------------------------------------------------- # Draw room information # # rgba: Color # fsize: Font size # ------------------------------------------------------------- def draw_room_data(myobj, op, region, rv3d, rgba, rgbaw, fsize, wfsize, space, measure, dspname): verts, activefaces, activenormals = get_wall_points(myobj) # -------------------------- # Get line points and draw # -------------------------- for face in activefaces: a1 = None b1 = None a2 = None b2 = None # Bottom for e in face: if verts[e][2] == 0: if a1 is None: a1 = e else: b1 = e # Top for e in face: if verts[e][2] != 0: if round(verts[a1][0], 5) == round(verts[e][0], 5) and round(verts[a1][1], 5) == round(verts[e][1], 5): a2 = e else: b2 = e # Points # a1_p = get_point((verts[a1][0], verts[a1][1], verts[a1][2]), myobj) # bottom a2_p = get_point((verts[a2][0], verts[a2][1], verts[a2][2] + space), myobj) # top a2_s1 = get_point((verts[a2][0], verts[a2][1], verts[a2][2]), myobj) # vertical line a2_s2 = get_point((verts[a2][0], verts[a2][1], verts[a2][2] + space + fsize / 200), myobj) # vertical line # b1_p = get_point((verts[b1][0], verts[b1][1], verts[b1][2]), myobj) # bottom b2_p = get_point((verts[b2][0], verts[b2][1], verts[b2][2] + space), myobj) # top b2_s1 = get_point((verts[b2][0], verts[b2][1], verts[b2][2]), myobj) # vertical line b2_s2 = get_point((verts[b2][0], verts[b2][1], verts[b2][2] + space + fsize / 200), myobj) # vertical line # converting to screen coordinates screen_point_a = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_p) screen_point_b = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_p) screen_point_a1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_s1) screen_point_b1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_s1) screen_point_a2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a2_s2) screen_point_b2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b2_s2) # colour + line setup bgl.glEnable(bgl.GL_BLEND) bgl.glLineWidth(1) # -------------------------------- # Measures # -------------------------------- if measure is True: # Draw text dist = distance(a2_p, b2_p) txtpoint3d = interpolate3d(a2_p, b2_p, fabs(dist / 2)) # add a gap gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) # Draw horizontal line draw_line(screen_point_a, screen_point_b, rgba) # Draw vertical line 1 (upper vertical) draw_line(screen_point_a1, screen_point_a2, rgba) # Draw vertical line 2 (upper vertical) draw_line(screen_point_b1, screen_point_b2, rgba) # Draw vertical line 1 draw_line(screen_point_a, screen_point_a1, rgba) # Draw vertical line 2 draw_line(screen_point_b, screen_point_b1, rgba) # -------------------------------- # Wall Number # -------------------------------- if dspname is True: for i in range(0, op.wall_num): ap = get_point((op.walls[i].glpoint_a[0], op.walls[i].glpoint_a[1], op.walls[i].glpoint_a[2]), myobj) bp = get_point((op.walls[i].glpoint_b[0], op.walls[i].glpoint_b[1], op.walls[i].glpoint_b[2]), myobj) dist = distance(ap, bp) txtpoint3d = interpolate3d(ap, bp, fabs(dist / 2)) # add a gap gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2]) # + op.room_height / 2) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) txt = "Wall: " if op.walls[i].a is True: txt = "Advance: " if op.walls[i].curved is True: txt = "Curved: " draw_text(txtpoint2d[0], txtpoint2d[1], txt + str(i + 1), rgbaw, wfsize) return # ------------------------------------------------------------- # Draw door information # # rgba: Color # fsize: Font size # ------------------------------------------------------------- def draw_door_data(myobj, op, region, rv3d, rgba, fsize, space, measure): # Points a_p1 = get_point(op.glpoint_a, myobj) a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj) a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj) t_p1 = get_point(op.glpoint_b, myobj) t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj) t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj) b_p1 = get_point(op.glpoint_b, myobj) b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj) b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj) c_p1 = get_point(op.glpoint_c, myobj) c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj) c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj) d_p1 = get_point(op.glpoint_d, myobj) d_p2 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_b[2] + space + fsize / 300), myobj) d_p3 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] - fsize / 250), myobj) e_p1 = get_point(op.glpoint_e, myobj) e_p2 = get_point((op.glpoint_e[0], op.glpoint_e[1], op.glpoint_b[2] + space + fsize / 300), myobj) e_p3 = get_point((op.glpoint_e[0], op.glpoint_e[1], op.glpoint_e[2] - fsize / 250), myobj) # converting to screen coordinates screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1) screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1) screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1) screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1) screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2) screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2) screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2) screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2) screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3) screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3) screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3) screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3) screen_point_dp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p1) screen_point_dp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p2) screen_point_dp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p3) screen_point_ep1 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p1) screen_point_ep2 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p2) screen_point_ep3 = view3d_utils.location_3d_to_region_2d(region, rv3d, e_p3) # colour + line setup bgl.glEnable(bgl.GL_BLEND) bgl.glLineWidth(1) # -------------------------------- # Measures # -------------------------------- if measure is True: # Vertical dist = distance(a_p1, t_p1) txtpoint3d = interpolate3d(a_p1, t_p1, fabs(dist / 2)) gap3d = (a_p2[0], txtpoint3d[1], txtpoint3d[2]) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True) draw_line(screen_point_ap2, screen_point_tp2, rgba) draw_line(screen_point_ap3, screen_point_ap1, rgba) draw_line(screen_point_tp3, screen_point_tp1, rgba) # Horizontal dist = distance(b_p1, c_p1) txtpoint3d = interpolate3d(b_p1, c_p1, fabs(dist / 2)) gap3d = (txtpoint3d[0], txtpoint3d[1], b_p2[2] + 0.02) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) draw_line(screen_point_bp2, screen_point_cp2, rgba) draw_line(screen_point_bp3, screen_point_bp1, rgba) draw_line(screen_point_cp3, screen_point_cp1, rgba) # Door size dist = distance(d_p1, e_p1) txtpoint3d = interpolate3d(d_p1, e_p1, fabs(dist / 2)) gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.02) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) draw_line(screen_point_dp1, screen_point_ep1, rgba) draw_line(screen_point_dp2, screen_point_dp3, rgba) draw_line(screen_point_ep2, screen_point_ep3, rgba) return # ------------------------------------------------------------- # Draw window rail information # # rgba: Color # fsize: Font size # ------------------------------------------------------------- def draw_window_rail_data(myobj, op, region, rv3d, rgba, fsize, space, measure): # Points a_p1 = get_point(op.glpoint_a, myobj) a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj) a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj) t_p1 = get_point(op.glpoint_b, myobj) t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj) t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj) b_p1 = get_point(op.glpoint_b, myobj) b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj) b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj) c_p1 = get_point(op.glpoint_c, myobj) c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj) c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj) # converting to screen coordinates screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1) screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1) screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1) screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1) screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2) screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2) screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2) screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2) screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3) screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3) screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3) screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3) # colour + line setup bgl.glEnable(bgl.GL_BLEND) bgl.glLineWidth(1) # -------------------------------- # Measures # -------------------------------- if measure is True: # Vertical dist = distance(a_p1, t_p1) txtpoint3d = interpolate3d(a_p1, t_p1, fabs(dist / 2)) gap3d = (a_p2[0], txtpoint3d[1], txtpoint3d[2]) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True) draw_line(screen_point_ap2, screen_point_tp2, rgba) draw_line(screen_point_ap3, screen_point_ap1, rgba) draw_line(screen_point_tp3, screen_point_tp1, rgba) # Horizontal dist = distance(b_p1, c_p1) txtpoint3d = interpolate3d(b_p1, c_p1, fabs(dist / 2)) gap3d = (txtpoint3d[0], txtpoint3d[1], b_p2[2] + 0.02) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) draw_line(screen_point_bp2, screen_point_cp2, rgba) draw_line(screen_point_bp3, screen_point_bp1, rgba) draw_line(screen_point_cp3, screen_point_cp1, rgba) return # ------------------------------------------------------------- # Draw window panel information # # rgba: Color # fsize: Font size # ------------------------------------------------------------- def draw_window_panel_data(myobj, op, region, rv3d, rgba, fsize, space, measure): # Points a_p1 = get_point(op.glpoint_a, myobj) a_p2 = get_point((op.glpoint_a[0] - space, op.glpoint_a[1], op.glpoint_a[2]), myobj) a_p3 = get_point((op.glpoint_a[0] - space - fsize / 200, op.glpoint_a[1], op.glpoint_a[2]), myobj) f_p1 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_a[2]), myobj) f_p2 = get_point((op.glpoint_c[0] + space, op.glpoint_c[1], op.glpoint_a[2]), myobj) f_p3 = get_point((op.glpoint_c[0] + space + fsize / 200, op.glpoint_c[1], op.glpoint_a[2]), myobj) t_p1 = get_point(op.glpoint_b, myobj) t_p2 = get_point((op.glpoint_b[0] - space, op.glpoint_b[1], op.glpoint_b[2]), myobj) t_p3 = get_point((op.glpoint_b[0] - space - fsize / 200, op.glpoint_b[1], op.glpoint_b[2]), myobj) b_p1 = get_point(op.glpoint_b, myobj) b_p2 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space), myobj) b_p3 = get_point((op.glpoint_b[0], op.glpoint_b[1], op.glpoint_b[2] + space + fsize / 200), myobj) c_p1 = get_point(op.glpoint_c, myobj) c_p2 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space), myobj) c_p3 = get_point((op.glpoint_c[0], op.glpoint_c[1], op.glpoint_c[2] + space + fsize / 200), myobj) d_p1 = get_point(op.glpoint_c, myobj) d_p2 = get_point((op.glpoint_c[0] + space, op.glpoint_c[1], op.glpoint_c[2]), myobj) d_p3 = get_point((op.glpoint_c[0] + space + fsize / 200, op.glpoint_c[1], op.glpoint_c[2]), myobj) g_p2 = get_point((op.glpoint_d[0], op.glpoint_d[1], 0), myobj) g_p3 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2]), myobj) g_p4 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] + space), myobj) g_p5 = get_point((op.glpoint_d[0], op.glpoint_d[1], op.glpoint_d[2] + space + fsize / 200), myobj) h_p1 = get_point((op.glpoint_a[0], op.glpoint_a[1], op.glpoint_a[2] - space), myobj) h_p2 = get_point((op.glpoint_a[0], op.glpoint_a[1], op.glpoint_a[2] - space - fsize / 200), myobj) h_p3 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2]), myobj) h_p4 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2] - space), myobj) h_p5 = get_point((op.glpoint_c[0], op.glpoint_a[1], op.glpoint_a[2] - space - fsize / 200), myobj) # converting to screen coordinates screen_point_ap1 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p1) screen_point_bp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p1) screen_point_cp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p1) screen_point_tp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p1) screen_point_ap2 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p2) screen_point_bp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p2) screen_point_cp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p2) screen_point_tp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p2) screen_point_ap3 = view3d_utils.location_3d_to_region_2d(region, rv3d, a_p3) screen_point_bp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, b_p3) screen_point_cp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, c_p3) screen_point_tp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, t_p3) screen_point_dp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p1) screen_point_dp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p2) screen_point_dp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, d_p3) screen_point_fp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p1) screen_point_fp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p2) screen_point_fp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, f_p3) screen_point_gp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p2) screen_point_gp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p3) screen_point_gp4 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p4) screen_point_gp5 = view3d_utils.location_3d_to_region_2d(region, rv3d, g_p5) # colour + line setup bgl.glEnable(bgl.GL_BLEND) bgl.glLineWidth(1) # -------------------------------- # Measures # -------------------------------- if measure is True: # Vertical (right) dist = distance(a_p1, t_p1) txtpoint3d = interpolate3d(a_p1, t_p1, fabs(dist / 2)) gap3d = (a_p2[0], txtpoint3d[1], txtpoint3d[2]) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True) draw_line(screen_point_ap2, screen_point_tp2, rgba) draw_line(screen_point_ap3, screen_point_ap1, rgba) draw_line(screen_point_tp3, screen_point_tp1, rgba) # Vertical (Left) dist = distance(f_p1, d_p1) txtpoint3d = interpolate3d(f_p1, d_p1, fabs(dist / 2)) gap3d = (f_p2[0], txtpoint3d[1], txtpoint3d[2]) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) draw_line(screen_point_fp2, screen_point_dp2, rgba) draw_line(screen_point_fp1, screen_point_fp3, rgba) draw_line(screen_point_dp1, screen_point_dp3, rgba) # Horizontal (not triangle nor arch) if op.UST != "4" and op.UST != "2": dist = distance(b_p1, c_p1) txtpoint3d = interpolate3d(b_p2, c_p2, fabs(dist / 2)) gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) draw_line(screen_point_bp2, screen_point_cp2, rgba) draw_line(screen_point_bp3, screen_point_bp1, rgba) draw_line(screen_point_cp3, screen_point_cp1, rgba) else: dist = distance(b_p1, g_p3) txtpoint3d = interpolate3d(b_p2, g_p4, fabs(dist / 2)) gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize, True) dist = distance(g_p3, c_p1) txtpoint3d = interpolate3d(g_p4, c_p2, fabs(dist / 2)) gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] + 0.05) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) draw_line(screen_point_bp2, screen_point_gp4, rgba) draw_line(screen_point_gp4, screen_point_cp2, rgba) draw_line(screen_point_bp3, screen_point_bp1, rgba) draw_line(screen_point_cp3, screen_point_cp1, rgba) draw_line(screen_point_gp3, screen_point_gp5, rgba) # Only for Triangle or arch if op.UST == "2" or op.UST == "4": dist = distance(g_p2, g_p3) txtpoint3d = interpolate3d(g_p2, g_p3, fabs(dist / 2)) gap3d = (txtpoint3d[0] + 0.05, txtpoint3d[1], txtpoint3d[2]) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) draw_line(screen_point_gp2, screen_point_gp3, rgba) # Only for Triangle and Inclines or arch if op.UST == "3" or op.UST == "4" or op.UST == "2": screen_point_hp1 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p1) screen_point_hp2 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p2) screen_point_hp3 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p3) screen_point_hp4 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p4) screen_point_hp5 = view3d_utils.location_3d_to_region_2d(region, rv3d, h_p5) dist = distance(h_p1, h_p3) txtpoint3d = interpolate3d(h_p1, h_p3, fabs(dist / 2)) gap3d = (txtpoint3d[0], txtpoint3d[1], txtpoint3d[2] - space - 0.05) txtpoint2d = view3d_utils.location_3d_to_region_2d(region, rv3d, gap3d) draw_text(txtpoint2d[0], txtpoint2d[1], "%6.2f" % dist, rgba, fsize) draw_line(screen_point_ap1, screen_point_hp2, rgba) draw_line(screen_point_hp3, screen_point_hp5, rgba) draw_line(screen_point_hp1, screen_point_hp4, rgba) return # -------------------------------------------------------------------- # Distance between 2 points in 3D space # v1: first point # v2: second point # return: distance # -------------------------------------------------------------------- def distance(v1, v2): return sqrt((v2[0] - v1[0]) ** 2 + (v2[1] - v1[1]) ** 2 + (v2[2] - v1[2]) ** 2) # -------------------------------------------------------------------- # Interpolate 2 points in 3D space # v1: first point # v2: second point # d1: distance # return: interpolate point # -------------------------------------------------------------------- def interpolate3d(v1, v2, d1): # calculate vector v = (v2[0] - v1[0], v2[1] - v1[1], v2[2] - v1[2]) # calculate distance between points d0 = distance(v1, v2) # calculate interpolate factor (distance from origin / distance total) # if d1 > d0, the point is projected in 3D space if d0 > 0: x = d1 / d0 else: x = d1 final = (v1[0] + (v[0] * x), v1[1] + (v[1] * x), v1[2] + (v[2] * x)) return final # -------------------------------------------------------------------- # Get point rotated and relative to parent # v1: point # mainobject # -------------------------------------------------------------------- def get_point(v1, mainobject): # Using World Matrix vt = Vector((v1[0], v1[1], v1[2], 1)) m4 = mainobject.matrix_world vt2 = m4 @ vt v2 = [vt2[0], vt2[1], vt2[2]] return v2 # -------------------------------------------------------------------- # rotate point EULER X # v1: point # rad: Angles of rotation in Radians # -------------------------------------------------------------------- def rotate_x(v1, rot): v2 = [0, 0, 0] radx = rot[0] # X axis v2[0] = v1[0] v2[1] = v1[1] * cos(radx) - v1[2] * sin(radx) v2[2] = v1[1] * sin(radx) + v1[2] * cos(radx) return v2 # -------------------------------------------------------------------- # rotate point EULER Y # v1: point # rad: Angles of rotation in Radians # -------------------------------------------------------------------- def rotate_y(v1, rot): v2 = [0, 0, 0] rady = rot[1] # Y axis v2[0] = v1[0] * cos(rady) + v1[2] * sin(rady) v2[1] = v1[1] v2[2] = v1[2] * cos(rady) - v1[0] * sin(rady) return v2 # -------------------------------------------------------------------- # rotate point EULER Z # v1: point # rad: Angles of rotation in Radians # -------------------------------------------------------------------- def rotate_z(v1, rot): v2 = [0, 0, 0] radz = rot[2] # Z axis v2[0] = v1[0] * cos(radz) - v1[1] * sin(radz) v2[1] = v1[0] * sin(radz) + v1[1] * cos(radz) v2[2] = v1[2] return v2