import assert from 'node:assert/strict' import * as THREE from 'three' import { planPipeEnhancement } from '../../../src/modules/cockpit/domain/pipeEnhancement.js' import { planPipeModels } from '../../../src/modules/cockpit/domain/pipeModels.js' import { pipeSurface } from '../../../src/modules/cockpit/domain/pipePhysical.js' import { mountPipeEnhancement } from '../../../src/modules/cockpit/services/threePipeEnhancement.js' const surfaces = [['钢', 'steel'], ['钢管', 'steel'], ['玻璃钢管', 'frp'], ['未知编码', 'unknown']] for (const [value, expected] of surfaces) assert.equal(pipeSurface(value).kind, expected) const anomaly = planPipeEnhancement({ selected: { kind: 'pipe', code: 'zero' }, visiblePipes: [{ code: 'zero', diameter: 400, length: 0, material: '钢', positions: [[110, 28], [110.001, 28]] }] }) assert.equal(anomaly.object.lengthM, 0) const pipes = [ { code: 'fine', industry: 'WATER_SUPPLY', diameter: 400, length: 70, material: 'PE', positions: [[110, 28], [110.001, 28]] }, { code: 'coarse', industry: 'WATER_SUPPLY', diameter: 200, length: 45, material: '钢管', positions: [[110, 28.0001], [110.001, 28.0001]] }, { code: 'missing', industry: 'WATER_SUPPLY', diameter: null, positions: [[110, 28.0002], [110.001, 28.0002]] }, ] const input = { selected: { kind: 'pipe', code: 'fine' }, visiblePipes: pipes } const plan = planPipeEnhancement(input) assert.equal(plan.object.diameterM, 0.4) assert.equal(plan.object.lengthM, 70) assert.ok(plan.object.geographicLengthM > 98 && plan.object.geographicLengthM < 99) assert.equal(plan.object.surface.kind, 'pe') const map = planPipeModels({ pipes }) assert.equal(map.instances.find((i) => i.id === 'pipe:fine').displayDiameterM, 0.4) assert.equal(map.instances.find((i) => i.id === 'pipe:coarse').surface.kind, 'steel') assert.ok(!map.instances.some((i) => i.id === 'pipe:missing')) let scene, camera const canvas = new EventTarget() const host = { clientWidth: 900, clientHeight: 500, appendChild(n) { n.parentNode = this }, removeChild(n) { n.parentNode = null } } const viewer = mountPipeEnhancement(host, plan, { rendererFactory: () => ({ domElement: canvas, setSize() {}, dispose() {}, render(s, c) { scene = s; camera = c } }) }) scene.updateMatrixWorld(true) const body = scene.getObjectByName('pipe-wall') const coarse = scene.getObjectByName('neighbor-pipe-wall') assert.ok(body && coarse) body.geometry.computeBoundingBox() assert.ok(Math.abs(body.geometry.boundingBox.max.x - 0.2) < 1e-6) assert.equal(coarse.geometry.parameters.radiusTop, 0.1) assert.ok(Math.abs(body.getWorldScale(new THREE.Vector3()).x - 1) < 1e-8) assert.ok(Math.abs(body.geometry.boundingBox.max.y - body.geometry.boundingBox.min.y - plan.object.geographicLengthM) < 1e-4) assert.equal(body.material.metalness, 0) assert.ok(coarse.material.metalness > 0.7) const outlines = [] scene.traverse((n) => { if (n.name === 'selected-pipe-outline') outlines.push(n) }) assert.ok(outlines.length) assert.ok(!outlines.some((n) => n.parent.name === 'neighbor-pipe-wall')) const outline = outlines[0] assert.equal(outline.material.uniforms.resolution.value.x, 900) assert.equal(outline.material.depthTest, true) let released = false outline.material.addEventListener('dispose', () => { released = true }) assert.ok(camera.far > camera.position.length()) viewer.destroy() assert.equal(released, true) console.log('PASS 精粗源管径/地理长度/数据材质一致;缺径不造管体;精模描边及释放')