@@ -287,12 +287,17 @@ However it may generate non-manifold meshes, while Marching
287
287
Tetrahedra guarentees a manifold mesh.
288
288
"""
289
289
function marching_cubes (sdf:: SignedDistanceField{3,ST,FT} ,
290
- iso= 0.0 ,
291
- MT:: Type{M} = SimpleMesh{Point{3 ,Float64},Face{3 ,Int}}) where {ST,FT,M<: AbstractMesh }
290
+ iso= 0.0 ,
291
+ MT:: Type{M} = SimpleMesh{Point{3 ,Float64},Face{3 ,Int}},
292
+ eps= 0.00001 ) where {ST,FT,M<: AbstractMesh }
292
293
nx, ny, nz = size (sdf)
293
294
h = HyperRectangle (sdf)
294
295
w = widths (h)
295
- s = Point {3,Float64} (w[1 ]/ nx, w[2 ]/ ny, w[3 ]/ nz)
296
+ orig = origin (HyperRectangle (sdf))
297
+
298
+ # we subtract one from the length along each axis because
299
+ # an NxNxN SDF has N-1 cells on each axis
300
+ s = Point {3,Float64} (w[1 ]/ (nx- 1 ), w[2 ]/ (ny- 1 ), w[3 ]/ (nz- 1 ))
296
301
297
302
# arrays for vertices and faces
298
303
vts = Point{3 ,Float64}[]
@@ -315,63 +320,63 @@ function marching_cubes(sdf::SignedDistanceField{3,ST,FT},
315
320
# Cube is entirely in/out of the surface
316
321
edge_table[cubeindex] == 0 && continue
317
322
318
- points = (Point {3,Float64} (xi- 1 ,yi- 1 ,zi- 1 ).* s ,
319
- Point {3,Float64} (xi,yi- 1 ,zi- 1 ).* s ,
320
- Point {3,Float64} (xi,yi,zi- 1 ).* s ,
321
- Point {3,Float64} (xi- 1 ,yi,zi- 1 ).* s ,
322
- Point {3,Float64} (xi- 1 ,yi- 1 ,zi).* s ,
323
- Point {3,Float64} (xi,yi- 1 ,zi).* s ,
324
- Point {3,Float64} (xi,yi,zi).* s ,
325
- Point {3,Float64} (xi- 1 ,yi,zi).* s )
323
+ points = (Point {3,Float64} (xi- 1 ,yi- 1 ,zi- 1 ) .* s .+ orig ,
324
+ Point {3,Float64} (xi,yi- 1 ,zi- 1 ) .* s .+ orig ,
325
+ Point {3,Float64} (xi,yi,zi- 1 ) .* s .+ orig ,
326
+ Point {3,Float64} (xi- 1 ,yi,zi- 1 ) .* s .+ orig ,
327
+ Point {3,Float64} (xi- 1 ,yi- 1 ,zi) .* s .+ orig ,
328
+ Point {3,Float64} (xi,yi- 1 ,zi) .* s .+ orig ,
329
+ Point {3,Float64} (xi,yi,zi) .* s .+ orig ,
330
+ Point {3,Float64} (xi- 1 ,yi,zi) .* s .+ orig )
326
331
327
332
# Find the vertices where the surface intersects the cube
328
333
if (edge_table[cubeindex] & 1 != 0 )
329
334
vertlist[1 ] =
330
- vertex_interp (iso,points[1 ],points[2 ],sdf[xi,yi,zi],sdf[xi+ 1 ,yi,zi])
335
+ vertex_interp (iso,points[1 ],points[2 ],sdf[xi,yi,zi],sdf[xi+ 1 ,yi,zi], eps )
331
336
end
332
337
if (edge_table[cubeindex] & 2 != 0 )
333
338
vertlist[2 ] =
334
- vertex_interp (iso,points[2 ],points[3 ],sdf[xi+ 1 ,yi,zi],sdf[xi+ 1 ,yi+ 1 ,zi])
339
+ vertex_interp (iso,points[2 ],points[3 ],sdf[xi+ 1 ,yi,zi],sdf[xi+ 1 ,yi+ 1 ,zi], eps )
335
340
end
336
341
if (edge_table[cubeindex] & 4 != 0 )
337
342
vertlist[3 ] =
338
- vertex_interp (iso,points[3 ],points[4 ],sdf[xi+ 1 ,yi+ 1 ,zi],sdf[xi,yi+ 1 ,zi])
343
+ vertex_interp (iso,points[3 ],points[4 ],sdf[xi+ 1 ,yi+ 1 ,zi],sdf[xi,yi+ 1 ,zi], eps )
339
344
end
340
345
if (edge_table[cubeindex] & 8 != 0 )
341
346
vertlist[4 ] =
342
- vertex_interp (iso,points[4 ],points[1 ],sdf[xi,yi+ 1 ,zi],sdf[xi,yi,zi])
347
+ vertex_interp (iso,points[4 ],points[1 ],sdf[xi,yi+ 1 ,zi],sdf[xi,yi,zi], eps )
343
348
end
344
349
if (edge_table[cubeindex] & 16 != 0 )
345
350
vertlist[5 ] =
346
- vertex_interp (iso,points[5 ],points[6 ],sdf[xi,yi,zi+ 1 ],sdf[xi+ 1 ,yi,zi+ 1 ])
351
+ vertex_interp (iso,points[5 ],points[6 ],sdf[xi,yi,zi+ 1 ],sdf[xi+ 1 ,yi,zi+ 1 ], eps )
347
352
end
348
353
if (edge_table[cubeindex] & 32 != 0 )
349
354
vertlist[6 ] =
350
- vertex_interp (iso,points[6 ],points[7 ],sdf[xi+ 1 ,yi,zi+ 1 ],sdf[xi+ 1 ,yi+ 1 ,zi+ 1 ])
355
+ vertex_interp (iso,points[6 ],points[7 ],sdf[xi+ 1 ,yi,zi+ 1 ],sdf[xi+ 1 ,yi+ 1 ,zi+ 1 ], eps )
351
356
end
352
357
if (edge_table[cubeindex] & 64 != 0 )
353
358
vertlist[7 ] =
354
- vertex_interp (iso,points[7 ],points[8 ],sdf[xi+ 1 ,yi+ 1 ,zi+ 1 ],sdf[xi,yi+ 1 ,zi+ 1 ])
359
+ vertex_interp (iso,points[7 ],points[8 ],sdf[xi+ 1 ,yi+ 1 ,zi+ 1 ],sdf[xi,yi+ 1 ,zi+ 1 ], eps )
355
360
end
356
361
if (edge_table[cubeindex] & 128 != 0 )
357
362
vertlist[8 ] =
358
- vertex_interp (iso,points[8 ],points[5 ],sdf[xi,yi+ 1 ,zi+ 1 ],sdf[xi,yi,zi+ 1 ])
363
+ vertex_interp (iso,points[8 ],points[5 ],sdf[xi,yi+ 1 ,zi+ 1 ],sdf[xi,yi,zi+ 1 ], eps )
359
364
end
360
365
if (edge_table[cubeindex] & 256 != 0 )
361
366
vertlist[9 ] =
362
- vertex_interp (iso,points[1 ],points[5 ],sdf[xi,yi,zi],sdf[xi,yi,zi+ 1 ])
367
+ vertex_interp (iso,points[1 ],points[5 ],sdf[xi,yi,zi],sdf[xi,yi,zi+ 1 ], eps )
363
368
end
364
369
if (edge_table[cubeindex] & 512 != 0 )
365
370
vertlist[10 ] =
366
- vertex_interp (iso,points[2 ],points[6 ],sdf[xi+ 1 ,yi,zi],sdf[xi+ 1 ,yi,zi+ 1 ])
371
+ vertex_interp (iso,points[2 ],points[6 ],sdf[xi+ 1 ,yi,zi],sdf[xi+ 1 ,yi,zi+ 1 ], eps )
367
372
end
368
373
if (edge_table[cubeindex] & 1024 != 0 )
369
374
vertlist[11 ] =
370
- vertex_interp (iso,points[3 ],points[7 ],sdf[xi+ 1 ,yi+ 1 ,zi],sdf[xi+ 1 ,yi+ 1 ,zi+ 1 ])
375
+ vertex_interp (iso,points[3 ],points[7 ],sdf[xi+ 1 ,yi+ 1 ,zi],sdf[xi+ 1 ,yi+ 1 ,zi+ 1 ], eps )
371
376
end
372
377
if (edge_table[cubeindex] & 2048 != 0 )
373
378
vertlist[12 ] =
374
- vertex_interp (iso,points[4 ],points[8 ],sdf[xi,yi+ 1 ,zi],sdf[xi,yi+ 1 ,zi+ 1 ])
379
+ vertex_interp (iso,points[4 ],points[8 ],sdf[xi,yi+ 1 ,zi],sdf[xi,yi+ 1 ,zi+ 1 ], eps )
375
380
end
376
381
377
382
# Create the triangle
@@ -399,3 +404,14 @@ function vertex_interp(iso, p1, p2, valp1, valp2, eps = 0.00001)
399
404
400
405
return p
401
406
end
407
+
408
+ struct MarchingCubes{T} <: AbstractMeshingAlgorithm
409
+ iso:: T
410
+ eps:: T
411
+ end
412
+
413
+ MarchingCubes (iso:: T1 = 0.0 , eps:: T2 = 1e-3 ) where {T1, T2} = MarchingCubes {promote_type(T1, T2)} (iso, eps)
414
+
415
+ function (:: Type{MT} )(df:: SignedDistanceField , method:: MarchingCubes ) where {MT <: AbstractMesh }
416
+ marching_cubes (df, method. iso, MT, method. eps)
417
+ end
0 commit comments