UNPKG

web-ifc-viewer

Version:
155 lines 5.94 kB
import { CylinderGeometry, DoubleSide, Mesh, MeshBasicMaterial, Object3D, Plane, PlaneGeometry } from 'three'; import { TransformControls } from 'three/examples/jsm/controls/TransformControls'; import { IfcComponent } from '../../../base-types'; import { ClippingEdges } from './clipping-edges'; export class IfcPlane extends IfcComponent { constructor(context, origin, normal, onStartDragging, onEndDragging, planeSize, edgesEnabled) { super(context); this.arrowBoundingBox = new Mesh(); this.isVisible = true; this.enabled = true; this.edgesActive = true; // Wether this plane is a section or floor plan this.isPlan = false; this.removeFromScene = () => { this.helper.removeFromParent(); this.arrowBoundingBox.removeFromParent(); this.arrowBoundingBox.geometry.dispose(); this.arrowBoundingBox = undefined; this.planeMesh.geometry.dispose(); this.planeMesh.geometry = undefined; this.controls.removeFromParent(); this.controls.dispose(); this.edges.dispose(); this.helper.removeFromParent(); }; this.planeSize = planeSize; this.context = context; this.plane = new Plane(); this.planeMesh = this.getPlaneMesh(); this.normal = normal; this.origin = origin; this.helper = this.createHelper(); this.controls = this.newTransformControls(); this.setupEvents(onStartDragging, onEndDragging); this.plane.setFromNormalAndCoplanarPoint(normal, origin); this.edges = new ClippingEdges(this.plane); this.edgesActive = edgesEnabled; } get active() { return this.enabled; } set active(state) { this.enabled = state; const planes = this.context.getClippingPlanes(); this.edges.visible = state; if (state) { planes.push(this.plane); } else { const index = planes.indexOf(this.plane); if (index >= 0) planes.splice(index); } } get visible() { return this.isVisible; } set visible(state) { this.isVisible = state; this.controls.visible = state; this.helper.visible = state; this.edges.visible = state; } dispose() { if (IfcPlane.planeMaterial) { IfcPlane.planeMaterial.dispose(); IfcPlane.planeMaterial = null; IfcPlane.planeMaterial = IfcPlane.getPlaneMaterial(); } if (IfcPlane.hiddenMaterial) { IfcPlane.hiddenMaterial.dispose(); IfcPlane.hiddenMaterial = null; IfcPlane.hiddenMaterial = IfcPlane.getHiddenMaterial(); } this.removeFromScene(); this.edges.disposeStylesAndHelpers(); this.edges = null; this.context = null; } static getPlaneMaterial() { return new MeshBasicMaterial({ color: 0xffff00, side: DoubleSide, transparent: true, opacity: 0.2 }); } static getHiddenMaterial() { return new MeshBasicMaterial({ visible: false }); } newTransformControls() { const camera = this.context.getCamera(); const container = this.context.getDomElement(); const controls = new TransformControls(camera, container); this.initializeControls(controls); const scene = this.context.getScene(); scene.add(controls); this.context.renderer.postProduction.excludedItems.add(controls); return controls; } initializeControls(controls) { controls.attach(this.helper); controls.showX = false; controls.showY = false; controls.setSpace('local'); this.createArrowBoundingBox(); controls.children[0].children[0].add(this.arrowBoundingBox); } createArrowBoundingBox() { this.arrowBoundingBox.geometry = new CylinderGeometry(0.18, 0.18, 1.2); this.arrowBoundingBox.material = IfcPlane.hiddenMaterial; this.arrowBoundingBox.rotateX(Math.PI / 2); this.arrowBoundingBox.updateMatrix(); this.arrowBoundingBox.geometry.applyMatrix4(this.arrowBoundingBox.matrix); } setupEvents(onStart, onEnd) { this.controls.addEventListener('change', () => { if (!this.enabled) return; this.plane.setFromNormalAndCoplanarPoint(this.normal, this.helper.position); if (this.edgesActive) this.edges.updateEdges(); }); this.controls.addEventListener('dragging-changed', (event) => { if (!this.enabled) return; this.isVisible = !event.value; this.context.toggleCameraControls(this.isVisible); if (event.value) onStart(); else onEnd(); }); this.context.ifcCamera.currentNavMode.onChangeProjection.on((camera) => { this.controls.camera = camera; }); } createHelper() { const helper = new Object3D(); helper.lookAt(this.normal); helper.position.copy(this.origin); const scene = this.context.getScene(); scene.add(helper); helper.add(this.planeMesh); this.context.renderer.postProduction.excludedItems.add(helper); return helper; } getPlaneMesh() { const planeGeom = new PlaneGeometry(this.planeSize, this.planeSize, 1); return new Mesh(planeGeom, IfcPlane.planeMaterial); } } IfcPlane.planeMaterial = IfcPlane.getPlaneMaterial(); IfcPlane.hiddenMaterial = IfcPlane.getHiddenMaterial(); //# sourceMappingURL=planes.js.map