# 3D single-mesh variations isolated from multi-part products

This pass fixes the regression introduced when single-mesh GLB support was applied too broadly to every Product 3D model.

## Root cause

`table(1).glb` and `scene-nike-complete(1).glb` do not have the same topology:

- `table(1).glb`: one rendered mesh, one material, one connected component;
- `scene-nike-complete(1).glb`: seven logical rendered meshes and eleven materials.

The previous pass generated a native `Default` variation for every detected part. This changed the established variation tree of multi-part models, created unnecessary child variations and increased the amount of material resolution and event work performed for each variation change.

## Corrected rules

### Multi-part products

The established behavior is restored unchanged:

- one part group per detected logical part;
- existing user variations may be used as templates for those groups;
- no automatic `Default` child is invented;
- no native-material bookkeeping is added to the multi-part runtime;
- no additional wrapper or sub-variation level is introduced.

The Nike model therefore keeps its original seven logical part groups without synthetic children.

### Single-mesh products

Only the exact one-part case receives the new behavior:

- one logical part covers the whole product;
- variations remain at the root of the tree;
- when no variation exists, one flat `Default` variation is created;
- `Default` initially restores the GLB native material;
- editing color, texture, repeat, roughness or metallic disables native restoration and applies the custom material;
- manually created variations retain their identifiers and hierarchy without a synthetic part group.

## Regression cleanup

The previous faulty pass marked its generated children with `asukaProduct3DAutoDefaultVariation`.

When a multi-part model is inspected again, only those marked auto-generated children are removed. User-created variations, including a user-created variation named `Default`, are preserved.

## Variation batching

Linked or multi-target variation changes now suppress both events and history commits for intermediate targets. The last target emits one change and creates one history snapshot.

This avoids repeated store persistence, preview refreshes and material resolution while preserving one undoable entry per user action.

## Files changed

- `src/components/domain/elements/Product3DElementFields.tsx`
- `src/components/domain/elements/ElementVariationTreeField.tsx`
- `src/components/modules/ElementsModule.tsx`
- `src/components/modules/ElementVariationPickerModule.tsx`
- `src/addons/asuka-3d-engine.addon.ts`
- `src/core/renderEngine.ts`
- `src/store/asukaStore.ts`
- mirrored files under `pass/src/`
- regression tests under `src/core/__tests__/` and `pass/src/core/__tests__/`

## Verification

- Vitest: 52/52 tests passed;
- TypeScript `tsc --noEmit`: passed;
- engine-neutrality audit: passed;
- canonical 3D contract audit: passed on 580 files;
- TypeScript syntax audit: passed;
- product Vite build: passed;
- `src/` and `pass/src/`: synchronized.

The unchanged build warnings concern the named Fabric import and the size of the Babylon chunk.
