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