juliageometry / meshing.jl Goto Github PK
View Code? Open in Web Editor NEWMeshing and isosurface extraction algorithms
License: Other
Meshing and isosurface extraction algorithms
License: Other
Any objections to me tagging a v0.1.0 release (which will add Julia v0.6 support and drop Julia v0.5)?
The NRRD format is commonly used for dicom data exports. The NRRD FileIO loader produces an axis array, which is similar to the SDF format, but significantly more mature and feature-rich. In order to be useful for the julia medical/imaging communities, it might be good to have support for Axis Arrays to make the pipeline to a mesh far simpler.
Does this package have documentation? Where can I find it?
Hi, I have this method for extracting plane cuts and isosurfaces from general tetmeshes:
The output can also creates a GeometryBasics.Mesh which can be used with Makie:
There is also "marching_triangles" for isoline calculation.
In the moment, these are not exported, but they are used by other packages (PlutoVista.jl) or projects (@jlchan). Logically, they should reside outside of GridVisualize.jl, and I have the impression that Meshing.jl could be the right place (though I find the package name a bit misleading...). So before creating another package I would like to discuss to move these into Meshing.jl and export them.
A couple of points:
How do you look at this ?
After digging into Contour and discussing with some collaborators, the isosurface(x,y,z, V)
idiom is somewhat common. Moreso those coming from Matlab, but there are other benefits. One could apply a rotation to the points before meshing occurs and retain the signed distance array/levelset.
I apologize if this is the wrong place for this issue. I pulled this MWE from the tests so that runs on Meshing#master but doesn't plot.
julia> A = rand(20,20,20);
julia> m = GeometryBasics.mesh(A,MarchingTetrahedra(1.0),origin=Point(Float32(0),Float32(0),Float32(0)),widths=Point(
Float32(1),Float32(1),Float32(1)));
julia> Makie.mesh(m)
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
┌ Warning: limits of scene contain non finite values: Float32[Inf, Inf, Inf] .. Float32[NaN, NaN, NaN]
└ @ AbstractPlotting ~/.julia/packages/AbstractPlotting/jOgYQ/src/scenes.jl:586
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
┌ Warning: No strict ticks found
└ @ PlotUtils ~/.julia/packages/PlotUtils/Zg3aP/src/ticks.jl:283
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
ArgumentError: At least one finite value must be provided to formatter.with ticks: [-Inf, Inf]
1 : #version 410
2 :
3 :
4 : in dvec3 vertices;
5 : uniform vec4 vertex_color;
6 : uniform vec2 texturecoordinates;
7 : in vec3 normals;
8 :
9 : uniform vec3 lightposition;
10 : uniform mat4 projection, view, model;
11 : void render(vec4 vertices, vec3 normals, mat4 viewmodel, mat4 projection, vec3 lightposition);
12 :
13 : uniform uint objectid;
14 : flat out uvec2 o_id;
15 : out vec2 o_uv;
16 : out vec4 o_color;
17 :
18 : vec3 to_3d(vec2 v){return vec3(v, 0);}
19 : vec3 to_3d(vec3 v){return v;}
20 :
21 : vec2 to_2d(float v){return vec2(v, 0);}
22 : vec2 to_2d(vec2 v){return v;}
23 :
24 : vec4 to_color(vec3 c){return vec4(c, 1);}
25 : vec4 to_color(vec4 c){return c;}
26 :
27 : void main()
28 : {
29 : o_id = uvec2(objectid, gl_VertexID+1);
30 : vec2 tex_uv = to_2d(texturecoordinates);
31 : o_uv = vec2(1.0 - tex_uv.y, tex_uv.x);
32 : o_color = to_color(vertex_color);
33 : vec3 v = to_3d(vertices);
34 : render(model * vec4(v, 1), (model * vec4(normals, 0)).xyz, view, projection, lightposition);
35 : }
36 :
┌ Warning: shader /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/GLVisualize/assets/shader/standard.vert didn'
t compile.
│ ERROR: 0:33: No matching function for call to to_3d(dvec3)
│ ERROR: 0:34: Use of undeclared identifier 'v'
└ @ GLMakie.GLAbstraction ~/.julia/packages/GLMakie/S9Zib/src/GLAbstraction/GLShader.jl:139
1 : #version 410
2 :
3 :
4 : in dvec3 vertices;
5 : uniform vec4 vertex_color;
6 : uniform vec2 texturecoordinates;
7 : in vec3 normals;
8 :
9 : uniform vec3 lightposition;
10 : uniform mat4 projection, view, model;
11 : void render(vec4 vertices, vec3 normals, mat4 viewmodel, mat4 projection, vec3 lightposition);
12 :
13 : uniform uint objectid;
14 : flat out uvec2 o_id;
15 : out vec2 o_uv;
16 : out vec4 o_color;
17 :
18 : vec3 to_3d(vec2 v){return vec3(v, 0);}
19 : vec3 to_3d(vec3 v){return v;}
20 :
21 : vec2 to_2d(float v){return vec2(v, 0);}
22 : vec2 to_2d(vec2 v){return v;}
23 :
24 : vec4 to_color(vec3 c){return vec4(c, 1);}
25 : vec4 to_color(vec4 c){return c;}
26 :
27 : void main()
28 : {
29 : o_id = uvec2(objectid, gl_VertexID+1);
30 : vec2 tex_uv = to_2d(texturecoordinates);
31 : o_uv = vec2(1.0 - tex_uv.y, tex_uv.x);
32 : o_color = to_color(vertex_color);
33 : vec3 v = to_3d(vertices);
34 : render(model * vec4(v, 1), (model * vec4(normals, 0)).xyz, view, projection, lightposition);
35 : }
36 :
┌ Warning: shader /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/GLVisualize/assets/shader/standard.vert didn'
t compile.
│ ERROR: 0:33: No matching function for call to to_3d(dvec3)
│ ERROR: 0:34: Use of undeclared identifier 'v'
└ @ GLMakie.GLAbstraction ~/.julia/packages/GLMakie/S9Zib/src/GLAbstraction/GLShader.jl:139
Error showing value of type Scene:
ERROR: program 34 not linked. Error in:
/Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/GLVisualize/assets/shader/fragment_output.frag or /Users/zchris
tensen/.julia/packages/GLMakie/S9Zib/src/GLVisualize/assets/shader/util.vert or /Users/zchristensen/.julia/packages/G
LMakie/S9Zib/src/GLVisualize/assets/shader/standard.vert or /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/GLV
isualize/assets/shader/standard.frag
ERROR: One or more attached shaders not successfully compiled
Stacktrace:
[1] error(::String, ::String, ::String, ::String) at ./error.jl:42
[2] compile_program(::Array{GLMakie.GLAbstraction.Shader,1}, ::Array{Tuple{Int64,String},1}) at /Users/zchristensen/
.julia/packages/GLMakie/S9Zib/src/GLAbstraction/GLShader.jl:197
[3] (::GLMakie.GLAbstraction.var"#62#67"{Dict{Symbol,Any},NTuple{4,String},Dict{String,String},Array{Array{String,1}
,1},Array{Array{String,1},1}})() at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/GLAbstraction/GLShader.jl:2
62
[4] get!(::GLMakie.GLAbstraction.var"#62#67"{Dict{Symbol,Any},NTuple{4,String},Dict{String,String},Array{Array{Strin
g,1},1},Array{Array{String,1},1}}, ::Dict{Any,GLMakie.GLAbstraction.GLProgram}, ::Tuple{NTuple{4,String},Array{Array{
String,1},1}}) at ./dict.jl:452
[5] gl_convert(::GLMakie.GLVisualize.GLVisualizeShader, ::Dict{Symbol,Any}) at /Users/zchristensen/.julia/packages/G
LMakie/S9Zib/src/GLAbstraction/GLShader.jl:254
[6] GLMakie.GLAbstraction.RenderObject(::Dict{Symbol,Any}, ::GLMakie.GLVisualize.GLVisualizeShader, ::GLMakie.GLAbst
raction.StandardPrerender, ::Nothing, ::GeometryBasics.HyperRectangle{3,Float32}, ::Nothing) at /Users/zchristensen/.
julia/packages/GLMakie/S9Zib/src/GLAbstraction/GLTypes.jl:327
[7] assemble_robj(::Dict{Symbol,Any}, ::GLMakie.GLVisualize.GLVisualizeShader, ::GeometryBasics.HyperRectangle{3,Flo
at32}, ::UInt32, ::Nothing, ::Nothing) at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/GLVisualize/visualize
_interface.jl:96
[8] assemble_shader(::Dict{Symbol,Any}) at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/GLVisualize/visuali
ze_interface.jl:117
[9] visualize(::Any, ::Any, ::Any) at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/GLVisualize/visualize_in
terface.jl:166
[10] (::GLMakie.var"#108#112"{Mesh{...}})(::Dict{Symbol,Any}) at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/s
rc/drawing_primitives.jl:384
[11] (::GLMakie.var"#56#63"{GLMakie.var"#108#112"{Mesh{...}},GLMakie.Screen,Scene,Mesh{...}})() at /Users/zchristens
en/.julia/packages/GLMakie/S9Zib/src/drawing_primitives.jl:68
[12] get!(::GLMakie.var"#56#63"{GLMakie.var"#108#112"{Mesh{...}},GLMakie.Screen,Scene,Mesh{...}}, ::Dict{UInt64,GLMa
kie.GLAbstraction.RenderObject}, ::UInt64) at ./dict.jl:452
[13] cached_robj!(::GLMakie.var"#108#112"{Mesh{...}}, ::GLMakie.Screen, ::Scene, ::Mesh{...}) at /Users/zchristensen
/.julia/packages/GLMakie/S9Zib/src/drawing_primitives.jl:41
[14] draw_atomic at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/drawing_primitives.jl:349 [inlined]
[15] insert!(::GLMakie.Screen, ::Scene, ::Mesh{...}) at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/drawin
g_primitives.jl:158
[16] insertplots!(::GLMakie.Screen, ::Scene) at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/screen.jl:53
[17] backend_display(::GLMakie.Screen, ::Scene) at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/screen.jl:1
23
[18] backend_display at /Users/zchristensen/.julia/packages/GLMakie/S9Zib/src/gl_backend.jl:59 [inlined]
[19] display(::AbstractPlotting.PlotDisplay, ::Scene) at /Users/zchristensen/.julia/packages/AbstractPlotting/jOgYQ/
src/display.jl:45
[20] display(::Any) at ./multimedia.jl:323
[21] #invokelatest#1 at ./essentials.jl:712 [inlined]
[22] invokelatest at ./essentials.jl:711 [inlined]
[23] print_response(::IO, ::Any, ::Bool, ::Bool, ::Any) at /Users/julia/buildbot/worker/package_macos64/build/usr/sh
are/julia/stdlib/v1.4/REPL/src/REPL.jl:161
[24] print_response(::REPL.AbstractREPL, ::Any, ::Bool, ::Bool) at /Users/julia/buildbot/worker/package_macos64/buil
d/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:146
[25] (::REPL.var"#do_respond#38"{Bool,REPL.var"#48#57"{REPL.LineEditREPL,REPL.REPLHistoryProvider},REPL.LineEditREPL
,REPL.LineEdit.Prompt})(::Any, ::Any, ::Any) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/st
dlib/v1.4/REPL/src/REPL.jl:729
[26] #invokelatest#1 at ./essentials.jl:712 [inlined]
[27] invokelatest at ./essentials.jl:711 [inlined]
[28] run_interface(::REPL.Terminals.TextTerminal, ::REPL.LineEdit.ModalInterface, ::REPL.LineEdit.MIState) at /Users
/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.4/REPL/src/LineEdit.jl:2354
[29] run_frontend(::REPL.LineEditREPL, ::REPL.REPLBackendRef) at /Users/julia/buildbot/worker/package_macos64/build/
usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:1055
[30] run_repl(::REPL.AbstractREPL, ::Any) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdl
ib/v1.4/REPL/src/REPL.jl:206
[31] (::Base.var"#764#766"{Bool,Bool,Bool,Bool})(::Module) at ./client.jl:383
[32] #invokelatest#1 at ./essentials.jl:712 [inlined]
[33] invokelatest at ./essentials.jl:711 [inlined]
[34] run_main_repl(::Bool, ::Bool, ::Bool, ::Bool, ::Bool) at ./client.jl:367
[35] exec_options(::Base.JLOptions) at ./client.jl:305
[36] _start() at ./client.jl:484
When I run the first example in https://juliageometry.github.io/Meshing.jl/dev/api/#Quick-Start-GeometryBasics-1 using the following code https://gist.github.com/jlchan/833c7b085149500bbd2e79c7a227cf07, I get an error.
ERROR: LoadError: MethodError: no method matching (AbstractMesh{GeometryBasics.Ngon{Dim, Float32, 3, PointMeta{Dim, Float32, Pointf{Dim}, (:normals,), Tuple{Vec{3, Float32}}}}} where Dim)(::var"#15#16", ::Rect3{Float64}, ::MarchingCubes{Float64})
Stacktrace:
[1] top-level scope
@ ~/Downloads/test.jl:9
in expression starting at /Users/jessechan/Downloads/test.jl:9
I'm using Julia 1.6.3 if that helps.
It would be helpful to have some basic benchmarks to aid optimizations.
So isosurface(A)
will just work.
isosurface
?)Currently GeometryTypes has to also be imported to even call the Meshing functions. A non-type pirate variant of the function would allow this. The intneral of MarchingTetrahedra use an isosurface function
There are three options.
(Vector{SVector}, Vector{SVector})
(Vector{Point}, Vector{Face})
SimpleMesh
With the work to make the internals more generic, I think the first could be a good default, with an option for the second with different function arguments. Construction of a mesh from (Vector{Point}, Vector{Face})
is trivial and fast.
This is part of the above. MarchingTetrahedra
will take a 3D array rather than SDF. This should allow simple compatibility with Medical imagry, NRRD/AxisArrays without direct dependence on these packages.
Some of the NRRD data (all?) I have encountered uses positive signs for the interior of the isosurface. This should be a switch in all functions.
For clarity, the docs should be finished before tag.
This came up on slack. In some cases a user may always want a manifold surface from the isosurface extraction routing. We can generate "isocaps" that close the ends of the surface where it intersect with the bounding box to ensure that the surface is manifold for 3d printing or visualization of cross sections.
Currently each algorithm has its own mechanism for interpolating the edge crossing in a voxel. It may be useful in some visualization paradigms to just deliver the midpoint in each scenario for higher performance. Conversely, in the function variants we can use root finding for even higher precision.
These need to be brought over here.
I'm new, so sorry if this is known. I'm on JuliaPro, have cloned 0.5.4 after 0.5.3 in the package repository didn't work but I still get:
LoadError: MethodError: no method matching AbstractArray{GeometryBasics.Ngon{Dim,Float32,3,PointMeta{Dim,Float32,Point{Dim,Float32},(:normals,),Tuple{Vec{3,Float32}}}},1} where Dim(::var"#13#14", ::GeometryBasics.HyperRectangle{3,Float64}, ::MarchingCubes{Float64})
I have been thinking about a good way to allow for congruity of SDF types and Mesh types. Part of the current issue is that one may generate an SDF using Float32, but the internal computations for Meshing are Float64 converted back to Float32. Similarly, all direct samplings of a function pass Float64.
Geometry Types exports facetype
and vertextype
. These can be used to determine the sampling/interpolation types. If vertextype
is nothing, in the case of an SDF we will use a Point
of the same type as the sampling data.
If neither are specified, such as just calling HomogenousMesh(x -> norm(dot(x)) - 1, MarchingCubes())
we default to Float32 points for performance and better GPU interop.
TODO: In the case of faces I am not sure if Int32 or Int64 for Faces is preferable for GPU/Makie/Plots.
Normals:
I think there are mechanism for specifying normals in Geometry types. Since we may add ForwardDiff in the future for root finding, the computation of true normals on a smooth function should be possible to do in one pass.
There does not currently seem to be a constructor for HomogenousMesh with just the vertex and face arrays as inputs, causing this error message:
ERROR: LoadError: MethodError: `convert` has no method matching convert(::Type{GeometryTypes.HomogenousMesh{FixedSizeArrays.Point{3,Float64},GeometryTypes.Face{3,Int64,0},NormalT,TexCoordT,ColorT,AttribT,AttribIDT}}, ::Array{FixedSizeArrays.Point{3,Float64},1}, ::Array{GeometryTypes.Face{3,Int64,0},1}, ::Array{Any,1}, ::Array{Any,1}, ::Type{Void}, ::Type{Void}, ::Array{Any,1})
This may have arisen from a call to the constructor GeometryTypes.HomogenousMesh{FixedSizeArrays.Point{3,Float64},GeometryTypes.Face{3,Int64,0},NormalT,TexCoordT,ColorT,AttribT,AttribIDT}(...),
since type constructors fall back to convert methods.
Closest candidates are:
call{T<:GeometryTypes.AbstractMesh{VertT,FaceT}}(::Type{T<:GeometryTypes.AbstractMesh{VertT,FaceT}}, !Matched::GeometryTypes.GeometryPrimitive{N,T}, ::Any...)
call{M<:GeometryTypes.HomogenousMesh{VertT,FaceT,NormalT,TexCoordT,ColorT,AttribT,AttribIDT},VT,FT<:GeometryTypes.Face{N,T,IndexOffset}}(::Type{M<:GeometryTypes.HomogenousMesh{VertT,FaceT,NormalT,TexCoordT,ColorT,AttribT,AttribIDT}}, ::Array{FixedSizeArrays.Point{3,VT},1}, ::Array{FT<:GeometryTypes.Face{N,T,IndexOffset},1})
call{HM<:GeometryTypes.HomogenousMesh{VertT,FaceT,NormalT,TexCoordT,ColorT,AttribT,AttribIDT},ConstAttrib}(::Type{HM<:GeometryTypes.HomogenousMesh{VertT,FaceT,NormalT,TexCoordT,ColorT,AttribT,AttribIDT}}, !Matched::GeometryTypes.AbstractMesh{VertT,FaceT}, ::ConstAttrib)
...
in marching_cubes at /Users/james/.julia/v0.4/Meshing/src/marching_cubes.jl:386
in marching_cubes at /Users/james/.julia/v0.4/Meshing/src/marching_cubes.jl:292
in include at /Applications/Julia-0.4.5.app/Contents/Resources/julia/lib/julia/sys.dylib
in include_from_node1 at /Applications/Julia-0.4.5.app/Contents/Resources/julia/lib/julia/sys.dylib
in process_options at /Applications/Julia-0.4.5.app/Contents/Resources/julia/lib/julia/sys.dylib
in _start at /Applications/Julia-0.4.5.app/Contents/Resources/julia/lib/julia/sys.dylib
while loading /Users/james/.julia/v0.4/Meshing/test/runtests.jl, in expression starting on line 40
The tag name "0.2.0" is not of the appropriate SemVer form (vX.Y.Z).
cc: @rdeits
using Meshing
using GeometryTypes
using LinearAlgebra: dot, norm
using FileIO
f(v) = sqrt(sum(dot(v,v))) - 1
sdf = SignedDistanceField(f,HyperRectangle(Vec(-1,-1,-1.), Vec(2,2,2.)))
mc = HomogenousMesh(sdf, MarchingCubes())
mt = HomogenousMesh(sdf, MarchingTetrahedra())
ns = HomogenousMesh(sdf, NaiveSurfaceNets())
# save the Sphere as a PLY file
save("sphere_mc.ply",mc)
save("sphere_mt.ply",mt)
save("sphere_ns.ply",ns)
Recently I started using Meshing.isosurface()
, with MarchingCubes as method. The docs say that
setting reduceverts=true
(default: true) will merge vertices within a voxel to reduce mesh size by around 30%
and with slight performance improvement.
I called both Meshing.isosurface()
and skimage.measure.marching_cubes_lewiner()
, a Python function from scikit-image,
to extrude a brain within a volumetric data of size (91, 109, 91).
The number of vertices of the corresponding mesh, returned by Meshing function is (345752) almost 4 times greater
than that returned by skimage function (86473).
345752/86473 = 3.99, i.e. it is exaggerated.
Here are the two blocks of code:
using Meshing
using NPZ
brain_vol = npzread("MNI152.npy") # https://github.com/empet/Datasets/blob/master/MNI152.npy
verts, triangles = isosurface(brain_vol, MarchingCubes(iso=1.25, reduceverts=true, eps=1e-05))
length(verts), length(triangles)
(345752, 172932)
#unique vertices:
uni_verts = unique(i -> verts[i], 1:length(verts))
length(uni_verts)
89264
respectively:
import numpy as np
from skimage import measure
brain_vol= np.load("MNI152.npy")
verts, triangles = measure.marching_cubes_lewiner(brain_vol, 1.25)[:2]
len(verts), len(triangles)
(86473, 173070)
The corresponding Jupyter Notebook has the size of 111MB, vs 25MB, when using Python scikit-image.
Otherwise the mesh plot is great in both cases:
via slack:
julia> GLNormalMesh(A,MarchingTetrahedra(1.0),origin=Point(Float32(0),Float32(0),Float32(0)),widths=Point(Float32(1),Float32(1),Float32(1)))
ERROR: MethodError: no method matching isosurface(::Array{Float64,3}, ::MarchingTetrahedra{Float64}, ::Type{Point{3,Float32}}, ::Type{Face{3,OffsetInteger{-1,UInt32}}}, ::Pair{Symbol,Point{3,Float32}}, ::Pair{Symbol,Point{3,Float32}})
Closest candidates are:
isosurface(::AbstractArray{T,3}, ::MarchingTetrahedra, ::Type{VertType}, ::Type{FaceType}; origin, widths) where {T, VertType, FaceType} at C:\Users\kd2cc\.julia\dev\Meshing\src\marching_tetrahedra.jl:138
isosurface(::AbstractArray{T,3}, ::MarchingTetrahedra, ::Type{VertType}) where {T, VertType} at C:\Users\kd2cc\.julia\dev\Meshing\src\marching_tetrahedra.jl:138
isosurface(::AbstractArray{T,3}, ::MarchingCubes, ::Type{VertType}, ::Type{FaceType}; origin, widths) where {T, VertType, FaceType} at C:\Users\kd2cc\.julia\dev\Meshing\src\marching_cubes.jl:14
Under 0.7, linux ubunu
julia> versioninfo()
Julia Version 0.7.1-pre.0
Commit 36cddc1006 (2018-08-09 00:19 UTC)
Platform Info:
OS: Linux (x86_64-unknown-linux-gnu)
CPU: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.0 (ORCJIT, skylake)
Environment:
JULIA_DIR = $HOME/Julia/julia
JULIADEFAULTVERSION = 0.7
JULIACURRENTVERSION = 0.7
JULIAPYTHON =$HOME/.julia/packages/Conda/m7vem/deps/usr/bin/python2.7
JULIACONDA = $HOME/.julia/packages/Conda/m7vem/deps/usr/bin/conda
JULIACONDA_DIR = $HOME/.julia/packages/Conda/m7vem/deps/usr/
JULIAPYTHON_DIR = $HOME/.julia/packages/Conda/m7vem/deps/usr/bin/
JULIA_NUM_THREADS = 4
testing Meshing
produces internal errors (while tests are passed successfully)
(v0.7) pkg> test Meshing
Testing Meshing
Resolving package versions...
Status `/tmp/tmp0YFuw9/Manifest.toml`
[9e28174c] BinDeps v0.8.10
[b99e7846] BinaryProvider v0.4.2
[3da002f7] ColorTypes v0.7.4
[bbf7d656] CommonSubexpressions v0.2.0
[34da2185] Compat v1.1.0
[163ba53b] DiffResults v0.0.3
[b552c78f] DiffRules v0.0.7
[53c48c17] FixedPointNumbers v0.5.2
[f6369f11] ForwardDiff v0.7.5
[4d00f742] GeometryTypes v0.6.2
[c8e1da08] IterTools v1.0.0
[e6723b4c] Meshing v0.4.0
[77ba4419] NaNMath v0.3.2
[276daf66] SpecialFunctions v0.7.0
[90137ffa] StaticArrays v0.8.3
[30578b45] URIParser v0.4.0
[2a0f44e3] Base64 [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Base64`]
[ade2ca70] Dates [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Dates`]
[8bb1440f] DelimitedFiles [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/DelimitedFiles`]
[8ba89e20] Distributed [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Distributed`]
[b77e0a4c] InteractiveUtils [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/InteractiveUtils`]
[76f85450] LibGit2 [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/LibGit2`]
[8f399da3] Libdl [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Libdl`]
[37e2e46d] LinearAlgebra [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/LinearAlgebra`]
[56ddb016] Logging [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Logging`]
[d6f4376e] Markdown [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Markdown`]
[a63ad114] Mmap [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Mmap`]
[44cfe95a] Pkg [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Pkg`]
[de0858da] Printf [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Printf`]
[9abbd945] Profile [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Profile`]
[3fa0cd96] REPL [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/REPL`]
[9a3f8284] Random [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Random`]
[ea8e919c] SHA [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/SHA`]
[9e88b42a] Serialization [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Serialization`]
[1a1011a3] SharedArrays [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/SharedArrays`]
[6462fe0b] Sockets [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Sockets`]
[2f01184e] SparseArrays [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/SparseArrays`]
[10745b16] Statistics [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Statistics`]
[8dfed614] Test [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Test`]
[cf7118a7] UUIDs [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/UUIDs`]
[4ec0a83e] Unicode [`~/Julia/julia-release-0.7/usr/bin/../share/julia/stdlib/v0.7/Unicode`]
Internal error: encountered unexpected error in runtime:
TypeError(func=:<:, context="", expected=Type{T} where T, got=_)
rec_backtrace at $HOME/Julia/julia-release-0.7/src/stackwalk.c:94
record_backtrace at $HOME/Julia/julia-release-0.7/src/task.c:246
jl_throw at $HOME/Julia/julia-release-0.7/src/task.c:577
jl_type_error_rt at $HOME/Julia/julia-release-0.7/src/rtutils.c:118
jl_type_error at $HOME/Julia/julia-release-0.7/src/rtutils.c:124
jl_f_issubtype at $HOME/Julia/julia-release-0.7/src/builtins.c:414
...
We have mostly relied on the GeometryTypes API to generate normals. In GB we can do the same, but we shouldn't fix the calls to Mesh
. E.g. GLNormalMesh3D
should work.
Similarly I have been getting good results using autodiff to make normals on functions, so it would be nice to have an explicit API for passing a normal function to the meshing process.
The example given in README
using Meshing
using GeometryTypes
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
m = GLNormalMesh(HyperRectangle(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)
causes the following error
MethodError: no method matching GLNormalMesh(::getfield(Main, Symbol("##3#4")), ::HyperRectangle{3,Float64}, ::MarchingCubes{Float64})
Closest candidates are:
GLNormalMesh(::Any, ::Any, ::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any) where {VertT, FaceT, NormalT, TexCoordT, ColorT, AttribT, AttribIDT} at /home/jgraw/.julia/packages/GeometryTypes/ETYtg/src/types.jl:167
GLNormalMesh(!Matched::GeometryPrimitive, ::Any...) where T<:AbstractMesh at /home/jgraw/.julia/packages/GeometryTypes/ETYtg/src/primitives.jl:14
GLNormalMesh(!Matched::AbstractMesh, ::ConstAttrib) where {HM<:HomogenousMesh, ConstAttrib} at /home/jgraw/.julia/packages/GeometryTypes/ETYtg/src/meshes.jl:132
...
Apparently, GLNormalMesh
does not provide the convenience of constructing a SignedDistanceField automatically. Constructing the SDF manually works:
using Meshing
using GeometryTypes
using LinearAlgebra
using FileIO
# Mesh an equation of sphere in the Axis-Aligned Bounding box starting
# at -1,-1,-1 and widths of 2,2,2
sdf = SignedDistanceField(HyperRectangle(Vec3f0(-1), Vec3f0(2))) do v
return v ⋅ v - 1
end
m = GLNormalMesh(sdf, MarchingTetrahedra())
# save the Sphere as a PLY file
save("sphere.ply", m)
In addition the example requires MeshIO.jl
which should be noted as a prerequisite for the example.
Hello I´m trying to mesh a 3d object that I have as a triangulated surface (each face is given by 3 points), here is an example of how it looks like:
I want to get a 3d mesh with tetrahedron of the whole volume to model the internal mass distribution. I thought that maybe this package would do the trick, but reading carefully the documentation provided I currently understand that this is only possible if you have an implicit function of the surface that encloses the 3d body (using the SignedDistanceField
function). Am I wrong in this supposition or there is more functionality to Meshing.jl?
Caused by #35. In this case I was loading an NRRD file with Int16 data, which is not handled by the current system well.
ERROR: LoadError: InexactError: Int16(0.019569471624266144)
...
[7] marching_cubes(::GeometryTypes.SignedDistanceField{3,Int64,Int16},
::Type{GeometryTypes.Point{3,Int16}}, ::Type{GeometryTypes.Face{3,Int64}}, ::Float64,
::Type{GeometryTypes.HomogenousMesh}, ::Float64, ::Bool) at /home/steve/.julia/dev/Meshing/src/marching_cubes.jl:33
It might be good to make this a warning with deference to Float64.
This seems to have supplanted marching cubes in VTK as it is significantly more performant.
Hello,
I am using Meshing to create hypercomplex fractals and high dimension cellular automata
Is it possible to have the isosurface as simple squares perpendicular to the axes(so draw rectangular boxes, no other gradients)? If this is possible, can we parallelize it?
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
I think we should support AdaptiveDistanceFields: https://github.com/rdeits/AdaptiveDistanceFields.jl
@rdeits is this something you have tried? Any guidance would be appreciated.
Hello. I am currently using MarchingCubes
and MarchingTetrahedra
.
I would like to know the order of points in a face. In order word, Is that counter-clock wise or clock wise with respect to normal vector?
Thank you for your time in advance.
Is this the right package to calculate this? Can you post a simple example?
I like what the package does, I really do. The name, however, promises too much. "Meshing" seems to say "I do meshing". This implies not only producing meshes in different dimensions (boundary and interior of domains), but also producing meshes with some guarantees on shape (in some measure: aspect ratios, dihedral angles, ...).
Perhaps this is coming, but if not, then the name is slightly misleading.
From what I can tell this should be possible in at least MarchingCubes and NaiveSurfaceNets. There are some other optimizations from the NaiveSurfaceNet implementation I would also like to apply to MarchingCubes and Marching Tetrahedra.
applying marching_cubes
to an SignedDistanceField over a HyperRectangle, the resulting vertices ignore the origin of the HyperRectangle, resulting in result shifted by that origin :/
The following works fine:
HomogenousMesh(SignedDistanceField(HyperRectangle(Vec(0,0,0), Vec(1, 1, 1)),
randn(10, 10, 10)))
This one doesn't:
HomogenousMesh(SignedDistanceField(HyperRectangle(Vec(0,0,0), Vec(1, 1, 1)),
randn(Float32, 10, 10, 10)))
I get the following error:
MethodError: no method matching marchingTetrahedra(::Array{Float32,3}, ::Float64, ::Float64, ::Type{Int64})
Closest candidates are:
marchingTetrahedra{T<:Real,IT<:Integer}(::AbstractArray{T<:Real,3}, ::T<:Real, ::T<:Real, ::Type{IT<:Integer})
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.