Visual Computing Library  devel
Loading...
Searching...
No Matches
export_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_EXPORT_BUFFER_H
24#define VCL_ALGORITHMS_MESH_IMPORT_EXPORT_EXPORT_BUFFER_H
25
26#include "detail.h"
27
28#include <vclib/algorithms/mesh/utility.h>
29
30#include <vclib/algorithms/core.h>
31#include <vclib/mesh.h>
32#include <vclib/space/complex.h>
33
44namespace vcl {
45
46namespace detail {
47
48inline TriPolyIndexBiMap indexMap;
49
50} // namespace detail
51
73template<MeshConcept MeshType>
75 const MeshType& mesh,
76 auto* buffer,
77 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
78 uint rowNumber = UINT_NULL)
79{
80 using namespace detail;
81
82 const uint ROW_NUM =
83 rowNumber == UINT_NULL ? mesh.vertexNumber() : rowNumber;
84 for (uint i = 0; const auto& p : mesh.vertices() | views::positions) {
85 at(buffer, i, 0, ROW_NUM, 3, storage) = p.x();
86 at(buffer, i, 1, ROW_NUM, 3, storage) = p.y();
87 at(buffer, i, 2, ROW_NUM, 3, storage) = p.z();
88 ++i;
89 }
90}
91
110template<MeshConcept MeshType>
111void vertexQuadIndicesToBuffer(const MeshType& mesh, auto* buffer)
112{
113 // creates indices for two triangles (quad) for each vertex
114 //
115 // 2-------3
116 // | \ |
117 // | \ |
118 // | \ |
119 // | \ |
120 // | \ |
121 // 0-------1
122 //
123 // - Triangle 1: [0, 1, 2]
124 // - Triangle 2: [1, 3, 2]
125 //
126 for (uint i = 0; const auto& v : mesh.vertices()) {
127 const uint baseIdx = i * 6;
128 const uint quadIdx = i * 4;
129 buffer[baseIdx + 0] = quadIdx + 0;
130 buffer[baseIdx + 1] = quadIdx + 1;
131 buffer[baseIdx + 2] = quadIdx + 2;
132 buffer[baseIdx + 3] = quadIdx + 1;
133 buffer[baseIdx + 4] = quadIdx + 3;
134 buffer[baseIdx + 5] = quadIdx + 2;
135 ++i;
136 }
137}
138
163template<FaceMeshConcept MeshType>
164uint faceSizesToBuffer(const MeshType& mesh, auto* buffer)
165{
166 uint sum = 0;
167 for (uint i = 0; const auto& f : mesh.faces()) {
168 buffer[i] = f.vertexNumber();
169 sum += f.vertexNumber();
170 ++i;
171 }
172 return sum;
173}
174
225template<FaceMeshConcept MeshType>
227 const MeshType& mesh,
228 auto* buffer,
230{
231 const std::vector<uint> vertCompIndices =
232 detail::vertCompactIndices(mesh, getIndicesAsIfContainerCompact);
233
234 // lambda to get the vertex index of a face (considering compact indices)
235 auto vIndex = detail::vIndexLambda(mesh, vertCompIndices);
236
237 for (uint i = 0; const auto& f : mesh.faces()) {
238 for (uint j = 0; j < f.vertexNumber(); ++j) {
239 buffer[i] = vIndex(f, j);
240 ++i;
241 }
242 }
243}
244
291template<FaceMeshConcept MeshType>
293 const MeshType& mesh,
294 auto* buffer,
295 uint largestFaceSize,
296 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
298 uint rowNumber = UINT_NULL)
299{
300 using namespace detail;
301
302 const std::vector<uint> vertCompIndices =
303 detail::vertCompactIndices(mesh, getIndicesAsIfContainerCompact);
304
305 // lambda to get the vertex index of a face (considering compact indices)
306 auto vIndex = detail::vIndexLambda(mesh, vertCompIndices);
307
308 const uint ROW_NUM = rowNumber == UINT_NULL ? mesh.faceNumber() : rowNumber;
309
310 for (uint i = 0; const auto& f : mesh.faces()) {
311 for (uint j = 0; j < largestFaceSize; ++j) {
312 at(buffer, i, j, ROW_NUM, largestFaceSize, storage) =
313 j < f.vertexNumber() ? vIndex(f, j) : -1;
314 }
315 ++i;
316 }
317}
318
365template<FaceMeshConcept MeshType>
367 const MeshType& mesh,
368 auto* buffer,
369 TriPolyIndexBiMap& indexMap = detail::indexMap,
370 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
371 uint numTriangles = UINT_NULL,
373{
374 using namespace detail;
375
376 const std::vector<uint> vertCompIndices =
377 detail::vertCompactIndices(mesh, getIndicesAsIfContainerCompact);
378
379 // lambda to get the vertex index of a face (considering compact indices)
380 auto vIndex = detail::vIndexLambda(mesh, vertCompIndices);
381
382 // there will be at least a triangle for each polygon
383 indexMap.clear();
384 indexMap.reserve(mesh.faceNumber(), mesh.faceContainerSize());
385
386 if constexpr (TriangleMeshConcept<MeshType>) {
387 // construct the indexMap, which maps each triangle to the face index
388 for (uint t = 0; const auto& f : mesh.faces()) {
389 // map the ith triangle to the f face
390 indexMap.insert(t, f.index());
391 ++t;
392 }
393
395 mesh, buffer, 3, storage, getIndicesAsIfContainerCompact);
396 }
397 else {
398 // if the user did not give the number of triangles, and the buffer
399 // storage is column major, we need to compute the number of resulting
400 // triangles
401 if (numTriangles == UINT_NULL &&
402 storage == MatrixStorageType::COLUMN_MAJOR &&
403 mesh.faceNumber() > 0) {
405 }
406 for (uint t = 0; const auto& f : mesh.faces()) {
407 std::vector<uint> vind = vcl::earCut(f);
408
409 // for each triangle of the triangulation (t is the triangle index)
410 for (uint vi = 0; vi < vind.size(); vi += 3) {
411 // map the t-th triangle to the f polygonal face
412 indexMap.insert(t, f.index());
413
414 for (uint k = 0; k < 3; ++k)
415 at(buffer, t, k, numTriangles, 3, storage) =
416 vIndex(f, vind[vi + k]);
417
418 ++t;
419 }
420 }
421 }
422}
423
455template<EdgeMeshConcept MeshType>
457 const MeshType& mesh,
458 auto* buffer,
459 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
461 uint rowNumber = UINT_NULL)
462{
463 using namespace detail;
464
465 const std::vector<uint> vertCompIndices =
466 detail::vertCompactIndices(mesh, getIndicesAsIfContainerCompact);
467
468 // lambda to get the vertex index of a edge (considering compact indices)
469 auto vIndex = detail::vIndexLambda(mesh, vertCompIndices);
470
471 const uint ROW_NUM = rowNumber == UINT_NULL ? mesh.edgeNumber() : rowNumber;
472
473 for (uint i = 0; const auto& e : mesh.edges()) {
474 at(buffer, i, 0, ROW_NUM, 2, storage) = vIndex(e, 0);
475 at(buffer, i, 1, ROW_NUM, 2, storage) = vIndex(e, 1);
476
477 ++i;
478 }
479}
480
510template<FaceMeshConcept MeshType>
512 const MeshType& mesh,
513 auto* buffer,
514 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
516 uint rowNumber = UINT_NULL)
517{
518 using namespace detail;
519
520 const std::vector<uint> vertCompIndices =
521 detail::vertCompactIndices(mesh, getIndicesAsIfContainerCompact);
522
523 // lambda to get the vertex index of a edge (considering compact indices)
524 auto vIndex = detail::vIndexLambda(mesh, vertCompIndices);
525
526 const uint ROW_NUM =
528
529 for (uint i = 0; const auto& f : mesh.faces()) {
530 for (uint j = 0; j < f.vertexNumber(); ++j) {
531 uint v0 = vIndex(f, j);
532 uint v1 = vIndex(f, (j + 1) % f.vertexNumber());
533
534 at(buffer, i, 0, ROW_NUM, 2, storage) = v0;
535 at(buffer, i, 1, ROW_NUM, 2, storage) = v1;
536
537 ++i;
538 }
539 }
540}
541
569template<uint ELEM_ID, MeshConcept MeshType>
570void elementSelectionToBuffer(const MeshType& mesh, auto* buffer)
571{
572 for (uint i = 0; const auto& e : mesh.template elements<ELEM_ID>()) {
573 buffer[i] = e.selected();
574 ++i;
575 }
576}
577
603template<MeshConcept MeshType>
604void vertexSelectionToBuffer(const MeshType& mesh, auto* buffer)
605{
606 elementSelectionToBuffer<ElemId::VERTEX>(mesh, buffer);
607}
608
634template<FaceMeshConcept MeshType>
635void faceSelectionToBuffer(const MeshType& mesh, auto* buffer)
636{
637 elementSelectionToBuffer<ElemId::FACE>(mesh, buffer);
638}
639
665template<EdgeMeshConcept MeshType>
666void edgeSelectionToBuffer(const MeshType& mesh, auto* buffer)
667{
668 elementSelectionToBuffer<ElemId::EDGE>(mesh, buffer);
669}
670
693template<uint ELEM_ID, MeshConcept MeshType>
694void elementNormalsToBuffer(
695 const MeshType& mesh,
696 auto* buffer,
697 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
698 uint rowNumber = UINT_NULL)
699{
700 using namespace detail;
701
702 requirePerElementComponent<ELEM_ID, CompId::NORMAL>(mesh);
703
704 const uint ROW_NUM =
705 rowNumber == UINT_NULL ? mesh.template number<ELEM_ID>() : rowNumber;
706
707 for (uint i = 0;
708 const auto& n : mesh.template elements<ELEM_ID>() | views::normals) {
709 at(buffer, i, 0, ROW_NUM, 3, storage) = n.x();
710 at(buffer, i, 1, ROW_NUM, 3, storage) = n.y();
711 at(buffer, i, 2, ROW_NUM, 3, storage) = n.z();
712
713 ++i;
714 }
715}
716
738template<MeshConcept MeshType>
739void vertexNormalsToBuffer(
740 const MeshType& mesh,
741 auto* buffer,
742 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
743 uint rowNumber = UINT_NULL)
744{
745 elementNormalsToBuffer<ElemId::VERTEX>(mesh, buffer, storage, rowNumber);
746}
747
768template<FaceMeshConcept MeshType>
769void faceNormalsToBuffer(
770 const MeshType& mesh,
771 auto* buffer,
772 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
773 uint rowNumber = UINT_NULL)
774{
775 elementNormalsToBuffer<ElemId::FACE>(mesh, buffer, storage, rowNumber);
776}
777
802template<FaceMeshConcept MeshType>
803void triangulatedFaceNormalsToBuffer(
804 const MeshType& mesh,
805 auto* buffer,
806 const TriPolyIndexBiMap& indexMap,
807 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
808 uint rowNumber = UINT_NULL)
809{
810 using namespace detail;
811
813
814 const uint ROW_NUM =
815 rowNumber == UINT_NULL ? indexMap.triangleNumber() : rowNumber;
816
817 for (const auto& f : mesh.faces()) {
818 const auto& n = f.normal();
819 uint first = indexMap.triangleBegin(f.index());
820 uint last = first + indexMap.triangleNumber(f.index());
821 for (uint t = first; t < last; ++t) {
822 at(buffer, t, 0, ROW_NUM, 3, storage) = n.x();
823 at(buffer, t, 1, ROW_NUM, 3, storage) = n.y();
824 at(buffer, t, 2, ROW_NUM, 3, storage) = n.z();
825 }
826 }
827}
828
849template<EdgeMeshConcept MeshType>
850void edgeNormalsToBuffer(
851 const MeshType& mesh,
852 auto* buffer,
853 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
854 uint rowNumber = UINT_NULL)
855{
856 elementNormalsToBuffer<ElemId::EDGE>(mesh, buffer, storage, rowNumber);
857}
858
883template<uint ELEM_ID, MeshConcept MeshType>
884void elementColorsToBuffer(
885 const MeshType& mesh,
886 auto* buffer,
887 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
888 Color::Representation representation = Color::Representation::INT_0_255,
889 uint rowNumber = UINT_NULL)
890{
891 using namespace detail;
892
893 requirePerElementComponent<ELEM_ID, CompId::COLOR>(mesh);
894
895 const bool R_INT = representation == Color::Representation::INT_0_255;
896
897 const uint ROW_NUM =
898 rowNumber == UINT_NULL ? mesh.template number<ELEM_ID>() : rowNumber;
899
900 for (uint i = 0;
901 const auto& c : mesh.template elements<ELEM_ID>() | views::colors) {
902 at(buffer, i, 0, ROW_NUM, 4, storage) = R_INT ? c.red() : c.redF();
903 at(buffer, i, 1, ROW_NUM, 4, storage) = R_INT ? c.green() : c.greenF();
904 at(buffer, i, 2, ROW_NUM, 4, storage) = R_INT ? c.blue() : c.blueF();
905 at(buffer, i, 3, ROW_NUM, 4, storage) = R_INT ? c.alpha() : c.alphaF();
906
907 ++i;
908 }
909}
910
932template<uint ELEM_ID, MeshConcept MeshType>
933void elementColorsToBuffer(
934 const MeshType& mesh,
935 auto* buffer,
936 Color::Format colorFormat)
937{
938 requirePerElementComponent<ELEM_ID, CompId::COLOR>(mesh);
939
940 for (uint i = 0;
941 const auto& c : mesh.template elements<ELEM_ID>() | views::colors) {
942 switch (colorFormat) {
943 using enum Color::Format;
944 case ABGR: buffer[i] = c.abgr(); break;
945 case ARGB: buffer[i] = c.argb(); break;
946 case RGBA: buffer[i] = c.rgba(); break;
947 case BGRA: buffer[i] = c.bgra(); break;
948 }
949 ++i;
950 }
951}
952
977template<MeshConcept MeshType>
978void vertexColorsToBuffer(
979 const MeshType& mesh,
980 auto* buffer,
981 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
982 Color::Representation representation = Color::Representation::INT_0_255,
983 uint rowNumber = UINT_NULL)
984{
985 elementColorsToBuffer<ElemId::VERTEX>(
986 mesh, buffer, storage, representation, rowNumber);
987}
988
1009template<MeshConcept MeshType>
1010void vertexColorsToBuffer(
1011 const MeshType& mesh,
1012 auto* buffer,
1013 Color::Format colorFormat)
1014{
1015 elementColorsToBuffer<ElemId::VERTEX>(mesh, buffer, colorFormat);
1016}
1017
1041template<FaceMeshConcept MeshType>
1042void faceColorsToBuffer(
1043 const MeshType& mesh,
1044 auto* buffer,
1045 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
1046 Color::Representation representation = Color::Representation::INT_0_255,
1047 uint rowNumber = UINT_NULL)
1048{
1049 elementColorsToBuffer<ElemId::FACE>(
1050 mesh, buffer, storage, representation, rowNumber);
1051}
1052
1079template<FaceMeshConcept MeshType>
1080void triangulatedFaceColorsToBuffer(
1081 const MeshType& mesh,
1082 auto* buffer,
1083 const TriPolyIndexBiMap& indexMap,
1084 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
1085 Color::Representation representation = Color::Representation::INT_0_255,
1086 uint rowNumber = UINT_NULL)
1087{
1088 using namespace detail;
1089
1090 requirePerFaceColor(mesh);
1091
1092 const bool R_INT = representation == Color::Representation::INT_0_255;
1093
1094 const uint ROW_NUM =
1095 rowNumber == UINT_NULL ? indexMap.triangleNumber() : rowNumber;
1096
1097 for (const auto& f : mesh.faces()) {
1098 const auto& c = f.color();
1099 uint first = indexMap.triangleBegin(f.index());
1100 uint last = first + indexMap.triangleNumber(f.index());
1101 for (uint t = first; t < last; ++t) {
1102 at(buffer, t, 0, ROW_NUM, 4, storage) = R_INT ? c.red() : c.redF();
1103 at(buffer, t, 1, ROW_NUM, 4, storage) =
1104 R_INT ? c.green() : c.greenF();
1105 at(buffer, t, 2, ROW_NUM, 4, storage) =
1106 R_INT ? c.blue() : c.blueF();
1107 at(buffer, t, 3, ROW_NUM, 4, storage) =
1108 R_INT ? c.alpha() : c.alphaF();
1109 }
1110 }
1111}
1112
1133template<FaceMeshConcept MeshType>
1134void faceColorsToBuffer(
1135 const MeshType& mesh,
1136 auto* buffer,
1137 Color::Format colorFormat)
1138{
1139 elementColorsToBuffer<ElemId::FACE>(mesh, buffer, colorFormat);
1140}
1141
1165template<FaceMeshConcept MeshType>
1166void triangulatedFaceColorsToBuffer(
1167 const MeshType& mesh,
1168 auto* buffer,
1169 const TriPolyIndexBiMap& indexMap,
1170 Color::Format colorFormat)
1171{
1172 requirePerElementComponent<ElemId::FACE, CompId::COLOR>(mesh);
1173
1174 for (const auto& f : mesh.faces()) {
1175 const auto& c = f.color();
1176 uint first = indexMap.triangleBegin(f.index());
1177 uint last = first + indexMap.triangleNumber(f.index());
1178 for (uint t = first; t < last; ++t) {
1179 switch (colorFormat) {
1180 using enum Color::Format;
1181 case ABGR: buffer[t] = c.abgr(); break;
1182 case ARGB: buffer[t] = c.argb(); break;
1183 case RGBA: buffer[t] = c.rgba(); break;
1184 case BGRA: buffer[t] = c.bgra(); break;
1185 }
1186 }
1187 }
1188}
1189
1213template<EdgeMeshConcept MeshType>
1214void edgeColorsToBuffer(
1215 const MeshType& mesh,
1216 auto* buffer,
1217 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
1218 Color::Representation representation = Color::Representation::INT_0_255,
1219 uint rowNumber = UINT_NULL)
1220{
1221 elementColorsToBuffer<ElemId::EDGE>(
1222 mesh, buffer, storage, representation, rowNumber);
1223}
1224
1245template<EdgeMeshConcept MeshType>
1246void edgeColorsToBuffer(
1247 const MeshType& mesh,
1248 auto* buffer,
1249 Color::Format colorFormat)
1250{
1251 elementColorsToBuffer<ElemId::EDGE>(mesh, buffer, colorFormat);
1252}
1253
1273template<uint ELEM_ID, MeshConcept MeshType>
1274void elementQualityToBuffer(const MeshType& mesh, auto* buffer)
1275{
1276 requirePerElementComponent<ELEM_ID, CompId::QUALITY>(mesh);
1277
1278 for (uint i = 0;
1279 const auto& q : mesh.template elements<ELEM_ID>() | views::quality) {
1280 buffer[i] = q;
1281 ++i;
1282 }
1283}
1284
1303template<MeshConcept MeshType>
1304void vertexQualityToBuffer(const MeshType& mesh, auto* buffer)
1305{
1306 elementQualityToBuffer<ElemId::VERTEX>(mesh, buffer);
1307}
1308
1326template<MeshConcept MeshType>
1327void faceQualityToBuffer(const MeshType& mesh, auto* buffer)
1328{
1329 elementQualityToBuffer<ElemId::FACE>(mesh, buffer);
1330}
1331
1349template<MeshConcept MeshType>
1350void edgeQualityToBuffer(const MeshType& mesh, auto* buffer)
1351{
1352 elementQualityToBuffer<ElemId::FACE>(mesh, buffer);
1353}
1354
1381template<MeshConcept MeshType>
1382void vertexTangentsToBuffer(
1383 const MeshType& mesh,
1384 auto* buffer,
1385 bool storeHandednessAsW = true,
1386 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
1387 uint rowNumber = UINT_NULL)
1388{
1389 using namespace detail;
1390
1391 requirePerVertexTangent(mesh);
1392
1393 const uint ROW_NUM =
1394 rowNumber == UINT_NULL ? mesh.vertexNumber() : rowNumber;
1395 const uint COL_NUM = storeHandednessAsW ? 4 : 3;
1396
1397 for (uint i = 0; const auto& v : mesh.vertices()) {
1398 at(buffer, i, 0, ROW_NUM, COL_NUM, storage) = v.tangent().x();
1399 at(buffer, i, 1, ROW_NUM, COL_NUM, storage) = v.tangent().y();
1400 at(buffer, i, 2, ROW_NUM, COL_NUM, storage) = v.tangent().z();
1401 if (storeHandednessAsW) {
1402 at(buffer, i, 3, ROW_NUM, COL_NUM, storage) =
1403 v.tangentRightHanded() ? 1.0 : -1.0;
1404 }
1405
1406 ++i;
1407 }
1408}
1409
1431template<MeshConcept MeshType>
1432void vertexTexCoordsToBuffer(
1433 const MeshType& mesh,
1434 auto* buffer,
1435 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
1436 uint rowNumber = UINT_NULL)
1437{
1438 using namespace detail;
1439
1440 requirePerVertexTexCoord(mesh);
1441
1442 const uint ROW_NUM =
1443 rowNumber == UINT_NULL ? mesh.vertexNumber() : rowNumber;
1444
1445 for (uint i = 0; const auto& t : mesh.vertices() | views::texCoords) {
1446 at(buffer, i, 0, ROW_NUM, 2, storage) = t.u();
1447 at(buffer, i, 1, ROW_NUM, 2, storage) = t.v();
1448
1449 ++i;
1450 }
1451}
1452
1471template<MeshConcept MeshType>
1472void vertexMaterialIndicesToBuffer(const MeshType& mesh, auto* buffer)
1473{
1474 requirePerVertexMaterialIndex(mesh);
1475
1476 for (uint i = 0; const auto& v : mesh.vertices()) {
1477 buffer[i] = v.materialIndex();
1478 ++i;
1479 }
1480}
1481
1505template<FaceMeshConcept MeshType>
1506void vertexMaterialIndicesAsFaceMaterialIndicesToBuffer(
1507 const MeshType& mesh,
1508 auto* buffer)
1509{
1510 requirePerVertexMaterialIndex(mesh);
1511
1512 for (uint i = 0; const auto& f : mesh.faces()) {
1513 ushort ti = f.vertex(0)->materialIndex();
1514 buffer[i] = ti;
1515 ++i;
1516 }
1517}
1518
1543template<FaceMeshConcept MeshType>
1544void vertexMaterialIndicesAsTriangulatedFaceMaterialIndicesToBuffer(
1545 const MeshType& mesh,
1546 auto* buffer,
1547 const TriPolyIndexBiMap& indexMap)
1548{
1549 requirePerVertexMaterialIndex(mesh);
1550
1551 for (const auto& f : mesh.faces()) {
1552 ushort ti = f.vertex(0)->materialIndex();
1553 uint first = indexMap.triangleBegin(f.index());
1554 uint last = first + indexMap.triangleNumber(f.index());
1555 for (uint t = first; t < last; ++t) {
1556 buffer[t] = ti;
1557 }
1558 }
1559}
1560
1598template<FaceMeshConcept MeshType>
1600 const MeshType& mesh,
1601 auto* buffer,
1602 uint largestFaceSize = 3,
1603 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
1604 uint rowNumber = UINT_NULL)
1605{
1607
1608 const uint ROW_NUM = rowNumber == UINT_NULL ? mesh.faceNumber() : rowNumber;
1609
1610 for (uint i = 0; const auto& f : mesh.faces()) {
1611 for (uint j = 0; j < largestFaceSize * 2; ++j) {
1612 uint fi = j / 2;
1613 uint index = i * largestFaceSize * 2 + j;
1614 if (storage == MatrixStorageType::COLUMN_MAJOR)
1615 index = j * ROW_NUM + i;
1616 if (fi < f.vertexNumber()) {
1617 const auto& w = f.wedgeTexCoord(fi);
1618 if (j % 2 == 0)
1619 buffer[index] = w.u();
1620 else
1621 buffer[index] = w.v();
1622 }
1623 else {
1624 buffer[index] = 0;
1625 }
1626 }
1627 ++i;
1628 }
1629}
1630
1649template<FaceMeshConcept MeshType>
1650void faceMaterialIndicesToBuffer(const MeshType& mesh, auto* buffer)
1651{
1653
1654 for (uint i = 0; const auto& f : mesh.faces()) {
1655 buffer[i] = f.materialIndex();
1656 ++i;
1657 }
1658}
1659
1681template<FaceMeshConcept MeshType>
1683 const MeshType& mesh,
1684 auto* buffer,
1685 const TriPolyIndexBiMap& indexMap)
1686{
1688
1689 for (const auto& f : mesh.faces()) {
1690 uint first = indexMap.triangleBegin(f.index());
1691 uint last = first + indexMap.triangleNumber(f.index());
1692 for (uint t = first; t < last; ++t) {
1693 buffer[t] = f.materialIndex();
1694 }
1695 }
1696}
1697
1742template<FaceMeshConcept MeshType>
1744 const MeshType& mesh,
1745 const std::vector<std::pair<vcl::uint, vcl::uint>>& vertWedgeMap,
1746 const std::list<std::list<std::pair<vcl::uint, vcl::uint>>>&
1748 auto* buffer,
1749 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR)
1750{
1751 using namespace detail;
1752 using TexCoordType = typename MeshType::FaceType::WedgeTexCoordType;
1753
1755
1756 const uint ROW_NUM = mesh.vertexNumber() + facesToReassign.size();
1757
1758 // first export the texcoords of the non-duplicated vertices, using the
1759 // vertWedgeMap to get the texcoord index in the face
1760 uint vi = 0; // current vertex (or current row in the matrix)
1761 for (const auto& v : mesh.vertices()) {
1762 TexCoordType w;
1763 uint fInd = vertWedgeMap[vi].first;
1764 uint wInd = vertWedgeMap[vi].second;
1765
1766 // check if the vi is referenced
1767 if (fInd != UINT_NULL && wInd != UINT_NULL) {
1768 w = mesh.face(fInd).wedgeTexCoord(wInd);
1769 }
1770 at(buffer, vi, 0, ROW_NUM, 2, storage) = w.u();
1771 at(buffer, vi, 1, ROW_NUM, 2, storage) = w.v();
1772
1773 ++vi;
1774 }
1775
1776 // then append the texcoords of the duplicated vertices, that can be found
1777 // by looking into the any of the facesToReassign element lists
1778 for (const auto& list : facesToReassign) {
1779 assert(list.begin() != list.end());
1780 const auto& p = list.front();
1781 uint fInd = p.first;
1782 uint wInd = p.second;
1783
1784 const auto& w = mesh.face(fInd).wedgeTexCoord(wInd);
1785 at(buffer, vi, 0, ROW_NUM, 2, storage) = w.u();
1786 at(buffer, vi, 1, ROW_NUM, 2, storage) = w.v();
1787
1788 ++vi;
1789 }
1790}
1791
1834template<FaceMeshConcept MeshType>
1836 const MeshType& mesh,
1837 const std::vector<std::pair<vcl::uint, vcl::uint>>& vertWedgeMap,
1838 const std::list<std::list<std::pair<vcl::uint, vcl::uint>>>&
1840 auto* buffer)
1841{
1843
1844 const uint VERT_NUM = mesh.vertexNumber() + facesToReassign.size();
1845
1846 // first export the material indices of the non-duplicated vertices, using
1847 // the vertWedgeMap to get the material index in the face
1848 uint vi = 0; // current vertex (or current row in the matrix)
1849 for (const auto& v : mesh.vertices()) {
1850 uint fInd = vertWedgeMap[vi].first;
1851 ushort ti = mesh.face(fInd).materialIndex();
1852 buffer[vi] = ti;
1853 ++vi;
1854 }
1855
1856 // then append the material indices of the duplicated vertices, that can be
1857 // found by looking into the any of the facesToReassign element lists
1858 for (const auto& list : facesToReassign) {
1859 assert(list.begin() != list.end());
1860 const auto& p = list.front();
1861 uint fInd = p.first;
1862
1863 ushort ti = mesh.face(fInd).materialIndex();
1864 buffer[vi] = ti;
1865 ++vi;
1866 }
1867}
1868
1898template<MeshConcept MeshType>
1900 const MeshType& mesh,
1901 auto* buffer,
1903 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
1904 uint rowNumber = UINT_NULL)
1905{
1906 using namespace detail;
1907
1908 requireVertexContainerCompactness(mesh);
1909 requirePerVertexAdjacentVertices(mesh);
1910
1911 const uint ROW_NUM =
1912 rowNumber == UINT_NULL ? mesh.vertexNumber() : rowNumber;
1913
1915
1916 for (uint i = 0; const auto& v : mesh.vertices()) {
1917 uint adjIndex = 0;
1918 for (const auto* a : v.adjVertices()) {
1919 uint idx = a ? a->index() : UINT_NULL;
1920 at(buffer, i, adjIndex, ROW_NUM, COL_NUM, storage) = idx;
1921 ++adjIndex;
1922 }
1923 // fill the remaining entries with UINT_NULL
1924 for (; adjIndex < COL_NUM; ++adjIndex) {
1925 at(buffer, i, adjIndex, ROW_NUM, COL_NUM, storage) = UINT_NULL;
1926 }
1927 ++i;
1928 }
1929}
1930
1959template<uint ELEM_ID, FaceMeshConcept MeshType>
1961 const MeshType& mesh,
1962 auto* buffer,
1964 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
1965 uint rowNumber = UINT_NULL)
1966{
1967 using namespace detail;
1968
1971
1972 const uint ROW_NUM =
1973 rowNumber == UINT_NULL ? mesh.template number<ELEM_ID>() : rowNumber;
1974
1975 const uint COL_NUM = largestAdjacentFacesSize;
1976
1977 for (uint i = 0; const auto& v : mesh.template elements<ELEM_ID>()) {
1978 uint adjIndex = 0;
1979 for (const auto* a : v.adjFaces()) {
1980 uint idx = a ? a->index() : UINT_NULL;
1981 at(buffer, i, adjIndex, ROW_NUM, COL_NUM, storage) = idx;
1982 ++adjIndex;
1983 }
1984 // fill the remaining entries with UINT_NULL
1985 for (; adjIndex < COL_NUM; ++adjIndex) {
1986 at(buffer, i, adjIndex, ROW_NUM, COL_NUM, storage) = UINT_NULL;
1987 }
1988 ++i;
1989 }
1990}
1991
2020template<FaceMeshConcept MeshType>
2022 const MeshType& mesh,
2023 auto* buffer,
2025 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
2026 uint rowNumber = UINT_NULL)
2027{
2030}
2031
2053template<FaceMeshConcept MeshType>
2055 const MeshType& mesh,
2056 auto* buffer,
2057 uint largestFacesSize,
2058 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
2059 uint rowNumber = UINT_NULL)
2060{
2062 mesh, buffer, largestFacesSize, storage, rowNumber);
2063}
2064
2093template<FaceMeshConcept MeshType>
2095 const MeshType& mesh,
2096 auto* buffer,
2098 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
2100{
2103}
2104
2133template<uint ELEM_ID, EdgeMeshConcept MeshType>
2135 const MeshType& mesh,
2136 auto* buffer,
2138 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
2139 uint rowNumber = UINT_NULL)
2140{
2141 using namespace detail;
2142
2145
2146 const uint ROW_NUM =
2147 rowNumber == UINT_NULL ? mesh.template number<ELEM_ID>() : rowNumber;
2148
2149 const uint COL_NUM = largestAdjacentEdgesSize;
2150
2151 for (uint i = 0; const auto& v : mesh.template elements<ELEM_ID>()) {
2152 uint adjIndex = 0;
2153 for (const auto* a : v.adjEdges()) {
2154 uint idx = a ? a->index() : UINT_NULL;
2155 at(buffer, i, adjIndex, ROW_NUM, COL_NUM, storage) = idx;
2156 ++adjIndex;
2157 }
2158 // fill the remaining entries with UINT_NULL
2159 for (; adjIndex < COL_NUM; ++adjIndex) {
2160 at(buffer, i, adjIndex, ROW_NUM, COL_NUM, storage) = UINT_NULL;
2161 }
2162 ++i;
2163 }
2164}
2165
2194template<EdgeMeshConcept MeshType>
2196 const MeshType& mesh,
2197 auto* buffer,
2199 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
2200 uint rowNumber = UINT_NULL)
2201{
2204}
2205
2234template<EdgeMeshConcept MeshType>
2236 const MeshType& mesh,
2237 auto* buffer,
2239 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
2241{
2244}
2245
2274template<EdgeMeshConcept MeshType>
2276 const MeshType& mesh,
2277 auto* buffer,
2279 MatrixStorageType storage = MatrixStorageType::ROW_MAJOR,
2280 uint rowNumber = UINT_NULL)
2281{
2284}
2285
2286} // namespace vcl
2287
2288#endif // VCL_ALGORITHMS_MESH_IMPORT_EXPORT_EXPORT_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
void reserve(uint nTriangles, uint nPolygons)
Reserves enogh memory for the BiMap. Allows fast insertions.
Definition tri_poly_index_bimap.h:141
void insert(uint triangleIndex, uint polygonIndex)
Performs an insertion into the BiMap, and associates:
Definition tri_poly_index_bimap.h:162
void clear()
Clears the BiMap.
Definition tri_poly_index_bimap.h:127
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
The EdgeMeshConcept is evaluated true if the type T is a Mesh (it satisfies the vcl::MeshConcept) and...
Definition edge_requirements.h:58
The FaceMeshConcept is evaluated true if the type T is a Mesh (it satisfies the vcl::MeshConcept) and...
Definition face_requirements.h:70
Definition face_requirements.h:73
void wedgeTexCoordsAsDuplicatedVertexTexCoordsToBuffer(const MeshType &mesh, const std::vector< std::pair< vcl::uint, vcl::uint > > &vertWedgeMap, const std::list< std::list< std::pair< vcl::uint, vcl::uint > > > &facesToReassign, auto *buffer, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR)
Export wedge texture coordinates to a buffer of the duplicated vertex texture coordinates.
Definition export_buffer.h:1743
void faceMaterialIndicesAsDuplicatedVertexMaterialIndicesToBuffer(const MeshType &mesh, const std::vector< std::pair< vcl::uint, vcl::uint > > &vertWedgeMap, const std::list< std::list< std::pair< vcl::uint, vcl::uint > > > &facesToReassign, auto *buffer)
Export face material indices to a buffer of the duplicated vertex material indices.
Definition export_buffer.h:1835
MatrixStorageType
A simple type that enumerates the main storage types for matrices (row or column major).
Definition base.h:88
constexpr uint UINT_NULL
The UINT_NULL value represent a null value of uint that is the maximum value that can be represented ...
Definition base.h:48
std::vector< uint > earCut(Iterator begin, Iterator end)
Triangulates a simple polygon with no holes using the ear-cutting algorithm.
Definition ear_cut.h:90
void requireEdgeContainerCompactness(const MeshType &m)
This function asserts that a Mesh has the EdgeContainer compact (no elements flagged as deleted).
Definition edge_requirements.h:597
void vertexPositionsToBuffer(const MeshType &mesh, auto *buffer, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export the vertex positions of a mesh to a buffer.
Definition export_buffer.h:74
void edgeVertexIndicesToBuffer(const MeshType &mesh, auto *buffer, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, bool getIndicesAsIfContainerCompact=true, uint rowNumber=UINT_NULL)
Export into a buffer the vertex indices for each edge of a Mesh.
Definition export_buffer.h:456
void wireframeVertexIndicesToBuffer(const MeshType &mesh, auto *buffer, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, bool getIndicesAsIfContainerCompact=true, uint rowNumber=UINT_NULL)
Export into a buffer the vertex indices for each edge that composes the wireframe of the Mesh (i....
Definition export_buffer.h:511
void triangulatedFaceVertexIndicesToBuffer(const MeshType &mesh, auto *buffer, TriPolyIndexBiMap &indexMap=detail::indexMap, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint numTriangles=UINT_NULL, bool getIndicesAsIfContainerCompact=true)
Export into a buffer the vertex indices for each triangle computed by triangulating the faces of a Me...
Definition export_buffer.h:366
void vertexAdjacentEdgesToBuffer(const MeshType &mesh, auto *buffer, uint largestAdjacentEdgesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent edges indices for each vertex of a Mesh. The number of adjacent edg...
Definition export_buffer.h:2195
void faceAdjacentEdgesToBuffer(const MeshType &mesh, auto *buffer, uint largestAdjacentEdgesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent edges indices for each face of a Mesh. The number of adjacent edges...
Definition export_buffer.h:2235
void elementAdjacentEdgesToBuffer(const MeshType &mesh, auto *buffer, uint largestAdjacentEdgesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent edges indices for each ELEM_ID element of a Mesh....
Definition export_buffer.h:2134
void vertexAdjacentVerticesToBuffer(const MeshType &mesh, auto *buffer, uint largestAdjacentVerticesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent vertex indices for each vertex of a Mesh. The number of adjacent ve...
Definition export_buffer.h:1899
void faceAdjacentFacesToBuffer(const MeshType &mesh, auto *buffer, uint largestFacesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent faces indices for each face of a Mesh. The number of adjacent faces...
Definition export_buffer.h:2054
void edgeAdjacentFacesToBuffer(const MeshType &mesh, auto *buffer, uint largestAdjacentFacesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent faces indices for each edge of a Mesh. The number of adjacent faces...
Definition export_buffer.h:2094
void vertexAdjacentFacesToBuffer(const MeshType &mesh, auto *buffer, uint largestAdjacentFacesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent faces indices for each vertex of a Mesh. The number of adjacent fac...
Definition export_buffer.h:2021
void triangulatedFaceMaterialIndicesToBuffer(const MeshType &mesh, auto *buffer, const TriPolyIndexBiMap &indexMap)
Export into a buffer the per triangle material indices of a mesh. Triangles are computed by triangula...
Definition export_buffer.h:1682
void faceVertexIndicesToBuffer(const MeshType &mesh, auto *buffer, bool getIndicesAsIfContainerCompact=true)
Export into a buffer the vertex indices for each face of a Mesh. Faces can be polygons.
Definition export_buffer.h:226
void edgeAdjacentEdgesToBuffer(const MeshType &mesh, auto *buffer, uint largestAdjacentEdgesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent edges indices for each edge of a Mesh. The number of adjacent edges...
Definition export_buffer.h:2275
void faceWedgeTexCoordsToBuffer(const MeshType &mesh, auto *buffer, uint largestFaceSize=3, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export the selection status of the elements identified by ELEM_ID of a mesh to a buffer.
Definition export_buffer.h:1599
void vertexQuadIndicesToBuffer(const MeshType &mesh, auto *buffer)
Export the indices of a quad per vertex to a buffer.
Definition export_buffer.h:111
uint faceSizesToBuffer(const MeshType &mesh, auto *buffer)
Export into a buffer the sizes of the faces of a Mesh, and return the sum of the sizes.
Definition export_buffer.h:164
void elementAdjacentFacesToBuffer(const MeshType &mesh, auto *buffer, uint largestAdjacentFacesSize, MatrixStorageType storage=MatrixStorageType::ROW_MAJOR, uint rowNumber=UINT_NULL)
Export into a buffer the adjacent faces indices for each ELEM_ID element of a Mesh....
Definition export_buffer.h:1960
void faceMaterialIndicesToBuffer(const MeshType &mesh, auto *buffer)
Export into a buffer the per face material indices of a mesh.
Definition export_buffer.h:1650
void requirePerFaceWedgeTexCoords(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a WedgeTexCoords Component,...
Definition face_requirements.h:1322
void requirePerFaceMaterialIndex(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a MaterialIndex Component,...
Definition face_requirements.h:1143
void requireFaceContainerCompactness(const MeshType &m)
This function asserts that a Mesh has the FaceContainer compact (no elements flagged as deleted).
Definition face_requirements.h:966
void requirePerFaceNormal(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Normal Component,...
Definition face_requirements.h:1179
void requirePerFaceColor(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Color Component,...
Definition face_requirements.h:1073
uint countPerFaceVertexReferences(const FaceMeshConcept auto &mesh)
Count the number of references to vertices in the mesh faces.
Definition topology.h:182
uint largestFaceSize(const FaceMeshConcept auto &mesh)
Returns the largest face size in the mesh.
Definition topology.h:212
uint countTriangulatedTriangles(const FaceMeshConcept auto &mesh)
Counts the number of resulting triangles if the input mesh would be triangulated by splitting each fa...
Definition topology.h:240
constexpr detail::FacesView faces
A view that allows to iterate overt the Face elements of an object.
Definition face.h:84