/** * Initialize a new qe_Mesh with @InGameObject. Must have a valid meshfilter and mesh. * GameObject will have it's MeshFilter.sharedMesh property set to the clone mesh for editing. * Call qe_Mesh.Revert() to undo this change (and destroy the cloned mesh in the process). */ public static qe_Mesh Create(GameObject InGameObject) { qe_Mesh qmesh = ScriptableObject.CreateInstance <qe_Mesh>(); qmesh.hideFlags = HideFlags.DontSave; qmesh.gameObject = InGameObject; qmesh.transform = qmesh.gameObject.transform; qmesh.originalMesh = InGameObject.GetComponent <MeshFilter>().sharedMesh; qmesh.source = qe_Editor_Utility.GetMeshGUID(qmesh.originalMesh, ref qmesh.originalMeshGUID); // Copy mesh from InMesh. qmesh.cloneMesh = qe_Mesh_Utility.Clone(InGameObject.GetComponent <MeshFilter>().sharedMesh); Undo.RegisterCreatedObjectUndo(qmesh.cloneMesh, "Open Quick Edit"); Undo.RecordObject(qmesh, "Open Quick Edit"); qmesh.Apply(); qmesh.handlesRenderer = (qe_HandleRenderer)Undo.AddComponent(InGameObject, typeof(qe_HandleRenderer)); qmesh.handlesRenderer.hideFlags = HideFlags.HideAndDontSave; qmesh.handlesRenderer.mesh = new Mesh(); qmesh.handlesRenderer.mesh.hideFlags = HideFlags.HideAndDontSave; qmesh.handlesRenderer.material = null; qmesh.CacheElements(); return(qmesh); }
public static void RebuildUV2(qe_Mesh mesh) { Unwrapping.GenerateSecondaryUVSet(mesh.cloneMesh); // GenerateSecondaryUVSet may add vertices, so rebuild the // internal stores. mesh.CacheElements(); }
/** * Remove @triangles from this mesh. */ public static bool DeleteTriangles(qe_Mesh mesh, List <qe_Triangle> triangles) { List <qe_Triangle> trianglesToRemove = new List <qe_Triangle>(triangles); trianglesToRemove.Distinct(); if (trianglesToRemove.Count == mesh.faces.Length) { Debug.LogWarning("Cannot delete every triangle on a mesh!"); return(false); } int subMeshCount = mesh.cloneMesh.subMeshCount; for (int i = 0; i < subMeshCount; i++) { List <int> remove = new List <int>(); List <int> tris = mesh.GetIndices(i).ToList(); for (int n = 0; n < tris.Count; n += 3) { int index = trianglesToRemove.IndexOf(tris[n], tris[n + 1], tris[n + 2]); if (index > -1) { remove.Add(n + 0); remove.Add(n + 1); remove.Add(n + 2); trianglesToRemove.RemoveAt(index); } } remove.Sort(); List <int> rebuilt = new List <int>(); int removeIndex = 0; for (int n = 0; n < tris.Count; n++) { if (removeIndex < remove.Count && n == remove[removeIndex]) { removeIndex++; continue; } rebuilt.Add(tris[n]); } mesh.SetIndices(i, rebuilt.ToArray()); } RemoveUnusedVertices(ref mesh.cloneMesh); mesh.CacheElements(); return(true); }
/** * */ public static bool SnapVertices(qe_Mesh mesh, List <int> selected) { /* * Vector3 v = mesh.cloneMesh.vertices[selected[0]]; * * Vector3[] verts = mesh.cloneMesh.vertices; * for (int a = 1; a < selected.Count; a++) * { * for (int b = 0; b < verts.Length;b++) * if (verts[selected[a]] == verts[b]) * verts[b] = v; * } */ Vector3[] verts = mesh.cloneMesh.vertices; List <int> trueSelected = new List <int>(); Vector3 v = mesh.cloneMesh.vertices[selected[0]]; for (int b = 0; b < verts.Length; b++) { for (int a = 1; a < selected.Count; a++) { if (verts[selected[a]] == verts[b]) { trueSelected.Add(b); } } } foreach (int i in trueSelected) { verts[i] = v; } mesh.cloneMesh.vertices = verts; mesh.CacheElements(); // float d = Vector3.Distance(v,verts[selected[0]]); //Debug.Log(">>> " + selected.Count+" / "+c+"/"+d); return(true); }
public static void Facetize(qe_Mesh qmesh) { Mesh mesh = qmesh.cloneMesh; int triangleCount = mesh.triangles.Length; bool boneWeights_isNull = mesh.boneWeights.NullOrEmpty(); bool colors_isNull = mesh.colors.NullOrEmpty(); bool colors32_isNull = mesh.colors32.NullOrEmpty(); bool normals_isNull = mesh.normals.NullOrEmpty(); bool tangents_isNull = mesh.tangents.NullOrEmpty(); bool uv_isNull = mesh.uv.NullOrEmpty(); bool uv2_isNull = mesh.uv2.NullOrEmpty(); #if UNITY_5 bool uv3_isNull = mesh.uv3.NullOrEmpty(); bool uv4_isNull = mesh.uv4.NullOrEmpty(); #endif bool vertices_isNull = mesh.vertices.NullOrEmpty(); BoneWeight[] boneWeights = boneWeights_isNull ? null : new BoneWeight[triangleCount]; Color[] colors = colors_isNull ? null : new Color[triangleCount]; Color32[] colors32 = colors32_isNull ? null : new Color32[triangleCount]; Vector3[] normals = normals_isNull ? null : new Vector3[triangleCount]; Vector4[] tangents = tangents_isNull ? null : new Vector4[triangleCount]; Vector2[] uv = uv_isNull ? null : new Vector2[triangleCount]; Vector2[] uv2 = uv2_isNull ? null : new Vector2[triangleCount]; #if UNITY_5 Vector2[] uv3 = uv3_isNull ? null : new Vector2[triangleCount]; Vector2[] uv4 = uv4_isNull ? null : new Vector2[triangleCount]; #endif Vector3[] vertices = new Vector3[triangleCount]; // cache mesh arrays because accessing them through the reference is slooooow Vector3[] mVertices = mesh.vertices; BoneWeight[] mBoneWeights = mesh.boneWeights; Color[] mColors = mesh.colors; Color32[] mColors32 = mesh.colors32; Vector3[] mNormals = mesh.normals; Vector4[] mTangents = mesh.tangents; Vector2[] mUv = mesh.uv; Vector2[] mUv2 = mesh.uv2; #if UNITY_5 Vector2[] mUv3 = mesh.uv3; Vector2[] mUv4 = mesh.uv4; #endif int index = 0; int[][] triangles = new int[mesh.subMeshCount][]; for (int i = 0; i < mesh.subMeshCount; i++) { triangles[i] = qmesh.GetIndices(i); for (int t = 0; t < triangles[i].Length; t++) { int n = triangles[i][t]; if (!boneWeights_isNull) { boneWeights[index] = mBoneWeights[n]; } if (!colors_isNull) { colors[index] = mColors[n]; } if (!colors32_isNull) { colors32[index] = mColors32[n]; } if (!normals_isNull) { normals[index] = mNormals[n]; } if (!tangents_isNull) { tangents[index] = mTangents[n]; } if (!uv_isNull) { uv[index] = mUv[n]; } if (!uv2_isNull) { uv2[index] = mUv2[n]; } #if UNITY_5 if (!uv3_isNull) { uv3[index] = mUv3[n]; } if (!uv4_isNull) { uv4[index] = mUv4[n]; } #endif if (!vertices_isNull) { vertices[index] = mVertices[n]; } triangles[i][t] = index; index++; } } mesh.vertices = vertices; mesh.boneWeights = boneWeights; mesh.colors = colors; mesh.colors32 = colors32; mesh.normals = normals; mesh.tangents = tangents; mesh.uv = uv; mesh.uv2 = uv2; #if UNITY_5 mesh.uv3 = uv3; mesh.uv4 = uv4; #endif for (int i = 0; i < mesh.subMeshCount; i++) { qmesh.SetIndices(i, triangles[i]); } mesh.RecalculateNormals(); qmesh.CacheElements(); }
/** * */ public static bool SmoothTriangles(qe_Mesh mesh, List <qe_Triangle> triangles) { List <Vector3> distinctVerts = new List <Vector3>(); List <int> tris = new List <int>(); int i = 0; foreach (var t in triangles) { for (int a = 0; a < 3; a++) { Vector3 v = mesh.vertices[t.indices[a]]; int oldIdx = -1; for (int b = 0; b < distinctVerts.Count; b++) { if (v == distinctVerts[b]) { oldIdx = b; break; } } if (oldIdx == -1) { oldIdx = distinctVerts.Count; distinctVerts.Add(v); } tris.Add(oldIdx); i++; } } Debug.Log("Distict verts: " + distinctVerts.Count); Mesh tmpMesh = new Mesh(); tmpMesh.SetVertices(distinctVerts); tmpMesh.SetTriangles(tris, 0); tmpMesh.RecalculateNormals(); Debug.Log("New normals: " + tmpMesh.normals.Length); Vector3[] norms = mesh.cloneMesh.normals; i = 0; foreach (var t in triangles) { for (int a = 0; a < 3; a++) { int di = tris[i]; Vector3 n = tmpMesh.normals[di]; norms[t.indices[a]] = n; i++; } } mesh.cloneMesh.normals = norms; mesh.CacheElements(); return(true); //mesh.cloneMesh.RecalculateNormals(); }