Added deduplicate_indexed()

This commit is contained in:
Revar Desmera 2020-03-24 14:51:37 -07:00
parent b0ebc77aba
commit 6183e6d0d2
4 changed files with 43 additions and 2 deletions

View file

@ -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)

View file

@ -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]);

View file

@ -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)? [] :

View file

@ -8,7 +8,7 @@
//////////////////////////////////////////////////////////////////////
BOSL_VERSION = [2,0,221];
BOSL_VERSION = [2,0,222];
// Section: BOSL Library Version Functions