Visual Computing Library  devel
Loading...
Searching...
No Matches
save.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2026 *
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_SAVE_H
24#define VCL_IO_MESH_PLY_SAVE_H
25
26#include "detail/edge.h"
27#include "detail/extra.h"
28#include "detail/face.h"
29#include "detail/material.h"
30#include "detail/vertex.h"
31
32#include <vclib/io/mesh/settings.h>
33
34namespace vcl {
35
36template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
37void savePly(
38 const MeshType& m,
39 std::ostream& fp,
40 const std::string& fileBasePath,
41 const SaveSettings& settings = SaveSettings(),
42 LogType& log = nullLogger)
43{
44 using namespace detail;
45 MeshInfo meshInfo(m);
46
47 // make sure that the given info contains only components that are actually
48 // available in the mesh. meshInfo will contain the intersection between the
49 // components that the user wants to save and the components that are
50 // available in the mesh.
51 if (!settings.info.isEmpty())
52 meshInfo = settings.info.intersect(meshInfo);
53
54 PlyHeader header(
55 settings.binary ? ply::BINARY_LITTLE_ENDIAN : ply::ASCII, meshInfo);
56 header.setVertexCount(m.vertexCount());
57
58 if constexpr (HasFaces<MeshType>) {
59 if (header.hasFaces()) {
60 header.setFaceCount(m.faceCount());
61 }
62 }
63 if constexpr (HasEdges<MeshType>) {
64 if (header.hasEdges()) {
65 header.setEdgeCount(m.edgeCount());
66 }
67 }
68 if constexpr (HasMaterials<MeshType>) {
69 if (header.hasMaterials()) {
70 header.setMaterialCount(m.materialCount());
71 }
72 }
73
74 // When meshlabCompatibility is enabled, we intentionally add legacy texture
75 // information to the header (via addTexturesToHeader) in addition to the
76 // newer material element written later. This redundancy maximizes
77 // compatibility with tools that only understand one of the two formats.
78 if (settings.meshlabCompatibility) {
79 addTexturesToHeader(header, m);
80 }
81
82 // this should never happen
83 if (!header.isValid())
84 throw std::runtime_error("Ply Header not valid.");
85
86 fp << header.toString(settings);
87
88 writePlyVertices(fp, header, m);
89
90 if constexpr (HasFaces<MeshType>) {
91 if (header.hasFaces()) {
92 writePlyFaces(fp, header, m);
93 }
94 }
95
96 if constexpr (HasEdges<MeshType>) {
97 if (header.hasEdges()) {
98 writePlyEdges(fp, header, m);
99 }
100 }
101
102 if constexpr (HasMaterials<MeshType>) {
103 if (header.hasMaterials()) {
104 writePlyMaterials(fp, header, m);
105 }
106 if (settings.saveTextureImages) {
107 saveTextureImages(m, fileBasePath, BitSet8::ALL(), log);
108 }
109 }
110}
111
112template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
113void savePly(
114 const MeshType& m,
115 const std::string& filename,
116 const SaveSettings& settings = SaveSettings(),
117 LogType& log = nullLogger)
118{
119 std::ofstream fp = openOutputFileStream(filename, "ply");
120
121 std::string basePath = FileInfo::pathWithoutFileName(filename);
122
123 savePly(m, fp, basePath, settings, log);
124}
125
126} // namespace vcl
127
128#endif // VCL_IO_MESH_PLY_SAVE_H
static constexpr BitSet< T > ALL()
Returns a BitSet with all the bits set to true.
Definition bit_set.h:366
static std::string pathWithoutFileName(const std::string &fullpath)
Get the path of a file.
Definition file_info.h:200
NullLogger nullLogger
The nullLogger object is an object of type NullLogger that is used as default argument in the functio...
Definition null_logger.h:123