예제 #1
0
        private static int MergeDuplicatePositions(IList <Vector3F> positions, float positionTolerance, int[] positionRemap)
        {
            Debug.Assert(positions != null);
            Debug.Assert(positions.Count > 0);
            Debug.Assert(positionTolerance > 0);
            Debug.Assert(positionRemap == null || positionRemap.Length == positions.Count);

            // Create working data.
            int numberOfVertices = positions.Count;
            var data             = new WeldVertex[numberOfVertices];

            for (int i = 0; i < numberOfVertices; i++)
            {
                Vector3F position = positions[i];
                data[i].Position      = position;
                data[i].OriginalIndex = i;
                data[i].SortValue     = Math.Abs(position.X) + Math.Abs(position.Y) + Math.Abs(position.Z);
                data[i].MergedIndex   = -1;
            }

            // Sort positions by absolute component sum of position |X|+|Y|+|Z|.
            Array.Sort(data, WeldVertex.CompareSortValue);

            int numberOfMergedVertices = 0;

            // Loop over positions. Try to merge each vertex with the next positions in the array.
            for (int i = 0; i < numberOfVertices; i++)
            {
                // For positions that have already been merged, the index was set to > -1.
                if (data[i].MergedIndex >= 0)
                {
                    // Vertex is a duplicate. - Nothing to do.
                    continue;
                }

                // Now, we compare vertex i against the next positions in the array.
                for (int j = i + 1; j < numberOfVertices; j++)
                {
                    // We can stop comparing if the SortValue differs by more than 3 * epsilon.
                    if (data[j].SortValue - data[i].SortValue > 3 * positionTolerance)
                    {
                        break;
                    }

                    //if (Vector3F.AreNumericallyEqual(data[i].Position, data[j].Position, positionTolerance))
                    // Optimized version: (Probably does not work for infinite float values!)
                    float delta = Math.Abs(data[i].Position.X - data[j].Position.X);
                    if (delta <= positionTolerance)
                    {
                        delta = Math.Abs(data[i].Position.Y - data[j].Position.Y);
                        if (delta <= positionTolerance)
                        {
                            delta = Math.Abs(data[i].Position.Z - data[j].Position.Z);
                            if (delta <= positionTolerance)
                            {
                                // Vertex positions are near each other and should be merged.
                                numberOfMergedVertices++;
                                data[j].MergedIndex = data[i].OriginalIndex;
                            }
                        }
                    }
                }
            }

            if (numberOfMergedVertices == 0)
            {
                return(0);
            }

            // Sort by original index.
            Array.Sort(data, WeldVertex.CompareOriginalIndex);

            // Rebuild positions (omitting the merged positions).
            positions.Clear();
            if (positionRemap == null)
            {
                for (int i = 0; i < numberOfVertices; i++)
                {
                    if (data[i].MergedIndex < 0)
                    {
                        positions.Add(data[i].Position);
                    }
                }
            }
            else
            {
                // Rebuild positions and at the same time we fill the position remap table.
                for (int i = 0; i < numberOfVertices; i++)
                {
                    if (data[i].MergedIndex < 0)
                    {
                        positionRemap[i] = positions.Count;
                        positions.Add(data[i].Position);
                    }
                    else
                    {
                        positionRemap[i] = -1;
                    }
                }

                // Now, fill in the other entries in the index redirection table.
                for (int i = 0; i < numberOfVertices; i++)
                {
                    if (data[i].MergedIndex >= 0)
                    {
                        positionRemap[i] = positionRemap[data[i].MergedIndex];
                    }

                    Debug.Assert(positionRemap[i] != -1);
                }
            }

            return(numberOfMergedVertices);
        }
예제 #2
0
 public static int CompareOriginalIndex(WeldVertex v0, WeldVertex v1)
 {
     return(v0.OriginalIndex.CompareTo(v1.OriginalIndex));
 }
예제 #3
0
            public int      MergedIndex;   // >= 0 if this vertex was merged.

            public static int CompareSortValue(WeldVertex v0, WeldVertex v1)
            {
                return(v0.SortValue.CompareTo(v1.SortValue));
            }
