43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
import { Group, Mesh, SphereGeometry, Vector3 } from 'three'
|
|
import { buildSection, INCHES_TO_METERS } from '../duct-segment/geometry'
|
|
import { createPipeMaterial } from '../pipe-segment/geometry'
|
|
import { localPipeFittingPorts } from './ports'
|
|
import type { PipeFittingNode } from './schema'
|
|
|
|
const RADIAL_SEGMENTS = 20
|
|
|
|
/**
|
|
* Pure geometry builder for a DWV fitting, in the node's LOCAL frame.
|
|
* One cylinder stub per port from the junction outward, an oversized
|
|
* hub sphere at the junction, and a smaller hub at each collar opening
|
|
* (solvent-weld couplings). Wyes read correctly because their branch
|
|
* stub leaves at 45° — the port layout does the work.
|
|
*/
|
|
export function buildPipeFittingGeometry(node: PipeFittingNode): Group {
|
|
const group = new Group()
|
|
const material = createPipeMaterial(node)
|
|
const radiusRun = (node.diameter * INCHES_TO_METERS) / 2
|
|
|
|
for (const port of localPipeFittingPorts(node)) {
|
|
const radius = (port.diameter * INCHES_TO_METERS) / 2
|
|
const stub = buildSection(
|
|
new Vector3(0, 0, 0),
|
|
port.position,
|
|
radius,
|
|
material,
|
|
`pipe-fitting-stub-${port.id}`,
|
|
)
|
|
if (stub) group.add(stub)
|
|
const hub = new Mesh(new SphereGeometry(radius * 1.18, RADIAL_SEGMENTS, 12), material)
|
|
hub.name = `pipe-fitting-hub-${port.id}`
|
|
hub.position.copy(port.position)
|
|
group.add(hub)
|
|
}
|
|
|
|
const junction = new Mesh(new SphereGeometry(radiusRun * 1.18, RADIAL_SEGMENTS, 12), material)
|
|
junction.name = 'pipe-fitting-junction'
|
|
group.add(junction)
|
|
|
|
return group
|
|
}
|