Files
2026-03-04 10:03:45 +08:00

170 lines
2.9 KiB
C#

using System;
using TriangleNet.Geometry;
using TriangleNet.Topology.DCEL;
using TriangleNet.Voronoi;
namespace TriangleNet.Smoothing
{
internal class VoronoiFactory : IVoronoiFactory
{
private class ObjectPool<T> where T : class
{
private int index;
private int count;
private T[] pool;
public int Count => count;
public int Capacity
{
get
{
return pool.Length;
}
set
{
Resize(value);
}
}
public ObjectPool(int capacity = 3)
{
index = 0;
count = 0;
pool = new T[capacity];
}
public ObjectPool(T[] pool)
{
index = 0;
count = 0;
this.pool = pool;
}
public bool TryGet(out T obj)
{
if (index < count)
{
obj = pool[index++];
return true;
}
obj = null;
return false;
}
public void Put(T obj)
{
int num = pool.Length;
if (num <= count)
{
Resize(2 * num);
}
pool[count++] = obj;
index++;
}
public void Release()
{
index = 0;
}
private void Resize(int size)
{
if (size > count)
{
Array.Resize(ref pool, size);
}
}
}
private ObjectPool<TriangleNet.Topology.DCEL.Vertex> vertices;
private ObjectPool<HalfEdge> edges;
private ObjectPool<Face> faces;
public VoronoiFactory()
{
vertices = new ObjectPool<TriangleNet.Topology.DCEL.Vertex>();
edges = new ObjectPool<HalfEdge>();
faces = new ObjectPool<Face>();
}
public void Initialize(int vertexCount, int edgeCount, int faceCount)
{
vertices.Capacity = vertexCount;
edges.Capacity = edgeCount;
faces.Capacity = faceCount;
for (int i = vertices.Count; i < vertexCount; i++)
{
vertices.Put(new TriangleNet.Topology.DCEL.Vertex(0.0, 0.0));
}
for (int j = edges.Count; j < edgeCount; j++)
{
edges.Put(new HalfEdge(null));
}
for (int k = faces.Count; k < faceCount; k++)
{
faces.Put(new Face(null));
}
Reset();
}
public void Reset()
{
vertices.Release();
edges.Release();
faces.Release();
}
public TriangleNet.Topology.DCEL.Vertex CreateVertex(double x, double y)
{
if (vertices.TryGet(out var obj))
{
obj.x = x;
obj.y = y;
obj.leaving = null;
return obj;
}
obj = new TriangleNet.Topology.DCEL.Vertex(x, y);
vertices.Put(obj);
return obj;
}
public HalfEdge CreateHalfEdge(TriangleNet.Topology.DCEL.Vertex origin, Face face)
{
if (edges.TryGet(out var obj))
{
obj.origin = origin;
obj.face = face;
obj.next = null;
obj.twin = null;
if (face != null && face.edge == null)
{
face.edge = obj;
}
return obj;
}
obj = new HalfEdge(origin, face);
edges.Put(obj);
return obj;
}
public Face CreateFace(TriangleNet.Geometry.Vertex vertex)
{
if (faces.TryGet(out var obj))
{
obj.id = vertex.id;
obj.generator = vertex;
obj.edge = null;
return obj;
}
obj = new Face(vertex);
faces.Put(obj);
return obj;
}
}
}