We were having a lot of trouble using the measure tool in Blender — after discovering that you can hold the Ctrl key and “snap” your selection to a vertex, it actually worked in the way we wanted it to. But, before that discovery, my thought was to manually select two vertices and use a Python script to measure the distance between those points. That is “blender units” … and the metric or imperial units would be more meaningful. So I converted based on the scene configuration.
import bpy
import bmesh
def format_metric(meters: float) -> str:
a = abs(meters)
if a >= 1.0:
return f"{meters:.6f} m"
elif a >= 0.01:
return f"{meters * 100.0:.3f} cm"
else:
return f"{meters * 1000.0:.3f} mm"
def format_imperial(meters: float) -> str:
total_inches = meters / 0.0254
sign = "-" if total_inches < 0 else ""
total_inches = abs(total_inches)
feet = int(total_inches // 12)
inches = total_inches - (feet * 12)
if feet > 0:
return f"{sign}{feet} ft {inches:.3f} in"
else:
return f"{sign}{total_inches:.3f} in"
def measure_selected_vertices():
ctx = bpy.context
obj = ctx.edit_object
if obj is None or obj.type != 'MESH':
raise RuntimeError("Go into Edit Mode on a mesh and select exactly 2 vertices.")
bm = bmesh.from_edit_mesh(obj.data)
selected_verts = [v for v in bm.verts if v.select]
if len(selected_verts) != 2:
raise RuntimeError(f"Expected exactly 2 selected vertices, found {len(selected_verts)}.")
v1, v2 = selected_verts
# Convert local vertex coordinates to world-space coordinates
p1 = obj.matrix_world @ v1.co
p2 = obj.matrix_world @ v2.co
# Raw world-space distance in Blender units
raw_distance = (p2 - p1).length
scene = ctx.scene
units = scene.unit_settings
scale_length = units.scale_length if units.scale_length != 0 else 1.0
# Convert Blender units to meters according to the scene unit scale
distance_meters = raw_distance * scale_length
print("\n----- Vertex Distance -----")
print(f"Object: {obj.name}")
print(f"Raw distance (Blender units): {raw_distance:.6f}")
print(f"Scene unit system: {units.system}")
print(f"Scene unit scale: {scale_length}")
if units.system == 'METRIC':
print(f"Formatted distance: {format_metric(distance_meters)}")
elif units.system == 'IMPERIAL':
print(f"Formatted distance: {format_imperial(distance_meters)}")
else:
print("Formatted distance: Scene unit system is 'NONE'")
print(f"Interpreted using current unit scale: {format_metric(distance_meters)}")
measure_selected_vertices()