@@ -305,21 +305,6 @@ function marching_cubes(sdf::SignedDistanceField{3,ST,FT},
305
305
vertlist = Vector {Point{3,Float64}} (undef, 12 )
306
306
@inbounds for xi = 1 : nx- 1 , yi = 1 : ny- 1 , zi = 1 : nz- 1
307
307
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
-
323
308
points = (Point {3,Float64} (xi- 1 ,yi- 1 ,zi- 1 ) .* s .+ orig,
324
309
Point {3,Float64} (xi,yi- 1 ,zi- 1 ) .* s .+ orig,
325
310
Point {3,Float64} (xi,yi,zi- 1 ) .* s .+ orig,
@@ -328,56 +313,32 @@ function marching_cubes(sdf::SignedDistanceField{3,ST,FT},
328
313
Point {3,Float64} (xi,yi- 1 ,zi) .* s .+ orig,
329
314
Point {3,Float64} (xi,yi,zi) .* s .+ orig,
330
315
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
331
339
332
340
# 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)
381
342
382
343
# Create the triangle
383
344
for i = 1 : 3 : 13
@@ -418,7 +379,6 @@ function marching_cubes(f::Function,
418
379
points = Vector {Point{3,Float64}} (undef,8 )
419
380
@inbounds for xi = 1 : nx- 1 , yi = 1 : ny- 1 , zi = 1 : nz- 1
420
381
421
-
422
382
if zi == 1
423
383
points[1 ] = Point {3,Float64} (xi- 1 ,yi- 1 ,zi- 1 ) .* s .+ orig
424
384
points[2 ] = Point {3,Float64} (xi,yi- 1 ,zi- 1 ) .* s .+ orig
@@ -468,54 +428,7 @@ function marching_cubes(f::Function,
468
428
# Find the vertices where the surface intersects the cube
469
429
# TODO this can use the underlying function to find the zero.
470
430
# 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)
519
432
520
433
# Create the triangle
521
434
for i = 1 : 3 : 13
@@ -530,6 +443,57 @@ function marching_cubes(f::Function,
530
443
MT (vts,fcs)
531
444
end
532
445
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
+
533
497
# Linearly interpolate the position where an isosurface cuts
534
498
# an edge between two vertices, each with their own scalar value
535
499
function vertex_interp (iso, p1, p2, valp1, valp2, eps = 0.00001 )
0 commit comments