Mesh Processing Library

Mesh Processing Library


This package contains a C++ library and several application programs that demonstrate mesh processing technologies published in research papers at ACM SIGGRAPH in 1992–1998:

  • surface reconstruction (from unorganized, unoriented points)
  • mesh optimization
  • subdivision surface fitting
  • mesh simplification
  • progressive meshes (level-of-detail representation)
  • geomorphs (smooth transitions across LOD meshes)
  • view-dependent mesh refinement
  • smooth terrain LOD
  • progressive simplicial complexes

The source code follows modern C++11 style and is designed for cross-platform use.

Version history

Version 1.0 — 2016-04-28.

Requirements / dependencies

The source code can be compiled with Microsoft Visual Studio 2015 from the included solution (.sln) and project (.vcxproj) files, using either the Integrated Development Environment (IDE) or the msbuild command.

The code can also be compiled using gcc and clang compilers (as well as the Microsoft Visual Studio cl compiler) using a set of Makefiles designed for GNU make (available in Unix and in the Windows Cygwin environment).

On Microsoft Windows, the library reads/writes images and videos using Windows Imaging Component (WIC) and Windows Media Foundation (WMF), respectively. Image I/O can also use the standard libpng and libjpeg libraries. Alternatively, if the command ffmpeg is present in the PATH, that command is spawned in a piped subprocess to read/write both images and videos.

Code compilation

Compiling using the Microsoft Visual Studio IDE

Open the distrib.sln file and build the solution (typically using the “ReleaseMD - x64” build configuration).
Executables are placed in the bin, bin/debug, bin/Win32, or bin/Win32/debug directory, depending on the build configuration (64-bit versus 32-bit, and release versus debug).

Compiling using msbuild

Set the appropriate environment variables and run msbuild, e.g.:

PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%

msbuild -nologo -verbosity:minimal distrib.sln -maxcpucount:4 -p:PlatformToolset=v140 -p:platform=x64 -p:configuration=ReleaseMD

(Some alternatives are to set platform to Win32, or configuration to DebugMD, Release, or Debug; here MD stands for multithreaded DLL.)
Executables are placed in the same target directory as in the IDE.

Compiling using GNU make

The CONFIG environment variable determines
which of the Makefile_defs_* configuration definitions are loaded.

For example, to build using the Microsoft cl compiler (Debug, with 8 parallel processes, placing *.exe into directory bin/win):

make CONFIG=win -j8

To build just the library using the mingw gcc compiler:

make CONFIG=mingw -j libHh

To build the library using the clang compiler and run the unit tests:

make CONFIG=clang -j test

To build the Filtermesh program on a Unix environment (into the directory bin/unix):

make CONFIG=unix -j Filtermesh

To build all program and run all demos using the Cygwin gcc compiler:

make CONFIG=cygwin -j demos

To run unit tests under all configurations:

make CONFIG=all -j test

(Note that additional options such as debug/release, 32-bit/64-bit, and
compiler tool paths/parameters are set in the various Makefile_defs* files.
These need to be adjusted depending on the versions and installation paths of the tools.
For instance, the line “rel ?= 0” in Makefile_defs_win specifies a debug (non-release) build, and “PATH := ” sets the compiler directory.)

Publications and associated programs/demos

Hugues Hoppe, Tony DeRose, Tom Duchamp, John McDonald, Werner Stuetzle.

ACM SIGGRAPH 1992 Proceedings, 71-78.

Signed-distance field estimated from a set of unoriented noisy points.

programs: Recon

demos: create_recon_*.{sh,bat}, view_recon_*.{sh,bat}

Hugues Hoppe, Tony DeRose, Tom Duchamp, John McDonald, Werner Stuetzle.

ACM SIGGRAPH 1993 Proceedings, 19-26.

Traversing the space of triangle meshes to optimize model fidelity and conciseness.

programs: Meshfit

demos: create_recon_*, view_recon_*, create_simplified_using_meshopt, view_simplified_using_meshopt

Hugues Hoppe, Tony DeRose, Tom Duchamp, Michael Halstead, Hubert Jin, John McDonald, Jean Schweitzer, Werner Stuetzle.

ACM SIGGRAPH 1994 Proceedings, 295-302.

Subdivision surfaces with sharp features, and their automatic creation by data fitting.

programs: Subdivfit

demos: create_recon_cactus, view_recon_cactus

Hugues Hoppe.

ACM SIGGRAPH 1996 Proceedings, 99-108.

