23#ifndef VCL_SPACE_COMPLEX_MESH_INFO_H
24#define VCL_SPACE_COMPLEX_MESH_INFO_H
26#include <vclib/mesh.h>
27#include <vclib/base.h>
82 enum class MeshType { TRIANGLE_MESH, QUAD_MESH, POLYGON_MESH, UNKNOWN };
91 enum Element { VERTEX, FACE, EDGE, MESH, NUM_ELEMENTS };
129 std::bitset<NUM_ELEMENTS> mElements = {
false};
132 std::array<std::bitset<NUM_COMPONENTS>, NUM_ELEMENTS> mPerElemComponents = {
136 Eigen::Matrix<DataType, NUM_ELEMENTS, NUM_COMPONENTS>
137 mPerElemComponentsType;
140 std::array<std::vector<CustomComponent>, NUM_ELEMENTS>
141 mPerElemCustomComponents;
153 MeshInfo() { mPerElemComponentsType.fill(PrimitiveType::NONE); }
164 template<MeshConcept Mesh>
168 setPerVertexPosition(
172 if (isPerVertexNormalAvailable(
m)) {
176 typename Mesh::VertexType::NormalType::ScalarType>());
180 if (isPerVertexColorAvailable(
m)) {
181 setPerVertexColor(
true, PrimitiveType::UCHAR);
185 if (isPerVertexQualityAvailable(
m)) {
191 if (isPerVertexTexCoordAvailable(
m)) {
192 setPerVertexTexCoord(
195 typename Mesh::VertexType::TexCoordType::ScalarType>());
199 auto names =
m.perVertexCustomComponentNames();
200 for (
auto& name :
names) {
202 if (
dt != PrimitiveType::NONE) {
203 addPerVertexCustomComponent(name,
dt);
210 setPerFaceVertexReferences();
225 typename Mesh::FaceType::NormalType::ScalarType>());
230 setPerFaceColor(
true, PrimitiveType::UCHAR);
241 setPerFaceWedgeTexCoords(
243 getType<
typename Mesh::FaceType::WedgeTexCoordType::
248 auto names =
m.perFaceCustomComponentNames();
249 for (
auto& name :
names) {
251 if (
dt != PrimitiveType::NONE) {
252 addPerFaceCustomComponent(name,
dt);
260 setPerEdgeVertexReferences();
267 if (
m.textureNumber() > 0) {
282 for (
auto& comp : mPerElemComponents)
284 mPerElemComponentsType.fill(PrimitiveType::NONE);
286 for (
auto& v : mPerElemCustomComponents)
289 mType = MeshType::UNKNOWN;
296 bool isEmpty()
const {
return !mElements.any(); }
298 MeshType meshType()
const {
return mType; }
300 bool isUnkownMesh()
const {
return mType == MeshType::UNKNOWN; }
314 bool isQuadMesh()
const {
return mType == MeshType::QUAD_MESH; }
329 bool hasElement(
Element el)
const {
return mElements[
el]; }
333 return mPerElemComponents[el][comp];
348 return hasPerElementComponent(VERTEX, POSITION);
357 return hasPerElementComponent(VERTEX, NORMAL);
366 return hasPerElementComponent(VERTEX, COLOR);
375 return hasPerElementComponent(VERTEX, QUALITY);
384 return hasPerElementComponent(VERTEX, TEXCOORD);
393 return hasPerElementComponent(VERTEX, CUSTOM_COMPONENTS);
408 return hasPerElementComponent(FACE, VREFS);
411 bool hasPerFaceNormal()
const
413 return hasPerElementComponent(FACE, NORMAL);
416 bool hasPerFaceColor()
const {
return hasPerElementComponent(FACE, COLOR); }
418 bool hasPerFaceQuality()
const
420 return hasPerElementComponent(FACE, QUALITY);
423 bool hasPerFaceWedgeTexCoords()
const
425 return hasPerElementComponent(FACE, WEDGE_TEXCOORDS);
428 bool hasPerFaceCustomComponents()
const
430 return hasPerElementComponent(FACE, CUSTOM_COMPONENTS);
439 bool hasPerEdgeVertexReferences()
const
441 return hasPerElementComponent(EDGE, VREFS);
444 bool hasPerEdgeColor()
const {
return hasPerElementComponent(EDGE, COLOR); }
446 bool hasPerEdgeNormal()
const
448 return hasPerElementComponent(EDGE, NORMAL);
451 bool hasPerEdgeQuality()
const
453 return hasPerElementComponent(EDGE, QUALITY);
456 bool hasPerEdgeCustomComponents()
const
458 return hasPerElementComponent(EDGE, CUSTOM_COMPONENTS);
461 bool hasTextures()
const {
return hasPerElementComponent(MESH, TEXTURES); }
470 void updateMeshType(uint faceSize)
472 if (mType == MeshType::UNKNOWN) {
475 else if (faceSize == 4)
480 else if (mType == MeshType::TRIANGLE_MESH && faceSize != 3) {
483 else if (mType == MeshType::QUAD_MESH && faceSize != 4) {
488 void setUnknownMesh() { mType = MeshType::UNKNOWN; }
490 void setTriangleMesh() { mType = MeshType::TRIANGLE_MESH; }
492 void setQuadMesh() { mType = MeshType::QUAD_MESH; }
494 void setPolygonMesh() { mType = MeshType::POLYGON_MESH; }
496 void setMeshType(
MeshType t) { mType = t; }
498 void setElement(
Element el,
bool b =
true) { mElements[el] = b; }
503 mPerElemComponents[el][c] = b;
505 mPerElemComponentsType(el, c) = t;
508 void setVertices(
bool b =
true) { setElement(VERTEX, b); }
510 void setPerVertexPosition(
bool b =
true,
DataType t = PrimitiveType::DOUBLE)
512 setPerElementComponent(VERTEX, POSITION, b, t);
515 void setPerVertexNormal(
bool b =
true,
DataType t = PrimitiveType::FLOAT)
517 setPerElementComponent(VERTEX, NORMAL, b, t);
520 void setPerVertexColor(
bool b =
true,
DataType t = PrimitiveType::UCHAR)
522 setPerElementComponent(VERTEX, COLOR, b, t);
525 void setPerVertexQuality(
bool b =
true,
DataType t = PrimitiveType::DOUBLE)
527 setPerElementComponent(VERTEX, QUALITY, b, t);
530 void setPerVertexTexCoord(
bool b =
true,
DataType t = PrimitiveType::FLOAT)
532 setPerElementComponent(VERTEX, TEXCOORD, b, t);
535 void setPerVertexCustomComponents(
bool b =
true)
537 setPerElementComponent(
538 VERTEX, CUSTOM_COMPONENTS, b, PrimitiveType::NONE);
541 void setFaces(
bool b =
true) { setElement(FACE, b); }
543 void setPerFaceVertexReferences(
bool b =
true)
545 setPerElementComponent(FACE, VREFS, b, PrimitiveType::NONE);
548 void setPerFaceNormal(
bool b =
true,
DataType t = PrimitiveType::FLOAT)
550 setPerElementComponent(FACE, NORMAL, b, t);
553 void setPerFaceColor(
bool b =
true,
DataType t = PrimitiveType::UCHAR)
555 setPerElementComponent(FACE, COLOR, b, t);
558 void setPerFaceQuality(
bool b =
true,
DataType t = PrimitiveType::DOUBLE)
560 setPerElementComponent(FACE, QUALITY, b, t);
563 void setPerFaceWedgeTexCoords(
567 setPerElementComponent(FACE, WEDGE_TEXCOORDS, b, t);
570 void setPerFaceCustomComponents(
bool b =
true)
572 setPerElementComponent(FACE, CUSTOM_COMPONENTS, b, PrimitiveType::NONE);
575 void setEdges(
bool b =
true) { setElement(EDGE, b); }
577 void setPerEdgeVertexReferences(
bool b =
true)
579 setPerElementComponent(EDGE, VREFS, b, PrimitiveType::NONE);
582 void setPerEdgeColor(
bool b =
true,
DataType t = PrimitiveType::UCHAR)
584 setPerElementComponent(EDGE, COLOR, b, t);
587 void setPerEdgeNormal(
bool b =
true,
DataType t = PrimitiveType::FLOAT)
589 setPerElementComponent(EDGE, NORMAL, b, t);
592 void setPerEdgeQuality(
bool b =
true,
DataType t = PrimitiveType::DOUBLE)
594 setPerElementComponent(EDGE, QUALITY, b, t);
597 void setPerEdgeCustomComponents(
bool b =
true)
599 setPerElementComponent(EDGE, CUSTOM_COMPONENTS, b, PrimitiveType::NONE);
602 void setTextures(
bool b =
true)
604 setPerElementComponent(MESH, TEXTURES, b, PrimitiveType::NONE);
607 void addPerElementCustomComponent(
609 const std::string& name,
612 setPerElementComponent(
613 el, CUSTOM_COMPONENTS,
true, PrimitiveType::NONE);
614 mPerElemCustomComponents[el].emplace_back(name, t);
617 void clearPerElementCustomComponents(
Element el)
619 setPerElementComponent(
620 el, CUSTOM_COMPONENTS,
false, PrimitiveType::NONE);
621 mPerElemCustomComponents[el].clear();
624 void addPerVertexCustomComponent(
const std::string& name,
DataType t)
626 addPerElementCustomComponent(VERTEX, name, t);
629 void clearPerVertexCustomComponents()
631 clearPerElementCustomComponents(VERTEX);
634 void addPerFaceCustomComponent(
const std::string& name,
DataType t)
636 addPerElementCustomComponent(FACE, name, t);
639 void clearPerFaceCustomComponents()
641 clearPerElementCustomComponents(FACE);
644 void addPerEdgeCustomComponent(
const std::string& name,
DataType t)
646 addPerElementCustomComponent(EDGE, name, t);
649 void clearPerEdgeCustomComponents()
651 clearPerElementCustomComponents(EDGE);
661 return mPerElemComponentsType(el, comp);
664 DataType perVertexPositionType()
const
666 return perElementComponentType(VERTEX, POSITION);
669 DataType perVertexNormalType()
const
671 return perElementComponentType(VERTEX, NORMAL);
676 return perElementComponentType(VERTEX, COLOR);
679 DataType perVertexQualityType()
const
681 return perElementComponentType(VERTEX, QUALITY);
684 DataType perVertexTexCoordType()
const
686 return perElementComponentType(VERTEX, TEXCOORD);
691 return perElementComponentType(FACE, NORMAL);
696 return perElementComponentType(FACE, COLOR);
701 return perElementComponentType(FACE, QUALITY);
704 DataType perFaceWedgeTexCoordsType()
const
706 return perElementComponentType(FACE, WEDGE_TEXCOORDS);
711 return perElementComponentType(EDGE, NORMAL);
716 return perElementComponentType(EDGE, COLOR);
721 return perElementComponentType(EDGE, QUALITY);
724 const std::vector<CustomComponent>& perElementCustomComponents(
727 return mPerElemCustomComponents[el];
730 const std::vector<CustomComponent>& perVertexCustomComponents()
const
732 return mPerElemCustomComponents[VERTEX];
735 const std::vector<CustomComponent>& perFaceCustomComponents()
const
737 return mPerElemCustomComponents[FACE];
740 const std::vector<CustomComponent>& perEdgeCustomComponents()
const
742 return mPerElemCustomComponents[EDGE];
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];
765 if (
res.mPerElemComponents[
i][
j]) {
766 res.mPerElemComponentsType(
i,
j) =
767 mPerElemComponentsType(
i,
j);
772 if (mType == info.mType) {
775 res.mPerElemCustomComponents = mPerElemCustomComponents;
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;
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;
812 return PrimitiveType::NONE;
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;
837template<u
int ELEM_ID, MeshConcept MeshType>
838void addPerElementCustomComponent(
840 const MeshInfo::CustomComponent& cc)
843 case PrimitiveType::CHAR:
844 m.template addPerElementCustomComponent<ELEM_ID, char>(cc.name);
846 case PrimitiveType::UCHAR:
847 m.template addPerElementCustomComponent<ELEM_ID, unsigned char>(
850 case PrimitiveType::SHORT:
851 m.template addPerElementCustomComponent<ELEM_ID, short>(cc.name);
853 case PrimitiveType::USHORT:
854 m.template addPerElementCustomComponent<ELEM_ID, unsigned short>(
857 case PrimitiveType::INT:
858 m.template addPerElementCustomComponent<ELEM_ID, int>(cc.name);
860 case PrimitiveType::UINT:
861 m.template addPerElementCustomComponent<ELEM_ID, uint>(cc.name);
863 case PrimitiveType::FLOAT:
864 m.template addPerElementCustomComponent<ELEM_ID, float>(cc.name);
866 case PrimitiveType::DOUBLE:
867 m.template addPerElementCustomComponent<ELEM_ID, double>(cc.name);
873template<MeshConcept MeshType>
874void addPerVertexCustomComponent(
876 const MeshInfo::CustomComponent& cc)
878 addPerElementCustomComponent<ElemId::VERTEX>(m, cc);
881template<FaceMeshConcept MeshType>
882void addPerFaceCustomComponent(MeshType& m,
const MeshInfo::CustomComponent& cc)
884 addPerElementCustomComponent<ElemId::FACE>(m, cc);
887template<EdgeMeshConcept MeshType>
888void addPerEdgeCustomComponent(MeshType& m,
const MeshInfo::CustomComponent& cc)
890 addPerElementCustomComponent<ElemId::EDGE>(m, cc);
906template<MeshConcept MeshType>
907void enableOptionalComponentsFromInfo(MeshInfo& info, MeshType& m)
909 if (info.hasVertices()) {
910 if (info.hasPerVertexColor()) {
911 if (!enableIfPerVertexColorOptional(m)) {
912 info.setPerVertexColor(
false);
915 if (info.hasPerVertexNormal()) {
916 if (!enableIfPerVertexNormalOptional(m)) {
917 info.setPerVertexNormal(
false);
920 if (info.hasPerVertexQuality()) {
921 if (!enableIfPerVertexQualityOptional(m)) {
922 info.setPerVertexQuality(
false);
925 if (info.hasPerVertexTexCoord()) {
926 if (!enableIfPerVertexTexCoordOptional(m)) {
927 info.setPerVertexTexCoord(
false);
930 if (info.hasPerVertexCustomComponents()) {
931 if constexpr (HasPerVertexCustomComponents<MeshType>) {
932 for (
const auto& cc : info.perVertexCustomComponents()) {
933 addPerVertexCustomComponent(m, cc);
937 info.clearPerVertexCustomComponents();
942 info.setVertices(
false);
945 if constexpr (HasFaces<MeshType>) {
946 if (info.hasFaces()) {
947 if (info.hasPerFaceColor()) {
949 info.setPerFaceColor(
false);
952 if (info.hasPerFaceNormal()) {
954 info.setPerFaceNormal(
false);
957 if (info.hasPerFaceQuality()) {
959 info.setPerFaceQuality(
false);
962 if (info.hasPerFaceWedgeTexCoords()) {
964 info.setPerFaceWedgeTexCoords(
false);
967 if (info.hasPerFaceCustomComponents()) {
968 if constexpr (HasPerFaceCustomComponents<MeshType>) {
969 for (
const auto& cc : info.perFaceCustomComponents()) {
970 addPerFaceCustomComponent(m, cc);
974 info.clearPerFaceCustomComponents();
979 info.setFaces(
false);
983 info.setFaces(
false);
986 if constexpr (HasEdges<MeshType>) {
987 if (info.hasEdges()) {
988 if (info.hasPerEdgeColor()) {
990 info.setPerEdgeColor(
false);
993 if (info.hasPerEdgeNormal()) {
995 info.setPerEdgeNormal(
false);
998 if (info.hasPerEdgeQuality()) {
1000 info.setPerEdgeQuality(
false);
1003 if (info.hasPerEdgeCustomComponents()) {
1004 if constexpr (HasPerEdgeCustomComponents<MeshType>) {
1005 for (
const auto& cc : info.perEdgeCustomComponents()) {
1006 addPerEdgeCustomComponent(m, cc);
1010 info.clearPerEdgeCustomComponents();
1015 info.setEdges(
false);
1019 info.setEdges(
false);
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