From 22cff037060de442c96c6336142490c582269107 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Sun, 20 Aug 2023 01:38:56 +0900 Subject: [PATCH 1/3] chore: MeshInfoComputer returns BlendShape weight --- Editor/EditSkinnedMeshComponentUtil.cs | 12 ++++++------ Editor/FreezeBlendShapeEditor.cs | 6 +++--- .../SkinnedMeshes/EditSkinnedMeshProcessor.cs | 10 +++++----- .../FreezeBlendShapeProcessor.cs | 4 ++-- .../MergeSkinnedMeshProcessor.cs | 19 +++++++++++++++++-- .../RemoveMeshByBlendShapeProcessor.cs | 4 ++-- .../SkinnedMeshes/RemoveMeshInBoxProcessor.cs | 10 +--------- Editor/RemoveMeshByBlendShapeEditor.cs | 6 +++--- 8 files changed, 39 insertions(+), 32 deletions(-) diff --git a/Editor/EditSkinnedMeshComponentUtil.cs b/Editor/EditSkinnedMeshComponentUtil.cs index 0e71a63c9..90df5dd73 100644 --- a/Editor/EditSkinnedMeshComponentUtil.cs +++ b/Editor/EditSkinnedMeshComponentUtil.cs @@ -43,9 +43,9 @@ private static void OnDestroy(EditSkinnedMeshComponent component) public static bool IsModifiedByEditComponent(SkinnedMeshRenderer renderer) => EditorShared.IsModifiedByEditComponent(renderer); - public static string[] GetBlendShapes(SkinnedMeshRenderer renderer) => EditorShared.GetBlendShapes(renderer); + public static (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer) => EditorShared.GetBlendShapes(renderer); - public static string[] GetBlendShapes(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before) => + public static (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before) => EditorShared.GetBlendShapes(renderer, before); public static Material[] GetMaterials(SkinnedMeshRenderer renderer) => EditorShared.GetMaterials(renderer); @@ -81,9 +81,9 @@ public bool IsModifiedByEditComponent(SkinnedMeshRenderer renderer) => readonly Dictionary ProcessorsByRenderer = new Dictionary(); - public string[] GetBlendShapes(SkinnedMeshRenderer renderer) => GetBlendShapes(renderer, null); + public (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer) => GetBlendShapes(renderer, null); - public string[] GetBlendShapes(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before) => + public (string name, float weight)[] GetBlendShapes(SkinnedMeshRenderer renderer, EditSkinnedMeshComponent before) => GetProcessors(renderer)?.GetBlendShapes(before) ?? SourceMeshInfoComputer.BlendShapes(renderer); public Material[] GetMaterials(SkinnedMeshRenderer renderer) => GetMaterials(renderer, null); @@ -185,7 +185,7 @@ private IMeshInfoComputer GetComputer(EditSkinnedMeshComponent before = null) => ? GetComputers().Last() : GetComputers()[_sorted.FindIndex(x => x.Component == before)]; - public string[] GetBlendShapes(EditSkinnedMeshComponent before = null) => GetComputer(before).BlendShapes(); + public (string, float)[] GetBlendShapes(EditSkinnedMeshComponent before = null) => GetComputer(before).BlendShapes(); public Material[] GetMaterials(EditSkinnedMeshComponent before = null, bool fast = true) => GetComputer(before).Materials(fast); @@ -218,7 +218,7 @@ private T CheckRecursive(Func compute) } } - public string[] BlendShapes() => CheckRecursive(() => _origin.BlendShapes()); + public (string, float)[] BlendShapes() => CheckRecursive(() => _origin.BlendShapes()); public Material[] Materials(bool fast = true) => CheckRecursive(() => _origin.Materials(fast)); } } diff --git a/Editor/FreezeBlendShapeEditor.cs b/Editor/FreezeBlendShapeEditor.cs index c5f23886f..ae3344a74 100644 --- a/Editor/FreezeBlendShapeEditor.cs +++ b/Editor/FreezeBlendShapeEditor.cs @@ -28,7 +28,7 @@ protected override void OnInspectorGUIInner() var label = new GUIContent(); serializedObject.Update(); - foreach (var shapeKeyName in shapes) + foreach (var (shapeKeyName, _) in shapes) { var rect = EditorGUILayout.GetControlRect(); label.text = shapeKeyName; @@ -41,13 +41,13 @@ protected override void OnInspectorGUIInner() { if (GUILayout.Button(CL4EE.Tr("FreezeBlendShape:button:Check All"))) { - foreach (var shapeKeyName in shapes) + foreach (var (shapeKeyName, _) in shapes) _shapeKeysSet.GetElementOf(shapeKeyName).EnsureAdded(); } if (GUILayout.Button(CL4EE.Tr("FreezeBlendShape:button:Invert All"))) { - foreach (var shapeKeyName in shapes) + foreach (var (shapeKeyName, _) in shapes) { var element = _shapeKeysSet.GetElementOf(shapeKeyName); if (element.Contains) element.EnsureRemoved(); diff --git a/Editor/Processors/SkinnedMeshes/EditSkinnedMeshProcessor.cs b/Editor/Processors/SkinnedMeshes/EditSkinnedMeshProcessor.cs index 3d8162e0f..c227e4e66 100644 --- a/Editor/Processors/SkinnedMeshes/EditSkinnedMeshProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/EditSkinnedMeshProcessor.cs @@ -49,7 +49,7 @@ internal interface IEditSkinnedMeshProcessor internal interface IMeshInfoComputer { - string[] BlendShapes(); + (string name, float weight)[] BlendShapes(); Material[] Materials(bool fast = true); } @@ -62,7 +62,7 @@ public AbstractMeshInfoComputer(IMeshInfoComputer upstream) _upstream = upstream; } - public virtual string[] BlendShapes() => _upstream?.BlendShapes() ?? Array.Empty(); + public virtual (string name, float weight)[] BlendShapes() => _upstream?.BlendShapes() ?? Array.Empty<(string, float)>(); public virtual Material[] Materials(bool fast = true) => _upstream?.Materials(fast) ?? Array.Empty(); } @@ -75,14 +75,14 @@ internal class SourceMeshInfoComputer : IMeshInfoComputer public SourceMeshInfoComputer(SkinnedMeshRenderer target) => _target = target; - public static string[] BlendShapes(SkinnedMeshRenderer renderer) => Enumerable + public static (string, float)[] BlendShapes(SkinnedMeshRenderer renderer) => Enumerable .Range(0, renderer.sharedMesh.blendShapeCount) - .Select(i => renderer.sharedMesh.GetBlendShapeName(i)) + .Select(i => (renderer.sharedMesh.GetBlendShapeName(i), renderer.GetBlendShapeWeight(i))) .ToArray(); public static Material[] Materials(SkinnedMeshRenderer renderer) => renderer.sharedMaterials; - public string[] BlendShapes() => BlendShapes(_target); + public (string, float)[] BlendShapes() => BlendShapes(_target); public Material[] Materials(bool fast = true) => Materials(_target); } } diff --git a/Editor/Processors/SkinnedMeshes/FreezeBlendShapeProcessor.cs b/Editor/Processors/SkinnedMeshes/FreezeBlendShapeProcessor.cs index 6a2d5860e..24c796c50 100644 --- a/Editor/Processors/SkinnedMeshes/FreezeBlendShapeProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/FreezeBlendShapeProcessor.cs @@ -79,10 +79,10 @@ class MeshInfoComputer : AbstractMeshInfoComputer public MeshInfoComputer(FreezeBlendShapeProcessor processor, IMeshInfoComputer upstream) : base(upstream) => _processor = processor; - public override string[] BlendShapes() + public override (string, float)[] BlendShapes() { var set = _processor.Component.FreezingShapeKeys; - return base.BlendShapes().Where(x => !set.Contains(x)).ToArray(); + return base.BlendShapes().Where(x => !set.Contains(x.name)).ToArray(); } } } diff --git a/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs b/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs index 09c465735..a1b91f697 100644 --- a/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs @@ -181,10 +181,10 @@ class MeshInfoComputer : IMeshInfoComputer public MeshInfoComputer(MergeSkinnedMeshProcessor processor) => _processor = processor; - public string[] BlendShapes() => + public (string, float)[] BlendShapes() => _processor.Component.renderersSet.GetAsList() .SelectMany(EditSkinnedMeshComponentUtil.GetBlendShapes) - .Distinct() + .Distinct(BlendShapeNameComparator.Instance) .ToArray(); public Material[] Materials(bool fast = true) @@ -197,6 +197,21 @@ public Material[] Materials(bool fast = true) .materials .ToArray(); } + + private class BlendShapeNameComparator : IEqualityComparer<(string name, float weight)> + { + public static readonly BlendShapeNameComparator Instance = new BlendShapeNameComparator(); + + public bool Equals((string name, float weight) x, (string name, float weight) y) + { + return x.name == y.name; + } + + public int GetHashCode((string name, float weight) obj) + { + return obj.name?.GetHashCode() ?? 0; + } + } } } } diff --git a/Editor/Processors/SkinnedMeshes/RemoveMeshByBlendShapeProcessor.cs b/Editor/Processors/SkinnedMeshes/RemoveMeshByBlendShapeProcessor.cs index 09c3c7cab..6e9a1acfb 100644 --- a/Editor/Processors/SkinnedMeshes/RemoveMeshByBlendShapeProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/RemoveMeshByBlendShapeProcessor.cs @@ -63,10 +63,10 @@ class MeshInfoComputer : AbstractMeshInfoComputer public MeshInfoComputer(RemoveMeshByBlendShapeProcessor processor, IMeshInfoComputer upstream) : base(upstream) => _processor = processor; - public override string[] BlendShapes() + public override (string, float)[] BlendShapes() { var set = _processor.Component.RemovingShapeKeys; - return base.BlendShapes().Where(x => !set.Contains(x)).ToArray(); + return base.BlendShapes().Where(x => !set.Contains(x.name)).ToArray(); } } } diff --git a/Editor/Processors/SkinnedMeshes/RemoveMeshInBoxProcessor.cs b/Editor/Processors/SkinnedMeshes/RemoveMeshInBoxProcessor.cs index ff84c13e1..6780969de 100644 --- a/Editor/Processors/SkinnedMeshes/RemoveMeshInBoxProcessor.cs +++ b/Editor/Processors/SkinnedMeshes/RemoveMeshInBoxProcessor.cs @@ -58,14 +58,6 @@ public override void Process(OptimizerSession session, MeshInfo2 target, MeshInf target.Vertices.RemoveAll(x => !usingVertices.Contains(x)); } - public override IMeshInfoComputer GetComputer(IMeshInfoComputer upstream) => new MeshInfoComputer(this, upstream); - - class MeshInfoComputer : AbstractMeshInfoComputer - { - private readonly RemoveMeshInBoxProcessor _processor; - - public MeshInfoComputer(RemoveMeshInBoxProcessor processor, IMeshInfoComputer upstream) : base(upstream) - => _processor = processor; - } + public override IMeshInfoComputer GetComputer(IMeshInfoComputer upstream) => upstream; } } diff --git a/Editor/RemoveMeshByBlendShapeEditor.cs b/Editor/RemoveMeshByBlendShapeEditor.cs index 579aaaebe..41564f66f 100644 --- a/Editor/RemoveMeshByBlendShapeEditor.cs +++ b/Editor/RemoveMeshByBlendShapeEditor.cs @@ -32,7 +32,7 @@ protected override void OnInspectorGUIInner() var label = new GUIContent(); - foreach (var shapeKeyName in shapes) + foreach (var (shapeKeyName, _) in shapes) { var rect = EditorGUILayout.GetControlRect(); label.text = shapeKeyName; @@ -45,13 +45,13 @@ protected override void OnInspectorGUIInner() { if (GUILayout.Button(CL4EE.Tr("RemoveMeshByBlendShape:button:Check All"))) { - foreach (var shapeKeyName in shapes) + foreach (var (shapeKeyName, _) in shapes) _shapeKeysSet.GetElementOf(shapeKeyName).EnsureAdded(); } if (GUILayout.Button(CL4EE.Tr("RemoveMeshByBlendShape:button:Invert All"))) { - foreach (var shapeKeyName in shapes) + foreach (var (shapeKeyName, _) in shapes) { var element = _shapeKeysSet.GetElementOf(shapeKeyName); if (element.Contains) element.EnsureRemoved(); From 4de72e14faf81c3d9c4c58c762b25a4af3ff9584 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Sun, 20 Aug 2023 02:05:35 +0900 Subject: [PATCH 2/3] chore: add warning about weight difference --- Editor/MergeSkinnedMeshEditor.cs | 22 +++++++++++++++++++--- Localization/en.po | 7 ++++++- Localization/ja.po | 5 +++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/Editor/MergeSkinnedMeshEditor.cs b/Editor/MergeSkinnedMeshEditor.cs index b3c7c0288..a1bbd9344 100644 --- a/Editor/MergeSkinnedMeshEditor.cs +++ b/Editor/MergeSkinnedMeshEditor.cs @@ -30,9 +30,17 @@ static MergeSkinnedMeshEditor() { ComponentValidation.RegisterValidator(component => { + var err = new List(); if (component.GetComponent().sharedMesh) - return new[] { ErrorLog.Warning("MergeSkinnedMesh:warning:MeshIsNotNone") }; - return null; + err.Add(ErrorLog.Warning("MergeSkinnedMesh:warning:MeshIsNotNone")); + + err.AddRange(component.renderersSet.GetAsSet() + .SelectMany(EditSkinnedMeshComponentUtil.GetBlendShapes) + .GroupBy(x => x.name, x => x.weight) + .Where(grouping => grouping.Distinct().Count() != 1) + .Select(grouping => ErrorLog.Warning("MergeSkinnedMesh:warning:blendShapeWeightMismatch", grouping.Key))); + + return err; }); } @@ -56,10 +64,18 @@ private void OnEnable() protected override void OnInspectorGUIInner() { - if (((MergeSkinnedMesh)target).GetComponent().sharedMesh) + var component = (MergeSkinnedMesh)target; + if (component.GetComponent().sharedMesh) { EditorGUILayout.HelpBox(CL4EE.Tr("MergeSkinnedMesh:warning:MeshIsNotNone"), MessageType.Warning); } + + foreach (var grouping in component.renderersSet.GetAsSet() + .SelectMany(EditSkinnedMeshComponentUtil.GetBlendShapes) + .GroupBy(x => x.name, x => x.weight) + .Where(grouping => grouping.Distinct().Count() != 1)) + EditorGUILayout.HelpBox(string.Format(CL4EE.Tr("MergeSkinnedMesh:warning:blendShapeWeightMismatch"), grouping.Key), + MessageType.Warning); EditorGUILayout.PropertyField(_renderersSetProp); EditorGUILayout.PropertyField(_staticRenderersSetProp); diff --git a/Localization/en.po b/Localization/en.po index d7faf772e..b0a6157c7 100644 --- a/Localization/en.po +++ b/Localization/en.po @@ -214,9 +214,14 @@ msgstr "Components" # region MergeSkinnedMesh +msgid "MergeSkinnedMesh:warning:blendShapeWeightMismatch" +msgstr "" +"Some weights of BlendShape '{0}' of some source SkinnedMeshRenderer are not same value.\n" +"In this case, the weight of final SkinnedMeshRenderer is not defined so please make uniform weight or freeze BlendShape." + msgid "MergeSkinnedMesh:warning:MeshIsNotNone" msgstr "" -""Mesh of SkinnedMeshRenderer is not None!\n" +"Mesh of SkinnedMeshRenderer is not None!\n" "You should add MergeSkinnedMesh onto new GameObject with new SkinnedMeshRenderer!" msgid "MergeSkinnedMesh:prop:renderers" diff --git a/Localization/ja.po b/Localization/ja.po index 4ed4d2895..1f0c09083 100644 --- a/Localization/ja.po +++ b/Localization/ja.po @@ -151,6 +151,11 @@ msgstr "コンポーネント" # region MergeSkinnedMesh +msgid "MergeSkinnedMesh:warning:blendShapeWeightMismatch" +msgstr "" +"マージ元のSkinnedMeshRendererのBlendShape '{0}'のWeightが揃っていません。\n" +"複数のWeightのうちどのWeightが適用されるかが不定であるためWeightを揃えるか固定・削除してください。" + msgid "MergeSkinnedMesh:warning:MeshIsNotNone" msgstr "" "SkinnedMeshRendererのMeshがNoneではありません!\n" From d53e8598a6add6d659f60206dd1b4d0ed7f40b63 Mon Sep 17 00:00:00 2001 From: anatawa12 Date: Sun, 20 Aug 2023 02:13:55 +0900 Subject: [PATCH 3/3] docs(changelog): add There is no warning about BlendShape weight difference --- CHANGELOG-PRERELEASE.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG-PRERELEASE.md b/CHANGELOG-PRERELEASE.md index f88a5de48..74e934685 100644 --- a/CHANGELOG-PRERELEASE.md +++ b/CHANGELOG-PRERELEASE.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog]. ### Fixed - Unity Editor may freezes when there are circular dependency `#329` +- There is no warning about BlendShape weight difference `#336` ### Security diff --git a/CHANGELOG.md b/CHANGELOG.md index 37383bb75..5a6c6614f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog]. ### Fixed - Unity Editor may freezes when there are circular dependency `#329` +- There is no warning about BlendShape weight difference `#336` ### Security