diff --git a/package-lock.json b/package-lock.json index 5147ef5..a00623c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "three": "^0.163.0", "three-mesh-bvh": "^0.7.4", "three-stdlib": "^2.29.6", + "uuid": "^9.0.1", "web-ifc": "^0.0.54" }, "devDependencies": { @@ -5066,6 +5067,18 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vite": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", diff --git a/package.json b/package.json index ee733da..878d774 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "three": "^0.163.0", "three-mesh-bvh": "^0.7.4", "three-stdlib": "^2.29.6", + "uuid": "^9.0.1", "web-ifc": "^0.0.54" }, "devDependencies": { diff --git a/src/BimModel/index.ts b/src/BimModel/index.ts index a3b9e30..9b1b5d4 100644 --- a/src/BimModel/index.ts +++ b/src/BimModel/index.ts @@ -1,13 +1,14 @@ import { Components, - CubeMapComponent, disposeSignals, + CubeMapComponent, MaterialComponent, ModelingComponent, PropertyComponent, RendererComponent, StructureComponent, ProjectComponent, + SystemComponent, } from "./src"; export class BimModel { @@ -47,6 +48,8 @@ export class BimModel { propertyComponent.enabled = true; const structureComponent = this.components.tools.get(StructureComponent); structureComponent.enabled = true; + structureComponent.init(this.structure); + new SystemComponent(this.components); this.components.gameLoop(); } } diff --git a/src/BimModel/src/Components/index.ts b/src/BimModel/src/Components/index.ts index 4d9e0e3..42a0cdb 100644 --- a/src/BimModel/src/Components/index.ts +++ b/src/BimModel/src/Components/index.ts @@ -1,5 +1,5 @@ import * as THREE from "three"; -import {Component, Disposable} from "../types"; +import {Disposable} from "../types"; import {ToolComponent} from "../Tool"; import { acceleratedRaycast, @@ -8,6 +8,7 @@ import { } from "three-mesh-bvh"; import {effect} from "@preact/signals-react"; import {appTheme} from "@signals/theme"; +import {isModelingSignal, isOrthoSignal, keyboardSignal} from "../Signals"; /** * The entry point of Open BIM Components. * It contains the basic items to create a BIM 3D scene based on Three.js, as @@ -32,21 +33,26 @@ export class Components implements Disposable { set setupEvent(enabled: boolean) { if (enabled) { window.addEventListener("resize", this.onResize); + document.addEventListener("keydown", this.onKeyDown); + document.addEventListener("keyup", this.onKeyUp); } else { window.removeEventListener("resize", this.onResize); + document.removeEventListener("keydown", this.onKeyDown); + document.removeEventListener("keyup", this.onKeyUp); } } get rect(): DOMRect { if (!this.container) throw new Error("Not Initialized!"); return this.container.getBoundingClientRect(); } + constructor(public container: HTMLDivElement) { this.init(); this.setupBVH(); this.tools = new ToolComponent(this); this.setupEvent = true; effect(() => { - this.scene.background = appTheme.value === "dark" ? sceneBG : null; + this.scene.background = appTheme.value === "dark" ? null : sceneBG; }); } async dispose() { @@ -78,6 +84,16 @@ export class Components implements Disposable { } } }; + private onKeyDown = (e: KeyboardEvent) => { + if (e.key === "Escape" && isModelingSignal.value) + isModelingSignal.value = false; + if (e.key === "F8") isOrthoSignal.value = !isOrthoSignal.value; + keyboardSignal.value = e.key; + }; + private onKeyUp = (_e: KeyboardEvent) => { + keyboardSignal.value = null; + }; + private initClock() { const clock = new THREE.Clock(); clock.start(); diff --git a/src/BimModel/src/CubeMapComponent/index.ts b/src/BimModel/src/CubeMapComponent/index.ts index 14a3f6b..8c9ba2c 100644 --- a/src/BimModel/src/CubeMapComponent/index.ts +++ b/src/BimModel/src/CubeMapComponent/index.ts @@ -98,6 +98,17 @@ export class CubeMapComponent if (!this.container) throw new Error("Not Initialized!"); return this.container.getBoundingClientRect(); } + private _visible = false; + set visible(visible: boolean) { + if (!this.container || !this.components.container) return; + if (this._visible === visible) return; + this._visible = visible; + if (visible) { + this.components.container.appendChild(this.container); + } else { + this.container.remove(); + } + } /** * */ @@ -159,7 +170,7 @@ export class CubeMapComponent this.container.style.position = "absolute"; this.container.style.zIndex = "20"; this.container.appendChild(this.canvas); - container.appendChild(this.container); + this.visible = true; this.align = "top-right"; } diff --git a/src/BimModel/src/MaterialComponent/index.ts b/src/BimModel/src/MaterialComponent/index.ts index 113fc6a..d7715d6 100644 --- a/src/BimModel/src/MaterialComponent/index.ts +++ b/src/BimModel/src/MaterialComponent/index.ts @@ -1,15 +1,25 @@ import * as THREE from "three"; +import {LineMaterial} from "three/examples/jsm/lines/LineMaterial"; import {Components} from "../Components"; import {ToolComponent} from "../Tool"; -import {Component, Disposable, UUID} from "../types"; -export class MaterialComponent extends Component implements Disposable { +import {Component, Disposable, Updateable, UUID} from "../types"; +import {effect} from "@preact/signals-react"; +import {clippingPlanesSignal, lineTypeSignal} from "../Signals"; + +export class MaterialComponent + extends Component + implements Disposable, Updateable +{ static readonly uuid = UUID.MaterialComponent; + static readonly exclude = ["LocationMaterial"]; enabled = false; listMaterial: Map< string, - THREE.MeshLambertMaterial | THREE.MeshBasicMaterial + THREE.MeshLambertMaterial | THREE.MeshBasicMaterial | LineMaterial > = new Map(); - + get LocationMaterial() { + return this.listMaterial.get("LocationMaterial"); + } get() { return MaterialComponent.uuid; } @@ -19,6 +29,34 @@ export class MaterialComponent extends Component implements Disposable { constructor(components: Components) { super(components); this.components.tools.add(MaterialComponent.uuid, this); + this.addMaterial( + "LocationMaterial", + new LineMaterial({ + linewidth: 1, // in world units with size attenuation, pixels otherwise + vertexColors: true, + color: 0xfcb603, + alphaToCoverage: true, + dashed: false, + dashScale: 1, + dashSize: 1, + gapSize: 1, + depthTest: false, + }) + ); + effect(() => { + for (const [name, mat] of this.listMaterial) { + if (MaterialComponent.exclude.includes(name)) continue; + mat.clippingPlanes = clippingPlanesSignal.value; + } + }); + effect(() => { + (this.LocationMaterial as LineMaterial).linewidth = + lineTypeSignal.value === "thin" ? 0.5 : 3; + }); + } + update(_delta?: number): void { + const {width, height} = this.components.rect; + (this.LocationMaterial as LineMaterial)?.resolution.set(width, height); } async dispose() { for (const [_, mat] of this.listMaterial) { @@ -29,7 +67,7 @@ export class MaterialComponent extends Component implements Disposable { addMaterial( name: string, - mat: THREE.MeshLambertMaterial | THREE.MeshBasicMaterial + mat: THREE.MeshLambertMaterial | THREE.MeshBasicMaterial | LineMaterial ) { if (this.listMaterial.has(name)) throw new Error("Material's name is existed!"); diff --git a/src/BimModel/src/ModelingComponent/index.ts b/src/BimModel/src/ModelingComponent/index.ts index b73d8da..3ec3454 100644 --- a/src/BimModel/src/ModelingComponent/index.ts +++ b/src/BimModel/src/ModelingComponent/index.ts @@ -11,6 +11,7 @@ export class ModelingComponent extends Component implements Disposable { get ProjectComponent(): ProjectComponent { return this.components.tools.get(ProjectComponent); } + /** * */ @@ -22,6 +23,7 @@ export class ModelingComponent extends Component implements Disposable { this.modelingContainer?.remove(); this.optionContainer?.remove(); (this.modelingContainer as any) = null; + (this.optionContainer as any) = null; } get() { throw new Error("Method not implemented."); @@ -33,4 +35,5 @@ export class ModelingComponent extends Component implements Disposable { option.appendChild(this.optionContainer); } } +// ToolComponent.libraryUUIDs.add(ModelingComponent.uuid); diff --git a/src/BimModel/src/ModelingComponent/src/InitComponents.tsx b/src/BimModel/src/ModelingComponent/src/InitComponents.tsx index efc1f50..27c2e97 100644 --- a/src/BimModel/src/ModelingComponent/src/InitComponents.tsx +++ b/src/BimModel/src/ModelingComponent/src/InitComponents.tsx @@ -6,6 +6,8 @@ import ProjectInfo from "./Project/ProjectInfo"; import ModelingOption from "./ModelingOption/ModelingOption"; import Units from "./Units/Units"; import NewProject from "./Project/NewProject"; +import VisibilityOption from "./VisibilityOption/VisibilityOption"; +import LineOption from "./LineOption/LineOption"; export function createModelingContainer(modeling: ModelingComponent) { const div = document.createElement("div"); @@ -25,7 +27,11 @@ export function createOptionContainer(_modeling: ModelingComponent) { ReactDOM.createRoot(div).render( <> - +
+ + + +
); return div; diff --git a/src/BimModel/src/ModelingComponent/src/LineOption/LineOption.tsx b/src/BimModel/src/ModelingComponent/src/LineOption/LineOption.tsx new file mode 100644 index 0000000..4316434 --- /dev/null +++ b/src/BimModel/src/ModelingComponent/src/LineOption/LineOption.tsx @@ -0,0 +1,35 @@ +import React, {memo} from "react"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@components/ui/select"; +import {lineTypeSignal, ListLineTypes} from "@BimModel/src/Signals"; +import {ILineType} from "@BimModel/src/ProjectComponent/types"; +const LineOption = () => { + return ( +
+
+ + +
+ ); +}; + +export default memo(LineOption); diff --git a/src/BimModel/src/ModelingComponent/src/Modeling/ContentModeling.tsx b/src/BimModel/src/ModelingComponent/src/Modeling/ContentModeling.tsx index 08579bb..d44b788 100644 --- a/src/BimModel/src/ModelingComponent/src/Modeling/ContentModeling.tsx +++ b/src/BimModel/src/ModelingComponent/src/Modeling/ContentModeling.tsx @@ -1,5 +1,5 @@ import React, {FC, useState} from "react"; -import {IModeling, ITool} from "@BimModel/src/types"; +import {IModeling, ITool} from "@ModelingComponent/types"; import ModelingButton from "./ModelingButton"; import {useSignalEffect} from "@preact/signals-react"; import {modelingSignal} from "@BimModel/src/Signals"; diff --git a/src/BimModel/src/ModelingComponent/src/Modeling/FileTabs.tsx b/src/BimModel/src/ModelingComponent/src/Modeling/FileTabs.tsx index 947ea9e..d3b3d7d 100644 --- a/src/BimModel/src/ModelingComponent/src/Modeling/FileTabs.tsx +++ b/src/BimModel/src/ModelingComponent/src/Modeling/FileTabs.tsx @@ -8,8 +8,7 @@ import {CiSaveDown2 as Save} from "react-icons/ci"; import dotbim from "@assets/dotbim.png"; import gltf from "@assets/gltf-icon.png"; import ifc from "@assets/ifc-icon.png"; -import revit from "@assets/revit-256.png"; -import {ITool} from "@BimModel/src/types"; +import {ITool} from "@ModelingComponent/types"; import { Tooltip, TooltipContent, diff --git a/src/BimModel/src/ModelingComponent/src/Modeling/ModelingButton.tsx b/src/BimModel/src/ModelingComponent/src/Modeling/ModelingButton.tsx index 7cc6f9b..1be2d49 100644 --- a/src/BimModel/src/ModelingComponent/src/Modeling/ModelingButton.tsx +++ b/src/BimModel/src/ModelingComponent/src/Modeling/ModelingButton.tsx @@ -1,5 +1,5 @@ import React, {FC} from "react"; -import {ITool} from "@BimModel/src/types"; +import {ITool} from "@ModelingComponent/types"; import {Button} from "@/components/ui/button"; import { Tooltip, @@ -7,12 +7,13 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; -import {modelingSignal} from "@BimModel/src/Signals"; +import {isModelingSignal, modelingSignal} from "@BimModel/src/Signals"; import {useComputed} from "@preact/signals-react"; const ModelingButton: FC = ({type, discipline}) => { const handleModeling = (type: string) => { modelingSignal.value = {discipline, type}; + isModelingSignal.value = true; }; const disabled = useComputed(() => { return ( @@ -24,6 +25,7 @@ const ModelingButton: FC = ({type, discipline}) => { modelingSignal.value !== null && modelingSignal.value.type === type.type ); }); + return ( diff --git a/src/BimModel/src/ModelingComponent/src/Modeling/ModelingTabs.tsx b/src/BimModel/src/ModelingComponent/src/Modeling/ModelingTabs.tsx index 7f9312e..600c5cd 100644 --- a/src/BimModel/src/ModelingComponent/src/Modeling/ModelingTabs.tsx +++ b/src/BimModel/src/ModelingComponent/src/Modeling/ModelingTabs.tsx @@ -1,7 +1,7 @@ import React, {memo} from "react"; import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs"; import {ModelingTools} from "../constants"; -import {IModelingToolTabs} from "@BimModel/src/types"; +import {IModelingToolTabs} from "@ModelingComponent/types"; import ContentModeling from "./ContentModeling"; import { disciplineSignal, @@ -28,9 +28,8 @@ const ModelingTabs = () => { value={tab.discipline} className="mx-1 select-none" disabled={ - !projectSignal.value || - (modelingSignal.value !== null && - modelingSignal.value.discipline !== tab.discipline) + modelingSignal.value !== null && + modelingSignal.value.discipline !== tab.discipline } > {tab.discipline} diff --git a/src/BimModel/src/ModelingComponent/src/Modeling/ToolButton.tsx b/src/BimModel/src/ModelingComponent/src/Modeling/ToolButton.tsx index 4c3e4ea..24d9d89 100644 --- a/src/BimModel/src/ModelingComponent/src/Modeling/ToolButton.tsx +++ b/src/BimModel/src/ModelingComponent/src/Modeling/ToolButton.tsx @@ -1,5 +1,5 @@ import React, {FC} from "react"; -import {IModeling} from "@BimModel/src/types"; +import {IModeling} from "@ModelingComponent/types"; import {Button} from "@/components/ui/button"; import { Tooltip, diff --git a/src/BimModel/src/ModelingComponent/src/Units/Units.tsx b/src/BimModel/src/ModelingComponent/src/Units/Units.tsx index f2f85af..9123ad7 100644 --- a/src/BimModel/src/ModelingComponent/src/Units/Units.tsx +++ b/src/BimModel/src/ModelingComponent/src/Units/Units.tsx @@ -7,15 +7,16 @@ import { SelectValue, } from "@components/ui/select"; import {ListUnits, unitSignal} from "@BimModel/src/Signals"; -import {IUnit} from "@BimModel/src/types"; +import {IUnit} from "@BimModel/src/ProjectComponent/types"; const Units = () => { return ( -
+
+
+ (currentLevelSignal.value = listLevelSignal.value[+value]) + } + > + + + + + {listLevelSignal.value.map((level: ILevel) => ( + + {level.name} + + ))} + + +
+ ); +}; +const Elevations = () => { + return ( +
+ +
+ ); +}; + +const VisibilityOption = () => { + const [option, setOption] = useState(<>); + useSignalEffect(() => { + switch (visibilityStateSignal.value) { + case "3D": + setOption(<>); + break; + case "Elevation": + setOption(); + break; + case "Plane": + setOption(); + break; + } + }); + return ( +
+
+ {option} + {VisibilityStates.map( + ({icon, tooltip}: IVisibilityButton, index: number) => ( + + ) + )} +
+ ); +}; + +export default memo(VisibilityOption); diff --git a/src/BimModel/src/ModelingComponent/src/WorkPlaneOption/WorkPlaneOption.tsx b/src/BimModel/src/ModelingComponent/src/WorkPlaneOption/WorkPlaneOption.tsx new file mode 100644 index 0000000..f5a44cc --- /dev/null +++ b/src/BimModel/src/ModelingComponent/src/WorkPlaneOption/WorkPlaneOption.tsx @@ -0,0 +1,13 @@ +import React, {memo} from "react"; + +const WorkPlaneOption = () => { + return ( +
+
+ +
+
+ ); +}; + +export default memo(WorkPlaneOption); diff --git a/src/BimModel/src/ModelingComponent/src/constants.tsx b/src/BimModel/src/ModelingComponent/src/constants.tsx index 4eb1738..12e6196 100644 --- a/src/BimModel/src/ModelingComponent/src/constants.tsx +++ b/src/BimModel/src/ModelingComponent/src/constants.tsx @@ -4,36 +4,25 @@ import { IModeling, IModelingToolTabs, ITool, -} from "@BimModel/src/types"; + IVisibilityButton, +} from "@ModelingComponent/types"; //#region Draw import {AiOutlineCheckCircle as Finish} from "react-icons/ai"; import {PiLineSegmentDuotone as Line} from "react-icons/pi"; import {BsBoundingBoxCircles as Rectangular} from "react-icons/bs"; -import {BsDashCircleDotted as Arc} from "react-icons/bs"; +import {CgArrowLongUp as PickLine} from "react-icons/cg"; +import {BiCircle as Arc} from "react-icons/bi"; import {MdOutlineShare as PolyLines} from "react-icons/md"; import {TiDeleteOutline as Cancel} from "react-icons/ti"; import {FaRegCircleDot as Point} from "react-icons/fa6"; export const iConClassName = "w-[30px] h-[30px]"; const onClick = (drawType: IDrawType) => { - switch (drawType) { - case "Finish": - case "Cancel": - drawingTypeSignal.value = "None"; - modelingSignal.value = null; - break; - case "Line": - break; - case "Rectangular": - break; - case "PolyLines": - break; - case "Arc": - break; - case "Point": - break; - default: - break; + if (drawType === "Finish" || drawType === "Cancel") { + drawingTypeSignal.value = "None"; + modelingSignal.value = null; + return; } + drawingTypeSignal.value = drawType; }; export const Modelings = { @@ -67,6 +56,11 @@ export const Modelings = { drawType: "Point", onClick, } as IModeling, + PickLine: { + icon: , + drawType: "PickLine", + onClick, + } as IModeling, Cancel: { icon: , drawType: "Cancel", @@ -74,6 +68,27 @@ export const Modelings = { } as IModeling, }; +//#endregion +//#region IVisibilityButton +import {BsBoxSeam as Icon3D} from "react-icons/bs"; +import {FiGrid as IconElevation} from "react-icons/fi"; +import {LuGrid as IConPlane} from "react-icons/lu"; + +export const VisibilityStates: IVisibilityButton[] = [ + { + tooltip: "3D", + icon: , + }, + { + tooltip: "Plane", + icon: , + }, + { + tooltip: "Elevation", + icon: , + }, +]; + //#endregion //#region Architecture diff --git a/src/BimModel/src/ModelingComponent/src/utils.ts b/src/BimModel/src/ModelingComponent/src/utils.ts index ad3abde..4f07f09 100644 --- a/src/BimModel/src/ModelingComponent/src/utils.ts +++ b/src/BimModel/src/ModelingComponent/src/utils.ts @@ -1,18 +1,19 @@ -import {IModeling} from "@BimModel/src/types"; +import {IModeling} from "@ModelingComponent/types"; import {Modelings} from "./constants"; export function getModelings(type: string): IModeling[] { if (!type) return []; - const {Finish, Cancel, Line, Rectangular, Arc, PolyLines, Point} = Modelings; + const {Finish, Cancel, Line, Rectangular, Arc, PolyLines, Point, PickLine} = + Modelings; switch (type) { case "Wall": return [Line, Rectangular, Arc, PolyLines]; case "Floor": - return [Finish, Line, Rectangular, Arc, PolyLines, Cancel]; + return [Finish, Line, Rectangular, Arc, PolyLines, PickLine, Cancel]; case "Ceiling": - return [Finish, Line, Rectangular, Arc, PolyLines, Cancel]; + return [Finish, Line, Rectangular, Arc, PolyLines, PickLine, Cancel]; case "Roof": - return [Finish, Line, Rectangular, Arc, PolyLines, Cancel]; + return [Finish, Line, Rectangular, Arc, PolyLines, PickLine, Cancel]; case "Column": return [Point, Cancel]; case "Door": @@ -26,9 +27,9 @@ export function getModelings(type: string): IModeling[] { case "Structure Wall": return [Line, Rectangular, Arc, PolyLines]; case "Structure Slab": - return [Finish, Line, Rectangular, Arc, PolyLines, Cancel]; + return [Finish, Line, Rectangular, Arc, PolyLines, PickLine, Cancel]; case "Structure Foundation": - return [Finish, Line, Rectangular, Arc, PolyLines, Cancel]; + return [Finish, Line, Rectangular, Arc, PolyLines, PickLine, Cancel]; case "ReinForcement": return []; case "Duct": diff --git a/src/BimModel/src/types/modeling.ts b/src/BimModel/src/ModelingComponent/types.ts similarity index 76% rename from src/BimModel/src/types/modeling.ts rename to src/BimModel/src/ModelingComponent/types.ts index e7299c5..f62e8ea 100644 --- a/src/BimModel/src/types/modeling.ts +++ b/src/BimModel/src/ModelingComponent/types.ts @@ -8,6 +8,7 @@ export type IDrawType = | "Cancel" | "Finish" | "Point" + | "PickLine" | "None"; export interface IModeling { icon: ReactElement; @@ -27,3 +28,8 @@ export interface ITool { type: string; icon: ReactNode; } +export type IVisibility = "3D" | "Plane" | "Elevation"; +export interface IVisibilityButton { + tooltip: IVisibility; + icon: ReactNode; +} diff --git a/src/BimModel/src/ProjectComponent/index.ts b/src/BimModel/src/ProjectComponent/index.ts index ea92166..a239a44 100644 --- a/src/BimModel/src/ProjectComponent/index.ts +++ b/src/BimModel/src/ProjectComponent/index.ts @@ -1,22 +1,52 @@ +import {effect} from "@preact/signals-react"; import {Components} from "../Components"; import {ToolComponent} from "../Tool"; import {Component, Disposable, UUID} from "../types"; +import {CubeMapComponent} from "../CubeMapComponent"; +import { + clippingPlanesSignal, + currentLevelSignal, + visibilityStateSignal, +} from "../Signals"; +import {LevelSystem} from "../system"; +import {RendererComponent} from "../RendererComponent"; export * from "./src"; export class ProjectComponent extends Component implements Disposable { static readonly uuid = UUID.ProjectComponent; enabled = false; - - get() { - return ProjectComponent.uuid; + get camera() { + return this.components.tools.get(RendererComponent)?.camera; } + /** * */ constructor(components: Components) { super(components); this.components.tools.add(ProjectComponent.uuid, this); + effect(() => { + this.components.tools.get(CubeMapComponent)!.visible = + visibilityStateSignal.value === "3D"; + + if (visibilityStateSignal.value === "3D") { + this.camera!.resetState(); + clippingPlanesSignal.value = []; + this.components.tools.get(LevelSystem)!.level = null; + } else { + this.camera!.saveState(); + if (visibilityStateSignal.value === "Plane") { + this.components.tools.get(LevelSystem)!.level = + currentLevelSignal.value; + } else { + // + } + } + }); } async dispose() {} + get() { + return ProjectComponent.uuid; + } } ToolComponent.libraryUUIDs.add(ProjectComponent.uuid); diff --git a/src/BimModel/src/types/project.ts b/src/BimModel/src/ProjectComponent/types.ts similarity index 74% rename from src/BimModel/src/types/project.ts rename to src/BimModel/src/ProjectComponent/types.ts index 9a52e1f..f391a12 100644 --- a/src/BimModel/src/types/project.ts +++ b/src/BimModel/src/ProjectComponent/types.ts @@ -1,4 +1,5 @@ export type IUnit = "m" | "mm"; +export type ILineType = "thin" | "thickness"; export interface IProjectInfo { address: string; } diff --git a/src/BimModel/src/RendererComponent/index.ts b/src/BimModel/src/RendererComponent/index.ts index dd48bb4..a9fdebd 100644 --- a/src/BimModel/src/RendererComponent/index.ts +++ b/src/BimModel/src/RendererComponent/index.ts @@ -13,7 +13,9 @@ import { UUID, } from "../types"; import {CSS2DRenderer} from "three/examples/jsm/renderers/CSS2DRenderer"; -import {Camera, Grid, PostProduction} from "./src"; +import {Camera, PostProduction} from "./src"; +import {WorkPlaneSystem} from "../system"; +export * from "./src"; /** * */ @@ -25,10 +27,9 @@ export class RendererComponent enabled = false; size: THREE.Vector2 = new THREE.Vector2(); public camera!: Camera; - private labelRenderer!: CSS2DRenderer; - private renderer!: THREE.WebGLRenderer; - private grid!: Grid; - private postProduction!: PostProduction; + public labelRenderer!: CSS2DRenderer; + public renderer!: THREE.WebGLRenderer; + public postProduction!: PostProduction; set setupEvents(setupEvents: boolean) { const controls = this.camera.cameraControls; const domElement = this.components.canvas; @@ -39,6 +40,7 @@ export class RendererComponent controls.addEventListener("wake", this.onWake); controls.addEventListener("controlend", this.onControlEnd); controls.addEventListener("sleep", this.onSleep); + controls.addEventListener("update", this.onUpdate); domElement.addEventListener("wheel", this.onWheel); } else { controls.removeEventListener("control", this.onControl); @@ -46,6 +48,7 @@ export class RendererComponent controls.removeEventListener("wake", this.onWake); controls.removeEventListener("controlend", this.onControlEnd); controls.removeEventListener("sleep", this.onSleep); + controls.removeEventListener("update", this.onUpdate); domElement.removeEventListener("wheel", this.onWheel); } } @@ -54,23 +57,22 @@ export class RendererComponent private lastWheelUsed = 0; private lastResized = 0; private resizeDelay = 200; + constructor(components: Components) { super(components); this.components.tools.add(RendererComponent.uuid, this); this.camera = new Camera(this.components); this.camera.enabled = true; - this.grid = new Grid(this.components, this.camera); + this.initRenderer(); this.initLabelRenderer(); this.initPostProduction(); - this.postProduction.customEffects.excludedMeshes.push(this.grid.grid); + this.setupEvents = true; } async dispose() { this.enabled = false; this.setupEvents = false; - this.grid?.dispose(); - (this.grid as any) = null; this.camera?.dispose(); (this.camera as any) = null; this.postProduction?.dispose(); @@ -162,19 +164,19 @@ export class RendererComponent this.postProduction.enabled = true; this.postProduction.customEffects.outlineEnabled = true; } - onControlStart = (_event: any) => { + private onControlStart = (_event: any) => { this.isUserControllingCamera = true; }; - onWake = (_event: any) => { + private onWake = (_event: any) => { this.isControlSleeping = false; }; - onControl = (_event: any) => { + private onControl = (_event: any) => { if (!this.postProduction.enabled) return; this.postProduction.visible = false; }; - onControlEnd = (_event: any) => { + private onControlEnd = (_event: any) => { if (!this.postProduction.enabled) return; this.isUserControllingCamera = false; if (!this.isUserControllingCamera && this.isControlSleeping) { @@ -182,12 +184,12 @@ export class RendererComponent } }; - onWheel = (_event: any) => { + private onWheel = (_event: any) => { if (!this.postProduction.enabled) return; this.lastResized = performance.now(); }; - onSleep = (_event: any) => { + private onSleep = (_event: any) => { if (!this.postProduction.enabled) return; this.isControlSleeping = true; const currentWheel = performance.now(); @@ -198,5 +200,9 @@ export class RendererComponent } }, 100); }; + private onUpdate = () => { + const materialGrid = this.components.tools.get(WorkPlaneSystem).material; + materialGrid.uniforms.uZoom.value = this.camera.currentCamera.zoom; + }; } ToolComponent.libraryUUIDs.add(RendererComponent.uuid); diff --git a/src/BimModel/src/RendererComponent/src/Camera.ts b/src/BimModel/src/RendererComponent/src/Camera.ts index 4da951f..f791904 100644 --- a/src/BimModel/src/RendererComponent/src/Camera.ts +++ b/src/BimModel/src/RendererComponent/src/Camera.ts @@ -5,7 +5,11 @@ import * as THREE from "three"; import CameraControls from "camera-controls"; import {Disposable, Resizeable, Updateable} from "../../types"; import {Components} from "../../Components"; -import {initOrthographicCamera, initPerspectiveCamera} from "../../utils"; +import { + defaultCameraFar, + initOrthographicCamera, + initPerspectiveCamera, +} from "../../utils"; CameraControls.install({ THREE, @@ -43,6 +47,10 @@ export class Camera implements Disposable, Resizeable, Updateable { get projection() { return this._projection; } + private state: {position: THREE.Vector3; target: THREE.Vector3} = { + position: new THREE.Vector3(), + target: new THREE.Vector3(), + }; constructor(private components: Components) { this.init(); @@ -81,7 +89,30 @@ export class Camera implements Disposable, Resizeable, Updateable { getSize() { return this.size; } - + setLookAt(position: THREE.Vector3, target: THREE.Vector3) { + this.cameraControls.setLookAt( + position.x, + position.y, + position.z, + target.x, + target.y, + target.z + ); + } + saveState() { + const {position, target} = this.state; + this.cameraControls.getPosition(position); + this.cameraControls.getTarget(target); + this.cameraControls.mouseButtons.left = 0; + } + resetState() { + if (!this.cameraControls) return; + const {position, target} = this.state; + this.setLookAt(position, target); + this.cameraControls.mouseButtons.left = 1; + this.currentCamera.far = defaultCameraFar; + this.currentCamera.near = -defaultCameraFar; + } private init() { const {width, height} = this.components.rect; this.size.x = width; @@ -97,5 +128,8 @@ export class Camera implements Disposable, Resizeable, Updateable { this.cameraControls.infinityDolly = true; this.cameraControls.dollySpeed = 2; this.cameraControls.setTarget(0, 0, 0); + const {position, target} = this.state; + this.cameraControls.getPosition(position); + this.cameraControls.getTarget(target); } } diff --git a/src/BimModel/src/RendererComponent/src/index.ts b/src/BimModel/src/RendererComponent/src/index.ts index 3f7d325..b525b09 100644 --- a/src/BimModel/src/RendererComponent/src/index.ts +++ b/src/BimModel/src/RendererComponent/src/index.ts @@ -1,3 +1,2 @@ export * from "./Camera"; -export * from "./Grid"; export * from "./PostProduction"; diff --git a/src/BimModel/src/Signals/ClippingPlanes/index.ts b/src/BimModel/src/Signals/ClippingPlanes/index.ts new file mode 100644 index 0000000..9edb735 --- /dev/null +++ b/src/BimModel/src/Signals/ClippingPlanes/index.ts @@ -0,0 +1,7 @@ +import {signal} from "@preact/signals-react"; +import * as THREE from "three"; + +export const clippingPlanesSignal = signal([]); +export function disposeClippingPlanes() { + clippingPlanesSignal.value = []; +} diff --git a/src/BimModel/src/Signals/Keyboard/index.ts b/src/BimModel/src/Signals/Keyboard/index.ts new file mode 100644 index 0000000..2332907 --- /dev/null +++ b/src/BimModel/src/Signals/Keyboard/index.ts @@ -0,0 +1,6 @@ +import {signal} from "@preact/signals-react"; + +export const keyboardSignal = signal(null); +export function disposeKeyboard() { + keyboardSignal.value = null; +} diff --git a/src/BimModel/src/Signals/Level/index.ts b/src/BimModel/src/Signals/Level/index.ts new file mode 100644 index 0000000..bff7bfb --- /dev/null +++ b/src/BimModel/src/Signals/Level/index.ts @@ -0,0 +1,9 @@ +import {signal} from "@preact/signals-react"; +import {ILevel} from "@system/08-level/types"; + +export const currentLevelSignal = signal(null); +export const listLevelSignal = signal([]); +export function disposeLevel() { + currentLevelSignal.value = null; + listLevelSignal.value = []; +} diff --git a/src/BimModel/src/Signals/Modeling/index.ts b/src/BimModel/src/Signals/Modeling/index.ts index 81208ac..1d4a4f3 100644 --- a/src/BimModel/src/Signals/Modeling/index.ts +++ b/src/BimModel/src/Signals/Modeling/index.ts @@ -1,12 +1,24 @@ -import {IDrawType, IModelingTool} from "@BimModel/src/types"; -import {signal} from "@preact/signals-react"; +import {IDrawType, IModelingTool} from "@ModelingComponent/types"; +import {effect, signal} from "@preact/signals-react"; // export const modelings = getAllModelingType(); export const disciplineSignal = signal("Files"); export const modelingSignal = signal(null); export const drawingTypeSignal = signal("None"); + +//#region +export const isModelingSignal = signal(false); +export const isOrthoSignal = signal(false); + +//#endregion +effect(() => { + if (!isModelingSignal.value) modelingSignal.value = null; +}); + export function disposeModeling() { disciplineSignal.value = "Files"; modelingSignal.value = null; drawingTypeSignal.value = "None"; + isModelingSignal.value = false; + isOrthoSignal.value = false; } diff --git a/src/BimModel/src/Signals/Project/index.ts b/src/BimModel/src/Signals/Project/index.ts index 28c4992..4aecc07 100644 --- a/src/BimModel/src/Signals/Project/index.ts +++ b/src/BimModel/src/Signals/Project/index.ts @@ -1,5 +1,6 @@ import {signal} from "@preact/signals-react"; export * from "./unit"; +export * from "./line"; export const projectSignal = signal(null); export const openProjectInfoSignal = signal(false); export const newProjectInfoSignal = signal(false); diff --git a/src/BimModel/src/Signals/Project/line.ts b/src/BimModel/src/Signals/Project/line.ts new file mode 100644 index 0000000..50bbdb9 --- /dev/null +++ b/src/BimModel/src/Signals/Project/line.ts @@ -0,0 +1,16 @@ +import {ILineType} from "@ProjectComponent/types"; +import {effect, signal} from "@preact/signals-react"; + +export const ListLineTypes: ILineType[] = ["thin", "thickness"]; +const storageKey = "lines"; + +function getDefaultLineType(): ILineType { + let unit = window.localStorage.getItem(storageKey) as ILineType; + if (!unit) unit = "thin" as ILineType; + return unit; +} + +export const lineTypeSignal = signal(getDefaultLineType()); +effect(() => { + window.localStorage.setItem(storageKey, lineTypeSignal.value); +}); diff --git a/src/BimModel/src/Signals/Project/unit.ts b/src/BimModel/src/Signals/Project/unit.ts index 8a7d2c6..59fd047 100644 --- a/src/BimModel/src/Signals/Project/unit.ts +++ b/src/BimModel/src/Signals/Project/unit.ts @@ -1,4 +1,4 @@ -import {IUnit} from "@BimModel/src/types"; +import {IUnit} from "@ProjectComponent/types"; import {effect, signal} from "@preact/signals-react"; export const ListUnits: IUnit[] = ["m", "mm"]; diff --git a/src/BimModel/src/Signals/Visibility/index.ts b/src/BimModel/src/Signals/Visibility/index.ts new file mode 100644 index 0000000..6157ab6 --- /dev/null +++ b/src/BimModel/src/Signals/Visibility/index.ts @@ -0,0 +1,9 @@ +import {IVisibility} from "@ModelingComponent/types"; +import {signal} from "@preact/signals-react"; + +// export const modelings = getAllModelingType(); +export const visibilityStateSignal = signal("3D"); + +export function disposeVisibility() { + visibilityStateSignal.value = "3D"; +} diff --git a/src/BimModel/src/Signals/index.ts b/src/BimModel/src/Signals/index.ts index 0c7565d..aac21cf 100644 --- a/src/BimModel/src/Signals/index.ts +++ b/src/BimModel/src/Signals/index.ts @@ -1,10 +1,22 @@ import {disposeModeling} from "./Modeling"; import {disposeProject} from "./Project"; +import {disposeVisibility} from "./Visibility"; +import {disposeLevel} from "./Level"; +import {disposeKeyboard} from "./Keyboard"; +import {disposeClippingPlanes} from "./ClippingPlanes"; export * from "./Modeling"; export * from "./Project"; +export * from "./Visibility"; +export * from "./Level"; +export * from "./Keyboard"; +export * from "./ClippingPlanes"; export function disposeSignals() { disposeModeling(); disposeProject(); + disposeVisibility(); + disposeLevel(); + disposeKeyboard(); + disposeClippingPlanes(); } diff --git a/src/BimModel/src/StructureComponent/index.ts b/src/BimModel/src/StructureComponent/index.ts index f61c798..6e14b24 100644 --- a/src/BimModel/src/StructureComponent/index.ts +++ b/src/BimModel/src/StructureComponent/index.ts @@ -9,6 +9,7 @@ export class StructureComponent { static readonly uuid = UUID.StructureComponent; enabled = false; + private container!: HTMLDivElement; get ProjectComponent(): ProjectComponent { return this.components.tools.get(ProjectComponent); } @@ -24,5 +25,6 @@ export class StructureComponent get() { return StructureComponent.uuid; } + init(_structure: HTMLDivElement) {} } ToolComponent.libraryUUIDs.add(StructureComponent.uuid); diff --git a/src/BimModel/src/Tool/index.ts b/src/BimModel/src/Tool/index.ts index 069e119..3e7704f 100644 --- a/src/BimModel/src/Tool/index.ts +++ b/src/BimModel/src/Tool/index.ts @@ -86,6 +86,7 @@ export class ToolComponent tool.enabled = false; if (tool.isDisposeable()) { await tool.dispose(); + this.notifyDispose(tool); } } } @@ -103,4 +104,11 @@ export class ToolComponent - If you're using a platform tool, verify the uuid isn't misspelled or contact the tool creator.` ); } + notifyDispose(tool: Component) { + const isDev = import.meta.env.DEV; + if (!isDev) return; + if (!tool.constructor || !tool.constructor.name) return; + const name = tool.constructor.name; + console.log(`${name} disposed!`); + } } diff --git a/src/BimModel/src/index.ts b/src/BimModel/src/index.ts index 9562378..53181bd 100644 --- a/src/BimModel/src/index.ts +++ b/src/BimModel/src/index.ts @@ -7,4 +7,5 @@ export * from "./PropertyComponent"; export * from "./CubeMapComponent"; export * from "./ProjectComponent"; export * from "./Signals"; +export * from "./system"; export * from "./types"; diff --git a/src/BimModel/src/system/00-base/BaseCategory.ts b/src/BimModel/src/system/00-base/BaseCategory.ts deleted file mode 100644 index fd5a3e3..0000000 --- a/src/BimModel/src/system/00-base/BaseCategory.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as WEBIFC from "web-ifc"; -import {IfcCategoryMap} from "./IfcCategoryMap"; -export type IfcClass = (typeof WEBIFC)[keyof typeof WEBIFC] extends string - ? keyof typeof WEBIFC - : never; - -export abstract class BaseCategory { - abstract categoryName: IfcClass; -} diff --git a/src/BimModel/src/system/00-base/BaseElement.ts b/src/BimModel/src/system/00-base/BaseElement.ts deleted file mode 100644 index 7a27cc4..0000000 --- a/src/BimModel/src/system/00-base/BaseElement.ts +++ /dev/null @@ -1 +0,0 @@ -export abstract class BaseElement {} diff --git a/src/BimModel/src/system/00-base/BaseElementType.ts b/src/BimModel/src/system/00-base/BaseElementType.ts deleted file mode 100644 index 899da5a..0000000 --- a/src/BimModel/src/system/00-base/BaseElementType.ts +++ /dev/null @@ -1 +0,0 @@ -export abstract class BaseElementType {} diff --git a/src/BimModel/src/system/00-base/BaseFamily.ts b/src/BimModel/src/system/00-base/BaseFamily.ts deleted file mode 100644 index a8e15f0..0000000 --- a/src/BimModel/src/system/00-base/BaseFamily.ts +++ /dev/null @@ -1 +0,0 @@ -export abstract class BaseFamily {} diff --git a/src/BimModel/src/system/00-base/BaseGeometry.ts b/src/BimModel/src/system/00-base/BaseGeometry.ts deleted file mode 100644 index 15e8b64..0000000 --- a/src/BimModel/src/system/00-base/BaseGeometry.ts +++ /dev/null @@ -1 +0,0 @@ -export abstract class BaseGeometry {} diff --git a/src/BimModel/src/system/00-base/BaseParameter.ts b/src/BimModel/src/system/00-base/BaseParameter.ts deleted file mode 100644 index 848f995..0000000 --- a/src/BimModel/src/system/00-base/BaseParameter.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as WEBIFC from "web-ifc"; - -export type IBaseParameterValue = - | "IFCLOGICAL" - | "IFCBOOLEAN" - | "IFCREAL" - | "IFCINTEGER" - | "IFCIDENTIFIER"; -export abstract class BaseParameter { - abstract name: string; - abstract value: string; - abstract valueType: IBaseParameterValue; -} diff --git a/src/BimModel/src/system/00-base/BaseParameterGroup.ts b/src/BimModel/src/system/00-base/BaseParameterGroup.ts deleted file mode 100644 index 42607d3..0000000 --- a/src/BimModel/src/system/00-base/BaseParameterGroup.ts +++ /dev/null @@ -1 +0,0 @@ -export abstract class BaseParameterGroup {} diff --git a/src/BimModel/src/system/00-base/BaseSchema.ts b/src/BimModel/src/system/00-base/BaseSchema.ts deleted file mode 100644 index 33822a5..0000000 --- a/src/BimModel/src/system/00-base/BaseSchema.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {IFC4, IFC2X3, IFC4X3, Schemas} from "web-ifc"; - -export abstract class BaseSchema { - abstract schemaName: Schemas; - get schema() { - if (!this.schemaName) throw new Error("Need to define schema name"); - switch (this.schemaName) { - case "IFC2X3": - return IFC2X3; - case "IFC4": - return IFC4; - case "IFC4X3": - return IFC4X3; - default: - return IFC4; - } - } -} diff --git a/src/BimModel/src/system/00-base/IBaseExport.ts b/src/BimModel/src/system/00-base/IBaseExport.ts deleted file mode 100644 index 03179c4..0000000 --- a/src/BimModel/src/system/00-base/IBaseExport.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface IBaseExport { - getIfc: () => any; - toIfc: () => string; - toDotBim: () => string; -} diff --git a/src/BimModel/src/system/00-base/IfcEnum.ts b/src/BimModel/src/system/00-base/IfcEnum.ts new file mode 100644 index 0000000..c5b502e --- /dev/null +++ b/src/BimModel/src/system/00-base/IfcEnum.ts @@ -0,0 +1,24 @@ +import {IFC4} from "web-ifc"; +export const IfcRoleEnum = Object.keys(IFC4.IfcRoleEnum); +export const IfcAddressTypeEnum = Object.keys(IFC4.IfcAddressTypeEnum); +export const IfcStateEnum = Object.keys(IFC4.IfcStateEnum); +export const IfcChangeActionEnum = Object.keys(IFC4.IfcChangeActionEnum); +export const IfcUnitEnum = Object.keys(IFC4.IfcUnitEnum); +export const IfcSIUnitName = Object.keys(IFC4.IfcSIUnitName); +export const IfcGeometricProjectionEnum = Object.keys( + IFC4.IfcGeometricProjectionEnum +); +export const IfcSIPrefix = Object.keys(IFC4.IfcSIPrefix); +export const IfcWallTypeEnum = Object.keys(IFC4.IfcWallTypeEnum); +export const IfcColumnTypeEnum = Object.keys(IFC4.IfcColumnTypeEnum); +export const IfcDoorTypeEnum = Object.keys(IFC4.IfcDoorTypeEnum); +export const IfcWindowTypeEnum = Object.keys(IFC4.IfcWindowTypeEnum); +export const IfcBeamTypeEnums = Object.keys(IFC4.IfcBeamTypeEnum); +export const IfcSlabTypeEnums = Object.keys(IFC4.IfcSlabTypeEnum); +export const IfcDuctFittingTypeEnum = Object.keys(IFC4.IfcDuctFittingTypeEnum); +export const IfcDuctSegmentTypeEnum = Object.keys(IFC4.IfcDuctSegmentTypeEnum); +export const IfcPipeFittingTypeEnum = Object.keys(IFC4.IfcPipeFittingTypeEnum); +export const IfcPipeSegmentTypeEnum = Object.keys(IFC4.IfcPipeSegmentTypeEnum); +export const IfcReinforcingBarTypeEnum = Object.keys( + IFC4.IfcReinforcingBarTypeEnum +); diff --git a/src/BimModel/src/system/00-base/Utils.ts b/src/BimModel/src/system/00-base/Utils.ts index e69de29..16f5e72 100644 --- a/src/BimModel/src/system/00-base/Utils.ts +++ b/src/BimModel/src/system/00-base/Utils.ts @@ -0,0 +1,5 @@ +import {IFC4} from "web-ifc"; +import {v4 as uuid4} from "uuid"; +export function globalId(): IFC4.IfcGloballyUniqueId { + return new IFC4.IfcGloballyUniqueId(uuid4()); +} diff --git a/src/BimModel/src/system/00-base/index.ts b/src/BimModel/src/system/00-base/index.ts index 9a08a1d..5e21c03 100644 --- a/src/BimModel/src/system/00-base/index.ts +++ b/src/BimModel/src/system/00-base/index.ts @@ -1,11 +1,4 @@ -export * from "./IBaseExport"; -export * from "./BaseSchema"; -export * from "./BaseGeometry"; -export * from "./BaseCategory"; -export * from "./BaseElement"; -export * from "./BaseElementType"; -export * from "./BaseParameterGroup"; -export * from "./BaseParameter"; -export * from "./BaseFamily"; export * from "./IfcCategoryMap"; export * from "./IfcElements"; +export * from "./IfcEnum"; +export * from "./utils"; diff --git a/src/BimModel/src/system/01-geometry/index.ts b/src/BimModel/src/system/01-geometry/index.ts index 709facc..ef26758 100644 --- a/src/BimModel/src/system/01-geometry/index.ts +++ b/src/BimModel/src/system/01-geometry/index.ts @@ -1 +1,26 @@ -export const geometry = 5; +/** + * @module GeometrySystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class GeometrySystem extends Component implements Disposable { + static readonly uuid = systemGUID.geometry; + enabled = false; + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(GeometrySystem.uuid, this); + } + async dispose() {} + + get() { + return GeometrySystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(GeometrySystem.uuid); diff --git a/src/BimModel/src/system/01-geometry/src/index.ts b/src/BimModel/src/system/01-geometry/src/index.ts new file mode 100644 index 0000000..00f0f51 --- /dev/null +++ b/src/BimModel/src/system/01-geometry/src/index.ts @@ -0,0 +1 @@ +export * from "./location"; diff --git a/src/BimModel/src/system/01-geometry/src/location/LocationArc.ts b/src/BimModel/src/system/01-geometry/src/location/LocationArc.ts new file mode 100644 index 0000000..39239fc --- /dev/null +++ b/src/BimModel/src/system/01-geometry/src/location/LocationArc.ts @@ -0,0 +1,4 @@ +import {Disposable} from "@BimModel/src"; +export class LocationArc implements Disposable { + async dispose() {} +} diff --git a/src/BimModel/src/system/01-geometry/src/location/LocationCurve.ts b/src/BimModel/src/system/01-geometry/src/location/LocationCurve.ts new file mode 100644 index 0000000..e98c94d --- /dev/null +++ b/src/BimModel/src/system/01-geometry/src/location/LocationCurve.ts @@ -0,0 +1,4 @@ +import {Disposable} from "@BimModel/src"; +export class LocationCurve implements Disposable { + async dispose() {} +} diff --git a/src/BimModel/src/system/01-geometry/src/location/LocationLine.ts b/src/BimModel/src/system/01-geometry/src/location/LocationLine.ts new file mode 100644 index 0000000..d0c38eb --- /dev/null +++ b/src/BimModel/src/system/01-geometry/src/location/LocationLine.ts @@ -0,0 +1,4 @@ +import {Disposable} from "@BimModel/src"; +export class LocationLine implements Disposable { + async dispose() {} +} diff --git a/src/BimModel/src/system/01-geometry/src/location/LocationPoint.ts b/src/BimModel/src/system/01-geometry/src/location/LocationPoint.ts new file mode 100644 index 0000000..bb402e4 --- /dev/null +++ b/src/BimModel/src/system/01-geometry/src/location/LocationPoint.ts @@ -0,0 +1,4 @@ +import {Disposable} from "@BimModel/src"; +export class LocationPoint implements Disposable { + async dispose() {} +} diff --git a/src/BimModel/src/system/01-geometry/src/location/index.ts b/src/BimModel/src/system/01-geometry/src/location/index.ts new file mode 100644 index 0000000..a115e51 --- /dev/null +++ b/src/BimModel/src/system/01-geometry/src/location/index.ts @@ -0,0 +1,4 @@ +export * from "./LocationArc"; +export * from "./LocationCurve"; +export * from "./LocationLine"; +export * from "./LocationPoint"; diff --git a/src/BimModel/src/system/01-geometry/types.ts b/src/BimModel/src/system/01-geometry/types.ts new file mode 100644 index 0000000..f17349e --- /dev/null +++ b/src/BimModel/src/system/01-geometry/types.ts @@ -0,0 +1,10 @@ +export const GeometryCSS = { + snap: { + endpoint: "snap-endpoint", + endLine: "endLine", + intersect: "snap-intersect", + middle: "snap-middle", + }, + tag: "tag", + tagInfo: "tag info", +}; diff --git a/src/BimModel/src/system/02-element/index.ts b/src/BimModel/src/system/02-element/index.ts index 409f905..79fc16b 100644 --- a/src/BimModel/src/system/02-element/index.ts +++ b/src/BimModel/src/system/02-element/index.ts @@ -1 +1,27 @@ -export const element1 = 5; +/** + * @module ElementSystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class ElementSystem extends Component implements Disposable { + static readonly uuid = systemGUID.element; + enabled = false; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(ElementSystem.uuid, this); + } + async dispose() {} + + get() { + return ElementSystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(ElementSystem.uuid); diff --git a/src/BimModel/src/system/02-element/src/ElementId.ts b/src/BimModel/src/system/02-element/src/ElementId.ts new file mode 100644 index 0000000..176a77d --- /dev/null +++ b/src/BimModel/src/system/02-element/src/ElementId.ts @@ -0,0 +1,6 @@ +export class ElementId { + private static readonly limitRedo = 5 as const; + static currentId = 0; + static undoIds: number[] = []; + static redoIds: number[] = []; +} diff --git a/src/BimModel/src/system/02-element/src/index.ts b/src/BimModel/src/system/02-element/src/index.ts new file mode 100644 index 0000000..b2f0471 --- /dev/null +++ b/src/BimModel/src/system/02-element/src/index.ts @@ -0,0 +1 @@ +export * from "./ElementId"; diff --git a/src/BimModel/src/system/03-element-type/index.ts b/src/BimModel/src/system/03-element-type/index.ts index 2a43ae6..3ec1f61 100644 --- a/src/BimModel/src/system/03-element-type/index.ts +++ b/src/BimModel/src/system/03-element-type/index.ts @@ -1 +1,27 @@ -export const element2 = 5; +/** + * @module ElementTypeSystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class ElementTypeSystem extends Component implements Disposable { + static readonly uuid = systemGUID.elementType; + enabled = false; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(ElementTypeSystem.uuid, this); + } + async dispose() {} + + get() { + return ElementTypeSystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(ElementTypeSystem.uuid); diff --git a/src/BimModel/src/system/04-draw-tool/index.ts b/src/BimModel/src/system/04-draw-tool/index.ts index d558a5d..ad2c4f7 100644 --- a/src/BimModel/src/system/04-draw-tool/index.ts +++ b/src/BimModel/src/system/04-draw-tool/index.ts @@ -1 +1,33 @@ -export const element3 = 5; +/** + * @module DrawToolSystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +import {BaseDraw} from "./src"; +export class DrawToolSystem extends Component implements Disposable { + static readonly uuid = systemGUID.drawTool; + enabled = false; + private draws: {[name: string]: BaseDraw} = {}; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(DrawToolSystem.uuid, this); + } + async dispose() { + for (const name in this.draws) { + this.draws[name]?.dispose(); + } + } + + get() { + return DrawToolSystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(DrawToolSystem.uuid); diff --git a/src/BimModel/src/system/04-draw-tool/src/BaseDraw.ts b/src/BimModel/src/system/04-draw-tool/src/BaseDraw.ts new file mode 100644 index 0000000..d881497 --- /dev/null +++ b/src/BimModel/src/system/04-draw-tool/src/BaseDraw.ts @@ -0,0 +1,45 @@ +/** + * @module BaseDraw + */ +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {MaterialComponent} from "@BimModel/src/MaterialComponent"; +import {LineMaterial} from "three/examples/jsm/lines/LineMaterial"; +export abstract class BaseDraw { + abstract onClick: (e: MouseEvent) => void; + abstract onMouseMove: (e: MouseEvent) => void; + abstract onKeyDown: (e: KeyboardEvent) => void; + abstract onMousedown: (e: MouseEvent) => void; + abstract onFinished: () => void; + abstract onCallBack: (value?: number) => void; + abstract dispose: () => void; + + get LocationMaterial(): LineMaterial { + return this.components.tools.get(MaterialComponent) + ?.LocationMaterial as LineMaterial; + } + get container() { + return this.components.container; + } + private _setupEvent = false; + set setupEvent(enabled: boolean) { + if (!this.container) return; + if (!this._setupEvent === enabled) return; + if (enabled) { + this.container.addEventListener("click", this.onClick); + this.container.addEventListener("mousemove", this.onMouseMove); + this.container.addEventListener("mousedown", this.onMousedown); + } else { + this.container.removeEventListener("click", this.onClick); + this.container.removeEventListener("mousemove", this.onMouseMove); + this.container.removeEventListener("mousedown", this.onMousedown); + } + } + get setupEvent() { + return this._setupEvent; + } + /** + * + */ + constructor(private components: Components) {} +} diff --git a/src/BimModel/src/system/04-draw-tool/src/index.ts b/src/BimModel/src/system/04-draw-tool/src/index.ts new file mode 100644 index 0000000..9b7f2d4 --- /dev/null +++ b/src/BimModel/src/system/04-draw-tool/src/index.ts @@ -0,0 +1 @@ +export * from "./BaseDraw"; diff --git a/src/BimModel/src/system/05-parameter/index.ts b/src/BimModel/src/system/05-parameter/index.ts index 09a82ac..47238cf 100644 --- a/src/BimModel/src/system/05-parameter/index.ts +++ b/src/BimModel/src/system/05-parameter/index.ts @@ -1 +1,27 @@ -export const element5 = 5; +/** + * @module ParameterSystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class ParameterSystem extends Component implements Disposable { + static readonly uuid = systemGUID.parameter; + enabled = false; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(ParameterSystem.uuid, this); + } + async dispose() {} + + get() { + return ParameterSystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(ParameterSystem.uuid); diff --git a/src/BimModel/src/system/05-parameter/src/Parameter.ts b/src/BimModel/src/system/05-parameter/src/Parameter.ts index 82f7b42..094bbad 100644 --- a/src/BimModel/src/system/05-parameter/src/Parameter.ts +++ b/src/BimModel/src/system/05-parameter/src/Parameter.ts @@ -1,7 +1,5 @@ -import {BaseParameter, IBaseParameterValue} from "../../00-base"; - -export class Parameter extends BaseParameter { +export class Parameter { name!: string; value!: string; - valueType!: IBaseParameterValue; + valueType!: string; } diff --git a/src/BimModel/src/system/06-category/index.ts b/src/BimModel/src/system/06-category/index.ts index 5f2cb35..ee8c315 100644 --- a/src/BimModel/src/system/06-category/index.ts +++ b/src/BimModel/src/system/06-category/index.ts @@ -1 +1,27 @@ -export const element6 = 5; +/** + * @module CategorySystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class CategorySystem extends Component implements Disposable { + static readonly uuid = systemGUID.category; + enabled = false; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(CategorySystem.uuid, this); + } + async dispose() {} + + get() { + return CategorySystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(CategorySystem.uuid); diff --git a/src/BimModel/src/system/07-family/index.ts b/src/BimModel/src/system/07-family/index.ts index ac109bd..c46628b 100644 --- a/src/BimModel/src/system/07-family/index.ts +++ b/src/BimModel/src/system/07-family/index.ts @@ -1 +1,27 @@ -export const element7 = 5; +/** + * @module FamilySystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class FamilySystem extends Component implements Disposable { + static readonly uuid = systemGUID.family; + enabled = false; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(FamilySystem.uuid, this); + } + async dispose() {} + + get() { + return FamilySystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(FamilySystem.uuid); diff --git a/src/BimModel/src/system/08-level/index.ts b/src/BimModel/src/system/08-level/index.ts new file mode 100644 index 0000000..45e429d --- /dev/null +++ b/src/BimModel/src/system/08-level/index.ts @@ -0,0 +1,89 @@ +/** + * @module LevelSystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +import {ILevel} from "./types"; +import { + clippingPlanesSignal, + currentLevelSignal, + listLevelSignal, +} from "@BimModel/src/Signals"; +import {RendererComponent} from "@BimModel/src/RendererComponent"; +import {WorkPlaneSystem} from "../12-work-plane"; + +const defaultLevels: ILevel[] = [ + { + name: "Level 1", + index: 0, + elevation: 0.0, + }, + { + name: "Level 2", + index: 1, + elevation: 4.0, + }, +]; +const upVector = new THREE.Vector3(0, 1, 0); +const downVector = new THREE.Vector3(0, -1, 0); +const upPosition = new THREE.Vector3(0, 0, 0); +const downPosition = new THREE.Vector3(0, 0, 0); +const upPlane = new THREE.Plane(); +const downPlane = new THREE.Plane(); + +export class LevelSystem extends Component implements Disposable { + static readonly uuid = systemGUID.level; + enabled = false; + get renderer() { + return this.components.tools.get(RendererComponent); + } + get workPlane() { + return this.components.tools.get(WorkPlaneSystem); + } + get camera() { + return this.renderer?.camera; + } + set level(level: ILevel | null) { + if (!level) { + this.workPlane.grid.position.y = 0; + return; + } + if (!this.camera || this.camera.projection) return; + const {elevation} = level; + const camera = this.camera.currentCamera as THREE.OrthographicCamera; + camera.near = 0; + camera.far = 2; + upPosition.y = elevation + 1; + downPosition.y = elevation - 1; + this.camera.setLookAt(upPosition, downPosition); + upPlane.setFromNormalAndCoplanarPoint(upVector, upPosition); + downPlane.setFromNormalAndCoplanarPoint(downVector, downPosition); + clippingPlanesSignal.value = [upPlane, downPlane]; + this.workPlane.grid.position.y = elevation; + } + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(LevelSystem.uuid, this); + this.initDefaultLevel(); + } + async dispose() {} + + get() { + return LevelSystem.uuid; + } + private initDefaultLevel() { + listLevelSignal.value = defaultLevels; + currentLevelSignal.value = listLevelSignal.value[0]; + this.renderer.postProduction.customEffects.excludedMeshes.push( + this.workPlane.grid + ); + } +} +ToolComponent.libraryUUIDs.add(LevelSystem.uuid); diff --git a/src/BimModel/src/system/08-level/types.ts b/src/BimModel/src/system/08-level/types.ts new file mode 100644 index 0000000..edf68c6 --- /dev/null +++ b/src/BimModel/src/system/08-level/types.ts @@ -0,0 +1,5 @@ +export interface ILevel { + name: string; + index: number; + elevation: number; +} diff --git a/src/BimModel/src/system/09-grid/index.ts b/src/BimModel/src/system/09-grid/index.ts new file mode 100644 index 0000000..872a499 --- /dev/null +++ b/src/BimModel/src/system/09-grid/index.ts @@ -0,0 +1,27 @@ +/** + * @module GridSystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class GridSystem extends Component implements Disposable { + static readonly uuid = systemGUID.grid; + enabled = false; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(GridSystem.uuid, this); + } + async dispose() {} + + get() { + return GridSystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(GridSystem.uuid); diff --git a/src/BimModel/src/system/10-project/index.ts b/src/BimModel/src/system/10-project/index.ts new file mode 100644 index 0000000..0d6065f --- /dev/null +++ b/src/BimModel/src/system/10-project/index.ts @@ -0,0 +1,27 @@ +/** + * @module ProjectSystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class ProjectSystem extends Component implements Disposable { + static readonly uuid = systemGUID.project; + enabled = false; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(ProjectSystem.uuid, this); + } + async dispose() {} + + get() { + return ProjectSystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(ProjectSystem.uuid); diff --git a/src/BimModel/src/system/11-snapper/index.ts b/src/BimModel/src/system/11-snapper/index.ts new file mode 100644 index 0000000..d956c1d --- /dev/null +++ b/src/BimModel/src/system/11-snapper/index.ts @@ -0,0 +1,27 @@ +/** + * @module SnapperSystem + */ + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +export class SnapperSystem extends Component implements Disposable { + static readonly uuid = systemGUID.snapper; + enabled = false; + + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(SnapperSystem.uuid, this); + } + async dispose() {} + + get() { + return SnapperSystem.uuid; + } +} +ToolComponent.libraryUUIDs.add(SnapperSystem.uuid); diff --git a/src/BimModel/src/RendererComponent/src/Grid.ts b/src/BimModel/src/system/12-work-plane/index.ts similarity index 74% rename from src/BimModel/src/RendererComponent/src/Grid.ts rename to src/BimModel/src/system/12-work-plane/index.ts index 8316281..22bcda2 100644 --- a/src/BimModel/src/RendererComponent/src/Grid.ts +++ b/src/BimModel/src/system/12-work-plane/index.ts @@ -1,15 +1,20 @@ -import * as THREE from "three"; -import {Disposable} from "../../types"; -import {Components} from "../../Components"; -import {Camera} from "./Camera"; - /** - * An infinite grid. Created by - * [fyrestar](https://github.com/Fyrestar/THREE.InfiniteGridHelper) - * and translated to typescript by - * [dkaraush](https://github.com/dkaraush/THREE.InfiniteGridHelper/blob/master/InfiniteGridHelper.ts). + * @module WorkPlaneSystem */ -export class Grid implements Disposable { + +import * as THREE from "three"; +import {Components} from "@BimModel/src/Components"; +import {ToolComponent} from "@BimModel/src/Tool"; +import {Component, Disposable} from "@BimModel/src/types"; +import {systemGUID} from "../constants"; +import {Camera, RendererComponent} from "@BimModel/src/RendererComponent"; +export class WorkPlaneSystem extends Component implements Disposable { + static readonly uuid = systemGUID.workPlane; + static readonly size1 = 1; + static readonly size2 = 10; + static readonly distance = 500; + static readonly color = new THREE.Color(0x666666); + enabled = false; /** The material of the grid. */ get material() { return this._grid.material as THREE.ShaderMaterial; @@ -41,29 +46,22 @@ export class Grid implements Disposable { return this._grid.visible; } + get camera() { + return this.components.tools.get(RendererComponent)!.camera; + } get cameraControls() { return this.camera.cameraControls; } - set setupEvents(active: boolean) { - if (active) { - this.cameraControls.addEventListener("update", this.updateZoom); - } else { - this.cameraControls.removeEventListener("update", this.updateZoom); - } - } + get grid() { return this._grid; } - constructor( - private components: Components, - private camera: Camera, - color = new THREE.Color(0x666666), - size1 = 1, - size2 = 10, - distance = 500 - ) { - // Source: https://github.com/dkaraush/THREE.InfiniteGridHelper/blob/master/InfiniteGridHelper.ts - // Author: Fyrestar https://mevedia.com (https://github.com/Fyrestar/THREE.InfiniteGridHelper) + /** + * + */ + constructor(components: Components) { + super(components); + this.components.tools.add(WorkPlaneSystem.uuid, this); const geometry = new THREE.PlaneGeometry(2, 2, 1, 1); @@ -72,16 +70,16 @@ export class Grid implements Disposable { uniforms: { uSize1: { - value: size1, + value: WorkPlaneSystem.size1, }, uSize2: { - value: size2, + value: WorkPlaneSystem.size2, }, uColor: { - value: color, + value: WorkPlaneSystem.color, }, uDistance: { - value: distance, + value: WorkPlaneSystem.distance, }, uFade: { value: this._fade, @@ -164,15 +162,16 @@ export class Grid implements Disposable { this._grid = new THREE.Mesh(geometry, material); this._grid.frustumCulled = false; this.components.scene.add(this._grid); - this.setupEvents = true; } - - /** {@link Disposable.dispose} */ async dispose() { - this.setupEvents = false; + this.enabled = false; + (this._grid.material as THREE.ShaderMaterial).dispose(); + (this._grid.material as any) = null; + this._grid.geometry.dispose(); } - private updateZoom = () => { - this.material.uniforms.uZoom.value = this.camera.currentCamera.zoom; - }; + get() { + return WorkPlaneSystem.uuid; + } } +ToolComponent.libraryUUIDs.add(WorkPlaneSystem.uuid); diff --git a/src/BimModel/src/system/constants.ts b/src/BimModel/src/system/constants.ts new file mode 100644 index 0000000..dffcd3f --- /dev/null +++ b/src/BimModel/src/system/constants.ts @@ -0,0 +1,14 @@ +export const systemGUID = { + geometry: "0b2bd272-5c40-4334-8010-5b799211e99e", + element: "c2b0f468-aa98-4ff7-b6f7-d5f932f73a3b", + elementType: "3e788cae-960f-450f-9624-e9d4a5e9fca5", + drawTool: "9f57c4ea-8628-4454-9296-5cc63c93d7af", + parameter: "aaacab20-84c2-4cc3-8a35-84f506ccabe5", + category: "c46a8db0-df2e-48f5-9a17-edf982ec31a2", + family: "80e12dbd-caa6-4bf5-a848-fd9f179cf32f", + level: "53ee394d-abf2-4df2-b362-8a1a845fd4af", + grid: "a867769b-c9e3-4274-a1d2-252332dbbb5d", + project: "19939a5b-bd03-4bca-b736-5abfce4ab3ee", + snapper: "01c5b0e1-561a-4e1b-a170-aa74d32e7287", + workPlane: "9c682b63-417d-41a5-9174-e9c56366fd34", +}; diff --git a/src/BimModel/src/system/index.ts b/src/BimModel/src/system/index.ts index e2bb2b9..cbb6eb4 100644 --- a/src/BimModel/src/system/index.ts +++ b/src/BimModel/src/system/index.ts @@ -1,3 +1,17 @@ +import {Components} from "../Components"; +import {GeometrySystem} from "./01-geometry"; +import {ElementSystem} from "./02-element"; +import {ElementTypeSystem} from "./03-element-type"; +import {DrawToolSystem} from "./04-draw-tool"; +import {ParameterSystem} from "./05-parameter"; +import {CategorySystem} from "./06-category"; +import {FamilySystem} from "./07-family"; +import {LevelSystem} from "./08-level"; +import {GridSystem} from "./09-grid"; +import {ProjectSystem} from "./10-project"; +import {SnapperSystem} from "./11-snapper"; +import {WorkPlaneSystem} from "./12-work-plane"; + export * from "./00-base"; export * from "./01-geometry"; export * from "./02-element"; @@ -6,3 +20,40 @@ export * from "./04-draw-tool"; export * from "./05-parameter"; export * from "./06-category"; export * from "./07-family"; +export * from "./08-level"; +export * from "./09-grid"; +export * from "./10-project"; +export * from "./11-snapper"; +export * from "./12-work-plane"; + +export class SystemComponent { + /** + * + */ + constructor(components: Components) { + const geometry = components.tools.get(GeometrySystem); + geometry.enabled = true; + const elementSystem = components.tools.get(ElementSystem); + elementSystem.enabled = true; + const elementSystemType = components.tools.get(ElementTypeSystem); + elementSystemType.enabled = true; + const drawToolSystem = components.tools.get(DrawToolSystem); + drawToolSystem.enabled = true; + const parameterSystem = components.tools.get(ParameterSystem); + parameterSystem.enabled = true; + const categorySystem = components.tools.get(CategorySystem); + categorySystem.enabled = true; + const familySystem = components.tools.get(FamilySystem); + familySystem.enabled = true; + const levelSystem = components.tools.get(LevelSystem); + levelSystem.enabled = true; + const gridSystem = components.tools.get(GridSystem); + gridSystem.enabled = true; + const projectSystem = components.tools.get(ProjectSystem); + projectSystem.enabled = true; + const snapperSystem = components.tools.get(SnapperSystem); + snapperSystem.enabled = true; + const workPlaneSystem = components.tools.get(WorkPlaneSystem); + workPlaneSystem.enabled = true; + } +} diff --git a/src/BimModel/src/types/index.ts b/src/BimModel/src/types/index.ts index dcc5919..2d103c1 100644 --- a/src/BimModel/src/types/index.ts +++ b/src/BimModel/src/types/index.ts @@ -3,5 +3,3 @@ export * from "./component"; export * from "./base-types"; export * from "./cameraData"; export * from "./constants"; -export * from "./modeling"; -export * from "./project"; diff --git a/src/BimModel/src/utils/cameraUtils.ts b/src/BimModel/src/utils/cameraUtils.ts index 4a36e1d..6c9c255 100644 --- a/src/BimModel/src/utils/cameraUtils.ts +++ b/src/BimModel/src/utils/cameraUtils.ts @@ -2,19 +2,24 @@ import * as THREE from "three"; import {INavigation} from "../types"; const near = 1, - far = 10000, distance = 20, corner = Math.sqrt(3 * distance * distance); const max = new THREE.Vector3(corner, corner, corner); const pos1 = new THREE.Vector3(corner, corner, corner); const min = new THREE.Vector3(-corner, -corner, -corner); +export const defaultCameraFar = 10000; export const defaultBox = new THREE.Box3(min, max); export const defaultSphere = () => { const center = new THREE.Vector3().lerpVectors(max, min, 0.5); return new THREE.Sphere(center, max.distanceTo(min) / 2); }; export function initPerspectiveCamera(aspect: number): THREE.PerspectiveCamera { - const camera = new THREE.PerspectiveCamera(45, aspect, near, far); + const camera = new THREE.PerspectiveCamera( + 45, + aspect, + near, + defaultCameraFar + ); camera.position.copy(max); camera.lookAt(0, 0, 0); return camera; @@ -25,8 +30,8 @@ export function initOrthographicCamera(width: number, height: number) { width / 50, height / 50, height / -50, - -far, - far + -defaultCameraFar, + defaultCameraFar ); camera.position.copy(pos1); camera.lookAt(0, 0, 0); diff --git a/src/pages/viewer/Viewer.css b/src/pages/viewer/Viewer.css new file mode 100644 index 0000000..e0eb897 --- /dev/null +++ b/src/pages/viewer/Viewer.css @@ -0,0 +1,103 @@ +.showPanel { + width: 15%; + transition: width 0.05s; +} + +.hidePanel { + width: 0; + transition: width 0.05s; +} + +:root { + --color: rgb(8, 8, 255) +} + +.snap-intersect { + position: relative; + height: 30px; + /* this can be anything */ + width: 30px; + /* ...but maintain 1:1 aspect ratio */ + display: flex; + flex-direction: column; + justify-content: center; +} + +.snap-intersect::before, +.snap-intersect::after { + position: absolute; + content: ''; + width: 100%; + height: 1px; + /* cross thickness */ + background-color: var(--color); +} + +.snap-intersect::before { + transform: rotate(45deg); +} + +.snap-intersect::after { + transform: rotate(-45deg); +} + +.snap-middle { + width: 0; + height: 0; + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-bottom: 17.32px solid var(--color) +} + +.snap-endpoint { + width: 20px; + height: 20px; + border: 1px solid var(--color) +} + +.endLine { + width: 10px; + height: 10px; + border: 2px solid var(--color); + border-radius: 50%; + background-color: #8cae69; +} + +.tag { + position: absolute; + left: 0; + font-family: monospace; + width: auto; + text-align: center; + border: none; + border-radius: 5px; + padding: 5px; + margin: auto; + background: transparent; + background-color: rgb(78, 78, 174); + color: white!important; + font-weight: 700; + z-index: 4000; + padding: 5px; + display: flex; + justify-content: flex-start; +} + +.tag.info { + border-radius: 5px; + background-color: rgb(168, 197, 197); + top: 0px!important; + height: auto; + color: white!important; + font-weight: 700; +} + +.selectionWindow { + border: 1px solid #55aaff; + background: transparent; + position: fixed; + z-index: 3000; + pointer-events: none; + top: 0; + left: 0 +} \ No newline at end of file diff --git a/src/pages/viewer/index.tsx b/src/pages/viewer/index.tsx index 1f40652..e9996b1 100644 --- a/src/pages/viewer/index.tsx +++ b/src/pages/viewer/index.tsx @@ -1,8 +1,10 @@ +import React, {useEffect, useRef} from "react"; + import {BimModel} from "@BimModel/index"; import SwitchTheme from "@components/SwitchTheme/SwitchTheme"; import {disposeSignal} from "@signals/disposeSignal"; +import "./Viewer.css"; -import React, {useEffect, useRef} from "react"; const Viewer = () => { const containerRef = useRef(null); const modelingRef = useRef(null); diff --git a/tsconfig.json b/tsconfig.json index 1fceb3f..44ab5d4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,6 +28,14 @@ "@components/*": ["src/components/*"], "@assets/*": ["src/assets/*"], "@BimModel/*": ["src/BimModel/*"], + "@CubeMapComponent/*": ["src/BimModel/src/CubeMapComponent/*"], + "@MaterialComponent/*": ["src/BimModel/src/MaterialComponent/*"], + "@ModelingComponent/*": ["src/BimModel/src/ModelingComponent/*"], + "@PropertyComponent/*": ["src/BimModel/src/PropertyComponent/*"], + "@RendererComponent/*": ["src/BimModel/src/RendererComponent/*"], + "@StructureComponent/*": ["src/BimModel/src/StructureComponent/*"], + "@ProjectComponent/*": ["src/BimModel/src/ProjectComponent/*"], + "@system/*": ["src/BimModel/src/system/*"], "@signals/*": ["src/signals/*"], "@pages/*": ["src/pages/*"], "@baseTypes/*": ["src/baseTypes/*"], diff --git a/vite.config.ts b/vite.config.ts index c313d25..4acec12 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -27,6 +27,35 @@ export default defineConfig(() => { alias: { "@assets": path.resolve(__dirname, "./src/assets"), "@BimModel": path.resolve(__dirname, "./src/BimModel"), + "@CubeMapComponent": path.resolve( + __dirname, + "./src/BimModel/src/CubeMapComponent" + ), + "@MaterialComponent": path.resolve( + __dirname, + "./src/BimModel/src/MaterialComponent" + ), + "@ModelingComponent": path.resolve( + __dirname, + "./src/BimModel/src/ModelingComponent" + ), + "@PropertyComponent": path.resolve( + __dirname, + "./src/BimModel/src/PropertyComponent" + ), + "@RendererComponent": path.resolve( + __dirname, + "./src/BimModel/src/RendererComponent" + ), + "@StructureComponent": path.resolve( + __dirname, + "./src/BimModel/src/StructureComponent" + ), + "@ProjectComponent": path.resolve( + __dirname, + "./src/BimModel/src/ProjectComponent" + ), + "@system": path.resolve(__dirname, "./src/BimModel/src/system"), "@components": path.resolve(__dirname, "./src/components"), "@signals": path.resolve(__dirname, "./src/signals"), "@pages": path.resolve(__dirname, "./src/pages"),