23#ifndef VCL_IO_MESH_PLY_DETAIL_EDGE_H
24#define VCL_IO_MESH_PLY_DETAIL_EDGE_H
28#include <vclib/io/write.h>
30namespace vcl::detail {
32template<EdgeMeshConcept MeshType, EdgeConcept EdgeType,
typename Stream>
33void readPlyEdgeProperty(
38 std::endian end = std::endian::little)
40 bool hasBeenRead =
false;
42 if (p.name == ply::vertex_indices) {
43 std::vector<uint> vids;
44 uint eSize = io::readPrimitiveType<uint>(file, p.listSizeType, end);
46 for (uint i = 0; i < eSize; ++i) {
47 vids[i] = io::readPrimitiveType<size_t>(file, p.type, end);
48 if (vids[i] >= mesh.vertexNumber()) {
49 throw MalformedFileException(
50 "Bad vertex index for edge " + std::to_string(e.index()));
54 e.setVertex(0u, vids[0]);
55 e.setVertex(1u, vids[1]);
57 if (p.name == ply::vertex1) {
58 uint v0 = io::readPrimitiveType<uint>(file, p.type, end);
62 if (p.name == ply::vertex2) {
63 uint v1 = io::readPrimitiveType<uint>(file, p.type, end);
68 if (p.name >= ply::nx && p.name <= ply::nz) {
69 if constexpr (HasPerEdgeNormal<MeshType>) {
71 using Scalar = EdgeType::NormalType::ScalarType;
72 int a = p.name - ply::nx;
73 Scalar n = io::readPrimitiveType<Scalar>(file, p.type, end);
79 if (p.name >= ply::red && p.name <= ply::alpha) {
80 if constexpr (HasPerFaceColor<MeshType>) {
82 int a = p.name - ply::red;
84 io::readPrimitiveType<unsigned char>(file, p.type, end);
89 if (p.name == ply::quality) {
90 if constexpr (HasPerFaceQuality<MeshType>) {
91 using QualityType = EdgeType::QualityType;
94 io::readPrimitiveType<QualityType>(file, p.type, end);
99 if (p.name == ply::unknown) {
100 if constexpr (HasPerFaceCustomComponents<MeshType>) {
101 if (mesh.hasPerFaceCustomComponent(p.unknownPropertyName)) {
102 io::readCustomComponent(
103 file, e, p.unknownPropertyName, p.type, end);
112 uint s = io::readPrimitiveType<int>(file, p.listSizeType, end);
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<EdgeConcept EdgeType, MeshConcept MeshType>
127 const std::list<PlyProperty>& edgeProperties)
129 Tokenizer spaceTokenizer = readAndTokenizeNextNonEmptyLine(file);
130 Tokenizer::iterator token = spaceTokenizer.begin();
131 for (
const PlyProperty& p : edgeProperties) {
132 if (token == spaceTokenizer.end()) {
133 throw MalformedFileException(
"Unexpected end of line.");
135 readPlyEdgeProperty(token, mesh, e, p);
139template<EdgeConcept EdgeType, MeshConcept MeshType>
144 const std::list<PlyProperty>& edgeProperties,
147 for (
const PlyProperty& p : edgeProperties) {
148 readPlyEdgeProperty(file, mesh, e, p, end);
152template<EdgeMeshConcept MeshType>
155 const PlyHeader& header,
156 const MeshType& mesh)
158 using EdgeType = MeshType::EdgeType;
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;
169 std::vector<uint> vIndices = mesh.vertexCompactIndices();
171 for (
const EdgeType& e : mesh.
edges()) {
172 for (
const PlyProperty& p : header.edgeProperties()) {
173 bool hasBeenWritten =
false;
174 if (p.name == ply::vertex1) {
176 file, vIndices[mesh.index(e.vertex(0))], p.type, format);
177 hasBeenWritten =
true;
179 if (p.name == ply::vertex2) {
181 file, vIndices[mesh.index(e.vertex(1))], p.type, format);
182 hasBeenWritten =
true;
184 if (p.name >= ply::nx && p.name <= ply::nz) {
185 if constexpr (HasPerEdgeNormal<MeshType>) {
187 file, e.normal()[p.name - ply::nx], p.type, format);
188 hasBeenWritten =
true;
191 if (p.name >= ply::red && p.name <= ply::alpha) {
192 if constexpr (HasPerEdgeColor<MeshType>) {
194 file, e.color()[p.name - ply::red], p.type, format);
195 hasBeenWritten =
true;
198 if (p.name == ply::quality) {
199 if constexpr (HasPerEdgeQuality<MeshType>) {
200 io::writeProperty(file, e.quality(), p.type, format);
201 hasBeenWritten =
true;
204 if (!hasBeenWritten) {
207 io::writeProperty(file, 0, p.type, format);
210 if (!format.isBinary)
215template<EdgeMeshConcept MeshType, LoggerConcept LogType>
218 const PlyHeader& header,
222 using EdgeType = MeshType::EdgeType;
223 m.reserveEdges(header.numberEdges());
225 log.startProgress(
"Reading edges", header.numberEdges());
227 for (uint eid = 0; eid < header.numberEdges(); ++eid) {
228 uint eeid = m.addEdge();
229 EdgeType& e = m.edge(eeid);
230 if (header.format() == ply::ASCII) {
231 detail::readPlyEdgeTxt(file, e, m, header.edgeProperties());
234 std::endian end = header.format() == ply::BINARY_BIG_ENDIAN ?
237 detail::readPlyEdgeBin(file, e, m, header.edgeProperties(), end);
bool isPerEdgeNormalAvailable(const MeshType &m)
Returns true if the Normal component is available (enabled) in the Edge element of the input mesh m.
Definition edge_requirements.h:486
bool isPerFaceQualityAvailable(const MeshType &m)
Returns true if the Quality component is available (enabled) in the Face element of the input mesh m.
Definition face_requirements.h:713
bool isPerFaceColorAvailable(const MeshType &m)
Returns true if the Color component is available (enabled) in the Face element of the input mesh m.
Definition face_requirements.h:476
constexpr detail::EdgesView edges
A view that allows to iterate overt the Edge elements of an object.
Definition edge.h:84