| 1234567891011121314151617181920212223242526272829 |
- // Export-ready four-ID subset: preserve seated geometry and remap only sampling references.
- import assert from 'node:assert/strict'
- import {createHash} from 'node:crypto'
- import {readFileSync,writeFileSync,mkdirSync,existsSync} from 'node:fs'
- import {resolve,join} from 'node:path'
- const root=resolve('tools/city-massing/city/cad-bim')
- const dir=resolve('.scratch/cockpit-shell-panel-layout/verify/artifacts/t35/negative-estate-pilot/input-v2')
- assert.ok(!existsSync(dir),'immutable input already exists')
- const ids=['cad-25612','cad-25467','cad-25968','cad-25957']
- const parentBytes=readFileSync(join(root,'seated-plan.json')),seat=JSON.parse(parentBytes),plan=JSON.parse(readFileSync(join(root,'plan.json')))
- assert.deepEqual(seat.transform,plan.transform)
- const samples=[],sourceById=new Map(plan.buildings.map(b=>[b.id,b]))
- const buildings=ids.map(id=>{
- const s=seat.buildings.find(b=>b.id===id),b=sourceById.get(id);assert.ok(s&&b)
- assert.ok(s.terrainRelief<=3.2&&s.terrainRelief<=s.heightM*.4)
- const indices=b.sampleIndices.map(i=>{assert.ok(plan.samples[i]);samples.push(structuredClone(plan.samples[i]));return samples.length-1})
- return {...s,sourceKind:s.kind,sourceArchetype:s.archetype,kind:'massing',sampleIndices:indices,sourceSampleIndices:b.sampleIndices,
- renderingPolicy:'exact surveyed seated shell at both LODs; near facade details estimated; source asset not stretched to impersonate floor count'}
- })
- const result={version:2,source:plan.source,origin:seat.origin,transform:seat.transform,bounds:seat.bounds||plan.bounds,
- notice:'Local offline candidate based on maintainer estate feedback. Footprints/seating preserved; heights and facades remain estimates. Not configured or visually accepted.',
- parentPlanSha256:createHash('sha256').update(parentBytes).digest('hex'),buildings,samples,
- selection:{ids,reason:'specific user-requested estate, source rural tag retained; no blanket rural loading',configured:false},
- caps:{maxRegions:1,maxContents:8,maxDecodedBytes:32*1024*1024}}
- assert.equal(result.transform.length,16)
- for(const b of buildings){const s=seat.buildings.find(s=>s.id===b.id);for(const k of ['footprintENU','positionENU','heightM','foundationBottom','terrainMin','terrainMax','terrainRelief','floors','construction'])assert.deepEqual(b[k],s[k],b.id+' '+k)
- assert.ok(b.sampleIndices.every(i=>Number.isInteger(i)&&i>=0&&i<samples.length))}
- mkdirSync(dir,{recursive:true});writeFileSync(join(dir,'seated-plan.json'),JSON.stringify(result,null,2))
- console.log(JSON.stringify({passed:true,buildings:ids,localSampleCount:samples.length,coordinateTransform:true,seatedFieldsPreserved:true,output:dir,configured:false}))
|