Skip to content

Commit

Permalink
Add tinyply 2.3 benchmarks
Browse files Browse the repository at this point in the history
Note; parsing of ASCII PLY files is not benchmarked as ASCII support in
tinyply 2.3 seems to be broken
(ddiakopoulos/tinyply#59).
  • Loading branch information
ton committed Jan 2, 2023
1 parent f03ee38 commit 60ac881
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "submodules/vcglib"]
path = submodules/vcglib
url = https://github.com/cnr-isti-vclab/vcglib
[submodule "submodules/tinyply"]
path = submodules/tinyply
url = https://github.com/ddiakopoulos/tinyply
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ add_library(msh_ply OBJECT
# and unit test applications.
add_library(PLYbench OBJECT
submodules/miniply/miniply.cpp
submodules/tinyply/source/tinyply.cpp
submodules/vcglib/wrap/ply/plylib.cpp
src/parsers.cpp
src/util.cpp
Expand Down
33 changes: 32 additions & 1 deletion src/parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
#include <happly/happly.h>
#include <miniply/miniply.h>
#include <rply/rply.h>
#include <tinyply/source/example-utils.hpp>
#include <tinyply/source/tinyply.h>
#include <vcglib/wrap/nanoply/include/nanoply.hpp>
#include <vcglib/wrap/ply/plylib.h>

#include <memory>
#include <optional>
#include <string>
#include <vcglib/wrap/nanoply/include/nanoply.hpp>
#include <vector>

std::optional<TriangleMesh> parseHapply(const std::string &filename)
Expand Down Expand Up @@ -326,3 +328,32 @@ std::optional<TriangleMesh> parseRPly(const std::string &filename)

return mesh;
}

std::optional<TriangleMesh> parseTinyply(const std::string &filename)
{
using namespace tinyply;

std::ifstream ifs(filename);

std::vector<uint8_t> buffer = read_file_binary(filename);
memory_stream is{(char *)buffer.data(), buffer.size()};

PlyFile file;
file.parse_header(is);

const std::shared_ptr<PlyData> vertices =
file.request_properties_from_element("vertex", {"x", "y", "z"});
const std::shared_ptr<PlyData> triangles =
file.request_properties_from_element("face", {"vertex_indices"}, 3);

file.read(is);

TriangleMesh mesh;
mesh.vertices.resize(vertices->count);
mesh.triangles.resize(triangles->count);

std::memcpy(mesh.vertices.data(), vertices->buffer.get(), vertices->buffer.size_bytes());
std::memcpy(mesh.triangles.data(), triangles->buffer.get(), triangles->buffer.size_bytes());

return mesh;
}
1 change: 1 addition & 0 deletions src/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ std::optional<TriangleMesh> parseNanoPly(const std::string &filename);
std::optional<TriangleMesh> parsePlyLib(const std::string &filename);
std::optional<TriangleMesh> parsePlywoot(const std::string &filename);
std::optional<TriangleMesh> parseRPly(const std::string &filename);
std::optional<TriangleMesh> parseTinyply(const std::string &filename);
37 changes: 37 additions & 0 deletions src/plybench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,33 @@ static void BM_WriteRPly(benchmark::State &state, Format format)
state.SetBytesProcessed(state.iterations() * meshSizeInBytes(mesh));
}

static void BM_ParseTinyply(benchmark::State &state, const std::string &filename)
{
benchmark::ClobberMemory();

std::optional<TriangleMesh> maybeMesh;
for (auto _ : state)
{
if (!(maybeMesh = parseTinyply(filename)))
state.SkipWithError((std::string{"could not parse '"} + filename + "' with tinyply").data());
}

if (maybeMesh) state.SetBytesProcessed(state.iterations() * meshSizeInBytes(*maybeMesh));
}

static void BM_WriteTinyply(benchmark::State &state, Format format)
{
benchmark::ClobberMemory();

const TriangleMesh mesh{createMesh()};
for (auto _ : state) { writeTinyply(mesh, format); }

state.SetBytesProcessed(state.iterations() * meshSizeInBytes(mesh));
}

// Note; tinyply 2.3 seems to be broken for ASCII
// (https://github.com/ddiakopoulos/tinyply/issues/59)

#define BENCHMARK_PARSE(name, filename) \
BENCHMARK_CAPTURE(BM_ParseHapply, (name), (filename))->Unit(benchmark::kMillisecond); \
BENCHMARK_CAPTURE(BM_ParseMiniply, (name), (filename))->Unit(benchmark::kMillisecond); \
Expand All @@ -174,9 +201,16 @@ static void BM_WriteRPly(benchmark::State &state, Format format)
BENCHMARK_CAPTURE(BM_ParseRPly, (name), (filename))->Unit(benchmark::kMillisecond);

BENCHMARK_PARSE("Asian Dragon (binary b/e)", "models/xyzrgb_dragon.ply")
BENCHMARK_CAPTURE(BM_ParseTinyply, "Asian Dragon (binary b/e)", "models/xyzrgb_dragon.ply")
->Unit(benchmark::kMillisecond);

