| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- // Assemble a complete regional generation with exactly the saved roof pilot overrides.
- // No configured path or source GLB is overwritten.
- import assert from 'node:assert/strict'
- import {readFileSync,writeFileSync,mkdirSync,copyFileSync,existsSync} from 'node:fs'
- import {resolve,join,relative,dirname} from 'node:path'
- import {createHash} from 'node:crypto'
- const root=resolve('tools/city-massing/city/cad-bim')
- const base=join(root,'city-regions-v7')
- const out=resolve(process.argv[2]||join(root,'city-regions-roof-pilot-v1'))
- const pilotPath=resolve('.scratch/cockpit-shell-panel-layout/verify/artifacts/t35/roof-quality-pilot/report.json')
- const configPath=resolve('public/cockpit/config.json')
- const sha=data=>createHash('sha256').update(data).digest('hex')
- const read=path=>JSON.parse(readFileSync(path))
- const configHash=sha(readFileSync(configPath)),pilot=read(pilotPath),manifest=read(join(base,'manifest.json'))
- assert.equal(pilot.passed,true);assert.equal(pilot.results.length,2)
- assert.ok(!existsSync(out),'use a new immutable generation')
- const rebased=(from,to,uri)=>relative(to,resolve(from,uri)).replaceAll('\\','/')
- const overrides=new Map(),changed=[]
- for(const entry of pilot.results){
- const key=entry.region+':'+entry.uri;assert.ok(!overrides.has(key));overrides.set(key,entry)
- assert.equal(sha(readFileSync(entry.pilotAsset)),entry.pilotAssetSha256,'pilot changed')
- assert.ok(entry.geometryUnchanged&&entry.uvUnchanged&&entry.facadeMaterialsUnchanged)
- }
- mkdirSync(out,{recursive:true})
- for(const r of manifest.regions){
- const oldTreePath=resolve(base,r.url),oldDir=dirname(oldTreePath)
- const selected=pilot.results.filter(p=>p.region===r.id)
- if(!selected.length){r.url=rebased(base,out,r.url);continue}
- const regionDir=join(out,'region-'+r.id);mkdirSync(regionDir)
- const tree=read(oldTreePath),replacements=new Map()
- for(const entry of selected){
- const before=r.fineRecords.find(f=>f.uri===entry.uri);assert.ok(before?.textured&&!before.preservedOriginal)
- const oldPath=resolve(oldDir,before.uri),newPath=join(regionDir,before.uri)
- assert.equal(sha(readFileSync(oldPath)),entry.currentAssetSha256,'configured source changed')
- copyFileSync(entry.pilotAsset,newPath);replacements.set(oldPath,newPath)
- Object.assign(before,entry.processed)
- r.decodedGeometryBytes+=entry.deltaDecodedTextureEstimate
- changed.push({region:r.id,uri:entry.uri,oldPath,newPath,currentAssetSha256:entry.currentAssetSha256,sourcePath:entry.sourcePath,sourceSha256:entry.sourceSha256,
- replacementSha256:entry.pilotAssetSha256,width:entry.processed.width,height:entry.processed.height,rasterSha256:entry.processed.rasterSha256,
- rasterBytes:entry.processed.rasterBytes,processing:entry.processed.processing,sourceTiles:entry.processed.sourceTiles,
- deltaDecodedTextureEstimate:entry.deltaDecodedTextureEstimate})
- }
- const resolveContent=uri=>{const path=resolve(oldDir,uri);return relative(regionDir,replacements.get(path)||path).replaceAll('\\','/')}
- function walk(t){if(t.content?.uri)t.content.uri=resolveContent(t.content.uri);for(const child of t.children||[])walk(child)}
- walk(tree.root)
- r.url=relative(out,join(regionDir,'tileset.json')).replaceAll('\\','/')
- r.contentUrls=r.contentUrls.map(resolveContent)
- r.previewContentUrls=r.previewContentUrls.map(resolveContent)
- for(const record of [...r.fineRecords,...r.previewRecords])record.uri=resolveContent(record.uri)
- assert.ok(r.decodedGeometryBytes<=96*1024*1024&&r.contentCount<=180)
- writeFileSync(join(regionDir,'tileset.json'),JSON.stringify(tree))
- }
- for(const r of manifest.coarseRecords)r.uri=rebased(base,out,r.uri)
- const coarse=read(join(base,'coarse-tileset.json'))
- function walkCoarse(t){if(t.content?.uri)t.content.uri=rebased(base,out,t.content.uri);for(const c of t.children||[])walkCoarse(c)}
- walkCoarse(coarse.root)
- manifest.assetBase='city-regions-v6'
- manifest.roofQualityCandidate={parentGeneration:'city-regions-v7',parentManifestSha256:sha(readFileSync(join(base,'manifest.json'))),
- pilotReportSha256:sha(readFileSync(pilotPath)),changedTiles:changed,configured:false,renderingValidated:false,
- policy:'Same regions/preview/bounds/LOD/geometry. Only two sourced roof rasters enhanced; estimate updated before admission.'}
- writeFileSync(join(out,'coarse-tileset.json'),JSON.stringify(coarse))
- writeFileSync(join(out,'manifest.json'),JSON.stringify(manifest,null,2))
- assert.equal(sha(readFileSync(configPath)),configHash,'configuration unexpectedly changed')
- console.log(JSON.stringify({passed:true,out,regions:manifest.regions.length,changedFineContents:changed.length,
- changedRegionEstimate:manifest.regions.find(r=>r.id===25).decodedGeometryBytes,configurationChanged:false}))
|