More code reorganization (5)

git-svn-id: https://triangle.svn.codeplex.com/svn@75153 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
SND\wo80_cp
2014-07-15 10:55:19 +00:00
parent e1861581cd
commit 96fb33322b
54 changed files with 408 additions and 251 deletions
+3 -1
View File
@@ -617,7 +617,9 @@ namespace MeshExplorer
this.voronoi = new StandardVoronoi(mesh);
}
renderManager.Set(voronoi.Vertices, voronoi.Edges, false);
// HACK: List<Vertex> -> ICollection<Point> ? Nope, no way.
// Vertex[] -> ICollection<Point> ? Well, ok.
renderManager.Set(voronoi.Vertices.ToArray(), voronoi.Edges, false);
}
private void ShowLog()
+1 -1
View File
@@ -11,7 +11,7 @@ namespace MeshExplorer.IO
using System.IO;
using System.Text;
using TriangleNet;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
+1 -1
View File
@@ -12,7 +12,7 @@ namespace MeshExplorer.IO.Formats
using System.IO;
using System.Text;
using TriangleNet;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
using TriangleNet.IO;
using TriangleNet.Meshing;
@@ -1,7 +1,7 @@
namespace MeshExplorer.Topology
{
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
public class OrientedTriangle
@@ -22,7 +22,7 @@ namespace TriangleNet.Rendering
void Add(IPolygon data);
void Add(IMesh data, bool reset);
void Add(Point[] points, IEnumerable<IEdge> edges, bool reset);
void Add(ICollection<Point> points, IEnumerable<IEdge> edges, bool reset);
void Add(float[] values);
void Add(int[] partition);
@@ -26,7 +26,7 @@ namespace TriangleNet.Rendering
BoundingBox SetPoints(IBuffer<float> buffer);
BoundingBox SetPoints(IPolygon poly);
BoundingBox SetPoints(IMesh mesh);
BoundingBox SetPoints(Point[] points);
BoundingBox SetPoints(ICollection<Point> points);
void SetPolygon(IPolygon poly);
void SetPolygon(IMesh mesh);
void SetMesh(IMesh mesh, bool elements);
@@ -117,7 +117,7 @@ namespace TriangleNet.Rendering
RenderLayers[3].IsActive = true;
}
public void Add(Point[] points, IEnumerable<IEdge> edges, bool reset)
public void Add(ICollection<Point> points, IEnumerable<IEdge> edges, bool reset)
{
RenderLayers[4].SetPoints(points);
RenderLayers[4].SetMesh(edges);
@@ -108,7 +108,7 @@ namespace TriangleNet.Rendering
return bounds;
}
public BoundingBox SetPoints(Point[] vertices)
public BoundingBox SetPoints(ICollection<Point> vertices)
{
BoundingBox bounds = new BoundingBox();
@@ -117,7 +117,7 @@ namespace TriangleNet.Rendering
/// <summary>
/// Set data for Voronoi layer.
/// </summary>
public void Set(Point[] points, IEnumerable<IEdge> edges, bool reset, bool refresh = true)
public void Set(ICollection<Point> points, IEnumerable<IEdge> edges, bool reset, bool refresh = true)
{
context.Add(points, edges, reset);
@@ -2,7 +2,7 @@
namespace TriangleNet.Rendering.Util
{
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
using TriangleNet.Rendering.Buffer;
@@ -36,9 +36,9 @@ namespace TriangleNet.Rendering.Util
return buffer as IBuffer<float>;
}
public static IBuffer<float> CreateVertexBuffer(Point[] points, ref BoundingBox bounds)
public static IBuffer<float> CreateVertexBuffer(ICollection<Point> points, ref BoundingBox bounds)
{
var buffer = new VertexBuffer(2 * points.Length);
var buffer = new VertexBuffer(2 * points.Count);
bounds.Reset();
+1 -1
View File
@@ -10,7 +10,7 @@ namespace TriangleNet.Geometry
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Data;
using TriangleNet.Topology;
/// <summary>
/// Represents a straight line segment in 2D space.
@@ -0,0 +1,145 @@
namespace TriangleNet.Geometry
{
using TriangleNet.Meshing;
public static class ExtensionMethods
{
#region IPolygon extensions
/// <summary>
/// Triangulates a polygon.
/// </summary>
public static IMesh Triangulate(this IPolygon polygon)
{
var mesher = new GenericMesher();
return mesher.Triangulate(polygon, null, null);
}
/// <summary>
/// Triangulates a polygon, applying constraint options.
/// </summary>
/// <param name="options">Constraint options.</param>
public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options)
{
var mesher = new GenericMesher();
return mesher.Triangulate(polygon, options, null);
}
/// <summary>
/// Triangulates a polygon, applying quality options.
/// </summary>
/// <param name="quality">Quality options.</param>
public static IMesh Triangulate(this IPolygon polygon, QualityOptions quality)
{
var mesher = new GenericMesher();
return mesher.Triangulate(polygon, null, quality);
}
/// <summary>
/// Triangulates a polygon, applying quality and constraint options.
/// </summary>
/// <param name="options">Constraint options.</param>
/// <param name="quality">Quality options.</param>
public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality)
{
var mesher = new GenericMesher();
var mesh = (Mesh)mesher.Triangulate(polygon.Points);
mesh.ApplyConstraints(polygon, options, quality);
return mesh;
}
/// <summary>
/// Triangulates a polygon, applying quality and constraint options.
/// </summary>
/// <param name="options">Constraint options.</param>
/// <param name="quality">Quality options.</param>
/// <param name="triangulator">The triangulation algorithm.</param>
public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality,
ITriangulator triangulator)
{
var mesher = new GenericMesher(triangulator);
var mesh = (Mesh)mesher.Triangulate(polygon.Points);
mesh.ApplyConstraints(polygon, options, quality);
return mesh;
}
#endregion
#region Rectangle extensions
/// <summary>
/// Find intersection of a rectangle with a segment.
/// </summary>
/// <param name="rect">The rectangle.</param>
/// <param name="p0">Segment start point.</param>
/// <param name="p1">Segment end point.</param>
/// <param name="c0">Intersection associated to start point.</param>
/// <param name="c1">Intersection associated to end point.</param>
/// <returns>Returns true, if segment intersects or lies completely in rectangle, otherwise false.</returns>
/// <remarks>
/// Liang-Barsky function by Daniel White, http://www.skytopia.com/project/articles/compsci/clipping.html
/// </remarks>
public static bool Intersect(this Rectangle rect, Point p0, Point p1, ref Point c0, ref Point c1)
{
// Define the x/y clipping values for the border.
double xmin = rect.Left;
double xmax = rect.Right;
double ymin = rect.Bottom;
double ymax = rect.Top;
// Define the start and end points of the line.
double x0 = p0.X;
double y0 = p0.Y;
double x1 = p1.X;
double y1 = p1.Y;
double t0 = 0.0;
double t1 = 1.0;
double dx = x1 - x0;
double dy = y1 - y0;
double p = 0.0, q = 0.0, r;
for (int edge = 0; edge < 4; edge++)
{
// Traverse through left, right, bottom, top edges.
if (edge == 0) { p = -dx; q = -(xmin - x0); }
if (edge == 1) { p = dx; q = (xmax - x0); }
if (edge == 2) { p = -dy; q = -(ymin - y0); }
if (edge == 3) { p = dy; q = (ymax - y0); }
r = q / p;
if (p == 0 && q < 0) return false; // Don't draw line at all. (parallel line outside)
if (p < 0)
{
if (r > t1) return false; // Don't draw line at all.
else if (r > t0) t0 = r; // Line is clipped!
}
else if (p > 0)
{
if (r < t0) return false; // Don't draw line at all.
else if (r < t1) t1 = r; // Line is clipped!
}
}
c0.x = x0 + t0 * dx;
c0.y = y0 + t0 * dy;
c1.x = x0 + t1 * dx;
c1.y = y0 + t1 * dy;
return true; // (clipped) line is drawn
}
#endregion
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
namespace TriangleNet.Geometry
{
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
/// <summary>
/// Polygon interface.
@@ -1,74 +0,0 @@
namespace TriangleNet.Geometry
{
using TriangleNet.Meshing;
public static class IPolygonExtensions
{
/// <summary>
/// Triangulates a polygon.
/// </summary>
public static IMesh Triangulate(this IPolygon polygon)
{
var mesher = new GenericMesher();
return mesher.Triangulate(polygon, null, null);
}
/// <summary>
/// Triangulates a polygon, applying constraint options.
/// </summary>
/// <param name="options">Constraint options.</param>
public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options)
{
var mesher = new GenericMesher();
return mesher.Triangulate(polygon, options, null);
}
/// <summary>
/// Triangulates a polygon, applying quality options.
/// </summary>
/// <param name="quality">Quality options.</param>
public static IMesh Triangulate(this IPolygon polygon, QualityOptions quality)
{
var mesher = new GenericMesher();
return mesher.Triangulate(polygon, null, quality);
}
/// <summary>
/// Triangulates a polygon, applying quality and constraint options.
/// </summary>
/// <param name="options">Constraint options.</param>
/// <param name="quality">Quality options.</param>
public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality)
{
var mesher = new GenericMesher();
var mesh = (Mesh)mesher.Triangulate(polygon.Points);
mesh.ApplyConstraints(polygon, options, quality);
return mesh;
}
/// <summary>
/// Triangulates a polygon, applying quality and constraint options.
/// </summary>
/// <param name="options">Constraint options.</param>
/// <param name="quality">Quality options.</param>
/// <param name="triangulator">The triangulation algorithm.</param>
public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality,
ITriangulator triangulator)
{
var mesher = new GenericMesher(triangulator);
var mesh = (Mesh)mesher.Triangulate(polygon.Points);
mesh.ApplyConstraints(polygon, options, quality);
return mesh;
}
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
namespace TriangleNet.Geometry
{
using TriangleNet.Data;
using TriangleNet.Topology;
/// <summary>
/// Triangle interface.
+1 -1
View File
@@ -3,7 +3,7 @@ namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
/// <summary>
/// A polygon represented as a planar straight line graph.
+1 -1
View File
@@ -8,7 +8,7 @@
namespace TriangleNet.Geometry
{
using System;
using TriangleNet.Data;
using TriangleNet.Topology;
/// <summary>
/// The vertex data structure.
+1 -1
View File
@@ -11,7 +11,7 @@ namespace TriangleNet.IO
using System.IO;
using System.IO.Compression;
using System.Text;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
+1 -1
View File
@@ -6,7 +6,7 @@
namespace TriangleNet.IO
{
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
+1 -1
View File
@@ -10,7 +10,7 @@ namespace TriangleNet.IO
using System;
using System.IO;
using System.Globalization;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Logging;
using TriangleNet.Geometry;
using System.Collections.Generic;
+1 -1
View File
@@ -10,7 +10,7 @@ namespace TriangleNet.IO
using System;
using System.IO;
using System.Globalization;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
using System.Collections.Generic;
+2 -1
View File
@@ -9,12 +9,13 @@ namespace TriangleNet
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Geometry;
using TriangleNet.Logging;
using TriangleNet.Meshing;
using TriangleNet.Meshing.Data;
using TriangleNet.Meshing.Iterators;
using TriangleNet.Tools;
using TriangleNet.Topology;
/// <summary>
/// Mesh data structure.
+1 -1
View File
@@ -8,7 +8,7 @@
namespace TriangleNet
{
using System;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
public static class MeshValidator
@@ -9,7 +9,7 @@ namespace TriangleNet.Meshing.Algorithm
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
@@ -8,7 +8,7 @@
namespace TriangleNet.Meshing.Algorithm
{
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
@@ -9,7 +9,7 @@ namespace TriangleNet.Meshing.Algorithm
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
using TriangleNet.Tools;
@@ -9,7 +9,7 @@ namespace TriangleNet.Meshing
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
using TriangleNet.Logging;
using TriangleNet.Meshing.Iterators;
+1 -1
View File
@@ -10,7 +10,7 @@ namespace TriangleNet.Meshing
using System;
using System.Collections.Generic;
using System.Linq;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
@@ -5,10 +5,11 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Data
namespace TriangleNet.Meshing.Data
{
using System;
using TriangleNet.Geometry;
using TriangleNet.Topology;
/// <summary>
/// A queue used to store encroached subsegments.
@@ -5,9 +5,10 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Data
namespace TriangleNet.Meshing.Data
{
using TriangleNet.Geometry;
using TriangleNet.Topology;
/// <summary>
/// A (priority) queue for bad triangles.
@@ -5,10 +5,11 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Data
namespace TriangleNet.Meshing.Data
{
using System;
using TriangleNet.Geometry;
using TriangleNet.Topology;
/// <summary>
/// A queue used to store bad triangles.
+1 -1
View File
@@ -2,7 +2,7 @@
namespace TriangleNet.Meshing
{
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
@@ -7,7 +7,7 @@
namespace TriangleNet.Meshing.Iterators
{
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
@@ -9,7 +9,7 @@ namespace TriangleNet.Meshing.Iterators
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
/// <summary>
/// Iterates the region a given triangle belongs to and applies an action
@@ -9,9 +9,10 @@ namespace TriangleNet.Meshing
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Geometry;
using TriangleNet.Logging;
using TriangleNet.Meshing.Data;
using TriangleNet.Topology;
/// <summary>
/// Provides methods for mesh quality enforcement and testing.
@@ -35,7 +35,7 @@ namespace TriangleNet.Meshing
public Func<ITriangle, double, bool> UserTest { get; set; }
/// <summary>
/// Gets or sets a area constraint per triangle.
/// Gets or sets an area constraint per triangle.
/// </summary>
/// <remarks>
/// If this flag is set to true, the <see cref="ITriangle.Area"/> value will
+1 -1
View File
@@ -8,7 +8,7 @@
namespace TriangleNet
{
using System;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
using TriangleNet.Tools;
+1 -1
View File
@@ -8,7 +8,7 @@
namespace TriangleNet
{
using System;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
using TriangleNet.Tools;
+1 -1
View File
@@ -8,7 +8,7 @@
namespace TriangleNet.Tools
{
using System;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
@@ -0,0 +1,119 @@

namespace TriangleNet.Topology.DCEL
{
using System.Collections.Generic;
using TriangleNet.Geometry;
public class DcelMesh
{
protected List<Vertex> vertices;
protected List<HalfEdge> edges;
protected List<Face> faces;
public DcelMesh()
: this(true)
{
}
protected DcelMesh(bool initialize)
{
if (initialize)
{
vertices = new List<Vertex>();
edges = new List<HalfEdge>();
faces = new List<Face>();
}
}
/// <summary>
/// Gets the vertices of the Voronoi diagram.
/// </summary>
public List<Vertex> Vertices
{
get { return vertices; }
}
/// <summary>
/// Gets the list of half-edges specify the Voronoi diagram topology.
/// </summary>
public List<HalfEdge> HalfEdges
{
get { return edges; }
}
/// <summary>
/// Gets the faces of the Voronoi diagram.
/// </summary>
public List<Face> Faces
{
get { return faces; }
}
/// <summary>
/// Gets the collection of edges of the Voronoi diagram.
/// </summary>
public IEnumerable<IEdge> Edges
{
get { return EnumerateEdges(); }
}
/// <summary>
/// Search for half-edge without twin and add a twin. Connect twins to form connected
/// boundary contours.
/// </summary>
/// <remarks>
/// This method assumes that all faces are closed (i.e. no edge.next pointers are null).
/// </remarks>
internal void ResolveBoundaryEdges()
{
// Maps vertices to leaving boundary edge.
var map = new Dictionary<int, HalfEdge>();
// TODO: parallel?
foreach (var edge in this.edges)
{
if (edge.twin == null)
{
var twin = edge.twin = new HalfEdge(edge.next.origin);
twin.twin = edge;
map.Add(twin.origin.id, twin);
}
}
int j = edges.Count;
foreach (var edge in map.Values)
{
edge.id = j++;
edge.next = map[edge.twin.origin.id];
this.edges.Add(edge);
}
}
/// <summary>
/// Enumerates all edges of the DCEL.
/// </summary>
/// <remarks>
/// This method assumes that each half-edge has a twin (i.e. NOT null).
/// </remarks>
protected virtual IEnumerable<IEdge> EnumerateEdges()
{
var edges = new List<IEdge>(this.edges.Count / 2);
foreach (var edge in this.edges)
{
var twin = edge.twin;
// Report edge only once.
if (edge.id < twin.id)
{
edges.Add(new Edge(edge.origin.id, twin.origin.id));
}
}
return edges;
}
}
}
@@ -4,7 +4,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Voronoi.DCEL
namespace TriangleNet.Topology.DCEL
{
using TriangleNet.Geometry;
@@ -13,6 +13,8 @@ namespace TriangleNet.Voronoi.DCEL
/// </summary>
public class Face
{
internal int id;
internal Point generator;
internal HalfEdge edge;
@@ -4,7 +4,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Voronoi.DCEL
namespace TriangleNet.Topology.DCEL
{
public class HalfEdge
{
@@ -4,11 +4,9 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Voronoi.DCEL
namespace TriangleNet.Topology.DCEL
{
using TriangleNet.Geometry;
public class Vertex : Point
public class Vertex : TriangleNet.Geometry.Point
{
internal HalfEdge leaving;
@@ -5,7 +5,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Data
namespace TriangleNet.Topology
{
using System;
using TriangleNet.Geometry;
@@ -5,7 +5,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Data
namespace TriangleNet.Topology
{
using System;
using TriangleNet.Geometry;
@@ -5,7 +5,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Data
namespace TriangleNet.Topology
{
using System;
using TriangleNet.Geometry;
@@ -21,7 +21,7 @@ namespace TriangleNet.Data
// triangle side or subsegment end that isn't attached to a real
// subsegment.
internal static Segment Empty;
internal static readonly Segment Empty;
static Segment()
{
@@ -34,8 +34,6 @@ namespace TriangleNet.Data
// can legally be dereferenced.
Empty.subsegs[0].seg = Empty;
Empty.subsegs[1].seg = Empty;
Triangle.Initialize();
}
#endregion
@@ -5,7 +5,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Data
namespace TriangleNet.Topology
{
using System;
using TriangleNet.Geometry;
@@ -36,18 +36,16 @@ namespace TriangleNet.Data
internal const int EmptyID = -1;
internal static Triangle Empty;
internal static readonly Triangle Empty;
/// <summary>
/// Initializes the dummytri (Triangle.Empty). The method is called by the static Segment
/// constructor (which ensures that dummysub (Segment.Empty) will not be null).
/// Initializes the dummytri (Triangle.Empty).
/// </summary>
internal static void Initialize()
static Triangle()
{
// Set up 'dummytri', the 'triangle' that occupies "outer space."
Empty = new Triangle();
Empty.hash = EmptyID;
Empty.id = EmptyID;
Empty.hash = Empty.id = EmptyID;
// Initialize the three adjoining triangles to be "outer space." These
// will eventually be changed by various bonding operations, but their
@@ -57,6 +55,12 @@ namespace TriangleNet.Data
Empty.neighbors[1].triangle = Empty;
Empty.neighbors[2].triangle = Empty;
if (Segment.Empty == null)
{
// In case the static Segment constructor hasn't been called yet.
Empty.subsegs[0].seg = new Segment();
}
// Initialize the three adjoining subsegments of 'dummytri' to be
// the omnipresent subsegment.
Empty.subsegs[0].seg = Segment.Empty;
+16 -12
View File
@@ -43,7 +43,7 @@
<ItemGroup>
<Compile Include="Geometry\IEdge.cs" />
<Compile Include="Geometry\IPolygon.cs" />
<Compile Include="Geometry\IPolygonExtensions.cs" />
<Compile Include="Geometry\ExtensionMethods.cs" />
<Compile Include="Geometry\Polygon.cs" />
<Compile Include="IO\FileProcessor.cs" />
<Compile Include="IO\IFileFormat.cs" />
@@ -54,15 +54,16 @@
<Compile Include="Meshing\IMesh.cs" />
<Compile Include="Meshing\IQualityMesher.cs" />
<Compile Include="Meshing\ITriangulator.cs" />
<Compile Include="Data\BadTriQueue.cs" />
<Compile Include="Meshing\Data\BadTriQueue.cs" />
<Compile Include="Behavior.cs" />
<Compile Include="Meshing\ConstraintMesher.cs" />
<Compile Include="Data\BadSubseg.cs" />
<Compile Include="Data\BadTriangle.cs" />
<Compile Include="Data\Osub.cs" />
<Compile Include="Data\Otri.cs" />
<Compile Include="Data\Segment.cs" />
<Compile Include="Data\Triangle.cs" />
<Compile Include="Meshing\Data\BadSubseg.cs" />
<Compile Include="Meshing\Data\BadTriangle.cs" />
<Compile Include="Topology\DCEL\DcelMesh.cs" />
<Compile Include="Topology\Osub.cs" />
<Compile Include="Topology\Otri.cs" />
<Compile Include="Topology\Segment.cs" />
<Compile Include="Topology\Triangle.cs" />
<Compile Include="Geometry\Vertex.cs" />
<Compile Include="Meshing\Algorithm\Dwyer.cs" />
<Compile Include="Geometry\Rectangle.cs" />
@@ -109,13 +110,16 @@
<Compile Include="Voronoi\Legacy\VoronoiRegion.cs" />
<Compile Include="TriangleLocator.cs" />
<Compile Include="Voronoi\BoundedVoronoi.cs" />
<Compile Include="Voronoi\DCEL\Face.cs" />
<Compile Include="Voronoi\DCEL\HalfEdge.cs" />
<Compile Include="Voronoi\DCEL\Vertex.cs" />
<Compile Include="Topology\DCEL\Face.cs" />
<Compile Include="Topology\DCEL\HalfEdge.cs" />
<Compile Include="Topology\DCEL\Vertex.cs" />
<Compile Include="Voronoi\StandardVoronoi.cs" />
<Compile Include="Voronoi\VoronoiBase.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Folder Include="Data\" />
<Folder Include="Voronoi\DCEL\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
+1 -1
View File
@@ -7,7 +7,7 @@
namespace TriangleNet
{
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
+39 -38
View File
@@ -6,9 +6,12 @@
namespace TriangleNet.Voronoi
{
using System;
using System.Collections.Generic;
using TriangleNet.Geometry;
using TriangleNet.Topology.DCEL;
using HVertex = TriangleNet.Topology.DCEL.Vertex;
using TVertex = TriangleNet.Geometry.Vertex;
public class BoundedVoronoi : VoronoiBase
{
@@ -19,26 +22,23 @@ namespace TriangleNet.Voronoi
{
// We explicitly told the base constructor to call the Generate method, so
// at this point the basic Voronoi diagram is already created.
offset = base.vertices.Length;
offset = base.vertices.Count;
// Each vertex of the hull will be part of a Voronoi cell.
Array.Resize(ref base.vertices, offset + mesh.hullsize);
base.vertices.Capacity = offset + mesh.hullsize;
// Create bounded Voronoi diagram.
PostProcess();
Array.Resize(ref base.vertices, offset);
ResolveBoundaryEdges();
}
/// <summary>
/// Computes edge intersections with mesh boundary edges.
/// </summary>
private void PostProcess()
{
// Compute edge intersections with mesh boundary edges.
ProcessBoundaryEdges();
}
private void ProcessBoundaryEdges()
{
var infEdges = new List<DCEL.HalfEdge>();
var infEdges = new List<HalfEdge>();
// TODO: save the half-infinite boundary edge in base class
// so we don't have to process the complete list here.
@@ -52,8 +52,8 @@ namespace TriangleNet.Voronoi
foreach (var edge in infEdges)
{
var v1 = (Vertex)edge.face.generator;
var v2 = (Vertex)edge.twin.face.generator;
var v1 = (TVertex)edge.face.generator;
var v2 = (TVertex)edge.twin.face.generator;
double dir = RobustPredicates.CounterClockwise(v1, v2, edge.origin);
@@ -68,7 +68,7 @@ namespace TriangleNet.Voronoi
}
}
private void HandleCase1(DCEL.HalfEdge edge, Vertex v1, Vertex v2)
private void HandleCase1(HalfEdge edge, TVertex v1, TVertex v2)
{
//int mark = GetBoundaryMark(v1);
@@ -81,10 +81,10 @@ namespace TriangleNet.Voronoi
v.y = (v1.y + v2.y) / 2.0;
// Close the cell connected to edge.
var gen = new DCEL.Vertex(v1.x, v1.y);
var gen = new HVertex(v1.x, v1.y);
var h1 = new DCEL.HalfEdge(edge.twin.origin, edge.face);
var h2 = new DCEL.HalfEdge(gen, edge.face);
var h1 = new HalfEdge(edge.twin.origin, edge.face);
var h2 = new HalfEdge(gen, edge.face);
h1.next = h2;
h2.next = edge.face.edge;
@@ -100,49 +100,50 @@ namespace TriangleNet.Voronoi
h1.id = count;
h2.id = count + 1;
base.vertices[offset] = gen;
gen.id = offset++;
base.vertices.Add(gen);
}
private void HandleCase2(DCEL.HalfEdge e1, Vertex v1, Vertex v2)
private void HandleCase2(HalfEdge edge, TVertex v1, TVertex v2)
{
var e2 = e1.twin.next;
var ei = e2.twin.next;
// The vertices of the infinite edge.
var p1 = (Point)e1.origin;
var pi = (Point)e1.twin.origin;
var p1 = (Point)edge.origin;
var p2 = (Point)edge.twin.origin;
// The two edges leaving p1, pointing into the mesh.
var e1 = edge.twin.next;
var e2 = e1.twin.next;
// Find the two intersections with boundary edge.
IntersectSegments(v1, v2, e2.origin, e2.twin.origin, ref pi);
IntersectSegments(v1, v2, ei.origin, ei.twin.origin, ref p1);
IntersectSegments(v1, v2, e1.origin, e1.twin.origin, ref p2);
IntersectSegments(v1, v2, e2.origin, e2.twin.origin, ref p1);
// The infinite edge will now lie on the boundary. Update pointers:
e2.twin.next = e1.twin;
e1.twin.next = ei;
e1.twin.face = ei.face;
e1.twin.next = edge.twin;
edge.twin.next = e2;
edge.twin.face = e2.face;
e2.origin = e1.twin.origin;
e1.origin = edge.twin.origin;
e1.twin.twin = null;
e1.twin = null;
edge.twin.twin = null;
edge.twin = null;
// Close the cell.
var gen = new DCEL.Vertex(v1.x, v1.y);
var he = new DCEL.HalfEdge(gen, e1.face);
var gen = new HVertex(v1.x, v1.y);
var he = new HalfEdge(gen, edge.face);
e1.next = he;
he.next = e1.face.edge;
edge.next = he;
he.next = edge.face.edge;
// Let the face edge point to the edge leaving at generator.
e1.face.edge = he;
edge.face.edge = he;
base.edges.Add(he);
he.id = base.edges.Count;
base.vertices[offset] = gen;
gen.id = offset++;
base.vertices.Add(gen);
}
/*
@@ -8,7 +8,7 @@ namespace TriangleNet.Voronoi.Legacy
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
@@ -18,6 +18,7 @@ namespace TriangleNet.Voronoi.Legacy
/// 2D Centroidal Voronoi Tessellations with Constraints, 2010,
/// Jane Tournois, Pierre Alliez and Olivier Devillers
/// </remarks>
[Obsolete("Use TriangleNet.Voronoi.BoundedVoronoi class instead.")]
public class BoundedVoronoiLegacy : IVoronoi
{
Mesh mesh;
@@ -9,12 +9,13 @@ namespace TriangleNet.Voronoi.Legacy
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
/// The Voronoi Diagram is the dual of a pointset triangulation.
/// </summary>
[Obsolete("Use TriangleNet.Voronoi.StandardVoronoi class instead.")]
public class SimpleVoronoi : IVoronoi
{
Mesh mesh;
@@ -8,7 +8,7 @@ namespace TriangleNet.Voronoi.Legacy
{
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
/// <summary>
+16 -65
View File
@@ -9,53 +9,17 @@ namespace TriangleNet.Voronoi
{
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Topology;
using TriangleNet.Geometry;
using TriangleNet.Voronoi.DCEL;
using TriangleNet.Topology.DCEL;
using Vertex = TriangleNet.Voronoi.DCEL.Vertex;
using Vertex = TriangleNet.Topology.DCEL.Vertex;
/// <summary>
/// The Voronoi diagram is the dual of a pointset triangulation.
/// </summary>
public abstract class VoronoiBase
public abstract class VoronoiBase : DcelMesh
{
protected Vertex[] vertices;
protected List<HalfEdge> edges;
protected Face[] faces;
/// <summary>
/// Gets the vertices of the Voronoi diagram.
/// </summary>
public Vertex[] Vertices
{
get { return vertices; }
}
/// <summary>
/// Gets the list of half-edges specify the Voronoi diagram topology.
/// </summary>
public List<HalfEdge> HalfEdges
{
get { return edges; }
}
/// <summary>
/// Gets the faces of the Voronoi diagram.
/// </summary>
public Face[] Faces
{
get { return faces; }
}
/// <summary>
/// Gets the collection of edges of the Voronoi diagram.
/// </summary>
public IEnumerable<IEdge> Edges
{
get { return EnumerateEdges(); }
}
/// <summary>
/// Initializes a new instance of the <see cref="VoronoiBase" /> class.
/// </summary>
@@ -63,6 +27,7 @@ namespace TriangleNet.Voronoi
/// <param name="generate">If set to true, the constuctor will call the Generate
/// method, which builds the Voronoi diagram.</param>
protected VoronoiBase(Mesh mesh, bool generate)
: base(false)
{
if (generate)
{
@@ -79,13 +44,14 @@ namespace TriangleNet.Voronoi
mesh.Renumber();
mesh.MakeVertexMap();
base.edges = new List<HalfEdge>();
// Allocate space for voronoi diagram
this.vertices = new Vertex[mesh.triangles.Count + mesh.hullsize];
this.faces = new Face[mesh.vertices.Count];
this.edges = new List<HalfEdge>();
var vertices = new Vertex[mesh.triangles.Count + mesh.hullsize];
var faces = new Face[mesh.vertices.Count];
// Compute triangles circumcenters and setup bounding box
var map = ComputeVertices(mesh);
var map = ComputeVertices(mesh, vertices);
// Create all Voronoi faces.
foreach (var vertex in mesh.vertices.Values)
@@ -93,17 +59,20 @@ namespace TriangleNet.Voronoi
faces[vertex.id] = new Face(vertex);
}
ComputeEdges(mesh, map);
ComputeEdges(mesh, vertices, faces, map);
// At this point all edges are computed, but the (edge.next) pointers aren't set.
ConnectEdges(map);
base.vertices = new List<Vertex>(vertices);
base.faces = new List<Face>(faces);
}
/// <summary>
/// Compute the Voronoi vertices (the circumcenters of the triangles).
/// </summary>
/// <returns>An empty map, which will map all vertices to a list of leaving edges.</returns>
protected List<HalfEdge>[] ComputeVertices(Mesh mesh)
protected List<HalfEdge>[] ComputeVertices(Mesh mesh, Vertex[] vertices)
{
Otri tri = default(Otri);
double xi = 0, eta = 0;
@@ -136,7 +105,7 @@ namespace TriangleNet.Voronoi
/// Compute the edges of the Voronoi diagram.
/// </summary>
/// <param name="map">Empty vertex map.</param>
protected void ComputeEdges(Mesh mesh, List<HalfEdge>[] map)
protected void ComputeEdges(Mesh mesh, Vertex[] vertices, Face[] faces, List<HalfEdge>[] map)
{
Otri tri, neighbor = default(Otri);
TriangleNet.Geometry.Vertex org, dest;
@@ -269,23 +238,5 @@ namespace TriangleNet.Voronoi
}
}
}
protected virtual IEnumerable<IEdge> EnumerateEdges()
{
var edges = new List<IEdge>(this.edges.Count / 2);
foreach (var edge in this.edges)
{
var twin = edge.twin;
// Report edge only once.
if (edge.id < twin.id)
{
edges.Add(new Edge(edge.origin.id, twin.origin.id));
}
}
return edges;
}
}
}