Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: more worker 2 #46

Draft
wants to merge 20 commits into
base: dev
Choose a base branch
from
2 changes: 1 addition & 1 deletion app/analyse/state/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import { type WindowType } from "@/server/data/windowTypes"
import { useSelectedHouseIds } from "../ui/HousesPillsSelector"
import { useElements } from "../../data/elements"
import { useEnergyInfos } from "../../data/energyInfos"
import { type House } from "../../data/houses"
import { useMaterials } from "../../data/materials"
import { useSpaceTypes } from "../../data/spaceTypes"
import { useWindowTypes } from "../../data/windowTypes"
import { useGetHouseModules, useHouses } from "../../design/state/houses"
import { type House } from "../../db/user"

export type SystemsData = {
houseTypes: Array<HouseType>
Expand Down
3 changes: 0 additions & 3 deletions app/api/trpc/[trpc]/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { initTRPC } from "@trpc/server"
import { fetchRequestHandler } from "@trpc/server/adapters/fetch"
import { appRouter } from "@/server/trpc/router"

const t = initTRPC.create()

export type AppRouter = typeof appRouter

const handler = async (request: Request) => {
Expand Down
7 changes: 4 additions & 3 deletions app/build/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client"
import dynamic from "next/dynamic"
import { PropsWithChildren } from "react"
import Footer from "../ui/Footer"
import { TrpcProvider } from "../ui/TrpcProvider"
import { PreloadSpeckleObjects } from "../utils/speckle/useSpeckleObject"
import { getLayoutsWorker, getSystemsWorker } from "../workers"
import BuildNav from "./common/BuildNav"

const HousesPillsSelector = dynamic(
Expand All @@ -13,6 +13,8 @@ const HousesPillsSelector = dynamic(
)

const BuildLayout = ({ children }: PropsWithChildren<{}>) => {
getSystemsWorker()
getLayoutsWorker()
return (
<TrpcProvider>
<div className="flex-auto overflow-y-auto flex flex-col">
Expand All @@ -26,7 +28,6 @@ const BuildLayout = ({ children }: PropsWithChildren<{}>) => {
<div className="flex-auto border-l border-grey-20">{children}</div>
</div>
</div>
<PreloadSpeckleObjects />
</TrpcProvider>
)
}
Expand Down
92 changes: 76 additions & 16 deletions app/data/elements.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { trpc } from "@/client/trpc"
import { liveQuery } from "dexie"
import { pipe } from "fp-ts/lib/function"
import { useMemo } from "react"
import { BufferGeometry } from "three"
import { BufferGeometry, BufferGeometryLoader } from "three"
import { proxy, ref, useSnapshot } from "valtio"
import { O, R, RA, S } from "~/utils/functions"
import { Element } from "../../server/data/elements"
import { Module } from "../../server/data/modules"
import useSpeckleObject from "../utils/speckle/useSpeckleObject"
import layoutsDB from "../db/layouts"
import systemsDB from "../db/systems"
import { isSSR } from "../utils/next"

export const useElements = (): Element[] => {
const { data = [] } = trpc.elements.useQuery()
Expand All @@ -20,6 +24,34 @@ export const useSystemElements = ({
return useElements().filter((x) => x.systemId === systemId)
}

export const ifcTagToElement = ({
systemId,
elements,
ifcTag,
}: {
elements: Element[]
ifcTag: string
systemId: string
}) => {
const result = pipe(
elements,
RA.findFirst((el) => {
return (
el.ifc4Variable.toUpperCase() === ifcTag && el.systemId === systemId
)
}),
O.toUndefined
)

if (result === undefined) {
console.log({
unmatchedIfcTag: { ifcTag },
})
}

return result
}

export const useIfcTagToElement = (systemId: string) => {
const elements = useSystemElements({ systemId })

Expand Down Expand Up @@ -55,27 +87,55 @@ export const invertModuleElementGeometriesKey = (input: string) => {
return { systemId, dna }
}

const models = proxy<Record<string, Record<string, BufferGeometry>>>({})

const loader = new BufferGeometryLoader()

if (!isSSR()) {
liveQuery(async () => {
const models = await layoutsDB.models.toArray()
const elements = await systemsDB.elements.toArray()
return { models, elements }
}).subscribe(({ models: dbModels, elements: dbElements }) => {
for (let { speckleBranchUrl, geometries, systemId } of dbModels) {
if (!(speckleBranchUrl in models)) {
const loadedModels: Record<string, BufferGeometry> = pipe(
geometries,
R.map((x) => loader.parse(x) as BufferGeometry),
R.reduceWithIndex(S.Ord)({}, (ifcTag, acc, geometry) => {
const el = ifcTagToElement({
systemId,
elements: dbElements,
ifcTag,
})
if (!el) return acc
return {
...acc,
[el.name]: geometry,
}
})
)
models[speckleBranchUrl] = ref(loadedModels)
}
}
})
}

export const useSpeckleObject = (speckleBranchUrl: string) => {
const snap = useSnapshot(models) as typeof models

return snap[speckleBranchUrl]
}

export const useModuleElements = ({
systemId,
speckleBranchUrl,
}: Module): Record<string, BufferGeometry> => {
const ifcTagToElement = useIfcTagToElement(systemId)
const speckleObject = useSpeckleObject(speckleBranchUrl)

return useMemo(
() =>
pipe(
speckleObject,
R.reduceWithIndex(S.Ord)({}, (ifcTag, acc, geometry) => {
const el = ifcTagToElement(ifcTag)
if (!el) return acc
return {
...acc,
[el.name]: geometry,
}
})
),
() => pipe(speckleObject),
// eslint-disable-next-line react-hooks/exhaustive-deps
[speckleBranchUrl]
[speckleBranchUrl, speckleObject]
)
}
40 changes: 0 additions & 40 deletions app/data/houses.ts

This file was deleted.

42 changes: 42 additions & 0 deletions app/db/layouts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Dexie from "dexie"
import { ColumnLayout } from "../design/state/layouts"
import { LastFetchStamped } from "./systems"

export type ParsedModel = {
speckleBranchUrl: string
geometries: any
systemId: string
}

export type IndexedLayout = {
layoutsKey: string
layout: ColumnLayout
}

export type LayoutsKey = {
systemId: string
dnas: string[]
}

export const serializeLayoutsKey = ({ systemId, dnas }: LayoutsKey) =>
`${systemId}:${dnas}`

class LayoutsDatabase extends Dexie {
models: Dexie.Table<LastFetchStamped<ParsedModel>, string>
layouts: Dexie.Table<IndexedLayout, string>

constructor() {
super("LayoutsDatabase")
this.version(1).stores({
models: "speckleBranchUrl,systemId",
layouts: "layoutsKey",
})
this.layouts = this.table("layouts")
this.models = this.table("models")
}
}

// Create Dexie database
const layoutsDB = new LayoutsDatabase()

export default layoutsDB
35 changes: 35 additions & 0 deletions app/db/systems.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Block } from "@/server/data/blocks"
import { Module } from "@/server/data/modules"
import Dexie from "dexie"
import { Element } from "../../server/data/elements"
import { HouseType } from "../../server/data/houseTypes"

export type LastFetchStamped<T> = T & {
lastFetched: number
}

class SystemsDatabase extends Dexie {
modules: Dexie.Table<LastFetchStamped<Module>, string>
houseTypes: Dexie.Table<LastFetchStamped<HouseType>, string>
elements: Dexie.Table<LastFetchStamped<Element>, string>
blocks: Dexie.Table<Block, string>

constructor() {
super("SystemsDatabase")
this.version(1).stores({
blocks: "id,systemId,name",
modules: "id,systemId,dna",
houseTypes: "id,systemId",
elements: "id,systemId",
})
this.modules = this.table("modules")
this.houseTypes = this.table("houseTypes")
this.blocks = this.table("blocks")
this.elements = this.table("elements")
}
}

// Create Dexie database
const systemsDB = new SystemsDatabase()

export default systemsDB
35 changes: 35 additions & 0 deletions app/db/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Dexie from "dexie"
import { z } from "zod"

export const houseParser = z.object({
id: z.string().min(1),
houseTypeId: z.string().min(1),
systemId: z.string().min(1),
dnas: z.array(z.string().min(1)),
modifiedMaterials: z.record(z.string().min(1)),
friendlyName: z.string().min(1),
position: z.object({
x: z.number(),
y: z.number(),
z: z.number(),
}),
rotation: z.number(),
})

export type House = z.infer<typeof houseParser>

class UserDatabase extends Dexie {
houses: Dexie.Table<House, string>

constructor() {
super("UserDatabase")
this.version(1).stores({
houses: "id,&friendlyName",
})
this.houses = this.table("houses")
}
}

const userDB = new UserDatabase()

export default userDB
2 changes: 1 addition & 1 deletion app/debug/system/ui-3d/DebugSpeckleModule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { pipe } from "fp-ts/lib/function"
import { useMemo, useRef } from "react"
import { Group, Material, MeshBasicMaterial } from "three"
import { Module } from "../../../../server/data/modules"
import { useSpeckleObject } from "../../../data/elements"
import { useGetDefaultElementMaterial } from "../../../design/state/hashedMaterials"
import { O, R, S } from "../../../utils/functions"
import useSpeckleObject from "../../../utils/speckle/useSpeckleObject"
import DebugSpeckleElement from "./DebugSpeckleElement"

const DebugSpeckleModule = ({ module }: { module: Module }) => {
Expand Down
4 changes: 4 additions & 0 deletions app/design/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
"use client"
import DataInit from "~/data/DataInit"
import { TrpcProvider } from "../ui/TrpcProvider"
import { getLayoutsWorker, getSystemsWorker } from "../workers"
import GroupedApp from "./ui-3d/grouped/GroupedApp"
import AppInit from "./ui-3d/init/AppInit"

const IndexPage = () => {
getSystemsWorker()
getLayoutsWorker()
return (
<TrpcProvider>
<DataInit>
Expand Down
13 changes: 11 additions & 2 deletions app/design/state/dimensions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { OBB } from "three-stdlib"
import { proxy, ref, useSnapshot } from "valtio"
import { useSubscribeKey } from "~/utils/hooks"
import { yAxis } from "~/utils/three"
import houses from "./houses"
import { serializeLayoutsKey } from "../../db/layouts"
import houses, { useHouse } from "./houses"
import { layouts } from "./layouts"
import { postTransformsTransients, Transforms } from "./transients/transforms"

Expand Down Expand Up @@ -68,17 +69,25 @@ export const usePostTransMatrix = (houseId: string) => {
}
}

export const useLayoutsKey = (houseId: string) => {
const { systemId, dnas } = useHouse(houseId)

return serializeLayoutsKey({ systemId, dnas })
}

export const useComputeDimensions = (houseId: string) => {
const translationMatrix = useRef(new Matrix4())
const rotationMatrix = useRef(new Matrix4())

const layoutsKey = useLayoutsKey(houseId)

return (transients: Transforms = {}): Dimensions => {
const {
rotation: dr = 0,
position: { dx, dy, dz } = { dx: 0, dy: 0, dz: 0 },
} = transients

const columns = layouts[houseId]
const columns = layouts[layoutsKey]

const width = columns[0].gridGroups[0].modules[0].module.width
const height = columns[0].gridGroups.reduce(
Expand Down
Loading