From 507ef402ce40e3d64bb85a2f6acb210d839e376d Mon Sep 17 00:00:00 2001 From: "SND\\wo80_cp" Date: Fri, 15 Jul 2016 15:07:38 +0000 Subject: [PATCH] Reduce size of exported EPS images. git-svn-id: https://triangle.svn.codeplex.com/svn@79345 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5 --- Triangle.NET/TestApp/IO/EpsImage.cs | 346 ++++++++++-------- .../TestApp/IO/FormattingStreamWriter.cs | 32 ++ Triangle.NET/TestApp/Mesh Explorer.csproj | 1 + 3 files changed, 234 insertions(+), 145 deletions(-) create mode 100644 Triangle.NET/TestApp/IO/FormattingStreamWriter.cs diff --git a/Triangle.NET/TestApp/IO/EpsImage.cs b/Triangle.NET/TestApp/IO/EpsImage.cs index cf2974a..0b2a5e9 100644 --- a/Triangle.NET/TestApp/IO/EpsImage.cs +++ b/Triangle.NET/TestApp/IO/EpsImage.cs @@ -8,12 +8,14 @@ namespace MeshExplorer.IO { using System; + using System.Collections.Generic; using System.IO; using System.Text; using TriangleNet; - using TriangleNet.Topology; using TriangleNet.Geometry; + using IntPoint = System.Drawing.Point; + /// /// Writes a mesh to an EPS file. /// @@ -55,17 +57,17 @@ namespace MeshExplorer.IO UpdateMetrics(mesh.Bounds); - using (StreamWriter eps = new StreamWriter(filename)) + using (var eps = new FormattingStreamWriter(filename)) { WriteHeader(filename, eps); DrawClip(eps); - DrawTriangles(eps, mesh, false); + DrawEdges(eps, mesh); DrawSegments(eps, mesh); - DrawPoints(eps, mesh, false); + DrawPoints(eps, mesh); WriteTrailer(eps); } @@ -79,7 +81,7 @@ namespace MeshExplorer.IO eps.WriteLine("%%Pages: 1"); eps.WriteLine("%%BoundingBox: {0} {1} {2} {3}", x_ps_min, y_ps_min, x_ps_max, y_ps_max); eps.WriteLine("%%Document-Fonts: Times-Roman"); - eps.WriteLine("%%LanguageLevel: 1"); + eps.WriteLine("%%LanguageLevel: 2"); eps.WriteLine("%%EndComments"); eps.WriteLine("%%BeginProlog"); eps.WriteLine("/inch {72 mul} def"); @@ -142,6 +144,123 @@ namespace MeshExplorer.IO eps.WriteLine("clip newpath"); } + private void DrawEdges(StreamWriter eps, Mesh mesh) + { + IntPoint a, b; + + eps.WriteLine("%"); + eps.WriteLine("% Draw the triangles (mesh edges)."); + eps.WriteLine("%"); + + SetStroke(eps, 0.6f, 0.6f, 0.6f, 0.4f); + + eps.WriteLine(@"/L { +2 dict begin +/y2 exch def +/x2 exch def +/y1 exch def +/x1 exch def +gsave +newpath x1 y1 moveto x2 y2 lineto stroke +grestore +end +} def"); + + foreach (var e in EnumerateEdges(mesh)) + { + a = Transform(e.GetVertex(0)); + b = Transform(e.GetVertex(1)); + + eps.WriteLine("{0} {1} {2} {3} L", a.X, a.Y, b.X, b.Y); + } + } + + private void DrawSegments(StreamWriter eps, Mesh mesh) + { + IntPoint a, b; + + eps.WriteLine("%"); + eps.WriteLine("% Draw the segments."); + eps.WriteLine("%"); + + SetStroke(eps, 0.27f, 0.5f, 0.7f, 0.8f); + + foreach (var s in mesh.Segments) + { + a = Transform(s.GetVertex(0)); + b = Transform(s.GetVertex(1)); + + eps.WriteLine("{0} {1} {2} {3} L", a.X, a.Y, b.X, b.Y); + } + } + + private void DrawPoints(StreamWriter eps, Mesh mesh) + { + IntPoint p; + + int n = mesh.Vertices.Count; + + // Size of the points. + int size = (n < 100) ? 3 : ((n < 500) ? 2 : 1); + + eps.WriteLine("%"); + eps.WriteLine("% Draw the vertices."); + eps.WriteLine("%"); + + SetColor(eps, 0.0f, 0.4f, 0.0f); + + eps.WriteLine(@"/P { +2 dict begin +/y exch def +/x exch def +gsave +newpath x y 1 0 360 arc fill +grestore +end +} def"); + + // TODO: EPS point size. + // newpath x y {size} 0 360 arc fill + + foreach (var node in mesh.Vertices) + { + p = Transform(node); + + eps.WriteLine("{0} {1} P", p.X, p.Y); + } + } + + /* + private void DrawPointLabels(StreamWriter eps, Mesh mesh) + { + int n = mesh.Vertices.Count; + + IntPoint p; + + StringBuilder labels = new StringBuilder(); + + foreach (var node in mesh.Vertices) + { + p = Transform(node); + + labels.AppendFormat(" {0} {1} moveto ({2}) show", p.X, p.Y + 5, node.ID); + labels.AppendLine(); + } + + eps.WriteLine("%"); + eps.WriteLine("% Label the nodes."); + eps.WriteLine("%"); + eps.WriteLine("% Set the RGB color to darker blue."); + eps.WriteLine("%"); + eps.WriteLine("0.000 0.250 0.850 setrgbcolor"); + eps.WriteLine("/Times-Roman findfont"); + eps.WriteLine("0.20 inch scalefont"); + eps.WriteLine("setfont"); + eps.WriteLine("%"); + + eps.WriteLine(labels.ToString()); + } + private void DrawTriangles(StreamWriter eps, Mesh mesh, bool label) { eps.WriteLine("%"); @@ -153,170 +272,86 @@ namespace MeshExplorer.IO eps.WriteLine("% Draw the triangles."); eps.WriteLine("%"); - StringBuilder labels = new StringBuilder(); + IntPoint a, b, c; - Vertex v1, v2, v3; - double x1, y1, x2, y2, x3, y3, xa, ya; - int x_ps, y_ps; - - foreach (var tri in mesh.Triangles) + foreach (var t in mesh.Triangles) { + a = Transform(t.GetVertex(0)); + b = Transform(t.GetVertex(1)); + c = Transform(t.GetVertex(2)); + eps.WriteLine("newpath"); - v1 = tri.GetVertex(0); - v2 = tri.GetVertex(1); - v3 = tri.GetVertex(2); - - x1 = v1.X; y1 = v1.Y; - x2 = v2.X; y2 = v2.Y; - x3 = v3.X; y3 = v3.Y; - - x_ps = (int)Math.Floor(((x_max - x1) * x_ps_min + (x1 - x_min) * x_ps_max) / (x_max - x_min)); - y_ps = (int)Math.Floor(((y_max - y1) * y_ps_min + (y1 - y_min) * y_ps_max) / (y_max - y_min)); - eps.WriteLine(" {0} {1} moveto", x_ps, y_ps); - - x_ps = (int)Math.Floor(((x_max - x2) * x_ps_min + (x2 - x_min) * x_ps_max) / (x_max - x_min)); - y_ps = (int)Math.Floor(((y_max - y2) * y_ps_min + (y2 - y_min) * y_ps_max) / (y_max - y_min)); - eps.WriteLine(" {0} {1} lineto", x_ps, y_ps); - - x_ps = (int)Math.Floor(((x_max - x3) * x_ps_min + (x3 - x_min) * x_ps_max) / (x_max - x_min)); - y_ps = (int)Math.Floor(((y_max - y3) * y_ps_min + (y3 - y_min) * y_ps_max) / (y_max - y_min)); - eps.WriteLine(" {0} {1} lineto", x_ps, y_ps); - - x_ps = (int)Math.Floor(((x_max - x1) * x_ps_min + (x1 - x_min) * x_ps_max) / (x_max - x_min)); - y_ps = (int)Math.Floor(((y_max - y1) * y_ps_min + (y1 - y_min) * y_ps_max) / (y_max - y_min)); - eps.WriteLine(" {0} {1} lineto", x_ps, y_ps); - - if (label) - { - xa = (x1 + x2 + x3) / 3.0; - ya = (y1 + y2 + y3) / 3.0; - - x_ps = (int)Math.Floor(((x_max - xa) * x_ps_min + (xa - x_min) * x_ps_max) / (x_max - x_min)); - y_ps = (int)Math.Floor(((y_max - ya) * y_ps_min + (ya - y_min) * y_ps_max) / (y_max - y_min)); - - labels.AppendFormat(" {0} {1} moveto ({2}) show", x_ps, y_ps, tri.ID); - labels.AppendLine(); - } - - eps.WriteLine("stroke"); - } - - // Label the triangles. - if (label) - { - eps.WriteLine("%"); - eps.WriteLine("% Label the triangles."); - eps.WriteLine("%"); - eps.WriteLine("% Set the RGB color to darker red."); - eps.WriteLine("%"); - eps.WriteLine("0.950 0.250 0.150 setrgbcolor"); - eps.WriteLine("/Times-Roman findfont"); - eps.WriteLine("0.20 inch scalefont"); - eps.WriteLine("setfont"); - eps.WriteLine("%"); - - eps.Write(labels.ToString()); - } - } - - private void DrawSegments(StreamWriter eps, Mesh mesh) - { - eps.WriteLine("%"); - eps.WriteLine("% Set the triangle line color and width."); - eps.WriteLine("%"); - eps.WriteLine("0.27 0.5 0.7 setrgbcolor"); - eps.WriteLine("0.75 setlinewidth"); - eps.WriteLine("%"); - eps.WriteLine("% Draw the triangles."); - eps.WriteLine("%"); - - StringBuilder labels = new StringBuilder(); - - double x1, y1, x2, y2; - int x_ps, y_ps; - - foreach (var seg in mesh.Segments) - { - eps.WriteLine("newpath"); - - x1 = seg.GetVertex(0).X; y1 = seg.GetVertex(0).Y; - x2 = seg.GetVertex(1).X; y2 = seg.GetVertex(1).Y; - - x_ps = (int)Math.Floor(((x_max - x1) * x_ps_min + (x1 - x_min) * x_ps_max) / (x_max - x_min)); - y_ps = (int)Math.Floor(((y_max - y1) * y_ps_min + (y1 - y_min) * y_ps_max) / (y_max - y_min)); - eps.WriteLine(" {0} {1} moveto", x_ps, y_ps); - - x_ps = (int)Math.Floor(((x_max - x2) * x_ps_min + (x2 - x_min) * x_ps_max) / (x_max - x_min)); - y_ps = (int)Math.Floor(((y_max - y2) * y_ps_min + (y2 - y_min) * y_ps_max) / (y_max - y_min)); - eps.WriteLine(" {0} {1} lineto", x_ps, y_ps); - + eps.WriteLine(" {0} {1} moveto", a.X, a.Y); + eps.WriteLine(" {0} {1} lineto", b.X, b.Y); + eps.WriteLine(" {0} {1} lineto", c.X, c.Y); + eps.WriteLine(" {0} {1} lineto", a.X, a.Y); eps.WriteLine("stroke"); } } - private void DrawPoints(StreamWriter eps, Mesh mesh, bool label) + private void DrawTriangleLabels(StreamWriter eps, Mesh mesh) { - int n = mesh.Vertices.Count; + var labels = new StringBuilder(); - int circle_size = 1; + IntPoint a, b, c; - if (n < 100) + foreach (var t in mesh.Triangles) { - circle_size = 3; - } - else if (n < 500) - { - circle_size = 2; + a = Transform(t.GetVertex(0)); + b = Transform(t.GetVertex(1)); + c = Transform(t.GetVertex(2)); + + eps.WriteLine("newpath"); + + a = Transform((a.X + b.X + c.X) / 3.0, (a.Y + b.Y + c.Y) / 3.0); + + labels.AppendFormat(" {0} {1} moveto ({2}) show", a.X, a.Y, t.ID); + labels.AppendLine(); + + eps.WriteLine("stroke"); } eps.WriteLine("%"); - eps.WriteLine("% Draw filled dots at the nodes."); + eps.WriteLine("% Label the triangles."); eps.WriteLine("%"); - eps.WriteLine("% Set the RGB color to blue."); + eps.WriteLine("% Set the RGB color to darker red."); eps.WriteLine("%"); - eps.WriteLine("0.0 0.4 0.0 setrgbcolor"); + eps.WriteLine("0.950 0.250 0.150 setrgbcolor"); + eps.WriteLine("/Times-Roman findfont"); + eps.WriteLine("0.20 inch scalefont"); + eps.WriteLine("setfont"); eps.WriteLine("%"); - double x, y; - int x_ps, y_ps; + eps.WriteLine(labels.ToString()); + } + //*/ - StringBuilder labels = new StringBuilder(); + private void SetColor(StreamWriter eps, float r, float g, float b) + { + eps.WriteLine("{0} {1} {2} setrgbcolor", r, g, b); + eps.WriteLine("%"); + } - foreach (var node in mesh.Vertices) - { - x = node.X; - y = node.Y; + private void SetStroke(StreamWriter eps, float r, float g, float b, float width) + { + eps.WriteLine("{0} {1} {2} setrgbcolor", r, g, b); + eps.WriteLine("{0} setlinewidth", width); + eps.WriteLine("%"); + } - x_ps = (int)Math.Floor(((x_max - x) * x_ps_min + (x - x_min) * x_ps_max) / (x_max - x_min)); - y_ps = (int)Math.Floor(((y_max - y) * y_ps_min + (y - y_min) * y_ps_max) / (y_max - y_min)); + private IntPoint Transform(Point p) + { + return Transform(p.X, p.Y); + } - eps.WriteLine(" newpath {0} {1} {2} 0 360 arc closepath fill", x_ps, y_ps, circle_size); - - if (label) - { - labels.AppendFormat(" {0} {1} moveto ({2}) show", x_ps, y_ps + 5, node); - labels.AppendLine(); - } - } - - // Label the nodes. - if (label) - { - eps.WriteLine("%"); - eps.WriteLine("% Label the nodes."); - eps.WriteLine("%"); - eps.WriteLine("% Set the RGB color to darker blue."); - eps.WriteLine("%"); - eps.WriteLine("0.000 0.250 0.850 setrgbcolor"); - eps.WriteLine("/Times-Roman findfont"); - eps.WriteLine("0.20 inch scalefont"); - eps.WriteLine("setfont"); - eps.WriteLine("%"); - - eps.Write(labels.ToString()); - } + private IntPoint Transform(double x, double y) + { + return new IntPoint( + (int)Math.Floor(((x_max - x) * x_ps_min + (x - x_min) * x_ps_max) / (x_max - x_min)), + (int)Math.Floor(((y_max - y) * y_ps_min + (y - y_min) * y_ps_max) / (y_max - y_min)) + ); } private void UpdateMetrics(Rectangle bounds) @@ -363,5 +398,26 @@ namespace MeshExplorer.IO y_scale = x_scale; } } + + public IEnumerable EnumerateEdges(Mesh mesh, bool segments = false) + { + foreach (var t in mesh.Triangles) + { + for (int i = 0; i < 3; i++) + { + int nid = t.GetNeighborID(i); + + if ((t.ID < nid) || (nid < 0)) + { + if (segments || t.GetSegment(i) == null) + { + yield return new Segment( + t.GetVertex((i + 1) % 3), + t.GetVertex((i + 2) % 3)); + } + } + } + } + } } } diff --git a/Triangle.NET/TestApp/IO/FormattingStreamWriter.cs b/Triangle.NET/TestApp/IO/FormattingStreamWriter.cs new file mode 100644 index 0000000..08af983 --- /dev/null +++ b/Triangle.NET/TestApp/IO/FormattingStreamWriter.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; +using System.IO; + +namespace MeshExplorer.IO +{ + // From http://stackoverflow.com/questions/12011789/streamwriter-and-iformatprovider + + public class FormattingStreamWriter : StreamWriter + { + private readonly IFormatProvider formatProvider; + + public FormattingStreamWriter(string path) + : this(path, CultureInfo.InvariantCulture) + { + } + + public FormattingStreamWriter(string path, IFormatProvider formatProvider) + : base(path) + { + this.formatProvider = formatProvider; + } + + public override IFormatProvider FormatProvider + { + get + { + return this.formatProvider; + } + } + } +} diff --git a/Triangle.NET/TestApp/Mesh Explorer.csproj b/Triangle.NET/TestApp/Mesh Explorer.csproj index d8d1ad3..d9b5218 100644 --- a/Triangle.NET/TestApp/Mesh Explorer.csproj +++ b/Triangle.NET/TestApp/Mesh Explorer.csproj @@ -113,6 +113,7 @@ +