23#ifndef VCL_IO_MESH_PLY_DETAIL_VERTEX_H
24#define VCL_IO_MESH_PLY_DETAIL_VERTEX_H
28#include <vclib/io/read.h>
29#include <vclib/io/write.h>
31#include <vclib/mesh.h>
33namespace vcl::detail {
35template<MeshConcept MeshType, VertexConcept VertexType,
typename Stream>
36void readPlyVertexProperty(
41 std::endian end = std::endian::little)
43 bool hasBeenRead =
false;
44 if (p.name >= ply::x && p.name <= ply::z) {
45 using Scalar = VertexType::PositionType::ScalarType;
46 int a = p.name - ply::x;
47 v.position()[a] = io::readPrimitiveType<Scalar>(file, p.type, end);
50 if (p.name >= ply::nx && p.name <= ply::nz) {
51 if constexpr (HasPerVertexNormal<MeshType>) {
52 if (isPerVertexNormalAvailable(mesh)) {
53 using Scalar = VertexType::NormalType::ScalarType;
54 int a = p.name - ply::nx;
56 io::readPrimitiveType<Scalar>(file, p.type, end);
61 if (p.name >= ply::red && p.name <= ply::alpha) {
62 if constexpr (HasPerVertexColor<MeshType>) {
63 if (isPerVertexColorAvailable(mesh)) {
64 int a = p.name - ply::red;
66 io::readPrimitiveType<unsigned char>(file, p.type, end);
71 if (p.name == ply::quality) {
72 if constexpr (HasPerVertexQuality<MeshType>) {
73 using QualityType = VertexType::QualityType;
74 if (isPerVertexQualityAvailable(mesh)) {
76 io::readPrimitiveType<QualityType>(file, p.type, end);
81 if (p.name >= ply::texture_u && p.name <= ply::texture_v) {
82 if constexpr (HasPerVertexTexCoord<MeshType>) {
83 using Scalar = VertexType::TexCoordType::ScalarType;
84 if (isPerVertexTexCoordAvailable(mesh)) {
85 int a = p.name - ply::texture_u;
87 io::readPrimitiveType<Scalar>(file, p.type, end);
92 if (p.name == ply::texnumber) {
93 if constexpr (HasPerVertexMaterialIndex<MeshType>) {
94 if (isPerVertexMaterialIndexAvailable(mesh)) {
96 io::readPrimitiveType<ushort>(file, p.type, end);
101 if (p.name == ply::unknown) {
102 if constexpr (HasPerVertexCustomComponents<MeshType>) {
103 if (mesh.hasPerVertexCustomComponent(p.unknownPropertyName)) {
104 io::readCustomComponent(
105 file, v, p.unknownPropertyName, p.type, end);
112 uint s = io::readPrimitiveType<int>(file, p.listSizeType);
113 for (uint i = 0; i < s; ++i)
114 io::readPrimitiveType<int>(file, p.type, end);
117 io::readPrimitiveType<int>(file, p.type, end);
122template<VertexConcept VertexType, MeshConcept MeshType>
123void readPlyVertexTxt(
127 const std::list<PlyProperty>& vertexProperties)
129 Tokenizer spaceTokenizer = readAndTokenizeNextNonEmptyLine(file);
130 Tokenizer::iterator token = spaceTokenizer.begin();
131 for (
const PlyProperty& p : vertexProperties) {
132 if (token == spaceTokenizer.end()) {
133 throw MalformedFileException(
"Unexpected end of line.");
135 readPlyVertexProperty(token, mesh, v, p);
139template<VertexConcept VertexType, MeshConcept MeshType>
140void readPlyVertexBin(
144 const std::list<PlyProperty>& vertexProperties,
147 for (
const PlyProperty& p : vertexProperties) {
148 readPlyVertexProperty(file, mesh, v, p, end);
152template<MeshConcept MeshType>
153void writePlyVertices(
155 const PlyHeader& header,
156 const MeshType& mesh)
158 using VertexType = MeshType::VertexType;
161 if (header.format() == ply::ASCII) {
162 format.isBinary =
false;
164 else if (header.format() == ply::BINARY_BIG_ENDIAN) {
165 format.endian = std::endian::big;
168 for (
const VertexType& v : mesh.
vertices()) {
169 for (
const PlyProperty& p : header.vertexProperties()) {
170 bool hasBeenWritten =
false;
171 if (p.name >= ply::x && p.name <= ply::z) {
173 file, v.position()[p.name - ply::x], p.type, format);
174 hasBeenWritten =
true;
176 if (p.name >= ply::nx && p.name <= ply::nz) {
177 if constexpr (HasPerVertexNormal<MeshType>) {
179 file, v.normal()[p.name - ply::nx], p.type, format);
180 hasBeenWritten =
true;
183 if (p.name >= ply::red && p.name <= ply::alpha) {
184 if constexpr (HasPerVertexColor<MeshType>) {
186 file, v.color()[p.name - ply::red], p.type, format);
187 hasBeenWritten =
true;
190 if (p.name == ply::quality) {
191 if constexpr (HasPerVertexQuality<MeshType>) {
192 io::writeProperty(file, v.quality(), p.type, format);
193 hasBeenWritten =
true;
196 if (p.name >= ply::texture_u && p.name <= ply::texture_v) {
197 if constexpr (HasPerVertexTexCoord<MeshType>) {
198 const uint a = p.name - ply::texture_u;
199 io::writeProperty(file, v.texCoord()[a], p.type, format);
200 hasBeenWritten =
true;
203 if (p.name == ply::texnumber) {
204 if constexpr (HasPerVertexMaterialIndex<MeshType>) {
205 io::writeProperty(file, v.materialIndex(), p.type, format);
206 hasBeenWritten =
true;
209 if (p.name == ply::unknown) {
210 if constexpr (HasPerVertexCustomComponents<MeshType>) {
211 if (mesh.hasPerVertexCustomComponent(
212 p.unknownPropertyName)) {
213 io::writeCustomComponent(
214 file, v, p.unknownPropertyName, p.type, format);
215 hasBeenWritten =
true;
219 if (!hasBeenWritten) {
222 io::writeProperty(file, 0, p.type, format);
225 if (!format.isBinary)
230template<MeshConcept MeshType, LoggerConcept LogType>
233 const PlyHeader& header,
237 m.addVertices(header.numberVertices());
239 log.startProgress(
"Reading vertices", header.numberVertices());
241 for (uint vid = 0; vid < header.numberVertices(); ++vid) {
242 auto& v = m.vertex(vid);
243 if (header.format() == ply::ASCII) {
244 detail::readPlyVertexTxt(file, v, m, header.vertexProperties());
247 std::endian end = header.format() == ply::BINARY_BIG_ENDIAN ?
250 detail::readPlyVertexBin(
251 file, v, m, header.vertexProperties(), end);
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:92