public static int FindClosestFaceOnMesh(Quad[] meshFaces, Vector3[] meshVertexPositions, Vector3 targetPoint) { int bestFaceIdx = -1; float bestFaceDist = float.PositiveInfinity; for (int faceIdx = 0; faceIdx < meshFaces.Length; ++faceIdx) { Quad quad = meshFaces[faceIdx]; for (int i = 0; i < 2; ++i) { int vertexIdxA = quad.GetCorner(i + 0); int vertexIdxB = quad.GetCorner(i + 1); int vertexIdxC = quad.GetCorner(i + 2); PointOnMesh closestOnFace = PointOnMesh.MakeClosestToFace(meshVertexPositions, vertexIdxA, vertexIdxB, vertexIdxC, targetPoint); Vector3 closestOnFacePosition = closestOnFace.AsPosition(meshVertexPositions); float dist = Vector3.DistanceSquared(targetPoint, closestOnFacePosition); if (dist < bestFaceDist) { bestFaceIdx = faceIdx; bestFaceDist = dist; } } } return(bestFaceIdx); }
public static int[] CalculateTextureToSpatialIndexMap(QuadTopology texturedTopology, Quad[] spatialFaces) { int faceCount = texturedTopology.Faces.Length; if (spatialFaces.Length != faceCount) { throw new InvalidOperationException("textured and spatial face count mismatch"); } int[] spatialIdxMap = new int[texturedTopology.VertexCount]; for (int faceIdx = 0; faceIdx < faceCount; ++faceIdx) { Quad texturedFace = texturedTopology.Faces[faceIdx]; Quad spatialFace = spatialFaces[faceIdx]; for (int i = 0; i < Quad.SideCount; ++i) { int texturedIdx = texturedFace.GetCorner(i); int spatialIdx = spatialFace.GetCorner(i); int previousMapping = spatialIdxMap[texturedIdx]; if (previousMapping != default(int) && previousMapping != spatialIdx) { throw new InvalidOperationException("mapping conflict"); } spatialIdxMap[texturedIdx] = spatialIdx; } } return(spatialIdxMap); }
private void AssignLabelToConnectedFaces(int label, int faceIdx) { int currentLabel = faceLabels[faceIdx]; if (currentLabel == label) { return; } if (currentLabel != -1) { throw new InvalidOperationException("a face cannot be assigned more than one label"); } faceLabels[faceIdx] = label; Quad face = faces[faceIdx]; for (int cornerIdx = 0; cornerIdx < Quad.SideCount; ++cornerIdx) { int vertexIdx = face.GetCorner(cornerIdx); foreach (int adjacentFaceIdx in adjacentFacesByVertex[vertexIdx]) { AssignLabelToConnectedFaces(label, adjacentFaceIdx); } } }
/** * Given two topologies with the same faces but different vertex indices, returns a map from the vertex * indices of one topology to the vertex indices of the other topologies. * * Each vertex in the source topology must map to a single vertex in the dest topology. However, it's * allowable for multiple source vertices to map to the same dest vertex. Thus it's possible to map * from a source UV topology with seams to a dest spatial topology without seams. */ public static int[] CalculateVertexIndexMap(QuadTopology sourceTopology, Quad[] destFaces) { int faceCount = sourceTopology.Faces.Length; if (destFaces.Length != faceCount) { throw new InvalidOperationException("face count mismatch"); } int[] indexMap = new int[sourceTopology.VertexCount]; for (int faceIdx = 0; faceIdx < faceCount; ++faceIdx) { Quad sourceFace = sourceTopology.Faces[faceIdx]; Quad destFace = destFaces[faceIdx]; for (int i = 0; i < Quad.SideCount; ++i) { int sourceIdx = sourceFace.GetCorner(i); int destIdx = destFace.GetCorner(i); int previousMapping = indexMap[sourceIdx]; if (previousMapping != default(int) && previousMapping != destIdx) { throw new InvalidOperationException("mapping conflict"); } indexMap[sourceIdx] = destIdx; } } return(indexMap); }
private void FillAdjancencyTable() { for (int faceIdx = 0; faceIdx < faces.Length; ++faceIdx) { Quad face = faces[faceIdx]; for (int cornerIdx = 0; cornerIdx < Quad.SideCount; ++cornerIdx) { adjacentFacesByVertex[face.GetCorner(cornerIdx)].Add(faceIdx); } } }