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