Visual Computing Library  devel
Loading...
Searching...
No Matches
mesh_info.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_MESH_INFO_H
24#define VCL_SPACE_COMPLEX_MESH_INFO_H
25
26#include <vclib/mesh.h>
27#include <vclib/base.h>
28
29#include <array>
30#include <bitset>
31#include <string>
32#include <typeindex>
33#include <vector>
34
35namespace vcl {
36
76{
77public:
82 enum class MeshType { TRIANGLE_MESH, QUAD_MESH, POLYGON_MESH, UNKNOWN };
83
91 enum Element { VERTEX, FACE, EDGE, MESH, NUM_ELEMENTS };
92
97 enum Component {
98 POSITION,
99 VREFS,
100 NORMAL,
101 COLOR,
102 QUALITY,
103 TEXCOORD,
104 WEDGE_TEXCOORDS,
105 CUSTOM_COMPONENTS,
106 TEXTURES,
107 NUM_COMPONENTS
108 };
109
114
120 {
121 std::string name;
122 DataType type;
123
124 CustomComponent(std::string n, DataType t) : name(n), type(t) {}
125 };
126
127private:
128 // Tell if elements are present in the file
129 std::bitset<NUM_ELEMENTS> mElements = {false};
130
131 // Tell if per element components are present in the file
132 std::array<std::bitset<NUM_COMPONENTS>, NUM_ELEMENTS> mPerElemComponents = {
133 false};
134
135 // Tell the data type for each component of each element
136 Eigen::Matrix<DataType, NUM_ELEMENTS, NUM_COMPONENTS>
137 mPerElemComponentsType;
138
139 // Store name and type of per element custom components
140 std::array<std::vector<CustomComponent>, NUM_ELEMENTS>
141 mPerElemCustomComponents;
142
143 // Mesh Type
144 MeshType mType = MeshType::UNKNOWN;
145
146public:
153 MeshInfo() { mPerElemComponentsType.fill(PrimitiveType::NONE); }
154
164 template<MeshConcept Mesh>
166 {
167 setVertices();
168 setPerVertexPosition(
169 true,
171 if constexpr (HasPerVertexNormal<Mesh>) {
172 if (isPerVertexNormalAvailable(m)) {
173 setPerVertexNormal(
174 true,
175 getType<
176 typename Mesh::VertexType::NormalType::ScalarType>());
177 }
178 }
179 if constexpr (HasPerVertexColor<Mesh>) {
180 if (isPerVertexColorAvailable(m)) {
181 setPerVertexColor(true, PrimitiveType::UCHAR);
182 }
183 }
184 if constexpr (HasPerVertexQuality<Mesh>) {
185 if (isPerVertexQualityAvailable(m)) {
186 setPerVertexQuality(
188 }
189 }
190 if constexpr (HasPerVertexTexCoord<Mesh>) {
191 if (isPerVertexTexCoordAvailable(m)) {
192 setPerVertexTexCoord(
193 true,
194 getType<
195 typename Mesh::VertexType::TexCoordType::ScalarType>());
196 }
197 }
199 auto names = m.perVertexCustomComponentNames();
200 for (auto& name : names) {
201 DataType dt = getType(m.perVertexCustomComponentType(name));
202 if (dt != PrimitiveType::NONE) {
203 addPerVertexCustomComponent(name, dt);
204 }
205 }
206 }
207
208 if constexpr (HasFaces<Mesh>) {
209 setFaces();
210 setPerFaceVertexReferences();
211 if (HasTriangles<Mesh>) {
212 setTriangleMesh();
213 }
214 else if (HasQuads<Mesh>) {
215 setQuadMesh();
216 }
217 else {
218 setPolygonMesh();
219 }
220 if constexpr (HasPerFaceNormal<Mesh>) {
222 setPerFaceNormal(
223 true,
224 getType<
225 typename Mesh::FaceType::NormalType::ScalarType>());
226 }
227 }
228 if constexpr (HasPerFaceColor<Mesh>) {
230 setPerFaceColor(true, PrimitiveType::UCHAR);
231 }
232 }
233 if constexpr (HasPerFaceQuality<Mesh>) {
235 setPerFaceQuality(
237 }
238 }
239 if constexpr (HasPerFaceWedgeTexCoords<Mesh>) {
241 setPerFaceWedgeTexCoords(
242 true,
243 getType<typename Mesh::FaceType::WedgeTexCoordType::
244 ScalarType>());
245 }
246 }
247 if constexpr (HasPerFaceCustomComponents<Mesh>) {
248 auto names = m.perFaceCustomComponentNames();
249 for (auto& name : names) {
250 DataType dt = getType(m.perFaceCustomComponentType(name));
251 if (dt != PrimitiveType::NONE) {
252 addPerFaceCustomComponent(name, dt);
253 }
254 }
255 }
256 }
257
258 if constexpr (HasEdges<Mesh>) {
259 setEdges();
260 setPerEdgeVertexReferences();
261 // if constexpr (HasPerEdgeColor<Mesh>)
262 // if (isPerEdgeColorAvailable(m))
263 // setEdgeColors(true, UCHAR);
264 }
265
266 if constexpr (HasTexturePaths<Mesh>) {
267 if (m.textureNumber() > 0) {
268 setTextures(true);
269 }
270 }
271 }
272
279 void clear()
280 {
281 mElements.reset();
282 for (auto& comp : mPerElemComponents)
283 comp.reset();
284 mPerElemComponentsType.fill(PrimitiveType::NONE);
285
286 for (auto& v : mPerElemCustomComponents)
287 v.clear();
288
289 mType = MeshType::UNKNOWN;
290 }
291
296 bool isEmpty() const { return !mElements.any(); }
297
298 MeshType meshType() const { return mType; }
299
300 bool isUnkownMesh() const { return mType == MeshType::UNKNOWN; }
301
307 bool isTriangleMesh() const { return mType == MeshType::TRIANGLE_MESH; }
308
314 bool isQuadMesh() const { return mType == MeshType::QUAD_MESH; }
315
321 bool isPolygonMesh() const { return mType == MeshType::POLYGON_MESH; }
322
323 /*
324 * Getter Elements/Components functions: they are used mostly after the
325 * loading of a Mesh from a file, to know if Elements/Components have been
326 * loaded.
327 */
328
329 bool hasElement(Element el) const { return mElements[el]; }
330
331 bool hasPerElementComponent(Element el, Component comp) const
332 {
333 return mPerElemComponents[el][comp];
334 }
335
340 bool hasVertices() const { return hasElement(VERTEX); }
341
347 {
348 return hasPerElementComponent(VERTEX, POSITION);
349 }
350
356 {
357 return hasPerElementComponent(VERTEX, NORMAL);
358 }
359
364 bool hasPerVertexColor() const
365 {
366 return hasPerElementComponent(VERTEX, COLOR);
367 }
368
374 {
375 return hasPerElementComponent(VERTEX, QUALITY);
376 }
377
383 {
384 return hasPerElementComponent(VERTEX, TEXCOORD);
385 }
386
392 {
393 return hasPerElementComponent(VERTEX, CUSTOM_COMPONENTS);
394 }
395
400 bool hasFaces() const { return hasElement(FACE); }
401
407 {
408 return hasPerElementComponent(FACE, VREFS);
409 }
410
411 bool hasPerFaceNormal() const
412 {
413 return hasPerElementComponent(FACE, NORMAL);
414 }
415
416 bool hasPerFaceColor() const { return hasPerElementComponent(FACE, COLOR); }
417
418 bool hasPerFaceQuality() const
419 {
420 return hasPerElementComponent(FACE, QUALITY);
421 }
422
423 bool hasPerFaceWedgeTexCoords() const
424 {
425 return hasPerElementComponent(FACE, WEDGE_TEXCOORDS);
426 }
427
428 bool hasPerFaceCustomComponents() const
429 {
430 return hasPerElementComponent(FACE, CUSTOM_COMPONENTS);
431 }
432
437 bool hasEdges() const { return hasElement(EDGE); }
438
439 bool hasPerEdgeVertexReferences() const
440 {
441 return hasPerElementComponent(EDGE, VREFS);
442 }
443
444 bool hasPerEdgeColor() const { return hasPerElementComponent(EDGE, COLOR); }
445
446 bool hasPerEdgeNormal() const
447 {
448 return hasPerElementComponent(EDGE, NORMAL);
449 }
450
451 bool hasPerEdgeQuality() const
452 {
453 return hasPerElementComponent(EDGE, QUALITY);
454 }
455
456 bool hasPerEdgeCustomComponents() const
457 {
458 return hasPerElementComponent(EDGE, CUSTOM_COMPONENTS);
459 }
460
461 bool hasTextures() const { return hasPerElementComponent(MESH, TEXTURES); }
462
463 /*
464 * Setter functions: they are used by the load functions to tell which
465 * Elements/Components are loaded from a file, and they can be used by the
466 * user that wants to save in a file only a specific set of
467 * Elements/Components of a Mesh.
468 */
469
470 void updateMeshType(uint faceSize)
471 {
472 if (mType == MeshType::UNKNOWN) {
473 if (faceSize == 3)
474 setTriangleMesh();
475 else if (faceSize == 4)
476 setQuadMesh();
477 else
478 setPolygonMesh();
479 }
480 else if (mType == MeshType::TRIANGLE_MESH && faceSize != 3) {
481 setPolygonMesh();
482 }
483 else if (mType == MeshType::QUAD_MESH && faceSize != 4) {
484 setPolygonMesh();
485 }
486 }
487
488 void setUnknownMesh() { mType = MeshType::UNKNOWN; }
489
490 void setTriangleMesh() { mType = MeshType::TRIANGLE_MESH; }
491
492 void setQuadMesh() { mType = MeshType::QUAD_MESH; }
493
494 void setPolygonMesh() { mType = MeshType::POLYGON_MESH; }
495
496 void setMeshType(MeshType t) { mType = t; }
497
498 void setElement(Element el, bool b = true) { mElements[el] = b; }
499
500 void setPerElementComponent(Element el, Component c, bool b, DataType t)
501 {
502 mElements[el] = b;
503 mPerElemComponents[el][c] = b;
504 if (b)
505 mPerElemComponentsType(el, c) = t;
506 }
507
508 void setVertices(bool b = true) { setElement(VERTEX, b); }
509
510 void setPerVertexPosition(bool b = true, DataType t = PrimitiveType::DOUBLE)
511 {
512 setPerElementComponent(VERTEX, POSITION, b, t);
513 }
514
515 void setPerVertexNormal(bool b = true, DataType t = PrimitiveType::FLOAT)
516 {
517 setPerElementComponent(VERTEX, NORMAL, b, t);
518 }
519
520 void setPerVertexColor(bool b = true, DataType t = PrimitiveType::UCHAR)
521 {
522 setPerElementComponent(VERTEX, COLOR, b, t);
523 }
524
525 void setPerVertexQuality(bool b = true, DataType t = PrimitiveType::DOUBLE)
526 {
527 setPerElementComponent(VERTEX, QUALITY, b, t);
528 }
529
530 void setPerVertexTexCoord(bool b = true, DataType t = PrimitiveType::FLOAT)
531 {
532 setPerElementComponent(VERTEX, TEXCOORD, b, t);
533 }
534
535 void setPerVertexCustomComponents(bool b = true)
536 {
537 setPerElementComponent(
538 VERTEX, CUSTOM_COMPONENTS, b, PrimitiveType::NONE);
539 }
540
541 void setFaces(bool b = true) { setElement(FACE, b); }
542
543 void setPerFaceVertexReferences(bool b = true)
544 {
545 setPerElementComponent(FACE, VREFS, b, PrimitiveType::NONE);
546 }
547
548 void setPerFaceNormal(bool b = true, DataType t = PrimitiveType::FLOAT)
549 {
550 setPerElementComponent(FACE, NORMAL, b, t);
551 }
552
553 void setPerFaceColor(bool b = true, DataType t = PrimitiveType::UCHAR)
554 {
555 setPerElementComponent(FACE, COLOR, b, t);
556 }
557
558 void setPerFaceQuality(bool b = true, DataType t = PrimitiveType::DOUBLE)
559 {
560 setPerElementComponent(FACE, QUALITY, b, t);
561 }
562
563 void setPerFaceWedgeTexCoords(
564 bool b = true,
565 DataType t = PrimitiveType::FLOAT)
566 {
567 setPerElementComponent(FACE, WEDGE_TEXCOORDS, b, t);
568 }
569
570 void setPerFaceCustomComponents(bool b = true)
571 {
572 setPerElementComponent(FACE, CUSTOM_COMPONENTS, b, PrimitiveType::NONE);
573 }
574
575 void setEdges(bool b = true) { setElement(EDGE, b); }
576
577 void setPerEdgeVertexReferences(bool b = true)
578 {
579 setPerElementComponent(EDGE, VREFS, b, PrimitiveType::NONE);
580 }
581
582 void setPerEdgeColor(bool b = true, DataType t = PrimitiveType::UCHAR)
583 {
584 setPerElementComponent(EDGE, COLOR, b, t);
585 }
586
587 void setPerEdgeNormal(bool b = true, DataType t = PrimitiveType::FLOAT)
588 {
589 setPerElementComponent(EDGE, NORMAL, b, t);
590 }
591
592 void setPerEdgeQuality(bool b = true, DataType t = PrimitiveType::DOUBLE)
593 {
594 setPerElementComponent(EDGE, QUALITY, b, t);
595 }
596
597 void setPerEdgeCustomComponents(bool b = true)
598 {
599 setPerElementComponent(EDGE, CUSTOM_COMPONENTS, b, PrimitiveType::NONE);
600 }
601
602 void setTextures(bool b = true)
603 {
604 setPerElementComponent(MESH, TEXTURES, b, PrimitiveType::NONE);
605 }
606
607 void addPerElementCustomComponent(
608 Element el,
609 const std::string& name,
610 DataType t)
611 {
612 setPerElementComponent(
613 el, CUSTOM_COMPONENTS, true, PrimitiveType::NONE);
614 mPerElemCustomComponents[el].emplace_back(name, t);
615 }
616
617 void clearPerElementCustomComponents(Element el)
618 {
619 setPerElementComponent(
620 el, CUSTOM_COMPONENTS, false, PrimitiveType::NONE);
621 mPerElemCustomComponents[el].clear();
622 }
623
624 void addPerVertexCustomComponent(const std::string& name, DataType t)
625 {
626 addPerElementCustomComponent(VERTEX, name, t);
627 }
628
629 void clearPerVertexCustomComponents()
630 {
631 clearPerElementCustomComponents(VERTEX);
632 }
633
634 void addPerFaceCustomComponent(const std::string& name, DataType t)
635 {
636 addPerElementCustomComponent(FACE, name, t);
637 }
638
639 void clearPerFaceCustomComponents()
640 {
641 clearPerElementCustomComponents(FACE);
642 }
643
644 void addPerEdgeCustomComponent(const std::string& name, DataType t)
645 {
646 addPerElementCustomComponent(EDGE, name, t);
647 }
648
649 void clearPerEdgeCustomComponents()
650 {
651 clearPerElementCustomComponents(EDGE);
652 }
653
654 /*
655 * Getter Component type functions : they are used mostly by save functions
656 * to know the type that needs to use to save a given Component
657 */
658
659 DataType perElementComponentType(Element el, Component comp) const
660 {
661 return mPerElemComponentsType(el, comp);
662 }
663
664 DataType perVertexPositionType() const
665 {
666 return perElementComponentType(VERTEX, POSITION);
667 }
668
669 DataType perVertexNormalType() const
670 {
671 return perElementComponentType(VERTEX, NORMAL);
672 }
673
674 DataType perVertexColorType() const
675 {
676 return perElementComponentType(VERTEX, COLOR);
677 }
678
679 DataType perVertexQualityType() const
680 {
681 return perElementComponentType(VERTEX, QUALITY);
682 }
683
684 DataType perVertexTexCoordType() const
685 {
686 return perElementComponentType(VERTEX, TEXCOORD);
687 }
688
689 DataType perFaceNormalType() const
690 {
691 return perElementComponentType(FACE, NORMAL);
692 }
693
694 DataType perFaceColorType() const
695 {
696 return perElementComponentType(FACE, COLOR);
697 }
698
699 DataType perFaceQualityType() const
700 {
701 return perElementComponentType(FACE, QUALITY);
702 }
703
704 DataType perFaceWedgeTexCoordsType() const
705 {
706 return perElementComponentType(FACE, WEDGE_TEXCOORDS);
707 }
708
709 DataType perEdgeNormalType() const
710 {
711 return perElementComponentType(EDGE, NORMAL);
712 }
713
714 DataType perEdgeColorType() const
715 {
716 return perElementComponentType(EDGE, COLOR);
717 }
718
719 DataType perEdgeQualityType() const
720 {
721 return perElementComponentType(EDGE, QUALITY);
722 }
723
724 const std::vector<CustomComponent>& perElementCustomComponents(
725 Element el) const
726 {
727 return mPerElemCustomComponents[el];
728 }
729
730 const std::vector<CustomComponent>& perVertexCustomComponents() const
731 {
732 return mPerElemCustomComponents[VERTEX];
733 }
734
735 const std::vector<CustomComponent>& perFaceCustomComponents() const
736 {
737 return mPerElemCustomComponents[FACE];
738 }
739
740 const std::vector<CustomComponent>& perEdgeCustomComponents() const
741 {
742 return mPerElemCustomComponents[EDGE];
743 }
744
756 [[nodiscard]] MeshInfo intersect(const MeshInfo& info) const
757 {
759 for (uint i = 0; i < NUM_ELEMENTS; ++i) {
760 res.mElements[i] = mElements[i] && info.mElements[i];
761 for (uint j = 0; j < NUM_COMPONENTS; ++j) {
762 res.mPerElemComponents[i][j] =
763 mPerElemComponents[i][j] && info.mPerElemComponents[i][j];
764
765 if (res.mPerElemComponents[i][j]) {
766 res.mPerElemComponentsType(i, j) =
767 mPerElemComponentsType(i, j);
768 }
769 }
770 }
771
772 if (mType == info.mType) {
773 res.mType = mType;
774 }
775 res.mPerElemCustomComponents = mPerElemCustomComponents;
776
777 return res;
778 }
779
780private:
789 template<typename T>
791 {
792 if constexpr (std::is_same_v<T, char>)
793 return PrimitiveType::CHAR;
794 if constexpr (std::is_same_v<T, unsigned char>)
795 return PrimitiveType::UCHAR;
796 if constexpr (std::is_same_v<T, short>)
797 return PrimitiveType::SHORT;
798 if constexpr (std::is_same_v<T, unsigned short>)
799 return PrimitiveType::USHORT;
800 if constexpr (std::is_same_v<T, int>)
801 return PrimitiveType::INT;
802 if constexpr (std::is_same_v<T, uint>)
803 return PrimitiveType::UINT;
804 if constexpr (std::is_integral_v<T>)
805 return PrimitiveType::INT; // fallback to int
806 if constexpr (std::is_same_v<T, float>)
807 return PrimitiveType::FLOAT;
808 if constexpr (std::is_same_v<T, double>)
809 return PrimitiveType::DOUBLE;
810 if constexpr (std::is_floating_point_v<T>)
811 return PrimitiveType::FLOAT; // fallback to float
812 return PrimitiveType::NONE;
813 }
814
815 static DataType getType(std::type_index ti)
816 {
817 if (ti == typeid(char))
818 return PrimitiveType::CHAR;
819 if (ti == typeid(unsigned char))
820 return PrimitiveType::UCHAR;
821 if (ti == typeid(short))
822 return PrimitiveType::SHORT;
823 if (ti == typeid(unsigned short))
824 return PrimitiveType::USHORT;
825 if (ti == typeid(int))
826 return PrimitiveType::INT;
827 if (ti == typeid(uint))
828 return PrimitiveType::UINT;
829 if (ti == typeid(float))
830 return PrimitiveType::FLOAT;
831 if (ti == typeid(double))
832 return PrimitiveType::DOUBLE;
833 return PrimitiveType::NONE;
834 }
835};
836
837template<uint ELEM_ID, MeshConcept MeshType>
838void addPerElementCustomComponent(
839 MeshType& m,
840 const MeshInfo::CustomComponent& cc)
841{
842 switch (cc.type) {
843 case PrimitiveType::CHAR:
844 m.template addPerElementCustomComponent<ELEM_ID, char>(cc.name);
845 break;
846 case PrimitiveType::UCHAR:
847 m.template addPerElementCustomComponent<ELEM_ID, unsigned char>(
848 cc.name);
849 break;
850 case PrimitiveType::SHORT:
851 m.template addPerElementCustomComponent<ELEM_ID, short>(cc.name);
852 break;
853 case PrimitiveType::USHORT:
854 m.template addPerElementCustomComponent<ELEM_ID, unsigned short>(
855 cc.name);
856 break;
857 case PrimitiveType::INT:
858 m.template addPerElementCustomComponent<ELEM_ID, int>(cc.name);
859 break;
860 case PrimitiveType::UINT:
861 m.template addPerElementCustomComponent<ELEM_ID, uint>(cc.name);
862 break;
863 case PrimitiveType::FLOAT:
864 m.template addPerElementCustomComponent<ELEM_ID, float>(cc.name);
865 break;
866 case PrimitiveType::DOUBLE:
867 m.template addPerElementCustomComponent<ELEM_ID, double>(cc.name);
868 break;
869 default: assert(0);
870 }
871}
872
873template<MeshConcept MeshType>
874void addPerVertexCustomComponent(
875 MeshType& m,
876 const MeshInfo::CustomComponent& cc)
877{
878 addPerElementCustomComponent<ElemId::VERTEX>(m, cc);
879}
880
881template<FaceMeshConcept MeshType>
882void addPerFaceCustomComponent(MeshType& m, const MeshInfo::CustomComponent& cc)
883{
884 addPerElementCustomComponent<ElemId::FACE>(m, cc);
885}
886
887template<EdgeMeshConcept MeshType>
888void addPerEdgeCustomComponent(MeshType& m, const MeshInfo::CustomComponent& cc)
889{
890 addPerElementCustomComponent<ElemId::EDGE>(m, cc);
891}
892
906template<MeshConcept MeshType>
907void enableOptionalComponentsFromInfo(MeshInfo& info, MeshType& m)
908{
909 if (info.hasVertices()) {
910 if (info.hasPerVertexColor()) {
911 if (!enableIfPerVertexColorOptional(m)) {
912 info.setPerVertexColor(false);
913 }
914 }
915 if (info.hasPerVertexNormal()) {
916 if (!enableIfPerVertexNormalOptional(m)) {
917 info.setPerVertexNormal(false);
918 }
919 }
920 if (info.hasPerVertexQuality()) {
921 if (!enableIfPerVertexQualityOptional(m)) {
922 info.setPerVertexQuality(false);
923 }
924 }
925 if (info.hasPerVertexTexCoord()) {
926 if (!enableIfPerVertexTexCoordOptional(m)) {
927 info.setPerVertexTexCoord(false);
928 }
929 }
930 if (info.hasPerVertexCustomComponents()) {
931 if constexpr (HasPerVertexCustomComponents<MeshType>) {
932 for (const auto& cc : info.perVertexCustomComponents()) {
933 addPerVertexCustomComponent(m, cc);
934 }
935 }
936 else {
937 info.clearPerVertexCustomComponents();
938 }
939 }
940 }
941 else {
942 info.setVertices(false);
943 }
944
945 if constexpr (HasFaces<MeshType>) {
946 if (info.hasFaces()) {
947 if (info.hasPerFaceColor()) {
949 info.setPerFaceColor(false);
950 }
951 }
952 if (info.hasPerFaceNormal()) {
954 info.setPerFaceNormal(false);
955 }
956 }
957 if (info.hasPerFaceQuality()) {
959 info.setPerFaceQuality(false);
960 }
961 }
962 if (info.hasPerFaceWedgeTexCoords()) {
964 info.setPerFaceWedgeTexCoords(false);
965 }
966 }
967 if (info.hasPerFaceCustomComponents()) {
968 if constexpr (HasPerFaceCustomComponents<MeshType>) {
969 for (const auto& cc : info.perFaceCustomComponents()) {
970 addPerFaceCustomComponent(m, cc);
971 }
972 }
973 else {
974 info.clearPerFaceCustomComponents();
975 }
976 }
977 }
978 else {
979 info.setFaces(false);
980 }
981 }
982 else {
983 info.setFaces(false);
984 }
985
986 if constexpr (HasEdges<MeshType>) {
987 if (info.hasEdges()) {
988 if (info.hasPerEdgeColor()) {
990 info.setPerEdgeColor(false);
991 }
992 }
993 if (info.hasPerEdgeNormal()) {
995 info.setPerEdgeNormal(false);
996 }
997 }
998 if (info.hasPerEdgeQuality()) {
1000 info.setPerEdgeQuality(false);
1001 }
1002 }
1003 if (info.hasPerEdgeCustomComponents()) {
1004 if constexpr (HasPerEdgeCustomComponents<MeshType>) {
1005 for (const auto& cc : info.perEdgeCustomComponents()) {
1006 addPerEdgeCustomComponent(m, cc);
1007 }
1008 }
1009 else {
1010 info.clearPerEdgeCustomComponents();
1011 }
1012 }
1013 }
1014 else {
1015 info.setEdges(false);
1016 }
1017 }
1018 else {
1019 info.setEdges(false);
1020 }
1021}
1022
1023} // namespace vcl
1024
1025#endif // VCL_SPACE_COMPLEX_MESH_INFO_H
A class representing a box in N-dimensional space.
Definition box.h:46
The Element class.
Definition element.h:75
A simple class that allows to store which elements and their components have been imported/loaded or ...
Definition mesh_info.h:76
MeshInfo intersect(const MeshInfo &info) const
Returns a MeshInfo object that is the intersection between this and info.
Definition mesh_info.h:756
bool hasPerVertexColor() const
Returns true if the current object has Vertex Colors.
Definition mesh_info.h:364
static DataType getType()
Given the template T, returns the corresponding enum DataType value of T.
Definition mesh_info.h:790
bool isEmpty() const
Returns whether the current MeshInfo object is empty, i.e., it has no Elements set.
Definition mesh_info.h:296
bool hasPerVertexNormal() const
Returns true if the current object has Vertex Normals.
Definition mesh_info.h:355
Component
Enum used to describe the type of Components that each Element can have.
Definition mesh_info.h:97
bool isTriangleMesh() const
Returns true if the current object has Mesh type set to MeshType::TRIANGLE_MESH.
Definition mesh_info.h:307
void clear()
Clears the MeshInfo object.
Definition mesh_info.h:279
bool hasPerVertexTexCoord() const
Returns true if the current object has Vertex Texture Coordinates.
Definition mesh_info.h:382
bool isQuadMesh() const
Returns true if the current object has Mesh type set to MeshType::QUAD_MESH.
Definition mesh_info.h:314
bool hasVertices() const
Returns true if the current object has Vertex Elements.
Definition mesh_info.h:340
bool hasPerVertexCustomComponents() const
Returns true if the current object has Vertex Custom Components.
Definition mesh_info.h:391
bool isPolygonMesh() const
Returns true if the current object has Mesh type set to MeshType::POLYGON_MESH.
Definition mesh_info.h:321
PrimitiveType DataType
Enum used to describe the type of Data stored in a component.
Definition mesh_info.h:113
bool hasFaces() const
Returns true if the current object has Face Elements.
Definition mesh_info.h:400
bool hasEdges() const
Returns true if the current object has Edge Elements.
Definition mesh_info.h:437
Element
Enum used to describe the type of Elements that can be found in a file.
Definition mesh_info.h:91
bool hasPerFaceVertexReferences() const
Returns true if the current object has per Face Vertex References.
Definition mesh_info.h:406
MeshInfo()
Default constructor.
Definition mesh_info.h:153
MeshInfo(const Mesh &m)
Sets the current status of the MeshInfo object from the input mesh.
Definition mesh_info.h:165
MeshType
Enum used to describe the type of the Mesh - by default, the value is set to UNKNOWN.
Definition mesh_info.h:82
bool hasPerVertexPosition() const
Returns true if the current object has Vertex Positions.
Definition mesh_info.h:346
bool hasPerVertexQuality() const
Returns true if the current object has Vertex Quality.
Definition mesh_info.h:373
The Mesh class represents a generic 3D mesh. A mesh is composed of a generic number of containers of ...
Definition mesh.h:68
HasEdges concepts is satisfied when at least one of its template types is (or inherits from) a vcl::m...
Definition edge_container.h:1064
HasFaces concepts is satisfied when at least one of its template types is (or inherits from) a vcl::m...
Definition face_container.h:1389
Concept that checks if a Mesh has the per Face Color component.
Definition face_requirements.h:141
Concept that checks if a Mesh has the per Face CustomComponents component.
Definition face_requirements.h:157
Concept that checks if a Mesh has the per Face Normal component.
Definition face_requirements.h:188
Concept that checks if a Mesh has the per Face Quality component.
Definition face_requirements.h:236
Concept that checks if a Mesh has the per Face WedgeTexCoords component.
Definition face_requirements.h:300
Concept that checks if a Mesh has the per Vertex Color component.
Definition vertex_requirements.h:110
Concept that checks if a Mesh has the per Vertex CustomComponents.
Definition vertex_requirements.h:200
Concept that checks if a Mesh has the per Vertex Normal component.
Definition vertex_requirements.h:140
Concept that checks if a Mesh has the per Vertex Quality component.
Definition vertex_requirements.h:171
Concept that checks if a Mesh has the per Vertex TexCoord component.
Definition vertex_requirements.h:186
Definition face_requirements.h:56
Concept that checks if a Mesh has the TexturePaths component.
Definition mesh_requirements.h:105
Definition face_requirements.h:52
PrimitiveType
A simple type that enumerates the main primitive types.
Definition base.h:58
bool enableIfPerEdgeColorOptional(MeshType &m)
If the input mesh has a EdgeContainer, and the Edge Element has a Color Component,...
Definition edge_requirements.h:394
bool enableIfPerEdgeNormalOptional(MeshType &m)
If the input mesh has a EdgeContainer, and the Edge Element has a Normal Component,...
Definition edge_requirements.h:510
bool enableIfPerEdgeQualityOptional(MeshType &m)
If the input mesh has a EdgeContainer, and the Edge Element has a Quality Component,...
Definition edge_requirements.h:568
bool enableIfPerFaceQualityOptional(MeshType &m)
If the input mesh has a FaceContainer, and the Face Element has a Quality Component,...
Definition face_requirements.h:737
bool enableIfPerFaceWedgeTexCoordsOptional(MeshType &m)
If the input mesh has a FaceContainer, and the Face Element has a WedgeTexCoords Component,...
Definition face_requirements.h:859
bool isPerFaceWedgeTexCoordsAvailable(const MeshType &m)
Returns true if the WedgeTexCoords component is available (enabled) in the Face element of the input ...
Definition face_requirements.h:833
bool isPerFaceNormalAvailable(const MeshType &m)
Returns true if the Normal component is available (enabled) in the Face element of the input mesh m.
Definition face_requirements.h:592
bool isPerFaceQualityAvailable(const MeshType &m)
Returns true if the Quality component is available (enabled) in the Face element of the input mesh m.
Definition face_requirements.h:713
bool isPerFaceColorAvailable(const MeshType &m)
Returns true if the Color component is available (enabled) in the Face element of the input mesh m.
Definition face_requirements.h:476
bool enableIfPerFaceNormalOptional(MeshType &m)
If the input mesh has a FaceContainer, and the Face Element has a Normal Component,...
Definition face_requirements.h:616
bool enableIfPerFaceColorOptional(MeshType &m)
If the input mesh has a FaceContainer, and the Face Element has a Color Component,...
Definition face_requirements.h:500
The CustomComponent struct is a simple structure that describes a custom component of an Element (or ...
Definition mesh_info.h:120