From 2d0b80fec95eb2021fc1a30caa50d689c3d7039e Mon Sep 17 00:00:00 2001 From: Kevin-Mattheus-Moerman Date: Fri, 29 Mar 2024 20:34:54 +0000 Subject: [PATCH] Testing for pointspacingmean --- examples/demo_extrudecurve.jl | 25 +++----------------- src/functions.jl | 34 ++++++++++++++++++++++++--- test/runtests.jl | 43 +++++++++++++++++++++++++++-------- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/examples/demo_extrudecurve.jl b/examples/demo_extrudecurve.jl index 5a57632..0fb4494 100644 --- a/examples/demo_extrudecurve.jl +++ b/examples/demo_extrudecurve.jl @@ -15,29 +15,10 @@ n = normalizevector(Vec{3, Float64}(0.0,0.0,1.0)) pointSpacing =0.25 s = 1 -function extrudecurve(V1,d; s=1, n=Point{3, Float64}(0.0,0.0,1.0),num_steps=missing,close_loop=false,face_type="quad") - if ismissing(num_steps) - num_steps = ceil(Int64,d/pointspacingmean(V1)) - if face_type==:tri - num_steps = num_steps + Int64(iseven(num_steps)) # Force uneven - end - end - if s==1 # Allong n from V1 - p = d.*n - elseif s==-1 # Against n from V1 - p = -d.*n - elseif s==0 # Extrude both ways from V1 - p = d.*n - V1 = [(eltype(V1))(v.-p./2) for v ∈ V1] #Shift V1 in negative direction - end - V2 = [(eltype(V1))(v.+p) for v ∈ V1] - return loftlinear(V1,V2;num_steps=num_steps,close_loop=close_loop,face_type=face_type) -end - # num_loft = ceil(Int64,d/pointSpacing) -F1,V1 = extrudecurve(Vc,d;s=1, close_loop=true,face_type=:quad) -F2,V2 = extrudecurve(Vc,d;s=0, close_loop=true,face_type=:tri) -F3,V3 = extrudecurve(Vc,d;s=-1, close_loop=true,face_type=:tri_slash) +F1,V1 = extrudecurve(Vc,d;s=1, n=n, close_loop=true,face_type=:quad) +F2,V2 = extrudecurve(Vc,d;s=0, n=n, close_loop=true,face_type=:tri) +F3,V3 = extrudecurve(Vc,d;s=-1, n=n, close_loop=true,face_type=:tri_slash) M1 = GeometryBasics.Mesh(V1,F1) M2 = GeometryBasics.Mesh(V2,F2) diff --git a/src/functions.jl b/src/functions.jl index eb76419..849c6e8 100644 --- a/src/functions.jl +++ b/src/functions.jl @@ -2126,23 +2126,50 @@ function edges2curve(Eb) e_ind = con_E2E[i] # Indices for connected edges if Eb[e_ind[1]][1]==ind[end] #Check if 1st point of 1st edge equals end i = e_ind[1] - elseif Eb[e_ind[2]][1]==ind[end] #Check if 1st point of 2nd edge equals end + elseif length(e_ind)>1 && Eb[e_ind[2]][1]==ind[end] #Check if 1st point of 2nd edge equals end i = e_ind[2] end end return ind end -function pointspacingmean(V)::Float64 +""" + pointspacingmean(V::Vector{Point3{Float64}}) + pointspacingmean(F::Array{NgonFace{N, Int64}, 1},V::Vector{Point3{Float64}}) where N + +The `pointspacingmean` function computes the mean spacing between points. The +input can be just the coordinate set `V`, a vector of GeometryBasics.Point3 +points, or also a set of edges `E` or faces `F`. If only `V` is provided it is +assumed that `V` represents an ordered set of "adjacent" points, e.g. as for a +curve. If a vector of edges `E` or a vector of faces `F is also provided, then +the average edge length is computed. If instead a set of faces `F` is provided +then edges are first computed after which the mean edge spacing is return. +""" +function pointspacingmean(V::Vector{Point3{Float64}}) # Equivalent to: mean(norm.(diff(V,dims=1))) p = 0.0 n = length(V) for i ∈ 1:n-1 - p += norm(V[i].-V[i+1])/(n-1) + p += norm(V[i]-V[i+1])/(n-1) + end + return p +end + +function pointspacingmean(F::Array{NgonFace{N, Int64}, 1},V::Vector{Point3{Float64}}) where N + if isa(F,Vector{LineFace{Int64}}) + E = F + else + E = meshedges(F; unique_only=true) + end + p = 0.0 + n = length(E) + for i ∈ 1:n + p += norm(V[E[i][1]]-V[E[i][2]])/n end return p end + function extrudecurve(V1,d; s=1, n=Point{3, Float64}(0.0,0.0,1.0),num_steps=nothing,close_loop=false,face_type=:quad) if isnothing(num_steps) num_steps = ceil(Int64,d/pointspacingmean(V1)) @@ -2162,6 +2189,7 @@ function extrudecurve(V1,d; s=1, n=Point{3, Float64}(0.0,0.0,1.0),num_steps=noth return loftlinear(V1,V2;num_steps=num_steps,close_loop=close_loop,face_type=face_type) end + function meshgroup(F; con_type = :v) if con_type == :v # Group based on vertex connectivity diff --git a/test/runtests.jl b/test/runtests.jl index 181a306..ad7bb77 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1761,16 +1761,41 @@ end @testset "edges2curve" begin - F, V = geosphere(3, 1.0) - VC = simplexcenter(F, V) - F = [F[i] for i in findall(map(v -> v[3] > 0, VC))] # Remove some faces - F, V = remove_unused_vertices(F, V) - Eb = boundaryedges(F) - ind = edges2curve(Eb) - @test length(ind) == 49 - @test ind == - [272, 205, 329, 168, 309, 184, 270, 145, 306, 220, 334, 223, 305, 138, 320, 204, 292, 232, 336, 234, 311, 203, 269, 115, 303, 194, 321, 133, 312, 207, 271, 164, 308, 209, 330, 231, 307, 154, 327, 206, 301, 240, 335, 229, 310, 196, 304, 208, 272] + # Open curve + E = LineFace{Int64}[[1, 2], [2, 3], [3, 4], [4, 5]] + ind = edges2curve(E) + @test ind == [1,2,3,4,5] + + # Closed curve + E = LineFace{Int64}[[1, 2], [2, 3], [3, 1]] + ind = edges2curve(E) + @test ind == [1,2,3,1] + +end + + +@testset "pointspacingmean" verbose = true begin + eps_level = 0.001 + @testset "Curve" begin + V = Point3{Float64}[[0.0,0.0,0.0],[0.25,0.0,0.0],[0.75,0.0,0.0],[1.75,0.0,0.0]] + r = pointspacingmean(V) + @test isapprox(r,mean(norm.(diff(V,dims=1))),atol = eps_tol) + end + + @testset "Edges" begin + V = Point3{Float64}[[0.0,0.0,0.0],[0.25,0.0,0.0],[0.75,0.0,0.0],[1.75,0.0,0.0]] + E = LineFace{Int64}[[1,2],[2,3],[3,4]] + r = pointspacingmean(E,V) + @test isapprox(r,mean(norm.(diff(V,dims=1))),atol = eps_tol) + end + + @testset "Faces" begin + V = Point3{Float64}[[0.0,0.0,0.0],[0.25,0.0,0.0],[0.25,0.5,0.0],[0,0.5,0.0],[0.0,0.0,0.0]] + F = QuadFace{Int64}[[1,2,3,4]] + r = pointspacingmean(F,V) + @test isapprox(r,mean(norm.(diff(V,dims=1))),atol = eps_tol) + end end