Editor plugin that detects geometrically-identical sibling StaticMeshes across a level, rebases each placement onto one canonical mesh with a corrected transform (W' = D * W, verified by exact vertex matching), and can collapse groups into HISM. Native Slate tool panel + BlueprintCallable UOptimizerSubsystem. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mesh Optimizer — Sibling Duplicate Remover
Editor-only Unreal Engine plugin that finds geometrically identical StaticMesh assets used across a level, rebases every placement onto a single canonical mesh with a corrected transform, and optionally collapses the group into a Hierarchical Instanced Static Mesh (HISM).
UE 5.7 · Editor module
OptimizerEditor· native Slate tool panel.
The problem it solves
Bought kits and Kitbash3D-style packs import the same geometry as many separate assets:
SM_Fence_01, SM_Fence_02, … are literal twins — identical vertices, sometimes with a different
baked pivot or rotation. That defeats instancing: the engine sees N different meshes, so it can't
batch them, and you can't make one HISM out of them.
Mesh Optimizer detects those "sibling" meshes, picks one to keep, and re-points every actor that used a sibling to the survivor — fixing each actor's transform so nothing moves on screen — leaving a set that is ready to become a single HISM.
What it does
- Scan (dry run — mutates nothing): walk the level's StaticMesh placements, fingerprint every
unique mesh, group the geometric siblings, and report each group with a confidence figure
(
maxDeviation). - Unify: reassign every sibling placement to its group's canonical mesh and apply the corrected
world transform. Undoable (
Ctrl+Z). - Build HISM: create one
HierarchicalInstancedStaticMeshComponentper group from the corrected transforms, optionally destroying the originals. Undoable.
Every mutation runs inside a single editor transaction.
How it works
extract geometry (LOD0 FMeshDescription)
→ fingerprint (welded vertex/tri counts, surface area, |volume|,
covariance eigenvalues, radial histogram — all rotation-invariant)
→ bucket by (welded vertex count, triangle count)
→ recover the rigid delta between candidates
(identity fast-path, then the 24/48 signed-permutation axis rotations)
→ verify by order-independent nearest-neighbour vertex match (spatial hash)
→ union-find into groups, pick a canonical
→ plan the corrected transform per placement
The corrective transform. With D = the recovered canonical-local → sibling-local delta and
W = the sibling placement's current world transform, the canonical mesh must be placed at
W' = D * W (UE FTransform multiply order; matrix W'_mat = D_mat * W_mat)
built via FMatrix and reconstructed into an FTransform. Because a non-uniform actor scale combined
with a rotational D can produce shear (which FTransform cannot represent), each result is
checked at the bounding-box corners and any placement that would shear is skipped and reported
rather than silently corrupted.
Every candidate match is confirmed by an exact vertex-set verification before it is ever applied, so a bad transform is rejected, not shipped.
Installation
- Copy this folder into your project's
Plugins/directory (so it lives atPlugins/Optimizer/). - Add it to your
.uproject(editor-only):{ "Name": "Optimizer", "Enabled": true, "TargetAllowList": [ "Editor" ] } - Regenerate project files and build the editor target (a new module needs a full build — Live Coding cannot register a brand-new module).
Requires Unreal Engine 5.7 and an editor build (<Project>Editor Win64 Development).
Usage
Open the panel from Tools → Optimizer → Mesh Optimizer.
| Control | Effect |
|---|---|
| Scan | Dry-run analysis of the current level; fills the report. Changes nothing. |
| Unify | Reassign sibling placements to the canonical mesh + corrected transform. |
| Build HISM | Collapse each group into one HISM actor. |
| ☐ Mirrored | Also treat negative-scale (mirrored) variants as siblings. |
| ☐ Scaled | Also treat uniformly-scaled copies as siblings. |
| ☐ Merge materials | Group siblings even if their material sets differ (the canonical's materials win). |
| ☐ Destroy originals | When building HISM, delete the original actors/components. |
Recommended flow: Scan → review the report (check maxDev and the flags) → Unify (or Build
HISM). Everything is undoable with Ctrl+Z.
Detection modes
- Exact + rigid (default): identical geometry up to a rigid transform (rotation and/or a baked pivot offset). Covers almost all Kitbash cases.
- + Mirrored: negative-scale reflections (kept as a separate canonical group, since HISM winding differs).
- + Scaled: uniform-scale copies (the instance carries the scale).
Advanced tolerances (weld epsilon, accept tolerance, scalar relative tolerance, degenerate-eigenvalue epsilon) are exposed on the scan settings for tuning against specific content.
Safety & limitations
- World Partition: only loaded cells are visible to the scan — coverage is partial and the report says so.
- Shear: non-uniform actor scale combined with a rotational delta is unrepresentable by
FTransform; those placements are skipped and counted, never corrupted. - ISM/HISM sources: existing instanced components are out of scope in this version (only plain
StaticMeshActors / components are processed). - Materials: by default siblings with different material sets are kept in separate groups so each HISM keeps one material set.
Architecture
Source/OptimizerEditor/
OptimizerEditor.Build.cs
Public/
OptimizerEditorModule.h – module + Tools menu / nomad tab
OptimizerSubsystem.h – UEditorSubsystem: ScanLevel / ApplyUnify / BuildHISM
OptimizerTypes.h – settings + result structs/enums
Private/
OptimizerEditorModule.cpp
OptimizerGeometry.{h,cpp} – geometry extraction + fingerprint + 3x3 Jacobi eigensolver
OptimizerMatcher.{h,cpp} – bucketing, transform recovery, spatial-hash verification
OptimizerReconciler.{h,cpp}– W' = D * W + shear detection
OptimizerSubsystem.cpp – enumeration, planning, transacted mutation, HISM build
SOptimizerPanel.{h,cpp} – native Slate tool panel
The heavy logic is UI-agnostic C++ in UOptimizerSubsystem (BlueprintCallable); the Slate panel is a
thin driver.
License
Internal tool. © IHY / ExbyteLabs.