23#ifndef VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H
24#define VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H
28#include <vclib/mesh.h>
29#include <vclib/space/complex.h>
40template<
typename Cont>
41void setReferencedVertices(
const auto& mesh,
auto& refs, uint& nRefs)
44 if constexpr (comp::HasVertexReferences<typename Cont::ElementType>) {
46 if (nRefs < mesh.vertexNumber()) {
47 constexpr uint ELEM_ID = Cont::ElementType::ELEMENT_ID;
49 for (
const auto& el : mesh.template elements<ELEM_ID>()) {
51 for (uint vi : el.vertexIndices()) {
66template<
typename... Cont>
67void setReferencedVertices(
75 (setReferencedVertices<Cont>(mesh, refs, nRefs), ...);
79template<
typename WedgeTexCoordType>
80struct WedgeTexCoordsInfo
82 WedgeTexCoordType texCoord;
85 bool operator<(
const WedgeTexCoordsInfo& other)
const
87 if (texCoordIndex == other.texCoordIndex) {
88 return texCoord < other.texCoord;
90 return texCoordIndex < other.texCoordIndex;
94template<FaceMeshConcept MeshType>
95std::vector<bool> nonManifoldVerticesVectorBool(
const MeshType& m)
96 requires HasPerFaceAdjacentFaces<MeshType>
100 using FaceType = MeshType::FaceType;
102 std::vector<bool> nonManifoldVertices(m.vertexContainerSize(),
false);
104 std::vector<uint> TD(m.vertexContainerSize(), 0);
105 std::vector<bool> nonManifoldInc(m.vertexContainerSize(),
false);
108 for (
const FaceType& f : m.
faces()) {
109 for (uint i = 0; i < f.vertexNumber(); ++i) {
110 TD[m.index(f.vertex(i))]++;
111 if (!isFaceManifoldOnEdge(f, i)) {
112 nonManifoldInc[m.index(f.vertex(i))] =
true;
113 nonManifoldInc[m.index(f.vertexMod(i + 1))] =
true;
118 std::vector<bool> visited(m.vertexContainerSize(),
false);
119 for (
const FaceType& f : m.
faces()) {
120 for (uint i = 0; i < f.vertexNumber(); ++i) {
121 if (!visited[m.index(f.vertex(i))]) {
122 visited[m.index(f.vertex(i))] =
true;
124 uint starSize = pos.numberOfAdjacentFacesToV();
125 if (starSize != TD[m.index(f.vertex(i))])
126 nonManifoldVertices[m.index(f.vertex(i))] =
true;
131 return nonManifoldVertices;
134template<FaceMeshConcept MeshType>
137 uint& numBoundaryEdges,
138 uint& numNonManifoldEdges)
140 std::vector<ConstMeshEdgeUtil<MeshType>> edgeVec =
141 fillAndSortMeshEdgeUtilVector(m);
144 numBoundaryEdges = 0;
145 numNonManifoldEdges = 0;
147 size_t f_on_cur_edge = 1;
148 for (
size_t i = 0; i < edgeVec.size(); ++i) {
149 if (((i + 1) == edgeVec.size()) || !(edgeVec[i] == edgeVec[i + 1])) {
151 if (f_on_cur_edge == 1)
153 if (f_on_cur_edge > 2)
154 ++numNonManifoldEdges;
164inline std::list<uint> dummyUintList;
165inline std::list<std::list<std::pair<uint, uint>>> dummyListOfLists;
166inline std::vector<std::pair<uint, uint>> dummyVectorOfPairs;
184 using MeshType =
decltype(mesh);
189 return mesh.faceNumber() * 3;
192 for (
const auto& f : mesh.faces()) {
193 nRefs += f.vertexNumber();
213 using MeshType =
decltype(mesh);
221 for (
const auto& f : mesh.faces()) {
241 using MeshType =
decltype(mesh);
245 for (
const auto& f : mesh.faces()) {
246 nTris += f.vertexNumber() - 2;
278template<FaceMeshConcept MeshType>
280 const MeshType& mesh,
282 detail::dummyVectorOfPairs,
285 detail::dummyListOfLists)
289 using WedgeTexCoordType = MeshType::FaceType::WedgeTexCoordType;
290 using WedgeTexCoordsInfo = detail::WedgeTexCoordsInfo<WedgeTexCoordType>;
294 using FaceList = std::list<std::pair<uint, uint>>;
306 std::vector<std::map<WedgeTexCoordsInfo, FaceList>>
wedges(
307 mesh.vertexContainerSize());
309 for (
const auto& f : mesh.faces()) {
310 for (uint
i = 0;
i < f.vertexNumber(); ++
i) {
311 uint
vi = f.vertexIndex(
i);
314 WedgeTexCoordsInfo
wi = {f.wedgeTexCoord(
i), f.textureIndex()};
327 it->second.emplace_back(f.index(),
i);
336 for (uint
vi = 0;
auto& map :
wedges) {
337 if (map.size() > 1) {
344 auto it = std::max_element(
345 map.begin(), map.end(), [](
const auto&
a,
const auto&
b) {
346 return a.second.size() < b.second.size();
354 for (
auto& [
wi,
fl] : map) {
360 if (map.size() == 1) {
407template<
typename Container, MeshConcept MeshType>
409 const MeshType& mesh,
413 using VertexType = MeshType::VertexType;
417 Container
refVertices(mesh.vertexContainerSize(),
false);
421 using FaceContainer = MeshType::FaceContainer;
423 detail::setReferencedVertices(
428 detail::setReferencedVertices(
455template<MeshConcept MeshType>
484template<FaceMeshConcept MeshType>
488 detail::nonManifoldVerticesVectorBool(
m);
513template<FaceMeshConcept MeshType>
540template<FaceMeshConcept MeshType>
545 using VertexType = MeshType::VertexType;
546 using FaceType = MeshType::FaceType;
551 std::vector<bool>
visitedFaces(
m.faceContainerSize(),
false);
555 for (
const FaceType& f :
m.faces()) {
557 for (
const VertexType* v : f.vertices()) {
562 curPos.nextEdgeOnBorderAdjacentToV();
597template<FaceMeshConcept MeshType>
603 using FaceType = MeshType::FaceType;
605 std::vector<std::set<uint>>
cc;
608 std::vector<bool>
visitedFaces(
m.faceContainerSize(),
false);
612 std::stack<const FaceType*>
sf;
616 for (
const FaceType& f :
m.faces()) {
623 ccf.insert(
m.index(f));
628 while (!
sf.empty()) {
629 const FaceType*
fpt =
sf.top();
635 for (uint
j = 0;
j <
fpt->vertexNumber(); ++
j) {
636 const FaceType*
adjf =
fpt->adjFace(
j);
668template<FaceMeshConcept MeshType>
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
The FaceMeshConcept is evaluated true if the type T is a Mesh (it satisfies the vcl::MeshConcept) and...
Definition face_requirements.h:70
Concept that checks if a Mesh has the per Face AdjacentFaces component.
Definition face_requirements.h:109
Definition face_requirements.h:73
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< std::set< uint > > connectedComponents(const MeshType &m)
Computes the connected components of the input mesh based on its topology.
Definition topology.h:598
uint numberUnreferencedVertices(const MeshType &m, bool onlyFaces=false)
Returns the number of non-deleted unreferenced vertices of the mesh.
Definition topology.h:456
uint numberHoles(const MeshType &m)
Counts the number of holes in the input mesh.
Definition topology.h:541
uint numberNonManifoldVertices(const MeshType &m)
Counts the number of non-manifold vertices in the input mesh.
Definition topology.h:485
Container referencedVertices(const MeshType &mesh, uint &nUnref, bool onlyFaces=false)
Returns a Container of values interpreted as booleans telling, for each vertex of the mesh,...
Definition topology.h:408
bool isWaterTight(const MeshType &m)
Determines whether the input mesh is water tight.
Definition topology.h:514
uint numberConnectedComponents(const MeshType &m)
Computes the number of connected components of the input mesh based on its topology.
Definition topology.h:669
void requirePerFaceWedgeTexCoords(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a WedgeTexCoords Component,...
Definition face_requirements.h:1209
void requirePerFaceAdjacentFaces(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a AdjacentFaces Component,...
Definition face_requirements.h:960
uint countVerticesToDuplicateByWedgeTexCoords(const MeshType &mesh, std::vector< std::pair< uint, uint > > &vertWedgeMap=detail::dummyVectorOfPairs, std::list< uint > &vertsToDuplicate=detail::dummyUintList, std::list< std::list< std::pair< uint, uint > > > &facesToReassign=detail::dummyListOfLists)
This function counts the number of vertices that must be duplicated in a mesh to have a unique texcoo...
Definition topology.h:279
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:211
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:239
constexpr detail::FacesView faces
A view that allows to iterate overt the Face elements of an object.
Definition face.h:84