private static int[] GenerateAdjacency(Vector3[] positions,
List<int> positionIndices)
{
// faces within mesh
int ncFaces = positionIndices.Count / 3;
// vertex count
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");
// the edge map will hold an edge center position as key and a list of edges that share the edge center position
Dictionary<Vector3, List<AdjEdge>> edgeMap = new Dictionary<Vector3, List<AdjEdge>>();
// edge center position
Vector3 edgeVector = new Vector3();
// iterate over list of position indices
// there are 3 indices per face
for (int i = 0; i < positionIndices.Count; i+=3)
{
// face index
int iFace = i / 3;
// compute edge center position
edgeVector = Quantize((positions[positionIndices[i + 0]] + positions[positionIndices[i + 1]]) / 2);
// if the edge center doesn't exist in the map then add a new entry
if (!edgeMap.ContainsKey(edgeVector))
edgeMap.Add(edgeVector, new List<AdjEdge>());
// add the edge
edgeMap[edgeVector].Add(
new AdjEdge(positions[positionIndices[i + 0]], positions[positionIndices[i + 1]], edgeVector, 0, iFace));
// compute edge center position
edgeVector = Quantize((positions[positionIndices[i + 1]] + positions[positionIndices[i + 2]]) / 2);
// if the edge center doesn't exist in the map then add a new entry
if (!edgeMap.ContainsKey(edgeVector))
edgeMap.Add(edgeVector, new List<AdjEdge>());
// add the edge
edgeMap[edgeVector].Add(
new AdjEdge(positions[positionIndices[i + 1]], positions[positionIndices[i + 2]], edgeVector, 1, iFace));
// compute edge center position
edgeVector = Quantize((positions[positionIndices[i + 2]] + positions[positionIndices[i + 0]]) / 2);
// if the edge center doesn't exist in the map then add a new entry
if (!edgeMap.ContainsKey(edgeVector))
edgeMap.Add(edgeVector, new List<AdjEdge>());
// add the edge
edgeMap[edgeVector].Add(
new AdjEdge(positions[positionIndices[i + 2]], positions[positionIndices[i + 0]], edgeVector, 2, iFace));
}
// iterate over the edge map
foreach (Vector3 key in edgeMap.Keys)
{
// list of edges sharing the same center position
List<AdjEdge> edges = edgeMap[key];
// iterate over source edges
for (int i = 0; i < edges.Count - 1; ++i)
{
// source edge
AdjEdge edgeA = edges[i];
// do not parse edge twice
if (edgeA._parsed)
continue;
// iterate over comparison edges
for (int j = i + 1; j < edges.Count; ++j)
{
// comparison edge
AdjEdge edgeB = edges[j];
// do not parse edge twice
if (edgeB._parsed)
continue;
// compare the edges
if (CompareVectors(edgeA._ref0, edgeB._ref1)
&& CompareVectors(edgeA._ref1, edgeB._ref0))
{
// the edges were similar so set adjacency for both edges
adjacency[3 * edgeA._face + edgeA._edge] = edgeB._face;
adjacency[3 * edgeB._face + edgeB._edge] = edgeA._face;
// set parsed state true
edgeA._parsed = true;
edgeB._parsed = true;
// break out of comparison loop
break;
}
}
}
}
return adjacency;
}
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;
}
List<int> positionIndices)
{
// faces within mesh
int ncFaces = positionIndices.Count / 3;
// vertex count
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");
// the edge map will hold an edge center position as key and a list of edges that share the edge center position
Dictionary<Vector3, List<AdjEdge>> edgeMap = new Dictionary<Vector3, List<AdjEdge>>();
// edge center position
Vector3 edgeVector = new Vector3();
// iterate over list of position indices
// there are 3 indices per face
for (int i = 0; i < positionIndices.Count; i+=3)
{
// face index
int iFace = i / 3;
// compute edge center position
edgeVector = Quantize((positions[positionIndices[i + 0]] + positions[positionIndices[i + 1]]) / 2);
// if the edge center doesn't exist in the map then add a new entry
if (!edgeMap.ContainsKey(edgeVector))
edgeMap.Add(edgeVector, new List<AdjEdge>());
// add the edge
edgeMap[edgeVector].Add(
new AdjEdge(positions[positionIndices[i + 0]], positions[positionIndices[i + 1]], edgeVector, 0, iFace));
// compute edge center position
edgeVector = Quantize((positions[positionIndices[i + 1]] + positions[positionIndices[i + 2]]) / 2);
// if the edge center doesn't exist in the map then add a new entry
if (!edgeMap.ContainsKey(edgeVector))
edgeMap.Add(edgeVector, new List<AdjEdge>());
// add the edge
edgeMap[edgeVector].Add(
new AdjEdge(positions[positionIndices[i + 1]], positions[positionIndices[i + 2]], edgeVector, 1, iFace));
// compute edge center position
edgeVector = Quantize((positions[positionIndices[i + 2]] + positions[positionIndices[i + 0]]) / 2);
// if the edge center doesn't exist in the map then add a new entry
if (!edgeMap.ContainsKey(edgeVector))
edgeMap.Add(edgeVector, new List<AdjEdge>());
// add the edge
edgeMap[edgeVector].Add(
new AdjEdge(positions[positionIndices[i + 2]], positions[positionIndices[i + 0]], edgeVector, 2, iFace));
}
// iterate over the edge map
foreach (Vector3 key in edgeMap.Keys)
{
// list of edges sharing the same center position
List<AdjEdge> edges = edgeMap[key];
// iterate over source edges
for (int i = 0; i < edges.Count - 1; ++i)
{
// source edge
AdjEdge edgeA = edges[i];
// do not parse edge twice
if (edgeA._parsed)
continue;
// iterate over comparison edges
for (int j = i + 1; j < edges.Count; ++j)
{
// comparison edge
AdjEdge edgeB = edges[j];
// do not parse edge twice
if (edgeB._parsed)
continue;
// compare the edges
if (CompareVectors(edgeA._ref0, edgeB._ref1)
&& CompareVectors(edgeA._ref1, edgeB._ref0))
{
// the edges were similar so set adjacency for both edges
adjacency[3 * edgeA._face + edgeA._edge] = edgeB._face;
adjacency[3 * edgeB._face + edgeB._edge] = edgeA._face;
// set parsed state true
edgeA._parsed = true;
edgeB._parsed = true;
// break out of comparison loop
break;
}
}
}
}
return adjacency;
}
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;
}
No comments:
Post a Comment