Friday, 26 June 2015

A Simple C++ Class for 3D Mesh Decimation

Some time ago I wrote a simple C++ class to simplify a 3D mesh. It is based on Michael Garland's article "Surface Simplification Using Quadric Error Metrics"

The code is available under a BSD license.

A win64 executable is also available for quick testing.

The code produces good quality results. However, it is relatively slow!

MeshSimplification fileNameIn.obj targetNTrianglesDecimatedMesh targetNVerticesDecimatedMesh maxDecimationError fileNameOut.obj

For instance, to generate a decimated mesh with 1000 triangles use the following command line:
MeshSimplification input.obj 1000 0 1.0 decimated.obj

To generate a decimated mesh with 1000 vertices:
MeshSimplification input.obj 0 1000 1.0 decimated.obj

To generate a decimated mesh with an error of 1%:
MeshSimplification input.obj 0 0 0.01 decimated.obj

To use the mesh decimation class in your code, proceed as follows:

// input mesh    
Vec3<Float> * points; 
Vec3<int> * triangles;

// Fill points and triangles with input mesh
// ...

// decimate mesh
MeshDecimator myMDecimator;
myMDecimator.Initialize(nPoints, nTriangles, points, triangles);
myMDecimator.Decimate(targetNVerticesDecimatedMesh, targetNTrianglesDecimatedMesh, maxDecimationError);

// allocate memory for decimated mesh
size_t nVerticesDecimatedMesh = myMDecimator.GetNVertices();
size_t nTrianglesDecimatedMesh = myMDecimator.GetNVertices();
Vec3<Float> * decimatedMeshPoints = new Vec3<Float>[nVerticesDecimatedMesh];
Vec3<int> * decimatedMeshTriangles = new Vec3<int>[nTrianglesDecimatedMesh];

// retrieve decimated mesh
myMDecimator.GetMeshData(decimatedMeshPoints, decimatedMeshTriangles);

1 comment:

  1. Hello, nice piece of work: and i'm using your method to implement progressive LOD (original meshes polycount : v:500-7000 f:500-5000, i got interesting results but for some reasons there are many cases where the decimate function is not able to reach target parameters and it is also occuring mainly on the biggest meshes of the scene (e.g buildings for instance) tried also to toy with maxDecimationError but wasn't a big help.. Do you have any idea how to force the decimate function to reach the vert or Triangles target amount?