mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-30 08:19:36 +00:00
Speeding up of hull3d
This commit is contained in:
parent
703e582846
commit
6647c9e0b3
2 changed files with 29 additions and 28 deletions
49
hull.scad
49
hull.scad
|
@ -81,8 +81,8 @@ function _backtracking(i,points,h,t,m,all) =
|
|||
|
||||
// clockwise check (2d)
|
||||
function _is_cw(a,b,c,all) =
|
||||
all ? cross(a-c,b-c)<=EPSILON*norm(a-c)*norm(b-c) :
|
||||
cross(a-c,b-c)<-EPSILON*norm(a-c)*norm(b-c);
|
||||
all ? cross(a-c,b-c)<=EPSILON*norm(a-c)*norm(b-c) :
|
||||
cross(a-c,b-c)<-EPSILON*norm(a-c)*norm(b-c);
|
||||
|
||||
|
||||
// Function: hull2d_path()
|
||||
|
@ -111,7 +111,7 @@ function hull2d_path(points, all=false) =
|
|||
ip = sortidx(points) )
|
||||
// lower hull points
|
||||
let( lh =
|
||||
[ for( i = 2,
|
||||
[ for( i = 2,
|
||||
k = 2,
|
||||
h = [ip[0],ip[1]]; // current list of hull point indices
|
||||
i <= n;
|
||||
|
@ -120,7 +120,7 @@ function hull2d_path(points, all=false) =
|
|||
i = i+1
|
||||
) if( i==n ) h ][0] )
|
||||
// concat lower hull points with upper hull ones
|
||||
[ for( i = n-2,
|
||||
[ for( i = n-2,
|
||||
k = len(lh),
|
||||
t = k+1,
|
||||
h = lh; // current list of hull point indices
|
||||
|
@ -129,7 +129,7 @@ function hull2d_path(points, all=false) =
|
|||
h = [for(j=[0:1:k-2]) h[j], if(i>0) ip[i]],
|
||||
i = i-1
|
||||
) if( i==-1 ) h ][0] ;
|
||||
|
||||
|
||||
|
||||
function _hull_collinear(points) =
|
||||
let(
|
||||
|
@ -207,25 +207,33 @@ function _hull3d_iterative(points, triangles, planes, remaining, _i=0) =
|
|||
let (
|
||||
// pick a point
|
||||
i = remaining[_i],
|
||||
// evaluate the triangle plane equations at point i
|
||||
planeq_val = planes*[each points[i], -1],
|
||||
// find the triangles that are in conflict with the point (point not inside)
|
||||
conflicts = _find_conflicts(points[i], planes),
|
||||
// for all triangles that are in conflict, collect their halfedges
|
||||
conflicts = [ for (i = [0:1:len(planes)-1]) if (planeq_val[i]>0) i ],
|
||||
// collect the halfedges of all triangles that are in conflict
|
||||
halfedges = [
|
||||
for(c = conflicts, i = [0:2]) let(
|
||||
j = (i+1)%3
|
||||
) [triangles[c][i], triangles[c][j]]
|
||||
for(c = conflicts, i = [0:2])
|
||||
[triangles[c][i], triangles[c][(i+1)%3]]
|
||||
],
|
||||
// find the outer perimeter of the set of conflicting triangles
|
||||
horizon = _remove_internal_edges(halfedges),
|
||||
// generate a new triangle for each horizon halfedge together with the picked point i
|
||||
new_triangles = [ for (h = horizon) concat(h,i) ],
|
||||
// calculate the corresponding plane equations
|
||||
new_planes = [ for (t = new_triangles) plane3pt_indexed(points, t[0], t[1], t[2]) ]
|
||||
// generate new triangles connecting point i to each horizon halfedge vertices
|
||||
tri2add = [ for (h = horizon) concat(h,i) ],
|
||||
// add tria2add and remove conflict triangles
|
||||
new_triangles =
|
||||
concat( tri2add,
|
||||
[ for (i = [0:1:len(planes)-1]) if (planeq_val[i]<=0) triangles[i] ]
|
||||
),
|
||||
// add the plane equations of new added triangles and remove the plane equations of the conflict ones
|
||||
new_planes =
|
||||
concat( [ for (t = tri2add) plane3pt_indexed(points, t[0], t[1], t[2]) ],
|
||||
[ for (i = [0:1:len(planes)-1]) if (planeq_val[i]<=0) planes[i] ]
|
||||
)
|
||||
) _hull3d_iterative(
|
||||
points,
|
||||
// remove the conflicting triangles and add the new ones
|
||||
concat(list_remove(triangles, conflicts), new_triangles),
|
||||
concat(list_remove(planes, conflicts), new_planes),
|
||||
new_triangles,
|
||||
new_planes,
|
||||
remaining,
|
||||
_i+1
|
||||
);
|
||||
|
@ -238,13 +246,6 @@ function _remove_internal_edges(halfedges) = [
|
|||
];
|
||||
|
||||
|
||||
function _find_conflicts(point, planes) = [
|
||||
for (i = [0:1:len(planes)-1])
|
||||
if (in_front_of_plane(planes[i], point))
|
||||
i
|
||||
];
|
||||
|
||||
|
||||
function _find_first_noncoplanar(plane, points, i=0) =
|
||||
(i >= len(points) || !points_on_plane([points[i]],plane))? i :
|
||||
_find_first_noncoplanar(plane, points, i+1);
|
||||
|
|
|
@ -87,12 +87,12 @@ module test_hull() {
|
|||
[-4.81079, -0.967785, -10.4726], [-0.949023, 23.1441, -2.08208], [16.1256, -8.2295, -24.0113], [6.45274,
|
||||
-7.21416, 23.1409], [22.8274, 1.07038, 19.1756], [-10.6256, -10.0112, -6.12274], [6.29254, -7.81875,
|
||||
-24.4037], [22.8538, 8.78163, -6.82567], [-1.96142, 19.1728, -1.726]];
|
||||
assert_equal(hull(rand25_3d),[[21, 29, 11], [29, 21, 20], [21, 14, 20], [20, 14, 26], [15, 0, 28], [13, 29, 31], [0, 15,
|
||||
assert_equal(sort(hull(rand25_3d)),sort([[21, 29, 11], [29, 21, 20], [21, 14, 20], [20, 14, 26], [15, 0, 28], [13, 29, 31], [0, 15,
|
||||
31], [15, 9, 31], [9, 24, 31], [24, 13, 31], [28, 0, 31], [11, 29, 35], [29, 13, 35], [15,
|
||||
21, 36], [9, 15, 36], [24, 9, 36], [13, 24, 36], [15, 28, 37], [28, 26, 37], [28, 31, 39],
|
||||
[31, 29, 39], [14, 21, 42], [21, 15, 42], [26, 14, 42], [15, 37, 42], [37, 26, 42], [29, 20,
|
||||
43], [39, 29, 43], [20, 26, 43], [26, 28, 43], [21, 13, 44], [13, 36, 44], [36, 21, 44],
|
||||
[21, 11, 45], [11, 35, 45], [13, 21, 45], [35, 13, 45], [28, 39, 47], [39, 43, 47], [43, 28, 47]]);
|
||||
[21, 11, 45], [11, 35, 45], [13, 21, 45], [35, 13, 45], [28, 39, 47], [39, 43, 47], [43, 28, 47]]));
|
||||
|
||||
/* // Inconsistently treats coplanar faces: sometimes face center vertex is included in output, sometimes not
|
||||
test_cube_3d = [for(x=[1:3], y=[1:3], z=[1:3]) [x,y,z]];
|
||||
|
@ -178,12 +178,12 @@ module test_hull3d_faces() {
|
|||
[-4.81079, -0.967785, -10.4726], [-0.949023, 23.1441, -2.08208], [16.1256, -8.2295, -24.0113], [6.45274,
|
||||
-7.21416, 23.1409], [22.8274, 1.07038, 19.1756], [-10.6256, -10.0112, -6.12274], [6.29254, -7.81875,
|
||||
-24.4037], [22.8538, 8.78163, -6.82567], [-1.96142, 19.1728, -1.726]];
|
||||
assert_equal(hull(rand25_3d),[[21, 29, 11], [29, 21, 20], [21, 14, 20], [20, 14, 26], [15, 0, 28], [13, 29, 31], [0, 15,
|
||||
assert_equal(sort(hull(rand25_3d)), sort([[21, 29, 11], [29, 21, 20], [21, 14, 20], [20, 14, 26], [15, 0, 28], [13, 29, 31], [0, 15,
|
||||
31], [15, 9, 31], [9, 24, 31], [24, 13, 31], [28, 0, 31], [11, 29, 35], [29, 13, 35], [15,
|
||||
21, 36], [9, 15, 36], [24, 9, 36], [13, 24, 36], [15, 28, 37], [28, 26, 37], [28, 31, 39],
|
||||
[31, 29, 39], [14, 21, 42], [21, 15, 42], [26, 14, 42], [15, 37, 42], [37, 26, 42], [29, 20,
|
||||
43], [39, 29, 43], [20, 26, 43], [26, 28, 43], [21, 13, 44], [13, 36, 44], [36, 21, 44],
|
||||
[21, 11, 45], [11, 35, 45], [13, 21, 45], [35, 13, 45], [28, 39, 47], [39, 43, 47], [43, 28, 47]]);
|
||||
[21, 11, 45], [11, 35, 45], [13, 21, 45], [35, 13, 45], [28, 39, 47], [39, 43, 47], [43, 28, 47]]));
|
||||
}
|
||||
test_hull3d_faces();
|
||||
|
||||
|
|
Loading…
Reference in a new issue