Skip to content

Commit 44741d7

Browse files
committed
generalize vertex interpolation code to share between MC implementations
1 parent 39c7d23 commit 44741d7

File tree

1 file changed

+76
-112
lines changed

1 file changed

+76
-112
lines changed

src/marching_cubes.jl

Lines changed: 76 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -305,21 +305,6 @@ function marching_cubes(sdf::SignedDistanceField{3,ST,FT},
305305
vertlist = Vector{Point{3,Float64}}(undef, 12)
306306
@inbounds for xi = 1:nx-1, yi = 1:ny-1, zi = 1:nz-1
307307

308-
#Determine the index into the edge table which
309-
#tells us which vertices are inside of the surface
310-
cubeindex = sdf[xi,yi,zi] < iso ? 1 : 0
311-
sdf[xi+1,yi,zi] < iso && (cubeindex |= 2)
312-
sdf[xi+1,yi+1,zi] < iso && (cubeindex |= 4)
313-
sdf[xi,yi+1,zi] < iso && (cubeindex |= 8)
314-
sdf[xi,yi,zi+1] < iso && (cubeindex |= 16)
315-
sdf[xi+1,yi,zi+1] < iso && (cubeindex |= 32)
316-
sdf[xi+1,yi+1,zi+1] < iso && (cubeindex |= 64)
317-
sdf[xi,yi+1,zi+1] < iso && (cubeindex |= 128)
318-
cubeindex += 1
319-
320-
# Cube is entirely in/out of the surface
321-
edge_table[cubeindex] == 0 && continue
322-
323308
points = (Point{3,Float64}(xi-1,yi-1,zi-1) .* s .+ orig,
324309
Point{3,Float64}(xi,yi-1,zi-1) .* s .+ orig,
325310
Point{3,Float64}(xi,yi,zi-1) .* s .+ orig,
@@ -328,56 +313,32 @@ function marching_cubes(sdf::SignedDistanceField{3,ST,FT},
328313
Point{3,Float64}(xi,yi-1,zi) .* s .+ orig,
329314
Point{3,Float64}(xi,yi,zi) .* s .+ orig,
330315
Point{3,Float64}(xi-1,yi,zi) .* s .+ orig)
316+
iso_vals = (sdf[xi,yi,zi],
317+
sdf[xi+1,yi,zi],
318+
sdf[xi+1,yi+1,zi],
319+
sdf[xi,yi+1,zi],
320+
sdf[xi,yi,zi+1],
321+
sdf[xi+1,yi,zi+1],
322+
sdf[xi+1,yi+1,zi+1],
323+
sdf[xi,yi+1,zi+1])
324+
325+
#Determine the index into the edge table which
326+
#tells us which vertices are inside of the surface
327+
cubeindex = iso_vals[1] < iso ? 1 : 0
328+
iso_vals[2] < iso && (cubeindex |= 2)
329+
iso_vals[3] < iso && (cubeindex |= 4)
330+
iso_vals[4] < iso && (cubeindex |= 8)
331+
iso_vals[5] < iso && (cubeindex |= 16)
332+
iso_vals[6] < iso && (cubeindex |= 32)
333+
iso_vals[7] < iso && (cubeindex |= 64)
334+
iso_vals[8] < iso && (cubeindex |= 128)
335+
cubeindex += 1
336+
337+
# Cube is entirely in/out of the surface
338+
edge_table[cubeindex] == 0 && continue
331339

332340
# Find the vertices where the surface intersects the cube
333-
if (edge_table[cubeindex] & 1 != 0)
334-
vertlist[1] =
335-
vertex_interp(iso,points[1],points[2],sdf[xi,yi,zi],sdf[xi+1,yi,zi], eps)
336-
end
337-
if (edge_table[cubeindex] & 2 != 0)
338-
vertlist[2] =
339-
vertex_interp(iso,points[2],points[3],sdf[xi+1,yi,zi],sdf[xi+1,yi+1,zi], eps)
340-
end
341-
if (edge_table[cubeindex] & 4 != 0)
342-
vertlist[3] =
343-
vertex_interp(iso,points[3],points[4],sdf[xi+1,yi+1,zi],sdf[xi,yi+1,zi], eps)
344-
end
345-
if (edge_table[cubeindex] & 8 != 0)
346-
vertlist[4] =
347-
vertex_interp(iso,points[4],points[1],sdf[xi,yi+1,zi],sdf[xi,yi,zi], eps)
348-
end
349-
if (edge_table[cubeindex] & 16 != 0)
350-
vertlist[5] =
351-
vertex_interp(iso,points[5],points[6],sdf[xi,yi,zi+1],sdf[xi+1,yi,zi+1], eps)
352-
end
353-
if (edge_table[cubeindex] & 32 != 0)
354-
vertlist[6] =
355-
vertex_interp(iso,points[6],points[7],sdf[xi+1,yi,zi+1],sdf[xi+1,yi+1,zi+1], eps)
356-
end
357-
if (edge_table[cubeindex] & 64 != 0)
358-
vertlist[7] =
359-
vertex_interp(iso,points[7],points[8],sdf[xi+1,yi+1,zi+1],sdf[xi,yi+1,zi+1], eps)
360-
end
361-
if (edge_table[cubeindex] & 128 != 0)
362-
vertlist[8] =
363-
vertex_interp(iso,points[8],points[5],sdf[xi,yi+1,zi+1],sdf[xi,yi,zi+1], eps)
364-
end
365-
if (edge_table[cubeindex] & 256 != 0)
366-
vertlist[9] =
367-
vertex_interp(iso,points[1],points[5],sdf[xi,yi,zi],sdf[xi,yi,zi+1], eps)
368-
end
369-
if (edge_table[cubeindex] & 512 != 0)
370-
vertlist[10] =
371-
vertex_interp(iso,points[2],points[6],sdf[xi+1,yi,zi],sdf[xi+1,yi,zi+1], eps)
372-
end
373-
if (edge_table[cubeindex] & 1024 != 0)
374-
vertlist[11] =
375-
vertex_interp(iso,points[3],points[7],sdf[xi+1,yi+1,zi],sdf[xi+1,yi+1,zi+1], eps)
376-
end
377-
if (edge_table[cubeindex] & 2048 != 0)
378-
vertlist[12] =
379-
vertex_interp(iso,points[4],points[8],sdf[xi,yi+1,zi],sdf[xi,yi+1,zi+1], eps)
380-
end
341+
find_vertices_interp!(vertlist, points, iso_vals, cubeindex, iso, eps)
381342

382343
# Create the triangle
383344
for i = 1:3:13
@@ -418,7 +379,6 @@ function marching_cubes(f::Function,
418379
points = Vector{Point{3,Float64}}(undef,8)
419380
@inbounds for xi = 1:nx-1, yi = 1:ny-1, zi = 1:nz-1
420381

421-
422382
if zi == 1
423383
points[1] = Point{3,Float64}(xi-1,yi-1,zi-1) .* s .+ orig
424384
points[2] = Point{3,Float64}(xi,yi-1,zi-1) .* s .+ orig
@@ -468,54 +428,7 @@ function marching_cubes(f::Function,
468428
# Find the vertices where the surface intersects the cube
469429
# TODO this can use the underlying function to find the zero.
470430
# The underlying space is non-linear so there will be error otherwise
471-
if (edge_table[cubeindex] & 1 != 0)
472-
vertlist[1] =
473-
vertex_interp(iso,points[1],points[2],iso_vals[1],iso_vals[2], eps)
474-
end
475-
if (edge_table[cubeindex] & 2 != 0)
476-
vertlist[2] =
477-
vertex_interp(iso,points[2],points[3],iso_vals[2],iso_vals[3], eps)
478-
end
479-
if (edge_table[cubeindex] & 4 != 0)
480-
vertlist[3] =
481-
vertex_interp(iso,points[3],points[4],iso_vals[3],iso_vals[4], eps)
482-
end
483-
if (edge_table[cubeindex] & 8 != 0)
484-
vertlist[4] =
485-
vertex_interp(iso,points[4],points[1],iso_vals[4],iso_vals[1], eps)
486-
end
487-
if (edge_table[cubeindex] & 16 != 0)
488-
vertlist[5] =
489-
vertex_interp(iso,points[5],points[6],iso_vals[5],iso_vals[6], eps)
490-
end
491-
if (edge_table[cubeindex] & 32 != 0)
492-
vertlist[6] =
493-
vertex_interp(iso,points[6],points[7],iso_vals[6],iso_vals[7], eps)
494-
end
495-
if (edge_table[cubeindex] & 64 != 0)
496-
vertlist[7] =
497-
vertex_interp(iso,points[7],points[8],iso_vals[7],iso_vals[8], eps)
498-
end
499-
if (edge_table[cubeindex] & 128 != 0)
500-
vertlist[8] =
501-
vertex_interp(iso,points[8],points[5],iso_vals[8],iso_vals[5], eps)
502-
end
503-
if (edge_table[cubeindex] & 256 != 0)
504-
vertlist[9] =
505-
vertex_interp(iso,points[1],points[5],iso_vals[1],iso_vals[5], eps)
506-
end
507-
if (edge_table[cubeindex] & 512 != 0)
508-
vertlist[10] =
509-
vertex_interp(iso,points[2],points[6],iso_vals[2],iso_vals[6], eps)
510-
end
511-
if (edge_table[cubeindex] & 1024 != 0)
512-
vertlist[11] =
513-
vertex_interp(iso,points[3],points[7],iso_vals[3],iso_vals[7], eps)
514-
end
515-
if (edge_table[cubeindex] & 2048 != 0)
516-
vertlist[12] =
517-
vertex_interp(iso,points[4],points[8],iso_vals[4],iso_vals[8], eps)
518-
end
431+
find_vertices_interp!(vertlist, points, iso_vals, cubeindex, iso, eps)
519432

520433
# Create the triangle
521434
for i = 1:3:13
@@ -530,6 +443,57 @@ function marching_cubes(f::Function,
530443
MT(vts,fcs)
531444
end
532445

446+
@inline function find_vertices_interp!(vertlist, points, iso_vals, cubeindex, iso, eps)
447+
if (edge_table[cubeindex] & 1 != 0)
448+
vertlist[1] =
449+
vertex_interp(iso,points[1],points[2],iso_vals[1],iso_vals[2], eps)
450+
end
451+
if (edge_table[cubeindex] & 2 != 0)
452+
vertlist[2] =
453+
vertex_interp(iso,points[2],points[3],iso_vals[2],iso_vals[3], eps)
454+
end
455+
if (edge_table[cubeindex] & 4 != 0)
456+
vertlist[3] =
457+
vertex_interp(iso,points[3],points[4],iso_vals[3],iso_vals[4], eps)
458+
end
459+
if (edge_table[cubeindex] & 8 != 0)
460+
vertlist[4] =
461+
vertex_interp(iso,points[4],points[1],iso_vals[4],iso_vals[1], eps)
462+
end
463+
if (edge_table[cubeindex] & 16 != 0)
464+
vertlist[5] =
465+
vertex_interp(iso,points[5],points[6],iso_vals[5],iso_vals[6], eps)
466+
end
467+
if (edge_table[cubeindex] & 32 != 0)
468+
vertlist[6] =
469+
vertex_interp(iso,points[6],points[7],iso_vals[6],iso_vals[7], eps)
470+
end
471+
if (edge_table[cubeindex] & 64 != 0)
472+
vertlist[7] =
473+
vertex_interp(iso,points[7],points[8],iso_vals[7],iso_vals[8], eps)
474+
end
475+
if (edge_table[cubeindex] & 128 != 0)
476+
vertlist[8] =
477+
vertex_interp(iso,points[8],points[5],iso_vals[8],iso_vals[5], eps)
478+
end
479+
if (edge_table[cubeindex] & 256 != 0)
480+
vertlist[9] =
481+
vertex_interp(iso,points[1],points[5],iso_vals[1],iso_vals[5], eps)
482+
end
483+
if (edge_table[cubeindex] & 512 != 0)
484+
vertlist[10] =
485+
vertex_interp(iso,points[2],points[6],iso_vals[2],iso_vals[6], eps)
486+
end
487+
if (edge_table[cubeindex] & 1024 != 0)
488+
vertlist[11] =
489+
vertex_interp(iso,points[3],points[7],iso_vals[3],iso_vals[7], eps)
490+
end
491+
if (edge_table[cubeindex] & 2048 != 0)
492+
vertlist[12] =
493+
vertex_interp(iso,points[4],points[8],iso_vals[4],iso_vals[8], eps)
494+
end
495+
end
496+
533497
# Linearly interpolate the position where an isosurface cuts
534498
# an edge between two vertices, each with their own scalar value
535499
function vertex_interp(iso, p1, p2, valp1, valp2, eps = 0.00001)

0 commit comments

Comments
 (0)