Exemplo n.º 1
0
        /// <summary>
        /// Merge vertices with the same <see cref="VertexContent.PositionIndices"/> and
        /// <see cref="VertexChannel"/> data within the specified
        /// <see cref="GeometryContent"/>.
        /// </summary>
        /// <param name="geometry">Geometry to be processed.</param>
        public static void MergeDuplicateVertices(GeometryContent geometry)
        {
            if (geometry == null)
            {
                throw new ArgumentNullException("geometry");
            }

            var verts   = geometry.Vertices;
            var hashMap = new Dictionary <int, List <VertexData> >();

            var indices = new IndexUpdateList(geometry.Indices);
            var vIndex  = 0;

            for (var i = 0; i < geometry.Indices.Count; i++)
            {
                var iIndex = geometry.Indices[i];
                var iData  = new VertexData
                {
                    Index         = iIndex,
                    PositionIndex = verts.PositionIndices[vIndex],
                    ChannelData   = new object[verts.Channels.Count]
                };

                for (var channel = 0; channel < verts.Channels.Count; channel++)
                {
                    iData.ChannelData[channel] = verts.Channels[channel][vIndex];
                }

                var hash = iData.ComputeHash();

                var merged = false;
                List <VertexData> candidates;
                if (hashMap.TryGetValue(hash, out candidates))
                {
                    for (var candidateIndex = 0; candidateIndex < candidates.Count; candidateIndex++)
                    {
                        var c = candidates[candidateIndex];
                        if (!iData.ContentEquals(c))
                        {
                            continue;
                        }

                        // Match! Update the corresponding indices and remove the vertex
                        indices.Update(iIndex, c.Index);
                        verts.RemoveAt(vIndex);
                        merged = true;
                    }
                    if (!merged)
                    {
                        candidates.Add(iData);
                    }
                }
                else
                {
                    // no vertices with the same hash yet, create a new list for the data
                    hashMap.Add(hash, new List <VertexData> {
                        iData
                    });
                }

                if (!merged)
                {
                    vIndex++;
                }
            }

            // update the indices because of the vertices we removed
            indices.Pack();
        }