webarchi/assets/bim.js

162 lines
4.3 KiB
JavaScript

import * as THREE from 'three';
import * as OBC from '@thatopen/components';
import * as OBF from '@thatopen/components-front';
import * as WEBIFC from 'web-ifc';
/**
* @namespace BIM
*/
const BIM = {};
BIM.clipper = undefined;
/**
*
* @param {HTMLElement} container The scene container element
* @returns {object} {components, world}
*/
BIM.init = function (container) {
const components = new OBC.Components();
const worlds = components.get(OBC.Worlds);
const world = worlds.create();
world.scene = new OBC.SimpleScene(components);
world.renderer = new OBC.SimpleRenderer(components, container);
world.camera = new OBC.SimpleCamera(components);
// Starts the app and updates components at 60 fps
components.init();
this.world = world;
this.components = components;
}
/**
* @param {HTMLElement} container The scene container element
*/
BIM.createScene = function (container) {
this.init(container);
// Add a grid to the scene
const grids = this.components.get(OBC.Grids);
const grid = grids.create(this.world);
// (zoom_level, position)
this.world.camera.controls.setLookAt(15, 15, 15, 0, 0, 0);
this.world.scene.setup();
}
/**
* Enable the clipping plane
*/
BIM.activateClipper = function () {
const casters = this.components.get(OBC.Raycasters);
casters.get(this.world);
// Enable plane clipper
const clipper = this.components.get(OBC.Clipper);
clipper.enabled = true;
clipper.create(this.world);
clipper.visible = true;
BIM.clipper = clipper;
}
/**
* Delete a selected clipping plane
*/
BIM.deleteClipper = function () {
if (this.clipper.enabled) {
this.clipper.delete(this.world);
}
}
/**
* @todo Serve web-ifc.wasm locally via AJAX
* @param {ArrayBuffer} buffer The uploaded IFC file
* @param {string} name The filename to be used as the model's name
* @returns {OBC.FragmentsGroup} model
*/
BIM.loadIfc = async function (buffer, name) {
if (this.fragments) {
this.fragments.dispose();
}
const fragments = this.components.get(OBC.FragmentsManager);
const fragmentIfcLoader = this.components.get(OBC.IfcLoader);
// NOTE: loads web-ifc WASM from https://unpkg.com/web-ifc@0.0.53/
await fragmentIfcLoader.setup();
/*
fragmentIfcLoader.settings.wasm = {
path: "./vendor/web-ifc/",
absolute: false
};
*/
// Excludes IFC categories from the fragment
const excludedCats = [
WEBIFC.IFCTENDONANCHOR,
WEBIFC.IFCREINFORCINGBAR,
WEBIFC.IFCREINFORCINGELEMENT,
];
for (const cat of excludedCats) {
fragmentIfcLoader.settings.excludedCategories.add(cat);
}
fragmentIfcLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true;
fragmentIfcLoader.settings.webIfc.OPTIMIZE_PROFILES = true;
const model = await fragmentIfcLoader.load(buffer);
model.name = name;
this.world.scene.three.add(model);
for (const fragment of model.items) {
this.world.meshes.add(fragment.mesh);
}
// Useful?
this.fragments = fragments;
this.model = model;
return model;
}
/**
* @param {OBC.FragmentsGroup} model The loaded IFC model
*/
BIM.setupHighligther = async function (model) {
const world = this.world;
const indexer = this.components.get(OBC.IfcRelationsIndexer);
await indexer.process(model);
let highlighter = null;
if (!this.highlighter) {
highlighter = this.components.get(OBF.Highlighter);
highlighter.setup({ world });
} else {
highlighter = this.highlighter;
}
const li = document.querySelector('#selected-prop');
highlighter.events.select.onHighlight.add(async (property) => {
const set = property[Object.keys(property)[0]]
const expressID = Array.from(set.entries())[0][0];
let testProp = await model.getProperties(Number.parseInt(expressID));
// BAD just for testing
if (testProp !== null) {
li.innerHTML = `
<ul>
<li><strong>Name</strong>: ${testProp['Name'].value}</span>
<li><strong>Tag</strong>: ${testProp['Tag'].value}</li>
</ul>
`;
}
});
highlighter.events.select.onClear.add(() => {
li.innerHTML = '';
});
this.highlighter = highlighter;
}
export default BIM;