@@ -287,12 +287,17 @@ However it may generate non-manifold meshes, while Marching
287287Tetrahedra guarentees a manifold mesh.
288288"""
289289function 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 }
292293 nx, ny, nz = size (sdf)
293294 h = HyperRectangle (sdf)
294295 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 ))
296301
297302 # arrays for vertices and faces
298303 vts = Point{3 ,Float64}[]
@@ -315,63 +320,63 @@ function marching_cubes(sdf::SignedDistanceField{3,ST,FT},
315320 # Cube is entirely in/out of the surface
316321 edge_table[cubeindex] == 0 && continue
317322
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 )
326331
327332 # Find the vertices where the surface intersects the cube
328333 if (edge_table[cubeindex] & 1 != 0 )
329334 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 )
331336 end
332337 if (edge_table[cubeindex] & 2 != 0 )
333338 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 )
335340 end
336341 if (edge_table[cubeindex] & 4 != 0 )
337342 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 )
339344 end
340345 if (edge_table[cubeindex] & 8 != 0 )
341346 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 )
343348 end
344349 if (edge_table[cubeindex] & 16 != 0 )
345350 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 )
347352 end
348353 if (edge_table[cubeindex] & 32 != 0 )
349354 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 )
351356 end
352357 if (edge_table[cubeindex] & 64 != 0 )
353358 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 )
355360 end
356361 if (edge_table[cubeindex] & 128 != 0 )
357362 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 )
359364 end
360365 if (edge_table[cubeindex] & 256 != 0 )
361366 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 )
363368 end
364369 if (edge_table[cubeindex] & 512 != 0 )
365370 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 )
367372 end
368373 if (edge_table[cubeindex] & 1024 != 0 )
369374 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 )
371376 end
372377 if (edge_table[cubeindex] & 2048 != 0 )
373378 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 )
375380 end
376381
377382 # Create the triangle
@@ -399,3 +404,14 @@ function vertex_interp(iso, p1, p2, valp1, valp2, eps = 0.00001)
399404
400405 return p
401406end
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 ):: MT where {MT <: AbstractMesh }
416+ marching_cubes (df, method. iso, MT, method. eps)
417+ end
0 commit comments