23#ifndef VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H
24#define VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H
26#include <vclib/concepts/mesh.h>
27#include <vclib/mesh/requirements.h>
36template<
typename Cont>
37void setReferencedVertices(
const auto& mesh,
auto& refs, uint& nRefs)
40 if constexpr (comp::HasVertexReferences<typename Cont::ElementType>) {
42 if (nRefs < mesh.vertexNumber()) {
43 constexpr uint ELEM_ID = Cont::ElementType::ELEMENT_ID;
45 for (
const auto& el : mesh.template elements<ELEM_ID>()) {
47 for (uint vi : el.vertexIndices()) {
62template<
typename... Cont>
63void setReferencedVertices(
71 (setReferencedVertices<Cont>(mesh, refs, nRefs), ...);
75template<
typename WedgeTexCoordType>
76struct WedgeTexCoordsInfo
78 WedgeTexCoordType texCoord;
81 bool operator<(
const WedgeTexCoordsInfo& other)
const
83 if (texCoordIndex == other.texCoordIndex) {
84 return texCoord < other.texCoord;
86 return texCoordIndex < other.texCoordIndex;
90inline std::list<uint> dummyUintList;
91inline std::list<std::list<std::pair<uint, uint>>> dummyListOfLists;
92inline std::vector<std::pair<uint, uint>> dummyVectorOfPairs;
106uint countPerFaceVertexReferences(
const MeshConcept
auto& mesh)
108 using MeshType =
decltype(mesh);
112 if constexpr (FaceMeshConcept<MeshType>) {
113 if constexpr (TriangleMeshConcept<MeshType>) {
114 return mesh.faceNumber() * 3;
117 for (
const auto& f : mesh.
faces()) {
118 nRefs += f.vertexNumber();
135uint largestFaceSize(
const MeshConcept
auto& mesh)
137 using MeshType =
decltype(mesh);
139 uint maxFaceSize = 0;
141 if constexpr (TriangleMeshConcept<MeshType>) {
144 else if constexpr (FaceMeshConcept<MeshType>) {
145 for (
const auto& f : mesh.
faces()) {
146 maxFaceSize = std::max(maxFaceSize, f.vertexNumber());
161uint countTriangulatedTriangles(
const MeshConcept
auto& mesh)
163 using MeshType =
decltype(mesh);
167 if constexpr (FaceMeshConcept<MeshType>) {
168 for (
const auto& f : mesh.
faces()) {
169 nTris += f.vertexNumber() - 2;
200template<
typename Container, MeshConcept MeshType>
201Container referencedVertices(
202 const MeshType& mesh,
204 bool onlyFaces =
false)
206 using VertexType = MeshType::VertexType;
210 Container refVertices(mesh.vertexContainerSize(),
false);
213 if constexpr (FaceMeshConcept<MeshType>) {
214 using FaceContainer = MeshType::FaceContainer;
216 detail::setReferencedVertices(
217 mesh, refVertices, nRefs, TypeWrapper<FaceContainer>());
221 detail::setReferencedVertices(
222 mesh, refVertices, nRefs,
typename MeshType::Containers());
225 nUnref = mesh.vertexNumber() - nRefs;
254template<FaceMeshConcept MeshType>
255uint countVerticesToDuplicateByWedgeTexCoords(
256 const MeshType& mesh,
257 std::vector<std::pair<uint, uint>>& vertWedgeMap =
258 detail::dummyVectorOfPairs,
259 std::list<uint>& vertsToDuplicate = detail::dummyUintList,
260 std::list<std::list<std::pair<uint, uint>>>& facesToReassign =
261 detail::dummyListOfLists)
265 using WedgeTexCoordType = MeshType::FaceType::WedgeTexCoordType;
266 using WedgeTexCoordsInfo = detail::WedgeTexCoordsInfo<WedgeTexCoordType>;
270 using FaceList = std::list<std::pair<uint, uint>>;
272 vertWedgeMap.resize(mesh.vertexContainerSize());
273 vertsToDuplicate.clear();
274 facesToReassign.clear();
282 std::vector<std::map<WedgeTexCoordsInfo, FaceList>> wedges(
283 mesh.vertexContainerSize());
286 for (
const auto& f : mesh.
faces()) {
287 for (uint i = 0; i < f.vertexNumber(); ++i) {
288 uint vi = f.vertexIndex(i);
291 WedgeTexCoordsInfo wi = {f.wedgeTexCoord(i), f.textureIndex()};
292 auto it = wedges[vi].find(wi);
293 if (it == wedges[vi].end()) {
296 if (!wedges[vi].empty()) {
299 wedges[vi][wi].emplace_back(f.index(), i);
304 it->second.emplace_back(f.index(), i);
313 for (uint vi = 0;
auto& map : wedges) {
314 if (map.size() > 1) {
321 auto it = std::max_element(
322 map.begin(), map.end(), [](
const auto& a,
const auto& b) {
323 return a.second.size() < b.second.size();
327 vertWedgeMap[vi] = it->second.front();
331 for (
auto& [wi, fl] : map) {
332 vertsToDuplicate.push_back(vi);
333 facesToReassign.push_back(std::move(fl));
337 if (map.size() == 1) {
340 vertWedgeMap[vi] = map.begin()->second.front();
349 assert(vertWedgeMap.size() == mesh.vertexContainerSize());
350 assert(vertsToDuplicate.size() == count);
351 assert(facesToReassign.size() == count);
void requirePerFaceWedgeTexCoords(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a WedgeTexCoords Component,...
Definition face_requirements.h:947
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
constexpr detail::FacesView faces
A view that allows to iterate overt the Face elements of an object.
Definition face.h:52