158 lines
3.0 KiB
C#
158 lines
3.0 KiB
C#
using System;
|
|
using TriangleNet.Topology;
|
|
|
|
namespace TriangleNet.Tools
|
|
{
|
|
public class AdjacencyMatrix
|
|
{
|
|
private int nnz;
|
|
|
|
private int[] pcol;
|
|
|
|
private int[] irow;
|
|
|
|
public readonly int N;
|
|
|
|
public int[] ColumnPointers => pcol;
|
|
|
|
public int[] RowIndices => irow;
|
|
|
|
public AdjacencyMatrix(Mesh mesh)
|
|
{
|
|
N = mesh.vertices.Count;
|
|
pcol = AdjacencyCount(mesh);
|
|
nnz = pcol[N];
|
|
irow = AdjacencySet(mesh, pcol);
|
|
SortIndices();
|
|
}
|
|
|
|
public AdjacencyMatrix(int[] pcol, int[] irow)
|
|
{
|
|
N = pcol.Length - 1;
|
|
nnz = pcol[N];
|
|
this.pcol = pcol;
|
|
this.irow = irow;
|
|
if (pcol[0] != 0)
|
|
{
|
|
throw new ArgumentException("Expected 0-based indexing.", "pcol");
|
|
}
|
|
if (irow.Length < nnz)
|
|
{
|
|
throw new ArgumentException();
|
|
}
|
|
}
|
|
|
|
public int Bandwidth()
|
|
{
|
|
int num = 0;
|
|
int num2 = 0;
|
|
for (int i = 0; i < N; i++)
|
|
{
|
|
for (int j = pcol[i]; j < pcol[i + 1]; j++)
|
|
{
|
|
int num3 = irow[j];
|
|
num = Math.Max(num, i - num3);
|
|
num2 = Math.Max(num2, num3 - i);
|
|
}
|
|
}
|
|
return num + 1 + num2;
|
|
}
|
|
|
|
private int[] AdjacencyCount(Mesh mesh)
|
|
{
|
|
int n = N;
|
|
int[] array = new int[n + 1];
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
array[i] = 1;
|
|
}
|
|
foreach (Triangle triangle in mesh.triangles)
|
|
{
|
|
int id = triangle.id;
|
|
int id2 = triangle.vertices[0].id;
|
|
int id3 = triangle.vertices[1].id;
|
|
int id4 = triangle.vertices[2].id;
|
|
int id5 = triangle.neighbors[2].tri.id;
|
|
if (id5 < 0 || id < id5)
|
|
{
|
|
array[id2]++;
|
|
array[id3]++;
|
|
}
|
|
id5 = triangle.neighbors[0].tri.id;
|
|
if (id5 < 0 || id < id5)
|
|
{
|
|
array[id3]++;
|
|
array[id4]++;
|
|
}
|
|
id5 = triangle.neighbors[1].tri.id;
|
|
if (id5 < 0 || id < id5)
|
|
{
|
|
array[id4]++;
|
|
array[id2]++;
|
|
}
|
|
}
|
|
for (int num = n; num > 0; num--)
|
|
{
|
|
array[num] = array[num - 1];
|
|
}
|
|
array[0] = 0;
|
|
for (int j = 1; j <= n; j++)
|
|
{
|
|
array[j] = array[j - 1] + array[j];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
private int[] AdjacencySet(Mesh mesh, int[] pcol)
|
|
{
|
|
int n = N;
|
|
int[] array = new int[n];
|
|
Array.Copy(pcol, array, n);
|
|
int[] array2 = new int[pcol[n]];
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
array2[array[i]] = i;
|
|
array[i]++;
|
|
}
|
|
foreach (Triangle triangle in mesh.triangles)
|
|
{
|
|
int id = triangle.id;
|
|
int id2 = triangle.vertices[0].id;
|
|
int id3 = triangle.vertices[1].id;
|
|
int id4 = triangle.vertices[2].id;
|
|
int id5 = triangle.neighbors[2].tri.id;
|
|
if (id5 < 0 || id < id5)
|
|
{
|
|
array2[array[id2]++] = id3;
|
|
array2[array[id3]++] = id2;
|
|
}
|
|
id5 = triangle.neighbors[0].tri.id;
|
|
if (id5 < 0 || id < id5)
|
|
{
|
|
array2[array[id3]++] = id4;
|
|
array2[array[id4]++] = id3;
|
|
}
|
|
id5 = triangle.neighbors[1].tri.id;
|
|
if (id5 < 0 || id < id5)
|
|
{
|
|
array2[array[id2]++] = id4;
|
|
array2[array[id4]++] = id2;
|
|
}
|
|
}
|
|
return array2;
|
|
}
|
|
|
|
public void SortIndices()
|
|
{
|
|
int n = N;
|
|
int[] array = irow;
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
int num = pcol[i];
|
|
int num2 = pcol[i + 1];
|
|
Array.Sort(array, num, num2 - num);
|
|
}
|
|
}
|
|
}
|
|
}
|