VCG Library
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
vcg::tri::HandleTunnelLoops< MeshType > Class Template Reference

Handle and tunnel loops of an orientable surface. More...

#include <handle_tunnel_loops.h>

Classes

struct  Param
 Options of Compute(); the defaults suit most meshes. More...
 

Public Types

typedef std::vector< int > Loop
 

Public Member Functions

void Compute (MeshType &m, const Param &par=Param())
 Compute genus, handles and tunnels of m.
 

Static Public Member Functions

template<class EdgeMeshType >
static void LoopsToEdgeMesh (const MeshType &m, const std::vector< Loop > &loops, EdgeMeshType &em)
 Append loops to the edge mesh em, one closed polyline each.
 

Public Attributes

std::vector< Loop > handles
 the handle loops, around the handles
 
std::vector< Loop > tunnels
 the tunnel loops, around the tunnels
 
int genus = 0
 genus of the surface, with its holes closed
 

Detailed Description

template<class MeshType>
class vcg::tri::HandleTunnelLoops< MeshType >

Handle and tunnel loops of an orientable surface.

A closed surface of genus g bounds an inside I and an outside O. A handle loop bounds a surface in I but not in O: it circles a handle, like the meridian of a torus, which goes around the tube. A tunnel loop bounds in O but not in I: it circles a tunnel, like the longitude of a torus, which goes around the hole. The handle loops span a g-dimensional half of the homology of the surface and the tunnel loops the other half. Compute() finds g short handle loops and g short tunnel loops spanning them, as closed vertex-edge paths on the mesh. They are what to cut to remove a handle or to fill a tunnel, e.g. to repair the topology of a scanned or reconstructed surface.

Usage
ht.Compute(m);
for (const auto &loop : ht.handles) // ht.genus loops
for (int vi : loop) { ... m.vert[vi] ... }
MyEdgeMesh em; // to save or draw them
Handle and tunnel loops of an orientable surface.
Definition: handle_tunnel_loops.h:142
std::vector< Loop > handles
the handle loops, around the handles
Definition: handle_tunnel_loops.h:162
static void LoopsToEdgeMesh(const MeshType &m, const std::vector< Loop > &loops, EdgeMeshType &em)
Append loops to the edge mesh em, one closed polyline each.
Definition: handle_tunnel_loops.h:224
void Compute(MeshType &m, const Param &par=Param())
Compute genus, handles and tunnels of m.
Definition: handle_tunnel_loops.h:175
See also the sample trimesh_handle_tunnel.cpp.
Requirements
  • Components: vertex coordinates and face vertex references only. The algorithm works on an internal copy with its own adjacency, so no adjacency has to be up to date and the mesh is not modified.
  • The surface must be connected, orientable and edge-manifold. Small holes are allowed: each is closed with a fan around its centroid, and the loops are routed along the hole boundary instead of across it. Larger or knotted holes make the handle/tunnel classification depend on how they would be closed.
  • A violated requirement throws vcg::MissingPreconditionException.
Output
genus, and the loops in handles and tunnels, as indices of mesh vertices. A sphere gives no loops.
Algorithm
It follows T. K. Dey, F. Fan and Y. Wang, "An efficient computation of handle and tunnel loops via Reeb graphs", ACM TOG 32(4), 2013, without any volume mesh:
  1. the Reeb graph (tri::ReebGraph) of a random height function gives g loops on the surface, each with a dual loop in the level set just above its lowest point;
  2. the local shape at that lowest point tells whether each loop is non-trivial inside or outside; pushing each loop off the surface on that side gives bases of the homology of I and of O;
  3. inverting the matrix of linking numbers between the loops on the surface and the pushed ones turns the 2g loops into a handle basis and a tunnel basis;
  4. both bases are then tightened: among the loops made of an edge and two shortest paths to a few base points, the shortest independent ones of each family are kept, and the base points are moved onto them, until the total length stops decreasing for Param::patience rounds.

Tightening is a heuristic: the loops are short, not the shortest. It dominates the running time, which grows with the size and the genus of the mesh: about 20 s for genus 4 and 640K triangles, 10 s for genus 27 and 92K triangles, 5 minutes for genus 100 and 287K triangles.

Before tightening (Param::maxIter = 0) a basis element is a sum of several of the 2g loops and often has more than one component: each becomes its own Loop, so there can be more than g of them. Tightened elements are single loops.

Local minima
A basis keeps one loop per independent direction, the shortest found. Where to cut a complex object is better answered by every place where a loop is locally short: the several necks of one long handle, which are all the same class and of which a basis keeps one, and the loops around a few handles at once. With Param::localMinima, Compute() starts from Param::samples root vertices spread over the surface (farthest point sampling); from each, the shortest loop of each handle and tunnel class through it is a candidate. Candidates of one class sharing more than Param::overlap of their vertices (of the smaller) are one, the shorter kept; each is then tightened on its own, re-rooted at its vertices while that finds a shorter loop of its class, and the duplicates merged again. Of these, the local minima of length are kept: those that no nearby loop of their class undercuts, and that are separated from any shorter one by loops at least Param::persistence longer, so that a tube of constant section gives one loop and two necks give two. handles and tunnels are then these loops, shortest first, as many as Param::maxLoops allows.

Member Typedef Documentation

◆ Loop

template<class MeshType >
typedef std::vector<int> vcg::tri::HandleTunnelLoops< MeshType >::Loop

A closed vertex-edge path: indices of mesh vertices, consecutive ones joined by an edge, the last joined to the first.

Member Function Documentation

◆ Compute()

template<class MeshType >
void vcg::tri::HandleTunnelLoops< MeshType >::Compute ( MeshType &  m,
const Param &  par = Param() 
)
inline

Compute genus, handles and tunnels of m.

Parameters
mthe surface; only read
paroptions
Exceptions
vcg::MissingPreconditionExceptionif the mesh has non-manifold edges, a hole whose boundary touches itself, more than one connected component, or no consistent orientation, or if every height direction tried was degenerate.

◆ LoopsToEdgeMesh()

template<class MeshType >
template<class EdgeMeshType >
static void vcg::tri::HandleTunnelLoops< MeshType >::LoopsToEdgeMesh ( const MeshType &  m,
const std::vector< Loop > &  loops,
EdgeMeshType &  em 
)
inlinestatic

Append loops to the edge mesh em, one closed polyline each.

Parameters
mthe mesh the loops are on
loopsloops of m, e.g. handles or tunnels
eman edge mesh with vertex coordinates and edge vertex references

The documentation for this class was generated from the following file: