Update SVG code to include region rendering.

This commit is contained in:
wo80
2022-05-14 16:52:52 +02:00
parent 9351a370d4
commit 2f23e33ffa
2 changed files with 69 additions and 31 deletions
+15 -14
View File
@@ -68,7 +68,7 @@ namespace TriangleNet.Rendering
return colors;
}
public void CreateColorDictionary(int length)
public Dictionary<int, Color> CreateColorDictionary(int length)
{
var keys = new int[length];
@@ -77,34 +77,35 @@ namespace TriangleNet.Rendering
keys[i] = i;
}
CreateColorDictionary(keys);
return CreateColorDictionary(keys);
}
public void CreateColorDictionary(IEnumerable<int> keys)
public Dictionary<int, Color> CreateColorDictionary(IEnumerable<int> keys)
{
this.ColorDictionary = new Dictionary<int, Color>();
ColorDictionary = new Dictionary<int, Color>();
int i = 0, n = regionColors.Length;
foreach (var key in keys)
{
this.ColorDictionary.Add(key, regionColors[i]);
ColorDictionary.Add(key, regionColors[i]);
i = (i + 1) % n;
}
return ColorDictionary;
}
// Change or add as many colors as you like...
private static Color[] regionColors = {
Color.Transparent,
Color.FromArgb(200, 0, 255, 0),
Color.FromArgb(200, 255, 0, 0),
Color.FromArgb(200, 0, 0, 255),
Color.FromArgb(200, 0, 255, 255),
Color.FromArgb(200, 255, 255, 0),
Color.FromArgb(200, 255, 0, 255),
Color.FromArgb(200, 127, 0, 255),
Color.FromArgb(200, 0, 127, 255)
Color.FromArgb(127, 0, 255, 0),
Color.FromArgb(127, 255, 0, 0),
Color.FromArgb(127, 0, 0, 255),
Color.FromArgb(127, 0, 255, 255),
Color.FromArgb(127, 255, 255, 0),
Color.FromArgb(127, 255, 0, 255),
Color.FromArgb(127, 127, 0, 255),
Color.FromArgb(127, 0, 127, 255)
};
}
}
+54 -17
View File
@@ -7,9 +7,9 @@
namespace TriangleNet.Rendering.Text
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using TriangleNet;
using TriangleNet.Geometry;
using TriangleNet.Meshing;
using TriangleNet.Meshing.Iterators;
@@ -19,7 +19,7 @@ namespace TriangleNet.Rendering.Text
/// </summary>
public class SvgImage
{
// Iterations to insert a linebreak in SVG path.
// Iterations to insert a line break in SVG path.
private const int LINEBREAK_COUNT = 10;
float scale = 1f;
@@ -35,7 +35,7 @@ namespace TriangleNet.Rendering.Text
public static void Save(IMesh mesh, string file = null, int width = 800,
bool regions = false, bool points = true)
{
new SvgImage().Export(mesh, file, width);
new SvgImage().Export(mesh, file, width, regions, points);
}
/// <summary>
@@ -44,7 +44,10 @@ namespace TriangleNet.Rendering.Text
/// <param name="mesh">The current mesh.</param>
/// <param name="filename">The SVG filename.</param>
/// <param name="width">The desired width of the image.</param>
public void Export(IMesh mesh, string filename, int width)
/// <param name="regions">Enable rendering of regions.</param>
/// <param name="points">Enable rendering of points.</param>
public void Export(IMesh mesh, string filename, int width,
bool regions = false, bool points = true)
{
// Check file name
if (string.IsNullOrWhiteSpace(filename))
@@ -68,10 +71,10 @@ namespace TriangleNet.Rendering.Text
scale = width / ((float)bounds.Width + 2 * margin);
int x_offset = -(int)((bounds.Left - margin) * scale);
int y_offset = (int)((bounds.Top + margin) * scale);
int x_offset = -(int)((bounds.Left - margin) * scale - 0.5);
int y_offset = (int)((bounds.Top + margin) * scale + 0.5);
int height = (int)((bounds.Height + 2 * margin) * scale);
int height = (int)((bounds.Height + 2 * margin) * scale + 0.5);
using (var svg = new FormattingStreamWriter(filename))
{
@@ -81,12 +84,15 @@ namespace TriangleNet.Rendering.Text
svg.WriteLine("<g transform=\"translate({0}, {1}) scale(1,-1)\">", x_offset, y_offset);
DrawTriangles(svg, mesh, false);
DrawTriangles(svg, mesh, regions, false);
//DrawEdges(svg, mesh);
DrawSegments(svg, mesh);
DrawPoints(svg, mesh, false);
if (points)
{
DrawPoints(svg, mesh, false);
}
svg.WriteLine("</g>");
@@ -94,17 +100,22 @@ namespace TriangleNet.Rendering.Text
}
}
private void DrawTriangles(StreamWriter svg, IMesh mesh, bool label)
private void DrawTriangles(StreamWriter svg, IMesh mesh, bool regions, bool label)
{
svg.Write("\t<path d=\"");
var labels = new StringBuilder();
var edges = new StringBuilder();
var filled = new Dictionary<int, StringBuilder>();
Vertex v1, v2, v3;
double x1, y1, x2, y2, x3, y3, xa, ya;
int i = 1;
edges.Append("\t<path d=\"");
var format = svg.FormatProvider;
foreach (var tri in mesh.Triangles)
{
v1 = tri.GetVertex(0);
@@ -118,29 +129,55 @@ namespace TriangleNet.Rendering.Text
x3 = scale * v3.X;
y3 = scale * v3.Y;
svg.Write("M {0:0.#},{1:0.#} L {2:0.#},{3:0.#} {4:0.#},{5:0.#} Z ",
var s = string.Format(format, "M {0:0.#},{1:0.#} L {2:0.#},{3:0.#} {4:0.#},{5:0.#} Z ",
x1, y1, x2, y2, x3, y3);
if (i % LINEBREAK_COUNT == 0)
{
svg.WriteLine();
svg.Write("\t");
s += Environment.NewLine + "\t";
}
edges.Append(s);
i++;
if (regions && tri.Label != 0)
{
if (!filled.TryGetValue(tri.Label, out var sb))
{
sb = new StringBuilder();
filled.Add(tri.Label, sb);
}
sb.Append(s);
}
if (label)
{
xa = (x1 + x2 + x3) / 3.0;
ya = (y1 + y2 + y3) / 3.0;
labels.AppendFormat("<text x=\"{0:0.#}\" y=\"{1:0.#}\">{2}</text>",
labels.AppendFormat(format, "<text x=\"{0:0.#}\" y=\"{1:0.#}\">{2}</text>",
xa, ya, tri.ID);
labels.AppendLine();
}
}
svg.WriteLine("\" style=\"stroke:#c2c2c2; fill:none; stroke-linejoin:bevel;\"/>");
edges.AppendLine("\" style=\"stroke:#c2c2c2; fill:none; stroke-linejoin:bevel;\"/>");
if (regions)
{
var colors = new ColorManager().CreateColorDictionary(filled.Keys);
foreach (var r in filled)
{
var c = colors[r.Key];
svg.Write("\t<path d=\"");
svg.Write(r.Value.ToString());
svg.WriteLine("\" fill=\"rgb({0},{1},{2})\" fill-opacity=\"{3:0.##}\"/>", c.R, c.G, c.B, c.A / 255f);
}
}
svg.Write(edges.ToString());
// Label the triangles.
if (label)