Skip to content

Commit 18ad6f0

Browse files
committed
add function for removing duplicate faces
1 parent 61759f4 commit 18ad6f0

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

src/basic_types.jl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,53 @@ function Base.show(io::IO, x::NgonFace{N, T}) where {N, T}
8181
return print(io, name, "(", join(value.(x), ", "), ")")
8282
end
8383

84+
# two faces are the same if they match or they just cycle indices
85+
function Base.:(==)(f1::FT, f2::FT) where {N, FT <: AbstractFace{N}}
86+
_, min_i1 = findmin(f1.data)
87+
_, min_i2 = findmin(f2.data)
88+
@inbounds for i in 1:N
89+
if f1[mod1(min_i1 + i, end)] !== f2[mod1(min_i2 + i, end)]
90+
return false
91+
end
92+
end
93+
return true
94+
end
95+
function Base.hash(f::AbstractFace{N}, h::UInt) where {N}
96+
_, min_i = findmin(f.data)
97+
@inbounds for i in min_i:N
98+
h = hash(f[i], h)
99+
end
100+
@inbounds for i in 1:min_i-1
101+
h = hash(f[i], h)
102+
end
103+
return h
104+
end
105+
Base.isequal(f1::AbstractFace, f2::AbstractFace) = ==(f1, f2)
106+
107+
# Fastpaths
108+
Base.:(==)(f1::FT, f2::FT) where {FT <: AbstractFace{2}} = minmax(f1.data...) == minmax(f2.data...)
109+
Base.hash(f::AbstractFace{2}, h::UInt) = hash(minmax(f.data...), h)
110+
111+
function Base.:(==)(f1::FT, f2::FT) where {FT <: AbstractFace{3}}
112+
return (f1.data == f2.data) || (f1.data == (f2[2], f2[3], f2[1])) ||
113+
(f1.data == (f2[3], f2[1], f2[2]))
114+
end
115+
function Base.hash(f::AbstractFace{3}, h::UInt)
116+
if f[1] < f[2]
117+
if f[1] < f[3]
118+
return hash(f.data, h)
119+
else
120+
return hash((f[3], f[1], f[2]), h)
121+
end
122+
else
123+
if f[2] < f[3]
124+
return hash((f[2], f[3], f[1]), h)
125+
else
126+
return hash((f[3], f[1], f[2]), h)
127+
end
128+
end
129+
end
130+
84131
Face(::Type{<:NgonFace{N}}, ::Type{T}) where {N,T} = NgonFace{N,T}
85132
Face(F::Type{NgonFace{N,FT}}, ::Type{T}) where {FT,N,T} = F
86133

src/meshes.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,17 @@ function split_mesh(mesh::Mesh, views::Vector{UnitRange{Int}} = mesh.views)
461461
end
462462
end
463463

464+
"""
465+
remove_duplicates(faces)
466+
467+
Uses a Dict to remove duplicates from the given `faces`.
468+
"""
469+
function remove_duplicates(fs::AbstractVector{FT}) where {FT <: AbstractFace}
470+
hashmap = Dict{FT, Nothing}()
471+
foreach(k -> setindex!(hashmap, nothing, k), fs)
472+
return collect(keys(hashmap))
473+
end
474+
464475

465476
function map_coordinates(f, mesh::Mesh)
466477
result = copy(mesh)

src/primitives/rectangles.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,13 @@ function Base.to_indices(A::AbstractMatrix{T}, I::Tuple{Rect2{IT}}) where {T,IT<
308308
return ((mini[1] + 1):(mini[1] + wh[1]), (mini[2] + 1):(mini[2] + wh[2]))
309309
end
310310

311-
function minmax(p::StaticVector, vmin, vmax)
311+
function Base.minmax(p::StaticVector, vmin, vmax)
312312
any(isnan, p) && return (vmin, vmax)
313313
return min.(p, vmin), max.(p, vmax)
314314
end
315315

316316
# Annoying special case for view(Vector{Point}, Vector{Face})
317-
function minmax(tup::Tuple, vmin, vmax)
317+
function Base.minmax(tup::Tuple, vmin, vmax)
318318
for p in tup
319319
any(isnan, p) && continue
320320
vmin = min.(p, vmin)

0 commit comments

Comments
 (0)