Utility_Apps/Blender/simple scripts/Select objects with an edge angle within a certain range/Select objects with an edge angle within a certain range.py
Ryan Schultz 74caa7d1da Add Blender script to filter mesh objects by edge angle
Implements selection tool that identifies mesh objects where ALL edges
are oriented at specific angles (40-60° or 120-140°) relative to the
X axis. Designed for filtering diagonal line segments at approximately
±45 degrees, particularly useful for processing imported SVG paths or
similar geometric data.
2026-01-26 17:02:51 -06:00

78 lines
No EOL
2.3 KiB
Python

import bpy
import bmesh
import math
from mathutils import Vector
def all_edges_in_angle_range(obj, ranges=[(40, 60), (120, 140)]):
"""
Check if ALL edges in a mesh object have angles to the X axis
within any of the specified ranges.
Returns True only if ALL edges satisfy the condition.
"""
bm = bmesh.new()
bm.from_mesh(obj.data)
bm.edges.ensure_lookup_table()
if len(bm.edges) == 0:
bm.free()
return False
x_axis = Vector((1, 0, 0))
for edge in bm.edges:
v1, v2 = edge.verts
# Get world space coordinates
v1_world = obj.matrix_world @ v1.co
v2_world = obj.matrix_world @ v2.co
# Calculate direction vector
direction = v2_world - v1_world
if direction.length > 0:
direction.normalize()
# Calculate angle from X axis
angle_rad = direction.angle(x_axis)
angle_deg = math.degrees(angle_rad)
# Check if this edge is in any of the valid ranges
edge_in_range = False
for min_angle, max_angle in ranges:
if min_angle <= angle_deg <= max_angle:
edge_in_range = True
break
# If this edge is NOT in any range, return False immediately
if not edge_in_range:
bm.free()
return False
# If we got here, all edges are in valid ranges
bm.free()
return True
def select_edges_by_angle():
"""
Select all mesh objects where ALL edges are angled 40-60° or 120-140° from X axis.
"""
# Deselect all objects first
bpy.ops.object.select_all(action='DESELECT')
selected_count = 0
# Check for both +45° (40-60°) and -45° (120-140°) ranges
angle_ranges = [(40, 60), (120, 140)]
# Iterate through all objects in the scene
for obj in bpy.context.scene.objects:
if obj.type == 'MESH':
if all_edges_in_angle_range(obj, ranges=angle_ranges):
obj.select_set(True)
selected_count += 1
print(f"Selected: {obj.name}")
print(f"\nTotal objects selected: {selected_count}")
# Run the script
select_edges_by_angle()