Visual Computing Library
Loading...
Searching...
No Matches
face_container.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_MESH_CONTAINERS_FACE_CONTAINER_H
24#define VCL_MESH_CONTAINERS_FACE_CONTAINER_H
25
26#include "element_container.h"
27
28#include <vclib/algorithms/core/polygon/ear_cut.h>
29#include <vclib/mesh/containers/custom_component_vector_handle.h>
30#include <vclib/mesh/elements/face.h>
31#include <vclib/mesh/elements/face_components.h>
32#include <vclib/views/mesh.h>
33
34namespace vcl::mesh {
35
52template<FaceConcept T>
54{
55 template<FaceConcept U>
56 friend class FaceContainer;
57
60
61public:
62 using Face = T;
63 using FaceType = T;
64 using FaceIterator = Base::ElementIterator;
65 using ConstFaceIterator = Base::ConstElementIterator;
66
70 FaceContainer() = default;
71
82 const FaceType& face(uint i) const { return Base::element(i); }
83
94 FaceType& face(uint i) { return Base::element(i); }
95
105 uint faceNumber() const { return Base::elementNumber(); }
106
116 uint faceContainerSize() const { return Base::elementContainerSize(); }
117
124 uint deletedFaceNumber() const { return Base::deletedElementNumber(); }
125
135 uint addFace() { return Base::addElement(); }
136
137 template<typename... V>
138 uint addFace(V... args) requires (sizeof...(args) >= 3)
139 {
140 uint fid = addFace();
141 Face& f = face(fid);
142
143 constexpr uint n = sizeof...(args);
144
145 if constexpr (T::VERTEX_NUMBER < 0) {
146 f.resizeVertices(n);
147 }
148 else {
149 static_assert(
150 n == T::VERTEX_NUMBER,
151 "Wrong number of vertices in Mesh::addFace.");
152 }
153
154 addFaceHelper(f, args...);
155 return fid;
156 }
157
158 template<Range Rng>
159 uint addFace(Rng&& r) requires (
160 InputRange<Rng, typename Face::VertexType*> || InputRange<Rng, uint>)
161 {
162 auto begin = std::ranges::begin(r);
163 auto end = std::ranges::end(r);
164
165 if (begin == end)
166 return UINT_NULL;
167 uint n = std::distance(begin, end);
168
169 uint fid = UINT_NULL;
170
171 assert(n >= 3);
172 if (n < 3)
173 return UINT_NULL;
174
175 if constexpr (T::VERTEX_NUMBER < 0) {
176 fid = addFace();
177 face(fid).resizeVertices(n);
178 }
179 else {
180 assert(n == T::VERTEX_NUMBER);
181 if (n == T::VERTEX_NUMBER)
182 fid = addFace();
183 }
184
185 if (fid != UINT_NULL) {
186 Face& f = face(fid);
187
188 unsigned int i = 0;
189 for (auto it = begin; it != end; ++it) {
190 f.setVertex(i, *it);
191 ++i;
192 }
193 }
194 return fid;
195 }
196
211 uint addFaces(uint n) { return Base::addElements(n); }
212
229 void clearFaces() { Base::clearElements(); }
230
259 void resizeFaces(uint n) { Base::resizeElements(n); }
260
279 void reserveFaces(uint n) { Base::reserveElements(n); }
280
287 void compactFaces() { Base::compactElements(); }
288
301 void deleteFace(uint i) { Base::deleteElement(i); }
302
316 void deleteFace(const FaceType* f) { Base::deleteElement(f); }
317
332 {
333 return Base::elementIndexIfCompact(i);
334 }
335
347 std::vector<uint> faceCompactIndices() const
348 {
349 return Base::elementCompactIndices();
350 }
351
376 void updateFaceIndices(const std::vector<uint>& newIndices)
377 {
378 Base::updateElementIndices(newIndices);
379 }
380
392 FaceIterator faceBegin(bool jumpDeleted = true)
393 {
394 return Base::elementBegin(jumpDeleted);
395 }
396
401 FaceIterator faceEnd() { return Base::elementEnd(); }
402
414 ConstFaceIterator faceBegin(bool jumpDeleted = true) const
415 {
416 return Base::elementBegin(jumpDeleted);
417 }
418
423 ConstFaceIterator faceEnd() const { return Base::elementEnd(); }
424
447 auto faces(bool jumpDeleted = true) { return Base::elements(jumpDeleted); }
448
471 auto faces(bool jumpDeleted = true) const
472 {
473 return Base::elements(jumpDeleted);
474 }
475
481 {
482 Base::enableAllOptionalComponents();
483 }
484
490 {
491 Base::disableAllOptionalComponents();
492 }
493
494 // AdjacentEdges
495
505 requires face::HasOptionalAdjacentEdges<T>
506 {
507 return Base::template isOptionalComponentEnabled<
508 typename T::AdjacentEdges>();
509 }
510
522 void enablePerFaceAdjacentEdges() requires face::HasOptionalAdjacentEdges<T>
523 {
525 }
526
534 requires face::HasOptionalAdjacentEdges<T>
535 {
537 }
538
539 // AdjacentFaces
540
550 requires face::HasOptionalAdjacentFaces<T>
551 {
552 return Base::template isOptionalComponentEnabled<
553 typename T::AdjacentFaces>();
554 }
555
567 void enablePerFaceAdjacentFaces() requires face::HasOptionalAdjacentFaces<T>
568 {
570 }
571
579 requires face::HasOptionalAdjacentFaces<T>
580 {
582 }
583
584 // Color
585
594 bool isPerFaceColorEnabled() const requires face::HasOptionalColor<T>
595 {
596 return Base::template isOptionalComponentEnabled<typename T::Color>();
597 }
598
605 void enablePerFaceColor() requires face::HasOptionalColor<T>
606 {
608 }
609
616 void disablePerFaceColor() requires face::HasOptionalColor<T>
617 {
619 }
620
621 // Mark
622
631 bool isPerFaceMarkEnabled() const requires face::HasOptionalMark<T>
632 {
633 return Base::template isOptionalComponentEnabled<typename T::Mark>();
634 }
635
642 void enablePerFaceMark() requires face::HasOptionalMark<T>
643 {
645 }
646
653 void disablePerFaceMark() requires face::HasOptionalMark<T>
654 {
656 }
657
658 // Normal
659
668 bool isPerFaceNormalEnabled() const requires face::HasOptionalNormal<T>
669 {
671 }
672
679 void enablePerFaceNormal() requires face::HasOptionalNormal<T>
680 {
682 }
683
690 void disablePerFaceNormal() requires face::HasOptionalNormal<T>
691 {
693 }
694
695 // PrincipalCurvature
696
707 requires face::HasOptionalPrincipalCurvature<T>
708 {
709 return Base::template isOptionalComponentEnabled<
710 typename T::PrincipalCurvature>();
711 }
712
720 requires face::HasOptionalPrincipalCurvature<T>
721 {
722 Base::template enableOptionalComponent<
723 typename T::PrincipalCurvature>();
724 }
725
733 requires face::HasOptionalPrincipalCurvature<T>
734 {
735 Base::template disableOptionalComponent<
736 typename T::PrincipalCurvature>();
737 }
738
739 // Quality
740
749 bool isPerFaceQualityEnabled() const requires face::HasOptionalQuality<T>
750 {
752 }
753
760 void enablePerFaceQuality() requires face::HasOptionalQuality<T>
761 {
763 }
764
771 void disablePerFaceQuality() requires face::HasOptionalQuality<T>
772 {
774 }
775
776 // WedgeColors
777
787 requires face::HasOptionalWedgeColors<T>
788 {
789 return Base::template isOptionalComponentEnabled<
790 typename T::WedgeColors>();
791 }
792
804 void enablePerFaceWedgeColors() requires face::HasOptionalWedgeColors<T>
805 {
807 }
808
815 void disablePerFaceWedgeColors() requires face::HasOptionalWedgeColors<T>
816 {
818 }
819
820 // WedgeTexCoords
821
831 requires face::HasOptionalWedgeTexCoords<T>
832 {
833 return Base::template isOptionalComponentEnabled<
834 typename T::WedgeTexCoords>();
835 }
836
849 requires face::HasOptionalWedgeTexCoords<T>
850 {
852 }
853
861 requires face::HasOptionalWedgeTexCoords<T>
862 {
864 }
865
866 // Custom Components
867
880 bool hasPerFaceCustomComponent(const std::string& name) const
882 {
883 return Base::hasElemCustomComponent(name);
884 }
885
896 std::vector<std::string> perFaceCustomComponentNames() const
898 {
899 return Base::elemCustomComponentNames();
900 }
901
927 template<typename K>
928 bool isPerFaceCustomComponentOfType(const std::string& name) const
930 {
931 return Base::template isElemCustomComponentOfType<K>(name);
932 }
933
949 std::type_index perFaceCustomComponentType(const std::string& name) const
951 {
952 return Base::elemComponentType(name);
953 }
954
974 template<typename K>
975 std::vector<std::string> perFaceCustomComponentNamesOfType() const
977 {
978 return Base::template elemCustomComponentNamesOfType<K>();
979 }
980
991 template<typename K>
992 void addPerFaceCustomComponent(const std::string& name)
994 {
995 Base::template addElemCustomComponent<K>(name);
996 }
997
1010 void deletePerFaceCustomComponent(const std::string& name)
1012 {
1013 Base::deleteElemCustomComponent(name);
1014 }
1015
1057 template<typename K>
1059 const std::string& name) requires face::HasCustomComponents<T>
1060 {
1061 return Base::template customComponentVectorHandle<K>(name);
1062 }
1063
1105 template<typename K>
1107 const std::string& name) const requires face::HasCustomComponents<T>
1108 {
1109 return Base::template customComponentVectorHandle<K>(name);
1110 }
1111
1112protected:
1119 template<typename OthMesh>
1121 {
1122 if constexpr (HasFaceContainer<OthMesh>) {
1123 using ParentMesh = Base::ParentMeshType;
1124 using VertexType = ParentMesh::VertexType;
1125 using MVertexType = OthMesh::VertexType;
1126 using MCoordType = MVertexType::CoordType;
1127 using MFaceType = OthMesh::FaceType;
1128
1129 using VertexContainer = ParentMesh::VertexContainer;
1130
1131 // if this is not a triangle mesh nor a polygon mesh (meaning that
1132 // we can't control the number of vertex pointers in this mesh), and
1133 // this mesh does not have the same number of vertex pointers of the
1134 // other, it means that we don't know how to convert these type of
1135 // meshes (e.g. we don't know how to convert a polygon mesh into a
1136 // quad mesh, or convert a quad mesh into a pentagonal mesh...)
1137 static_assert(
1138 !(FaceType::VERTEX_NUMBER != 3 && FaceType::VERTEX_NUMBER > 0 &&
1139 FaceType::VERTEX_NUMBER != MFaceType::VERTEX_NUMBER),
1140 "Cannot import from that type of Mesh. Don't know how to "
1141 "convert faces.");
1142
1143 // we need to manage conversion from poly or faces with cardinality
1144 // > 3 (e.g. quads) to triangle meshes. In this case, we triangulate
1145 // the polygon using the earcut algorithm.
1146 if constexpr (
1147 FaceType::VERTEX_NUMBER == 3 &&
1148 (MFaceType::VERTEX_NUMBER > 3 ||
1149 MFaceType::VERTEX_NUMBER < 0)) {
1150 VertexType* base = &Base::mParentMesh->vertex(0);
1151 const MVertexType* mvbase = &m.vertex(0);
1152
1153 for (const MFaceType& mf : m.faces()) {
1154 // if the current face has the same number of vertices of
1155 // this faces (3), then the vertex pointers have been
1156 // correctly imported from the import pointers function. The
1157 // import pointers function does nothing when importing from
1158 // a face with at least 4 vertices
1159 if (mf.vertexNumber() != FaceType::VERTEX_NUMBER) {
1160 // triangulate mf; the first triangle of the
1161 // triangulation will be this->face(m.index(mf)); the
1162 // other triangles will be added at the end of the
1163 // container
1164 std::vector<uint> tris =
1165 earCut(mf.vertices() | views::coords);
1166 FaceType& f = face(m.index(mf));
1167 importTriPointersHelper(f, mf, base, mvbase, tris, 0);
1168
1169 // number of other faces to add
1170 uint nf = tris.size() / 3 - 1;
1171 uint fid = addFaces(nf);
1172
1173 uint i = 3; // index that cycles into tris
1174 for (; fid < faceContainerSize(); ++fid) {
1175 FaceType& f = face(fid);
1176 importTriPointersHelper(
1177 f, mf, base, mvbase, tris, i);
1178 i += 3;
1179 }
1180 }
1181 }
1182 }
1183 }
1184 }
1185
1186private:
1187 void addFaceHelper(T& f) { /* base case: no need to add vertices */ }
1188
1189 template<typename... V>
1190 void addFaceHelper(T& f, typename T::VertexType* v, V... args)
1191 {
1192 // position on which add the vertex
1193 const std::size_t n = f.vertexNumber() - sizeof...(args) - 1;
1194 f.setVertex(n, v); // set the vertex
1195 // set the remanining vertices, recursive variadics
1196 addFaceHelper(f, args...);
1197 }
1198
1199 template<typename... V>
1200 void addFaceHelper(T& f, uint vid, V... args)
1201 {
1202 // position on which add the vertex
1203 const std::size_t n = f.vertexNumber() - sizeof...(args) - 1;
1204 f.setVertex(n, vid); // set the vertex
1205 // set the remanining vertices, recursive variadics
1206 addFaceHelper(f, args...);
1207 }
1208
1209 template<typename MFaceType, typename VertexType, typename MVertexType>
1210 static void importTriPointersHelper(
1211 FaceType& f,
1212 const MFaceType& mf,
1213 VertexType* base,
1214 const MVertexType* mvbase,
1215 const std::vector<uint>& tris,
1216 uint basetri)
1217 {
1218 f.importFrom(mf); // import all the components from mf
1219 for (uint i = basetri, j = 0; i < basetri + 3; i++, j++) {
1220 f.setVertex(j, base + (mf.vertex(tris[i]) - mvbase));
1221
1222 // wedge colors
1223 if constexpr (
1224 face::HasWedgeColors<FaceType> &&
1225 face::HasWedgeColors<MFaceType>) {
1226 if (comp::isWedgeColorsAvailableOn(f) &&
1227 comp::isWedgeColorsAvailableOn(mf)) {
1228 f.wedgeColor(j) = mf.wedgeColor(tris[i]);
1229 }
1230 }
1231
1232 // wedge texcoords
1233 if constexpr (
1234 face::HasWedgeTexCoords<FaceType> &&
1235 face::HasWedgeTexCoords<MFaceType>) {
1236 if (comp::isWedgeTexCoordsAvailableOn(f) &&
1237 comp::isWedgeTexCoordsAvailableOn(mf)) {
1238 using ST = typename FaceType::WedgeTexCoordType::ScalarType;
1239 f.wedgeTexCoord(j) =
1240 mf.wedgeTexCoord(tris[i]).template cast<ST>();
1241 }
1242 }
1243 }
1244 }
1245};
1246
1247} // namespace vcl::mesh
1248
1249#endif // VCL_MESH_CONTAINERS_FACE_CONTAINER_H
The Face class represents an Face element of the vcl::Mesh class.
Definition face.h:49
void resizeVertices(uint n)
Resize the number of Vertex Pointers of the Face, taking care of updating also the other components o...
Definition face.h:135
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
Definition element.h:44
The FaceContainer class represents a container of Face elements that can be used in a Mesh class.
Definition face_container.h:54
FaceType & face(uint i)
Returns a reference of the Face at the i-th position in the Face Container of the Mesh,...
Definition face_container.h:94
void disablePerFacePrincipalCurvature()
Disables the Optional PrincipalCurvature of the Face.
Definition face_container.h:732
ConstFaceIterator faceEnd() const
Returns a const iterator to the end of the container.
Definition face_container.h:423
void enablePerFaceQuality()
Enable the Optional Quality of the Face.
Definition face_container.h:760
FaceIterator faceBegin(bool jumpDeleted=true)
Returns an iterator to the beginning of the container.
Definition face_container.h:392
void disablePerFaceAdjacentEdges()
Disables the Optional AdjacentEdges of the Face.
Definition face_container.h:533
std::vector< std::string > perFaceCustomComponentNames() const
Returns a vector containing all the names of the custom components of any type associated to the Face...
Definition face_container.h:896
bool isPerFaceMarkEnabled() const
Checks if the Face Optional Mark is enabled.
Definition face_container.h:631
bool isPerFaceAdjacentFacesEnabled() const
Checks if the Face Optional AdjacentFaces is enabled.
Definition face_container.h:549
void disablePerFaceAdjacentFaces()
Disables the Optional AdjacentFaces of the Face.
Definition face_container.h:578
FaceIterator faceEnd()
Returns an iterator to the end of the container.
Definition face_container.h:401
bool isPerFaceWedgeColorsEnabled() const
Checks if the Face Optional WedgeColors is enabled.
Definition face_container.h:786
void disablePerFaceQuality()
Disables the Optional Quality of the Face.
Definition face_container.h:771
CustomComponentVectorHandle< K > perFaceCustomComponentVectorHandle(const std::string &name)
Returns a vector handle to the custom component having the type K and the given name.
Definition face_container.h:1058
void enablePerFacePrincipalCurvature()
Enable the Optional PrincipalCurvature of the Face.
Definition face_container.h:719
bool isPerFacePrincipalCurvatureEnabled() const
Checks if the Face Optional PrincipalCurvature is enabled.
Definition face_container.h:706
uint faceContainerSize() const
Returns the number of Faces (also deleted) contained in the Face container of the Mesh.
Definition face_container.h:116
std::vector< uint > faceCompactIndices() const
Returns a vector that tells, for each actual Face index, the new index that the Face would have in a ...
Definition face_container.h:347
auto faces(bool jumpDeleted=true) const
Returns a small view object that allows to iterate over the Faces of the containers,...
Definition face_container.h:471
bool hasPerFaceCustomComponent(const std::string &name) const
Checks if Faces have a custom component with the given name.
Definition face_container.h:880
void disablePerFaceWedgeTexCoords()
Disables the Optional WedgeTexCoords of the Face.
Definition face_container.h:860
void enablePerFaceColor()
Enable the Optional Color of the Face.
Definition face_container.h:605
void addPerFaceCustomComponent(const std::string &name)
Adds a custom component of type K to the Face, having the given name.
Definition face_container.h:992
auto faces(bool jumpDeleted=true)
Returns a small view object that allows to iterate over the Faces of the containers,...
Definition face_container.h:447
FaceContainer()=default
Empty constructor that creates an empty container of Faces.
void clearFaces()
Clears the Face container of the Mesh, deleting all the Faces.
Definition face_container.h:229
void disableAllPerFaceOptionalComponents()
Disables all the optional components associated to the Face type contained in the FaceContainer.
Definition face_container.h:489
bool isPerFaceQualityEnabled() const
Checks if the Face Optional Quality is enabled.
Definition face_container.h:749
void disablePerFaceMark()
Disables the Optional Mark of the Face.
Definition face_container.h:653
bool isPerFaceNormalEnabled() const
Checks if the Face Optional Normal is enabled.
Definition face_container.h:668
void reserveFaces(uint n)
Reserve a number of Faces in the container of Faces. This is useful when you know (or you have an ide...
Definition face_container.h:279
uint deletedFaceNumber() const
Returns the number of deleted Faces in the Face container, that is faceContainerSize() - faceNumber()...
Definition face_container.h:124
void deleteFace(const FaceType *f)
Marks as deleted the given Face, before asserting that the Face belongs to this container.
Definition face_container.h:316
std::vector< std::string > perFaceCustomComponentNamesOfType() const
Returns a vector containing all the names of the custom components associated to the Edge Element hav...
Definition face_container.h:975
void deleteFace(uint i)
Marks as deleted the Face with the given id.
Definition face_container.h:301
void disablePerFaceColor()
Disables the Optional Color of the Face.
Definition face_container.h:616
bool isPerFaceCustomComponentOfType(const std::string &name) const
Checks if the custom component of the Face Element having the given name has the same type of the giv...
Definition face_container.h:928
void enablePerFaceNormal()
Enable the Optional Normal of the Face.
Definition face_container.h:679
void disablePerFaceWedgeColors()
Disables the Optional WedgeColors of the Face.
Definition face_container.h:815
bool isPerFaceWedgeTexCoordsEnabled() const
Checks if the Face Optional WedgeTexCoords is enabled.
Definition face_container.h:830
void deletePerFaceCustomComponent(const std::string &name)
Deletes the custom component of the given name from the Face Element.
Definition face_container.h:1010
void disablePerFaceNormal()
Disables the Optional Normal of the Face.
Definition face_container.h:690
ConstCustomComponentVectorHandle< K > perFaceCustomComponentVectorHandle(const std::string &name) const
Returns a const vector handle to the custom component having type K and the given name.
Definition face_container.h:1106
void compactFaces()
Compacts the FaceContainer, removing all the Faces marked as deleted. Faces indices will change accor...
Definition face_container.h:287
std::type_index perFaceCustomComponentType(const std::string &name) const
Returns the std::type_index of the custom component of the Face Element having the given input name.
Definition face_container.h:949
ConstFaceIterator faceBegin(bool jumpDeleted=true) const
Returns a const iterator to the beginning of the container.
Definition face_container.h:414
void enablePerFaceWedgeTexCoords()
Enable the Optional WedgeTexCoords of the Face.
Definition face_container.h:848
void enablePerFaceAdjacentFaces()
Enable the Optional AdjacentFaces of the Face.
Definition face_container.h:567
uint faceNumber() const
Returns the number of non-deleted Faces contained in the Face container of the Mesh.
Definition face_container.h:105
void manageImportTriFromPoly(const OthMesh &m)
This function manages the case where we try to import into a TriMesh a PolyMesh Faces have been alrea...
Definition face_container.h:1120
void enablePerFaceWedgeColors()
Enable the Optional WedgeColors of the Face.
Definition face_container.h:804
uint addFaces(uint n)
Add an arbitrary number of n Faces, returning the id of the first added Face.
Definition face_container.h:211
uint faceIndexIfCompact(uint i) const
This is an utility member function that returns the index of an element if the container would be com...
Definition face_container.h:331
void enablePerFaceMark()
Enable the Optional Mark of the Face.
Definition face_container.h:642
uint addFace()
Add a Face to the container, returning its index.
Definition face_container.h:135
void updateFaceIndices(const std::vector< uint > &newIndices)
Updates all the indices and pointers of the Faces of this container that are stored in any container ...
Definition face_container.h:376
bool isPerFaceAdjacentEdgesEnabled() const
Checks if the Face Optional AdjacentEdges is enabled.
Definition face_container.h:504
void enablePerFaceAdjacentEdges()
Enable the Optional AdjacentEdges of the Face.
Definition face_container.h:522
void enableAllPerFaceOptionalComponents()
Enables all the optional components associated to the Face type contained in the FaceContainer.
Definition face_container.h:480
bool isPerFaceColorEnabled() const
Checks if the Face Optional Color is enabled.
Definition face_container.h:594
const FaceType & face(uint i) const
Returns a const reference of the Face at the i-th position in the Face Container of the Mesh,...
Definition face_container.h:82
void resizeFaces(uint n)
Resizes the Face container to contain n Faces.
Definition face_container.h:259
The Vertex Container class, will be used when the template argument given to the Mesh is a Vertex.
Definition vertex_container.h:51
Definition face.h:62
Definition per_mesh.h:39
The HasFaceContainer concept is satisfied only if a container class provides the types and member fun...
Definition face_container.h:44
std::vector< uint > earCut(Iterator begin, Iterator end)
Triangulates a simple polygon with no holes using the ear-cutting algorithm.
Definition ear_cut.h:92
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