I have a list of indexed triangles for which I need to generate adjacency data. I've already written a brute force algorithm that creates 3 edge data structures for each triangle and then compares the edge structures with those of other triangles like so:
public struct AdjEdge
{
public Vector3 _ref0;
public Vector3 _ref1;
public int _edge;
public int _face;
public bool _parsed;
public AdjEdge(Vector3 ref0, Vector3 ref1, int edge, int face)
{
_ref0 = ref0;
_ref1 = ref1;
_edge = edge;
_face = face;
_parsed = false;
}
}
private static int[] GenerateAdjacency(Vector3[] positions,
List<int> positionIndices)
{
int ncFaces = positionIndices.Count / 3;
int ncVertices = positions.Length;
// inst. adjacency array and set all values to -1
int[] adjacency = Enumerable.Repeat(-1, 3 * ncFaces).ToArray();
if (adjacency == null)
throw new OutOfMemoryException("Failed to allocate memory for adjacency data");
List<AdjEdge> edges = new List<AdjEdge>();
for (int i = 0; i < positionIndices.Count; i+=3)
{
int iFace = i / 3;
edges.Add(new AdjEdge(positions[positionIndices[i + 0]], positions[positionIndices[i + 1]], 0, iFace));
edges.Add(new AdjEdge(positions[positionIndices[i + 1]], positions[positionIndices[i + 2]], 1, iFace));
edges.Add(new AdjEdge(positions[positionIndices[i + 2]], positions[positionIndices[i + 0]], 2, iFace));
}
for (int i = 0; i < edges.Count - 1; ++i)
{
AdjEdge edgeA = edges[i];
if (edgeA._parsed)
continue;
for (int j = 3 - (i % 3) + i; j < edges.Count; ++j)
{
AdjEdge edgeB = edges[j];
if (edgeB._parsed)
continue;
// CompareVectors() returns true if the vectors are separated by a distance less than 1e-6f
if (CompareVectors(edgeA._ref0, edgeB._ref1)
&& CompareVectors(edgeA._ref1, edgeB._ref0))
{
adjacency[3 * edgeA._face + edgeA._edge] = edgeB._face;
adjacency[3 * edgeB._face + edgeB._edge] = edgeA._face;
edgeA._parsed = true;
edgeB._parsed = true;
break;
}
}
}
return adjacency;
}
Needless to say, time complexity is an issue here. What is the most efficient method for generating adjacency when comparing position data using an epsilon?