GTS Library Reference Manual
<<< Previous Page | Home | Up | Next Page >>>

# Surface simplification and refinement

## Name

Surface simplification and refinement -- reducing or increasing the number of edges of a triangulated surface.

## Synopsis

    #include <gts.h>

    void        gts_surface_refine              (GtsSurface *surface,
                                                 GtsKeyFunc cost_func,
                                                 gpointer cost_data,
                                                 GtsStopFunc stop_func,
                                                 gpointer stop_data);

    GtsVertex*  (*GtsCoarsenFunc)               (GtsEdge *e,
                                                 GtsVertexClass *klass,
                                                 gpointer data);
    gboolean    (*GtsStopFunc)                  (gdouble cost,
                                                 guint nedge,
                                                 gpointer data);
    void        gts_surface_coarsen             (GtsSurface *surface,
                                                 GtsKeyFunc cost_func,
                                                 gpointer cost_data,
                                                 GtsCoarsenFunc coarsen_func,
                                                 gpointer coarsen_data,
                                                 GtsStopFunc stop_func,
                                                 gpointer stop_data,
                                                 gdouble minangle);
    gboolean    gts_coarsen_stop_number         (gdouble cost,
                                                 guint nedge,
                                                 guint *min_number);
    gboolean    gts_coarsen_stop_cost           (gdouble cost,
                                                 guint nedge,
                                                 gdouble *max_cost);

    struct      GtsVolumeOptimizedParams;
    GtsVertex*  gts_volume_optimized_vertex     (GtsEdge *edge,
                                                 GtsVertexClass *klass,
                                                 GtsVolumeOptimizedParams *params);
    gdouble     gts_volume_optimized_cost       (GtsEdge *e,
                                                 GtsVolumeOptimizedParams *params);
    gboolean    gts_edge_collapse_is_valid      (GtsEdge *e);
    gboolean    gts_edge_collapse_creates_fold  (GtsEdge *e,
                                                 GtsVertex *v,
                                                 gdouble max);

## Description

The gts_surface_coarsen() function allows to reduce the number of edges (and of course faces and vertices) of a given surface. Each edge is collapsed according to an order described by a user-defined cost function. It is then replaced by a single vertex given by another user-defined function. Two sets of cost and replacement functions are provided with the library. The default uses the squared length of the segment as cost and replaces the segment with its midpoint.

The functions gts_volume_optimized_cost() and gts_volume_optimized_vertex() are an implementation of an algorithm proposed by Lindstrom and Turk called "memoryless simplification". This algorithm has been shown to be both computationally efficient and very accurate in terms of error between the simplified surface and the original one. It also preserves the volume enclosed by the surface both globally and locally.

Surface refinement is obtained by splitting the edges in two equal parts according to an order described by a user-defined cost function. The default is to use the squared length of the segments as cost.

The coarsening or refinement processes are stopped using a user-defined stop function. Two functions are provided stopping either when the cost of collapsing an edge is too large (gts_coarsen_stop_cost()) or when the number of edges is too small (gts_coarsen_stop_number()).

## Details

### gts_surface_refine ()

    void        gts_surface_refine              (GtsSurface *surface,
                                                 GtsKeyFunc cost_func,
                                                 gpointer cost_data,
                                                 GtsStopFunc stop_func,
                                                 gpointer stop_data);

Refine `surface` using a midvertex insertion technique. All the edges of `surface` are ordered according to `cost_func`. The edges are then processed in order until `stop_func` returns `TRUE`. Each edge is split in two and new edges and faces are created.

If `cost_func` is set to `NULL`, the edges are sorted according to their length squared (the longest is on top).

`surface` : | a GtsSurface.
`cost_func` : | a function returning the cost for a given edge.
`cost_data` : | user data to be passed to `cost_func`.
`stop_func` : | a GtsStopFunc.
`stop_data` : | user data to be passed to `stop_func`.

### GtsCoarsenFunc ()

    GtsVertex*  (*GtsCoarsenFunc)               (GtsEdge *e,
                                                 GtsVertexClass *klass,
                                                 gpointer data);

User-defined function taking an edge `e` and returning a replacement vertex of class `klass`.

`e` : | a GtsEdge.
`klass` : | the GtsVertexClass of the replacement vertex.
`data` : | user data passed to the function.
Returns : | a replacement vertex of class `klass`.

### GtsStopFunc ()

    gboolean    (*GtsStopFunc)                  (gdouble cost,
                                                 guint nedge,
                                                 gpointer data);

User-defined function used to stop the coarsening process.

`cost` : | the cost of collapse of the current edge.
`nedge` : | the number of edges of the surface after collapse of the current edge.
`data` : | user data passed to the function.
Returns : | `TRUE` if the collapse of the current edge is not to take place, `FALSE` otherwise.

### gts_surface_coarsen ()

    void        gts_surface_coarsen             (GtsSurface *surface,
                                                 GtsKeyFunc cost_func,
                                                 gpointer cost_data,
                                                 GtsCoarsenFunc coarsen_func,
                                                 gpointer coarsen_data,
                                                 GtsStopFunc stop_func,
                                                 gpointer stop_data,
                                                 gdouble minangle);

