Visual Computing Library
Loading...
Searching...
No Matches
load.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_LOAD_H
24#define VCL_LOAD_SAVE_PLY_LOAD_H
25
26#include "detail/edge.h"
27#include "detail/extra.h"
28#include "detail/face.h"
29#include "detail/tristrip.h"
30#include "detail/vertex.h"
31
32#include <vclib/load_save/settings.h>
33#include <vclib/misc/logger.h>
34#include <vclib/space/complex/mesh_info.h>
35
36namespace vcl {
37
38namespace detail {
39
40template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
41void loadPly(
42 MeshType& m,
43 std::istream& file,
44 const std::string& filename,
45 MeshInfo& loadedInfo,
46 LogType& log = nullLogger,
47 const LoadSettings& settings = LoadSettings())
48{
49 PlyHeader header(file, filename);
50 if (header.errorWhileLoading())
51 throw MalformedFileException("Header not valid: " + filename);
52
53 m.clear();
54
55 loadedInfo = header.getInfo();
56
57 if (settings.enableOptionalComponents)
58 enableOptionalComponentsFromInfo(loadedInfo, m);
59
60 if constexpr (HasName<MeshType>) {
61 m.name() = FileInfo::fileNameWithoutExtension(filename);
62 }
63 if constexpr (HasTexturePaths<MeshType>) {
64 m.meshBasePath() = FileInfo::pathWithoutFileName(filename);
65 }
66
67 // for logging
68 std::vector<uint> eln;
69 uint sum = 0;
70 for (const PlyElement& el : header) {
71 eln.push_back(el.numberElements);
72 sum += el.numberElements;
73 }
74
75 try {
76 uint currElems = 0;
77 uint i = 0;
78 for (const PlyElement& el : header) {
79 double beginPerc = double(currElems) / sum * 100.0;
80 double endPerc = double(currElems + eln[i]) / sum * 100.0;
81
82 switch (el.type) {
83 case ply::VERTEX:
84 log.startNewTask(beginPerc, endPerc, "Reading vertices");
85 readPlyVertices(file, header, m, log);
86 log.endTask("Reading vertices");
87 break;
88 case ply::FACE:
89 log.startNewTask(beginPerc, endPerc, "Reading faces");
90 if constexpr (HasFaces<MeshType>)
91 readPlyFaces(file, header, m, loadedInfo, log);
92 else
93 readPlyUnknownElement(file, header, el, log);
94 log.endTask("Reading faces");
95 break;
96 case ply::TRISTRIP:
97 log.startNewTask(beginPerc, endPerc, "Reading tristrips");
98 if constexpr (HasFaces<MeshType>) {
99 loadedInfo.setTriangleMesh();
100 readPlyTriStrips(file, header, m, log);
101 }
102 else
103 readPlyUnknownElement(file, header, el, log);
104 log.endTask("Reading tristrips");
105 break;
106 case ply::EDGE:
107 log.startNewTask(beginPerc, endPerc, "Reading edges");
108 if constexpr (HasEdges<MeshType>)
109 readPlyEdges(file, header, m, log);
110 else
111 readPlyUnknownElement(file, header, el, log);
112 log.endTask("Reading edges");
113 break;
114 default:
115 log.startNewTask(
116 beginPerc, endPerc, "Reading unknown elements");
117 readPlyUnknownElement(file, header, el, log);
118 log.endTask("Reading unknown elements");
119 break;
120 }
121 currElems += eln[i];
122 ++i;
123 }
124 readPlyTextures(header, m, log, settings);
125 }
126 catch (const std::runtime_error& err) {
127 m.clear();
128 throw err;
129 }
130}
131
132} // namespace detail
133
158template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
160 MeshType& m,
161 std::istream& inputPlyStream,
163 LogType& log = nullLogger,
164 const LoadSettings& settings = LoadSettings())
165{
166 detail::loadPly(m, inputPlyStream, "", loadedInfo, log, settings);
167}
168
188template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
190 MeshType& m,
191 std::istream& inputPlyStream,
192 LogType& log = nullLogger,
193 const LoadSettings& settings = LoadSettings())
194{
196 loadPly(m, inputPlyStream, loadedInfo, log, settings);
197}
198
223template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
224MeshType loadPly(
225 std::istream& inputPlyStream,
227 LogType& log = nullLogger,
228 const LoadSettings& settings = LoadSettings())
229{
230 MeshType m;
231 loadPly(m, inputPlyStream, loadedInfo, log, settings);
232 return m;
233}
234
254template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
255MeshType loadPly(
256 std::istream& inputPlyStream,
257 LogType& log = nullLogger,
258 const LoadSettings& settings = LoadSettings())
259{
261 return loadPly<MeshType>(inputPlyStream, loadedInfo, log, settings);
262}
263
287template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
289 MeshType& m,
290 const std::string& filename,
292 LogType& log = nullLogger,
293 const LoadSettings& settings = LoadSettings())
294{
295 std::ifstream file = openInputFileStream(filename);
296
297 detail::loadPly(m, file, filename, loadedInfo, log, settings);
298}
299
318template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
320 MeshType& m,
321 const std::string& filename,
322 LogType& log = nullLogger,
323 const LoadSettings& settings = LoadSettings())
324{
326 loadPly(m, filename, loadedInfo, log, settings);
327}
328
353template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
354MeshType loadPly(
355 const std::string& filename,
357 LogType& log = nullLogger,
358 const LoadSettings& settings = LoadSettings())
359{
360 MeshType m;
361 loadPly(m, filename, loadedInfo, log, settings);
362 return m;
363}
364
384template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
385MeshType loadPly(
386 const std::string& filename,
387 LogType& log = nullLogger,
388 const LoadSettings& settings = LoadSettings())
389{
391 return loadPly<MeshType>(filename, loadedInfo, log, settings);
392}
393
394} // namespace vcl
395
396#endif // VCL_LOAD_SAVE_PLY_LOAD_H
static std::string fileNameWithoutExtension(const std::string &fullpath)
Get the file name without extension of a file.
Definition file_info.h:217
static std::string pathWithoutFileName(const std::string &fullpath)
Get the path of a file.
Definition file_info.h:197
A simple class that allows to store which elements and their components have been imported/loaded or ...
Definition mesh_info.h:76
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
void loadPly(MeshType &m, std::istream &inputPlyStream, MeshInfo &loadedInfo, LogType &log=nullLogger, const LoadSettings &settings=LoadSettings())
Loads from the given input ply stream and puts the content into the mesh m.
Definition load.h:159
NullLogger nullLogger
The nullLogger object is an object of type NullLogger that is used as default argument in the functio...
Definition null_logger.h:125
The LoadSettings structure contains the settings that can be used to load a mesh from a stream/file.
Definition settings.h:35