Skip to content

Commit

Permalink
Bring back support for PMP format
Browse files Browse the repository at this point in the history
  • Loading branch information
dsieger committed Oct 2, 2022
1 parent a54e93b commit 921d370
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 10 deletions.
5 changes: 5 additions & 0 deletions src/pmp/SurfaceMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -2022,6 +2022,11 @@ class SurfaceMesh
// are there any deleted entities?
inline bool has_garbage() const { return has_garbage_; }

// io functions that need access to internal details
friend void read_pmp(SurfaceMesh&, const std::string&);
friend void write_pmp(const SurfaceMesh&, const std::string&,
const IOFlags&);

// property containers for each entity type and object
PropertyContainer oprops_;
PropertyContainer vprops_;
Expand Down
18 changes: 12 additions & 6 deletions src/pmp/io/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@

#include "pmp/io/read_obj.h"
#include "pmp/io/read_off.h"
#include "pmp/io/read_pmp.h"
#include "pmp/io/read_stl.h"
#include "pmp/io/write_obj.h"
#include "pmp/io/write_off.h"
#include "pmp/io/write_pmp.h"
#include "pmp/io/write_stl.h"

namespace pmp {
Expand All @@ -25,10 +27,12 @@ void read(SurfaceMesh& mesh, const std::string& filename)
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);

// extension determines reader
if (ext == "off")
read_off(mesh, filename);
else if (ext == "obj")
if (ext == "obj")
read_obj(mesh, filename);
else if (ext == "off")
read_off(mesh, filename);
else if (ext == "pmp")
read_pmp(mesh, filename);
else if (ext == "stl")
read_stl(mesh, filename);
else
Expand All @@ -46,10 +50,12 @@ void write(const SurfaceMesh& mesh, const std::string& filename,
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);

