Added rendering of regions (try "Circle with Hole" input generator)
git-svn-id: https://triangle.svn.codeplex.com/svn@71652 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
@@ -6,6 +6,14 @@ namespace MeshRenderer.Core
|
||||
{
|
||||
public class ColorManager
|
||||
{
|
||||
// Change or add as many colors as you like...
|
||||
private static Color[] regionColors = {
|
||||
Color.FromArgb(20, 0, 255, 0),
|
||||
Color.FromArgb(20, 255, 255, 0),
|
||||
Color.FromArgb(20, 255, 0, 0),
|
||||
Color.FromArgb(20, 0, 0, 255)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets a color scheme with black background.
|
||||
/// </summary>
|
||||
@@ -50,6 +58,70 @@ namespace MeshRenderer.Core
|
||||
internal Pen segment;
|
||||
internal Pen voronoiLine;
|
||||
|
||||
internal SolidBrush[] regions;
|
||||
internal Dictionary<int, int> regionMap;
|
||||
|
||||
#region Public methods
|
||||
|
||||
/// <summary>
|
||||
/// Setup a region map.
|
||||
/// </summary>
|
||||
/// <param name="partition">Mesh partition (size = number of triangles in mesh)</param>
|
||||
/// <param name="size">Number of partitions / regions.</param>
|
||||
public void MakeRegionMap(int[] partition, int size)
|
||||
{
|
||||
if (regions == null || regions.Length != size)
|
||||
{
|
||||
int n = regionColors.Length;
|
||||
|
||||
regions = new SolidBrush[size];
|
||||
|
||||
for (int j = 0; j < size; j++)
|
||||
{
|
||||
regions[j] = new SolidBrush(regionColors[j % n]);
|
||||
}
|
||||
}
|
||||
|
||||
if (regionMap == null)
|
||||
{
|
||||
regionMap = new Dictionary<int, int>(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
regionMap.Clear();
|
||||
}
|
||||
|
||||
int k = 0;
|
||||
for (int i = 0; i < partition.Length; i++)
|
||||
{
|
||||
if (!regionMap.ContainsKey(partition[i]))
|
||||
{
|
||||
regionMap.Add(partition[i], k++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the color defined for given region.
|
||||
/// </summary>
|
||||
public Brush GetRegionBrush(int region)
|
||||
{
|
||||
if (regionMap == null)
|
||||
{
|
||||
return triangle;
|
||||
}
|
||||
|
||||
int k;
|
||||
if (regionMap.TryGetValue(region, out k))
|
||||
{
|
||||
return regions[k];
|
||||
}
|
||||
|
||||
return triangle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
|
||||
public Color Background
|
||||
|
||||
@@ -28,9 +28,10 @@ namespace MeshRenderer.Core.GDI
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MeshRenderer" /> class.
|
||||
/// </summary>
|
||||
public MeshRenderer(RenderData data)
|
||||
public MeshRenderer(RenderData data, ColorManager renderColors)
|
||||
{
|
||||
this.data = data;
|
||||
this.renderColors = renderColors;
|
||||
|
||||
int featureCount = data.Points.Length;
|
||||
|
||||
@@ -44,23 +45,36 @@ namespace MeshRenderer.Core.GDI
|
||||
}
|
||||
|
||||
this.ignoreBounds = featureCount < 1000;
|
||||
|
||||
if (data.Triangles != null && data.NumberOfRegions > 0)
|
||||
{
|
||||
renderColors.MakeRegionMap(data.TrianglePartition, data.NumberOfRegions);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the mesh.
|
||||
/// </summary>
|
||||
public void Render(Graphics g, Zoom zoom, ColorManager renderColors)
|
||||
public void Render(Graphics g, Zoom zoom)
|
||||
{
|
||||
Render(g, zoom, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the mesh.
|
||||
/// </summary>
|
||||
public void Render(Graphics g, Zoom zoom, bool fillTriangles)
|
||||
{
|
||||
this.renderColors = renderColors;
|
||||
this.zoom = zoom;
|
||||
|
||||
if (data.MeshEdges != null)
|
||||
if (data.MeshEdges != null && !fillTriangles)
|
||||
{
|
||||
this.RenderEdges(g);
|
||||
}
|
||||
else if (data.Triangles != null)
|
||||
|
||||
if (fillTriangles && data.Triangles != null)
|
||||
{
|
||||
this.RenderTriangles(g);
|
||||
this.RenderTriangles(g, fillTriangles && (data.NumberOfRegions > 0));
|
||||
}
|
||||
|
||||
if (data.Segments != null)
|
||||
@@ -77,9 +91,8 @@ namespace MeshRenderer.Core.GDI
|
||||
/// <summary>
|
||||
/// Renders only the mesh edges (no points or segments).
|
||||
/// </summary>
|
||||
public void RenderMesh(Graphics g, Zoom zoom, ColorManager renderColors)
|
||||
public void RenderMesh(Graphics g, Zoom zoom)
|
||||
{
|
||||
this.renderColors = renderColors;
|
||||
this.zoom = zoom;
|
||||
|
||||
if (data.MeshEdges != null)
|
||||
@@ -88,16 +101,15 @@ namespace MeshRenderer.Core.GDI
|
||||
}
|
||||
else if (data.Triangles != null)
|
||||
{
|
||||
this.RenderTriangles(g);
|
||||
this.RenderTriangles(g, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders only points and segments (no mesh triangles).
|
||||
/// </summary>
|
||||
public void RenderGeometry(Graphics g, Zoom zoom, ColorManager renderColors)
|
||||
public void RenderGeometry(Graphics g, Zoom zoom)
|
||||
{
|
||||
this.renderColors = renderColors;
|
||||
this.zoom = zoom;
|
||||
|
||||
if (data.Segments != null)
|
||||
@@ -142,11 +154,11 @@ namespace MeshRenderer.Core.GDI
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderTriangles(Graphics g)
|
||||
private void RenderTriangles(Graphics g, bool fillTriangles)
|
||||
{
|
||||
int n = data.Triangles.Length / 3;
|
||||
uint k0, k1, k2;
|
||||
PointF p0, p1, p2;
|
||||
PointF[] tri = new PointF[3];
|
||||
float[] pts = data.Points;
|
||||
|
||||
// Draw triangles
|
||||
@@ -161,13 +173,16 @@ namespace MeshRenderer.Core.GDI
|
||||
zoom.ViewportContains(pts[k1], pts[k1 + 1]) ||
|
||||
zoom.ViewportContains(pts[k2], pts[k2 + 1])))
|
||||
{
|
||||
p0 = zoom.WorldToScreen(pts[k0], pts[k0 + 1]);
|
||||
p1 = zoom.WorldToScreen(pts[k1], pts[k1 + 1]);
|
||||
p2 = zoom.WorldToScreen(pts[k2], pts[k2 + 1]);
|
||||
tri[0] = zoom.WorldToScreen(pts[k0], pts[k0 + 1]);
|
||||
tri[1] = zoom.WorldToScreen(pts[k1], pts[k1 + 1]);
|
||||
tri[2] = zoom.WorldToScreen(pts[k2], pts[k2 + 1]);
|
||||
|
||||
g.DrawLine(renderColors.Line, p0, p1);
|
||||
g.DrawLine(renderColors.Line, p1, p2);
|
||||
g.DrawLine(renderColors.Line, p2, p0);
|
||||
g.DrawPolygon(renderColors.Line, tri);
|
||||
|
||||
if (fillTriangles)
|
||||
{
|
||||
g.FillPolygon(renderColors.GetRegionBrush(data.TrianglePartition[i]), tri);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace MeshRenderer.Core.GDI
|
||||
|
||||
bool initialized = false;
|
||||
bool showVoronoi = false;
|
||||
bool showRegions = true;
|
||||
|
||||
string coordinate = String.Empty;
|
||||
|
||||
@@ -71,6 +72,32 @@ namespace MeshRenderer.Core.GDI
|
||||
};
|
||||
}
|
||||
|
||||
public bool ShowVoronoi
|
||||
{
|
||||
get { return showVoronoi; }
|
||||
set
|
||||
{
|
||||
if (showVoronoi != value)
|
||||
{
|
||||
this.Render();
|
||||
}
|
||||
showVoronoi = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowRegions
|
||||
{
|
||||
get { return showRegions; }
|
||||
set
|
||||
{
|
||||
if (showRegions != value)
|
||||
{
|
||||
this.Render();
|
||||
}
|
||||
showRegions = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the graphics buffer (should be called in the forms load event).
|
||||
/// </summary>
|
||||
@@ -91,7 +118,7 @@ namespace MeshRenderer.Core.GDI
|
||||
{
|
||||
this.data = data;
|
||||
|
||||
meshRenderer = new MeshRenderer(data);
|
||||
meshRenderer = new MeshRenderer(data, renderColors);
|
||||
|
||||
this.showVoronoi = data.VoronoiPoints != null;
|
||||
|
||||
@@ -181,13 +208,13 @@ namespace MeshRenderer.Core.GDI
|
||||
|
||||
if (voronoiRenderer != null && this.showVoronoi)
|
||||
{
|
||||
meshRenderer.RenderMesh(g, zoom, renderColors);
|
||||
meshRenderer.RenderMesh(g, zoom);
|
||||
voronoiRenderer.Render(g, zoom, renderColors);
|
||||
meshRenderer.RenderGeometry(g, zoom, renderColors);
|
||||
meshRenderer.RenderGeometry(g, zoom);
|
||||
}
|
||||
else if (meshRenderer != null)
|
||||
{
|
||||
meshRenderer.Render(g, zoom, renderColors);
|
||||
meshRenderer.Render(g, zoom, showRegions);
|
||||
}
|
||||
|
||||
this.Invalidate();
|
||||
|
||||
@@ -13,6 +13,9 @@ namespace MeshRenderer.Core
|
||||
/// </summary>
|
||||
public interface IMeshRenderer
|
||||
{
|
||||
bool ShowVoronoi { get; set; }
|
||||
bool ShowRegions { get; set; }
|
||||
|
||||
void Zoom(float x, float y, int delta);
|
||||
void HandleResize();
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
namespace MeshRenderer.Core
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TriangleNet;
|
||||
using TriangleNet.Geometry;
|
||||
using TriangleNet.Tools;
|
||||
@@ -23,7 +22,9 @@ namespace MeshRenderer.Core
|
||||
public uint[] MeshEdges;
|
||||
public float[] VoronoiPoints;
|
||||
public uint[] VoronoiEdges;
|
||||
public int[] TrianglePartition;
|
||||
|
||||
public int NumberOfRegions;
|
||||
public int NumberOfInputPoints;
|
||||
public BoundingBox Bounds;
|
||||
|
||||
@@ -42,6 +43,7 @@ namespace MeshRenderer.Core
|
||||
int n = data.Count;
|
||||
int i = 0;
|
||||
|
||||
this.NumberOfRegions = data.Regions.Count;
|
||||
this.NumberOfInputPoints = n;
|
||||
|
||||
// Copy points
|
||||
@@ -124,6 +126,14 @@ namespace MeshRenderer.Core
|
||||
}
|
||||
this.MeshEdges = edges.ToArray();
|
||||
|
||||
|
||||
if (this.NumberOfRegions > 0)
|
||||
{
|
||||
this.TrianglePartition = new int[mesh.Triangles.Count];
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
// Copy Triangles
|
||||
var triangles = new List<uint>(3 * mesh.Triangles.Count);
|
||||
foreach (var tri in mesh.Triangles)
|
||||
@@ -131,6 +141,11 @@ namespace MeshRenderer.Core
|
||||
triangles.Add((uint)tri.P0);
|
||||
triangles.Add((uint)tri.P1);
|
||||
triangles.Add((uint)tri.P2);
|
||||
|
||||
if (this.NumberOfRegions > 0)
|
||||
{
|
||||
this.TrianglePartition[i++] = tri.Region;
|
||||
}
|
||||
}
|
||||
this.Triangles = triangles.ToArray();
|
||||
|
||||
|
||||
@@ -31,6 +31,18 @@ namespace MeshRenderer.Core
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowVoronoi
|
||||
{
|
||||
get { return renderer.ShowVoronoi; }
|
||||
set { renderer.ShowVoronoi = value; }
|
||||
}
|
||||
|
||||
public bool ShowRegions
|
||||
{
|
||||
get { return renderer.ShowRegions; }
|
||||
set { renderer.ShowRegions = value; }
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
renderer.Initialize();
|
||||
|
||||
@@ -84,8 +84,8 @@ namespace MeshExplorer.IO
|
||||
|
||||
g.SmoothingMode = SmoothingMode.HighQuality;
|
||||
|
||||
MeshRenderer meshRenderer = new MeshRenderer(data);
|
||||
meshRenderer.Render(g, zoom, colors);
|
||||
MeshRenderer meshRenderer = new MeshRenderer(data, colors);
|
||||
meshRenderer.Render(g, zoom);
|
||||
|
||||
g.Dispose();
|
||||
}
|
||||
|
||||
@@ -95,6 +95,11 @@ namespace TriangleNet.Smoothing
|
||||
geometry.AddHole(hole.x, hole.y);
|
||||
}
|
||||
|
||||
foreach (var region in mesh.regions)
|
||||
{
|
||||
geometry.AddRegion(region.point.x, region.point.y, region.id);
|
||||
}
|
||||
|
||||
return geometry;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user