Visual Computing Library  devel
Loading...
Searching...
No Matches
tristrip.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_IO_MESH_PLY_DETAIL_TRISTRIP_H
24#define VCL_IO_MESH_PLY_DETAIL_TRISTRIP_H
25
26#include "header.h"
27
28#include <vclib/io/read.h>
29
30#include <istream>
31
32namespace vcl::detail {
33
34template<FaceMeshConcept MeshType>
35void facesFromPlyTriStrip(MeshType& m, const std::vector<int>& tristrip)
36{
37 using FaceType = MeshType::FaceType;
38
39 bool firstOddPos = false;
40 for (uint k = 0; k < tristrip.size() - 2; ++k) {
41 if (tristrip[k + 2] < 0) {
42 k += 2;
43 if (k % 2 == 0)
44 firstOddPos = false;
45 else
46 firstOddPos = true;
47 }
48 else {
49 uint fid = m.addFace();
50 FaceType& f = m.face(fid);
51 if constexpr (FaceType::VERTEX_NUMBER < 0) {
52 f.resizeVertices(3);
53 }
54 for (uint i = 0; i < f.vertexNumber(); ++i) {
55 f.setVertex(i, tristrip[k + i]);
56 }
57
58 if (k % 2 == 0 != firstOddPos) {
59 auto* tmp = f.vertex(0);
60 f.setVertex(0U, f.vertex(1));
61 f.setVertex(1U, tmp);
62 }
63 }
64 }
65}
66
67template<FaceMeshConcept MeshType, LoggerConcept LogType>
68void readPlyTriStripsTxt(
69 std::istream& file,
70 const PlyHeader& header,
71 MeshType& m,
72 LogType& log)
73{
74 log.startProgress("Reading Triangle Strips", header.numberTriStrips());
75
76 for (uint tid = 0; tid < header.numberTriStrips(); ++tid) {
77 Tokenizer spaceTokenizer = readAndTokenizeNextNonEmptyLine(file);
78 Tokenizer::iterator token = spaceTokenizer.begin();
79 for (const PlyProperty& p : header.triStripsProperties()) {
80 if (token == spaceTokenizer.end()) {
81 throw MalformedFileException("Unexpected end of line.");
82 }
83 bool hasBeenRead = false;
84 if (p.name == ply::vertex_indices) {
85 uint tSize = io::readPrimitiveType<uint>(token, p.listSizeType);
86 std::vector<int> tristrip(tSize);
87 for (uint i = 0; i < tSize; ++i) {
88 tristrip[i] = io::readPrimitiveType<size_t>(token, p.type);
89 }
90 hasBeenRead = true;
91 facesFromPlyTriStrip(m, tristrip);
92 }
93 if (!hasBeenRead) {
94 if (p.list) {
95 uint s = io::readPrimitiveType<int>(token, p.listSizeType);
96 for (uint i = 0; i < s; ++i) {
97 ++token;
98 }
99 }
100 else {
101 ++token;
102 }
103 }
104 }
105 log.progress(tid);
106 }
107 log.endProgress();
108}
109
110template<FaceMeshConcept MeshType, LoggerConcept LogType>
111void readPlyTriStripsBin(
112 std::istream& file,
113 const PlyHeader& header,
114 MeshType& m,
115 std::endian end,
116 LogType& log)
117{
118 log.startProgress("Reading Triangle Strips", header.numberTriStrips());
119 for (uint tid = 0; tid < header.numberTriStrips(); ++tid) {
120 for (const PlyProperty& p : header.triStripsProperties()) {
121 bool hasBeenRead = false;
122 if (p.name == ply::vertex_indices) {
123 uint tSize =
124 io::readPrimitiveType<uint>(file, p.listSizeType, end);
125 std::vector<int> tristrip(tSize);
126 for (uint i = 0; i < tSize; ++i)
127 tristrip[i] = io::readPrimitiveType<int>(file, p.type, end);
128 hasBeenRead = true;
129 facesFromPlyTriStrip(m, tristrip);
130 }
131 if (!hasBeenRead) {
132 if (p.list) {
133 uint s =
134 io::readPrimitiveType<int>(file, p.listSizeType, end);
135 for (uint i = 0; i < s; ++i)
136 io::readPrimitiveType<int>(file, p.type, end);
137 }
138 else {
139 io::readPrimitiveType<int>(file, p.type, end);
140 }
141 }
142 }
143 log.progress(tid);
144 }
145 log.endProgress();
146}
147
148template<FaceMeshConcept MeshType, LoggerConcept LogType>
149void readPlyTriStrips(
150 std::istream& file,
151 const PlyHeader& header,
152 MeshType& mesh,
153 LogType& log)
154{
155 if (header.format() == ply::ASCII) {
156 detail::readPlyTriStripsTxt(file, header, mesh, log);
157 }
158 else {
159 std::endian end = header.format() == ply::BINARY_BIG_ENDIAN ?
160 std::endian::big :
161 std::endian::little;
162 detail::readPlyTriStripsBin(file, header, mesh, end, log);
163 }
164}
165
166} // namespace vcl::detail
167
168#endif // VCL_IO_MESH_PLY_DETAIL_TRISTRIP_H