diff --git a/examples/demo_trisurfslice.jl b/examples/demo_trisurfslice.jl index e51b434..159e145 100644 --- a/examples/demo_trisurfslice.jl +++ b/examples/demo_trisurfslice.jl @@ -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) @@ -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 \ No newline at end of file diff --git a/src/functions.jl b/src/functions.jl index 2cb1661..8361bf7 100644 --- a/src/functions.jl +++ b/src/functions.jl @@ -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 @@ -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) @@ -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 @@ -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 @@ -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 @@ -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} diff --git a/test/runtests.jl b/test/runtests.jl index 0806be9..6312fe4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -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