Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sjk/nodep2 #96

Merged
merged 3 commits into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions bench/Project.toml

This file was deleted.

27 changes: 0 additions & 27 deletions bench/iso_masjk.jl

This file was deleted.

3 changes: 1 addition & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ makedocs(
modules = [Meshing],
pages = ["Index" => "index.md",
"API" => "api.md",
"Examples" => "examples.md",
"Internals" => "internals.md"]
"Examples" => "examples.md"]
)

deploydocs(
Expand Down
32 changes: 1 addition & 31 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,6 @@ A = rand(50,50,50) # 3D Matrix
points,faces = isosurface(A, MarchingCubes(iso=1))
```

Alternatively, we can use the `isosurface` API to sample a function, avoiding allocations:

```julia
using Meshing
using LinearAlgebra
using StaticArrays

points, faces = isosurface(origin=SVector(-1,-1,-1.), widths = SVector(2,2,2.), samples = (40,40,40)) do v
sqrt(sum(dot(v,v))) - 1
end

# by default MarchingCubes() is used, but we may specify a different algorithm as follows

points, faces = isosurface(MarchingTetrahedra(), origin=SVector(-1,-1,-1.), widths = SVector(2,2,2.), samples = (40,40,40)) do v
sqrt(sum(dot(v,v))) - 1
end
```

## Isosurface

`isosurface` is the common and generic API for isosurface extraction with any type of abstract vector/vertex/face type.
Expand All @@ -48,30 +30,19 @@ end
isosurface
```


## Meshing Algorithms

Three meshing algorithms exist:

* `MarchingCubes()`
* `MarchingTetrahedra()`
* `NaiveSurfaceNets()`

Each takes optional `iso`, `eps`, and `insidepositive` parameters, e.g. `MarchingCubes(iso=0.0,eps=1e-6,insidepositive=false)`.
Each takes optional `iso` and `eps` parameters, e.g. `MarchingCubes(iso=0.0,eps=1e-6)`.

Here `iso` controls the offset for the boundary detection. By default this is set to 0. `eps` is the detection tolerance for a voxel edge intersection.
`insidepositive` sets the sign convention for inside/outside the surface (default: false).

Users must construct an algorithm type and use it as an argument to a GeometryTypes mesh call or `isosurface` call.

Below is a comparison of the algorithms:

| Algorithm Type | Face Type | Unique Vertices | Performance | Interpolation |
|---------------------|-----------|-----------------|-------------|-------------------|
| Naive Surface Nets | Quad | Yes | ~1x | Voxel Edge Weight |
| Marching Cubes | Triangle | No/Partial | 1x | Linear on Edge |
| Marching Tetrahedra | Triangle | Yes | 3x | Linear on Edge |

Visual Comparison:
From left: Marching Cubes, Naive Surface Nets, Marching Tetrahedra

Expand All @@ -80,6 +51,5 @@ From left: Marching Cubes, Naive Surface Nets, Marching Tetrahedra
```@docs
MarchingCubes
MarchingTetrahedra
NaiveSurfaceNets
Meshing.AbstractMeshingAlgorithm
```
65 changes: 15 additions & 50 deletions docs/src/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,29 @@
The file for this example can be found here: [http://www.slicer.org/slicerWiki/images/0/00/CTA-cardio.nrrd](http://www.slicer.org/slicerWiki/images/0/00/CTA-cardio.nrrd)

```julia

using Meshing
using FileIO
using NRRD
using Meshing
using MeshIO
using WGLMakie
using Downloads
using GeometryBasics

nrrd = Downloads.download("http://www.slicer.org/slicerWiki/images/0/00/CTA-cardio.nrrd")

# load the file as an AxisArray
ctacardio = load("CTA-cardio.nrrd")
ctacardio = load(nrrd)

# use marching cubes with isolevel at 100
algo = MarchingCubes(iso=100, insidepositive=true)
#algo = MarchingCubes(iso=100)
# use marching tetrahedra with iso at 100
# algo = MarchingTetrahedra(iso=100, insidepositive=true)
# use Naive Surface Nets with iso at 100
# algo = NaiveSurfaceNets(iso=100, insidepositive=true)
algo = MarchingTetrahedra(iso=100)


# generate the mesh using marching cubes
mc = Mesh(ctacardio, algo)
vts, fcs = isosurface(ctacardio, algo)

# we can call isosurface to get a vector of points and vector of faces indexing to the points
# vertices, faces = isosurface(ctacardio, algo, Point{3,Float32}, TriangleFace{Int})
WGLMakie.mesh(vts, map(v -> GeometryBasics.TriangleFace(v...), fcs))

# save the file as a PLY file (change extension to save as STL, OBJ, OFF)
save("ctacardio_mc.ply", mc)
```

![cta cardio](./img/ctacardio.png)
Expand Down Expand Up @@ -60,44 +58,11 @@ Makie.mesh(gy_mesh, color=[norm(v) for v in coordinates(gy_mesh)])
![gyroid](./img/gyroid.png)


```julia
using Meshing
using GeometryBasics
using LinearAlgebra: dot, norm
using FileIO

# Mesh an equation of sphere in the Axis-Aligned Bounding box starting
# at -1,-1,-1 and widths of 2,2,2 using Marching Cubes
m = GLNormalMesh(Rect(Vec(-1,-1,-1.), Vec(2,2,2.)), MarchingCubes()) do v
sqrt(sum(dot(v,v))) - 1
end

# save the Sphere as a PLY file
save("sphere.ply",m)
```

For a full listing of concrete `AbstractMesh` types see [GeometryBasics.jl mesh documentation](http://juliageometry.github.io/GeometryBasics.jl/latest/types.html#Meshes-1).

Alternatively, we can use the `isosurface` API to sample a function:

```julia
using Meshing
using LinearAlgebra
using StaticArrays

points, faces = isosurface(origin=SVector(-1,-1,-1.), widths = SVector(2,2,2.), samples = (40,40,40)) do v
sqrt(sum(dot(v,v))) - 1
end

# by default MarchingCubes() is used, but we may specify a different algorithm as follows

points, faces = isosurface(MarchingTetrahedra(), origin=SVector(-1,-1,-1.), widths = SVector(2,2,2.), samples = (40,40,40)) do v
sqrt(sum(dot(v,v))) - 1
end
```

## Isocaps

We do not provide an equivalent to `isocaps` in Matlab, though
a similar result may be achieved by setting the boundary to a large value:

```julia
using GeometryTypes

Expand All @@ -120,4 +85,4 @@ gy_mesh = GLNormalMesh(A, MarchingCubes())
import Makie
using LinearAlgebra
Makie.mesh(gy_mesh, color=[norm(v) for v in gy_mesh.vertices])
```
```
1 change: 0 additions & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Algorithms included:

* [Marching Tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra)
* [Marching Cubes](https://en.wikipedia.org/wiki/Marching_cubes)
* [Naive Surface Nets](https://0fps.net/2012/07/12/smooth-voxel-terrain-part-2/)

## What is isosurface extraction?

Expand Down
58 changes: 0 additions & 58 deletions docs/src/internals.md

This file was deleted.

10 changes: 1 addition & 9 deletions src/Meshing.jl
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
module Meshing

"""
_DEFAULT_SAMPLES = (24,24,24)

Global default sampling count for functions.
"""
const _DEFAULT_SAMPLES = (24,24,24)

include("algorithmtypes.jl")
include("common.jl")
include("marching_tetrahedra.jl")
include("marching_cubes.jl")
include("roots.jl")
include("adaptive.jl")
include("isosurface.jl")

export isosurface,
MarchingCubes,
Expand Down
Loading
Loading