private static HashSet <z_CommonEdge> GetEdgesDistinct(z_Mesh m, Dictionary <int, int> lookup, out List <z_CommonEdge> duplicates) { int[] tris = m.GetTriangles(); int count = tris.Length; HashSet <z_CommonEdge> edges = new HashSet <z_CommonEdge>(); duplicates = new List <z_CommonEdge>(); for (int i = 0; i < count; i += 3) { z_CommonEdge a = new z_CommonEdge(tris[i + 0], tris[i + 1], lookup[tris[i + 0]], lookup[tris[i + 1]]); z_CommonEdge b = new z_CommonEdge(tris[i + 1], tris[i + 2], lookup[tris[i + 1]], lookup[tris[i + 2]]); z_CommonEdge c = new z_CommonEdge(tris[i + 2], tris[i + 0], lookup[tris[i + 2]], lookup[tris[i + 0]]); if (!edges.Add(a)) { duplicates.Add(a); } if (!edges.Add(b)) { duplicates.Add(b); } if (!edges.Add(c)) { duplicates.Add(c); } } return(edges); }
/** * Builds a lookup with each vertex index and a list of all neighboring indices. */ public static Dictionary <int, List <int> > GetAdjacentVertices(z_Mesh mesh) { List <List <int> > common = GetCommonVertices(mesh); Dictionary <int, int> lookup = common.GetCommonLookup <int>(); List <z_CommonEdge> edges = GetEdges(mesh, lookup).ToList(); List <List <int> > map = new List <List <int> >(); for (int i = 0; i < common.Count(); i++) { map.Add(new List <int>()); } for (int i = 0; i < edges.Count; i++) { map[edges[i].cx].Add(edges[i].y); map[edges[i].cy].Add(edges[i].x); } Dictionary <int, List <int> > adjacent = new Dictionary <int, List <int> >(); IEnumerable <int> distinctTriangles = mesh.GetTriangles().Distinct(); foreach (int i in distinctTriangles) { adjacent.Add(i, map[lookup[i]]); } return(adjacent); }
public static List <z_CommonEdge> GetEdges(z_Mesh m, Dictionary <int, int> lookup) { int[] tris = m.GetTriangles(); int count = tris.Length; List <z_CommonEdge> edges = new List <z_CommonEdge>(count); for (int i = 0; i < count; i += 3) { edges.Add(new z_CommonEdge(tris[i + 0], tris[i + 1], lookup[tris[i + 0]], lookup[tris[i + 1]])); edges.Add(new z_CommonEdge(tris[i + 1], tris[i + 2], lookup[tris[i + 1]], lookup[tris[i + 2]])); edges.Add(new z_CommonEdge(tris[i + 2], tris[i + 0], lookup[tris[i + 2]], lookup[tris[i + 0]])); } return(edges); }
public override void DrawGizmos(z_BrushTarget target, z_BrushSettings settings) { z_Mesh mesh = target.editableObject.editMesh; if (z_Util.IsValid(target) && paintMode == z_PaintMode.Fill) { Vector3[] vertices = mesh.vertices; int[] indices = mesh.GetTriangles(); z_Handles.PushMatrix(); z_Handles.PushHandleColor(); Handles.matrix = target.transform.localToWorldMatrix; int index = 0; foreach (z_RaycastHit hit in target.raycastHits) { if (hit.triangle > -1) { Handles.color = Color.green; index = hit.triangle * 3; Handles.DrawLine(vertices[indices[index + 0]] + hit.normal * .1f, vertices[indices[index + 1]] + hit.normal * .1f); Handles.DrawLine(vertices[indices[index + 1]] + hit.normal * .1f, vertices[indices[index + 2]] + hit.normal * .1f); Handles.DrawLine(vertices[indices[index + 2]] + hit.normal * .1f, vertices[indices[index + 0]] + hit.normal * .1f); _fillModeEdges[0].x = indices[index + 0]; _fillModeEdges[0].y = indices[index + 1]; _fillModeEdges[1].x = indices[index + 1]; _fillModeEdges[1].y = indices[index + 2]; _fillModeEdges[2].x = indices[index + 2]; _fillModeEdges[2].y = indices[index + 0]; for (int i = 0; i < 3; i++) { if (triangleLookup.TryGetValue(_fillModeEdges[i], out _fillModeAdjacentTris)) { for (int n = 0; n < _fillModeAdjacentTris.Count; n++) { index = _fillModeAdjacentTris[n] * 3; Handles.DrawLine(vertices[indices[index + 0]] + hit.normal * .1f, vertices[indices[index + 1]] + hit.normal * .1f); Handles.DrawLine(vertices[indices[index + 1]] + hit.normal * .1f, vertices[indices[index + 2]] + hit.normal * .1f); Handles.DrawLine(vertices[indices[index + 2]] + hit.normal * .1f, vertices[indices[index + 0]] + hit.normal * .1f); } } } } } z_Handles.PopHandleColor(); z_Handles.PopMatrix(); } else { base.DrawGizmos(target, settings); } }
/** * Returns a dictionary where each z_Edge is mapped to a list of triangle indices that share that edge. * To translate triangle list to vertex indices, multiply by 3 and take those indices (ex, triangles[index+{0,1,2}]) */ public static Dictionary <z_Edge, List <int> > GetAdjacentTriangles(z_Mesh m) { int len = m.GetTriangles().Length; if (len % 3 != 0 || len / 3 == m.vertexCount) { return(new Dictionary <z_Edge, List <int> >()); } Dictionary <z_Edge, List <int> > lookup = null; // @todo - should add some checks to make sure triangle structure hasn't changed if (adjacentTrianglesCache.TryGetValue(m, out lookup)) { return(lookup); } int smc = m.subMeshCount; lookup = new Dictionary <z_Edge, List <int> >(); List <int> connections; for (int n = 0; n < smc; n++) { int[] tris = m.GetIndices(n); for (int i = 0; i < tris.Length; i += 3) { int index = i / 3; z_Edge a = new z_Edge(tris[i], tris[i + 1]); z_Edge b = new z_Edge(tris[i + 1], tris[i + 2]); z_Edge c = new z_Edge(tris[i + 2], tris[i]); if (lookup.TryGetValue(a, out connections)) { connections.Add(index); } else { lookup.Add(a, new List <int>() { index }); } if (lookup.TryGetValue(b, out connections)) { connections.Add(index); } else { lookup.Add(b, new List <int>() { index }); } if (lookup.TryGetValue(c, out connections)) { connections.Add(index); } else { lookup.Add(c, new List <int>() { index }); } } } adjacentTrianglesCache.Add(m, lookup); return(lookup); }