Newer
Older
return fmt
# -------------------------------------------------------------
# Draw object num for debug
#
# -------------------------------------------------------------
# noinspection PyUnresolvedReferences,PyUnboundLocalVariable,PyUnusedLocal
def draw_object(context, myobj, region, rv3d):
scene = bpy.context.scene
rgba = scene.measureit_debug_obj_color
fsize = scene.measureit_debug_font
precision = scene.measureit_debug_precision
# --------------------
# object Loop
# --------------------
objs = bpy.context.scene.objects
obidxs = list(range(len(bpy.context.scene.objects)))
for o in obidxs:
# Display only selected
if scene.measureit_debug_select is True:
a_p1 = Vector(get_location(objs[o]))
# Text
txt = ''
if scene.measureit_debug_objects is True:
txt += str(o)
if scene.measureit_debug_object_loc is True:
txt += format_point(a_p1, precision)
# converting to screen coordinates
txtpoint2d = get_2d_point(region, rv3d, a_p1)
draw_text(myobj, txtpoint2d, txt, rgba, fsize)
# -------------------------------------------------------------
# Draw vertex num for debug
#
# -------------------------------------------------------------
# noinspection PyUnresolvedReferences,PyUnboundLocalVariable,PyUnusedLocal
def draw_vertices(context, myobj, region, rv3d):
# Only meshes
if myobj.type != "MESH":
return
scene = bpy.context.scene
rgba = scene.measureit_debug_vert_color
fsize = scene.measureit_debug_font
precision = scene.measureit_debug_precision
# --------------------
# vertex Loop
# --------------------
if scene.measureit_debug_vert_loc_toggle == '1':
co_mult = lambda c: c
else: # if global, convert local c to global
co_mult = lambda c: myobj.matrix_world @ c
if myobj.mode == 'EDIT':
bm = from_edit_mesh(myobj.data)
obverts = bm.verts
else:
obverts = myobj.data.vertices
for v in obverts:
# Display only selected
if scene.measureit_debug_select is True:
if v.select is False:
continue
# noinspection PyBroadException
a_p1 = get_point(v.co, myobj)
# converting to screen coordinates
txtpoint2d = get_2d_point(region, rv3d, a_p1)
# Text
txt = ''
if scene.measureit_debug_vertices is True:
txt += str(v.index)
if scene.measureit_debug_vert_loc is True:
txt += format_point(co_mult(v.co), precision)
draw_text(myobj, txtpoint2d, txt, rgba, fsize)
# except:
# print("Unexpected error:" + str(exc_info()))
# pass
return
# -------------------------------------------------------------
# Draw edge num for debug
#
# -------------------------------------------------------------
# noinspection PyUnresolvedReferences,PyUnboundLocalVariable,PyUnusedLocal
def draw_edges(context, myobj, region, rv3d):
# Only meshes
if myobj.type != "MESH":
return
rgba = scene.measureit_debug_edge_color
fsize = scene.measureit_debug_font
precision = scene.measureit_debug_precision
# --------------------
# edge Loop
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
# uses lambda for edge midpoint finder (midf) because edit mode
# edge vert coordinate is not stored in same places as in obj mode
# --------------------
if myobj.mode == 'EDIT':
bm = from_edit_mesh(myobj.data)
obedges = bm.edges
obverts = None # dummy value to avoid duplicating for loop
midf = lambda e, v: e.verts[0].co.lerp(e.verts[1].co, 0.5)
else:
obedges = myobj.data.edges
obverts = myobj.data.vertices
midf = lambda e, v: v[e.vertices[0]].co.lerp(v[e.vertices[1]].co, 0.5)
for e in obedges:
# Display only selected
if scene.measureit_debug_select is True:
if e.select is False:
continue
a_mp = midf(e, obverts)
a_p1 = get_point(a_mp, myobj)
# converting to screen coordinates
txtpoint2d = get_2d_point(region, rv3d, a_p1)
draw_text(myobj, txtpoint2d, str(e.index), rgba, fsize)
return
# -------------------------------------------------------------
# Draw face num for debug
#
# -------------------------------------------------------------
# noinspection PyUnresolvedReferences,PyUnboundLocalVariable,PyUnusedLocal
def draw_faces(context, myobj, region, rv3d):
# Only meshes
if myobj.type != "MESH":
return
scene = bpy.context.scene
rgba = scene.measureit_debug_face_color
rgba2 = scene.measureit_debug_norm_color
fsize = scene.measureit_debug_font
ln = scene.measureit_debug_normal_size
th = scene.measureit_debug_width
precision = scene.measureit_debug_precision
# --------------------
# face Loop
# --------------------
if myobj.mode == 'EDIT':
bm = from_edit_mesh(myobj.data)
obverts = bm.verts
myfaces = bm.faces
else:
obverts = myobj.data.vertices
myfaces = myobj.data.polygons
for f in myfaces:
normal = f.normal
# Display only selected
if scene.measureit_debug_select is True:
if f.select is False:
continue
# noinspection PyBroadException
try:
if myobj.mode == 'EDIT':
a_p1 = get_point(f.calc_center_median(), myobj)
else:
a_p1 = get_point(f.center, myobj)
a_p2 = (a_p1[0] + normal[0] * ln, a_p1[1] + normal[1] * ln, a_p1[2] + normal[2] * ln)
gpu.state.blend_set('ALPHA')
imm_set_line_width(th)
# converting to screen coordinates
txtpoint2d = get_2d_point(region, rv3d, a_p1)
point2 = get_2d_point(region, rv3d, a_p2)
# Text
if scene.measureit_debug_faces is True:
draw_text(myobj, txtpoint2d, str(f.index), rgba, fsize)
# Draw Normal
if scene.measureit_debug_normals is True:
gpu.state.blend_set('ALPHA')
draw_arrow(txtpoint2d, point2, rgba, 10, "99", "1")
if len(obverts) > 2 and scene.measureit_debug_normal_details is True:
if myobj.mode == 'EDIT':
i1 = f.verts[0].index
i2 = f.verts[1].index
i3 = f.verts[2].index
else:
i1 = f.vertices[0]
i2 = f.vertices[1]
i3 = f.vertices[2]
a_p1 = get_point(obverts[i1].co, myobj)
a_p2 = get_point(obverts[i2].co, myobj)
a_p3 = get_point(obverts[i3].co, myobj)
# converting to screen coordinates
a2d = get_2d_point(region, rv3d, a_p1)
b2d = get_2d_point(region, rv3d, a_p2)
c2d = get_2d_point(region, rv3d, a_p3)
# draw vectors
draw_arrow(a2d, b2d, rgba, 10, "99", "1")
draw_arrow(b2d, c2d, rgba, 10, "99", "1")
# Normal vector data
txt = format_point(normal, precision)
draw_text(myobj, point2, txt, rgba2, fsize)
except:
print("Unexpected error:" + str(exc_info()))
pass
return
# --------------------------------------------------------------------
# Distance between 2 points in 3D space
# v1: first point
# v2: second point
# locx/y/z: Use this axis
# return: distance
# --------------------------------------------------------------------
def distance(v1, v2, locx=True, locy=True, locz=True):
x = sqrt((v2[0] - v1[0]) ** 2 + (v2[1] - v1[1]) ** 2 + (v2[2] - v1[2]) ** 2)
# If axis is not used, make equal both (no distance)
v1b = [v1[0], v1[1], v1[2]]
v2b = [v2[0], v2[1], v2[2]]
if locx is False:
v2b[0] = v1b[0]
if locy is False:
v2b[1] = v1b[1]
if locz is False:
v2b[2] = v1b[2]
xloc = sqrt((v2b[0] - v1b[0]) ** 2 + (v2b[1] - v1b[1]) ** 2 + (v2b[2] - v1b[2]) ** 2)
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
return x, xloc
# --------------------------------------------------------------------
# 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, dloc = 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
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
v2 = [vt2[0], vt2[1], vt2[2]]
return v2
# --------------------------------------------------------------------
# Get location in world space
# v1: point
# mainobject
# --------------------------------------------------------------------
def get_location(mainobject):
# Using World Matrix
m4 = mainobject.matrix_world
return [m4[0][3], m4[1][3], m4[2][3]]
# --------------------------------------------------------------------
# Get vertex data
# mainobject
# --------------------------------------------------------------------
def get_mesh_vertices(myobj):
try:
if myobj.mode == 'EDIT':
bm = from_edit_mesh(myobj.data)
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
obverts = bm.verts
else:
obverts = myobj.data.vertices
return obverts
except AttributeError:
return None
# --------------------------------------------------------------------
# Get position for scale text
#
# --------------------------------------------------------------------
def get_scale_txt_location(context):
scene = context.scene
pos_x = int(context.region.width * scene.measureit_scale_pos_x / 100)
pos_y = int(context.region.height * scene.measureit_scale_pos_y / 100)
return pos_x, pos_y
# --------------------------------------------------------------------
# Get position in final render image
# (Z < 0 out of camera)
# return 2d position
# --------------------------------------------------------------------
def get_render_location(mypoint):
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
scene = bpy.context.scene
co_2d = object_utils.world_to_camera_view(scene, scene.camera, v1)
# Get pixel coords
render_scale = scene.render.resolution_percentage / 100
render_size = (int(scene.render.resolution_x * render_scale),
int(scene.render.resolution_y * render_scale))
return [round(co_2d.x * render_size[0]), round(co_2d.y * render_size[1])]
# ---------------------------------------------------------
# Get center of circle base on 3 points
#
# Point a: (x,y,z) arc start
# Point b: (x,y,z) center
# Point c: (x,y,z) midle point in the arc
# Point d: (x,y,z) arc end
# Return:
# ang: angle (radians)
# len: len of arc
#
# ---------------------------------------------------------
def get_arc_data(pointa, pointb, pointc, pointd):
v1 = Vector((pointa[0] - pointb[0], pointa[1] - pointb[1], pointa[2] - pointb[2]))
v2 = Vector((pointc[0] - pointb[0], pointc[1] - pointb[1], pointc[2] - pointb[2]))
v3 = Vector((pointd[0] - pointb[0], pointd[1] - pointb[1], pointd[2] - pointb[2]))
angle = v1.angle(v2) + v2.angle(v3)
rclength = pi * 2 * v2.length * (angle / (pi * 2))
return angle, rclength
# -------------------------------------------------------------
# Format a number to the right unit
#
# -------------------------------------------------------------
def format_distance(fmt, units, value, factor=1):
s_code = "\u00b2" # Superscript two
hide_units = bpy.context.scene.measureit_hide_units
# ------------------------
# Units automatic
# ------------------------
if units == "1":
# Units
if bpy.context.scene.unit_settings.system == "IMPERIAL":
feet = value * (3.2808399 ** factor)
if round(feet, 2) >= 1.0:
if hide_units is False:
fmt += " ft"
if factor == 2:
fmt += s_code
tx_dist = fmt % feet
else:
inches = value * (39.3700787 ** factor)
if hide_units is False:
fmt += " in"
if factor == 2:
fmt += s_code
tx_dist = fmt % inches
elif bpy.context.scene.unit_settings.system == "METRIC":
if round(value, 2) >= 1.0:
if hide_units is False:
fmt += " m"
if factor == 2:
fmt += s_code
tx_dist = fmt % value
else:
if round(value, 2) >= 0.01:
if hide_units is False:
fmt += " cm"
if factor == 2:
fmt += s_code
d_cm = value * (100 ** factor)
tx_dist = fmt % d_cm
else:
if hide_units is False:
fmt += " mm"
if factor == 2:
fmt += s_code
d_mm = value * (1000 ** factor)
tx_dist = fmt % d_mm
else:
tx_dist = fmt % value
# ------------------------
# Units meters
# ------------------------
elif units == "2":
if hide_units is False:
fmt += " m"
if factor == 2:
fmt += s_code
tx_dist = fmt % value
# ------------------------
# Units centimeters
# ------------------------
elif units == "3":
if hide_units is False:
fmt += " cm"
if factor == 2:
fmt += s_code
d_cm = value * (100 ** factor)
tx_dist = fmt % d_cm
# ------------------------
# Units millimeters
# ------------------------
elif units == "4":
if hide_units is False:
fmt += " mm"
if factor == 2:
fmt += s_code
d_mm = value * (1000 ** factor)
tx_dist = fmt % d_mm
# ------------------------
# Units feet
# ------------------------
elif units == "5":
if hide_units is False:
fmt += " ft"
if factor == 2:
fmt += s_code
feet = value * (3.2808399 ** factor)
tx_dist = fmt % feet
# ------------------------
# Units inches
# ------------------------
elif units == "6":
if hide_units is False:
fmt += " in"
if factor == 2:
fmt += s_code
inches = value * (39.3700787 ** factor)
tx_dist = fmt % inches
# ------------------------
# Default
# ------------------------
else:
tx_dist = fmt % value
return tx_dist
# -------------------------------------------------------------
# Get radian float based on angle choice
#
# -------------------------------------------------------------
def get_angle_in_rad(fangle):
if fangle == 0:
return 0.0
else:
return radians(fangle)