verify-aligned-cad-bim.mjs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // Verify the corrected GIS-aligned CAD/BIM batches and far wrapper provenance.
  2. import assert from 'node:assert/strict'
  3. import { readFileSync, existsSync } from 'node:fs'
  4. import { join, resolve } from 'node:path'
  5. const root = resolve('tools/city-massing/city/cad-bim')
  6. const dirs = process.argv.slice(2)
  7. assert.ok(dirs.length, 'aligned batch directories required')
  8. const requiredMaterials = ['Door_Walnut', 'Glass_Dark']
  9. const results = []
  10. const ids = new Set()
  11. for (const name of dirs) {
  12. const dir = resolve(name)
  13. const manifestPath = join(dir, 'manifest.json')
  14. const treePath = join(dir, 'tileset.json')
  15. assert.ok(existsSync(manifestPath), `${name}: manifest missing`)
  16. const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
  17. const tree = JSON.parse(readFileSync(treePath, 'utf8'))
  18. assert.equal(manifest.provenance?.gisFootprints, true, `${name}: GIS footprint provenance missing`)
  19. assert.equal(manifest.provenance?.roadsProcedural, false, `${name}: procedural roads provenance`)
  20. assert.equal(manifest.provenance?.lod1FootprintOnly, true, `${name}: LOD1 footprint mode missing`)
  21. assert.equal(manifest.provenance?.facadeDetails, true, `${name}: facade provenance missing`)
  22. assert.ok(tree.root?.transform?.length === 16, `${name}: root transform missing`)
  23. assert.ok(tree.root?.children?.length, `${name}: no coarse children`)
  24. const cellIds = manifest.cells.flatMap((cell) => cell.buildingIds)
  25. assert.equal(cellIds.length, manifest.count, `${name}: manifest coverage count mismatch`)
  26. for (const id of cellIds) {
  27. assert.ok(!ids.has(id), `${name}: duplicate building id ${id}`)
  28. ids.add(id)
  29. }
  30. const lod1Files = manifest.coarseCells.map((record) => record.uri)
  31. assert.ok(lod1Files.length, `${name}: no coarse records`)
  32. const materials = new Set()
  33. for (const uri of lod1Files) {
  34. const bytes = readFileSync(join(dir, uri))
  35. const length = bytes.readUInt32LE(12)
  36. const gltf = JSON.parse(bytes.toString('utf8', 20, 20 + length))
  37. for (const material of gltf.materials || []) if (material.name) materials.add(material.name)
  38. }
  39. for (const material of requiredMaterials) assert.ok(materials.has(material), `${name}: LOD1 lacks ${material}`)
  40. results.push({ name, buildings: manifest.count, coarseFiles: lod1Files.length,
  41. lod1Triangles: manifest.totals.lod1.triangles, lod0Triangles: manifest.totals.lod0.triangles,
  42. materials: [...materials].sort() })
  43. }
  44. console.log(JSON.stringify({ passed: true, batches: results, buildings: ids.size }))