Skip to content

v0.4.23

@EdvardGK EdvardGK tagged this 01 Jun 13:24
The glTF writer now groups products by representation step_id and
emits one shared mesh + one node per group with EXT_mesh_gpu_instancing
(per-instance TRS attributes). Multi-fragment products and rep-unique
singletons fall through to the existing baked path so backwards-
compat is preserved for viewers that don't read the extension.

Plan:
- Classify products: single-fragment + non-empty mesh + rep shared
  with ≥2 others → instance group; everything else → baked.
- Per group: pack the first member's local_vertices/local_indices
  as the shared mesh, then TRS-decompose each member's
  world_transform * instance_transform via glam's
  to_scale_rotation_translation. Write TRANSLATION (VEC3), ROTATION
  (VEC4 quat xyzw), SCALE (VEC3) accessors per group.
- Per-instance identity goes into node.extras.instances[] as a
  parallel array indexed by glTF instance order — viewers map
  picked instance_id → guid/entity/segments without a side channel.
- Materials: baked path keeps per-product GUID materials (legacy
  pick-to-BIM hook); instanced path uses one entity-type material
  per group (per-instance materials aren't supported by the
  extension).

File size measurements (real Skiplum client files):
- LBK_RIBp_C 41 MB (structural, 4.84 instances/rep): 118.5 MB
  → 72.9 MB (38% smaller). 804 instance groups with 25,565
  total instances; 8,464 baked singletons.
- LBK_ARK_C 192 MB (architecture, 1.13 instances/rep): 86.9 MB
  → 86.8 MB (no harm). Most reps unique → very little to dedup.
- Bundled minimal fixture: 296 bytes both ways (no dedup possible).

Structural validation (custom Python checker on the .glb): all
accessor/bufferView refs valid, T/R/S accessor counts matched
per group, ifcfast-bench / all 13 mesh_reveal / 7 cut_openings_
integration / 76 Python tests pass.

Bumps to v0.4.23. No cache schema change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Assets 2
Loading