Skip to content

Instantly share code, notes, and snippets.

@zeffii
Created January 13, 2019 21:16
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/f63d8f34592c3c8d10d89d2ea4ebb637 to your computer and use it in GitHub Desktop.
Save zeffii/f63d8f34592c3c8d10d89d2ea4ebb637 to your computer and use it in GitHub Desktop.
sockets = """
in points v
in edges s
out new_verts v
"""
cdef = """
int intersectAll(float vertices[][3], int lines[][2], float new_verts[][3]);
"""
import bpy
code = bpy.data.texts['xall.c'].as_string()
sources = [ "mathlib.c" ]
def setup():
import os, bpy
from pathlib import Path
root = Path(bpy.data.filepath).parent
py = Path(bpy.app.binary_path).parent / "2.80" / "python" / "include";
build = Path(root) / "build";
srcroot = Path(root) / "mathlib"
incroot = Path(root) / "mathlib"
srcs = str(srcroot)
incs = [str(incroot)]
libs = []
lib_dirs = []
comp = []
link = []
lang = 'c'
return str(py), str(build), srcs, incs, libs, lib_dirs, comp, link, lang
def execute(lib, ffi, node):
points = node.inputs["points"].sv_get(default=[[]])[0]
edges = node.inputs["edges"].sv_get(default=[[]])[0]
new_verts = xall(lib, ffi, points, edges)
if new_verts:
node.outputs["new_verts"].sv_set(new_verts)
def xall(lib, ffi, points, edges):
if not points and edges:
return [[]]
n = len(edges)
max_num = int(((n*n) - n) / 2)
new_verts = ffi.new("float[][3]", max_num)
cpoints = ffi.new("float[][3]", len(points))
cedges = ffi.new("int[][2]", len(edges))
for i, p in enumerate(points):
cpoints[i] = p
for i, e in enumerate(edges):
cedges[i] = e
num_new_verts = lib.intersectAll(cpoints, cedges, new_verts)
verts = []
for i in range(n, max_num):
v = new_verts[i]
verts.append((v[0], v[1], v[2]))
return [verts]
// # xall.c
#include "mathlib.h"
int intersectAll(float vertices[][3], int lines[][2], float new_verts[][3]){
float lambda;
int isect_result;
int count = sizeof(lines) / sizeof(lines[0]);
const float epsilon = 0.0001f;
float v1[3], v2[3], v3[3], v4[3], r_i1[3], r_i2[3]; // #, i2[3], i1[3];
int intersections = 0;
for (int i = 0; i <= count; i++) {
for (int j = 0; j <= count; j++) {
// # skip identical indices and 1 half of 2d matrix by ignoring duplicate comparrisons
if (j <= i){ continue; }
// # skip duplicate indices, assume a line is never two identical indices
// # by definition these indices result in edges touching at those verts
// if (lines[i][0] == lines[j][0] || lines[i][0] == lines[j][1]) { continue; }
// if (lines[i][1] == lines[j][0] || lines[i][1] == lines[j][1]) { continue; }
copy_v3_v3(v1, vertices[lines[i][0]]);
copy_v3_v3(v2, vertices[lines[i][1]]);
copy_v3_v3(v3, vertices[lines[j][0]]);
copy_v3_v3(v4, vertices[lines[j][1]]);
isect_result = isect_line_line_epsilon_v3(v1, v2, v3, v4, r_i1, r_i2, epsilon);
if (isect_result == 0) { continue; }
else if (isect_result == 1)
{
// # handle intersection possible on one edge
// # find closest point to p on line through (l1, l2) and return lambda,
// # where (0 <= lambda <= 1) when cp is in the line segment (l1, l2)
//
// # lambda = closest_to_line_v3(rclose, p, l1, l2)
// # lambda = closest_to_line_v3(r_i2, r_i1, v3, v4);
// # explanation time: :)
// # if lambda is between (and including) 0 and 1, then the intersection occurs
// # on v3, v4 at point p.
// # if however lambda is less than 0 or more than 1, then the intersection occurs
// # on v1, v2 at point p
// # if (0 <= lambda && lambda <= 1)
// # intersection (p) is on v3, v4
// # else { intersection (p) is on v1, v2 }
copy_v3_v3(new_verts[intersections], r_i1);
}
else if (isect_result == 2)
{
// # handle intersection on both edges possibly
copy_v3_v3(new_verts[intersections], r_i1);
copy_v3_v3(new_verts[intersections+1], r_i1);
}
intersections += isect_result;
}
}
printf("%d\n", intersections);
return intersections;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment