diff --git a/arrays.scad b/arrays.scad index af6bd65..1cb0947 100644 --- a/arrays.scad +++ b/arrays.scad @@ -276,6 +276,40 @@ function deduplicate(list, closed=false, eps=EPSILON) = [for (i=[0:1:l-1]) if (i==end || list[i] != list[(i+1)%l]) list[i]]; +// Function: deduplicate_indexed() +// Usage: +// new_idxs = deduplicate_indexed(list, indices, [closed], [eps]); +// Description: +// Given a list, and indices into it, removes consecutive indices that +// index to the same values in the list. +// Arguments: +// list = The list that the indices index into. +// indices = The list of indices to deduplicate. +// closed = If true, drops trailing indices if what they index matches what the first index indexes. +// eps = The maximum difference to allow between numbers or vectors. +// Examples: +// deduplicate_indexed([8,6,4,6,3], [1,4,3,1,2,2,0,1]); // Returns: [1,4,3,2,0,1] +// deduplicate_indexed([8,6,4,6,3], [1,4,3,1,2,2,0,1], closed=true); // Returns: [1,4,3,2,0] +function deduplicate_indexed(list, indices, closed=false, eps=EPSILON) = + assert(is_list(list)||is_string(list)) + assert(indices==[] || is_vector(indices)) + indices==[]? [] : + let( + l = len(indices), + end = l-(closed?0:1) + ) [ + for (i = [0:1:l-1]) let( + a = list[indices[i]], + b = list[indices[(i+1)%l]], + eq = (a == b)? true : + (a*0 != b*0)? false : + is_num(a)? approx(a, b, eps=eps) : + is_vector(a)? approx(a, b, eps=eps) : + false + ) if (i==end || !eq) indices[i] + ]; + + // Function: repeat_entries() // Usage: // newlist = repeat_entries(list, N) diff --git a/tests/test_arrays.scad b/tests/test_arrays.scad index 68009fc..b066049 100644 --- a/tests/test_arrays.scad +++ b/tests/test_arrays.scad @@ -90,6 +90,13 @@ module test_deduplicate() { test_deduplicate(); +module test_deduplicate_indexed() { + assert(deduplicate_indexed([8,6,4,6,3], [1,4,3,1,2,2,0,1]) == [1,4,1,2,0,1]); + assert(deduplicate_indexed([8,6,4,6,3], [1,4,3,1,2,2,0,1], closed=true) == [1,4,1,2,0]); +} +test_deduplicate_indexed(); + + module test_list_set() { assert(list_set([2,3,4,5], 2, 21) == [2,3,21,5]); assert(list_set([2,3,4,5], [1,3], [81,47]) == [2,81,4,47]); diff --git a/triangulation.scad b/triangulation.scad index 3de4617..efa2eff 100644 --- a/triangulation.scad +++ b/triangulation.scad @@ -130,7 +130,7 @@ function is_only_noncolinear_vertex(points, facelist, vertex) = // face = The face, given as a list of indices into the vertex array `points`. function triangulate_face(points, face) = let( - face = deduplicate(face), + face = deduplicate_indexed(points,face), count = len(face) ) (count < 3)? [] : diff --git a/version.scad b/version.scad index b400bc6..5bb7003 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,221]; +BOSL_VERSION = [2,0,222]; // Section: BOSL Library Version Functions