Skip to content

Commit

Permalink
Improved trisurfslice with face labels, added testing #20
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin-Mattheus-Moerman committed Apr 3, 2024
1 parent a0a6969 commit 1663bbd
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 30 deletions.
49 changes: 29 additions & 20 deletions examples/demo_trisurfslice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ p = mean(V,dims=1)[1]; # Point on cutting plane
n = normalizevector(Vec{3, Float64}(0.0,1.0,1.0))# Cutting plane normal
snapTolerance = 1e-6

Fn,Vn = trisurfslice(F,V,n,p; output_type=:below)
cutType = :full
Fn,Vn,Cn = trisurfslice(F,V,n,p; output_type=cutType)
Fn,Vn = separate_vertices(Fn,Vn)
CnV = simplex2vertexdata(Fn,Cn)
Mn = GeometryBasics.Mesh(Vn,Fn)


Expand All @@ -50,35 +53,41 @@ R = rotation_between(n,[0.0,0.0,1.0])
plateDim = (s,s)
plateElem = (1,1)
FG1,VG1 = quadplate(plateDim,plateElem)
MG = GeometryBasics.Mesh(VG1,FG1)
VGn = [GeometryBasics.Point{3, Float64}(R'*v)+p for v VG1]
MG = GeometryBasics.Mesh(VGn,FG1)

fig = Figure(size=(800,800))
ax1 = Axis3(fig[1, 1], aspect = :data, xlabel = "X", ylabel = "Y", zlabel = "Z", title = "A sliced mesh")

stepRange = range(-s,s,50)
hSlider = Slider(fig[2, 1], range = stepRange, startvalue = 0,linewidth=30)

Mn = lift(hSlider.value) do stepIndex
pp = [p[1],p[2],p[3]+stepIndex]
Fn,Vn = trisurfslice(F,V,n,pp; output_type=:below)
# hp1 = mesh!(ax1,GeometryBasics.Mesh(V,F),color=:white, shading = FastShading, transparency=true)
hp2 = wireframe!(ax1,MG, linewidth=5, color=:red)
hp3 = poly!(ax1,Mn, color=CnV, strokewidth=1, strokecolor=:black, shading = FastShading, transparency=false, colorrange = (-2,2),colormap=:Spectral)
# hp3 = normalplot(ax1,Mn)
hp4 = Colorbar(fig[1,2],hp3)

on(hSlider.value) do stepIndex
pp = p + stepIndex*n
Fn,Vn,Cn = trisurfslice(F,V,n,pp; output_type=cutType)

if isempty(Fn)
return GeometryBasics.Mesh(V,F)
Mn = GeometryBasics.Mesh(V,F)
CnV = zeros(length(V))
else
return GeometryBasics.Mesh(Vn,Fn)
Fn,Vn = separate_vertices(Fn,Vn)
CnV = simplex2vertexdata(Fn,Cn)
Mn = GeometryBasics.Mesh(Vn,Fn)
end
end

MG = lift(hSlider.value) do stepIndex
pp = [p[1],p[2],p[3]+stepIndex]

VGn = [GeometryBasics.Point{3, Float64}(R'*v) for v VG1] # Rotate plane
VGn = map(v-> v.+pp,VGn) # Offset plate
return GeometryBasics.Mesh(togeometrybasics_points(VGn),FG1)
end
VGn = [GeometryBasics.Point{3, Float64}(R'*v)+pp for v VG1] # Rotate plane
MG = GeometryBasics.Mesh(togeometrybasics_points(VGn),FG1)

hp1 = mesh!(ax1,GeometryBasics.Mesh(V,F),color=:white, shading = FastShading, transparency=true)
hp2 = wireframe!(ax1,MG, linewidth=5, color=:red)
hp3 = poly!(ax1,Mn, strokewidth=2,color=:white, strokecolor=:blue, shading = FastShading, transparency=false)
# hp3 = normalplot(ax1,Mn)
hp2[1] = MG
hp3[1] = Mn
hp3.color = CnV
end

slidercontrol(hSlider,ax1)
fig
fig
27 changes: 20 additions & 7 deletions src/functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ function slidercontrol(hSlider::Slider,ax::Union{Axis3, Figure})
sliderIndex -= 1
end
end
println(sliderIndex)
set_close_to!(hSlider, sliderRange[sliderIndex])
hSlider.selected_index = sliderIndex
end
end
end
Expand Down Expand Up @@ -2157,7 +2156,7 @@ function remove_unused_vertices(F,V)::Tuple
return Fc, Vc, indFix
end

function trisurfslice(F,V,n = (0.0,0.0,1.0), p = mean(V,dims=1); snapTolerance = 0, output_type=:full)
function trisurfslice(F,V,n = Vec{3, Float64}(0.0,1.0,1.0), p = mean(V,dims=1); snapTolerance = 0, output_type=:full)

intersectFunc(v1,v2,d,n) = v1 .- d/dot(n,v2.-v1) .* (v2.-v1)

Expand All @@ -2169,6 +2168,7 @@ function trisurfslice(F,V,n = (0.0,0.0,1.0), p = mean(V,dims=1); snapTolerance =
LV = d.<0

Fn = Vector{TriangleFace{Int64}}()
Cn = Vector{Int64}()
Vn = deepcopy(V)
D = Dict{Vector{Int64},Int64}() # For pointing from edge to intersection point index
for f F
Expand All @@ -2178,6 +2178,7 @@ function trisurfslice(F,V,n = (0.0,0.0,1.0), p = mean(V,dims=1); snapTolerance =
if all(lf) # All below
if output_type == :full || output_type == :below
push!(Fn,f)
push!(Cn,-2)
end
else # Some below -> cut
nBelow = sum(lf) # Number of nodes below
Expand All @@ -2196,11 +2197,16 @@ function trisurfslice(F,V,n = (0.0,0.0,1.0), p = mean(V,dims=1); snapTolerance =
D[e2] = length(Vn)
end

if output_type == :above || output_type == :full
if output_type == :above || output_type == :full
push!(Fn,TriangleFace{Int64}(D[e1],indP[2],indP[3]))
push!(Fn,TriangleFace{Int64}(D[e1],indP[3],D[e2]))
elseif output_type == :below || output_type == :full
push!(Cn,1)
push!(Cn,1)
end

if output_type == :below || output_type == :full
push!(Fn,TriangleFace{Int64}(indP[1],D[e1],D[e2]))
push!(Cn,-1)
end

else # 1-above, 2 below
Expand All @@ -2221,18 +2227,25 @@ function trisurfslice(F,V,n = (0.0,0.0,1.0), p = mean(V,dims=1); snapTolerance =
if output_type == :below || output_type == :full
push!(Fn,TriangleFace{Int64}(D[e1],indP[2],indP[3]))
push!(Fn,TriangleFace{Int64}(D[e1],indP[3],D[e2]))
elseif output_type == :above || output_type == :full
push!(Cn,-1)
push!(Cn,-1)
end

if output_type == :above || output_type == :full
push!(Fn,TriangleFace{Int64}(indP[1],D[e1],D[e2]))
push!(Cn,1)
end
end
end
else # Not any below -> all above
if output_type == :full || output_type == :above
push!(Fn,f)
push!(Cn,2)
end
end
end
return remove_unused_vertices(Fn,Vn)
Fn,Vn = remove_unused_vertices(Fn,Vn)
return Fn,Vn,Cn
end

function count_edge_face(F,E_uni=nothing,indReverse=nothing)::Vector{Int64}
Expand Down
51 changes: 48 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2353,10 +2353,55 @@ end
end


# @testset "trisurfslice" begin
# F,V = geosphere(2,1.0)
@testset "trisurfslice" begin
tol_level = 1e-2

r = 2.5 # Sphere radius
F,V = geosphere(3,r)

p = [0.0,0.0,0.0]; # Point on cutting plane
n = normalizevector(Vec{3, Float64}(0.0,0.0,1.0))# Cutting plane normal
snapTolerance = 1e-6
output_type = :full

Fn,Vn,Cn = trisurfslice(F,V,n,p; output_type=output_type)

# Check if cut defines a circle of expected radius
Fn_below = Fn[Cn.<0]
En_below = boundaryedges(Fn_below)
ind_below = unique(reduce(vcat,En_below))
d = [norm(v) for v Vn[ind]]
@test isapprox(sum((d.-r).^2),0.0,atol=tol_level) # Should

p = [0.0,0.0,0.0]; # Point on cutting plane
n = normalizevector(Vec{3, Float64}(0.0,1.0,1.0))# Cutting plane normal
snapTolerance = 1e-6
output_type = :full

Fn,Vn,Cn = trisurfslice(F,V,n,p; output_type=output_type)

# Check if cut defines a circle of expected radius
Fn_below = Fn[Cn.<0]
En_below = boundaryedges(Fn_below)
ind_below = unique(reduce(vcat,En_below))
d = [norm(v) for v Vn[ind]]
@test isapprox(sum((d.-r).^2),0.0,atol=tol_level) # Should

p = [0.0,0.0,0.0]; # Point on cutting plane
n = normalizevector(Vec{3, Float64}(1.0,1.0,1.0))# Cutting plane normal
snapTolerance = 1e-6
output_type = :full

Fn,Vn,Cn = trisurfslice(F,V,n,p; output_type=output_type)

# Check if cut defines a circle of expected radius
Fn_below = Fn[Cn.<0]
En_below = boundaryedges(Fn_below)
ind_below = unique(reduce(vcat,En_below))
d = [norm(v) for v Vn[ind]]
@test isapprox(sum((d.-r).^2),0.0,atol=tol_level) # Should
end

# end

@testset "count_edge_face" verbose = true begin

Expand Down

0 comments on commit 1663bbd

Please sign in to comment.