Skip to content

Commit

Permalink
feat: RemoveMeshByMaterial
Browse files Browse the repository at this point in the history
  • Loading branch information
bdunderscore committed Nov 29, 2024
1 parent 41e2cc7 commit 8cbed0b
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 1 deletion.
57 changes: 57 additions & 0 deletions Editor/EditModePreview/RemoveMeshByMaterialFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using nadena.dev.ndmf;
using nadena.dev.ndmf.preview;
using UnityEngine;

namespace Anatawa12.AvatarOptimizer.EditModePreview
{
internal class RemoveMeshByMaterialRenderFilter : AAORenderFilterBase<RemoveMeshByMaterial>
{
private RemoveMeshByMaterialRenderFilter() : base("Remove Mesh by Material", "remove-mesh-by-material")
{
}

public static RemoveMeshByMaterialRenderFilter Instance { get; } = new();
protected override AAORenderFilterNodeBase<RemoveMeshByMaterial> CreateNode() => new RemoveMeshByMaterialRendererNode();
protected override bool SupportsMultiple() => false;
}

internal class RemoveMeshByMaterialRendererNode : AAORenderFilterNodeBase<RemoveMeshByMaterial>
{
protected override ValueTask Process(
SkinnedMeshRenderer original,
SkinnedMeshRenderer proxy,
RemoveMeshByMaterial[] components,
Mesh duplicated,
ComputeContext context
)
{
HashSet<ObjectReference> toRemove = new();
foreach (var component in components)
{
var materials = context.Observe(component, c => c.Materials.ToImmutableList());
foreach (var material in materials)
{
toRemove.Add(ObjectRegistry.GetReference(material));
}
}

var actualMaterials = proxy.sharedMaterials ?? Array.Empty<Material>();
for (int i = 0; i < actualMaterials.Length; i++)
{
var mat = actualMaterials[i];
if (mat == null || !toRemove.Contains(ObjectRegistry.GetReference(mat))) continue;

var submesh = duplicated.GetSubMesh(i);
submesh.indexCount = 0;
duplicated.SetSubMesh(i, submesh);
}

return default;
}
}
}
3 changes: 3 additions & 0 deletions Editor/EditModePreview/RemoveMeshByMaterialFilter.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Editor/EditSkinnedMeshComponentUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ private T CheckRecursive<T>(Func<T> compute)
[typeof(MergeSkinnedMesh)] = x => new MergeSkinnedMeshProcessor((MergeSkinnedMesh)x),
[typeof(FreezeBlendShape)] = x => new FreezeBlendShapeProcessor((FreezeBlendShape)x),
[typeof(MergeToonLitMaterial)] = x => new MergeToonLitMaterialProcessor((MergeToonLitMaterial)x),
[typeof(RemoveMeshByMaterial)] = x => new RemoveMeshByMaterialProcessor((RemoveMeshByMaterial)x),
[typeof(RemoveMeshInBox)] = x => new RemoveMeshInBoxProcessor((RemoveMeshInBox)x),
[typeof(RemoveMeshByBlendShape)] = x => new RemoveMeshByBlendShapeProcessor((RemoveMeshByBlendShape)x),
[typeof(RemoveMeshByMask)] = x => new RemoveMeshByMaskProcessor((RemoveMeshByMask)x),
Expand Down
2 changes: 1 addition & 1 deletion Editor/Inspector/AvatarTagComponentEditorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Anatawa12.AvatarOptimizer
{
abstract class AvatarTagComponentEditorBase : Editor
public abstract class AvatarTagComponentEditorBase : Editor
{
public sealed override void OnInspectorGUI()
{
Expand Down
13 changes: 13 additions & 0 deletions Editor/Inspector/RemoveMeshByMaterialEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using UnityEditor;

namespace Anatawa12.AvatarOptimizer;

[CustomEditor(typeof(RemoveMeshByMaterial))]
public class RemoveMeshByMaterialEditor : AvatarTagComponentEditorBase
{
// TODO
protected override void OnInspectorGUIInner()
{
DrawDefaultInspector();
}
}
3 changes: 3 additions & 0 deletions Editor/Inspector/RemoveMeshByMaterialEditor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Editor/OptimizerPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ protected override void Configure()
.Then.Run(Processors.MergePhysBoneProcessor.Instance)
#endif
.Then.Run(Processors.EditSkinnedMeshComponentProcessor.Instance)
.PreviewingWith(EditModePreview.RemoveMeshByMaterialRenderFilter.Instance)
.PreviewingWith(EditModePreview.RemoveMeshByMaskRenderFilter.Instance)
.PreviewingWith(EditModePreview.RemoveMeshByBlendShapeRenderFilter.Instance)
.PreviewingWith(EditModePreview.RemoveMeshInBoxRenderFilter.Instance)
Expand Down
35 changes: 35 additions & 0 deletions Editor/Processors/SkinnedMeshes/RemoveMeshByMaterialProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using nadena.dev.ndmf;
using UnityEngine;

namespace Anatawa12.AvatarOptimizer.Processors.SkinnedMeshes;

internal class RemoveMeshByMaterialProcessor : EditSkinnedMeshProcessor<RemoveMeshByMaterial>
{
public RemoveMeshByMaterialProcessor(RemoveMeshByMaterial component) : base(component)
{
}

public override EditSkinnedMeshProcessorOrder ProcessOrder => EditSkinnedMeshProcessorOrder.RemovingMesh;
public override void Process(BuildContext context, MeshInfo2 target)
{
var submeshes = target.SubMeshes;
var toDeleteMats = new HashSet<ObjectReference>(Component.Materials.Select(m => ObjectRegistry.GetReference(m)));
Renderer renderer = Component.GetComponent<Renderer>();
var actualMats = renderer.sharedMaterials ?? Array.Empty<Material>();

for (int i = 0; i < submeshes.Count; i++)
{
if (i < actualMats.Length && toDeleteMats.Contains(ObjectRegistry.GetReference(actualMats[i])))
{
submeshes[i].RemovePrimitives("RemoveMeshByMaterial", v => true);
}
}

target.RemoveUnusedVertices();
}

public override IMeshInfoComputer GetComputer(IMeshInfoComputer upstream) => upstream;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 68 additions & 0 deletions Runtime/RemoveMeshByMaterial.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using JetBrains.Annotations;
using UnityEngine;

namespace Anatawa12.AvatarOptimizer
{
[AddComponentMenu("Avatar Optimizer/AAO Remove Mesh By Material")]
[RequireComponent(typeof(SkinnedMeshRenderer))]
[AllowMultipleComponent]
[HelpURL("https://vpm.anatawa12.com/avatar-optimizer/ja/docs/reference/remove-mesh-by-material/")]
[PublicAPI]
public class RemoveMeshByMaterial : EditSkinnedMeshComponent, ISerializationCallbackReceiver
{
[SerializeField] internal PrefabSafeSet.PrefabSafeSet<Material> materials;

internal RemoveMeshByMaterial()
{
materials = new PrefabSafeSet.PrefabSafeSet<Material>(this);
}

private void ValidatePSUC()
{
PrefabSafeSet.PrefabSafeSet.OnValidate(this, x => x.materials);
}

private void OnValidate() => ValidatePSUC();
void ISerializationCallbackReceiver.OnBeforeSerialize() => ValidatePSUC();

void ISerializationCallbackReceiver.OnAfterDeserialize()
{
}

APIChecker _checker;

/// <summary>
/// Initializes the RemoveMEshByBlendShape with the specified default behavior version.
///
/// As Described in the documentation, you have to call this method after `AddComponent` to make sure
/// the default configuration is what you want.
/// Without calling this method, the default configuration might be changed in the future.
/// </summary>
/// <param name="version">
/// The default configuration version.
/// Since 1.7.0, version 1 is supported.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">Unsupported configuration version</exception>
[PublicAPI]
public void Initialize(int version)
{
switch (version)
{
case 1:
// nothing to do
break;
default:
throw new ArgumentOutOfRangeException(nameof(version), $"unsupported version: {version}");
}
_checker.OnInitialize(version, this);
}

/// <summary>
/// Gets the set of materials to delete from the target mesh.
/// </summary>
[PublicAPI]
public API.PrefabSafeSetAccessor<Material> Materials =>
_checker.OnAPIUsage(this, new API.PrefabSafeSetAccessor<Material>(materials));
}
}
3 changes: 3 additions & 0 deletions Runtime/RemoveMeshByMaterial.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8cbed0b

Please sign in to comment.