// extension determines reader
if (ext == "off")
write_off(mesh, filename, flags);
else if (ext == "obj")
if (ext == "obj")
write_obj(mesh, filename, flags);
else if (ext == "off")
write_off(mesh, filename, flags);
else if (ext == "pmp")
write_pmp(mesh, filename, flags);
else if (ext == "stl")
write_stl(mesh, filename, flags);
else
Expand Down
10 changes: 6 additions & 4 deletions src/pmp/io/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ namespace pmp {
//!
//! Format | ASCII | Binary | Normals | Colors | Texcoords
//! -------|-------|--------|---------|--------|----------
//! OFF | yes | yes | a / b | a | a / b
//! OBJ | yes | no | a | no | no
//! OFF | yes | yes | a / b | a | a / b
//! PMP | no | yes | no | no | no
//! STL | yes | yes | no | no | no
//!
//! In addition, the OBJ supports reading per-halfedge
//! In addition, the OBJ and PMP formats support reading per-halfedge
//! texture coordinates.
//! \ingroup io
void read(SurfaceMesh& mesh, const std::string& filename);
Expand All @@ -31,11 +32,12 @@ void read(SurfaceMesh& mesh, const std::string& filename);
//!
//! Format | ASCII | Binary | Normals | Colors | Texcoords
//! -------|-------|--------|---------|--------|----------
//! OFF | yes | yes | a | a | a
//! OBJ | yes | no | a | no | no
//! OFF | yes | yes | a | a | a
//! PMP | no | yes | no | no | no
//! STL | yes | no | no | no | no
//!
//! In addition, the OBJ format supports writing per-halfedge
//! In addition, the OBJ and PMP formats support writing per-halfedge
//! texture coordinates.
//! \ingroup io
void write(const SurfaceMesh& mesh, const std::string& filename,
Expand Down
67 changes: 67 additions & 0 deletions src/pmp/io/read_pmp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2011-2022 the Polygon Mesh Processing Library developers.
// Distributed under a MIT-style license, see LICENSE.txt for details.

#include "pmp/io/read_pmp.h"

#include "pmp/io/helpers.h"

namespace pmp {

void read_pmp(SurfaceMesh& mesh, const std::string& filename)
{
// open file (in binary mode)
FILE* in = fopen(filename.c_str(), "rb");
if (!in)
throw IOException("Failed to open file: " + filename);

// how many elements?
unsigned int nv(0), ne(0), nh(0), nf(0);
tfread(in, nv);
tfread(in, ne);
tfread(in, nf);
nh = 2 * ne;

// texture coordinates?
bool has_htex(false);
tfread(in, has_htex);

// resize containers
mesh.vprops_.resize(nv);
mesh.hprops_.resize(nh);
mesh.eprops_.resize(ne);
mesh.fprops_.resize(nf);

// get properties
auto vconn =
mesh.vertex_property<SurfaceMesh::VertexConnectivity>("v:connectivity");
auto hconn = mesh.halfedge_property<SurfaceMesh::HalfedgeConnectivity>(
"h:connectivity");
auto fconn =
mesh.face_property<SurfaceMesh::FaceConnectivity>("f:connectivity");
auto point = mesh.vertex_property<Point>("v:point");

// read properties from file
size_t nvc = fread((char*)vconn.data(),
sizeof(SurfaceMesh::VertexConnectivity), nv, in);
size_t nhc = fread((char*)hconn.data(),
sizeof(SurfaceMesh::HalfedgeConnectivity), nh, in);
size_t nfc = fread((char*)fconn.data(),
sizeof(SurfaceMesh::FaceConnectivity), nf, in);
size_t np = fread((char*)point.data(), sizeof(Point), nv, in);
PMP_ASSERT(nvc == nv);
PMP_ASSERT(nhc == nh);
PMP_ASSERT(nfc == nf);
PMP_ASSERT(np == nv);

// read texture coordiantes
if (has_htex)
{
auto htex = mesh.halfedge_property<TexCoord>("h:tex");
size_t nhtc = fread((char*)htex.data(), sizeof(TexCoord), nh, in);
PMP_ASSERT(nhtc == nh);
}

fclose(in);
}

} // namespace pmp
14 changes: 14 additions & 0 deletions src/pmp/io/read_pmp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2011-2022 the Polygon Mesh Processing Library developers.
// Distributed under a MIT-style license, see LICENSE.txt for details.

#pragma once

#include <string>

#include "pmp/SurfaceMesh.h"

namespace pmp {

void read_pmp(SurfaceMesh& mesh, const std::string& filename);

} // namespace pmp
56 changes: 56 additions & 0 deletions src/pmp/io/write_pmp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2011-2022 the Polygon Mesh Processing Library developers.
// Distributed under a MIT-style license, see LICENSE.txt for details.

#include "pmp/io/write_pmp.h"
#include "pmp/Types.h"
#include "pmp/io/helpers.h"

namespace pmp {

void write_pmp(const SurfaceMesh& mesh, const std::string& filename,
const IOFlags&)
{
// open file (in binary mode)
FILE* out = fopen(filename.c_str(), "wb");
if (!out)
throw IOException("Failed to open file: " + filename);

// get properties
auto vconn = mesh.get_vertex_property<SurfaceMesh::VertexConnectivity>(
"v:connectivity");
auto hconn = mesh.get_halfedge_property<SurfaceMesh::HalfedgeConnectivity>(
"h:connectivity");
auto fconn =
mesh.get_face_property<SurfaceMesh::FaceConnectivity>("f:connectivity");
auto point = mesh.get_vertex_property<Point>("v:point");
auto htex = mesh.get_halfedge_property<TexCoord>("h:tex");

// how many elements?
unsigned int nv, ne, nh, nf;
nv = mesh.n_vertices();
ne = mesh.n_edges();
nh = mesh.n_halfedges();
nf = mesh.n_faces();

// write header
tfwrite(out, nv);
tfwrite(out, ne);
tfwrite(out, nf);
tfwrite(out, (bool)htex);

// write properties to file
fwrite((char*)vconn.data(), sizeof(SurfaceMesh::VertexConnectivity), nv,
out);
fwrite((char*)hconn.data(), sizeof(SurfaceMesh::HalfedgeConnectivity), nh,
out);
fwrite((char*)fconn.data(), sizeof(SurfaceMesh::FaceConnectivity), nf, out);
fwrite((char*)point.data(), sizeof(Point), nv, out);

// texture coordinates
if (htex)
fwrite((char*)htex.data(), sizeof(TexCoord), nh, out);

fclose(out);
}

} // namespace pmp
16 changes: 16 additions & 0 deletions src/pmp/io/write_pmp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2011-2022 the Polygon Mesh Processing Library developers.
// Distributed under a MIT-style license, see LICENSE.txt for details.

#pragma once

#include <string>

#include "pmp/SurfaceMesh.h"
#include "pmp/Types.h"

namespace pmp {

void write_pmp(SurfaceMesh& mesh, const std::string& filename,
const IOFlags& flags);

} // namespace pmp
14 changes: 14 additions & 0 deletions tests/IOTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ TEST_F(IOTest, off_io_binary)
EXPECT_EQ(mesh.n_faces(), size_t(1));
}

TEST_F(IOTest, pmp_io)
{
add_triangle();
write(mesh, "test.pmp");
mesh.clear();
EXPECT_TRUE(mesh.is_empty());
read(mesh, "test.pmp");
EXPECT_EQ(mesh.n_vertices(), size_t(3));
EXPECT_EQ(mesh.n_faces(), size_t(1));

// check malformed file names
EXPECT_THROW(write(mesh, "testpolyly"), IOException);
}

TEST_F(IOTest, stl_io)
{
read(mesh, "pmp-data/stl/icosahedron_ascii.stl");
Expand Down

0 comments on commit 921d370

Please sign in to comment.