Skip to content

Commit

Permalink
[algorithms] move referencedVertices algorithm outside vcl::detail an…
Browse files Browse the repository at this point in the history
…d in stat/topology.h
  • Loading branch information
alemuntoni committed Jan 16, 2025
1 parent fcf9599 commit 40d5991
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 75 deletions.
79 changes: 5 additions & 74 deletions vclib/core/include/vclib/algorithms/mesh/clean.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <vclib/algorithms/core/polygon/ear_cut.h>
#include <vclib/algorithms/mesh/sort.h>
#include <vclib/algorithms/mesh/stat/topology.h>
#include <vclib/mesh/requirements.h>
#include <vclib/space/complex/mesh_pos.h>

Expand Down Expand Up @@ -58,73 +59,6 @@ class VertPositionComparator
}
};

template<typename Cont, typename MeshType>
void setReferencedVerticesOnVector(
const MeshType& m,
std::vector<bool>& refs,
uint& nRefs)
{
// check if the Cont container of the Mesh has vertex pointers
if constexpr (comp::HasVertexReferences<typename Cont::ElementType>) {
// 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<ELEM_ID>()) {
// 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<typename MeshType, typename... Cont>
void setReferencedVerticesOnVector(
const MeshType& m,
std::vector<bool>& refs,
uint& nRefs,
TypeWrapper<Cont...>)
{
// call the setReferencedVerticesOnVector function for each container of the
// mesh
(setReferencedVerticesOnVector<Cont>(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<typename MeshType>
std::vector<bool> unreferencedVerticesVectorBool(
const MeshType& m,
uint& nUnref)
{
using VertexType = MeshType::VertexType;

uint nRefs = 0;
std::vector<bool> 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.
Expand Down Expand Up @@ -285,10 +219,8 @@ template<MeshConcept MeshType>
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<bool> referredVertices =
detail::unreferencedVerticesVectorBool(m, nV);
// store the number of unref vertices into nV
referencedVertices<std::vector<bool>>(m, nV);

return nV;
}
Expand Down Expand Up @@ -320,8 +252,7 @@ uint removeUnreferencedVertices(MeshType& m)
// referenced by any of the mesh's elements.

uint n = 0;
std::vector<bool> referredVertices =
detail::unreferencedVerticesVectorBool(m, n);
std::vector<bool> refVertices = referencedVertices<std::vector<bool>>(m, n);

// need to mark as deleted vertices only if the number of unreferenced is
// less than vn
Expand All @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions vclib/core/include/vclib/algorithms/mesh/stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
129 changes: 129 additions & 0 deletions vclib/core/include/vclib/algorithms/mesh/stat/topology.h
Original file line number Diff line number Diff line change
@@ -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 <vclib/concepts/mesh.h>

namespace vcl {

namespace detail {

// function called for the Container Cont of the Mesh
template<typename Cont>
void setReferencedVertices(const auto& mesh, auto& refs, uint& nRefs)
{
// check if the Cont container of the Mesh has vertex references
if constexpr (comp::HasVertexReferences<typename Cont::ElementType>) {
// 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<ELEM_ID>()) {
// 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<typename... Cont>
void setReferencedVertices(
const auto& mesh,
auto& refs,
uint& nRefs,
TypeWrapper<Cont...>)
{
// call the setReferencedVerticesOnVector function for each container of the
// mesh
(setReferencedVertices<Cont>(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<typename Container, MeshConcept MeshType>
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<MeshType>) {
using FaceContainer = MeshType::FaceContainer;

detail::setReferencedVertices(
mesh, refVertices, nRefs, TypeWrapper<FaceContainer>());
}
}
else {
detail::setReferencedVertices(
mesh, refVertices, nRefs, typename MeshType::Containers());
}

nUnref = mesh.vertexNumber() - nRefs;

return refVertices;
}

} // namespace vcl

#endif // VCL_ALGORITHMS_MESH_STAT_TOPOLOGY_H
16 changes: 15 additions & 1 deletion vclib/core/include/vclib/mesh/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,20 @@ class Mesh : public Args...
FilterTypesByCondition<comp::IsComponentPred, TypeWrapper<Args...>>::
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<ElemId::VERTEX>;
* ```
*/
template<uint ELEM_ID>
using ContainerType = ContainerOfElement<ELEM_ID>::type;

/**
* @brief ElementType is an alias that exposes the type of the Element
* identified by the template parameter ELEM_ID.
Expand All @@ -134,7 +148,7 @@ class Mesh : public Args...
* ```
*/
template<uint ELEM_ID>
using ElementType = ContainerOfElement<ELEM_ID>::type::ElementType;
using ElementType = ContainerType<ELEM_ID>::ElementType;

/* Constexpr static member functions */

Expand Down

0 comments on commit 40d5991

Please sign in to comment.