Efficient, lossless, continuous-resolution representation of surface triangulations.

demos: create_geomorphs, view_geomorphs

Hugues Hoppe.

Computers & Graphics, 22(1), 1998, 27-36.

Progressive mesh data structures compatible with GPU vertex buffers.

programs: FilterPM, G3dOGL

demos: create_pm_club, view_pm_club, determine_approximation_error

Hugues Hoppe.

ACM SIGGRAPH 1997 Proceedings, 189-198.

Lossless multiresolution structure for incremental local refinement/coarsening.

programs: FilterPM, G3dOGL

demos: create_sr_office, view_sr_office

Hugues Hoppe.

IEEE Visualization 1998 Conference, 35-42.

Visually smooth adaptation of mesh refinement using cascaded temporal geomorphs.

programs: StitchPM, G3dOGL

demos: create_terrain_hierarchy, view_terrain_hierarchy, create_sr_terrain, view_sr_terrain, view_gcanyon_*

Jovan Popovic, Hugues Hoppe.

ACM SIGGRAPH 1997 Proceedings, 217-224.

Progressive encoding of both topology and geometry.

programs: G3dOGL

demos: view_psc_drumset


After the code is compiled, the demos can be run as follows.

In Windows, create and view all the results using the batch scripts



In Unix or Windows Cygwin, either run the bash scripts



or alternatively (and faster), invoke make to create all results in parallel and then view them sequentially:

make CONFIG= config -j demos    # config ∈&nbsp{win, mingw, clang, cygwin, mingw32, w32, unix}

Filter programs

All programs recognize the argument --help (or -?) to show their many options.

The programs Filterimage, Filtermesh, Filtervideo,
FilterPM, and Filterframe are all designed to:

  • read media from std::cin (or from files or procedures specified as initial arguments),
  • perform operations specified by arguments, and
  • write media to std::cout (unless -nooutput is specified).

For example, the command

Filterimage demos/data/gaudipark.png -rotate 20 -cropleft 100 -cropright 100 -filter lanczos6 -scaletox 100 -color 0 0 255 255 -boundary border -cropall -20 -setalpha 255 -color 0 0 0 0 -drawrectangle 30% 30% -30% -30% -gdfill -info -to jpg >

  • reads the specified image,
  • rotates it 20 degrees counterclockwise (with the default reflection boundary rule),
  • crops its left and right sides by 100 pixels,
  • scales it uniformly to a horizontal resolution of 100 pixels using a 6×6 Lanczos filter,
  • adds a 20-pixel blue border on all sides,
  • creates an undefined (alpha=0) rectangular region in the image center,
  • fills this region using gradient-domain smoothing,
  • outputs some statistics on pixel colors (to std::cerr), and
  • writes the result to a file under a different encoding.

As another example, the command

FilterPM demos/data/ -info -nfaces 1000 -outmesh |

Filtermesh -info -signeddistcontour 60 -genus |

G3dOGL -key DmDe

  • reads a progressive mesh stream to construct a mesh with 1000 faces,
  • reports statistics on the mesh geometry,
  • remeshes the surface as the zero isocontour of its signed-distance function on a 603 grid,
  • reports the new mesh genus, and
  • shows the result in an interactive viewer using the specified view parameters,
  • simulating keypresses Dm to enable flat shading and De to make mesh edges visible.

The command

FilterPM demos/data/ -nf 500 -outmesh |

Filtermesh -angle 37 -mark -silsubdiv -silsubdiv -mark |

G3dOGL -st demos/data/club.s3d -key DmDeDbJ–

  • reads a 500-face mesh, marks all edges with dihedral angle greater than 37 degrees as sharp,
  • applies two steps of adaptive subdivision near these sharp edges, and
  • shows the result flat-shaded (Dm), with edges (De), without backface culling (Db), spinning (J) somewhat slowly (--).

The command

Filtervideo demos/data/palmtrees_small.mp4 -filter keys -scaleu 1.5 >palmtrees_small.scale1.5.mp4

  • reads the video (entirely into memory),
  • uniformly scales the two spatial dimensions by a factor 1.5 using the Keys bicubic filter, and
  • saves the new video.

The command

Filtervideo demos/data/palmtrees_small.mp4 -info -trimbeg 4 -boundary clamped -trimend -20% -tscale 1.5 -framerate 150% -croprectangle 50% 50% 400 240 -gamma 1.5 -bitrate 10m |

