Visual Computing Library
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_LOAD_SAVE_PLY_DETAIL_TRISTRIP_H
24#define VCL_LOAD_SAVE_PLY_DETAIL_TRISTRIP_H
25
26#include "header.h"
27
28#include <vclib/io/read.h>
29#include <vclib/misc/tokenizer.h>
30
31#include <istream>
32
33namespace vcl::detail {
34
35template<FaceMeshConcept MeshType>
36void facesFromPlyTriStrip(MeshType& m, const std::vector<int>& tristrip)
37{
38 using FaceType = MeshType::FaceType;
39
40 bool firstOddPos = false;
41 for (uint k = 0; k < tristrip.size() - 2; ++k) {
42 if (tristrip[k + 2] < 0) {
43 k += 2;
44 if (k % 2 == 0)
45 firstOddPos = false;
46 else
47 firstOddPos = true;
48 }
49 else {
50 uint fid = m.addFace();
51 FaceType& f = m.face(fid);
52 if constexpr (FaceType::VERTEX_NUMBER < 0) {
53 f.resizeVertices(3);
54 }
55 for (uint i = 0; i < f.vertexNumber(); ++i) {
56 f.setVertex(i, tristrip[k + i]);
57 }
58
59 if (k % 2 == 0 != firstOddPos) {
60 auto* tmp = f.vertex(0);
61 f.setVertex(0U, f.vertex(1));
62 f.setVertex(1U, tmp);
63 }
64 }
65 }
66}
67
68template<FaceMeshConcept MeshType>
69void readPlyTriStripsTxt(
70 std::istream& file,
71 const PlyHeader& header,
72 MeshType& m)
73{
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.");
80 }
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);
87 }
88 hasBeenRead = true;
89 facesFromPlyTriStrip(m, tristrip);
90 }
91 if (!hasBeenRead) {
92 if (p.list) {
93 uint s = io::readPrimitiveType<int>(token, p.listSizeType);
94 for (uint i = 0; i < s; ++i) {
95 ++token;
96 }
97 }
98 else {
99 ++token;
100 }
101 }
102 }
103 }
104}
105
106template<FaceMeshConcept MeshType>
107void readPlyTriStripsBin(
108 std::istream& file,
109 const PlyHeader& header,
110 MeshType& m,
111 std::endian end)
112{
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) {
117 uint tSize =
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);
122 hasBeenRead = true;
123 facesFromPlyTriStrip(m, tristrip);
124 }
125 if (!hasBeenRead) {
126 if (p.list) {
127 uint s =
128 io::readPrimitiveType<int>(file, p.listSizeType, end);
129 for (uint i = 0; i < s; ++i)
130 io::readPrimitiveType<int>(file, p.type, end);
131 }
132 else {
133 io::readPrimitiveType<int>(file, p.type, end);
134 }
135 }
136 }
137 }
138}
139
140template<FaceMeshConcept MeshType, LoggerConcept LogType>
141void readPlyTriStrips(
142 std::istream& file,
143 const PlyHeader& header,
144 MeshType& mesh,
145 LogType& log)
146{
147 // todo: manage log
148 if (header.format() == ply::ASCII) {
149 detail::readPlyTriStripsTxt(file, header, mesh);
150 }
151 else {
152 std::endian end = header.format() == ply::BINARY_BIG_ENDIAN ?
153 std::endian::big :
154 std::endian::little;
155 detail::readPlyTriStripsBin(file, header, mesh, end);
156 }
157}
158
159} // namespace vcl::detail
160
161#endif // VCL_LOAD_SAVE_PLY_DETAIL_TRISTRIP_H