BENCHMARK_PARSE("Lucy (binary b/e)", "models/lucy.ply");
BENCHMARK_CAPTURE(BM_ParseTinyply, "Lucy (binary b/e)", "models/lucy.ply")
->Unit(benchmark::kMillisecond);

BENCHMARK_PARSE("DOOM Combat Scene (binary l/e)", "models/Doom combat scene.ply");
BENCHMARK_CAPTURE(BM_ParseTinyply, "DOOM Combat Scene (binary l/e)", "models/Doom combat scene.ply")
->Unit(benchmark::kMillisecond);

BENCHMARK_PARSE("Dragon (ASCII)", "models/dragon_vrip.ply");
BENCHMARK_PARSE("Happy Buddha (ASCII)", "models/happy_vrip.ply");
Expand All @@ -197,5 +231,8 @@ BENCHMARK_CAPTURE(BM_WritePlywoot, "Binary", Format::BinaryLittleEndian)
BENCHMARK_CAPTURE(BM_WriteRPly, "ASCII", Format::Ascii)->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(BM_WriteRPly, "Binary", Format::BinaryLittleEndian)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(BM_WriteTinyply, "ASCII", Format::Ascii)->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(BM_WriteTinyply, "Binary", Format::BinaryLittleEndian)
->Unit(benchmark::kMillisecond);

BENCHMARK_MAIN();
27 changes: 26 additions & 1 deletion src/tests.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "mesh.h"
#include "mesh_ios.h"
#include "parsers.h"
#include "writers.h"
#include "util.h"
#include "writers.h"

#include <catch2/catch_session.hpp>
#include <catch2/catch_test_macros.hpp>
Expand Down Expand Up @@ -128,6 +128,20 @@ TEST_CASE("Verify parsers against PLYwoot")
}
}

// Note; tinyply 2.3 is broken for ASCII PLY files (see:
// https://github.com/ddiakopoulos/tinyply/issues/59).
TEST_CASE("Verify tinyply against PLYwoot")
{
auto filename = GENERATE("lucy.ply", "xyzrgb_dragon.ply", "Doom combat scene.ply");

const auto plywootMesh = parsePlywoot(std::string("models/") + filename);

auto mesh = parseTinyply(std::string("models/") + filename);

INFO(std::string{filename} + ": " + meshComparisonInfo(mesh, plywootMesh, "tinyply", "PLYwoot"));
CHECK(mesh == plywootMesh);
}

TEST_CASE("Test functionality of various writer libraries")
{
auto format = GENERATE(Format::Ascii, Format::BinaryLittleEndian);
Expand Down Expand Up @@ -188,6 +202,17 @@ TEST_CASE("Test functionality of various writer libraries")
REQUIRE(maybeMesh.has_value());
CHECK(mesh == *maybeMesh);
}

SECTION(std::string{"tinyply ("} + formatToString(format) + ')')
{
TemporaryFile tf = writeTinyply(mesh, format);
REQUIRE(bool(tf));
tf.stream().flush();

const std::optional<TriangleMesh> maybeMesh = parsePlywoot(tf.filename());
REQUIRE(maybeMesh.has_value());
CHECK(mesh == *maybeMesh);
}
}

int main(int argc, char *argv[]) { return Catch::Session().run(argc, argv); }
19 changes: 19 additions & 0 deletions src/writers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <happly/happly.h>
#include <miniply/miniply.h>
#include <rply/rply.h>
#include <tinyply/source/tinyply.h>
#include <vcglib/wrap/nanoply/include/nanoply.hpp>
#include <vcglib/wrap/ply/plylib.h>

Expand Down Expand Up @@ -217,3 +218,21 @@ TemporaryFile writeRPly(const TriangleMesh &mesh, Format format)

return tf;
}

TemporaryFile writeTinyply(const TriangleMesh &mesh, Format format)
{
TemporaryFile tf;

tinyply::PlyFile outFile;
outFile.add_properties_to_element(
"vertex", {"x", "y", "z"}, tinyply::Type::FLOAT32, mesh.vertices.size(),
reinterpret_cast<uint8_t *>(const_cast<Vertex *>(mesh.vertices.data())),
tinyply::Type::INVALID, 0);
outFile.add_properties_to_element(
"face", {"vertex_indices"}, tinyply::Type::UINT32, mesh.triangles.size(),
reinterpret_cast<uint8_t *>(const_cast<Triangle *>(mesh.triangles.data())),
tinyply::Type::UINT8, 3);
outFile.write(tf.stream(), format != Format::Ascii);

return tf;
}
1 change: 1 addition & 0 deletions src/writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ TemporaryFile writeMshPly(const TriangleMesh &mesh, Format format);
TemporaryFile writeNanoPly(const TriangleMesh &mesh, Format format);
TemporaryFile writePlywoot(const TriangleMesh &mesh, Format format);
TemporaryFile writeRPly(const TriangleMesh &mesh, Format format);
TemporaryFile writeTinyply(const TriangleMesh &mesh, Format format);
1 change: 1 addition & 0 deletions submodules/tinyply
Submodule tinyply added at 40aa4a

0 comments on commit 60ac881

Please sign in to comment.