Example #1
0
        public void AllocateBuffers(int trianglesNum)
        {
            if (lsHash == null || lsHash.Capacity() < trianglesNum * 2)
            {
//                Utils.Log("Allocating contour: " + trianglesNum);

                midPoints = new ArrayDictionary <MidPoint>(trianglesNum * 2);
                contour   = new List <Dictionary <int, int> >();
                lsHash    = new LSHash(0.001f, trianglesNum * 2);
            }
            else
            {
                lsHash.Clear();
                foreach (var item in contour)
                {
                    item.Clear();
                }
                contour.Clear();

                if (midPoints.Size < trianglesNum * 2)
                {
//                    Utils.Log("Re-allocating midPoint: " + trianglesNum);

                    midPoints = new ArrayDictionary <MidPoint>(trianglesNum * 2);
                }
                else
                {
                    midPoints.Clear();
                }
            }
        }
Example #2
0
        /// <summary>
        /// find and isolate independent (not connecting) parts in a mesh
        /// </summary>
        public static List <CutterMesh> IsolateMeshIslands(Mesh mesh)
        {
            var triangles   = mesh.triangles;
            var vertexCount = mesh.vertexCount;

            // cache mesh data
            var trianglesNum    = mesh.triangles.Length;
            var tangents        = mesh.tangents;
            var colors          = mesh.colors32;
            var vertices        = mesh.vertices;
            var normals         = mesh.normals;
            var uvs             = mesh.uv;
            var useMeshTangents = tangents != null && tangents.Length > 0;
            var useVertexColors = colors != null && colors.Length > 0;
            var useNormals      = normals != null && normals.Length > 0;

            if (trianglesNum <= 3)
            {
                return(null);
            }

            ExploderUtils.Assert(trianglesNum > 3, "IsolateMeshIslands error: " + trianglesNum);

            var lsHash   = new LSHash(0.1f, vertexCount);
            var vertHash = new int[trianglesNum];

            for (int i = 0; i < trianglesNum; i++)
            {
                vertHash[i] = lsHash.Hash(vertices[triangles[i]]);
            }

            var islands = new List <HashSet <int> > {
                new HashSet <int> {
                    vertHash[0], vertHash[1], vertHash[2]
                }
            };
            var islandsIdx = new List <List <int> > {
                new List <int>(trianglesNum)
                {
                    0, 1, 2
                }
            };
            var triVisited = new bool[trianglesNum];

            triVisited[0] = true;
            triVisited[1] = true;
            triVisited[2] = true;

            var currIsland    = islands[0];
            var currIslandIdx = islandsIdx[0];

            var counter        = 3;
            var lastInvalidIdx = -1;
            var loopCounter    = 0;

            while (true)
            {
                var foundIsland = false;

                for (int j = 3; j < trianglesNum; j += 3)
                {
                    if (triVisited[j])
                    {
                        continue;
                    }

                    if (currIsland.Contains(vertHash[j]) ||
                        currIsland.Contains(vertHash[j + 1]) ||
                        currIsland.Contains(vertHash[j + 2]))
                    {
                        currIsland.Add(vertHash[j]);
                        currIsland.Add(vertHash[j + 1]);
                        currIsland.Add(vertHash[j + 2]);

                        currIslandIdx.Add(j);
                        currIslandIdx.Add(j + 1);
                        currIslandIdx.Add(j + 2);

                        triVisited[j]     = true;
                        triVisited[j + 1] = true;
                        triVisited[j + 2] = true;

                        counter    += 3;
                        foundIsland = true;
                    }
                    else
                    {
                        lastInvalidIdx = j;
                    }
                }

                if (counter == trianglesNum)
                {
                    break;
                }

                if (!foundIsland)
                {
                    // create new island
                    currIsland = new HashSet <int> {
                        vertHash[lastInvalidIdx], vertHash[lastInvalidIdx + 1], vertHash[lastInvalidIdx + 2]
                    };
                    currIslandIdx = new List <int>(trianglesNum / 2)
                    {
                        lastInvalidIdx, lastInvalidIdx + 1, lastInvalidIdx + 2
                    };

                    islands.Add(currIsland);
                    islandsIdx.Add(currIslandIdx);
                }

                loopCounter++;
                if (loopCounter > 100)
                {
                    ExploderUtils.Log("10000 loop exceeded, islands: " + islands.Count);
                    break;
                }
            }

            var islandNum = islands.Count;

            ExploderUtils.Assert(islandNum >= 1, "No island found!");

            // no more than one islands
            if (islandNum == 1)
            {
                return(null);
            }

            var result = new List <CutterMesh>(islands.Count);

            foreach (var island in islandsIdx)
            {
                var cutterMesh = new CutterMesh {
                    mesh = new Mesh()
                };
                var triCount = island.Count;

                var m = cutterMesh.mesh;

                var tt = new List <int>(triCount);
                var vs = new List <Vector3>(triCount);
                var ns = new List <Vector3>(triCount);
                var us = new List <Vector2>(triCount);
                var cs = new List <Color32>(triCount);
                var ts = new List <Vector4>(triCount);

                var triCache        = new Dictionary <int, int>(trianglesNum);
                var centroid        = Vector3.zero;
                var centroidCounter = 0;
                var triCounter      = 0;

                foreach (var i in island)
                {
                    var tri = triangles[i];
                    var id  = 0;

                    if (triCache.TryGetValue(tri, out id))
                    {
                        tt.Add(id);
                        continue;
                    }

                    tt.Add(triCounter);
                    triCache.Add(tri, triCounter);
                    triCounter++;

                    centroid += vertices[tri];
                    centroidCounter++;

                    vs.Add(vertices[tri]);
                    us.Add(uvs[tri]);

                    if (useNormals)
                    {
                        ns.Add(normals[tri]);
                    }

                    if (useVertexColors)
                    {
                        cs.Add(colors[tri]);
                    }

                    if (useMeshTangents)
                    {
                        ts.Add(tangents[tri]);
                    }
                }

                m.vertices = vs.ToArray();
                m.uv       = us.ToArray();

                if (useNormals)
                {
                    m.normals = ns.ToArray();
                }
                if (useVertexColors)
                {
                    m.colors32 = cs.ToArray();
                }
                if (useMeshTangents)
                {
                    m.tangents = ts.ToArray();
                }

                m.triangles = tt.ToArray();

                cutterMesh.centroid = centroid / centroidCounter;

                result.Add(cutterMesh);
            }

            return(result);
        }
Example #3
0
        public void AllocateBuffers(int trianglesNum)
        {
            if (lsHash == null || lsHash.Capacity() < trianglesNum*2)
            {
            //                Utils.Log("Allocating contour: " + trianglesNum);

                midPoints = new ArrayDictionary<MidPoint>(trianglesNum * 2);
                contour = new List<Dictionary<int, int>>();
                lsHash = new LSHash(0.001f, trianglesNum * 2);
            }
            else
            {
                lsHash.Clear();
                foreach (var item in contour)
                {
                    item.Clear();
                }
                contour.Clear();

                if (midPoints.Size < trianglesNum*2)
                {
            //                    Utils.Log("Re-allocating midPoint: " + trianglesNum);

                    midPoints = new ArrayDictionary<MidPoint>(trianglesNum * 2);
                }
                else
                {
                    midPoints.Clear();
                }
            }
        }