web-ifc-viewer
Version:
155 lines • 5.94 kB
JavaScript
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