Last active
December 17, 2015 01:10
-
-
Save zeffii/5526816 to your computer and use it in GitHub Desktop.
find real intersections
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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