diff --git a/vclib/core/include/vclib/algorithms/mesh/clean.h b/vclib/core/include/vclib/algorithms/mesh/clean.h index 432efca8d..363e0a28f 100644 --- a/vclib/core/include/vclib/algorithms/mesh/clean.h +++ b/vclib/core/include/vclib/algorithms/mesh/clean.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -58,73 +59,6 @@ class VertPositionComparator } }; -template -void setReferencedVerticesOnVector( - const MeshType& m, - std::vector& refs, - uint& nRefs) -{ - // check if the Cont container of the Mesh has vertex pointers - if constexpr (comp::HasVertexReferences) { - // if there are still some vertices non-referenced - if (nRefs < m.vertexNumber()) { - constexpr uint ELEM_ID = Cont::ElementType::ELEMENT_ID; - // for eache element of the Cont container - for (const auto& el : m.template elements()) { - // for each vertex of the element - for (uint vi : el.vertexIndices()) { - assert(vi != UINT_NULL); - if (!refs[vi]) { - // set the vertex as referenced - refs[vi] = true; - nRefs++; - } - } - } - } - } -} - -template -void setReferencedVerticesOnVector( - const MeshType& m, - std::vector& refs, - uint& nRefs, - TypeWrapper) -{ - // call the setReferencedVerticesOnVector function for each container of the - // mesh - (setReferencedVerticesOnVector(m, refs, nRefs), ...); -} - -/** - * @brief unreferencedVerticesVectorBool returns a vector of boolean telling, - * for each vertex of the Mesh m, if it is referenced by any other Element of - * the Mesh. - * - * The size of the vector will be == to the vertexContainerSize of m, and all - * the deleted vertices are marked as unreferenced by default. - * - * @param m - * @return - */ -template -std::vector unreferencedVerticesVectorBool( - const MeshType& m, - uint& nUnref) -{ - using VertexType = MeshType::VertexType; - - uint nRefs = 0; - std::vector referredVertices(m.vertexContainerSize(), false); - - setReferencedVerticesOnVector( - m, referredVertices, nRefs, typename MeshType::Containers()); - nUnref = m.vertexNumber() - nRefs; - - return referredVertices; -} - /** * @brief The SortedIndexContainer class stores a sorted container of indices of * type IndexType, plus a Sentinel value. @@ -285,10 +219,8 @@ template uint numberUnreferencedVertices(const MeshType& m) { uint nV = 0; - // Generate a vector of boolean flags indicating whether each vertex is - // referenced by any of the mesh's elements. - std::vector referredVertices = - detail::unreferencedVerticesVectorBool(m, nV); + // store the number of unref vertices into nV + referencedVertices>(m, nV); return nV; } @@ -320,8 +252,7 @@ uint removeUnreferencedVertices(MeshType& m) // referenced by any of the mesh's elements. uint n = 0; - std::vector referredVertices = - detail::unreferencedVerticesVectorBool(m, n); + std::vector refVertices = referencedVertices>(m, n); // need to mark as deleted vertices only if the number of unreferenced is // less than vn @@ -331,7 +262,7 @@ uint removeUnreferencedVertices(MeshType& m) // Iterate over all vertices in the mesh, and mark any unreferenced // vertex as deleted. for (const VertexType& v : m.vertices()) { - if (!referredVertices[m.index(v)]) { + if (!refVertices[m.index(v)]) { m.deleteVertex(m.index(v)); } else { diff --git a/vclib/core/include/vclib/algorithms/mesh/stat.h b/vclib/core/include/vclib/algorithms/mesh/stat.h index 2d6e947b7..dbc61a768 100644 --- a/vclib/core/include/vclib/algorithms/mesh/stat.h +++ b/vclib/core/include/vclib/algorithms/mesh/stat.h @@ -28,6 +28,7 @@ #include "stat/geometry.h" #include "stat/quality.h" #include "stat/selection.h" +#include "stat/topology.h" /** * @defgroup mesh_stat Mesh Statistic Algorithms diff --git a/vclib/core/include/vclib/algorithms/mesh/stat/topology.h b/vclib/core/include/vclib/algorithms/mesh/stat/topology.h new file mode 100644 index 000000000..e29507946 --- /dev/null +++ b/vclib/core/include/vclib/algorithms/mesh/stat/topology.h @@ -0,0 +1,129 @@ +/***************************************************************************** + * VCLib * + * Visual Computing Library * + * * + * Copyright(C) 2021-2025 * + * Visual Computing Lab * + * ISTI - Italian National Research Council * + * * + * All rights reserved. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the Mozilla Public License Version 2.0 as published * + * by the Mozilla Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * Mozilla Public License Version 2.0 * + * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. * + ****************************************************************************/ + +#ifndef VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H +#define VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H + +#include + +namespace vcl { + +namespace detail { + +// function called for the Container Cont of the Mesh +template +void setReferencedVertices(const auto& mesh, auto& refs, uint& nRefs) +{ + // check if the Cont container of the Mesh has vertex references + if constexpr (comp::HasVertexReferences) { + // if there are still some vertices non-referenced + if (nRefs < mesh.vertexNumber()) { + constexpr uint ELEM_ID = Cont::ElementType::ELEMENT_ID; + // for eache element of the Cont container + for (const auto& el : mesh.template elements()) { + // for each vertex of the element + for (uint vi : el.vertexIndices()) { + // vertex references shoule never be null + assert(vi != UINT_NULL); + if (!refs[vi]) { + // set the vertex as referenced + refs[vi] = true; + nRefs++; + } + } + } + } + } +} + +// function called for each container of the Mesh, using variadic templates +template +void setReferencedVertices( + const auto& mesh, + auto& refs, + uint& nRefs, + TypeWrapper) +{ + // call the setReferencedVerticesOnVector function for each container of the + // mesh + (setReferencedVertices(mesh, refs, nRefs), ...); +} + +} // namespace detail + +/** + * @brief Returns a Container of values interpreted as booleans telling, for + * each vertex of the mesh, if it is referenced. + * + * If the parameter `onlyFaces` is `false` (default), the check is made for each + * Element of the mesh that stores Vertex References. If `onlyFaces` is `true`, + * the check is made only for the Faces of the mesh. + * + * The size of the returned container will be == to the vertexContainerSize of + * the mesh, and all the deleted vertices are marked as unreferenced by default. + * + * @tparam Container: The type of the container to be used to store the boolean + * values. It must be a container that can be indexed with integer values and + * that can be initialized with a size and a default value. + * @tparam MeshType: The type of the input Mesh. It must satisfy the + * MeshConcept. + * + * @param[in] mesh: The input mesh for which to calculate the referenced + * vertices. + * @param[out] nUnref: The number of non-referenced vertices. + * @param[in] onlyFaces: If true, only the faces of the mesh are considered. + * @return a Container of values interpreted as booleans telling, for each + * vertex of the mesh, if it is referenced. + */ +template +Container referencedVertices( + const MeshType& mesh, + uint& nUnref, + bool onlyFaces = false) +{ + using VertexType = MeshType::VertexType; + + uint nRefs = 0; + + Container refVertices(mesh.vertexContainerSize(), false); + + if (onlyFaces) { + if constexpr (FaceMeshConcept) { + using FaceContainer = MeshType::FaceContainer; + + detail::setReferencedVertices( + mesh, refVertices, nRefs, TypeWrapper()); + } + } + else { + detail::setReferencedVertices( + mesh, refVertices, nRefs, typename MeshType::Containers()); + } + + nUnref = mesh.vertexNumber() - nRefs; + + return refVertices; +} + +} // namespace vcl + +#endif // VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H diff --git a/vclib/core/include/vclib/mesh/mesh.h b/vclib/core/include/vclib/mesh/mesh.h index 75c6a6c14..6b2fb4d78 100644 --- a/vclib/core/include/vclib/mesh/mesh.h +++ b/vclib/core/include/vclib/mesh/mesh.h @@ -122,6 +122,20 @@ class Mesh : public Args... FilterTypesByCondition>:: type; + /** + * @brief ContainerType is an alias that exposes the type of the Container + * that stores the Element identified by the template parameter ELEM_ID. + * + * To be used, the Mesh must have an ElementContainer having ID ELEM_ID. + * + * Usage: + * ```cpp + * using VertexContainer = MeshType::template ContainerType; + * ``` + */ + template + using ContainerType = ContainerOfElement::type; + /** * @brief ElementType is an alias that exposes the type of the Element * identified by the template parameter ELEM_ID. @@ -134,7 +148,7 @@ class Mesh : public Args... * ``` */ template - using ElementType = ContainerOfElement::type::ElementType; + using ElementType = ContainerType::ElementType; /* Constexpr static member functions */