Closed plut closed 1 year ago
Meshes.jl
allows the creation of SimpleMeshes by providing an array of points and a topology definition. However, it seems that even though this package loads the mesh into a separate point list and triangle list, the triangle list is built in such a way that the triangles do not point to the point list, instead, they define new points... This approach does not make much sense to me, but I may be missing something since I just started working with Julia.
Anyway, this is a brute force approach that one can use to load the mesh into Meshes.jl
:
mesh = load("../data/bunny.obj")
faces = []
for triangle in mesh
i1 = findfirst(isequal(triangle[1]), mesh.position)
i2 = findfirst(isequal(triangle[2]), mesh.position)
i3 = findfirst(isequal(triangle[3]), mesh.position)
push!(faces, (i1, i2, i3))
end
topology = FullTopology(connect.(faces))
result = SimpleMesh([Point([x[1], x[2], x[3]]) for x in mesh.position], topology)
Note that I am manually searching each point position in the point list, which is very inefficient. It would be nice if the package owners could present an optimized way of doing this.
@edit: This is a more performant way of doing it:
mesh = load("../data/bunny.obj")
vertexToIdx = Dict()
for i = 1:length(mesh.position)
vertex = mesh.position[i]
@assert !haskey(vertexToIdx, vertex) # duplicated vertices
vertexToIdx[vertex] = i
end
faces = []
for triangle in mesh
i1 = vertexToIdx[triangle[1]]
i2 = vertexToIdx[triangle[2]]
i3 = vertexToIdx[triangle[3]]
push!(faces, (i1, i2, i3))
end
topology = FullTopology(connect.(faces))
result = SimpleMesh([Point([x[1], x[2], x[3]]) for x in mesh.position], topology)
Thanks for @felipeek . Here is an MeshBridge now.
For reference, the README was referring to https://github.com/JuliaGeometry/OldMeshes.jl/
Would it have a plan to switch to new MeshIO.jl ?
The code by @felipeek didn’t work for me, since I had duplicate vertices when loading an STL file. In case anyone else has this issue, here’s a simple version that works fine:
function loadmesh(path)
mesh = FileIO.load(path)
points = [Tuple(p) for p in Set(mesh.position)]
indices = Dict(p => i for (i, p) in enumerate(points))
connectivities = map(mesh) do el
Meshes.connect(Tuple(indices[Tuple(p)] for p in el))
end
Meshes.SimpleMesh(points, connectivities)
end
According to
README.md
, mesh manipulating functions are inMeshes.jl
. However, this package actually usesGeometryBasics.jl
(only). Both packages are not compatible with each other (I tried).