blender-addons/archimesh/achm_gltools.py

686 lines
29 KiB
Python

# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# ----------------------------------------------------------
# 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