JuliaIO / MeshIO.jl

IO for Meshes
Other
79 stars 31 forks source link

README.md claims that this works with `Meshes.jl`; this seems incorrect #67

Closed plut closed 1 year ago

plut commented 3 years ago

According to README.md, mesh manipulating functions are in Meshes.jl. However, this package actually uses GeometryBasics.jl (only). Both packages are not compatible with each other (I tried).

felipeek commented 2 years 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)
HaoxuanGuo commented 2 years ago

Thanks for @felipeek . Here is an MeshBridge now.

sjkelly commented 2 years ago

For reference, the README was referring to https://github.com/JuliaGeometry/OldMeshes.jl/

HaoxuanGuo commented 2 years ago

Would it have a plan to switch to new MeshIO.jl ?

mfsch commented 1 year ago

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