The edges of `surface` are sorted according to `cost_func` to create a priority heap (a GtsEHeap). The edges are extracted in turn from the top of the heap and collapsed (i.e. the vertices are replaced by the vertex returned by the `coarsen_func` function) until the `stop_func` functions returns `TRUE`.

If `cost_func` is set to `NULL`, the edges are sorted according to their length squared (the shortest is on top).

If `coarsen_func` is set to `NULL` gts_segment_midvertex() is used.

The minimum angle is used to avoid introducing faces which would be folded.

`surface` : | a GtsSurface.
`cost_func` : | a function returning the cost for a given edge.
`cost_data` : | user data to be passed to `cost_func`.
`coarsen_func` : | a GtsCoarsenVertexFunc.
`coarsen_data` : | user data to be passed to `coarsen_func`.
`stop_func` : | a GtsStopFunc.
`stop_data` : | user data to be passed to `stop_func`.
`minangle` : | minimum angle between two neighboring triangles.

### gts_coarsen_stop_number ()

    gboolean    gts_coarsen_stop_number         (gdouble cost,
                                                 guint nedge,
                                                 guint *min_number);

This function is to be used as the `stop_func` argument of gts_surface_coarsen() or gts_psurface_new().

`cost` : | the cost of the edge collapse considered.
`nedge` : | the current number of edges of the surface being simplified.
`min_number` : | a pointer to the minimum number of edges desired for the surface being simplified.
Returns : | `TRUE` if the edge collapse would create a surface with a smaller number of edges than given by `min_number`, `FALSE` otherwise.

### gts_coarsen_stop_cost ()

    gboolean    gts_coarsen_stop_cost           (gdouble cost,
                                                 guint nedge,
                                                 gdouble *max_cost);

This function is to be used as the `stop_func` argument of gts_surface_coarsen() or gts_psurface_new().

`cost` : | the cost of the edge collapse considered.
`nedge` : | the current number of edges of the surface being simplified.
`max_cost` : | a pointer to the maximum cost allowed for an edge collapse.
Returns : | `TRUE` if the cost of the edge collapse considered is larger than given by `max_cost`, `FALSE` otherwise.

### struct GtsVolumeOptimizedParams

    struct GtsVolumeOptimizedParams {
      gdouble volume_weight;
      gdouble boundary_weight;
      gdouble shape_weight;
    };

The parameters for the volume optimization algorithm of Lindstrom and Turk. THey define the relative weight of the volume, boundary and shape optimization part of the algorithm. Lindstrom and Turk advice is to set them to 0.5, 0.5 and 0. You may want to experiment depending on your problem. Setting `shape_weight` to a very small value (1e-10) for example might help improve the quality of the resulting triangulation.

gdouble `volume_weight` | Weight of the volume optimization.
gdouble `boundary_weight` | Weight of the boundary optimization.
gdouble `shape_weight` | Weight of the shape optimization.

### gts_volume_optimized_vertex ()

    GtsVertex*  gts_volume_optimized_vertex     (GtsEdge *edge,
                                                 GtsVertexClass *klass,
                                                 GtsVolumeOptimizedParams *params);

`edge` : | a GtsEdge.
`klass` : | a GtsVertexClass to be used for the new vertex.
`params` : | a GtsVolumeOptimizedParms.
Returns : | a GtsVertex which can be used to replace `edge` for an edge collapse operation. The position of the vertex is optimized in order to minimize the changes in area and volume for the surface using `edge`. The volume enclosed by the surface is locally preserved. For more details see "Fast and memory efficient polygonal simplification" (1998) and "Evaluation of memoryless simplification" (1999) by Lindstrom and Turk.

### gts_volume_optimized_cost ()

    gdouble     gts_volume_optimized_cost       (GtsEdge *e,
                                                 GtsVolumeOptimizedParams *params);

`e` : | a GtsEdge.
`params` : | a GtsVolumeOptimizedParams.
Returns : | the cost for the collapse of `e` as minimized by the function gts_volume_optimized_vertex().

### gts_edge_collapse_is_valid ()

    gboolean    gts_edge_collapse_is_valid      (GtsEdge *e);

An implementation of the topological constraints described in the "Mesh Optimization" article of Hoppe et al (1993).

`e` : | a GtsEdge.
Returns : | `TRUE` if `e` can be collapsed without violation of the topological constraints, `FALSE` otherwise.

### gts_edge_collapse_creates_fold ()

    gboolean    gts_edge_collapse_creates_fold  (GtsEdge *e,
                                                 GtsVertex *v,
                                                 gdouble max);

`e` : | a GtsEdge.
`v` : | a GtsVertex.
`max` : | the maximum value of the square of the cosine of the angle between two triangles.
Returns : | `TRUE` if collapsing edge `e` to vertex `v` would create faces making an angle the cosine squared of which would be larger than max, `FALSE` otherwise.

<<< Previous Page | Home | Up | Next Page >>>
Boolean operations | Out-of-core simplification