예제 #4
0
 public static int CompareSortValue(WeldVertex v0, WeldVertex v1)
 {
     return v0.SortValue.CompareTo(v1.SortValue);
 }
예제 #5
0
            public float SortValue; // Absolute component sum of position: |X|+|Y|+|Z|

            #endregion Fields

            #region Methods

            public static int CompareOriginalIndex(WeldVertex v0, WeldVertex v1)
            {
                return v0.OriginalIndex.CompareTo(v1.OriginalIndex);
            }
예제 #6
0
        private static int MergeDuplicatePositions(IList<Vector3F> positions, float positionTolerance, int[] positionRemap)
        {
            Debug.Assert(positions != null);
              Debug.Assert(positions.Count > 0);
              Debug.Assert(positionTolerance > 0);
              Debug.Assert(positionRemap == null || positionRemap.Length == positions.Count);

              // Create working data.
              int numberOfVertices = positions.Count;
              var data = new WeldVertex[numberOfVertices];
              for (int i = 0; i < numberOfVertices; i++)
              {
            Vector3F position = positions[i];
            data[i].Position = position;
            data[i].OriginalIndex = i;
            data[i].SortValue = Math.Abs(position.X) + Math.Abs(position.Y) + Math.Abs(position.Z);
            data[i].MergedIndex = -1;
              }

              // Sort positions by absolute component sum of position |X|+|Y|+|Z|.
              Array.Sort(data, WeldVertex.CompareSortValue);

              int numberOfMergedVertices = 0;

              // Loop over positions. Try to merge each vertex with the next positions in the array.
              for (int i = 0; i < numberOfVertices; i++)
              {
            // For positions that have already been merged, the index was set to > -1.
            if (data[i].MergedIndex >= 0)
            {
              // Vertex is a duplicate. - Nothing to do.
              continue;
            }

            // Now, we compare vertex i against the next positions in the array.
            for (int j = i + 1; j < numberOfVertices; j++)
            {
              // We can stop comparing if the SortValue differs by more than 3 * epsilon.
              if (data[j].SortValue - data[i].SortValue > 3 * positionTolerance)
            break;

              //if (Vector3F.AreNumericallyEqual(data[i].Position, data[j].Position, positionTolerance))
              // Optimized version: (Probably does not work for infinite float values!)
              float delta = Math.Abs(data[i].Position.X - data[j].Position.X);
              if (delta <= positionTolerance)
              {
            delta = Math.Abs(data[i].Position.Y - data[j].Position.Y);
            if (delta <= positionTolerance)
            {
              delta = Math.Abs(data[i].Position.Z - data[j].Position.Z);
              if (delta <= positionTolerance)
              {
                // Vertex positions are near each other and should be merged.
                numberOfMergedVertices++;
                data[j].MergedIndex = data[i].OriginalIndex;
              }
            }
              }
            }
              }

              if (numberOfMergedVertices == 0)
            return 0;

              // Sort by original index.
              Array.Sort(data, WeldVertex.CompareOriginalIndex);

              // Rebuild positions (omitting the merged positions).
              positions.Clear();
              if (positionRemap == null)
              {
            for (int i = 0; i < numberOfVertices; i++)
              if (data[i].MergedIndex < 0)
            positions.Add(data[i].Position);
              }
              else
              {
            // Rebuild positions and at the same time we fill the position remap table.
            for (int i = 0; i < numberOfVertices; i++)
            {
              if (data[i].MergedIndex < 0)
              {
            positionRemap[i] = positions.Count;
            positions.Add(data[i].Position);
              }
              else
              {
            positionRemap[i] = -1;
              }
            }

            // Now, fill in the other entries in the index redirection table.
            for (int i = 0; i < numberOfVertices; i++)
            {
              if (data[i].MergedIndex >= 0)
            positionRemap[i] = positionRemap[data[i].MergedIndex];

              Debug.Assert(positionRemap[i] != -1);
            }
              }

              return numberOfMergedVertices;
        }