UNPKG

web-ifc-viewer

Version:
187 lines 8.27 kB
import { Mesh, Vector3 } from 'three'; import { IFCBUILDINGSTOREY, IFCBUILDING } from 'web-ifc'; import { CameraProjections, NavigationModes } from '../../../base-types'; import { UnitType } from '../../ifc/units'; import { disposeMeshRecursively } from '../../../utils/ThreeUtils'; export class PlanManager { constructor(ifc, context, clipper) { this.ifc = ifc; this.context = context; this.clipper = clipper; this.planLists = {}; this.active = false; this.defaultSectionOffset = 1.5; this.defaultCameraOffset = 30; this.storeys = []; this.floorPlanViewCached = false; this.previousCamera = new Vector3(); this.previousTarget = new Vector3(); this.previousProjection = CameraProjections.Perspective; this.sectionFill = new Mesh(); } dispose() { disposeMeshRecursively(this.sectionFill); this.sectionFill = null; this.storeys = null; this.planLists = null; } getAll(modelID) { const currentPlans = this.planLists[modelID]; if (!currentPlans) throw new Error("The requested model doesn't have floor plans generated"); return Object.keys(currentPlans); } async create(config) { const { modelID, name } = config; const ortho = config.ortho || true; if (this.planLists[modelID] === undefined) this.planLists[modelID] = {}; const currentPlanlist = this.planLists[modelID]; const expressID = config.expressID; if (currentPlanlist[expressID]) return; currentPlanlist[expressID] = { modelID, name, ortho, expressID }; await this.createClippingPlane(config, currentPlanlist[expressID]); } async goTo(modelID, name, animate = false) { var _a; if (((_a = this.currentPlan) === null || _a === void 0 ? void 0 : _a.modelID) === modelID && this.currentPlan.name === name) return; this.storeCameraPosition(); this.hidePreviousClippingPlane(); this.getCurrentPlan(modelID, name); this.activateCurrentPlan(); if (!this.active) { await this.moveCameraTo2DPlanPosition(animate); this.active = true; } } async exitPlanView(animate = false) { if (!this.active) return; this.active = false; this.cacheFloorplanView(); this.context.ifcCamera.setNavigationMode(NavigationModes.Orbit); this.context.ifcCamera.projection = this.previousProjection; if (this.currentPlan && this.currentPlan.plane) { this.currentPlan.plane.active = false; } this.currentPlan = undefined; await this.context.ifcCamera.cameraControls.setLookAt(this.previousCamera.x, this.previousCamera.y, this.previousCamera.z, this.previousTarget.x, this.previousTarget.y, this.previousTarget.z, animate); } async computeAllPlanViews(modelID) { var _a; await this.getCurrentStoreys(modelID); const unitsScale = await this.ifc.units.getUnits(modelID, UnitType.LENGTHUNIT); const siteCoords = await this.getSiteCoords(modelID); const transformHeight = await this.getTransformHeight(modelID); const storeys = this.storeys[modelID]; for (let i = 0; i < storeys.length; i++) { if (storeys[i]) { const baseHeight = ((_a = storeys[i].Elevation) === null || _a === void 0 ? void 0 : _a.value) || 0; const elevation = (baseHeight + siteCoords[2]) * unitsScale + transformHeight; const expressID = storeys[i].expressID; // eslint-disable-next-line no-await-in-loop await this.create({ modelID, name: this.getFloorplanName(storeys[i]), point: new Vector3(0, elevation + this.defaultSectionOffset, 0), normal: new Vector3(0, -1, 0), rotation: 0, ortho: true, expressID }); } } } storeCameraPosition() { if (this.active) { this.cacheFloorplanView(); } else { this.store3dCameraPosition(); } } async createClippingPlane(config, plan) { if (config.normal && config.point) { const { normal, point } = config; const plane = this.clipper.createFromNormalAndCoplanarPoint(normal, point, true); plane.visible = false; plane.active = false; plan.plane = plane; await plane.edges.updateEdges(); plane.edges.visible = false; } } async getTransformHeight(modelID) { const transformMatrix = await this.ifc.loader.ifcManager.ifcAPI.GetCoordinationMatrix(modelID); return transformMatrix[13]; } async getCurrentStoreys(modelID) { if (!this.storeys[modelID]) { this.storeys[modelID] = await this.ifc.getAllItemsOfType(modelID, IFCBUILDINGSTOREY, true); } } async getSiteCoords(modelID) { const building = await this.getBuilding(modelID); const sitePlace = building.ObjectPlacement.PlacementRelTo.RelativePlacement.Location; return sitePlace.Coordinates.map((coord) => coord.value); } async getBuilding(modelID) { const allBuildingsIDs = await this.ifc.getAllItemsOfType(modelID, IFCBUILDING, false); const buildingID = allBuildingsIDs[0]; return this.ifc.getProperties(modelID, buildingID, false, true); } cacheFloorplanView() { this.floorPlanViewCached = true; this.context.ifcCamera.cameraControls.saveState(); } async moveCameraTo2DPlanPosition(animate) { if (this.floorPlanViewCached) await this.context.ifcCamera.cameraControls.reset(animate); else await this.context.ifcCamera.cameraControls.setLookAt(0, 100, 0, 0, 0, 0, animate); } activateCurrentPlan() { if (!this.currentPlan) throw new Error('Current plan is not defined.'); if (this.currentPlan.plane) this.currentPlan.plane.active = true; this.context.ifcCamera.setNavigationMode(NavigationModes.Plan); this.context.ifcCamera.projection = this.currentPlan.ortho ? CameraProjections.Orthographic : CameraProjections.Perspective; } store3dCameraPosition() { this.context.getCamera().getWorldPosition(this.previousCamera); this.context.ifcCamera.cameraControls.getTarget(this.previousTarget); this.previousProjection = this.context.ifcCamera.projection; } getCurrentPlan(modelID, name) { if (this.planLists[modelID] === undefined) throw new Error('The specified plan is undefined!'); const currentPlanList = this.planLists[modelID]; if (currentPlanList[name] === undefined) throw new Error('The specified plan is undefined!'); if (!currentPlanList[name]) throw new Error('The specified plan name does not exist!'); this.currentPlan = currentPlanList[name]; } hidePreviousClippingPlane() { var _a; const plane = (_a = this.currentPlan) === null || _a === void 0 ? void 0 : _a.plane; if (plane) plane.active = false; } getFloorplanName(floorplan) { var _a, _b, _c, _d; if ((_b = (_a = floorplan === null || floorplan === void 0 ? void 0 : floorplan.Name) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.length) { return floorplan.Name.value; } if ((_d = (_c = floorplan === null || floorplan === void 0 ? void 0 : floorplan.LongName) === null || _c === void 0 ? void 0 : _c.value) === null || _d === void 0 ? void 0 : _d.length) { return floorplan.LongName.value; } return floorplan.GlobalId.value; } } //# sourceMappingURL=plan-manager.js.map