public void Smooth(IMesh mesh, int limit) { var smoothedMesh = (Mesh)mesh; var mesher = new GenericMesher(config); var predicates = config.Predicates(); // The smoother should respect the mesh segment splitting behavior. this.options.SegmentSplitting = smoothedMesh.behavior.NoBisect; // Take a few smoothing rounds (Lloyd's algorithm). for (int i = 0; i < limit; i++) { Step(smoothedMesh, factory, predicates); // Actually, we only want to rebuild, if the mesh is no longer // Delaunay. Flipping edges could be the right choice instead // of re-triangulating... smoothedMesh = (Mesh)mesher.Triangulate(Rebuild(smoothedMesh), options); factory.Reset(); } smoothedMesh.CopyTo((Mesh)mesh); }
/// <summary> /// Smooth mesh with a maximum given number of rounds of Voronoi /// iteration. /// </summary> /// <param name="mesh">The mesh.</param> /// <param name="limit">The maximum number of iterations. If /// non-positive, no iteration is applied at all.</param> /// <param name="tol">The desired tolerance on the result. At each /// iteration, the maximum movement by any side is considered, both for /// the previous and the current solutions. If their relative difference /// is not greater than the tolerance, the current solution is /// considered good enough already.</param> /// <returns>The number of actual iterations performed. It is 0 if a /// non-positive limit is passed. Otherwise, it is always a value /// between 1 and the limit (inclusive). /// </returns> public int Smooth(IMesh mesh, int limit = 10, double tol = .01) { if (limit <= 0) { return(0); } var smoothedMesh = (Mesh)mesh; var mesher = new GenericMesher(config); var predicates = config.Predicates(); // The smoother should respect the mesh segment splitting behavior. this.options.SegmentSplitting = smoothedMesh.behavior.NoBisect; // The maximum distances moved from any site at the previous and // current iterations. double prevMax = Double.PositiveInfinity, currMax = Step(smoothedMesh, factory, predicates); // Take a few smoothing rounds (Lloyd's algorithm). The stop // criteria are the maximum number of iterations and the convergence // criterion. int i = 1; while (i < limit && Math.Abs(currMax - prevMax) > tol * currMax) { prevMax = currMax; currMax = Step(smoothedMesh, factory, predicates); // Actually, we only want to rebuild, if the mesh is no longer // Delaunay. Flipping edges could be the right choice instead // of re-triangulating... smoothedMesh = (Mesh)mesher.Triangulate(Rebuild(smoothedMesh), options); factory.Reset(); i++; } smoothedMesh.CopyTo((Mesh)mesh); return(i); }