VideoViewer demos/data/palmtrees_small.mp4 - -key =an

  • reads the video (entirely into memory),
  • reports statistics on the color channels,
  • trims off 4 frames at the beginning,
  • adds repeated copies of the last frames (with length 20% of the video),
  • temporally scales the content by a factor of 1.5 and adjusts the framerate accordingly,
  • spatially crops a centered rectangle with width 400 pixels and height 240 pixels,
  • adjusts the color gamma,
  • sets the output bitrate to 10 megabits/sec, and
  • shows the result (- for std::cin) together with the original video in an interactive viewer,
  • with keypress = to scale the window size by 2, a to loop all (two) videos, and n to initially select the next (second) video.

Surface reconstruction


This program reads a list of 3D (x, y, z) points assumed to be sampled near some unknown manifold surface,
and reconstructs an approximating triangle mesh. For example,

Recon <demos/data/distcap.pts -samplingd 0.02 |

Filtermesh -genus -rmcomp 100 -fillholes 30 -triangulate -genus | tee distcap.recon.m |

G3dOGL -st demos/data/distcap.s3d -key DmDe

  • reads the text file of points,
  • reconstructs a triangle mesh assuming a maximum sample spacing (δ+ρ in paper) of 2% of the bounding volume,
  • reports the genus of this initial mesh,
  • removes all connected components with fewer than 100 triangle faces,
  • fills and triangulates any hole bounded by 30 or fewer mesh edges,
  • reports the genus of the modified mesh,
  • saves it to a file, and
  • displays it interactively from a specified viewpoint, with flat-shaded faces (Dm)
    and mesh edges (De).

To show the progression of the Marching Cubes algorithm,

Recon <demos/data/distcap.pts -samplingd 0.02 -what c |

Filtera3d -split 30 | G3dOGL -key DCDb -st demos/data/distcap_backside.s3d -terse

  • selects the ‘c’ (cubes) output stream,
  • forces a frame refresh every 30 polygon primitive, and
  • shows the result without display-list caching (DC) and without backface culling (Db).

To show a similar streaming reconstruction of the surface mesh,

Recon <demos/data/distcap.pts -samplingd 0.02 -what m | Filtermesh -toa3d |

Filtera3d -split 30 | G3dOGL demos/data/distcap.pts -key DCDb -st demos/data/distcap_backside.s3d -terse -input -key _Jo

  • selects the default ‘m’ (mesh) output stream,
  • converts the mesh to a stream of polygons, and
  • shows the points and streamed reconstruction with a slow (_) automatic rotation (J) about the object frame (o).

The same program can also read a list of 2D (y, z) points to reconstruct an approximating curve:

Recon <demos/data/curve1.pts -samplingd 0.06 -grid 30 |

Filtera3d -joinlines | tee curve1.a3d |

G3dOGL demos/data/curve1.pts -input -st demos/data/curve1.s3d


Given an initial mesh and a list of 3D points, this program optimizes both the mesh connectivity and
geometry to improve the fit, i.e. minimizing the squared distances from the points to the surface.
For example,

Meshfit -mfile distcap.recon.m -file demos/data/distcap.pts -crep 1e-5 -reconstruct |

tee distcap.opt.m | G3dOGL -st demos/data/distcap.s3d -key DmDe

  • reads the previously reconstructed mesh and the original list of points,
  • applies an optimized sequence of perturbations to improve both the mesh connectivity and geometry,
  • using a specified tradeoff between mesh conciseness and fidelity (crep=1e-4 yields a coarser mesh),
  • saves the result to a file, and displays it interactively.

The input points can also be sampled from an existing surface, e.g.:

Filtermesh demos/data/blob5.orig.m -randpts 10000 -vertexpts |

Meshfit -mfile demos/data/blob5.orig.m -file - -crep 1e-6 -simplify |

G3dOGL -st demos/data/blob5.s3d -key DmDe

To view the real-time fitting optimization,

Meshfit -mfile distcap.recon.m -file demos/data/distcap.pts -crep 1e-5 -outmesh - -record -reconstruct | G3dOGL -st demos/data/distcap.s3d -key DmDeDC -async -terse

  • writes both the initial mesh and the stream of mesh modifications, and
  • displays the changing mesh asynchronously with display-list caching disabled (DC).


This related program performs a similar optimization of a 1D polyline (either open or closed) to fit a set of 2D points. For example,

Polyfit -pfile curve1.a3d -file demos/data/curve1.pts -crep 3e-4 -spring 1 -reconstruct |

