Visual Computing Library  devel
Loading...
Searching...
No Matches
save.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_OFF_SAVE_H
24#define VCL_IO_MESH_OFF_SAVE_H
25
26#include <vclib/io/mesh/settings.h>
27#include <vclib/io/write.h>
28
29#include <vclib/space/complex.h>
30
31namespace vcl {
32
33template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
34void saveOff(
35 const MeshType& m,
36 std::ostream& fp,
37 const SaveSettings& settings = SaveSettings(),
38 LogType& log = nullLogger)
39{
40 MeshInfo meshInfo(m);
41
42 // make sure that the given info contains only components that are actually
43 // available in the mesh. meshInfo will contain the intersection between the
44 // components that the user wants to save and the components that are
45 // available in the mesh.
46 if (!settings.info.isEmpty())
47 meshInfo = settings.info.intersect(meshInfo);
48
49 if (meshInfo.hasPerVertexNormal())
50 fp << "N";
51 if (meshInfo.hasPerVertexColor())
52 fp << "C";
53 if (meshInfo.hasPerVertexTexCoord())
54 fp << "ST";
55 fp << "OFF" << std::endl;
56
57 uint vn = 0;
58 uint fn = 0;
59 uint en = 0;
60 if constexpr (HasVertices<MeshType>) {
61 vn = m.vertexNumber();
62 }
63 if constexpr (HasFaces<MeshType>) {
64 fn = m.faceNumber();
65 }
66
67 io::writeInt(fp, vn, false);
68 io::writeInt(fp, fn, false);
69 io::writeInt(fp, en, false);
70 fp << std::endl; // remove last char (a space) and add a newline
71
72 // vertices
73 if constexpr (HasVertices<MeshType>) {
74 using VertexType = MeshType::VertexType;
75 for (const VertexType& v : m.vertices()) {
76 io::writeDouble(fp, v.position().x(), false);
77 io::writeDouble(fp, v.position().y(), false);
78 io::writeDouble(fp, v.position().z(), false);
79
80 if constexpr (HasPerVertexColor<MeshType>) {
81 if (meshInfo.hasPerVertexColor()) {
82 io::writeInt(fp, v.color().red(), false);
83 io::writeInt(fp, v.color().green(), false);
84 io::writeInt(fp, v.color().blue(), false);
85 io::writeInt(fp, v.color().alpha(), false);
86 }
87 }
88 if constexpr (HasPerVertexNormal<MeshType>) {
89 if (meshInfo.hasPerVertexNormal()) {
90 io::writeDouble(fp, v.normal().x(), false);
91 io::writeDouble(fp, v.normal().y(), false);
92 io::writeDouble(fp, v.normal().z(), false);
93 }
94 }
95 if constexpr (HasPerVertexTexCoord<MeshType>) {
96 if (meshInfo.hasPerVertexTexCoord()) {
97 io::writeDouble(fp, v.texCoord().u(), false);
98 io::writeDouble(fp, v.texCoord().v(), false);
99 }
100 }
101
102 fp << std::endl;
103 }
104 }
105
106 // faces
107 if constexpr (HasFaces<MeshType>) {
108 using VertexType = MeshType::VertexType;
109 using FaceType = MeshType::FaceType;
110
111 // indices of vertices that do not consider deleted vertices
112 std::vector<uint> vIndices = m.vertexCompactIndices();
113
114 for (const FaceType& f : m.faces()) {
115 io::writeInt(fp, f.vertexNumber(), false);
116 for (const VertexType* v : f.vertices()) {
117 io::writeInt(fp, vIndices[m.index(v)], false);
118 }
119 if constexpr (HasPerFaceColor<MeshType>) {
120 if (meshInfo.hasPerFaceColor()) {
121 io::writeInt(fp, f.color().red(), false);
122 io::writeInt(fp, f.color().green(), false);
123 io::writeInt(fp, f.color().blue(), false);
124 io::writeInt(fp, f.color().alpha(), false);
125 }
126 }
127
128 fp << std::endl;
129 }
130 }
131}
132
133template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
134void saveOff(
135 const MeshType& m,
136 const std::string& filename,
137 const SaveSettings& settings = SaveSettings(),
138 LogType& log = nullLogger)
139{
140 std::ofstream fp = openOutputFileStream(filename, "off");
141 saveOff(m, fp, settings, log);
142 fp.close();
143}
144
145} // namespace vcl
146
147#endif // VCL_IO_MESH_OFF_SAVE_H
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
constexpr detail::FacesView faces
A view that allows to iterate overt the Face elements of an object.
Definition face.h:84
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:92