@@ -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)
531444end
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
535499function vertex_interp (iso, p1, p2, valp1, valp2, eps = 0.00001 )
0 commit comments