Delaunay Mesh Generator – Example6

The Delaunay Mesh Generator of Fade creates quality meshes in a polygonal area. The triangles in these meshes meet the specified quality criteria like minimum interior angle or maximum edge length. The present article covers the straightforward refine() method. If you need detailed control over the mesh generation process read also Advanced Mesh Generator.

Preparing the initial situation

The code below creates two polygons (ConstraintGraph2 objects). Then it creates a zone between them by growing the zone’s area from a seed point. There is nothing new in this code snippet if you have worked through the previous examples. The images below show the two polygons and the original triangular mesh between.

	Fade_2D dt;
	vector<Point2> vPoints;
	vPoints.push_back(Point2(40,1));
	vPoints.push_back(Point2(60,1));
	vPoints.push_back(Point2(70,70));
	vPoints.push_back(Point2(30,70));
	vPoints.push_back(Point2(0,0));
	vPoints.push_back(Point2(100,0));
	vPoints.push_back(Point2(100,100));
	vPoints.push_back(Point2(0,100));
	dt.insert(vPoints);

	// 2) Create two ConstraintGraph2 objects from the
        //    points 0,1,2,3 and 4,5,6,7
	std::vector<Segment2> vSegments1;
	std::vector<Segment2> vSegments2;
	for(size_t i=0;i<4;++i)
	{
		Point2& p0(vPoints[i]);
		Point2& p1(vPoints[(i+1)%4]);
		vSegments1.push_back(Segment2(p0,p1));

		Point2& p0a(vPoints[4+i]);
		Point2& p1a(vPoints[4+(i+1)%4]);
		vSegments2.push_back(Segment2(p0a,p1a));
	}
	ConstraintGraph2* pCG1(NULL);
	ConstraintGraph2* pCG2(NULL);
	pCG1=dt.createConstraint(vSegments1,CIS_CONSTRAINED_DELAUNAY);
	pCG2=dt.createConstraint(vSegments2,CIS_CONSTRAINED_DELAUNAY);
	dt.applyConstraintsAndZones();

	// 4) Create a Zone2 using ZL_GROW
	Point2 seedPoint(1,1);
	vector<ConstraintGraph2*> vCG;
	vCG.push_back(pCG1);
	vCG.push_back(pCG2);
	Zone2* pZone=dt.createZone(vCG,ZL_GROW,seedPoint);

	// 5) Extract the triangles of pZone
	std::vector<Triangle2*> vTriangles;
	pZone->getTriangles(vTriangles);
	cout<<"pZone size: "<<vTriangles.size()<<endl;
	Visualizer2 vis("example6_originalZone.ps");
	for(std::vector<Triangle2*>::iterator it(vTriangles.begin());
	    it!=vTriangles.end();++it)
	{
		vis.addObject(**it,Color(1,0,0,0.01,true));
	}
	vis.writeFile();
ConstraintGraph2

ConstraintGraph2


Original zone

Original zone


Delaunay Mesh Generation

The area inside the previously defined Zone2 object pZone is refined. The parameters to Fade_2D::refine(..) are:

  • A Zone2* pointer of a (bounded) zone to be remeshed
  • The minimum interior angle of each result triangle, up to 30 deg.
  • The minimum edge length (no further refinement below that length)
  • The maximum edge length (largest edge in the output)
  • A boolean value which defines if constraint edges can be splitted (usually true)

The first line of the code below remeshes the area. The other ones visualize the resulting triangulation.

	Zone2* pBoundedZone(pGrowZone->convertToBoundedZone());
	dt.refine(pBoundedZone,27,0.01,15,true);

	std::vector<Triangle2*> vTriangles2;
	pBoundedZone->getTriangles(vTriangles2);
	cout<<"\nAfter refinement: "<<vTriangles2.size()<<" triangles"<<endl;
	Visualizer2 vis2("example6_refinedZone.ps");
	for(std::vector<Triangle2*>::iterator it(vTriangles2.begin());
	    it!=vTriangles2.end();++it)
	{
		vis2.addObject(**it,Color(1,0,0,0.01,true));
	}
	vis2.writeFile();
Refined zone

Refined zone


You may also be interested in the advanced mesh generator.

Spread the word. Share this post!

3 Comments

  1. Reply Pieter

    I have a global zone with a couple of constraints on interior segments. These segments should NOT be split upon refinement (easily realized by setting the last argument of refine(…) to false). Unfortunately, the bounds of the zone are apparently also seen as constraints, which means that in this setting they won’t be split either. This often results in sliver triangles at the bounds of the zone. Is there a way to avoid this? Thanks!

  2. Reply Bernhard Kornberger

    Hello Pieter,

    I must admit that I have not foreseen this setting, sorry. The next library version will contain a solution for this case. In the meantime you can use a workaround:
    * Use Fade_2D::getConvexHull() to remember the current convex hull
    * Use Fade_2D::computeBoundingBox() to get the bounding box of your current data
    * Enlarge the bounding box by factor 10 and insert its 4 corners.
    * Now refine() the global zone
    * Use the former convex hull to create an inside zone that contains your desired result.

    Hope that helps,
    best regards
    Bernhard

    • Reply Pieter

      Hi Bernhard, thanks for the swift reply! Glad that I could contribute something :). Looking forward to the next version. Best, Pieter

Leave A Reply

Your email address will not be published. Required fields are marked *

*

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close