12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657 |
- import * as WebIFC from 'web-ifc';
- import { IFCSPACE, IFCOPENINGELEMENT, IFCPRODUCTDEFINITIONSHAPE, IFCRELAGGREGATES, IFCRELCONTAINEDINSPATIALSTRUCTURE, IFCRELDEFINESBYPROPERTIES, IFCRELASSOCIATESMATERIAL, IFCRELDEFINESBYTYPE, IFCPROJECT, IFCBUILDING } from 'web-ifc';
- import { Mesh, Color, MeshLambertMaterial, DoubleSide, Matrix4, BufferGeometry, BufferAttribute, Loader, FileLoader } from 'three';
- import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils';
- const nullIfcManagerErrorMessage = 'IfcManager is null!';
- class IFCModel extends Mesh {
- constructor() {
- super(...arguments);
- this.modelID = IFCModel.modelIdCounter++;
- this.ifcManager = null;
- this.mesh = this;
- }
- static dispose() {
- IFCModel.modelIdCounter = 0;
- }
- setIFCManager(manager) {
- this.ifcManager = manager;
- }
- setWasmPath(path) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- this.ifcManager.setWasmPath(path);
- }
- close(scene) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- this.ifcManager.close(this.modelID, scene);
- }
- getExpressId(geometry, faceIndex) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- return this.ifcManager.getExpressId(geometry, faceIndex);
- }
- getAllItemsOfType(type, verbose) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- return this.ifcManager.getAllItemsOfType(this.modelID, type, verbose);
- }
- getItemProperties(id, recursive = false) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- return this.ifcManager.getItemProperties(this.modelID, id, recursive);
- }
- getPropertySets(id, recursive = false) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- return this.ifcManager.getPropertySets(this.modelID, id, recursive);
- }
- getTypeProperties(id, recursive = false) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- return this.ifcManager.getTypeProperties(this.modelID, id, recursive);
- }
- getIfcType(id) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- return this.ifcManager.getIfcType(this.modelID, id);
- }
- getSpatialStructure() {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- return this.ifcManager.getSpatialStructure(this.modelID);
- }
- getSubset(material) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- return this.ifcManager.getSubset(this.modelID, material);
- }
- removeSubset(material, customID) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- this.ifcManager.removeSubset(this.modelID, material, customID);
- }
- createSubset(config) {
- if (this.ifcManager === null)
- throw new Error(nullIfcManagerErrorMessage);
- const modelConfig = {
- ...config,
- modelID: this.modelID
- };
- return this.ifcManager.createSubset(modelConfig);
- }
- }
- IFCModel.modelIdCounter = 0;
- class IFCParser {
- constructor(state, BVH) {
- this.state = state;
- this.BVH = BVH;
- this.loadedModels = 0;
- this.optionalCategories = {
- [IFCSPACE]: true,
- [IFCOPENINGELEMENT]: false
- };
- this.geometriesByMaterials = {};
- this.loadingState = {
- total: 0,
- current: 0,
- step: 0.1
- };
- this.currentWebIfcID = -1;
- this.currentModelID = -1;
- }
- async setupOptionalCategories(config) {
- this.optionalCategories = config;
- }
- async parse(buffer, coordinationMatrix) {
- if (this.state.api.wasmModule === undefined)
- await this.state.api.Init();
- await this.newIfcModel(buffer);
- this.loadedModels++;
- if (coordinationMatrix) {
- await this.state.api.SetGeometryTransformation(this.currentWebIfcID, coordinationMatrix);
- }
- return this.loadAllGeometry(this.currentWebIfcID);
- }
- getAndClearErrors(_modelId) {}
- notifyProgress(loaded, total) {
- if (this.state.onProgress)
- this.state.onProgress({
- loaded,
- total
- });
- }
- async newIfcModel(buffer) {
- const data = new Uint8Array(buffer);
- this.currentWebIfcID = await this.state.api.OpenModel(data, this.state.webIfcSettings);
- this.currentModelID = this.state.useJSON ? this.loadedModels : this.currentWebIfcID;
- this.state.models[this.currentModelID] = {
- modelID: this.currentModelID,
- mesh: {},
- types: {},
- jsonData: {}
- };
- }
- async loadAllGeometry(modelID) {
- this.addOptionalCategories(modelID);
- await this.initializeLoadingState(modelID);
- this.state.api.StreamAllMeshes(modelID, (mesh) => {
- this.updateLoadingState();
- this.streamMesh(modelID, mesh);
- });
- this.notifyLoadingEnded();
- const geometries = [];
- const materials = [];
- Object.keys(this.geometriesByMaterials).forEach((key) => {
- const geometriesByMaterial = this.geometriesByMaterials[key].geometries;
- const merged = mergeGeometries(geometriesByMaterial);
- materials.push(this.geometriesByMaterials[key].material);
- geometries.push(merged);
- });
- const combinedGeometry = mergeGeometries(geometries, true);
- this.cleanUpGeometryMemory(geometries);
- if (this.BVH)
- this.BVH.applyThreeMeshBVH(combinedGeometry);
- const model = new IFCModel(combinedGeometry, materials);
- this.state.models[this.currentModelID].mesh = model;
- return model;
- }
- async initializeLoadingState(modelID) {
- const shapes = await this.state.api.GetLineIDsWithType(modelID, IFCPRODUCTDEFINITIONSHAPE);
- this.loadingState.total = shapes.size();
- this.loadingState.current = 0;
- this.loadingState.step = 0.1;
- }
- notifyLoadingEnded() {
- this.notifyProgress(this.loadingState.total, this.loadingState.total);
- }
- updateLoadingState() {
- const realCurrentItem = Math.min(this.loadingState.current++, this.loadingState.total);
- if (realCurrentItem / this.loadingState.total >= this.loadingState.step) {
- const currentProgress = Math.ceil(this.loadingState.total * this.loadingState.step);
- this.notifyProgress(currentProgress, this.loadingState.total);
- this.loadingState.step += 0.1;
- }
- }
- addOptionalCategories(modelID) {
- const optionalTypes = [];
- for (let key in this.optionalCategories) {
- if (this.optionalCategories.hasOwnProperty(key)) {
- const category = parseInt(key);
- if (this.optionalCategories[category])
- optionalTypes.push(category);
- }
- }
- this.state.api.StreamAllMeshesWithTypes(this.currentWebIfcID, optionalTypes, (mesh) => {
- this.streamMesh(modelID, mesh);
- });
- }
- streamMesh(modelID, mesh) {
- const placedGeometries = mesh.geometries;
- const size = placedGeometries.size();
- for (let i = 0; i < size; i++) {
- const placedGeometry = placedGeometries.get(i);
- let itemMesh = this.getPlacedGeometry(modelID, mesh.expressID, placedGeometry);
- let geom = itemMesh.geometry.applyMatrix4(itemMesh.matrix);
- this.storeGeometryByMaterial(placedGeometry.color, geom);
- }
- }
- getPlacedGeometry(modelID, expressID, placedGeometry) {
- const geometry = this.getBufferGeometry(modelID, expressID, placedGeometry);
- const mesh = new Mesh(geometry);
- mesh.matrix = this.getMeshMatrix(placedGeometry.flatTransformation);
- mesh.matrixAutoUpdate = false;
- return mesh;
- }
- getBufferGeometry(modelID, expressID, placedGeometry) {
- const geometry = this.state.api.GetGeometry(modelID, placedGeometry.geometryExpressID);
- const verts = this.state.api.GetVertexArray(geometry.GetVertexData(), geometry.GetVertexDataSize());
- const indices = this.state.api.GetIndexArray(geometry.GetIndexData(), geometry.GetIndexDataSize());
- const buffer = this.ifcGeometryToBuffer(expressID, verts, indices);
- geometry.delete();
- return buffer;
- }
- storeGeometryByMaterial(color, geometry) {
- let colID = `${color.x}${color.y}${color.z}${color.w}`;
- if (this.geometriesByMaterials[colID]) {
- this.geometriesByMaterials[colID].geometries.push(geometry);
- return;
- }
- const col = new Color().setRGB(color.x, color.y, color.z, 'srgb');
- const material = new MeshLambertMaterial({
- color: col,
- side: DoubleSide
- });
- material.transparent = color.w !== 1;
- if (material.transparent)
- material.opacity = color.w;
- this.geometriesByMaterials[colID] = {
- material,
- geometries: [geometry]
- };
- }
- getMeshMatrix(matrix) {
- const mat = new Matrix4();
- mat.fromArray(matrix);
- return mat;
- }
- ifcGeometryToBuffer(expressID, vertexData, indexData) {
- const geometry = new BufferGeometry();
- const posFloats = new Float32Array(vertexData.length / 2);
- const normFloats = new Float32Array(vertexData.length / 2);
- const idAttribute = new Uint32Array(vertexData.length / 6);
- for (let i = 0; i < vertexData.length; i += 6) {
- posFloats[i / 2] = vertexData[i];
- posFloats[i / 2 + 1] = vertexData[i + 1];
- posFloats[i / 2 + 2] = vertexData[i + 2];
- normFloats[i / 2] = vertexData[i + 3];
- normFloats[i / 2 + 1] = vertexData[i + 4];
- normFloats[i / 2 + 2] = vertexData[i + 5];
- idAttribute[i / 6] = expressID;
- }
- geometry.setAttribute('position', new BufferAttribute(posFloats, 3));
- geometry.setAttribute('normal', new BufferAttribute(normFloats, 3));
- geometry.setAttribute('expressID', new BufferAttribute(idAttribute, 1));
- geometry.setIndex(new BufferAttribute(indexData, 1));
- return geometry;
- }
- cleanUpGeometryMemory(geometries) {
- geometries.forEach(geometry => geometry.dispose());
- Object.keys(this.geometriesByMaterials).forEach((materialID) => {
- const geometriesByMaterial = this.geometriesByMaterials[materialID];
- geometriesByMaterial.geometries.forEach(geometry => geometry.dispose());
- geometriesByMaterial.geometries = [];
- geometriesByMaterial.material = null;
- });
- this.geometriesByMaterials = {};
- }
- }
- class ItemsMap {
- constructor(state) {
- this.state = state;
- this.map = {};
- }
- generateGeometryIndexMap(modelID) {
- if (this.map[modelID])
- return;
- const geometry = this.getGeometry(modelID);
- const items = this.newItemsMap(modelID, geometry);
- for (const group of geometry.groups) {
- this.fillItemsWithGroupInfo(group, geometry, items);
- }
- }
- getSubsetID(modelID, material, customID = 'DEFAULT') {
- const baseID = modelID;
- const materialID = material ? material.uuid : 'DEFAULT';
- return `${baseID} - ${materialID} - ${customID}`;
- }
- dispose() {
- Object.values(this.map).forEach(model => {
- model.indexCache = null;
- model.map = null;
- });
- this.map = null;
- }
- getGeometry(modelID) {
- const geometry = this.state.models[modelID].mesh.geometry;
- if (!geometry)
- throw new Error('Model without geometry.');
- if (!geometry.index)
- throw new Error('Geometry must be indexed');
- return geometry;
- }
- newItemsMap(modelID, geometry) {
- const startIndices = geometry.index.array;
- this.map[modelID] = {
- indexCache: startIndices.slice(0, geometry.index.array.length),
- map: new Map()
- };
- return this.map[modelID];
- }
- fillItemsWithGroupInfo(group, geometry, items) {
- let prevExpressID = -1;
- const materialIndex = group.materialIndex;
- const materialStart = group.start;
- const materialEnd = materialStart + group.count - 1;
- let objectStart = -1;
- let objectEnd = -1;
- for (let i = materialStart; i <= materialEnd; i++) {
- const index = geometry.index.array[i];
- const bufferAttr = geometry.attributes.expressID;
- const expressID = bufferAttr.array[index];
- if (prevExpressID === -1) {
- prevExpressID = expressID;
- objectStart = i;
- }
- const isEndOfMaterial = i === materialEnd;
- if (isEndOfMaterial) {
- const store = this.getMaterialStore(items.map, expressID, materialIndex);
- store.push(objectStart, materialEnd);
- break;
- }
- if (prevExpressID === expressID)
- continue;
- const store = this.getMaterialStore(items.map, prevExpressID, materialIndex);
- objectEnd = i - 1;
- store.push(objectStart, objectEnd);
- prevExpressID = expressID;
- objectStart = i;
- }
- }
- getMaterialStore(map, id, matIndex) {
- if (map.get(id) === undefined) {
- map.set(id, {});
- }
- const storedIfcItem = map.get(id);
- if (storedIfcItem === undefined)
- throw new Error('Geometry map generation error');
- if (storedIfcItem[matIndex] === undefined) {
- storedIfcItem[matIndex] = [];
- }
- return storedIfcItem[matIndex];
- }
- }
- class SubsetUtils {
- static getAllIndicesOfGroup(modelID, ids, materialIndex, items, flatten = true) {
- const indicesByGroup = [];
- for (const expressID of ids) {
- const entry = items.map.get(expressID);
- if (!entry)
- continue;
- const value = entry[materialIndex];
- if (!value)
- continue;
- SubsetUtils.getIndexChunk(value, indicesByGroup, materialIndex, items, flatten);
- }
- return indicesByGroup;
- }
- static getIndexChunk(value, indicesByGroup, materialIndex, items, flatten) {
- const pairs = value.length / 2;
- for (let pair = 0; pair < pairs; pair++) {
- const pairIndex = pair * 2;
- const start = value[pairIndex];
- const end = value[pairIndex + 1];
- for (let j = start; j <= end; j++) {
- if (flatten)
- indicesByGroup.push(items.indexCache[j]);
- else {
- if (!indicesByGroup[materialIndex])
- indicesByGroup[materialIndex] = [];
- indicesByGroup[materialIndex].push(items.indexCache[j]);
- }
- }
- }
- }
- }
- class SubsetCreator {
- constructor(state, items, subsets, BVH) {
- this.state = state;
- this.items = items;
- this.subsets = subsets;
- this.BVH = BVH;
- this.tempIndex = [];
- }
- createSubset(config, subsetID) {
- if (!this.items.map[config.modelID])
- this.items.generateGeometryIndexMap(config.modelID);
- if (!this.subsets[subsetID])
- this.initializeSubset(config, subsetID);
- this.filterIndices(config, subsetID);
- this.constructSubsetByMaterial(config, subsetID);
- config.ids.forEach(id => this.subsets[subsetID].ids.add(id));
- this.subsets[subsetID].mesh.geometry.setIndex(this.tempIndex);
- this.tempIndex.length = 0;
- const subset = this.subsets[subsetID].mesh;
- if (config.applyBVH)
- this.BVH.applyThreeMeshBVH(subset.geometry);
- if (config.scene)
- config.scene.add(subset);
- return this.subsets[subsetID].mesh;
- }
- dispose() {
- this.tempIndex = [];
- }
- initializeSubset(config, subsetID) {
- const model = this.state.models[config.modelID].mesh;
- const subsetGeom = new BufferGeometry();
- this.initializeSubsetAttributes(subsetGeom, model);
- if (!config.material)
- this.initializeSubsetGroups(subsetGeom, model);
- const mesh = new Mesh(subsetGeom, config.material || model.material);
- mesh.modelID = config.modelID;
- const bvh = Boolean(config.applyBVH);
- this.subsets[subsetID] = {
- ids: new Set(),
- mesh,
- bvh
- };
- model.add(mesh);
- }
- initializeSubsetAttributes(subsetGeom, model) {
- subsetGeom.setAttribute('position', model.geometry.attributes.position);
- subsetGeom.setAttribute('normal', model.geometry.attributes.normal);
- subsetGeom.setAttribute('expressID', model.geometry.attributes.expressID);
- subsetGeom.setIndex([]);
- }
- initializeSubsetGroups(subsetGeom, model) {
- subsetGeom.groups = JSON.parse(JSON.stringify(model.geometry.groups));
- this.resetGroups(subsetGeom);
- }
- filterIndices(config, subsetID) {
- const geometry = this.subsets[subsetID].mesh.geometry;
- if (config.removePrevious) {
- geometry.setIndex([]);
- this.resetGroups(geometry);
- return;
- }
- const previousIndices = geometry.index.array;
- const previousIDs = this.subsets[subsetID].ids;
- config.ids = config.ids.filter(id => !previousIDs.has(id));
- this.tempIndex = Array.from(previousIndices);
- }
- constructSubsetByMaterial(config, subsetID) {
- const model = this.state.models[config.modelID].mesh;
- const newIndices = {
- count: 0
- };
- for (let i = 0; i < model.geometry.groups.length; i++) {
- this.insertNewIndices(config, subsetID, i, newIndices);
- }
- }
- insertNewIndices(config, subsetID, materialIndex, newIndices) {
- const items = this.items.map[config.modelID];
- const indicesOfOneMaterial = SubsetUtils.getAllIndicesOfGroup(config.modelID, config.ids, materialIndex, items);
- if (!config.material) {
- this.insertIndicesAtGroup(subsetID, indicesOfOneMaterial, materialIndex, newIndices);
- } else {
- indicesOfOneMaterial.forEach(index => this.tempIndex.push(index));
- }
- }
- insertIndicesAtGroup(subsetID, indicesByGroup, index, newIndices) {
- const currentGroup = this.getCurrentGroup(subsetID, index);
- currentGroup.start += newIndices.count;
- let newIndicesPosition = currentGroup.start + currentGroup.count;
- newIndices.count += indicesByGroup.length;
- if (indicesByGroup.length > 0) {
- let position = newIndicesPosition;
- const start = this.tempIndex.slice(0, position);
- const end = this.tempIndex.slice(position);
- this.tempIndex = Array.prototype.concat.apply([], [start, indicesByGroup, end]);
- currentGroup.count += indicesByGroup.length;
- }
- }
- getCurrentGroup(subsetID, groupIndex) {
- const geometry = this.subsets[subsetID].mesh.geometry;
- return geometry.groups[groupIndex];
- }
- resetGroups(geometry) {
- geometry.groups.forEach((group) => {
- group.start = 0;
- group.count = 0;
- });
- }
- }
- class SubsetManager {
- constructor(state, BVH) {
- this.subsets = {};
- this.state = state;
- this.items = new ItemsMap(state);
- this.BVH = BVH;
- this.subsetCreator = new SubsetCreator(state, this.items, this.subsets, this.BVH);
- }
- getAllSubsets() {
- return this.subsets;
- }
- getSubset(modelID, material, customId) {
- const subsetID = this.getSubsetID(modelID, material, customId);
- return this.subsets[subsetID].mesh;
- }
- removeSubset(modelID, material, customID) {
- const subsetID = this.getSubsetID(modelID, material, customID);
- const subset = this.subsets[subsetID];
- if (!subset)
- return;
- if (subset.mesh.parent)
- subset.mesh.removeFromParent();
- subset.mesh.geometry.attributes = {};
- subset.mesh.geometry.index = null;
- subset.mesh.geometry.dispose();
- subset.mesh.geometry = null;
- delete this.subsets[subsetID];
- }
- createSubset(config) {
- const subsetID = this.getSubsetID(config.modelID, config.material, config.customID);
- return this.subsetCreator.createSubset(config, subsetID);
- }
- removeFromSubset(modelID, ids, customID, material) {
- const subsetID = this.getSubsetID(modelID, material, customID);
- if (!this.subsets[subsetID])
- return;
- const previousIDs = this.subsets[subsetID].ids;
- ids.forEach((id) => {
- if (previousIDs.has(id))
- previousIDs.delete(id);
- });
- return this.createSubset({
- modelID,
- removePrevious: true,
- material,
- customID,
- applyBVH: this.subsets[subsetID].bvh,
- ids: Array.from(previousIDs),
- scene: this.subsets[subsetID].mesh.parent
- });
- }
- clearSubset(modelID, customID, material) {
- const subsetID = this.getSubsetID(modelID, material, customID);
- if (!this.subsets[subsetID])
- return;
- this.subsets[subsetID].ids.clear();
- const subset = this.getSubset(modelID, material, customID);
- subset.geometry.setIndex([]);
- }
- dispose() {
- this.items.dispose();
- this.subsetCreator.dispose();
- Object.values(this.subsets).forEach(subset => {
- subset.ids = null;
- subset.mesh.removeFromParent();
- const mats = subset.mesh.material;
- if (Array.isArray(mats))
- mats.forEach(mat => mat.dispose());
- else
- mats.dispose();
- subset.mesh.geometry.index = null;
- subset.mesh.geometry.dispose();
- const geom = subset.mesh.geometry;
- if (geom.disposeBoundsTree)
- geom.disposeBoundsTree();
- subset.mesh = null;
- });
- this.subsets = null;
- }
- getSubsetID(modelID, material, customID = 'DEFAULT') {
- const baseID = modelID;
- const materialID = material ? material.uuid : 'DEFAULT';
- return `${baseID} - ${materialID} - ${customID}`;
- }
- }
- const IdAttrName = 'expressID';
- const PropsNames = {
- aggregates: {
- name: IFCRELAGGREGATES,
- relating: 'RelatingObject',
- related: 'RelatedObjects',
- key: 'children'
- },
- spatial: {
- name: IFCRELCONTAINEDINSPATIALSTRUCTURE,
- relating: 'RelatingStructure',
- related: 'RelatedElements',
- key: 'children'
- },
- psets: {
- name: IFCRELDEFINESBYPROPERTIES,
- relating: 'RelatingPropertyDefinition',
- related: 'RelatedObjects',
- key: 'hasPsets'
- },
- materials: {
- name: IFCRELASSOCIATESMATERIAL,
- relating: 'RelatingMaterial',
- related: 'RelatedObjects',
- key: 'hasMaterial'
- },
- type: {
- name: IFCRELDEFINESBYTYPE,
- relating: 'RelatingType',
- related: 'RelatedObjects',
- key: 'hasType'
- }
- };
- class BasePropertyManager {
- constructor(state) {
- this.state = state;
- }
- async getPropertySets(modelID, elementID, recursive = false) {
- return await this.getProperty(modelID, elementID, recursive, PropsNames.psets);
- }
- async getTypeProperties(modelID, elementID, recursive = false) {
- return await this.getProperty(modelID, elementID, recursive, PropsNames.type);
- }
- async getMaterialsProperties(modelID, elementID, recursive = false) {
- return await this.getProperty(modelID, elementID, recursive, PropsNames.materials);
- }
- async getSpatialNode(modelID, node, treeChunks, includeProperties) {
- await this.getChildren(modelID, node, treeChunks, PropsNames.aggregates, includeProperties);
- await this.getChildren(modelID, node, treeChunks, PropsNames.spatial, includeProperties);
- }
- async getChildren(modelID, node, treeChunks, propNames, includeProperties) {
- const children = treeChunks[node.expressID];
- if (children == undefined)
- return;
- const prop = propNames.key;
- const nodes = [];
- for (let i = 0; i < children.length; i++) {
- const child = children[i];
- let node = this.newNode(modelID, child);
- if (includeProperties) {
- const properties = await this.getItemProperties(modelID, node.expressID);
- node = {
- ...properties, ...node
- };
- }
- await this.getSpatialNode(modelID, node, treeChunks, includeProperties);
- nodes.push(node);
- }
- node[prop] = nodes;
- }
- newNode(modelID, id) {
- const typeName = this.getNodeType(modelID, id);
- return {
- expressID: id,
- type: typeName,
- children: []
- };
- }
- async getSpatialTreeChunks(modelID) {
- const treeChunks = {};
- await this.getChunks(modelID, treeChunks, PropsNames.aggregates);
- await this.getChunks(modelID, treeChunks, PropsNames.spatial);
- return treeChunks;
- }
- saveChunk(chunks, propNames, rel) {
- const relating = rel[propNames.relating].value;
- const related = rel[propNames.related].map((r) => r.value);
- if (chunks[relating] == undefined) {
- chunks[relating] = related;
- } else {
- chunks[relating] = chunks[relating].concat(related);
- }
- }
- getRelated(rel, propNames, IDs) {
- const element = rel[propNames.relating];
- if (!element) {
- return console.warn(`The object with ID ${rel.expressID} has a broken reference.`);
- }
- if (!Array.isArray(element))
- IDs.push(element.value);
- else
- element.forEach((ele) => IDs.push(ele.value));
- }
- static isRelated(id, rel, propNames) {
- const relatedItems = rel[propNames.related];
- if (Array.isArray(relatedItems)) {
- const values = relatedItems.map((item) => item.value);
- return values.includes(id);
- }
- return relatedItems.value === id;
- }
- static newIfcProject(id) {
- return {
- expressID: id,
- type: 'IFCPROJECT',
- children: []
- };
- }
- async getProperty(modelID, elementID, recursive = false, propName) {}
- async getChunks(modelID, chunks, propNames) {}
- async getItemProperties(modelID, expressID, recursive = false) {}
- getNodeType(modelID, id) {}
- }
- class WebIfcPropertyManager extends BasePropertyManager {
- async getItemProperties(modelID, id, recursive = false) {
- return this.state.api.GetLine(modelID, id, recursive);
- }
- async getHeaderLine(modelID, headerType) {
- return this.state.api.GetHeaderLine(modelID, headerType);
- }
- async getSpatialStructure(modelID, includeProperties) {
- const chunks = await this.getSpatialTreeChunks(modelID);
- const allLines = await this.state.api.GetLineIDsWithType(modelID, IFCPROJECT);
- const projectID = allLines.get(0);
- const project = WebIfcPropertyManager.newIfcProject(projectID);
- await this.getSpatialNode(modelID, project, chunks, includeProperties);
- return project;
- }
- async getAllItemsOfType(modelID, type, verbose) {
- let items = [];
- const lines = await this.state.api.GetLineIDsWithType(modelID, type);
- for (let i = 0; i < lines.size(); i++)
- items.push(lines.get(i));
- if (!verbose)
- return items;
- const result = [];
- for (let i = 0; i < items.length; i++) {
- result.push(await this.state.api.GetLine(modelID, items[i]));
- }
- return result;
- }
- async getProperty(modelID, elementID, recursive = false, propName) {
- const propSetIds = await this.getAllRelatedItemsOfType(modelID, elementID, propName);
- const result = [];
- for (let i = 0; i < propSetIds.length; i++) {
- result.push(await this.state.api.GetLine(modelID, propSetIds[i], recursive));
- }
- return result;
- }
- getNodeType(modelID, id) {
- const typeID = this.state.models[modelID].types[id];
- return this.state.api.GetNameFromTypeCode(typeID);
- }
- async getChunks(modelID, chunks, propNames) {
- const relation = await this.state.api.GetLineIDsWithType(modelID, propNames.name);
- for (let i = 0; i < relation.size(); i++) {
- const rel = await this.state.api.GetLine(modelID, relation.get(i), false);
- this.saveChunk(chunks, propNames, rel);
- }
- }
- async getAllRelatedItemsOfType(modelID, id, propNames) {
- const lines = await this.state.api.GetLineIDsWithType(modelID, propNames.name);
- const IDs = [];
- for (let i = 0; i < lines.size(); i++) {
- const rel = await this.state.api.GetLine(modelID, lines.get(i));
- const isRelated = BasePropertyManager.isRelated(id, rel, propNames);
- if (isRelated)
- this.getRelated(rel, propNames, IDs);
- }
- return IDs;
- }
- }
- class JSONPropertyManager extends BasePropertyManager {
- async getItemProperties(modelID, id, recursive = false) {
- return {
- ...this.state.models[modelID].jsonData[id]
- };
- }
- async getHeaderLine(modelID) {
- return {};
- }
- async getSpatialStructure(modelID, includeProperties) {
- const chunks = await this.getSpatialTreeChunks(modelID);
- const projectsIDs = await this.getAllItemsOfType(modelID, IFCPROJECT, false);
- const projectID = projectsIDs[0];
- const project = JSONPropertyManager.newIfcProject(projectID);
- await this.getSpatialNode(modelID, project, chunks, includeProperties);
- return {
- ...project
- };
- }
- async getAllItemsOfType(modelID, type, verbose) {
- const data = this.state.models[modelID].jsonData;
- const typeName = await this.state.api.GetNameFromTypeCode(type);
- if (!typeName) {
- throw new Error(`Type not found: ${type}`);
- }
- return this.filterItemsByType(data, typeName, verbose);
- }
- async getProperty(modelID, elementID, recursive = false, propName) {
- const resultIDs = await this.getAllRelatedItemsOfType(modelID, elementID, propName);
- const result = this.getItemsByID(modelID, resultIDs);
- if (recursive) {
- result.forEach(result => this.getReferencesRecursively(modelID, result));
- }
- return result;
- }
- getNodeType(modelID, id) {
- return this.state.models[modelID].jsonData[id].type;
- }
- async getChunks(modelID, chunks, propNames) {
- const relation = await this.getAllItemsOfType(modelID, propNames.name, true);
- relation.forEach(rel => {
- this.saveChunk(chunks, propNames, rel);
- });
- }
- filterItemsByType(data, typeName, verbose) {
- const result = [];
- Object.keys(data).forEach(key => {
- const numKey = parseInt(key);
- if (data[numKey].type.toUpperCase() === typeName) {
- result.push(verbose ? {
- ...data[numKey]
- } : numKey);
- }
- });
- return result;
- }
- async getAllRelatedItemsOfType(modelID, id, propNames) {
- const lines = await this.getAllItemsOfType(modelID, propNames.name, true);
- const IDs = [];
- lines.forEach(line => {
- const isRelated = JSONPropertyManager.isRelated(id, line, propNames);
- if (isRelated)
- this.getRelated(line, propNames, IDs);
- });
- return IDs;
- }
- getItemsByID(modelID, ids) {
- const data = this.state.models[modelID].jsonData;
- const result = [];
- ids.forEach(id => result.push({
- ...data[id]
- }));
- return result;
- }
- getReferencesRecursively(modelID, jsonObject) {
- if (jsonObject == undefined)
- return;
- const keys = Object.keys(jsonObject);
- for (let i = 0; i < keys.length; i++) {
- const key = keys[i];
- this.getJSONItem(modelID, jsonObject, key);
- }
- }
- getJSONItem(modelID, jsonObject, key) {
- if (Array.isArray(jsonObject[key])) {
- return this.getMultipleJSONItems(modelID, jsonObject, key);
- }
- if (jsonObject[key] && jsonObject[key].type === 5) {
- jsonObject[key] = this.getItemsByID(modelID, [jsonObject[key].value])[0];
- this.getReferencesRecursively(modelID, jsonObject[key]);
- }
- }
- getMultipleJSONItems(modelID, jsonObject, key) {
- jsonObject[key] = jsonObject[key].map((item) => {
- if (item.type === 5) {
- item = this.getItemsByID(modelID, [item.value])[0];
- this.getReferencesRecursively(modelID, item);
- }
- return item;
- });
- }
- }
- const geometryTypes = new Set([
- 1123145078, 574549367, 1675464909, 2059837836, 3798115385, 32440307, 3125803723, 3207858831,
- 2740243338, 2624227202, 4240577450, 3615266464, 3724593414, 220341763, 477187591, 1878645084,
- 1300840506, 3303107099, 1607154358, 1878645084, 846575682, 1351298697, 2417041796, 3049322572,
- 3331915920, 1416205885, 776857604, 3285139300, 3958052878, 2827736869, 2732653382, 673634403,
- 3448662350, 4142052618, 2924175390, 803316827, 2556980723, 1809719519, 2205249479, 807026263,
- 3737207727, 1660063152, 2347385850, 3940055652, 2705031697, 3732776249, 2485617015, 2611217952,
- 1704287377, 2937912522, 2770003689, 1281925730, 1484403080, 3448662350, 4142052618, 3800577675,
- 4006246654, 3590301190, 1383045692, 2775532180, 2047409740, 370225590, 3593883385, 2665983363,
- 4124623270, 812098782, 3649129432, 987898635, 1105321065, 3510044353, 1635779807, 2603310189,
- 3406155212, 1310608509, 4261334040, 2736907675, 3649129432, 1136057603, 1260505505, 4182860854,
- 2713105998, 2898889636, 59481748, 3749851601, 3486308946, 3150382593, 1062206242, 3264961684,
- 15328376, 1485152156, 370225590, 1981873012, 2859738748, 45288368, 2614616156, 2732653382,
- 775493141, 2147822146, 2601014836, 2629017746, 1186437898, 2367409068, 1213902940, 3632507154,
- 3900360178, 476780140, 1472233963, 2804161546, 3008276851, 738692330, 374418227, 315944413,
- 3905492369, 3570813810, 2571569899, 178912537, 2294589976, 1437953363, 2133299955, 572779678,
- 3092502836, 388784114, 2624227202, 1425443689, 3057273783, 2347385850, 1682466193, 2519244187,
- 2839578677, 3958567839, 2513912981, 2830218821, 427810014
- ]);
- class PropertySerializer {
- constructor(webIfc) {
- this.webIfc = webIfc;
- }
- dispose() {
- this.webIfc = null;
- }
- async serializeAllProperties(modelID, maxSize, event) {
- const blobs = [];
- await this.getPropertiesAsBlobs(modelID, blobs, maxSize, event);
- return blobs;
- }
- async getPropertiesAsBlobs(modelID, blobs, maxSize, event) {
- const geometriesIDs = await this.getAllGeometriesIDs(modelID);
- let properties = await this.initializePropertiesObject(modelID);
- const allLinesIDs = await this.webIfc.GetAllLines(modelID);
- const linesCount = allLinesIDs.size();
- let lastEvent = 0.1;
- let counter = 0;
- for (let i = 0; i < linesCount; i++) {
- const id = allLinesIDs.get(i);
- if (!geometriesIDs.has(id)) {
- await this.getItemProperty(modelID, id, properties);
- counter++;
- }
- if (maxSize && counter > maxSize) {
- blobs.push(new Blob([JSON.stringify(properties)], {
- type: 'application/json'
- }));
- properties = {};
- counter = 0;
- }
- if (event && i / linesCount > lastEvent) {
- event(i, linesCount);
- lastEvent += 0.1;
- }
- }
- blobs.push(new Blob([JSON.stringify(properties)], {
- type: 'application/json'
- }));
- }
- async getItemProperty(modelID, id, properties) {
- try {
- const props = await this.webIfc.GetLine(modelID, id);
- if (props.type) {
- props.type = this.webIfc.GetNameFromTypeCode(props.type);
- }
- this.formatItemProperties(props);
- properties[id] = props;
- } catch (e) {
- console.log(`There was a problem getting the properties of the item with ID ${id}`);
- }
- }
- formatItemProperties(props) {
- Object.keys(props).forEach((key) => {
- const value = props[key];
- if (value && value.value !== undefined)
- props[key] = value.value;
- else if (Array.isArray(value))
- props[key] = value.map((item) => {
- if (item && item.value)
- return item.value;
- return item;
- });
- });
- }
- async initializePropertiesObject(modelID) {
- return {
- coordinationMatrix: await this.webIfc.GetCoordinationMatrix(modelID),
- globalHeight: await this.getBuildingHeight(modelID)
- };
- }
- async getBuildingHeight(modelID) {
- const building = await this.getBuilding(modelID);
- let placement;
- const siteReference = building.ObjectPlacement.PlacementRelTo;
- if (siteReference)
- placement = siteReference.RelativePlacement.Location;
- else
- placement = building.ObjectPlacement.RelativePlacement.Location;
- const transform = placement.Coordinates.map((coord) => coord.value);
- return transform[2];
- }
- async getBuilding(modelID) {
- const allBuildingsIDs = await this.webIfc.GetLineIDsWithType(modelID, IFCBUILDING);
- const buildingID = allBuildingsIDs.get(0);
- return this.webIfc.GetLine(modelID, buildingID, true);
- }
- async getAllGeometriesIDs(modelID) {
- const geometriesIDs = new Set();
- const geomTypesArray = Array.from(geometryTypes);
- for (let i = 0; i < geomTypesArray.length; i++) {
- const category = geomTypesArray[i];
- const ids = await this.webIfc.GetLineIDsWithType(modelID, category);
- const idsSize = ids.size();
- for (let j = 0; j < idsSize; j++) {
- geometriesIDs.add(ids.get(j));
- }
- }
- return geometriesIDs;
- }
- }
- class PropertyManager {
- constructor(state) {
- this.state = state;
- this.webIfcProps = new WebIfcPropertyManager(state);
- this.jsonProps = new JSONPropertyManager(state);
- this.currentProps = this.webIfcProps;
- this.serializer = new PropertySerializer(this.state.api);
- }
- getExpressId(geometry, faceIndex) {
- if (!geometry.index)
- throw new Error('Geometry does not have index information.');
- const geoIndex = geometry.index.array;
- const bufferAttr = geometry.attributes[IdAttrName];
- return bufferAttr.getX(geoIndex[3 * faceIndex]);
- }
- async getHeaderLine(modelID, headerType) {
- this.updateCurrentProps();
- return this.currentProps.getHeaderLine(modelID, headerType);
- }
- async getItemProperties(modelID, elementID, recursive = false) {
- this.updateCurrentProps();
- return this.currentProps.getItemProperties(modelID, elementID, recursive);
- }
- async getAllItemsOfType(modelID, type, verbose) {
- this.updateCurrentProps();
- return this.currentProps.getAllItemsOfType(modelID, type, verbose);
- }
- async getPropertySets(modelID, elementID, recursive = false) {
- this.updateCurrentProps();
- return this.currentProps.getPropertySets(modelID, elementID, recursive);
- }
- async getTypeProperties(modelID, elementID, recursive = false) {
- this.updateCurrentProps();
- return this.currentProps.getTypeProperties(modelID, elementID, recursive);
- }
- async getMaterialsProperties(modelID, elementID, recursive = false) {
- this.updateCurrentProps();
- return this.currentProps.getMaterialsProperties(modelID, elementID, recursive);
- }
- async getSpatialStructure(modelID, includeProperties) {
- this.updateCurrentProps();
- if (!this.state.useJSON && includeProperties) {
- console.warn('Including properties in getSpatialStructure with the JSON workflow disabled can lead to poor performance.');
- }
- return await this.currentProps.getSpatialStructure(modelID, includeProperties);
- }
- updateCurrentProps() {
- this.currentProps = this.state.useJSON ? this.jsonProps : this.webIfcProps;
- }
- }
- class TypeManager {
- constructor(state) {
- this.state = state;
- this.state = state;
- }
- async getAllTypes(worker) {
- for (let modelID in this.state.models) {
- if (this.state.models.hasOwnProperty(modelID)) {
- const types = this.state.models[modelID].types;
- if (Object.keys(types).length == 0) {
- await this.getAllTypesOfModel(parseInt(modelID), worker);
- }
- }
- }
- }
- async getAllTypesOfModel(modelID, worker) {
- const result = {};
- const elements = await this.state.api.GetIfcEntityList(modelID);
- for (let i = 0; i < elements.length; i++) {
- const element = elements[i];
- const lines = await this.state.api.GetLineIDsWithType(modelID, element);
- const size = lines.size();
- for (let i = 0; i < size; i++)
- result[lines.get(i)] = element;
- }
- if (this.state.worker.active && worker) {
- await worker.workerState.updateModelStateTypes(modelID, result);
- }
- this.state.models[modelID].types = result;
- }
- }
- class BvhManager {
- initializeMeshBVH(computeBoundsTree, disposeBoundsTree, acceleratedRaycast) {
- this.computeBoundsTree = computeBoundsTree;
- this.disposeBoundsTree = disposeBoundsTree;
- this.acceleratedRaycast = acceleratedRaycast;
- this.setupThreeMeshBVH();
- }
- applyThreeMeshBVH(geometry) {
- if (this.computeBoundsTree)
- geometry.computeBoundsTree();
- }
- setupThreeMeshBVH() {
- if (!this.computeBoundsTree || !this.disposeBoundsTree || !this.acceleratedRaycast)
- return;
- BufferGeometry.prototype.computeBoundsTree = this.computeBoundsTree;
- BufferGeometry.prototype.disposeBoundsTree = this.disposeBoundsTree;
- Mesh.prototype.raycast = this.acceleratedRaycast;
- }
- }
- var WorkerActions;
- (function(WorkerActions) {
- WorkerActions["updateStateUseJson"] = "updateStateUseJson";
- WorkerActions["updateStateWebIfcSettings"] = "updateStateWebIfcSettings";
- WorkerActions["updateModelStateTypes"] = "updateModelStateTypes";
- WorkerActions["updateModelStateJsonData"] = "updateModelStateJsonData";
- WorkerActions["loadJsonDataFromWorker"] = "loadJsonDataFromWorker";
- WorkerActions["dispose"] = "dispose";
- WorkerActions["Close"] = "Close";
- WorkerActions["DisposeWebIfc"] = "DisposeWebIfc";
- WorkerActions["Init"] = "Init";
- WorkerActions["OpenModel"] = "OpenModel";
- WorkerActions["CreateModel"] = "CreateModel";
- WorkerActions["ExportFileAsIFC"] = "ExportFileAsIFC";
- WorkerActions["GetGeometry"] = "GetGeometry";
- WorkerActions["GetLine"] = "GetLine";
- WorkerActions["GetAndClearErrors"] = "GetAndClearErrors";
- WorkerActions["WriteLine"] = "WriteLine";
- WorkerActions["FlattenLine"] = "FlattenLine";
- WorkerActions["GetRawLineData"] = "GetRawLineData";
- WorkerActions["WriteRawLineData"] = "WriteRawLineData";
- WorkerActions["GetLineIDsWithType"] = "GetLineIDsWithType";
- WorkerActions["GetAllLines"] = "GetAllLines";
- WorkerActions["SetGeometryTransformation"] = "SetGeometryTransformation";
- WorkerActions["GetCoordinationMatrix"] = "GetCoordinationMatrix";
- WorkerActions["GetVertexArray"] = "GetVertexArray";
- WorkerActions["GetIndexArray"] = "GetIndexArray";
- WorkerActions["getSubArray"] = "getSubArray";
- WorkerActions["CloseModel"] = "CloseModel";
- WorkerActions["StreamAllMeshes"] = "StreamAllMeshes";
- WorkerActions["StreamAllMeshesWithTypes"] = "StreamAllMeshesWithTypes";
- WorkerActions["IsModelOpen"] = "IsModelOpen";
- WorkerActions["LoadAllGeometry"] = "LoadAllGeometry";
- WorkerActions["GetFlatMesh"] = "GetFlatMesh";
- WorkerActions["SetWasmPath"] = "SetWasmPath";
- WorkerActions["GetNameFromTypeCode"] = "GetNameFromTypeCode";
- WorkerActions["GetIfcEntityList"] = "GetIfcEntityList";
- WorkerActions["GetTypeCodeFromName"] = "GetTypeCodeFromName";
- WorkerActions["parse"] = "parse";
- WorkerActions["setupOptionalCategories"] = "setupOptionalCategories";
- WorkerActions["getExpressId"] = "getExpressId";
- WorkerActions["initializeProperties"] = "initializeProperties";
- WorkerActions["getAllItemsOfType"] = "getAllItemsOfType";
- WorkerActions["getItemProperties"] = "getItemProperties";
- WorkerActions["getMaterialsProperties"] = "getMaterialsProperties";
- WorkerActions["getPropertySets"] = "getPropertySets";
- WorkerActions["getSpatialStructure"] = "getSpatialStructure";
- WorkerActions["getTypeProperties"] = "getTypeProperties";
- WorkerActions["getHeaderLine"] = "getHeaderLine";
- })(WorkerActions || (WorkerActions = {}));
- var WorkerAPIs;
- (function(WorkerAPIs) {
- WorkerAPIs["workerState"] = "workerState";
- WorkerAPIs["webIfc"] = "webIfc";
- WorkerAPIs["properties"] = "properties";
- WorkerAPIs["parser"] = "parser";
- })(WorkerAPIs || (WorkerAPIs = {}));
- class Vector {
- constructor(vector) {
- this._data = {};
- this._size = vector.size;
- const keys = Object.keys(vector).filter((key) => key.indexOf('size') === -1).map(key => parseInt(key));
- keys.forEach((key) => this._data[key] = vector[key]);
- }
- size() {
- return this._size;
- }
- get(index) {
- return this._data[index];
- }
- }
- class IfcGeometry {
- constructor(vector) {
- this._GetVertexData = vector.GetVertexData;
- this._GetVertexDataSize = vector.GetVertexDataSize;
- this._GetIndexData = vector.GetIndexData;
- this._GetIndexDataSize = vector.GetIndexDataSize;
- }
- GetVertexData() {
- return this._GetVertexData;
- }
- GetVertexDataSize() {
- return this._GetVertexDataSize;
- }
- GetIndexData() {
- return this._GetIndexData;
- }
- GetIndexDataSize() {
- return this._GetIndexDataSize;
- }
- }
- class FlatMesh {
- constructor(serializer, flatMesh) {
- this.expressID = flatMesh.expressID;
- this.geometries = serializer.reconstructVector(flatMesh.geometries);
- }
- }
- class FlatMeshVector {
- constructor(serializer, vector) {
- this._data = {};
- this._size = vector.size;
- const keys = Object.keys(vector).filter((key) => key.indexOf('size') === -1).map(key => parseInt(key));
- keys.forEach(key => this._data[key] = serializer.reconstructFlatMesh(vector[key]));
- }
- size() {
- return this._size;
- }
- get(index) {
- return this._data[index];
- }
- }
- class SerializedMaterial {
- constructor(material) {
- this.color = [material.color.r, material.color.g, material.color.b];
- this.opacity = material.opacity;
- this.transparent = material.transparent;
- }
- }
- class MaterialReconstructor {
- static new(material) {
- return new MeshLambertMaterial({
- color: new Color(material.color[0], material.color[1], material.color[2]),
- opacity: material.opacity,
- transparent: material.transparent,
- side: DoubleSide
- });
- }
- }
- class SerializedGeometry {
- constructor(geometry) {
- var _a,
- _b,
- _c,
- _d;
- this.position = ((_a = geometry.attributes.position) === null || _a === void 0 ? void 0 : _a.array) || [];
- this.normal = ((_b = geometry.attributes.normal) === null || _b === void 0 ? void 0 : _b.array) || [];
- this.expressID = ((_c = geometry.attributes.expressID) === null || _c === void 0 ? void 0 : _c.array) || [];
- this.index = ((_d = geometry.index) === null || _d === void 0 ? void 0 : _d.array) || [];
- this.groups = geometry.groups;
- }
- }
- class GeometryReconstructor {
- static new(serialized) {
- const geom = new BufferGeometry();
- GeometryReconstructor.set(geom, 'expressID', new Uint32Array(serialized.expressID), 1);
- GeometryReconstructor.set(geom, 'position', new Float32Array(serialized.position), 3);
- GeometryReconstructor.set(geom, 'normal', new Float32Array(serialized.normal), 3);
- geom.setIndex(Array. from (serialized.index));
- geom.groups = serialized.groups;
- return geom;
- }
- static set(geom, name, data, size) {
- if (data.length > 0) {
- geom.setAttribute(name, new BufferAttribute(data, size));
- }
- }
- }
- class SerializedMesh {
- constructor(model) {
- this.materials = [];
- this.modelID = model.modelID;
- this.geometry = new SerializedGeometry(model.geometry);
- if (Array.isArray(model.material)) {
- model.material.forEach(mat => {
- this.materials.push(new SerializedMaterial(mat));
- });
- } else {
- this.materials.push(new SerializedMaterial(model.material));
- }
- }
- }
- class MeshReconstructor {
- static new(serialized) {
- const model = new IFCModel();
- model.modelID = serialized.modelID;
- model.geometry = GeometryReconstructor.new(serialized.geometry);
- MeshReconstructor.getMaterials(serialized, model);
- return model;
- }
- static getMaterials(serialized, model) {
- model.material = [];
- const mats = model.material;
- serialized.materials.forEach(mat => {
- mats.push(MaterialReconstructor.new(mat));
- });
- }
- }
- class Serializer {
- serializeVector(vector) {
- const size = vector.size();
- const serialized = {
- size
- };
- for (let i = 0; i < size; i++) {
- serialized[i] = vector.get(i);
- }
- return serialized;
- }
- reconstructVector(vector) {
- return new Vector(vector);
- }
- serializeIfcGeometry(geometry) {
- const GetVertexData = geometry.GetVertexData();
- const GetVertexDataSize = geometry.GetVertexDataSize();
- const GetIndexData = geometry.GetIndexData();
- const GetIndexDataSize = geometry.GetIndexDataSize();
- return {
- GetVertexData,
- GetVertexDataSize,
- GetIndexData,
- GetIndexDataSize
- };
- }
- reconstructIfcGeometry(geometry) {
- return new IfcGeometry(geometry);
- }
- serializeFlatMesh(flatMesh) {
- return {
- expressID: flatMesh.expressID,
- geometries: this.serializeVector(flatMesh.geometries)
- };
- }
- reconstructFlatMesh(flatMesh) {
- return new FlatMesh(this, flatMesh);
- }
- serializeFlatMeshVector(vector) {
- const size = vector.size();
- const serialized = {
- size
- };
- for (let i = 0; i < size; i++) {
- const flatMesh = vector.get(i);
- serialized[i] = this.serializeFlatMesh(flatMesh);
- }
- return serialized;
- }
- reconstructFlatMeshVector(vector) {
- return new FlatMeshVector(this, vector);
- }
- serializeIfcModel(model) {
- return new SerializedMesh(model);
- }
- reconstructIfcModel(model) {
- return MeshReconstructor.new(model);
- }
- }
- class PropertyHandler {
- constructor(handler) {
- this.handler = handler;
- this.API = WorkerAPIs.properties;
- }
- getExpressId(geometry, faceIndex) {
- if (!geometry.index)
- throw new Error('Geometry does not have index information.');
- const geoIndex = geometry.index.array;
- const bufferAttr = geometry.attributes[IdAttrName];
- return bufferAttr.getX(geoIndex[3 * faceIndex]);
- }
- getHeaderLine(modelID, headerType) {
- return this.handler.request(this.API, WorkerActions.getHeaderLine, {
- modelID,
- headerType
- });
- }
- getAllItemsOfType(modelID, type, verbose) {
- return this.handler.request(this.API, WorkerActions.getAllItemsOfType, {
- modelID,
- type,
- verbose
- });
- }
- getItemProperties(modelID, elementID, recursive) {
- return this.handler.request(this.API, WorkerActions.getItemProperties, {
- modelID,
- elementID,
- recursive
- });
- }
- getMaterialsProperties(modelID, elementID, recursive) {
- return this.handler.request(this.API, WorkerActions.getMaterialsProperties, {
- modelID,
- elementID,
- recursive
- });
- }
- getPropertySets(modelID, elementID, recursive) {
- return this.handler.request(this.API, WorkerActions.getPropertySets, {
- modelID,
- elementID,
- recursive
- });
- }
- getTypeProperties(modelID, elementID, recursive) {
- return this.handler.request(this.API, WorkerActions.getTypeProperties, {
- modelID,
- elementID,
- recursive
- });
- }
- getSpatialStructure(modelID, includeProperties) {
- return this.handler.request(this.API, WorkerActions.getSpatialStructure, {
- modelID,
- includeProperties
- });
- }
- }
- class WebIfcHandler {
- constructor(handler, serializer) {
- this.handler = handler;
- this.serializer = serializer;
- this.API = WorkerAPIs.webIfc;
- }
- async Init() {
- this.wasmModule = true;
- return this.handler.request(this.API, WorkerActions.Init);
- }
- async OpenModel(data, settings) {
- return this.handler.request(this.API, WorkerActions.OpenModel, {
- data,
- settings
- });
- }
- async CreateModel(model, settings) {
- return this.handler.request(this.API, WorkerActions.CreateModel, {
- model,
- settings
- });
- }
- async ExportFileAsIFC(modelID) {
- return this.handler.request(this.API, WorkerActions.ExportFileAsIFC, {
- modelID
- });
- }
- async GetHeaderLine(modelID, headerType) {
- return this.handler.request(this.API, WorkerActions.getHeaderLine, {
- modelID,
- headerType
- });
- }
- async GetGeometry(modelID, geometryExpressID) {
- this.handler.serializeHandlers[this.handler.requestID] = (geom) => {
- return this.serializer.reconstructIfcGeometry(geom);
- };
- return this.handler.request(this.API, WorkerActions.GetGeometry, {
- modelID,
- geometryExpressID
- });
- }
- async GetLine(modelID, expressID, flatten) {
- return this.handler.request(this.API, WorkerActions.GetLine, {
- modelID,
- expressID,
- flatten
- });
- }
- async GetAndClearErrors(modelID) {
- this.handler.serializeHandlers[this.handler.requestID] = (vector) => {
- return this.serializer.reconstructVector(vector);
- };
- return this.handler.request(this.API, WorkerActions.GetAndClearErrors, {
- modelID
- });
- }
- async GetNameFromTypeCode(type) {
- return this.handler.request(this.API, WorkerActions.GetNameFromTypeCode, {
- type
- });
- }
- async GetIfcEntityList(modelID) {
- return this.handler.request(this.API, WorkerActions.GetIfcEntityList, {
- modelID
- });
- }
- async GetTypeCodeFromName(modelID, typeName) {
- return this.handler.request(this.API, WorkerActions.GetTypeCodeFromName, {
- modelID,
- typeName
- });
- }
- async WriteLine(modelID, lineObject) {
- return this.handler.request(this.API, WorkerActions.WriteLine, {
- modelID,
- lineObject
- });
- }
- async FlattenLine(modelID, line) {
- return this.handler.request(this.API, WorkerActions.FlattenLine, {
- modelID,
- line
- });
- }
- async GetRawLineData(modelID, expressID) {
- return this.handler.request(this.API, WorkerActions.GetRawLineData, {
- modelID,
- expressID
- });
- }
- async WriteRawLineData(modelID, data) {
- return this.handler.request(this.API, WorkerActions.WriteRawLineData, {
- modelID,
- data
- });
- }
- async GetLineIDsWithType(modelID, type) {
- this.handler.serializeHandlers[this.handler.requestID] = (vector) => {
- return this.serializer.reconstructVector(vector);
- };
- return this.handler.request(this.API, WorkerActions.GetLineIDsWithType, {
- modelID,
- type
- });
- }
- async GetAllLines(modelID) {
- this.handler.serializeHandlers[this.handler.requestID] = (vector) => {
- return this.serializer.reconstructVector(vector);
- };
- return this.handler.request(this.API, WorkerActions.GetAllLines, {
- modelID
- });
- }
- async SetGeometryTransformation(modelID, transformationMatrix) {
- return this.handler.request(this.API, WorkerActions.SetGeometryTransformation, {
- modelID,
- transformationMatrix
- });
- }
- async GetCoordinationMatrix(modelID) {
- return this.handler.request(this.API, WorkerActions.GetCoordinationMatrix, {
- modelID
- });
- }
- async GetVertexArray(ptr, size) {
- return this.handler.request(this.API, WorkerActions.GetVertexArray, {
- ptr,
- size
- });
- }
- async GetIndexArray(ptr, size) {
- return this.handler.request(this.API, WorkerActions.GetIndexArray, {
- ptr,
- size
- });
- }
- async getSubArray(heap, startPtr, sizeBytes) {
- return this.handler.request(this.API, WorkerActions.getSubArray, {
- heap,
- startPtr,
- sizeBytes
- });
- }
- async CloseModel(modelID) {
- return this.handler.request(this.API, WorkerActions.CloseModel, {
- modelID
- });
- }
- async StreamAllMeshes(modelID, meshCallback) {
- this.handler.callbackHandlers[this.handler.requestID] = {
- action: meshCallback,
- serializer: this.serializer.reconstructFlatMesh
- };
- return this.handler.request(this.API, WorkerActions.StreamAllMeshes, {
- modelID
- });
- }
- async StreamAllMeshesWithTypes(modelID, types, meshCallback) {
- this.handler.callbackHandlers[this.handler.requestID] = {
- action: meshCallback,
- serializer: this.serializer.reconstructFlatMesh
- };
- return this.handler.request(this.API, WorkerActions.StreamAllMeshesWithTypes, {
- modelID,
- types
- });
- }
- async IsModelOpen(modelID) {
- return this.handler.request(this.API, WorkerActions.IsModelOpen, {
- modelID
- });
- }
- async LoadAllGeometry(modelID) {
- this.handler.serializeHandlers[this.handler.requestID] = (vector) => {
- return this.serializer.reconstructFlatMeshVector(vector);
- };
- return this.handler.request(this.API, WorkerActions.LoadAllGeometry, {
- modelID
- });
- }
- async GetFlatMesh(modelID, expressID) {
- this.handler.serializeHandlers[this.handler.requestID] = (flatMesh) => {
- return this.serializer.reconstructFlatMesh(flatMesh);
- };
- return this.handler.request(this.API, WorkerActions.GetFlatMesh, {
- modelID,
- expressID
- });
- }
- async SetWasmPath(path) {
- return this.handler.request(this.API, WorkerActions.SetWasmPath, {
- path
- });
- }
- }
- class WorkerStateHandler {
- constructor(handler) {
- this.handler = handler;
- this.API = WorkerAPIs.workerState;
- this.state = this.handler.state;
- }
- async updateStateUseJson() {
- const useJson = this.state.useJSON;
- return this.handler.request(this.API, WorkerActions.updateStateUseJson, {
- useJson
- });
- }
- async updateStateWebIfcSettings() {
- const webIfcSettings = this.state.webIfcSettings;
- return this.handler.request(this.API, WorkerActions.updateStateWebIfcSettings, {
- webIfcSettings
- });
- }
- async updateModelStateTypes(modelID, types) {
- return this.handler.request(this.API, WorkerActions.updateModelStateTypes, {
- modelID,
- types
- });
- }
- async updateModelStateJsonData(modelID, jsonData) {
- return this.handler.request(this.API, WorkerActions.updateModelStateJsonData, {
- modelID,
- jsonData
- });
- }
- async loadJsonDataFromWorker(modelID, path) {
- return this.handler.request(this.API, WorkerActions.loadJsonDataFromWorker, {
- modelID,
- path
- });
- }
- }
- var DBOperation;
- (function(DBOperation) {
- DBOperation[DBOperation["transferIfcModel"] = 0] = "transferIfcModel";
- DBOperation[DBOperation["transferIndividualItems"] = 1] = "transferIndividualItems";
- })(DBOperation || (DBOperation = {}));
- class IndexedDatabase {
- async save(item, id) {
- const open = IndexedDatabase.openOrCreateDB(id);
- this.createSchema(open, id);
- return new Promise((resolve, reject) => {
- open.onsuccess = () => this.saveItem(item, open, id, resolve);
- });
- }
- async load(id) {
- const open = IndexedDatabase.openOrCreateDB(id);
- return new Promise((resolve, reject) => {
- open.onsuccess = () => this.loadItem(open, id, resolve);
- });
- }
- createSchema(open, id) {
- open.onupgradeneeded = function() {
- const db = open.result;
- db.createObjectStore(id.toString(), {
- keyPath: "id"
- });
- };
- }
- saveItem(item, open, id, resolve) {
- const {db, tx, store} = IndexedDatabase.getDBItems(open, id);
- item.id = id;
- store.put(item);
- tx.oncomplete = () => IndexedDatabase.closeDB(db, tx, resolve);
- }
- loadItem(open, id, resolve) {
- const {db, tx, store} = IndexedDatabase.getDBItems(open, id);
- const item = store.get(id);
- const callback = () => {
- delete item.result.id;
- resolve(item.result);
- };
- tx.oncomplete = () => IndexedDatabase.closeDB(db, tx, callback);
- }
- static getDBItems(open, id) {
- const db = open.result;
- const tx = db.transaction(id.toString(), "readwrite");
- const store = tx.objectStore(id.toString());
- return {
- db,
- tx,
- store
- };
- }
- static openOrCreateDB(id) {
- return indexedDB.open(id.toString(), 1);
- }
- static closeDB(db, tx, resolve) {
- db.close();
- resolve("success");
- }
- }
- class ParserHandler {
- constructor(handler, serializer, BVH, IDB) {
- this.handler = handler;
- this.serializer = serializer;
- this.BVH = BVH;
- this.IDB = IDB;
- this.optionalCategories = {
- [IFCSPACE]: true,
- [IFCOPENINGELEMENT]: false
- };
- this.API = WorkerAPIs.parser;
- }
- async setupOptionalCategories(config) {
- this.optionalCategories = config;
- return this.handler.request(this.API, WorkerActions.setupOptionalCategories, {
- config
- });
- }
- async parse(buffer, coordinationMatrix) {
- this.handler.onprogressHandlers[this.handler.requestID] = (progress) => {
- if (this.handler.state.onProgress)
- this.handler.state.onProgress(progress);
- };
- this.handler.serializeHandlers[this.handler.requestID] = async (result) => {
- this.updateState(result.modelID);
- return this.getModel();
- };
- return this.handler.request(this.API, WorkerActions.parse, {
- buffer,
- coordinationMatrix
- });
- }
- getAndClearErrors(_modelId) {}
- updateState(modelID) {
- this.handler.state.models[modelID] = {
- modelID: modelID,
- mesh: {},
- types: {},
- jsonData: {}
- };
- }
- async getModel() {
- const serializedModel = await this.IDB.load(DBOperation.transferIfcModel);
- const model = this.serializer.reconstructIfcModel(serializedModel);
- this.BVH.applyThreeMeshBVH(model.geometry);
- this.handler.state.models[model.modelID].mesh = model;
- return model;
- }
- }
- class IFCWorkerHandler {
- constructor(state, BVH) {
- this.state = state;
- this.BVH = BVH;
- this.requestID = 0;
- this.rejectHandlers = {};
- this.resolveHandlers = {};
- this.serializeHandlers = {};
- this.callbackHandlers = {};
- this.onprogressHandlers = {};
- this.serializer = new Serializer();
- this.IDB = new IndexedDatabase();
- this.workerPath = this.state.worker.path;
- this.ifcWorker = new Worker(this.workerPath);
- this.ifcWorker.onmessage = (data) => this.handleResponse(data);
- this.properties = new PropertyHandler(this);
- this.parser = new ParserHandler(this, this.serializer, this.BVH, this.IDB);
- this.webIfc = new WebIfcHandler(this, this.serializer);
- this.workerState = new WorkerStateHandler(this);
- }
- request(worker, action, args) {
- const data = {
- worker,
- action,
- args,
- id: this.requestID,
- result: undefined,
- onProgress: false
- };
- return new Promise((resolve, reject) => {
- this.resolveHandlers[this.requestID] = resolve;
- this.rejectHandlers[this.requestID] = reject;
- this.requestID++;
- this.ifcWorker.postMessage(data);
- });
- }
- async terminate() {
- await this.request(WorkerAPIs.workerState, WorkerActions.dispose);
- await this.request(WorkerAPIs.webIfc, WorkerActions.DisposeWebIfc);
- this.ifcWorker.terminate();
- }
- async Close() {
- await this.request(WorkerAPIs.webIfc, WorkerActions.Close);
- }
- handleResponse(event) {
- const data = event.data;
- if (data.onProgress) {
- this.resolveOnProgress(data);
- return;
- }
- this.callHandlers(data);
- delete this.resolveHandlers[data.id];
- delete this.rejectHandlers[data.id];
- delete this.onprogressHandlers[data.id];
- }
- callHandlers(data) {
- try {
- this.resolveSerializations(data);
- this.resolveCallbacks(data);
- this.resolveHandlers[data.id](data.result);
- } catch (error) {
- this.rejectHandlers[data.id](error);
- }
- }
- resolveOnProgress(data) {
- if (this.onprogressHandlers[data.id]) {
- data.result = this.onprogressHandlers[data.id](data.result);
- }
- }
- resolveSerializations(data) {
- if (this.serializeHandlers[data.id]) {
- data.result = this.serializeHandlers[data.id](data.result);
- delete this.serializeHandlers[data.id];
- }
- }
- resolveCallbacks(data) {
- if (this.callbackHandlers[data.id]) {
- let callbackParameter = data.result;
- if (this.callbackHandlers[data.id].serializer) {
- callbackParameter = this.callbackHandlers[data.id].serializer(data.result);
- }
- this.callbackHandlers[data.id].action(callbackParameter);
- }
- }
- }
- class MemoryCleaner {
- constructor(state) {
- this.state = state;
- }
- async dispose() {
- Object.keys(this.state.models).forEach(modelID => {
- const model = this.state.models[parseInt(modelID, 10)];
- model.mesh.removeFromParent();
- const geom = model.mesh.geometry;
- if (geom.disposeBoundsTree)
- geom.disposeBoundsTree();
- geom.dispose();
- if (!Array.isArray(model.mesh.material))
- model.mesh.material.dispose();
- else
- model.mesh.material.forEach(mat => mat.dispose());
- model.mesh = null;
- model.types = null;
- model.jsonData = null;
- });
- this.state.api = null;
- this.state.models = null;
- }
- }
- class IFCUtils {
- constructor(state) {
- this.state = state;
- this.map = {};
- }
- isA(entity, entity_class) {
- var test = false;
- if (entity_class) {
- if (this.state.api.GetNameFromTypeCode(entity.type) === entity_class.toUpperCase()) {
- test = true;
- }
- return test;
- } else {
- return this.state.api.GetNameFromTypeCode(entity.type);
- }
- }
- async byId(modelID, id) {
- return this.state.api.GetLine(modelID, id);
- }
- async idsByType(modelID, entity_class) {
- let entities_ids = await this.state.api.GetLineIDsWithType(modelID, Number(this.state.api.GetTypeCodeFromName(modelID, entity_class.toUpperCase())));
- return entities_ids;
- }
- async byType(modelID, entity_class) {
- let entities_ids = await this.idsByType(modelID, entity_class);
- if (entities_ids !== null) {
- let items = [];
- for (let i = 0; i < entities_ids.size(); i++) {
- let entity = await this.byId(modelID, entities_ids.get(i));
- items.push(entity);
- }
- return items;
- }
- }
- }
- class Data {
- constructor(state) {
- this.state = state;
- this.isLoaded = false;
- this.workPlans = {};
- this.workSchedules = {};
- this.workCalendars = {};
- this.workTimes = {};
- this.recurrencePatterns = {};
- this.timePeriods = {};
- this.tasks = {};
- this.taskTimes = {};
- this.lagTimes = {};
- this.sequences = {};
- this.utils = new IFCUtils(this.state);
- }
- async load(modelID) {
- await this.loadTasks(modelID);
- await this.loadWorkSchedules(modelID);
- await this.loadWorkCalendars(modelID);
- await this.loadWorkTimes(modelID);
- await this.loadTimePeriods(modelID);
- this.isLoaded = true;
- }
- async loadWorkSchedules(modelID) {
- let workSchedules = await this.utils.byType(modelID, "IfcWorkSchedule");
- for (let i = 0; i < workSchedules.length; i++) {
- let workSchedule = workSchedules[i];
- this.workSchedules[workSchedule.expressID] = {
- "Id": workSchedule.expressID,
- "Name": workSchedule.Name.value,
- "Description": ((workSchedule.Description) ? workSchedule.Description.value : ""),
- "Creators": [],
- "CreationDate": ((workSchedule.CreationDate) ? workSchedule.CreationDate.value : ""),
- "StartTime": ((workSchedule.StartTime) ? workSchedule.StartTime.value : ""),
- "FinishTime": ((workSchedule.FinishTime) ? workSchedule.FinishTime.value : ""),
- "TotalFloat": ((workSchedule.TotalFloat) ? workSchedule.TotalFloat.value : ""),
- "RelatedObjects": [],
- };
- }
- this.loadWorkScheduleRelatedObjects(modelID);
- }
- async loadWorkScheduleRelatedObjects(modelID) {
- let relsControls = await this.utils.byType(modelID, "IfcRelAssignsToControl");
- for (let i = 0; i < relsControls.length; i++) {
- let relControls = relsControls[i];
- let relatingControl = await this.utils.byId(modelID, relControls.RelatingControl.value);
- let relatedObjects = relControls.RelatedObjects;
- if (this.utils.isA(relatingControl, "IfcWorkSchedule")) {
- for (var objectIndex = 0; objectIndex < relatedObjects.length; objectIndex++) {
- this.workSchedules[relatingControl.expressID]["RelatedObjects"].push(relatedObjects[objectIndex].value);
- }
- }
- }
- }
- async loadTasks(modelID) {
- let tasks = await this.utils.byType(modelID, "IfcTask");
- for (let i = 0; i < tasks.length; i++) {
- let task = tasks[i];
- this.tasks[task.expressID] = {
- "Id": task.expressID,
- "Name": ((task.Name) ? task.Name.value : ""),
- "PredefinedType": ((task.PredefinedType) ? task.PredefinedType.value : ""),
- "TaskTime": ((task.TaskTime) ? await this.utils.byId(modelID, task.TaskTime.value) : ""),
- "Identification": ((task.Identification) ? task.Identification.value : ""),
- "IsMilestone": ((task.IsMilestone) ? task.IsMilestone.value : ""),
- "IsPredecessorTo": [],
- "IsSucessorFrom": [],
- "Inputs": [],
- "Resources": [],
- "Outputs": [],
- "Controls": [],
- "Nests": [],
- "IsNestedBy": [],
- "OperatesOn": [],
- "HasAssignmentsWorkCalendars": [],
- };
- }
- await this.loadTaskSequence(modelID);
- await this.loadTaskOutputs(modelID);
- await this.loadTaskNesting(modelID);
- await this.loadTaskOperations(modelID);
- await this.loadAssignementsWorkCalendar(modelID);
- }
- async loadTaskSequence(modelID) {
- let relsSequence = await this.utils.idsByType(modelID, "IfcRelSequence");
- for (let i = 0; i < relsSequence.size(); i++) {
- let relSequenceId = relsSequence.get(i);
- if (relSequenceId !== 0) {
- let relSequence = await this.utils.byId(modelID, relSequenceId);
- let related_process = relSequence.RelatedProcess.value;
- let relatingProcess = relSequence.RelatingProcess.value;
- this.tasks[relatingProcess]["IsPredecessorTo"].push(relSequence.expressID);
- this.tasks[related_process]["IsSucessorFrom"].push(relSequence.expressID);
- }
- }
- }
- async loadTaskOutputs(modelID) {
- let rels_assigns_to_product = await this.utils.byType(modelID, "IfcRelAssignsToProduct");
- for (let i = 0; i < rels_assigns_to_product.length; i++) {
- let relAssignsToProduct = rels_assigns_to_product[i];
- let relatedObject = await this.utils.byId(modelID, relAssignsToProduct.RelatedObjects[0].value);
- if (this.utils.isA(relatedObject, "IfcTask")) {
- let relatingProduct = await this.utils.byId(modelID, relAssignsToProduct.RelatingProduct.value);
- this.tasks[relatedObject.expressID]["Outputs"].push(relatingProduct.expressID);
- }
- }
- }
- async loadTaskNesting(modelID) {
- let rels_nests = await this.utils.byType(modelID, "IfcRelNests");
- for (let i = 0; i < rels_nests.length; i++) {
- let relNests = rels_nests[i];
- let relating_object = await this.utils.byId(modelID, relNests.RelatingObject.value);
- if (this.utils.isA(relating_object, "IfcTask")) {
- let relatedObjects = relNests.RelatedObjects;
- for (var object_index = 0; object_index < relatedObjects.length; object_index++) {
- this.tasks[relating_object.expressID]["IsNestedBy"].push(relatedObjects[object_index].value);
- this.tasks[relatedObjects[object_index].value]["Nests"].push(relating_object.expressID);
- }
- }
- }
- }
- async loadTaskOperations(modelID) {
- let relsAssignsToProcess = await this.utils.byType(modelID, "IfcRelAssignsToProcess");
- for (let i = 0; i < relsAssignsToProcess.length; i++) {
- let relAssignToProcess = relsAssignsToProcess[i];
- let relatingProcess = await this.utils.byId(modelID, relAssignToProcess.RelatingProcess.value);
- if (this.utils.isA(relatingProcess, "IfcTask")) {
- let relatedObjects = relAssignToProcess.RelatedObjects;
- for (var object_index = 0; object_index < relatedObjects.length; object_index++) {
- this.tasks[relatingProcess.expressID]["OperatesOn"].push(relatedObjects[object_index].value);
- }
- }
- }
- }
- async loadAssignementsWorkCalendar(modelID) {
- let relsAssignsToControl = await this.utils.byType(modelID, "IfcRelAssignsToControl");
- for (let i = 0; i < relsAssignsToControl.length; i++) {
- let relAssignsToControl = relsAssignsToControl[i];
- let relatingControl = await this.utils.byId(modelID, relAssignsToControl.RelatingControl.value);
- if (this.utils.isA(relatingControl, "IfcWorkCalendar")) {
- let relatedObjects = relAssignsToControl.RelatedObjects;
- for (var object_index = 0; object_index < relatedObjects.length; object_index++) {
- this.tasks[relatedObjects[object_index].value]["HasAssignmentsWorkCalendars"].push(relatingControl.expressID);
- }
- }
- }
- }
- async loadWorkCalendars(modelID) {
- let workCalendars = await this.utils.byType(modelID, "IfcWorkCalendar");
- for (let i = 0; i < workCalendars.length; i++) {
- let workCalendar = workCalendars[i];
- let workCalenderData = {
- "Id": workCalendar.expressID,
- "Name": ((workCalendar.Name) ? workCalendar.Name.value : ""),
- "Description": ((workCalendar.Description) ? workCalendar.Description.value : ""),
- "WorkingTimes": ((workCalendar.WorkingTimes) ? workCalendar.WorkingTimes : []),
- "ExceptionTimes": ((workCalendar.ExceptionTimes) ? workCalendar.ExceptionTimes : []),
- };
- this.workCalendars[workCalendar.expressID] = workCalenderData;
- }
- }
- async loadWorkTimes(modelID) {
- let workTimes = await this.utils.byType(modelID, "IfcWorkTime");
- for (let i = 0; i < workTimes.length; i++) {
- let workTime = workTimes[i];
- let workTimeData = {
- "Name": ((workTime.Name) ? workTime.Name.value : ""),
- "RecurrencePattern": ((workTime.RecurrencePattern) ? await this.utils.byId(modelID, workTime.RecurrencePattern.value) : ""),
- "Start": ((workTime.Start) ? new Date(workTime.Start.value) : ""),
- "Finish": ((workTime.Finish) ? new Date(workTime.Finish.value) : ""),
- };
- this.workTimes[workTime.expressID] = workTimeData;
- }
- }
- async loadTimePeriods(modelID) {
- let timePeriods = await this.utils.byType(modelID, "IfcTimePeriod");
- for (let i = 0; i < timePeriods.length; i++) {
- let timePeriod = timePeriods[i];
- let workTimeData = {
- "StartTime": ((timePeriod.StartTime) ? new Date(timePeriod.StartTime.value) : ""),
- "EndTime": ((timePeriod.EndTime) ? new Date(timePeriod.EndTime.value) : ""),
- };
- this.timePeriods[timePeriod.expressID] = workTimeData;
- }
- }
- }
- class IFCManager {
- constructor() {
- this.state = {
- models: [],
- api: new WebIFC.IfcAPI(),
- useJSON: false,
- worker: {
- active: false,
- path: ''
- }
- };
- this.BVH = new BvhManager();
- this.parser = new IFCParser(this.state, this.BVH);
- this.subsets = new SubsetManager(this.state, this.BVH);
- this.utils = new IFCUtils(this.state);
- this.sequenceData = new Data(this.state);
- this.properties = new PropertyManager(this.state);
- this.types = new TypeManager(this.state);
- this.useFragments = false;
- this.cleaner = new MemoryCleaner(this.state);
- }
- get ifcAPI() {
- return this.state.api;
- }
- async parse(buffer) {
- var _a;
- let model = await this.parser.parse(buffer, (_a = this.state.coordinationMatrix) === null || _a === void 0 ? void 0 : _a.toArray());
- model.setIFCManager(this);
- try {
- await this.types.getAllTypes(this.worker);
- } catch (e) {
- console.log("Could not get all types of model.");
- }
- return model;
- }
- async setWasmPath(path) {
- this.state.api.SetWasmPath(path);
- this.state.wasmPath = path;
- }
- setupThreeMeshBVH(computeBoundsTree, disposeBoundsTree, acceleratedRaycast) {
- this.BVH.initializeMeshBVH(computeBoundsTree, disposeBoundsTree, acceleratedRaycast);
- }
- setOnProgress(onProgress) {
- this.state.onProgress = onProgress;
- }
- setupCoordinationMatrix(matrix) {
- this.state.coordinationMatrix = matrix;
- }
- clearCoordinationMatrix() {
- delete this.state.coordinationMatrix;
- }
- async applyWebIfcConfig(settings) {
- this.state.webIfcSettings = settings;
- if (this.state.worker.active && this.worker) {
- await this.worker.workerState.updateStateWebIfcSettings();
- }
- }
- async useWebWorkers(active, path) {
- if (this.state.worker.active === active)
- return;
- this.state.api = null;
- if (active) {
- if (!path)
- throw new Error('You must provide a path to the web worker.');
- this.state.worker.active = active;
- this.state.worker.path = path;
- await this.initializeWorkers();
- const wasm = this.state.wasmPath;
- if (wasm)
- await this.setWasmPath(wasm);
- } else {
- this.state.api = new WebIFC.IfcAPI();
- }
- }
- async useJSONData(useJSON = true) {
- var _a;
- this.state.useJSON = useJSON;
- if (useJSON) {
- await ((_a = this.worker) === null || _a === void 0 ? void 0 : _a.workerState.updateStateUseJson());
- }
- }
- async addModelJSONData(modelID, data) {
- var _a;
- const model = this.state.models[modelID];
- if (!model)
- throw new Error('The specified model for the JSON data does not exist');
- if (this.state.worker.active) {
- await ((_a = this.worker) === null || _a === void 0 ? void 0 : _a.workerState.updateModelStateJsonData(modelID, data));
- } else {
- model.jsonData = data;
- }
- }
- async loadJsonDataFromWorker(modelID, path) {
- var _a;
- if (this.state.worker.active) {
- await ((_a = this.worker) === null || _a === void 0 ? void 0 : _a.workerState.loadJsonDataFromWorker(modelID, path));
- }
- }
- close(modelID, scene) {
- try {
- this.state.api.CloseModel(modelID);
- const mesh = this.state.models[modelID].mesh;
- const {geometry, material} = mesh;
- if (scene)
- scene.remove(mesh);
- geometry === null || geometry === void 0 ? void 0 : geometry.dispose();
- Array.isArray(material) ? material.forEach(m => m.dispose()) : material === null || material === void 0 ? void 0 : material.dispose();
- delete this.state.models[modelID];
- } catch (e) {
- console.warn(`Close IFCModel ${modelID} failed`);
- }
- }
- getExpressId(geometry, faceIndex) {
- return this.properties.getExpressId(geometry, faceIndex);
- }
- getAllItemsOfType(modelID, type, verbose) {
- return this.properties.getAllItemsOfType(modelID, type, verbose);
- }
- getItemProperties(modelID, id, recursive = false) {
- return this.properties.getItemProperties(modelID, id, recursive);
- }
- getPropertySets(modelID, id, recursive = false) {
- return this.properties.getPropertySets(modelID, id, recursive);
- }
- getTypeProperties(modelID, id, recursive = false) {
- return this.properties.getTypeProperties(modelID, id, recursive);
- }
- getMaterialsProperties(modelID, id, recursive = false) {
- return this.properties.getMaterialsProperties(modelID, id, recursive);
- }
- getIfcType(modelID, id) {
- const typeID = this.state.models[modelID].types[id];
- return this.state.api.GetNameFromTypeCode(typeID);
- }
- getSpatialStructure(modelID, includeProperties) {
- return this.properties.getSpatialStructure(modelID, includeProperties);
- }
- getSubset(modelID, material, customId) {
- return this.subsets.getSubset(modelID, material, customId);
- }
- removeSubset(modelID, material, customID) {
- this.subsets.removeSubset(modelID, material, customID);
- }
- createSubset(config) {
- return this.subsets.createSubset(config);
- }
- removeFromSubset(modelID, ids, customID, material) {
- return this.subsets.removeFromSubset(modelID, ids, customID, material);
- }
- clearSubset(modelID, customID, material) {
- return this.subsets.clearSubset(modelID, customID, material);
- }
- async isA(entity, entity_class) {
- return this.utils.isA(entity, entity_class);
- }
- async getSequenceData(modelID) {
- await this.sequenceData.load(modelID);
- return this.sequenceData;
- }
- async byType(modelID, entityClass) {
- return this.utils.byType(modelID, entityClass);
- }
- async byId(modelID, id) {
- return this.utils.byId(modelID, id);
- }
- async idsByType(modelID, entityClass) {
- return this.utils.idsByType(modelID, entityClass);
- }
- async dispose() {
- IFCModel.dispose();
- await this.cleaner.dispose();
- this.subsets.dispose();
- if (this.worker && this.state.worker.active)
- await this.worker.terminate();
- this.state = null;
- }
- async disposeMemory() {
- var _a;
- if (this.state.worker.active) {
- await ((_a = this.worker) === null || _a === void 0 ? void 0 : _a.Close());
- } else {
- this.state.api.Close();
- this.state.api = null;
- this.state.api = new WebIFC.IfcAPI();
- }
- }
- getAndClearErrors(modelID) {
- return this.parser.getAndClearErrors(modelID);
- }
- async initializeWorkers() {
- this.worker = new IFCWorkerHandler(this.state, this.BVH);
- this.state.api = this.worker.webIfc;
- this.properties = this.worker.properties;
- await this.worker.parser.setupOptionalCategories(this.parser.optionalCategories);
- this.parser = this.worker.parser;
- await this.worker.workerState.updateStateUseJson();
- await this.worker.workerState.updateStateWebIfcSettings();
- }
- }
- class IFCLoader extends Loader {
- constructor(manager) {
- super(manager);
- this.ifcManager = new IFCManager();
- }
- load(url, onLoad, onProgress, onError) {
- const scope = this;
- const loader = new FileLoader(scope.manager);
- this.onProgress = onProgress;
- loader.setPath(scope.path);
- loader.setResponseType('arraybuffer');
- loader.setRequestHeader(scope.requestHeader);
- loader.setWithCredentials(scope.withCredentials);
- loader.load(url, async function (buffer) {
- try {
- if (typeof buffer == 'string') {
- throw new Error('IFC files must be given as a buffer!');
- }
- onLoad(await scope.parse(buffer));
- } catch (e) {
- if (onError) {
- onError(e);
- } else {
- console.error(e);
- }
- scope.manager.itemError(url);
- }
- }, onProgress, onError);
- }
- parse(buffer) {
- return this.ifcManager.parse(buffer);
- }
- }
- export { IFCLoader };
- //# sourceMappingURL=IFCLoader.js.map
|