Skip to content

Commit

Permalink
update for FaceView
Browse files Browse the repository at this point in the history
  • Loading branch information
ffreyer committed Sep 12, 2024
1 parent 7658f18 commit 78f443b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/io/ifs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function load(fs::Stream{format"IFS"}; facetype=GLTriangleFace, pointtype=Point3
nfaces = read(io, UInt32)
faces_int = read(io, UInt32, nfaces * 3)
faces = reinterpret(facetype, faces_int)
return GeometryBasics.mesh(vertices = verts, faces = faces)
return GeometryBasics.Mesh(verts, faces)
end

function save(fs::Stream{format"IFS"}, msh::AbstractMesh; meshname = "mesh")
Expand Down
34 changes: 18 additions & 16 deletions src/io/obj.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace,
pointtype=Point3f, normaltype=Vec3f, uvtype=Any)

points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], Any[]
points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], facetype[]
f_uv_n_faces = (faces, facetype[], facetype[])

for full_line in eachline(stream(io))
# read a line, remove newline and leading/trailing whitespaces
Expand Down Expand Up @@ -41,32 +42,28 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace,
elseif "f" == command # mesh always has faces
if any(x-> occursin("//", x), lines)
fs = process_face_normal(lines)
pos_faces = triangulated_faces(facetype, getindex.(fs, 1))
normal_faces = triangulated_faces(facetype, getindex.(fs, 2))
append!(faces, GeometryBasics.NormalFace.(pos_faces, normal_faces))

elseif any(x-> occursin("/", x), lines)
fs = process_face_uv_or_normal(lines)
pos_faces = triangulated_faces(facetype, getindex.(fs, 1))
uv_faces = triangulated_faces(facetype, getindex.(fs, 2))
if length(fs[1]) == 2
append!(faces, GeometryBasics.UVFace.(pos_faces, uv_faces))
else
normal_faces = triangulated_faces(facetype, getindex.(fs, 3))
append!(faces, GeometryBasics.UVNormalFace.(pos_faces, uv_faces, normal_faces))
end
else
append!(faces, triangulated_faces(facetype, lines))
continue
end
for i = 1:length(first(fs))
append!(f_uv_n_faces[i], triangulated_faces(facetype, getindex.(fs, i)))
end
else
#TODO
end
end
end

# TODO: Can we avoid this conversion?
# Also, is it safe to do? Or can an obj file define different face types for different groups?
faces = convert(Vector{typeof(first(faces))}, faces)
if !isempty(f_uv_n_faces[2]) && (f_uv_n_faces[2] != faces)
uv = FaceView(uv, f_uv_n_faces[2])
end

if !isempty(f_uv_n_faces[3]) && (f_uv_n_faces[3] != faces)
v_normals = FaceView(v_normals, f_uv_n_faces[3])
end

return GeometryBasics.mesh(
points, faces, facetype = facetype;
Expand All @@ -92,6 +89,11 @@ function _typemax(::Type{OffsetInteger{O, T}}) where {O, T}
end

function save(f::Stream{format"OBJ"}, mesh::AbstractMesh)
# TODO: allow saving with faceviews (i.e. build the / or // syntax)
if any(v -> v isa FaceView, values(vertex_attributes(mesh)))
mesh = GeometryBasics.clear_faceviews(mesh)
end

io = stream(f)
for p in decompose(Point3f, mesh)
println(io, "v ", p[1], " ", p[2], " ", p[3])
Expand Down
20 changes: 11 additions & 9 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ using Test
const tf = joinpath(dirname(@__FILE__), "testfiles")
using MeshIO

using GeometryBasics: GLNormalMesh

function test_face_indices(mesh)
for face in faces(mesh)
for index in face
Expand All @@ -23,8 +21,8 @@ end
Rect3f(Vec3f(baselen), Vec3f(baselen, dirlen, baselen)),
Rect3f(Vec3f(baselen), Vec3f(baselen, baselen, dirlen))
]
uvn_mesh = merge(map(uv_normal_mesh, mesh))
mesh = merge(map(triangle_mesh, mesh))
uvn_mesh = GeometryBasics.clear_faceviews(merge(map(uv_normal_mesh, mesh)))
mesh = GeometryBasics.clear_faceviews(merge(map(triangle_mesh, mesh)))
empty!(uvn_mesh.views)
empty!(mesh.views)

Expand Down Expand Up @@ -70,7 +68,8 @@ end
@test test_face_indices(msh)

msh = load(joinpath(tf, "binary.stl"))
@test msh isa GLNormalMesh
@test msh isa Mesh{D, Float32, GLTriangleFace} where D
@test all(v -> v isa AbstractVector, values(vertex_attributes(msh)))
@test length(faces(msh)) == 828
@test length(coordinates(msh)) == 2484
@test length(normals(msh)) == 2484
Expand All @@ -79,14 +78,16 @@ end
mktempdir() do tmpdir
save(File{format"STL_BINARY"}(joinpath(tmpdir, "test.stl")), msh)
msh1 = load(joinpath(tmpdir, "test.stl"))
@test msh1 isa GLNormalMesh
@test msh1 isa Mesh{D, Float32, GLTriangleFace} where D
@test all(v -> v isa AbstractVector, values(vertex_attributes(msh1)))
@test faces(msh) == faces(msh1)
@test coordinates(msh) == coordinates(msh1)
@test normals(msh) == normals(msh1)
end

msh = load(joinpath(tf, "binary_stl_from_solidworks.STL"))
@test msh isa GLNormalMesh
@test msh isa Mesh{D, Float32, GLTriangleFace} where D
@test all(v -> v isa AbstractVector, values(vertex_attributes(msh)))
@test length(faces(msh)) == 12
@test length(coordinates(msh)) == 36
@test test_face_indices(msh)
Expand Down Expand Up @@ -139,8 +140,9 @@ end
@testset "OBJ" begin
msh = load(joinpath(tf, "test.obj"))
@test length(faces(msh)) == 3954
@test length(coordinates(msh)) == 2519
@test length(normals(msh)) == 2519
@test length(coordinates(msh)) == 2248
@test length(normals(msh)) == 2240
@test length(texturecoordinates(msh)) == 2220
@test test_face_indices(msh)

msh = load(joinpath(tf, "cube.obj")) # quads
Expand Down

0 comments on commit 78f443b

Please sign in to comment.