Skip to content

Commit

Permalink
support AbstractRange types for coordinate vectors (#29)
Browse files Browse the repository at this point in the history
Co-authored-by: t-bltg <[email protected]>
  • Loading branch information
Kevin-Mattheus-Moerman and t-bltg authored Jan 7, 2025
1 parent 3571695 commit 71e3b84
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.10' # latest LTS
- 'lts'
- '1'
experimental:
- false
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/format-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
else
@error "Some files have not been formatted !!!"
write(stdout, out)
run(`git diff`)
exit(1)
end
'
6 changes: 5 additions & 1 deletion src/MarchingCubes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ struct MC{F,I}
y::AbstractVector{F} = F[],
z::AbstractVector{F} = F[],
) where {F<:AbstractFloat,G<:Integer} = begin
abs(normal_sign) == 1 || throw(ArgumentError("`normal_sign` should be either -1 or +1"))
isa(x, AbstractRange) && (x = collect(x))
isa(y, AbstractRange) && (y = collect(y))
isa(z, AbstractRange) && (z = collect(z))
abs(normal_sign) == 1 ||
throw(ArgumentError("`normal_sign` should be either -1 or +1"))
m = new{F,I}(
size(vol)...,
Ref(vol),
Expand Down
2 changes: 1 addition & 1 deletion src/example.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ makemesh_GeometryBasics(GeometryBasics::Module, m::MC) = begin
vertices = map(GeometryBasics.Point3f, m.vertices)
normals = map(GeometryBasics.Vec3f, m.normals)
triangles = map(t -> GeometryBasics.TriangleFace(t...), m.triangles)
GeometryBasics.Mesh(GeometryBasics.meta(vertices; normals), triangles)
GeometryBasics.Mesh(vertices, triangles; normal = normals)
end

makemesh(mod::Module, m::MC) =
Expand Down
58 changes: 48 additions & 10 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using BenchmarkTools
using GeometryBasics
using MarchingCubes
using Meshes
Expand Down Expand Up @@ -118,14 +117,6 @@ end
MarchingCubes.output(PlyIO, mc, tempname(); verbose = false)
end

@testset "types" begin
for F (Float16, Float32, Float64)
for I (Int16, Int32, Int64, Int128, UInt16, UInt32, UInt64, UInt128)
@test march(MarchingCubes.scenario(4, 4, 4; F, I)) isa Nothing
end
end
end

@testset "normalize" begin
nx, ny, nz = 10, 20, 30
start_x, stop_x = -0.1, 0.1
Expand Down Expand Up @@ -187,7 +178,54 @@ end
msh = MarchingCubes.makemesh(GeometryBasics, mc)
@test msh isa GeometryBasics.Mesh
@test length(msh.position) == length(mc.vertices)
@test length(msh.normals) == length(mc.normals)
@test length(msh.normal) == length(mc.normals)

@test_throws ArgumentError MarchingCubes.makemesh(PlyIO, mc)
end

@testset "coordinate input variations" begin
atol = 1e-3 # precision level

# define coordinate ranges (also creating 3 different lengths)
nx, ny, nz = 55, 46, 67 # these should be high enough to reach precision level
start_x, stop_x = -1.0, 1.0 # range limits centered on 0
start_y, stop_y = -1.2, 1.2 # range limits centered on 0
start_z, stop_z = -2.3, 2.3 # range limits centered on 0
x = range(start_x, stop_x; length = nx)
y = range(start_y, stop_y; length = ny)
z = range(start_z, stop_z; length = nz)

# create image (simple coordinate norm leading to spherical isosurface)
A = [(xi^2 + yi^2 + zi^2) for xi x, yi y, zi z]

level = 0.5 # isolevel should produce sphere with this radius

# process isosurface with ranged coordinate input
mc_ranged = MC(A, Int; x, y, z)
march(mc_ranged, level)

xv, yv, zv = collect.(Float64, (x, y, z))

# process isosurface with vector coordinate input
mc_vector = MC(A, Int; x = xv, y = yv, z = zv)
march(mc_vector, level)

# test equivalence between ranged and vector input
@test mc_ranged.vertices == mc_vector.vertices
@test mc_ranged.triangles == mc_vector.triangles

# test if coordinate input was used appropriately geometrically as expected
n = length(mc_ranged.vertices)
c = sum(mc_ranged.vertices) / n # mean coordinate i.e. center
r = sum(v -> (sum(abs2, v)), mc_ranged.vertices) / n # mean radius
@test isapprox(c, zeros(3); atol) # approximately zero mean for sphere
@test isapprox(r, level; atol) # approximately radius matching level
end

@testset "types" begin
for F (Float16, Float32, Float64),
I (Int16, Int32, Int64, Int128, UInt16, UInt32, UInt64, UInt128)

@test march(MarchingCubes.scenario(4, 4, 4; F, I)) isa Nothing
end
end

0 comments on commit 71e3b84

Please sign in to comment.