Kaynağa Gözat

Added renaming utilities

Vicente Penades 6 yıl önce
ebeveyn
işleme
e704771a84

+ 46 - 0
src/SharpGLTF.Core/Schema2/gltf.LogicalChildOfRoot.cs

@@ -55,6 +55,52 @@ namespace SharpGLTF.Schema2
             LogicalParent.UsingExtension(this.GetType(), extensionType);
         }
 
+        /// <summary>
+        /// Renames all the unnamed and duplicate name items in the collection so all the items have a unique valid name.
+        /// </summary>
+        /// <typeparam name="T">Any <see cref="LogicalChildOfRoot"/> derived type.</typeparam>
+        /// <param name="collection">The source collection.</param>
+        /// <param name="namePrefix">The name prefix to use.</param>
+        public static void RenameLogicalElements<T>(IEnumerable<T> collection, string namePrefix)
+            where T : LogicalChildOfRoot
+        {
+            if (collection == null) return;
+
+            var names = new HashSet<string>();
+            var index = -1;
+
+            foreach (var item in collection)
+            {
+                ++index;
+
+                // if the current name is already valid, keep it.
+                if (!string.IsNullOrWhiteSpace(item.Name))
+                {
+                    if (item.RenameIfAvailable(item.Name, names)) continue;
+                }
+
+                // try with a default name
+                var newName = $"{namePrefix}{index}";
+                if (item.RenameIfAvailable(newName, names)) continue;
+
+                // retry with different names until finding a valid name.
+                for (int i = 0; i < int.MaxValue; ++i)
+                {
+                    newName = $"{namePrefix}{index}-{i}";
+
+                    if (item.RenameIfAvailable(newName, names)) break;
+                }
+            }
+        }
+
+        private bool RenameIfAvailable(string newName, ISet<string> usedNames)
+        {
+            if (usedNames.Contains(newName)) return false;
+            this.Name = newName;
+            usedNames.Add(newName);
+            return true;
+        }
+
         #endregion
     }
 }

+ 32 - 17
src/SharpGLTF.Toolkit/Scenes/NodeBuilder.cs

@@ -169,36 +169,51 @@ namespace SharpGLTF.Scenes
             }
         }
 
-        public static void SetUniqueNames(NodeBuilder root)
+        /// <summary>
+        /// Rename all the <see cref="NodeBuilder"/> elements in <paramref name="collection"/>
+        /// so every node has a valid, unique name.
+        /// </summary>
+        /// <param name="collection">A collection of <see cref="NodeBuilder"/> elements.</param>
+        /// <param name="namePrefix">The name prefix.</param>
+        public static void Rename(IEnumerable<NodeBuilder> collection, string namePrefix)
         {
-            var nodes = Flatten(root).ToList();
+            if (collection == null) return;
 
             var names = new HashSet<string>();
+            var index = -1;
 
-            var ncount = 0;
-
-            foreach (var n in nodes)
+            foreach (var item in collection)
             {
-                if (!string.IsNullOrWhiteSpace(n.Name) && !names.Contains(n.Name))
+                ++index;
+
+                // if the current name is already valid, keep it.
+                if (!string.IsNullOrWhiteSpace(item.Name))
                 {
-                    names.Add(n.Name);
-                    continue;
+                    if (item.RenameIfAvailable(item.Name, names)) continue;
                 }
 
-                while (true)
+                // try with a default name
+                var newName = $"{namePrefix}{index}";
+                if (item.RenameIfAvailable(newName, names)) continue;
+
+                // retry with different names until finding a valid name.
+                for (int i = 0; i < int.MaxValue; ++i)
                 {
-                    var newName = $"Node{ncount++}";
-
-                    if (!names.Contains(newName))
-                    {
-                        n.Name = newName;
-                        names.Add(n.Name);
-                        break;
-                    }
+                    newName = $"{namePrefix}{index}-{i}";
+
+                    if (item.RenameIfAvailable(newName, names)) break;
                 }
             }
         }
 
+        private bool RenameIfAvailable(string newName, ISet<string> usedNames)
+        {
+            if (usedNames.Contains(newName)) return false;
+            this.Name = newName;
+            usedNames.Add(newName);
+            return true;
+        }
+
         #endregion
 
         #region API - transform

+ 13 - 0
src/SharpGLTF.Toolkit/Scenes/SceneBuilder.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Numerics;
 using System.Text;
 
@@ -83,6 +84,18 @@ namespace SharpGLTF.Scenes
             return instance;
         }
 
+        public void RenameAllNodes(string namePrefix)
+        {
+            var allNodes = Instances
+                .Select(item => item.Content.GetArmatureAsset())
+                .Where(item => item != null)
+                .SelectMany(item => NodeBuilder.Flatten(item))
+                .Distinct()
+                .ToList();
+
+            NodeBuilder.Rename(allNodes, namePrefix);
+        }
+
         #endregion
     }
 }