Visual Computing Library  devel
Loading...
Searching...
No Matches
mesh_sampler.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_SPACE_COMPLEX_SAMPLER_MESH_SAMPLER_H
24#define VCL_SPACE_COMPLEX_SAMPLER_MESH_SAMPLER_H
25
26#include <vclib/algorithms/core.h>
27#include <vclib/mesh.h>
28
29namespace vcl {
30
31template<MeshConcept MeshType>
33{
34 using PosView =
35 decltype(View<typename MeshType::VertexIterator>() | views::positions);
36
37 MeshType mMesh;
38
39public:
40 using PointType = MeshType::VertexType::PositionType;
41 using ScalarType = PointType::ScalarType;
42 using ConstIterator = std::ranges::iterator_t<PosView>;
43
45 {
46 enableIfPerVertexNormalOptional(mMesh);
47 enableIfPerVertexQualityOptional(mMesh);
48 if constexpr (HasName<MeshType>) {
49 mMesh.name() = "Sampling";
50 }
51 }
52
53 const MeshType& samples() const { return mMesh; }
54
55 const PointType& sample(uint i) const { return mMesh.vertex(i).position(); }
56
57 std::size_t size() const { return mMesh.vertexNumber(); }
58
59 void clear() { mMesh.clear(); }
60
61 void resize(uint n)
62 {
63 if (n > mMesh.vertexNumber()) {
64 uint k = n - mMesh.vertexNumber();
65 mMesh.addVertices(k);
66 }
67 }
68
69 void reserve(uint n) { mMesh.reserveVertices(n); }
70
71 void add(const PointType& p) { mMesh.addVertex(p); }
72
73 void set(uint i, const PointType& p) { mMesh.vertex(i).position() = p; }
74
75 template<VertexConcept VertexType>
76 void add(const VertexType& v)
77 {
78 uint vi = mMesh.addVertex(v.position());
79 mMesh.vertex(vi).importFrom(v, false);
80
81 setBirthElement(vi, "birthVertex", v.index());
82 }
83
84 template<VertexConcept VertexType>
85 void set(uint i, const VertexType& v)
86 {
87 mMesh.vertex(i).position() = v.position();
88 mMesh.vertex(i).importFrom(v, false);
89
90 setBirthElement(i, "birthVertex", v.index());
91 }
92
93 template<EdgeConcept EdgeType>
94 void add(const EdgeType& e, double u, bool copyQuality = true)
95 {
96 uint vi = mMesh.addVertex(
97 (e.vertex(0).position() * (1 - u)) + (e.vertex(1).position() * u));
98
99 if constexpr (
101 if (copyQuality) {
102 if (isPerVertexQualityAvailable(mMesh) &&
103 comp::isQualityAvailableOn(e)) {
104 mMesh.vertex(vi).quality() = e.quality();
105 }
106 }
107 }
108
109 setBirthElement(vi, "birthEdge", e.index());
110 }
111
112 template<EdgeConcept EdgeType>
113 void set(uint i, const EdgeType& e, double u, bool copyQuality = true)
114 {
115 mMesh.vertex(i).position() =
116 (e.vertex(0).position() * (1 - u)) + (e.vertex(1).position() * u);
117
118 if constexpr (
120 if (copyQuality) {
121 if (isPerVertexQualityAvailable(mMesh) &&
122 comp::isQualityAvailableOn(e)) {
123 mMesh.vertex(i).quality() = e.quality();
124 }
125 }
126 }
127
128 setBirthElement(i, "birthEdge", e.index());
129 }
130
131 template<FaceConcept FaceType>
132 void add(
133 const FaceType& f,
134 bool copyNormal = false,
135 bool copyQuality = true)
136 {
137 uint vi = mMesh.addVertex(faceBarycenter(f));
138
139 copyComponents(vi, f, copyNormal, copyQuality);
140 setBirthElement(vi, "birthFace", f.index());
141 }
142
143 template<FaceConcept FaceType>
144 void set(
145 uint i,
146 const FaceType& f,
147 bool copyNormal = false,
148 bool copyQuality = true)
149 {
150 mMesh.vertex(i).position() = faceBarycenter(f);
151
152 copyComponents(i, f, copyNormal, copyQuality);
153 setBirthElement(i, "birthFace", f.index());
154 }
155
156 template<FaceConcept FaceType>
157 void add(
158 const FaceType& f,
159 const std::vector<ScalarType>& barCoords,
160 bool copyNormal = false,
161 bool copyQuality = true)
162 {
163 assert(f.vertexNumber() <= barCoords.size());
164
165 PointType p;
166 for (uint i = 0; i < f.vertexNumber(); i++)
167 p += f.vertex(i)->position() * barCoords[i];
168
169 uint vi = mMesh.addVertex(p);
170
171 copyComponents(vi, f, copyNormal, copyQuality);
172 setBirthElement(vi, "birthFace", f.index());
173 }
174
175 template<FaceConcept FaceType>
176 void set(
177 uint i,
178 const FaceType& f,
179 const std::vector<ScalarType>& barCoords,
180 bool copyNormal = false,
181 bool copyQuality = true)
182 {
183 assert(f.vertexNumber() <= barCoords.size());
184
185 PointType p;
186 for (uint i = 0; i < f.vertexNumber(); i++)
187 p += f.vertex(i)->position() * barCoords[i];
188
189 mMesh.vertex(i).position() = p;
190
191 copyComponents(i, f, copyNormal, copyQuality);
192 setBirthElement(i, "birthFace", f.index());
193 }
194
195 template<FaceConcept FaceType>
196 void add(
197 const FaceType& f,
198 const PointType& barCoords,
199 bool copyNormal = false,
200 bool copyQuality = true)
201 {
202 static_assert(FaceType::NV == 3 || FaceType::NV == -1);
203 if constexpr (FaceType::NV == -1) {
204 assert(f.vertexNumber() == 3);
205 }
206
208
209 uint vi = mMesh.addVertex(p);
210
211 copyComponents(vi, f, copyNormal, copyQuality);
212 setBirthElement(vi, "birthFace", f.index());
213 }
214
215 template<FaceConcept FaceType>
216 void set(
217 uint i,
218 const FaceType& f,
219 const PointType& barCoords,
220 bool copyNormal = false,
221 bool copyQuality = true)
222 {
223 static_assert(FaceType::NV == 3 || FaceType::NV == -1);
224 if constexpr (FaceType::NV == -1) {
225 assert(f.vertexNumber() == 3);
226 }
227
229
230 mMesh.vertex(i).position() = p;
231
232 copyComponents(i, f, copyNormal, copyQuality);
233 setBirthElement(i, "birthFace", f.index());
234 }
235
236 ConstIterator begin() const
237 {
238 return std::ranges::begin(mMesh.vertices() | views::positions);
239 }
240
241 ConstIterator end() const
242 {
243 return std::ranges::end(mMesh.vertices() | views::positions);
244 }
245
246private:
247 template<FaceConcept FaceType>
248 void copyComponents(
249 uint vi,
250 const FaceType& f,
251 bool copyNormal,
252 bool copyQuality)
253 {
254 if constexpr (
256 if (copyNormal) {
257 if (isPerVertexNormalAvailable(mMesh) &&
258 comp::isNormalAvailableOn(f)) {
259 mMesh.vertex(vi).normal() = f.normal();
260 }
261 }
262 }
263
264 if constexpr (
266 if (copyQuality) {
267 if (isPerVertexQualityAvailable(mMesh) &&
268 comp::isQualityAvailableOn(f)) {
269 mMesh.vertex(vi).quality() = f.quality();
270 }
271 }
272 }
273 }
274
275 void setBirthElement(uint vi, const std::string& key, uint value)
276 {
278 if (!mMesh.hasPerVertexCustomComponent(key)) {
279 mMesh.template addPerVertexCustomComponent<uint>(key);
280 }
281 mMesh.vertex(vi).template customComponent<uint>(key) = value;
282 }
283 }
284};
285
286} // namespace vcl
287
288#endif // VCL_SPACE_COMPLEX_SAMPLER_MESH_SAMPLER_H
A class representing a box in N-dimensional space.
Definition box.h:46
PointT size() const
Computes the size of the box.
Definition box.h:267
Definition mesh_sampler.h:33
Concept that checks if a Mesh has the Name component.
Definition mesh_requirements.h:88
Concept that checks if a Mesh has the per Vertex CustomComponents.
Definition vertex_requirements.h:200
Concept that checks if a Mesh has the per Vertex Normal component.
Definition vertex_requirements.h:140
Concept that checks if a Mesh has the per Vertex Quality component.
Definition vertex_requirements.h:171
Definition edge_components.h:87
Definition face_components.h:90
Definition face_components.h:100
FaceType::VertexType::PositionType faceBarycenter(const FaceType &f)
Computes the barycenter of a face. Works both for triangle and polygonal faces, and it is optimized i...
Definition geometry.h:81