static void BuildStripes( ref Dictionary // output dictionary <float, quadByVertex> r, quadByVertex list, // input list of hashsets Vector3 N, // axis plane normal of quad list int direction // build for which direction in axis plane ) { // build a list of quads connected by a direction in a given axis plane if (list.Count <= 0) { return; } // which vector component do we need to check for grouping direction int i = 0; if (Mathf.Abs(N.x) > 0.0f) // X+,-: YZ plane { i = (direction == 0 ? 1 : 2); // X -> Z } else if (Mathf.Abs(N.y) > 0.0f) // Y+,-: XZ plane { i = (direction == 0 ? 2 : 0); // Z -> X } else if (Mathf.Abs(N.z) > 0.0f) // Z+,-: XY plane { i = (direction == 0 ? 1 : 0); // Y -> X } // now start grouping the quads into directions r.Clear(); foreach (HashSet <Vector3> A in list) // for every "quad vertex set A" { // calculate center, add to dictionary Vector3 center = Vector3.zero; // calculate a center for the quad foreach (Vector3 p in A) // sum up all the vertices { center += p; } center /= A.Count; // divide by fraction count // get the correct center direction for grouping, add quad to list float k = Mathf.Round(center[i] * 100.0f) / 100.0f; // round key to second fraction if (!r.ContainsKey(k)) // key not yet present { r[k] = new quadByVertex(); // add new list of hashsets } r[k].Add(A); // add current quad to list } }
static bool TrianglesToQuads( triangleByUV triangles, // input structure -> triangle primitives quadByUV quads, // output structure -> quad primitives int totalTriangles, // how many input triangles we have ref int totalQuads, // how many output quads were generated string at // element we're processing... ) { // pair the triangles into quads by max edge connections if (triangles == null || // no triangle list triangles.Count <= 0 || // OR no primitives quads == null) // OR no output list { return(true); } // calculate progess amount string title = "Triangle Primitives->Quads " + at; float increment = 1.0f / (totalTriangles - 1); bool wasCanceled = false; int atTriangle = 0; // sorted by "triangle A connectes to triangle B" triangleByQuad connections = new triangleByQuad(); quads.Clear(); foreach (Vector2 UV in triangles.Keys) // by UV color { foreach (Vector3 N in triangles[UV].Keys) // by normal direction { foreach (Vector2 r in triangles[UV][N].Keys) // by row in normal direction, axis plane { foreach (Triangle A in triangles[UV][N][r]) // triangle A { // go through all listed triangles as A/B atTriangle++; // up the current progress if (atTriangle % (totalTriangles / progressUpdates) == 0 && EditorUtility.DisplayCancelableProgressBar (title, "Searching...", atTriangle * increment)) { wasCanceled = true; goto Cancel; } if (!connections.ContainsValue(A)) // not yet listed in quads { foreach (Triangle B in triangles[UV][N][r]) // check all triangles against A { if (A != B && // not self-comparing !connections.ContainsValue(B) && // AND not yet listed in quads A.maxEdgeVertices.TrueForAll // AND the same two vertices are in both edge lists (o => B.maxEdgeVertices.Contains(o))) { // this is the connection A->B, forming a single quad connections[A] = B; // figure out the row of the quad float qr = 0; if (Mathf.Abs(N.x) > 0.0f) { qr = A.A.x; // X+,-: YZ plane } else if (Mathf.Abs(N.y) > 0.0f) { qr = A.A.y; // Y+,-: XZ plane } else if (Mathf.Abs(N.z) > 0.0f) { qr = A.A.z; // Z+,-: XY plane } // create missing acceleration structure levels if (!quads.ContainsKey(UV)) { quads[UV] = new quadByNormal(); } if (!quads[UV].ContainsKey(N)) { quads[UV][N] = new quadByRow(); } if (!quads[UV][N].ContainsKey(qr)) { quads[UV][N][qr] = new quadByVertex(); } // now add the quad by "UV->Normal->Row" key quads[UV][N][qr].Add( new HashSet <Vector3> (new Vector3[] { A.A, A.B, A.C, B.A, B.B, B.C }) ); break; } } } } } } } // export the amount of generated quad connections totalQuads = connections.Count; Cancel: // clear progress bar, signal "wasn't canceled" EditorUtility.ClearProgressBar(); return(wasCanceled); }