diff --git a/src/Triangle.Rendering/GDI/ImageRenderer.cs b/src/Triangle.Rendering/GDI/ImageRenderer.cs
index a30d65e..9045fbd 100644
--- a/src/Triangle.Rendering/GDI/ImageRenderer.cs
+++ b/src/Triangle.Rendering/GDI/ImageRenderer.cs
@@ -25,11 +25,44 @@ namespace TriangleNet.Rendering.GDI
public bool EnableRegions { get; set; }
public bool EnablePoints { get; set; }
-
+
///
- /// Export the mesh to PNG format.
+ /// Exports a polygon to PNG format.
///
- /// The current mesh.
+ /// The polygon.
+ /// The desired width (pixel) of the image.
+ /// The PNG filename.
+ /// Enable rendering of regions.
+ /// Enable rendering of points.
+ public static void Save(Geometry.IPolygon poly, string file = null, int width = 800,
+ bool points = true)
+ {
+ // Check file name
+ if (string.IsNullOrWhiteSpace(file))
+ {
+ file = string.Format("poly-{0}.png", DateTime.Now.ToString("yyyy-M-d-hh-mm-ss"));
+ }
+
+ // Ensure .png extension.
+ if (file.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
+ {
+ Path.ChangeExtension(file, ".png");
+ }
+
+ var renderer = new ImageRenderer();
+
+ renderer.EnableRegions = false;
+ renderer.EnablePoints = points;
+
+ var bitmap = renderer.Render(poly, width);
+
+ bitmap.Save(file, ImageFormat.Png);
+ }
+
+ ///
+ /// Exports a mesh to PNG format.
+ ///
+ /// The mesh.
/// The desired width (pixel) of the image.
/// The PNG filename.
/// Enable rendering of regions.
@@ -59,6 +92,58 @@ namespace TriangleNet.Rendering.GDI
bitmap.Save(file, ImageFormat.Png);
}
+ ///
+ /// Renders the polygon to a bitmap.
+ ///
+ /// The polygon.
+ /// The desired width (pixel) of the image.
+ /// The bitmap.
+ ///
+ /// The width has to be at least 2 * sqrt(n), n the number of vertices.
+ /// Otherwise, an empty bitmap
+ ///
+ public Bitmap Render(Geometry.IPolygon poly, int width = 800)
+ {
+ Bitmap bitmap;
+
+ // Check if the specified width is reasonable
+ if (width < 2 * Math.Sqrt(poly.Points.Count))
+ {
+ return new Bitmap(1, 1);
+ }
+
+ var bounds = poly.Bounds();
+
+ // World margin on each side
+ float margin = (float)bounds.Height * 0.05f;
+ float scale = width / ((float)bounds.Width + 2 * margin);
+
+ var target = new Rectangle(0, 0, width, (int)((bounds.Height + 2 * margin) * scale));
+
+ bitmap = new Bitmap(width, target.Height, PixelFormat.Format32bppPArgb);
+
+ using (var g = Graphics.FromImage(bitmap))
+ {
+ g.Clear(colors.Background);
+ g.SmoothingMode = SmoothingMode.HighQuality;
+
+ var context = new RenderContext(new Projection(target), colors);
+ context.Add(poly);
+
+ if (!EnablePoints)
+ {
+ context.Enable(3, false);
+ }
+
+ var renderer = new LayerRenderer();
+ renderer.Context = context;
+ renderer.RenderTarget = g;
+ renderer.Render();
+ }
+
+ return bitmap;
+ }
+
///
/// Renders the mesh to a bitmap.
///
@@ -116,6 +201,54 @@ namespace TriangleNet.Rendering.GDI
return bitmap;
}
+ public Bitmap Render(IMesh mesh, Topology.DCEL.DcelMesh dcel, int width = 800)
+ {
+ Bitmap bitmap;
+
+ // Check if the specified width is reasonable
+ if (width < 2 * Math.Sqrt(mesh.Vertices.Count))
+ {
+ return new Bitmap(1, 1);
+ }
+
+ var bounds = mesh.Bounds;
+
+ // World margin on each side
+ float margin = (float)bounds.Height * 0.05f;
+ float scale = width / ((float)bounds.Width + 2 * margin);
+
+ var target = new Rectangle(0, 0, width, (int)((bounds.Height + 2 * margin) * scale));
+
+ bitmap = new Bitmap(width, target.Height, PixelFormat.Format32bppPArgb);
+
+ using (var g = Graphics.FromImage(bitmap))
+ {
+ g.Clear(colors.Background);
+ g.SmoothingMode = SmoothingMode.HighQuality;
+
+ var context = new RenderContext(new Projection(target), colors);
+ context.Add(mesh, true);
+ context.Add(dcel.Vertices.ToArray(), dcel.Edges, false);
+
+ if (EnableRegions)
+ {
+ context.Add(GetRegions(mesh));
+ }
+
+ if (!EnablePoints)
+ {
+ context.Enable(3, false);
+ }
+
+ var renderer = new LayerRenderer();
+ renderer.Context = context;
+ renderer.RenderTarget = g;
+ renderer.Render();
+ }
+
+ return bitmap;
+ }
+
private int[] GetRegions(IMesh mesh)
{
mesh.Renumber();
diff --git a/src/Triangle.Rendering/IRenderContext.cs b/src/Triangle.Rendering/IRenderContext.cs
index 7d0e8ee..46f1036 100644
--- a/src/Triangle.Rendering/IRenderContext.cs
+++ b/src/Triangle.Rendering/IRenderContext.cs
@@ -28,5 +28,7 @@ namespace TriangleNet.Rendering
void Add(int[] partition);
void Enable(int layer, bool enabled);
+
+ void Clear();
}
}
diff --git a/src/Triangle.Rendering/IRenderLayer.cs b/src/Triangle.Rendering/IRenderLayer.cs
index 8a11104..a1785ad 100644
--- a/src/Triangle.Rendering/IRenderLayer.cs
+++ b/src/Triangle.Rendering/IRenderLayer.cs
@@ -13,7 +13,6 @@ namespace TriangleNet.Rendering
{
int Count { get; }
- // Points can be set, because layers may share vertices.
IBuffer Points { get; }
IBuffer Indices { get; }
diff --git a/src/Triangle.Rendering/RenderLayer.cs b/src/Triangle.Rendering/RenderLayer.cs
index b6a66b7..1042c9a 100644
--- a/src/Triangle.Rendering/RenderLayer.cs
+++ b/src/Triangle.Rendering/RenderLayer.cs
@@ -32,7 +32,6 @@ namespace TriangleNet.Rendering
public IBuffer Points
{
get { return points; }
- set { points = value; }
}
public IBuffer Indices
diff --git a/src/Triangle.Rendering/RenderManager.cs b/src/Triangle.Rendering/RenderManager.cs
index a5d1044..382db90 100644
--- a/src/Triangle.Rendering/RenderManager.cs
+++ b/src/Triangle.Rendering/RenderManager.cs
@@ -77,6 +77,12 @@ namespace TriangleNet.Rendering
control.HandleResize();
}
+ public void Clear()
+ {
+ context.Clear();
+ control.Refresh();
+ }
+
public void Enable(int layer, bool enabled)
{
context.Enable(layer, enabled);