13 std::ifstream ifs(path, std::ios::binary);
15 throw std::runtime_error(
"Failed to open PLY file: " + path);
19 ply.parse_header(ifs);
21 bool has_vertex_colors =
false;
22 tinyply::Type vertex_color_type = tinyply::Type::UINT8;
23 for (
const auto &el : ply.get_elements()) {
24 if (el.name ==
"vertex") {
25 for (
const auto &prop : el.properties) {
26 if (prop.name ==
"red" || prop.name ==
"green" || prop.name ==
"blue") {
27 has_vertex_colors =
true;
28 vertex_color_type = prop.propertyType;
35 auto vertices_data = ply.request_properties_from_element(
"vertex", {
"x",
"y",
"z"});
36 auto faces_data = ply.request_properties_from_element(
"face", {
"vertex_indices"}, 3);
37 std::shared_ptr<tinyply::PlyData> colors_data;
38 if (has_vertex_colors) {
39 colors_data = ply.request_properties_from_element(
"vertex", {
"red",
"green",
"blue"});
45 const size_t num_vertices = vertices_data->count;
48 const float *vptr =
reinterpret_cast<const float *
>(vertices_data->buffer.get_const());
49 for (
size_t i = 0; i < num_vertices; ++i) {
50 mesh.
vertices[i] =
Vec3(vptr[i * 3], vptr[i * 3 + 1], vptr[i * 3 + 2]);
53 if (has_vertex_colors && colors_data) {
54 mesh.
colors.resize(num_vertices);
55 if (vertex_color_type == tinyply::Type::UINT8) {
56 const uint8_t *cptr =
reinterpret_cast<const uint8_t *
>(colors_data->buffer.get_const());
57 for (
size_t i = 0; i < num_vertices; ++i) {
60 cptr[i * 3 + 1] / 255.0f,
61 cptr[i * 3 + 2] / 255.0f,
64 }
else if (vertex_color_type == tinyply::Type::FLOAT32) {
65 const float *cptr =
reinterpret_cast<const float *
>(colors_data->buffer.get_const());
66 for (
size_t i = 0; i < num_vertices; ++i) {
67 mesh.
colors[i] =
Color(cptr[i * 3], cptr[i * 3 + 1], cptr[i * 3 + 2], 1.0f);
72 const size_t num_faces = faces_data->count;
74 const int32_t *fptr =
reinterpret_cast<const int32_t *
>(faces_data->buffer.get_const());
75 for (
size_t i = 0; i < num_faces; ++i) {
77 static_cast<uint32_t
>(fptr[i * 3]),
78 static_cast<uint32_t
>(fptr[i * 3 + 1]),
79 static_cast<uint32_t
>(fptr[i * 3 + 2])};