t54-physical-details.mjs 3.4 KB

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