Visual Computing Library  devel
Loading...
Searching...
No Matches
append_replace_to_buffer.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_ALGORITHMS_MESH_IMPORT_EXPORT_APPEND_REPLACE_TO_BUFFER_H
24#define VCL_ALGORITHMS_MESH_IMPORT_EXPORT_APPEND_REPLACE_TO_BUFFER_H
25
26#include <vclib/mesh.h>
27#include <vclib/space/complex.h>
28
59namespace vcl {
60
99template<MeshConcept MeshType>
101 const MeshType& mesh,
102 const std::list<uint>& vertsToDuplicate,
103 auto* buffer,
104 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
105{
106 // no vertices to duplicate, do nothing
107 if (vertsToDuplicate.empty())
108 return;
109
110 const uint VERT_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
111
112 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
113 const auto& pos = mesh.vertex(v).position();
114 if (storage == MatrixStorageType::ROW_MAJOR) {
115 buffer[i * 3 + 0] = pos.x();
116 buffer[i * 3 + 1] = pos.y();
117 buffer[i * 3 + 2] = pos.z();
118 }
119 else {
120 buffer[0 * VERT_NUM + i] = pos.x();
121 buffer[1 * VERT_NUM + i] = pos.y();
122 buffer[2 * VERT_NUM + i] = pos.z();
123 }
124
125 ++i;
126 }
127}
128
174template<FaceMeshConcept MeshType>
176 const MeshType& mesh,
177 const std::list<uint>& vertsToDuplicate,
178 const std::list<std::list<std::pair<uint, uint>>>& facesToReassign,
179 auto* buffer,
180 uint largestFaceSize = 3,
181 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
182{
183 // no vertices have been duplicated, do nothing
184 if (vertsToDuplicate.empty())
185 return;
186
188
189 const uint FACE_NUM = mesh.faceNumber();
190
191 uint vFirst = mesh.vertexNumber();
192 uint vLast = mesh.vertexNumber() + vertsToDuplicate.size();
193 for (uint vi = vFirst; const auto& faces : facesToReassign) {
194 for (const auto& f : faces) {
195 if (storage == MatrixStorageType::ROW_MAJOR)
196 buffer[f.first * largestFaceSize + f.second] = vi;
197 else
198 buffer[f.second * FACE_NUM + f.first] = vi;
199 }
200 ++vi;
201 }
202}
203
251template<FaceMeshConcept MeshType>
253 const MeshType& mesh,
254 const std::list<uint>& vertsToDuplicate,
255 const std::list<std::list<std::pair<uint, uint>>>& facesToReassign,
256 const TriPolyIndexBiMap& indexMap,
257 auto* buffer,
258 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
259{
260 // no vertices have been duplicated, do nothing
261 if (vertsToDuplicate.empty())
262 return;
263
265
266 uint vFirst = mesh.vertexNumber();
267 uint vLast = mesh.vertexNumber() + vertsToDuplicate.size();
268
269 const uint FACE_NUM = indexMap.triangleNumber();
270
271 // the facesToReassign lists for each vertex contain pairs that in the
272 // second element store the index of the vertex in the face. However, the
273 // face has been triangulated, and this info is not useful anymore. We need
274 // to look into the triangles generated for the face (first elem of the
275 // pair) and look for the vertex index to set (that is the vertex index
276 // stored in the vertsToDuplicate list).
277 for (uint vi = vFirst; const auto& [vert, faces] :
278 std::views::zip(vertsToDuplicate, facesToReassign)) {
279 // vert is the vertex index in the mesh that we need to reassign with
280 // the index vi in the buffer
281
282 // for each face f that has at least a vertex to reassign
283 for (const auto& f : faces) {
284 // get the triangle indices of the face using the index map
285 uint tBegin = indexMap.triangleBegin(f.first);
286 uint tEnd = tBegin + indexMap.triangleNumber(f.first);
287 for (uint t = tBegin; t < tEnd; ++t) { // look into the triangles
288 for (uint j = 0; j < 3; ++j) { // for each vertex of triangle
289 if (storage == MatrixStorageType::ROW_MAJOR) {
290 if (buffer[t * 3 + j] == vert) {
291 buffer[t * 3 + j] = vi;
292 }
293 }
294 else {
295 if (buffer[j * FACE_NUM + t] == vert) {
296 buffer[j * FACE_NUM + t] = vi;
297 }
298 }
299 }
300 }
301 }
302 ++vi;
303 }
304}
305
343template<MeshConcept MeshType>
345 const MeshType& mesh,
346 const std::list<uint>& vertsToDuplicate,
347 auto* buffer)
348{
349 // no vertices to duplicate, do nothing
350 if (vertsToDuplicate.empty())
351 return;
352
353 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
354 buffer[i] = mesh.vertex(v).selected();
355 ++i;
356 }
357}
358
396template<MeshConcept MeshType>
398 const MeshType& mesh,
399 const std::list<uint>& vertsToDuplicate,
400 auto* buffer,
401 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
402{
403 // no vertices to duplicate, do nothing
404 if (vertsToDuplicate.empty())
405 return;
406
407 requirePerVertexNormal(mesh);
408
409 const uint VERT_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
410
411 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
412 const auto& normal = mesh.vertex(v).normal();
413 if (storage == MatrixStorageType::ROW_MAJOR) {
414 buffer[i * 3 + 0] = normal.x();
415 buffer[i * 3 + 1] = normal.y();
416 buffer[i * 3 + 2] = normal.z();
417 }
418 else {
419 buffer[0 * VERT_NUM + i] = normal.x();
420 buffer[1 * VERT_NUM + i] = normal.y();
421 buffer[2 * VERT_NUM + i] = normal.z();
422 }
423 ++i;
424 }
425}
426
465template<MeshConcept MeshType>
467 const MeshType& mesh,
468 const std::list<uint>& vertsToDuplicate,
469 auto* buffer,
470 Color::Representation representation = Color::Representation::INT_0_255,
471 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
472{
473 // no vertices to duplicate, do nothing
474 if (vertsToDuplicate.empty())
475 return;
476
477 requirePerVertexColor(mesh);
478
479 const bool R_INT = representation == Color::Representation::INT_0_255;
480 const uint VERT_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
481
482 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
483 const auto& c = mesh.vertex(v).color();
484 if (storage == MatrixStorageType::ROW_MAJOR) {
485 buffer[i * 4 + 0] = R_INT ? c.red() : c.redF();
486 buffer[i * 4 + 1] = R_INT ? c.green() : c.greenF();
487 buffer[i * 4 + 2] = R_INT ? c.blue() : c.blueF();
488 buffer[i * 4 + 3] = R_INT ? c.alpha() : c.alphaF();
489 }
490 else {
491 buffer[0 * VERT_NUM + i] = R_INT ? c.red() : c.redF();
492 buffer[1 * VERT_NUM + i] = R_INT ? c.green() : c.greenF();
493 buffer[2 * VERT_NUM + i] = R_INT ? c.blue() : c.blueF();
494 buffer[3 * VERT_NUM + i] = R_INT ? c.alpha() : c.alphaF();
495 }
496 ++i;
497 }
498}
499
539template<MeshConcept MeshType>
541 const MeshType& mesh,
542 const std::list<uint>& vertsToDuplicate,
543 auto* buffer,
545{
546 // no vertices to duplicate, do nothing
547 if (vertsToDuplicate.empty())
548 return;
549
550 requirePerVertexColor(mesh);
551
552 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
553 const auto& c = mesh.vertex(v).color();
554 switch (colorFormat) {
555 using enum Color::Format;
556 case ABGR: buffer[i] = c.abgr(); break;
557 case ARGB: buffer[i] = c.argb(); break;
558 case RGBA: buffer[i] = c.rgba(); break;
559 case BGRA: buffer[i] = c.bgra(); break;
560 }
561 ++i;
562 }
563}
564
601template<MeshConcept MeshType>
603 const MeshType& mesh,
604 const std::list<uint>& vertsToDuplicate,
605 auto* buffer)
606{
607 // no vertices to duplicate, do nothing
608 if (vertsToDuplicate.empty())
609 return;
610
611 requirePerVertexQuality(mesh);
612
613 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
614 buffer[i] = mesh.vertex(v).quality();
615 ++i;
616 }
617}
618
660template<MeshConcept MeshType>
662 const MeshType& mesh,
663 const std::list<uint>& vertsToDuplicate,
664 auto* buffer,
665 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
666{
667 // no vertices to duplicate, do nothing
668 if (vertsToDuplicate.empty())
669 return;
670
671 requirePerVertexTexCoord(mesh);
672
673 const uint VERT_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
674
675 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
676 const auto& t = mesh.vertex(v).texCoord();
677 if (storage == MatrixStorageType::ROW_MAJOR) {
678 buffer[i * 2 + 0] = t.u();
679 buffer[i * 2 + 1] = t.v();
680 }
681 else {
682 buffer[0 * VERT_NUM + i] = t.u();
683 buffer[1 * VERT_NUM + i] = t.v();
684 }
685 ++i;
686 }
687}
688
730template<MeshConcept MeshType>
732 const MeshType& mesh,
733 const std::list<uint>& vertsToDuplicate,
734 auto* buffer)
735{
736 // no vertices to duplicate, do nothing
737 if (vertsToDuplicate.empty())
738 return;
739
740 requirePerVertexTexCoord(mesh);
741
742 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
743 buffer[i] = mesh.vertex(v).texCoord().index();
744 ++i;
745 }
746}
747
748} // namespace vcl
749
750#endif // VCL_ALGORITHMS_MESH_IMPORT_EXPORT_APPEND_REPLACE_TO_BUFFER_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
Format
Color format enumeration.
Definition color.h:77
Representation
Color representation enumeration.
Definition color.h:64
The TriPolyIndexBiMap class allows to store a bidirectional mapping between a Polygon Mesh and a Tria...
Definition tri_poly_index_bimap.h:50
uint triangleBegin(uint polygonIndex) const
Returns the smallest index of set of triangles mapped to the polygon having the index given as input ...
Definition tri_poly_index_bimap.h:83
uint triangleNumber(uint polygonIndex) const
Returns the number of (consecutive index) triangles mapped to a polygon.
Definition tri_poly_index_bimap.h:112
void appendDuplicateVertexPositionsToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR)
Append the positions of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:100
void replaceTriangulatedFaceIndicesByVertexDuplicationToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, const std::list< std::list< std::pair< uint, uint > > > &facesToReassign, const TriPolyIndexBiMap &indexMap, auto *buffer, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR)
Replace the triangulated face vertex indices in the given buffer with the new indices of the duplicat...
Definition append_replace_to_buffer.h:252
void appendDuplicateVertexQualityToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer)
Append the quality of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:602
void appendDuplicateVertexColorsToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer, Color::Representation representation=Color::Representation::INT_0_255, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR)
Append the colors of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:466
void replaceFaceIndicesByVertexDuplicationToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, const std::list< std::list< std::pair< uint, uint > > > &facesToReassign, auto *buffer, uint largestFaceSize=3, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR)
Replace the face vertex indices in the given buffer with the new indices of the duplicated vertices.
Definition append_replace_to_buffer.h:175
void appendDuplicateVertexSelectionToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer)
Append the selection of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:344
void appendDuplicateVertexNormalsToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR)
Append the normals of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:397
void appendDuplicateVertexTexCoordIndicesToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer)
Append the texture coordinate indices of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:731
void appendDuplicateVertexTexCoordsToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR)
Append the texture coordinates of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:661
MatrixStorageType
A simple type that enumerates the main storage types for matrices (row or column major).
Definition base.h:76
uint largestFaceSize(const FaceMeshConcept auto &mesh)
Returns the largest face size in the mesh.
Definition topology.h:211