23#ifndef VCL_LOAD_SAVE_PLY_DETAIL_TRISTRIP_H
24#define VCL_LOAD_SAVE_PLY_DETAIL_TRISTRIP_H
28#include <vclib/io/read.h>
29#include <vclib/misc/tokenizer.h>
33namespace vcl::detail {
35template<FaceMeshConcept MeshType>
36void facesFromPlyTriStrip(MeshType& m,
const std::vector<int>& tristrip)
38 using FaceType = MeshType::FaceType;
40 bool firstOddPos =
false;
41 for (uint k = 0; k < tristrip.size() - 2; ++k) {
42 if (tristrip[k + 2] < 0) {
50 uint fid = m.addFace();
51 FaceType& f = m.face(fid);
52 if constexpr (FaceType::VERTEX_NUMBER < 0) {
55 for (uint i = 0; i < f.vertexNumber(); ++i) {
56 f.setVertex(i, tristrip[k + i]);
59 if (k % 2 == 0 != firstOddPos) {
60 auto* tmp = f.vertex(0);
61 f.setVertex(0U, f.vertex(1));
68template<FaceMeshConcept MeshType>
69void readPlyTriStripsTxt(
71 const PlyHeader& header,
74 for (uint tid = 0; tid < header.numberTriStrips(); ++tid) {
75 Tokenizer spaceTokenizer = readAndTokenizeNextNonEmptyLine(file);
76 Tokenizer::iterator token = spaceTokenizer.begin();
77 for (
const PlyProperty& p : header.triStripsProperties()) {
78 if (token == spaceTokenizer.end()) {
79 throw MalformedFileException(
"Unexpected end of line.");
81 bool hasBeenRead =
false;
82 if (p.name == ply::vertex_indices) {
83 uint tSize = io::readPrimitiveType<uint>(token, p.listSizeType);
84 std::vector<int> tristrip(tSize);
85 for (uint i = 0; i < tSize; ++i) {
86 tristrip[i] = io::readPrimitiveType<size_t>(token, p.type);
89 facesFromPlyTriStrip(m, tristrip);
93 uint s = io::readPrimitiveType<int>(token, p.listSizeType);
94 for (uint i = 0; i < s; ++i) {
106template<FaceMeshConcept MeshType>
107void readPlyTriStripsBin(
109 const PlyHeader& header,
113 for (uint tid = 0; tid < header.numberTriStrips(); ++tid) {
114 for (
const PlyProperty& p : header.triStripsProperties()) {
115 bool hasBeenRead =
false;
116 if (p.name == ply::vertex_indices) {
118 io::readPrimitiveType<uint>(file, p.listSizeType, end);
119 std::vector<int> tristrip(tSize);
120 for (uint i = 0; i < tSize; ++i)
121 tristrip[i] = io::readPrimitiveType<int>(file, p.type, end);
123 facesFromPlyTriStrip(m, tristrip);
128 io::readPrimitiveType<int>(file, p.listSizeType, end);
129 for (uint i = 0; i < s; ++i)
130 io::readPrimitiveType<int>(file, p.type, end);
133 io::readPrimitiveType<int>(file, p.type, end);
140template<FaceMeshConcept MeshType, LoggerConcept LogType>
141void readPlyTriStrips(
143 const PlyHeader& header,
148 if (header.format() == ply::ASCII) {
149 detail::readPlyTriStripsTxt(file, header, mesh);
152 std::endian end = header.format() == ply::BINARY_BIG_ENDIAN ?
155 detail::readPlyTriStripsBin(file, header, mesh, end);