G3dOGL demos/data/curve1.pts -input -st demos/data/curve1.s3d

  • reads the previously reconstructed polyline and the original list of points,
  • optimizes vertex positions and simplifies the number of line segments according to some representation cost, and
  • displays the result together with the original points.


In a subdivision surface representation, a coarse base mesh tagged with sharp edges defines a piecewise smooth surface as the limit of a subdivision process. Such a representation both improves geometric fidelity and leads to a more concise description.

Filtermesh distcap.opt.m -angle 52 -mark |

Subdivfit -mfile - -file demos/data/distcap.pts -crep 1e-5 -csharp .2e-5 -reconstruct >distcap.sub0.m

  • reads the previously optimized mesh and tags all edges with dihedral angle greater than 52 degrees as sharp,
  • loads this tagged mesh and the original list of points,
  • optimizes the mesh connectivity, geometry, and assignment of sharp edges to fit a subdivision surface to the points,
  • with a representation cost of 1e-5 per vertex and .2e-5 per sharp edge, and
  • saves the resulting optimized base mesh to a file. (The overall process takes a few minutes.)

To view the result,

G3dOGL distcap.sub0.m “Subdivfit -mf distcap.sub0.m -nsub 2 -outn | -st demos/data/distcap.s3d -key NDmDe -hwdelay 5 -hwkey N

  • reads the base mesh together with a second mesh obtained by applying two iterations of subdivision,
  • shows the first mesh (N) with flat-shaded faces and edges (DmDe),
  • waits for 5 seconds, and displays the second mesh (N) as a smooth surface without edges.


This program computes measures of differences between two meshes.
It samples a dense set of points from mesh1 and computes the
projections of each point onto the closest point on mesh2.

MeshDistance -mfile distcap.recon.m -mfile distcap.opt.m -bothdir 1 -maxerror 1 -distance

  • MeshDistance loads the earlier results of mesh reconstruction and mesh optimization,
  • computes correspondences from points sampled on each mesh to the other mesh (in both directions), and
  • reports differences in geometric distance, color, and surface normals, using both L2 (rms) and L (max) norms.

Mesh simplification

Given a mesh, MeshSimplify applies a sequence of edge collapse operations to simplify it to a coarse base mesh while trying to best preserve the appearance of the original model. It supports many different simplification criteria, as well as face properties, edges tagged as sharp, and vertex and corner attributes (normals, colors, and texture uv coordinates).

For example,

MeshSimplify demos/data/club.orig.m -prog club.prog -simplify >club.base.m

  • reads the original mesh and randomly samples points over its surface,
  • progressively simplifies it by examining point residual distances, while recording changes to a *.prog file, and
  • writes the resulting base mesh.

The next step is to reverse the sequence of stored edge collapse steps, i.e. forming a sequence of vertex splits:

reverselines club.prog >club.rprog

We construct a concise progressive mesh by encoding the base mesh together with the sequence of vertex splits that exactly recover the original mesh:

Filterprog -fbase club.base.m -fprog club.rprog -pm_encode >

The complete process from the original mesh to the progressive mesh is implemented by the script call

demos/bin/ meshtopm. {sh,bat} demos/data/club.orig.m >

Given a progressive mesh, we can interactively traverse its continuous levels of detail:

G3dOGL -pm_mode -st demos/data/club.s3d -lightambient .4

We can also define geomorphs between discrete levels of detail, e.g.

FilterPM -nfaces 2000 -geom_nfaces 3300 -geom_nfaces 5000 -geom_nfaces 8000 |

G3dOGL -st demos/data/club.s3d -key SPDeN -lightambient .5 -thickboundary 1 -video 101 - |
VideoViewer - -key m

  • creates a geomorph between 2000 and 3300 faces, another between 3300 and 5000 faces, and similarly one more,
  • shows these in a viewer with the level-of-detail slider enabled (S),
  • selects all three geomorph meshes (P), enables mesh edges (De), selects the first mesh (N),
  • records a video of 101 frames while moving the LOD slider, and
  • shows the resulting video with mirror looping enabled (m).

This example displays a progressive mesh after truncating all detail below 300 faces and above 10000 faces:

FilterPM demos/data/ -nf 300 -truncate_prior -nf 10000 -truncate_beyond |

G3dOGL -pm_mode - -st demos/data/standingblob.s3d

As an example of simplifying meshes with appearance attributes,

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页