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 "detail.h"
27
28#include <vclib/mesh.h>
29#include <vclib/space/complex.h>
30
61namespace vcl {
62
101template<MeshConcept MeshType>
103 const MeshType& mesh,
104 const std::list<uint>& vertsToDuplicate,
105 auto* buffer,
106 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
107{
108 using namespace detail;
109
110 // no vertices to duplicate, do nothing
111 if (vertsToDuplicate.empty())
112 return;
113
114 const uint ROW_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
115
116 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
117 const auto& pos = mesh.vertex(v).position();
118
119 at(buffer, i, 0, ROW_NUM, 3, storage) = pos.x();
120 at(buffer, i, 1, ROW_NUM, 3, storage) = pos.y();
121 at(buffer, i, 2, ROW_NUM, 3, storage) = pos.z();
122
123 ++i;
124 }
125}
126
172template<FaceMeshConcept MeshType>
174 const MeshType& mesh,
175 const std::list<uint>& vertsToDuplicate,
176 const std::list<std::list<std::pair<uint, uint>>>& facesToReassign,
177 auto* buffer,
178 uint largestFaceSize = 3,
179 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
180{
181 using namespace detail;
182
183 // no vertices have been duplicated, do nothing
184 if (vertsToDuplicate.empty())
185 return;
186
188
189 const uint ROW_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 at(buffer, f.first, f.second, ROW_NUM, largestFaceSize, storage) =
196 vi;
197 }
198 ++vi;
199 }
200}
201
249template<FaceMeshConcept MeshType>
251 const MeshType& mesh,
252 const std::list<uint>& vertsToDuplicate,
253 const std::list<std::list<std::pair<uint, uint>>>& facesToReassign,
254 const TriPolyIndexBiMap& indexMap,
255 auto* buffer,
256 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
257{
258 using namespace detail;
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 ROW_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 auto& triVert = at(buffer, t, j, ROW_NUM, 3, storage);
290 if (triVert == vert) {
291 triVert = vi;
292 }
293 }
294 }
295 }
296 ++vi;
297 }
298}
299
337template<MeshConcept MeshType>
339 const MeshType& mesh,
340 const std::list<uint>& vertsToDuplicate,
341 auto* buffer)
342{
343 // no vertices to duplicate, do nothing
344 if (vertsToDuplicate.empty())
345 return;
346
347 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
348 buffer[i] = mesh.vertex(v).selected();
349 ++i;
350 }
351}
352
390template<MeshConcept MeshType>
392 const MeshType& mesh,
393 const std::list<uint>& vertsToDuplicate,
394 auto* buffer,
395 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
396{
397 using namespace detail;
398
399 // no vertices to duplicate, do nothing
400 if (vertsToDuplicate.empty())
401 return;
402
403 requirePerVertexNormal(mesh);
404
405 const uint ROW_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
406
407 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
408 const auto& normal = mesh.vertex(v).normal();
409 at(buffer, i, 0, ROW_NUM, 3, storage) = normal.x();
410 at(buffer, i, 1, ROW_NUM, 3, storage) = normal.y();
411 at(buffer, i, 2, ROW_NUM, 3, storage) = normal.z();
412
413 ++i;
414 }
415}
416
455template<MeshConcept MeshType>
457 const MeshType& mesh,
458 const std::list<uint>& vertsToDuplicate,
459 auto* buffer,
460 Color::Representation representation = Color::Representation::INT_0_255,
461 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
462{
463 using namespace detail;
464
465 // no vertices to duplicate, do nothing
466 if (vertsToDuplicate.empty())
467 return;
468
469 requirePerVertexColor(mesh);
470
471 const bool R_INT = representation == Color::Representation::INT_0_255;
472 const uint ROW_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
473
474 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
475 const auto& c = mesh.vertex(v).color();
476 at(buffer, i, 0, ROW_NUM, 4, storage) = R_INT ? c.red() : c.redF();
477 at(buffer, i, 1, ROW_NUM, 4, storage) = R_INT ? c.green() : c.greenF();
478 at(buffer, i, 2, ROW_NUM, 4, storage) = R_INT ? c.blue() : c.blueF();
479 at(buffer, i, 3, ROW_NUM, 4, storage) = R_INT ? c.alpha() : c.alphaF();
480
481 ++i;
482 }
483}
484
524template<MeshConcept MeshType>
526 const MeshType& mesh,
527 const std::list<uint>& vertsToDuplicate,
528 auto* buffer,
530{
531 // no vertices to duplicate, do nothing
532 if (vertsToDuplicate.empty())
533 return;
534
535 requirePerVertexColor(mesh);
536
537 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
538 const auto& c = mesh.vertex(v).color();
539 switch (colorFormat) {
540 using enum Color::Format;
541 case ABGR: buffer[i] = c.abgr(); break;
542 case ARGB: buffer[i] = c.argb(); break;
543 case RGBA: buffer[i] = c.rgba(); break;
544 case BGRA: buffer[i] = c.bgra(); break;
545 }
546 ++i;
547 }
548}
549
586template<MeshConcept MeshType>
588 const MeshType& mesh,
589 const std::list<uint>& vertsToDuplicate,
590 auto* buffer)
591{
592 // no vertices to duplicate, do nothing
593 if (vertsToDuplicate.empty())
594 return;
595
596 requirePerVertexQuality(mesh);
597
598 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
599 buffer[i] = mesh.vertex(v).quality();
600 ++i;
601 }
602}
603
645template<MeshConcept MeshType>
647 const MeshType& mesh,
648 const std::list<uint>& vertsToDuplicate,
649 auto* buffer,
650 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
651{
652 using namespace detail;
653
654 // no vertices to duplicate, do nothing
655 if (vertsToDuplicate.empty())
656 return;
657
658 requirePerVertexTexCoord(mesh);
659
660 const uint ROW_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
661
662 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
663 const auto& t = mesh.vertex(v).texCoord();
664 at(buffer, i, 0, ROW_NUM, 2, storage) = t.u();
665 at(buffer, i, 1, ROW_NUM, 2, storage) = t.v();
666
667 ++i;
668 }
669}
670
718template<MeshConcept MeshType>
720 const MeshType& mesh,
721 const std::list<uint>& vertsToDuplicate,
722 auto* buffer,
723 bool storeHandednessAsW = true,
724 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
725{
726 using namespace detail;
727
728 // no vertices to duplicate, do nothing
729 if (vertsToDuplicate.empty())
730 return;
731
732 requirePerVertexTangent(mesh);
733
734 const uint ROW_NUM = mesh.vertexNumber() + vertsToDuplicate.size();
735 const uint COL_NUM = storeHandednessAsW ? 4 : 3;
736
737 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
738 const auto& t = mesh.vertex(v).tangent();
739
740 at(buffer, i, 0, ROW_NUM, COL_NUM, storage) = t.x();
741 at(buffer, i, 1, ROW_NUM, COL_NUM, storage) = t.y();
742 at(buffer, i, 2, ROW_NUM, COL_NUM, storage) = t.z();
743 if (storeHandednessAsW) {
744 at(buffer, i, 3, ROW_NUM, COL_NUM, storage) =
745 mesh.vertex(v).tangentRightHanded() ? 1.0 : -1.0;
746 }
747
748 ++i;
749 }
750}
751
791template<MeshConcept MeshType>
793 const MeshType& mesh,
794 const std::list<uint>& vertsToDuplicate,
795 auto* buffer)
796{
797 // no vertices to duplicate, do nothing
798 if (vertsToDuplicate.empty())
799 return;
800
801 requirePerVertexMaterialIndex(mesh);
802
803 for (uint i = mesh.vertexNumber(); const auto& v : vertsToDuplicate) {
804 buffer[i] = mesh.vertex(v).materialIndex();
805 ++i;
806 }
807}
808
809} // namespace vcl
810
811#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:84
uint triangleNumber(uint polygonIndex) const
Returns the number of (consecutive index) triangles mapped to a polygon.
Definition tri_poly_index_bimap.h:113
void replaceTriangulatedFaceVertexIndicesByVertexDuplicationToBuffer(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:250
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:102
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:587
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:456
void appendDuplicateVertexMaterialIndicesToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer)
Append the material indices of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:792
void replaceFaceVertexIndicesByVertexDuplicationToBuffer(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:173
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:338
void appendDuplicateVertexTangentsToBuffer(const MeshType &mesh, const std::list< uint > &vertsToDuplicate, auto *buffer, bool storeHandednessAsW=true, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR)
Append the tangent of the duplicated vertices to the given buffer.
Definition append_replace_to_buffer.h:719
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:391
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:646
MatrixStorageType
A simple type that enumerates the main storage types for matrices (row or column major).
Definition base.h:88
uint largestFaceSize(const FaceMeshConcept auto &mesh)
Returns the largest face size in the mesh.
Definition topology.h:212