The term Delaunay meshing does not mean simply creating a Delaunay mesh on points, but it is about Quality Meshing i.e., creating a Delaunay mesh with triangles that have a very specific quality. This is generally achieved by adding points, that is, by refining an existing triangulation. As always you can find the below source code in the Fade download in the file “examples_2D/ex7_qualityMeshing.cpp“.
The initial zone
The function createSimpleZone(Fade_2D& dt)
creates an initial shape. If you have studied the previous examples, you already know how to create a Zone2
from a polygon. Here is just a quick picture of it.
This Zone2
object will be remeshed in different ways now.

Delaunay Meshing with Default Parameters
The below code snippet sets up an initial zone. Then it creates a MeshGenParams
object which contains parameters that control the meshing process. These parameters have default values which are useful for the average case. We use the defaults and call the refineAdvanced()
method.

void strategy_default() { Fade_2D dt; Zone2* pZone=createSimpleZone(dt); MeshGenParams params(pZone); dt.refineAdvanced(&params); highlightTriangles(dt,pZone,"default.ps"); }
The Parameter growFactor
One of the parameters in the MeshGenParams
class is growFactor
. It is used to limit the area growth of adjacent triangles. More precisely, for two adjacent triangles T0 and T1, where T1 is the larger one, area(T0) / area(T1)<growFactor
. By default the value is DBL_MAX, that is, growth is not limited. In the code snippet below, we set the parameter to 3.0 to achieve smooth growth from small to large triangles.

void strategy_growFactor() { Fade_2D dt; Zone2* pZone=createSimpleZone(dt); MeshGenParams params(pZone); params.growFactor=3.0; dt.refineAdvanced(¶ms); highlightTriangles(dt,pZone,"growFactor.ps"); }
The Parameter maxEdgeLength
Among the properties that can be controlled via MeshGenParams
, the maximum length of the triangle edges is important. Use the maxEdgeLength
parameter to control the length of the edges in the generated mesh. By default maxEdgeLength
is set to DBL_MAX
, i.e. no limit.

void strategy_maxLength() { Fade_2D dt; Zone2* pZone=createSimpleZone(dt); MeshGenParams params(pZone); params.maxEdgeLength=10.0; dt.refineAdvanced(&params); highlightTriangles(dt,pZone,"maxLength.ps"); }
The Parameters gridLength and gridVector
Grid Meshing is a hybrid approach: Large areas are meshed with grid points while edge areas are meshed with classical Delaunay techniques. To enable grid meshing, set the gridLength
parameter to a positive value. This value will be adapted internally to fit the shape as good as possible. By default, the grid is axis-oriented, but you can change the alignment using the gridVector
parameter.


Fade_2D dt; Zone2* pZone=createSimpleZone(dt); MeshGenParams params(pZone); params.gridLength=3.0; params.gridVector=Vector2(1.0,0.0,0.0); // params.gridVector=Vector2(1.0,0.3,0.0); dt.refineAdvanced(¶ms); highlightTriangles(dt,pZone,"gridMeshing.ps");
Callback methods – create a custom parameters class
It is sometimes desirable that your program can control the mesh density locally. To do this, you derive a class from MeshGenParams
and override the getMaxTriangleArea()
or getMaxEdgeLength()
method with your own code. The example code below derives a class CustomParameters
and overrides getMaxTriangleArea()
to force small triangles in the range x<20, y<40.

class CustomParameters:public MeshGenParams { public: CustomParameters(Zone2* pZone):MeshGenParams(pZone) { } double getMaxTriangleArea(Triangle2* pT) { Point2 barycenter(pT->getBarycenter()); if(barycenter.x()<20 && barycenter.y()<40) { // Dense meshing in the lower left corner return 1.0; } else { // No density restriction otherwise return 10.0; } } }; // Uses CustomParameters with a custom getMaxTriangleArea method void strategy_customParameters() { Fade_2D dt; Zone2* pZone=createSimpleZone(dt); CustomParameters params(pZone); dt.refineAdvanced(¶ms); pZone->show("customParameters.ps",true,true); }
Height guide triangulations in 2.5D
We are dealing with a 2D example here, but refining a triangulation would of course also work in 2.5D. By default, the z-value of a new point is then calculated from the triangle that this point is currently refining. But alternatively, you might be in the special situation of having a second triangulation with higher resolution. In this case you would use this second triangulation as a height guide.
void strategy_heightGuide() { Fade_2D dt; Zone2* pZoneSimple=createSimpleZone(dt); // Another triangulation is used as height guide Fade_2D dt_guide; createHeightGuide(dt_guide); MeshGenParams params(pZoneSimple); params.maxTriangleArea=10.0; params.pHeightGuideTriangulation=&dt_guide; dt.refineAdvanced(¶ms); dt.writeWebScene("mesh_with_height"); }