public void FixMyPaintJob() { foreach (var triIndex in mesh.TriangleIndices()) { var thisTriGroup = mesh.GetTriangleGroup(triIndex); var neighbors = mesh.GetTriNeighbourTris(triIndex); var triGroup1 = mesh.GetTriangleGroup(neighbors[0]); if (triGroup1 == thisTriGroup) { continue; } var triGroup2 = mesh.GetTriangleGroup(neighbors[1]); if (triGroup2 == thisTriGroup) { continue; } var triGroup3 = mesh.GetTriangleGroup(neighbors[2]); if (triGroup1 == triGroup2 && triGroup2 == triGroup3) { mesh.SetTriangleGroup(triIndex, triGroup1); var colors = gameObject.GetComponent <MeshFilter>().sharedMesh.colors; colors[triIndex] = ColorManager.Instance.GetColorForId(triGroup1); gameObject.GetComponent <MeshFilter>().sharedMesh.colors = colors; } } Redraw(); }
// TODO: // - (in merge coincident) don't merge tris with same/opposite normals (option) // - after orienting components, try to find adjacent open components and // transfer orientation between them // - orient via nesting public void OrientComponents() { Components = new List <Component>(); HashSet <int> remaining = new HashSet <int>(Mesh.TriangleIndices()); List <int> stack = new List <int>(); while (remaining.Count > 0) { Component c = new Component(); c.triangles = new List <int>(); stack.Clear(); int start = remaining.First(); remaining.Remove(start); c.triangles.Add(start); stack.Add(start); while (stack.Count > 0) { int cur = stack[stack.Count - 1]; stack.RemoveAt(stack.Count - 1); Index3i tcur = Mesh.GetTriangle(cur); Index3i nbrs = Mesh.GetTriNeighbourTris(cur); for (int j = 0; j < 3; ++j) { int nbr = nbrs[j]; if (remaining.Contains(nbr) == false) { continue; } int a = tcur[j]; int b = tcur[(j + 1) % 3]; Index3i tnbr = Mesh.GetTriangle(nbr); if (IndexUtil.find_tri_ordered_edge(b, a, ref tnbr) == DMesh3.InvalidID) { Mesh.ReverseTriOrientation(nbr); } stack.Add(nbr); remaining.Remove(nbr); c.triangles.Add(nbr); } } Components.Add(c); } }
public static UnityMesh ToUnityMesh(this DMesh3 dMesh, bool bNorm = true, bool bUV = false, bool bCol = false) { bNorm &= dMesh.HasVertexNormals; bUV &= dMesh.HasVertexUVs; bCol &= dMesh.HasVertexColors; int[] vertexMap = new int[dMesh.VerticesBuffer.Length]; int[] triangleMap = new int[dMesh.TrianglesBuffer.Length]; int[] triangles = new int[dMesh.TriangleCount * 3]; List <Vector3d> vertices = new List <Vector3d>(); List <Vector3f> normals = new List <Vector3f>(); List <Vector2f> uv = new List <Vector2f>(); List <Colorf> colors = new List <Colorf>(); List <int> vertexUseCount = new List <int>(); NewVertexInfo vInfo = new NewVertexInfo(new Vector3d(), new Vector3f(), new Vector3f(), new Vector2f()); IEnumerator e = dMesh.TrianglesRefCounts.GetEnumerator(); int ti = 0; while (e.MoveNext()) { int iRef = (int)e.Current; Index3i triangle = dMesh.GetTriangle(iRef); triangleMap[iRef] = ti; for (int i = 0; i < 3; i++) { int vertIndex = triangle[i]; if (vertexMap[vertIndex] == 0) { vertexUseCount.Add(1); dMesh.GetVertex(vertIndex, ref vInfo, bNorm, bCol, bUV); vertices.Add(new Vector3f((float)vInfo.v.x, (float)vInfo.v.y, (float)vInfo.v.z)); vertexMap[vertIndex] = vertices.Count - 1; if (bNorm) { normals.Add(vInfo.n); } if (bUV) { uv.Add(vInfo.uv); } if (bCol) { colors.Add(new Colorf(vInfo.c.x, vInfo.c.y, vInfo.c.z)); } } else { vertexUseCount[vertexMap[vertIndex]]++; } triangles[ti * 3 + i] = vertexMap[vertIndex]; } ti++; } UnityMesh uMesh = new UnityMesh(vertexUseCount.ToArray(), triangles, vertices, normals, uv, colors); // Triangle normals and neighbors. e = dMesh.TrianglesRefCounts.GetEnumerator(); while (e.MoveNext()) { int iRef = (int)e.Current; int[] nb = dMesh.GetTriNeighbourTris(iRef).array; int[] neighbors = new int[3]; for (int i = 0; i < 3; i++) { neighbors[i] = (nb[i] != -1) ? triangleMap[nb[i]] : -1; } uMesh.AddTriangleInfo(triangleMap[iRef], (Vector3f)dMesh.GetTriNormal(iRef), neighbors); } return(uMesh); }