feat: HVAC ductwork + DWV plumbing systems (#402)

Adds two new MEP node families (HVAC ductwork, DWV plumbing) built on a shared port-connectivity model. Co-authored by @sudhir9297.
This commit is contained in:
Sudhir Yadav
2026-06-16 15:30:39 -04:00
committed by GitHub
parent a0d3d9c701
commit 5551500d98
172 changed files with 17361 additions and 150 deletions
@@ -29,6 +29,7 @@ const invalidGhostMaterial = new THREE.MeshStandardMaterial({
const SolarPanelPreview = ({ node, invalid }: { node: SolarPanelNode; invalid?: boolean }) => {
const material = invalid ? invalidGhostMaterial : ghostMaterial
// biome-ignore lint/correctness/useExhaustiveDependencies: deps deliberately list the build inputs; depending on the whole object would rebuild on unrelated field changes.
const geometry = useMemo(
() => buildSolarPanelGeometry(node),
[
@@ -98,6 +98,7 @@ const SolarPanelRenderer = ({ node: storeNode }: { node: SolarPanelNode }) => {
: segment
: undefined
// biome-ignore lint/correctness/useExhaustiveDependencies: deps deliberately list the build inputs; depending on the whole object would rebuild on unrelated field changes.
const geometry = useMemo(
() => buildSolarPanelGeometry(node),
[
@@ -138,6 +139,7 @@ const SolarPanelRenderer = ({ node: storeNode }: { node: SolarPanelNode }) => {
// the tilt normal flow from here, so a wall-height or pitch change
// re-seats and re-orients the panel automatically. `segmentOverrides`
// is in the deps so a live drag re-derives the frame mid-drag.
// biome-ignore lint/correctness/useExhaustiveDependencies: deps deliberately list the build inputs; depending on the whole object would rebuild on unrelated field changes.
const surfaceFrame = useMemo(() => {
if (!effectiveSegment) {
return { point: new THREE.Vector3(), normal: new THREE.Vector3(0, 1, 0) }