From c14313da89983796e136ec4a1ae1af195ebadec2 Mon Sep 17 00:00:00 2001 From: bboeyken Date: Mon, 2 Feb 2026 20:34:47 +0100 Subject: [PATCH 1/7] positive volume in 2D simplex --- src/charts.jl | 2 +- test/test_patches.jl | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/charts.jl b/src/charts.jl index b74ead2..beb761d 100644 --- a/src/charts.jl +++ b/src/charts.jl @@ -217,7 +217,7 @@ function _normals(tangents::SVector{2,SVector{2,T}}, ::Type{Val{0}}) where {T} t = tangents[1] s = tangents[2] - v = (t[1]*s[2] - t[2]*s[1])/2 + v = abs(t[1]*s[2] - t[2]*s[1])/2 # n[3] = tangents[1] × tangents[2] # l = norm(n) diff --git a/test/test_patches.jl b/test/test_patches.jl index 87ede45..e91f45f 100644 --- a/test/test_patches.jl +++ b/test/test_patches.jl @@ -1,6 +1,7 @@ using Test using CompScienceMeshes +# universe dimension 3 for T in [Float32, Float64] local mesh = meshrectangle(T(1.0), T(1.0), T(1.0)) local faces = skeleton(mesh, 2) @@ -18,3 +19,21 @@ for T in [Float32, Float64] point(T, 0.0, 0.0, -1.0)] @test p.volume == T(0.5) end + +# universe dimension 2 +for T in [Float32, Float64] + local mesh = meshrectangle(T(1.0), T(1.0), T(1.0),2) + local faces = skeleton(mesh, 2) + local verts = vertices(mesh, faces.faces[1]) + p = simplex(verts) + + @test p.vertices == [ + point(T, 0.0, 0.0), + point(T, 0.0, 1.0), + point(T, 1.0, 0.0)] + @test p.tangents == [ + point(T, -1.0, 0.0), + point(T, -1.0, 1.0)] + @test p.normals == [] + @test p.volume == T(0.5) +end From 59cbe7c34ba6442d7e990861f8eb06f250baad8e Mon Sep 17 00:00:00 2001 From: bboeyken Date: Mon, 2 Feb 2026 20:40:31 +0100 Subject: [PATCH 2/7] overlap for 2D simpleces --- src/overlap.jl | 31 ++++++++++++++++++++++++++++ test/test_overlap2D.jl | 47 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 test/test_overlap2D.jl diff --git a/src/overlap.jl b/src/overlap.jl index bef6432..193e165 100644 --- a/src/overlap.jl +++ b/src/overlap.jl @@ -106,3 +106,34 @@ function overlap(p::Simplex{3,3,0,4,T}, q::Simplex{3,3,0,4,T}) where T all(0+tol .<= u .<= 1-tol) && return true return false end + + +function overlap(p::Simplex{2,2,0,3,T}, q::Simplex{2,2,0,3,T}) where T + + # tol = sqrt(eps(T)) + tol = 1e3 * eps(T) + + # Are the patches in the same plane? + u1 = q.tangents[1] + u2 = q.tangents[2] + v = p.vertices[1] - q.vertices[2] + + for i in 1:3 + a = p.vertices[mod1(i+1,3)] + b = p.vertices[mod1(i+2,3)] + c = p.vertices[i] + t = b - a + m = StaticArrays.SVector{2,T}(t[2],-t[1]) + + sp = zeros(T,3); sp[i] = dot(c-a, m) + sq = T[dot(q.vertices[j]-a, m) for j in 1:3] + + minp, maxp = extrema(sp) + minq, maxq = extrema(sq) + + maxq <= minp + tol && return false + maxp <= minq + tol && return false + end + + return true +end \ No newline at end of file diff --git a/test/test_overlap2D.jl b/test/test_overlap2D.jl new file mode 100644 index 0000000..b1e96db --- /dev/null +++ b/test/test_overlap2D.jl @@ -0,0 +1,47 @@ +using Test +using CompScienceMeshes +using StaticArrays + +p = simplex( + point(0,0), + point(1,0), + point(0,1)) + +q1 = simplex( + point(0.6, 0.6), + point(1.6, 0.6), + point(0.6, 1.6), +) + +q2 = simplex( + point(0.4, 0.4), + point(1.4, 0.4), + point(0.4, 1.4), +) +overlap(p, q1) + +@test overlap(p, q1) == false +@test overlap(p, q2) == true + + +## make sure the submesh function work for 1D meshes + + +l1 = meshsegment(1.0,1/2) +vt = skeleton(l1,0) +bd = boundary(l1) + +overlaps = overlap_gpredicate(bd) +pred1 = c -> overlaps(simplex(vertices(vt,c))) +@test pred1(SVector(1)) +@test !pred1(SVector(2)) +@test pred1(SVector(3)) + + +# test a case where the segments are: +# not of unit length +# colinear and opposite +# meet in a common point +ch1 = simplex(point(1/3,0), point(1/3,1/3)) +ch2 = simplex(point(1/3,1/3), point(1/3,2/3)) +@test !overlap(ch1, ch2) \ No newline at end of file From e9916566de61077fd8c41036784da885583065d3 Mon Sep 17 00:00:00 2001 From: bboeyken Date: Tue, 3 Feb 2026 18:02:51 +0100 Subject: [PATCH 3/7] permutate vertices of mesh Allows to permutate the vertices of a mesh while keeping the faces the same. --- src/CompScienceMeshes.jl | 2 + src/permutatie_mesh.jl | 112 ++++++++++++++++++++++++++++++++++++ test/runtests.jl | 2 + test/test_permutate_mesh.jl | 72 +++++++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 src/permutatie_mesh.jl create mode 100644 test/test_permutate_mesh.jl diff --git a/src/CompScienceMeshes.jl b/src/CompScienceMeshes.jl index 817372a..5439299 100644 --- a/src/CompScienceMeshes.jl +++ b/src/CompScienceMeshes.jl @@ -38,6 +38,7 @@ export connectivity, cellpairs # marked for deprecation export translate, translate!, rotate, rotate! export fliporientation!, fliporientation export weld, union +export permutate_mesh # mesh refinement export barycentric_refinement, bisecting_refinement @@ -142,6 +143,7 @@ include("primitives/primitives.jl") include("baryref.jl") include("subdivision.jl") include("weld.jl") +include("permutatie_mesh.jl") include("mapper.jl") include("restrict.jl") diff --git a/src/permutatie_mesh.jl b/src/permutatie_mesh.jl new file mode 100644 index 0000000..962243e --- /dev/null +++ b/src/permutatie_mesh.jl @@ -0,0 +1,112 @@ +""" +permutate_mesh permutate the vertices of a mesh, while keeping the same cells. + +Permutation is represented as a Vector v which sets the v[i]-th vertex at the i-th place. + +mesh can be permutated from: +- Vector or SVector +- Permutations.Permutation +- another mesh with same universedimension +- another mesh with different universedimension, only works for combination of udims 2,3. + +In the last two, control that the other mesh is a submesh of the starting mesh. In either direct + + +""" + +function permutate_mesh(mesh::Mesh, σ::Union{Vector{<:Integer}, StaticArrays.SVector{Int32, <:Integer}}) + @assert numvertices(mesh) == length(σ) + permutate_mesh(mesh, Permutations.Permutation(σ)) +end + +function permutate_mesh(mesh::Mesh, σ::Permutations.Permutation) + mesh.vertices = mesh.vertices[σ.data] + for (i, a) in enumerate(mesh.faces) + mesh.faces[i] = σ'.data[a] + end +end + +function permutate_mesh(X::Mesh{U,D1}, Y::Mesh{U,D2}) where {U,D1,D2} + tol = sqrt(eps(coordtype(X))) + permut = Vector{Int32}() + temp = collect(1:numvertices(X)) + for p in Y.vertices + index = findfirst(isapprox(p;atol = tol), X.vertices) + @assert !isnothing(index) + + temp[index] = 0 + append!(permut, index) + end + + for i in temp + if i !=0 + push!(permut, i) + end end + permutate_mesh(X, Permutations.Permutation(permut)) + X +end + +function permutate_mesh(X::Mesh{2,D1}, Y::Mesh{3,D2}) where { D1, D2} + tol = sqrt(eps(coordtype(X))) + + # assert that the z-coordinate for the vertices in X is constant. + + permut = Vector{Int32}() + temp = collect(1:numvertices(X)) + + for p in Y.vertices + q = zeros(eltype(X.vertices[begin]), 2) + q[begin] = p[begin] + q[2] = p[2] + + + index = findfirst(isapprox(q;atol = tol), X.vertices) + @assert !isnothing(index) # vertex from Y exist in X + @assert temp[index] != 0 # vertex from Y unique in X + + temp[index] = 0 + append!(permut, index) + end + + for i in temp + if i !=0 + push!(permut, i) + end end + + permutate_mesh(X, Permutations.Permutation(permut)) + X +end + +function permutate_mesh(X::Mesh{3,D1}, Y::Mesh{2,D2}) where {D1, D2} + tol = sqrt(eps(coordtype(X))) + + # assert that the z-coordinate for the vertices in X is constant. + for v in X.vertices + @assert v[3] == X.vertices[1][3] + end + + permut = Vector{Int32}() + temp = collect(1:numvertices(X)) + + for p in Y.vertices + q = zeros(eltype(X.vertices[begin]), 3) + q[begin] = p[begin] + q[2] = p[2] + q[3] = X.vertices[1][3] + + index = findfirst(isapprox(q;atol = tol), X.vertices) + @assert !isnothing(index) # vertex from Y exist in X + @assert temp[index] != 0 # vertex from Y unique in X + + temp[index] = 0 + append!(permut, index) + end + + for i in temp + if i !=0 + push!(permut, i) + end end + + permutate_mesh(X, Permutations.Permutation(permut)) + X +end diff --git a/test/runtests.jl b/test/runtests.jl index f279d15..ff0c0c9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -32,12 +32,14 @@ include("test_geometry.jl") include("test_patches.jl") include("test_submesh.jl") include("test_overlap.jl") +include("test_overlap2D.jl") include("test_intersect.jl") include("test_sh_intersection.jl") include("test_isinside.jl") include("test_jctweld.jl") include("test_isinclosure.jl") include("test_permute_vertices.jl") +include("test_permutate_mesh.jl") include("test_trgauss.jl") include("test_trdunavant.jl") diff --git a/test/test_permutate_mesh.jl b/test/test_permutate_mesh.jl new file mode 100644 index 0000000..a6d8df6 --- /dev/null +++ b/test/test_permutate_mesh.jl @@ -0,0 +1,72 @@ +using Test +using CompScienceMeshes +import Permutations + +# check if permutated mesh has the same vertices and that the faces are the same. +function check_mesh(X, X_check) + # test same vertices + @test numvertices(X) == numvertices(X_check) + @test Set(X.vertices) == Set(X_check.vertices) + + # test that each face has the same points in identical order + @test numcells(X) == numcells(X_check) + for i in 1:numcells(X) + @test X.vertices[X.faces[i]] == X_check.vertices[X_check.faces[i]] + end +end + +# same universe dimension +for u in 2:3 + local X = meshrectangle(1.0, 1.0, 0.5, u) + local X_check = meshrectangle(1.0, 1.0, 0.5, u) + local Y = meshrectangle(0.5, 0.5, 0.5, u) + + local σ = Permutations.Permutation(reverse(collect(1:numvertices(X)))) + + permutate_mesh(X,σ.data) + check_mesh(X, X_check) + + permutate_mesh(X, σ') + @test X.vertices == X_check.vertices + @test X.faces == X_check.faces + + permutate_mesh(X, Y) + check_mesh(X, X_check) + + @test X.vertices[begin: begin+numvertices(Y)-1] == Y.vertices +end + + + +# different universe dimension +let + local X = meshrectangle(1.0, 1.0, 0.5, 2) + local X_check = meshrectangle(1.0, 1.0, 0.5, 2) + local Y = meshrectangle(0.5, 0.5, 0.5, 3) + + permutate_mesh(X, Y) + check_mesh(X, X_check) + @test X.vertices[begin: begin+numvertices(Y)-1] == map(x->x[1:2], Y.vertices) + + + permutate_mesh(X, X_check) + + translate!(Y, point(0,0,1)) + permutate_mesh(X, Y) + check_mesh(X, X_check) + @test X.vertices[begin: begin+numvertices(Y)-1] == map(x->x[1:2], Y.vertices) +end + +let + local X = meshrectangle(1.0, 1.0, 0.5, 3) + local X_check = meshrectangle(1.0, 1.0, 0.5, 3) + local Y = meshrectangle(0.5, 0.5, 0.5, 2) + translate!(X, point(0,0,1)) + translate!(X_check, point(0,0,1)) + + permutate_mesh(X, Y) + check_mesh(X, X_check) + + @test map(x->x[1:2], X.vertices[begin: begin+numvertices(Y)-1]) == Y.vertices + +end \ No newline at end of file From d0546b24538c2d167fde40a82ccb051b214a480f Mon Sep 17 00:00:00 2001 From: bboeyken Date: Thu, 19 Feb 2026 10:09:00 +0100 Subject: [PATCH 4/7] change name for permutate_mesh to general permutate --- src/CompScienceMeshes.jl | 2 +- src/permutatie_mesh.jl | 14 +++++++------- test/test_permutate_mesh.jl | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/CompScienceMeshes.jl b/src/CompScienceMeshes.jl index 5439299..deea6f7 100644 --- a/src/CompScienceMeshes.jl +++ b/src/CompScienceMeshes.jl @@ -38,7 +38,7 @@ export connectivity, cellpairs # marked for deprecation export translate, translate!, rotate, rotate! export fliporientation!, fliporientation export weld, union -export permutate_mesh +export permutate # mesh refinement export barycentric_refinement, bisecting_refinement diff --git a/src/permutatie_mesh.jl b/src/permutatie_mesh.jl index 962243e..a5f2727 100644 --- a/src/permutatie_mesh.jl +++ b/src/permutatie_mesh.jl @@ -14,19 +14,19 @@ In the last two, control that the other mesh is a submesh of the starting mesh. """ -function permutate_mesh(mesh::Mesh, σ::Union{Vector{<:Integer}, StaticArrays.SVector{Int32, <:Integer}}) +function permutate(mesh::Mesh, σ::Union{Vector{<:Integer}, StaticArrays.SVector{Int32, <:Integer}}) @assert numvertices(mesh) == length(σ) - permutate_mesh(mesh, Permutations.Permutation(σ)) + permutate(mesh, Permutations.Permutation(σ)) end -function permutate_mesh(mesh::Mesh, σ::Permutations.Permutation) +function permutate(mesh::Mesh, σ::Permutations.Permutation) mesh.vertices = mesh.vertices[σ.data] for (i, a) in enumerate(mesh.faces) mesh.faces[i] = σ'.data[a] end end -function permutate_mesh(X::Mesh{U,D1}, Y::Mesh{U,D2}) where {U,D1,D2} +function permutate(X::Mesh{U,D1}, Y::Mesh{U,D2}) where {U,D1,D2} tol = sqrt(eps(coordtype(X))) permut = Vector{Int32}() temp = collect(1:numvertices(X)) @@ -42,7 +42,7 @@ function permutate_mesh(X::Mesh{U,D1}, Y::Mesh{U,D2}) where {U,D1,D2} if i !=0 push!(permut, i) end end - permutate_mesh(X, Permutations.Permutation(permut)) + permutate(X, Permutations.Permutation(permut)) X end @@ -73,11 +73,11 @@ function permutate_mesh(X::Mesh{2,D1}, Y::Mesh{3,D2}) where { D1, D2} push!(permut, i) end end - permutate_mesh(X, Permutations.Permutation(permut)) + permutate(X, Permutations.Permutation(permut)) X end -function permutate_mesh(X::Mesh{3,D1}, Y::Mesh{2,D2}) where {D1, D2} +function permutate(X::Mesh{3,D1}, Y::Mesh{2,D2}) where {D1, D2} tol = sqrt(eps(coordtype(X))) # assert that the z-coordinate for the vertices in X is constant. diff --git a/test/test_permutate_mesh.jl b/test/test_permutate_mesh.jl index a6d8df6..abe895f 100644 --- a/test/test_permutate_mesh.jl +++ b/test/test_permutate_mesh.jl @@ -23,14 +23,14 @@ for u in 2:3 local σ = Permutations.Permutation(reverse(collect(1:numvertices(X)))) - permutate_mesh(X,σ.data) + permutate(X,σ.data) check_mesh(X, X_check) - permutate_mesh(X, σ') + permutate(X, σ') @test X.vertices == X_check.vertices @test X.faces == X_check.faces - permutate_mesh(X, Y) + permutate(X, Y) check_mesh(X, X_check) @test X.vertices[begin: begin+numvertices(Y)-1] == Y.vertices @@ -44,15 +44,15 @@ let local X_check = meshrectangle(1.0, 1.0, 0.5, 2) local Y = meshrectangle(0.5, 0.5, 0.5, 3) - permutate_mesh(X, Y) + permutate(X, Y) check_mesh(X, X_check) @test X.vertices[begin: begin+numvertices(Y)-1] == map(x->x[1:2], Y.vertices) - permutate_mesh(X, X_check) + permutate(X, X_check) translate!(Y, point(0,0,1)) - permutate_mesh(X, Y) + permutate(X, Y) check_mesh(X, X_check) @test X.vertices[begin: begin+numvertices(Y)-1] == map(x->x[1:2], Y.vertices) end @@ -64,7 +64,7 @@ let translate!(X, point(0,0,1)) translate!(X_check, point(0,0,1)) - permutate_mesh(X, Y) + permutate(X, Y) check_mesh(X, X_check) @test map(x->x[1:2], X.vertices[begin: begin+numvertices(Y)-1]) == Y.vertices From ccda1361c5be4bedab58a652b1a2fa13df8e51a9 Mon Sep 17 00:00:00 2001 From: bboeyken Date: Thu, 19 Feb 2026 16:34:42 +0100 Subject: [PATCH 5/7] update 0.11.0 Change the files to be conform with the 0.11.0 version. --- src/permutatie_mesh.jl | 21 +++++++++++---------- test/test_overlap2D.jl | 15 --------------- test/test_patches.jl | 7 ++++--- test/test_permutate_mesh.jl | 2 +- 4 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/permutatie_mesh.jl b/src/permutatie_mesh.jl index a5f2727..b74dfca 100644 --- a/src/permutatie_mesh.jl +++ b/src/permutatie_mesh.jl @@ -14,19 +14,20 @@ In the last two, control that the other mesh is a submesh of the starting mesh. """ -function permutate(mesh::Mesh, σ::Union{Vector{<:Integer}, StaticArrays.SVector{Int32, <:Integer}}) - @assert numvertices(mesh) == length(σ) - permutate(mesh, Permutations.Permutation(σ)) -end - function permutate(mesh::Mesh, σ::Permutations.Permutation) mesh.vertices = mesh.vertices[σ.data] for (i, a) in enumerate(mesh.faces) - mesh.faces[i] = σ'.data[a] + ind = σ'.data[a.indices] + mesh.faces[i] = SimplexGraph(ind...) end end -function permutate(X::Mesh{U,D1}, Y::Mesh{U,D2}) where {U,D1,D2} +function permutate(mesh::Mesh, σ::Union{Vector{<:Integer}, StaticArrays.SVector{Int32, <:Integer}}) + @assert numvertices(mesh) == length(σ) + permutate(mesh, Permutations.Permutation(σ)) +end + +function permutate(X::Mesh{U}, Y::Mesh{U}) where {U} tol = sqrt(eps(coordtype(X))) permut = Vector{Int32}() temp = collect(1:numvertices(X)) @@ -46,7 +47,7 @@ function permutate(X::Mesh{U,D1}, Y::Mesh{U,D2}) where {U,D1,D2} X end -function permutate_mesh(X::Mesh{2,D1}, Y::Mesh{3,D2}) where { D1, D2} +function permutate(X::Mesh{2}, Y::Mesh{3}) tol = sqrt(eps(coordtype(X))) # assert that the z-coordinate for the vertices in X is constant. @@ -77,7 +78,7 @@ function permutate_mesh(X::Mesh{2,D1}, Y::Mesh{3,D2}) where { D1, D2} X end -function permutate(X::Mesh{3,D1}, Y::Mesh{2,D2}) where {D1, D2} +function permutate(X::Mesh{3}, Y::Mesh{2}) tol = sqrt(eps(coordtype(X))) # assert that the z-coordinate for the vertices in X is constant. @@ -107,6 +108,6 @@ function permutate(X::Mesh{3,D1}, Y::Mesh{2,D2}) where {D1, D2} push!(permut, i) end end - permutate_mesh(X, Permutations.Permutation(permut)) + permutate(X, Permutations.Permutation(permut)) X end diff --git a/test/test_overlap2D.jl b/test/test_overlap2D.jl index b1e96db..942402e 100644 --- a/test/test_overlap2D.jl +++ b/test/test_overlap2D.jl @@ -18,26 +18,11 @@ q2 = simplex( point(1.4, 0.4), point(0.4, 1.4), ) -overlap(p, q1) @test overlap(p, q1) == false @test overlap(p, q2) == true -## make sure the submesh function work for 1D meshes - - -l1 = meshsegment(1.0,1/2) -vt = skeleton(l1,0) -bd = boundary(l1) - -overlaps = overlap_gpredicate(bd) -pred1 = c -> overlaps(simplex(vertices(vt,c))) -@test pred1(SVector(1)) -@test !pred1(SVector(2)) -@test pred1(SVector(3)) - - # test a case where the segments are: # not of unit length # colinear and opposite diff --git a/test/test_patches.jl b/test/test_patches.jl index 06832e8..1c5b63d 100644 --- a/test/test_patches.jl +++ b/test/test_patches.jl @@ -24,9 +24,10 @@ end # universe dimension 2 for T in [Float32, Float64] local mesh = meshrectangle(T(1.0), T(1.0), T(1.0),2) - local faces = skeleton(mesh, 2) - local verts = vertices(mesh, faces.faces[1]) - p = simplex(verts) + # local faces = skeleton(mesh, 2) + # local verts = cellvertices(mesh, 1) + p = chart(mesh, cells(mesh)[1]) + #p = simplex(verts) @test p.vertices == [ point(T, 0.0, 0.0), diff --git a/test/test_permutate_mesh.jl b/test/test_permutate_mesh.jl index abe895f..495ff98 100644 --- a/test/test_permutate_mesh.jl +++ b/test/test_permutate_mesh.jl @@ -11,7 +11,7 @@ function check_mesh(X, X_check) # test that each face has the same points in identical order @test numcells(X) == numcells(X_check) for i in 1:numcells(X) - @test X.vertices[X.faces[i]] == X_check.vertices[X_check.faces[i]] + @test X.vertices[X.faces[i].indices] == X_check.vertices[X_check.faces[i].indices] end end From 4ab49bae1db1229457063ca3507bcb87956750f6 Mon Sep 17 00:00:00 2001 From: bboeyken Date: Thu, 5 Mar 2026 21:35:57 +0100 Subject: [PATCH 6/7] patch for udim=2 Create a patch for a mesh of udim=2. --- src/plotlyjs_glue.jl | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/plotlyjs_glue.jl b/src/plotlyjs_glue.jl index 9fc87d2..d57f0e3 100644 --- a/src/plotlyjs_glue.jl +++ b/src/plotlyjs_glue.jl @@ -44,6 +44,44 @@ function __init__() return s end + @eval function patch(Γ::CompScienceMeshes.AbstractMesh{2}, fcr=nothing; + caxis=nothing, showscale=true, color="red", kwargs...) + + v = vertexarray(Γ) + c = cellarray(Γ) + + x = v[:,1]; y = v[:,2]; z = zeros(length(y)) + i = c[:,1].-1; j = c[:,2].-1; k = c[:,3].-1 + + + if fcr != nothing + m, M = extrema(fcr) + if caxis != nothing + m, M = caxis + end + + s = PlotlyBase.mesh3d(; + x=x, y=y, z=z, + i=i, j=j, k=k, + intensitymode="cell", + intensity=fcr, + colorscale="Viridis", + showscale=showscale, + cmin=m, + cmax=M, + kwargs... + ) + else + s = PlotlyBase.mesh3d(; + x=x, y=y, z=z, + i=i, j=j, k=k, + color=color, + kwargs... + ) + end + return s + end + @eval function patch(a::Vector{<:Simplex}; kwargs...) vertices = reduce(vcat, [v.vertices for v in a]) faces = collect(SVector(3*(i-1)+1, 3*(i-1)+2, 3*(i-1)+3) for i in 1:length(a)) From c51114b5a14332fa745c32ac14465b03faddfce5 Mon Sep 17 00:00:00 2001 From: bboeyken Date: Wed, 11 Mar 2026 09:39:20 +0100 Subject: [PATCH 7/7] improve boundary The function got an extra optional parameter. This is for indicating if the interior points needs to be included, as is now the case. And if they don't need to be included. --- src/mesh.jl | 19 +++++++++++++++++-- test/test_mesh.jl | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/mesh.jl b/src/mesh.jl index f801417..b1f1b2c 100644 --- a/src/mesh.jl +++ b/src/mesh.jl @@ -331,7 +331,7 @@ Base.getindex(m::AbstractMesh, I::Vector{Int}) = Mesh(vertices(m), cells(m)[I]) Returns the boundary of `mesh` as a mesh of lower dimension. """ -function boundary(mesh) +function boundary(mesh, include_interior_points=true) D = dimension(mesh) @@ -366,7 +366,22 @@ function boundary(mesh) end resize!(bnd_edges, i-1) - bnd = Mesh(vertices(mesh), bnd_edges) + if include_interior_points + return Mesh(vertices(mesh), bnd_edges) + else + originaltonew = Dict{Int,Int}() + sizehint!(originaltonew, i-1) + bnd_edges_new = Vector{I}(undef, length(bnd_edges)) + for (e,edge) in enumerate(bnd_edges) + get!(originaltonew, edge.indices[1], e) + end + for (e,edge) in enumerate(bnd_edges) + bnd_edges_new[e] =SimplexGraph( + get(originaltonew, edge.indices[1], -1), + get(originaltonew, edge.indices[2], -1)) + end + return Mesh(vertices(mesh)[collect(keys(originaltonew))], bnd_edges_new) + end end diff --git a/test/test_mesh.jl b/test/test_mesh.jl index 749375d..a4f5e18 100644 --- a/test/test_mesh.jl +++ b/test/test_mesh.jl @@ -82,4 +82,23 @@ T = Float64 Σᵀ = connectivity(edges, faces, identity) Σ = connectivity(faces, edges, identity) @test norm(Σᵀ - Σ', Inf) == 0 + + rectangle = meshrectangle(T(1.0), T(1.0), T(0.5)); + bnd = boundary(rectangle, true) + + @test dimension(bnd) == 1 + @test numvertices(bnd) == 9 + @test numcells(bnd) == 8 + + bnd = boundary(rectangle, false) + + @test dimension(bnd) == 1 + @test numvertices(bnd) == 8 + @test numcells(bnd) == 8 + + + m = meshrectangle(T(1.0),T(1.0),T(0.5)) + CompScienceMeshes.rotate!(m, [1,0,0]*T(π/2)) + + @test CompScienceMeshes.isoriented(boundary(m, false)) # end \ No newline at end of file