Deduplicate face vertices before triangulation.

This commit is contained in:
Revar Desmera 2020-03-24 13:33:38 -07:00
parent 07d47f4ffc
commit b0ebc77aba
2 changed files with 40 additions and 39 deletions

View file

@ -129,46 +129,47 @@ function is_only_noncolinear_vertex(points, facelist, vertex) =
// points = Array of vertices for the polyhedron. // points = Array of vertices for the polyhedron.
// face = The face, given as a list of indices into the vertex array `points`. // face = The face, given as a list of indices into the vertex array `points`.
function triangulate_face(points, face) = function triangulate_face(points, face) =
let(count=len(face)) let(
(3==count)? face = deduplicate(face),
[face] count = len(face)
: )
let( (count < 3)? [] :
facenorm=face_normal(points, face), (count == 3)? [face] :
cv=find_convex_vertex(points, face, facenorm), let(
pv=(count+cv-1)%count, facenorm=face_normal(points, face),
nv=(cv+1)%count, cv=find_convex_vertex(points, face, facenorm),
p0=points[face[pv]], pv=(count+cv-1)%count,
p1=points[face[cv]], nv=(cv+1)%count,
p2=points[face[nv]], p0=points[face[pv]],
tests=[ p1=points[face[cv]],
[cross(facenorm, p0-p2), cross(facenorm, p0-p2)*p0], p2=points[face[nv]],
[cross(facenorm, p1-p0), cross(facenorm, p1-p0)*p1], tests=[
[cross(facenorm, p2-p1), cross(facenorm, p2-p1)*p2] [cross(facenorm, p0-p2), cross(facenorm, p0-p2)*p0],
], [cross(facenorm, p1-p0), cross(facenorm, p1-p0)*p1],
ear_test=point_in_ear(points, face, tests), [cross(facenorm, p2-p1), cross(facenorm, p2-p1)*p2]
clipable_ear=(ear_test[0]<0), ],
diagonal_point=ear_test[1] ear_test=point_in_ear(points, face, tests),
) clipable_ear=(ear_test[0]<0),
(clipable_ear)? // There is no point inside the ear. diagonal_point=ear_test[1]
is_only_noncolinear_vertex(points, face, cv)? )
// In the point&line degeneracy clip to somewhere in the middle of the line. (clipable_ear)? // There is no point inside the ear.
flatten([ is_only_noncolinear_vertex(points, face, cv)?
triangulate_face(points, select(face, cv, (cv+2)%count)), // In the point&line degeneracy clip to somewhere in the middle of the line.
triangulate_face(points, select(face, (cv+2)%count, cv))
])
:
// Otherwise the ear is safe to clip.
flatten([
[select(face, pv, nv)],
triangulate_face(points, select(face, nv, pv))
])
: // If there is a point inside the ear, make a diagonal and clip along that.
flatten([ flatten([
triangulate_face(points, select(face, cv, diagonal_point)), triangulate_face(points, select(face, cv, (cv+2)%count)),
triangulate_face(points, select(face, diagonal_point, cv)) triangulate_face(points, select(face, (cv+2)%count, cv))
]) ])
; :
// Otherwise the ear is safe to clip.
flatten([
[select(face, pv, nv)],
triangulate_face(points, select(face, nv, pv))
])
: // If there is a point inside the ear, make a diagonal and clip along that.
flatten([
triangulate_face(points, select(face, cv, diagonal_point)),
triangulate_face(points, select(face, diagonal_point, cv))
]);
// Function: triangulate_faces() // Function: triangulate_faces()

View file

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