scimesh
0.3.4
Headless CPU-only 3D software renderer for scientific mesh visualization
Loading...
Searching...
No Matches
ply_io.cpp
Go to the documentation of this file.
1
#define TINYPLY_IMPLEMENTATION
2
#include "tinyply.h"
3
#include <
scimesh/ply_io.h
>
4
#include <
scimesh/types.h
>
5
6
#include <fstream>
7
#include <stdexcept>
8
#include <algorithm>
9
#include <cstdint>
10
#include <cstring>
11
12
namespace
scimesh
{
13
namespace
ply_io {
14
15
namespace
{
16
21
float
read_alpha
(
const
tinyply::PlyData &data,
size_t
i
) {
22
const
uint8_t
*
raw
= data.buffer.get_const();
23
switch
(data.t) {
24
case
tinyply::Type::UINT8:
25
return
raw
[
i
] / 255.0f;
26
case
tinyply::Type::INT8: {
27
int8_t
v
= 0;
28
std::memcpy(&
v
,
raw
+
i
,
sizeof
(
v
));
29
return
std::max<int>(0,
v
) / 255.0f;
30
}
31
case
tinyply::Type::UINT16: {
32
uint16_t
v
= 0;
33
std::memcpy(&
v
,
raw
+
i
*
sizeof
(
v
),
sizeof
(
v
));
34
return
v
/ 65535.0f;
35
}
36
case
tinyply::Type::FLOAT32: {
37
float
v
= 0.0f;
38
std::memcpy(&
v
,
raw
+
i
*
sizeof
(
v
),
sizeof
(
v
));
39
return
v
;
40
}
41
default
:
42
return
1.0f;
43
}
44
}
45
46
}
// anonymous namespace
47
48
Mesh
read_ply
(
const
std::string &
path
) {
49
std::ifstream
ifs
(
path
, std::ios::binary);
50
if
(!
ifs
.good()) {
51
throw
std::runtime_error(
"Failed to open PLY file: "
+
path
);
52
}
53
54
tinyply::PlyFile
ply
;
55
ply
.parse_header(
ifs
);
56
57
bool
has_vertex_colors
=
false
;
58
bool
has_vertex_alpha
=
false
;
59
tinyply::Type
vertex_color_type
= tinyply::Type::UINT8;
60
for
(
const
auto
&
el
:
ply
.get_elements()) {
61
if
(
el
.name ==
"vertex"
) {
62
for
(
const
auto
&
prop
:
el
.properties) {
63
if
(
prop
.name ==
"red"
||
prop
.name ==
"green"
||
prop
.name ==
"blue"
) {
64
if
(!
has_vertex_colors
)
vertex_color_type
=
prop
.propertyType;
65
has_vertex_colors
=
true
;
66
}
else
if
(
prop
.name ==
"alpha"
) {
67
has_vertex_alpha
=
true
;
68
}
69
}
70
}
71
}
72
73
auto
vertices_data
=
ply
.request_properties_from_element(
"vertex"
, {
"x"
,
"y"
,
"z"
});
74
auto
faces_data
=
ply
.request_properties_from_element(
"face"
, {
"vertex_indices"
}, 3);
75
std::shared_ptr<tinyply::PlyData>
colors_data
;
76
if
(
has_vertex_colors
) {
77
colors_data
=
ply
.request_properties_from_element(
"vertex"
, {
"red"
,
"green"
,
"blue"
});
78
}
79
std::shared_ptr<tinyply::PlyData>
alpha_data
;
80
if
(
has_vertex_alpha
) {
81
// Requested separately from red/green/blue: tinyply requires all
82
// properties of one request to share the same type, and RGBA files
83
// commonly mix 8-bit color with float alpha.
84
alpha_data
=
ply
.request_properties_from_element(
"vertex"
, {
"alpha"
});
85
}
86
87
ply
.read(
ifs
);
88
89
Mesh
mesh;
90
const
size_t
num_vertices
=
vertices_data
->count;
91
mesh.
vertices
.resize(
num_vertices
);
92
93
const
float
*
vptr
=
reinterpret_cast<
const
float
*
>
(
vertices_data
->buffer.get_const());
94
for
(
size_t
i
= 0;
i
<
num_vertices
; ++
i
) {
95
mesh.
vertices
[
i
] =
Vec3
(
vptr
[
i
* 3],
vptr
[
i
* 3 + 1],
vptr
[
i
* 3 + 2]);
96
}
97
98
if
(
has_vertex_colors
&&
colors_data
) {
99
mesh.
colors
.resize(
num_vertices
);
100
if
(
vertex_color_type
== tinyply::Type::UINT8) {
101
const
uint8_t
*
cptr
=
reinterpret_cast<
const
uint8_t
*
>
(
colors_data
->buffer.get_const());
102
for
(
size_t
i
= 0;
i
<
num_vertices
; ++
i
) {
103
mesh.
colors
[
i
] =
Color
(
104
cptr
[
i
* 3] / 255.0f,
105
cptr
[
i
* 3 + 1] / 255.0f,
106
cptr
[
i
* 3 + 2] / 255.0f,
107
alpha_data
?
read_alpha
(*
alpha_data
,
i
) : 1.0f);
108
}
109
}
else
if
(
vertex_color_type
== tinyply::Type::FLOAT32) {
110
const
float
*
cptr
=
reinterpret_cast<
const
float
*
>
(
colors_data
->buffer.get_const());
111
for
(
size_t
i
= 0;
i
<
num_vertices
; ++
i
) {
112
mesh.
colors
[
i
] =
Color
(
cptr
[
i
* 3],
cptr
[
i
* 3 + 1],
cptr
[
i
* 3 + 2],
113
alpha_data
?
read_alpha
(*
alpha_data
,
i
) : 1.0f);
114
}
115
}
else
if
(
alpha_data
) {
116
// No usable RGB type, but the file does carry alpha: keep the
117
// transparency information rather than dropping it silently.
118
for
(
size_t
i
= 0;
i
<
num_vertices
; ++
i
) {
119
mesh.
colors
[
i
] =
Color
(1.0f, 1.0f, 1.0f,
read_alpha
(*
alpha_data
,
i
));
120
}
121
}
122
}
else
if
(
alpha_data
) {
123
// Alpha without any color: white vertices with the file's alpha.
124
mesh.
colors
.resize(
num_vertices
);
125
for
(
size_t
i
= 0;
i
<
num_vertices
; ++
i
) {
126
mesh.
colors
[
i
] =
Color
(1.0f, 1.0f, 1.0f,
read_alpha
(*
alpha_data
,
i
));
127
}
128
}
129
130
const
size_t
num_faces
=
faces_data
->count;
131
mesh.
triangles
.resize(
num_faces
);
132
const
int32_t
*
fptr
=
reinterpret_cast<
const
int32_t
*
>
(
faces_data
->buffer.get_const());
133
for
(
size_t
i
= 0;
i
<
num_faces
; ++
i
) {
134
mesh.
triangles
[
i
] =
Triangle
{
135
static_cast<
uint32_t
>
(
fptr
[
i
* 3]),
136
static_cast<
uint32_t
>
(
fptr
[
i
* 3 + 1]),
137
static_cast<
uint32_t
>
(
fptr
[
i
* 3 + 2])};
138
}
139
140
// Keep Mesh::has_transparency in sync with the colors we just read.
141
mesh.
update_transparency
();
142
143
return
mesh;
144
}
145
146
}
// namespace ply_io
147
}
// namespace scimesh
scimesh::ply_io::read_ply
Mesh read_ply(const std::string &path)
Load a mesh from a Stanford PLY file.
Definition
ply_io.cpp:48
scimesh
Definition
camera.cpp:8
scimesh::Vec3
glm::vec3 Vec3
3-component floating-point vector (xyz).
Definition
types.h:46
ply_io.h
Read Stanford PLY files (.ply).
scimesh::Color
An RGBA color with floating-point components.
Definition
types.h:88
scimesh::Mesh
A 3D triangle mesh using an indexed face set representation.
Definition
mesh.h:76
scimesh::Mesh::update_transparency
void update_transparency()
Recompute has_transparency from the mesh's colors.
Definition
mesh.h:256
scimesh::Mesh::colors
std::vector< Color > colors
Per-vertex RGBA colors.
Definition
mesh.h:107
scimesh::Mesh::vertices
std::vector< Vec3 > vertices
3D vertex positions.
Definition
mesh.h:86
scimesh::Mesh::triangles
std::vector< Triangle > triangles
Triangle index triplets.
Definition
mesh.h:94
scimesh::Triangle
A triangle defined by three vertex indices.
Definition
types.h:127
x
int x
Left edge of the bitmap, in image pixels.
Definition
text.cpp:223
types.h
Fundamental types used throughout the scimesh rendering engine.
src
core
ply_io.cpp
Generated by
1.9.8