From 3fef86fc068937e1a1807534938cb7a501de7289 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 7 Mar 2025 23:48:19 +0100 Subject: [PATCH 1/6] use default getindex when not generating Polytopes --- src/basic_types.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/basic_types.jl b/src/basic_types.jl index 996b0800..e071a9c7 100644 --- a/src/basic_types.jl +++ b/src/basic_types.jl @@ -35,10 +35,6 @@ abstract type AbstractSimplex{Dim,T} <: Polytope{Dim,T} end return Polytope(P, F)(map(i-> points[i], face.data)) end -@propagate_inbounds function Base.getindex(elements::AbstractVector, face::F) where {F <: AbstractFace} - return map(i-> elements[i], face.data) -end - @fixed_vector SimplexFace = AbstractSimplexFace const TetrahedronFace{T} = SimplexFace{4,T} From fd85e7dc364c2e729be797fdc0d792c456b4e6b1 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 21 Mar 2025 16:28:13 +0100 Subject: [PATCH 2/6] revert Polytope return type for getindex --- src/basic_types.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/basic_types.jl b/src/basic_types.jl index e071a9c7..92ecc09e 100644 --- a/src/basic_types.jl +++ b/src/basic_types.jl @@ -31,10 +31,6 @@ abstract type AbstractNgonFace{N,T} <: AbstractFace{N,T} end abstract type AbstractSimplex{Dim,T} <: Polytope{Dim,T} end -@propagate_inbounds function Base.getindex(points::AbstractVector{P}, face::F) where {P<: Point, F <: AbstractFace} - return Polytope(P, F)(map(i-> points[i], face.data)) -end - @fixed_vector SimplexFace = AbstractSimplexFace const TetrahedronFace{T} = SimplexFace{4,T} From 34f8200df79ce72954131819c6421caf839b51c6 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 21 Mar 2025 17:04:30 +0100 Subject: [PATCH 3/6] fix tests --- src/meshes.jl | 6 ++++-- test/geometrytypes.jl | 4 ++-- test/meshes.jl | 4 ++-- test/runtests.jl | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/meshes.jl b/src/meshes.jl index 28a8d005..93b7c9c6 100644 --- a/src/meshes.jl +++ b/src/meshes.jl @@ -213,8 +213,10 @@ end Calculate the signed volume of one tetrahedron. Be sure the orientation of your surface is right. """ -function volume(triangle::Triangle) - v1, v2, v3 = triangle +volume(triangle::Triangle) = volume(triangle...) +volume(ps::SVector{3, <: VecTypes}) = volume(ps...) + +function volume(v1, v2, v3) sig = sign(orthogonal_vector(v1, v2, v3) ⋅ v1) return sig * abs(v1 ⋅ (v2 × v3)) / 6 end diff --git a/test/geometrytypes.jl b/test/geometrytypes.jl index 0c06beb2..3775af00 100644 --- a/test/geometrytypes.jl +++ b/test/geometrytypes.jl @@ -298,10 +298,10 @@ end ps = rand(Point2f, 10) f = GLTriangleFace(1, 2, 3) - @test ps[f] == Triangle(ps[[1,2,3]]...) + @test ps[f] == GeometryBasics.@SVector [ps[1], ps[2], ps[3]] data = [string(i) for i in 1:10] f = QuadFace(3, 4, 7, 8) - @test data[f] == ("3", "4", "7", "8") + @test data[f] == ["3", "4", "7", "8"] @test GeometryBasics.cyclic_hash(f) != GeometryBasics.cyclic_hash(QuadFace(1,2,3,4)) @test GeometryBasics.cyclic_hash(f) == GeometryBasics.cyclic_hash(QuadFace(3,4,7,8)) diff --git a/test/meshes.jl b/test/meshes.jl index e6c0b0e8..8a561b1f 100644 --- a/test/meshes.jl +++ b/test/meshes.jl @@ -11,7 +11,7 @@ end f = [TriangleFace(1, 2, 3), QuadFace(1, 2, 3, 4)] p = Point2f[(0, 1), (1, 2), (3, 4), (4, 5)] m = Mesh(p, f) - @test collect(m) == [Triangle(p[1], p[2], p[3]), GeometryBasics.Quadrilateral(p[1], p[2], p[3], p[4])] + @test collect(m) == [GeometryBasics.SVector(p[1], p[2], p[3]), GeometryBasics.SVector(p[1], p[2], p[3], p[4])] end @testset "Heterogenous faces" begin @@ -19,7 +19,7 @@ end f = [TriangleFace(1, 2, 3), QuadFace(1, 2, 3, 4)] p = Point2f[(0, 1), (1, 2), (3, 4), (4, 5)] m = Mesh(p, f) - @test collect(m) == [Triangle(p[1], p[2], p[3]), GeometryBasics.Quadrilateral(p[1], p[2], p[3], p[4])] + @test collect(m) == [GeometryBasics.SVector(p[1], p[2], p[3]), GeometryBasics.SVector(p[1], p[2], p[3], p[4])] end @testset "Ambiguous NgonFace constructors" begin diff --git a/test/runtests.jl b/test/runtests.jl index 5fb98ded..9ecaab59 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -136,7 +136,7 @@ end points = connect([1, 2, 3, 4, 5, 6, 7, 8], Point{2}) f = connect([1, 2, 3, 4], SimplexFace{4}) mesh = Mesh(points, f) - @test collect(mesh) == [Tetrahedron(points...)] + @test collect(mesh) == [GeometryBasics.SVector(points...)] @test faces(mesh) == [TetrahedronFace{Int64}(1,2,3,4)] @test decompose(LineFace{Int64}, mesh) == LineFace{Int64}[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] @test decompose(GLTriangleFace, mesh) == GLTriangleFace[(2, 3, 4), (1, 3, 4), (1, 2, 4), (1, 2, 3)] From 4dd9e762d9f3972f1f7d8e8fca28222e450b23eb Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 21 Mar 2025 17:47:19 +0100 Subject: [PATCH 4/6] make mesh[i] return a Polytope again --- src/basic_types.jl | 7 ++++++- test/meshes.jl | 4 ++-- test/runtests.jl | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/basic_types.jl b/src/basic_types.jl index 92ecc09e..48e776d8 100644 --- a/src/basic_types.jl +++ b/src/basic_types.jl @@ -589,7 +589,12 @@ Mutating these will change the mesh. """ vertex_attributes(mesh::Mesh) = getfield(mesh, :vertex_attributes) -Base.getindex(mesh::Mesh, i::Integer) = mesh.position[mesh.faces[i]] +function Base.getindex(mesh::Mesh, i::Integer) + f = mesh.faces[i] + P = Polytope(eltype(mesh.position), typeof(f)) + return P(map(j -> mesh.position[j], f.data)) +end + Base.length(mesh::Mesh) = length(mesh.faces) function Base.:(==)(a::Mesh, b::Mesh) diff --git a/test/meshes.jl b/test/meshes.jl index 8a561b1f..e6c0b0e8 100644 --- a/test/meshes.jl +++ b/test/meshes.jl @@ -11,7 +11,7 @@ end f = [TriangleFace(1, 2, 3), QuadFace(1, 2, 3, 4)] p = Point2f[(0, 1), (1, 2), (3, 4), (4, 5)] m = Mesh(p, f) - @test collect(m) == [GeometryBasics.SVector(p[1], p[2], p[3]), GeometryBasics.SVector(p[1], p[2], p[3], p[4])] + @test collect(m) == [Triangle(p[1], p[2], p[3]), GeometryBasics.Quadrilateral(p[1], p[2], p[3], p[4])] end @testset "Heterogenous faces" begin @@ -19,7 +19,7 @@ end f = [TriangleFace(1, 2, 3), QuadFace(1, 2, 3, 4)] p = Point2f[(0, 1), (1, 2), (3, 4), (4, 5)] m = Mesh(p, f) - @test collect(m) == [GeometryBasics.SVector(p[1], p[2], p[3]), GeometryBasics.SVector(p[1], p[2], p[3], p[4])] + @test collect(m) == [Triangle(p[1], p[2], p[3]), GeometryBasics.Quadrilateral(p[1], p[2], p[3], p[4])] end @testset "Ambiguous NgonFace constructors" begin diff --git a/test/runtests.jl b/test/runtests.jl index 9ecaab59..5fb98ded 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -136,7 +136,7 @@ end points = connect([1, 2, 3, 4, 5, 6, 7, 8], Point{2}) f = connect([1, 2, 3, 4], SimplexFace{4}) mesh = Mesh(points, f) - @test collect(mesh) == [GeometryBasics.SVector(points...)] + @test collect(mesh) == [Tetrahedron(points...)] @test faces(mesh) == [TetrahedronFace{Int64}(1,2,3,4)] @test decompose(LineFace{Int64}, mesh) == LineFace{Int64}[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] @test decompose(GLTriangleFace, mesh) == GLTriangleFace[(2, 3, 4), (1, 3, 4), (1, 2, 4), (1, 2, 3)] From 29bc439c6db1354abe86a3fcd121da0764ac8ad9 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 21 Mar 2025 17:51:34 +0100 Subject: [PATCH 5/6] test Bool operations on faces --- test/geometrytypes.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/geometrytypes.jl b/test/geometrytypes.jl index 166b7cd4..51746602 100644 --- a/test/geometrytypes.jl +++ b/test/geometrytypes.jl @@ -299,10 +299,15 @@ end ps = rand(Point2f, 10) f = GLTriangleFace(1, 2, 3) @test ps[f] == GeometryBasics.@SVector [ps[1], ps[2], ps[3]] + data = [string(i) for i in 1:10] f = QuadFace(3, 4, 7, 8) @test data[f] == ["3", "4", "7", "8"] + @test (f .== 4) == QuadFace(false, true, false, false) + @test f[f .== 4] isa Vector{Int} + @test f[f .== 4] == [4] + @test GeometryBasics.cyclic_hash(f) != GeometryBasics.cyclic_hash(QuadFace(1,2,3,4)) @test GeometryBasics.cyclic_hash(f) == GeometryBasics.cyclic_hash(QuadFace(3,4,7,8)) # cyclic permutation does not change the face From c1990320b0b065d4a4776d1b966395ce06a4b1a3 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 21 Mar 2025 17:55:48 +0100 Subject: [PATCH 6/6] revert changes to volume --- src/meshes.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/meshes.jl b/src/meshes.jl index 917b6b2f..8a106971 100644 --- a/src/meshes.jl +++ b/src/meshes.jl @@ -213,11 +213,9 @@ end Calculate the signed volume of one tetrahedron. Be sure the orientation of your surface is right. """ -volume(triangle::Triangle) = volume(triangle...) -volume(ps::SVector{3, <: VecTypes}) = volume(ps...) - -function volume(v1, v2, v3) - sig = sign(orthogonal_vector((v1, v2, v3)) ⋅ v1) +function volume(triangle::Triangle{3, T}) where {T} + v1, v2, v3 = triangle + sig = sign(orthogonal_vector(Vec3{T}, triangle) ⋅ v1) return sig * abs(v1 ⋅ (v2 × v3)) / 6 end