Skip to content

Instantly share code, notes, and snippets.

@zeffii
Last active December 17, 2015 01:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeffii/5526816 to your computer and use it in GitHub Desktop.
Save zeffii/5526816 to your computer and use it in GitHub Desktop.
find real intersections
import itertools
import bpy
import bmesh
from mathutils import Vector
obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)
selected_edges = [edge for edge in bm.edges if edge.select]
count_edges = len(selected_edges)
# edge_indices might look like [1,2,10,11]
edge_indices = [i.index for i in selected_edges]
# get all permulations
raw_permutations = itertools.permutations(edge_indices, 2)
# remove duplicates from the raw_permutations (1,3 <==> 3,1)
permutations = [result for result in raw_permutations if result[0] < result[1]]
# print(permutations)
# result : [(1, 2), (1, 10), (1, 11), (2, 10), (2, 11), (10, 11)]
def get_v4_from_edge_combo(edge):
edge_index_1 = edge[0]
edge_index_2 = edge[1]
v_idx_1 = bm.edges[edge_index_1].verts[0].index
v_idx_2 = bm.edges[edge_index_1].verts[1].index
v_idx_3 = bm.edges[edge_index_2].verts[0].index
v_idx_4 = bm.edges[edge_index_2].verts[1].index
return v_idx_1, v_idx_2, v_idx_3, v_idx_4
print("---")
final_permutations = []
for edge in permutations:
# this displays the vertex indices of the verts on the two edges
raw_vert_indices = get_v4_from_edge_combo(edge)
print(edge, ' -> ', raw_vert_indices)
# if we do a set() on this collection, and the size of the set becomes
# smaller then we know there is a duplicate and can disgard this edge combo.
if len(set(raw_vert_indices)) < len(raw_vert_indices):
continue
final_permutations.append(edge)
print('\n>', final_permutations)
from mathutils.geometry import intersect_line_line as LineIntersect
VTX_PRECISION = 1.0e-5 # or 1.0e-6 ..if you need Epsilon.
def vector_from_indices(raw_vert_indices):
return [bm.verts[i].co for i in raw_vert_indices]
intersecting_permutations = []
for edge in final_permutations:
raw_vert_indices = get_v4_from_edge_combo(edge)
vert_vectors = vector_from_indices(raw_vert_indices)
# Returns a tuple with the points on each line respectively closest to the other.
closest_points = LineIntersect(*vert_vectors)
# closest_points may be
# (Vector((nan, nan, nan)), Vector((nan, nan, nan))) or None
# Whatever the reason (parallel, not coplanar), this response
# is used to drop combinations from the permutations list
if not closest_points: continue
if not closest_points[0].x: continue
# only valid vector tuples should reach this point.
distance = (closest_points[0] - closest_points[1]).length
# the edges intersect if the distance is lower than (epsilon precision)
if distance < VTX_PRECISION:
intersecting_permutations.append((edge, closest_points))
print(intersecting_permutations)
num_intersections = len(intersecting_permutations)
print('number of intersections: {}'.format(num_intersections))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment