(() => {\r\n\t\t\treturn BUI.html`\r\n\t\t\t\r\n\t\t\t`;\r\n\t\t});\r\n\r\n\t\t//document.body.append(panel);\r\n\t\tconst container:HTMLElement = document.getElementById('container')!; // Get the element where the scene will be displayed\r\n\t\t//container.append(panel);\r\n\t\tcontainer.prepend(panel);\r\n\r\n\t\t/*\r\n\t\tOBCA.IfcStreamer;\r\n\t\tOBCB.Manager.\r\n\t\tOBCB.Toolbar;\r\n\t\tOBCB.ToolbarGroup;\r\n\t\tOBCB.ToolbarSection;\r\n\t\t*/\r\n\t}\r\n\r\n\r\n\tsetupLoaderUI_old_OpenBim2024_apr_style(comp: OBC.Components | undefined) {\r\n\t\t/* \r\n\t\tThis only worked this way until april 2024..\r\n\t\ttoolbar = new OBCU.Toolbar(comp); //const // ui/ToolbarComponent\r\n\t\tcomp.ui.addToolbar(toolbar);\r\n\t\t\r\n\t\tlet fragmentIfcLoader = this.OB.loader;\r\n\t\tconst loadIfc_button = fragmentIfcLoader!.uiElement.get(\"main\"); // (the 'primary' action of a tool is presumably named main)\r\n\t\ttoolbar.addChild(loadIfc_button); \r\n\t\tconsole.log('added fragmentIfcLoader-button to mainToolbar, tb is:', toolbar);\r\n\t\t\r\n\t\tconst mgr = new OBC.FragmentManager(comp);\r\n\t\ttoolbar.addChild(mgr.uiElement.get(\"main\"));\r\n\t\t*/\r\n\t}\r\n}\r\n\r\n/*\r\nHmm, der er noget der hedder openbim-components, \r\nMit mini-project får bl.a. OBC.Components,\r\nfra node_module openbim-components,\r\nsom f.eks. har dette 2024-release:\r\n'1.5.1': '2024-05-01T20:45:18.688Z'\r\n\r\nMen collab bruger slet ikke noget,\r\nder hedder openbim-components?!\r\n\r\nVi bruger istedet denne:\r\n\"@thatopen/components\": \"2.1.1\",\r\nsom er\r\n '2.1.1': '2024-07-10T19:53:06.909Z',\r\n\r\n Det ser ud til, at tingene PLEJEDE\r\n at hedde openbim-components \r\n frem til 2024-april,\r\n og at de saa hedder \r\n \"@thatopen/components\"\r\n fra 2024-maj og frem.\r\n\r\n*/\r\n","//import * as BF from \"bim-fragment\";\r\n//import {Fragment, FragmentsGroup} from \"@thatopen/fragments\";\r\nimport * as BF from \"@thatopen/fragments\";\r\n\r\n\r\nexport class GroupAndIdMappings {\r\n group: BF.FragmentsGroup;\r\n globalIdMapping: Map;\r\n expressIdMapping: Map;\r\n\r\n constructor(group: BF.FragmentsGroup,\r\n globalIdMapping: Map,\r\n expressIdMapping: Map) {\r\n this.group = group;\r\n this.globalIdMapping = globalIdMapping;\r\n this.expressIdMapping = expressIdMapping;\r\n }\r\n}\r\n\r\nexport class GroupManager {\r\n\r\n public results: Map;\r\n\r\n constructor() {\r\n this.results = new Map();\r\n }\r\n\r\n public addResult(group: GroupAndIdMappings) {\r\n this.results.set(group.group.uuid, group);\r\n }\r\n\r\n public getGlobalIdFromExpressID(expressId: number, groupId:string = \"\") : string | null { \r\n\r\n if (groupId != \"\") {\r\n let group = this.results.get(groupId);\r\n if (group) {\r\n let match = group.expressIdMapping.get(expressId);\r\n if (match) {\r\n return match;\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n for (const group of this.results.values()) {\r\n let match = group.expressIdMapping.get(expressId);\r\n if (match) {\r\n return match;\r\n };\r\n } \r\n return null;\r\n }\r\n\r\n public getExpressIDFromGlobalId(globalId: string, groupId: string = \"\") : number | null {\r\n\r\n if (groupId != \"\") {\r\n let group = this.results.get(groupId);\r\n if (group) {\r\n let match = group.globalIdMapping.get(globalId);\r\n if (match) {\r\n return match;\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n for (const group of this.results.values()) {\r\n let match = group.globalIdMapping.get(globalId);\r\n if (match) {\r\n return match;\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n}\r\n","import * as THREE from \"three\";\r\nimport * as OBC from \"@thatopen/components\";\r\nimport * as BF from \"@thatopen/fragments\";\r\n\r\nimport { IfcDataWrapper, IfcGeometryWrapper, IfcMeshWrapper, Color, GeometryRootData } from \"./IfcDataWrapper\"; //GroupAndIdMappings\r\nimport {GroupAndIdMappings} from \"./GroupResultManager\"; //C:\\dev\\aoc\\AO.Client\\ClientApp\\src\\app\\project\\ifc-fun\\EgMessagePackLoader\\\r\n\r\nimport * as fflate from \"fflate\";\r\nimport * as mp from \"@msgpack/msgpack\"\r\n\r\n/**\r\n * A tool to load Fragments from various formats\r\n */\r\n\r\nexport class EgFragmentLoader extends OBC.Component\r\n\timplements OBC.Disposable /*, OBC.Updateable */ {\r\n\tstatic readonly uuid = \"EFDECA14-5498-4BE1-9F70-1ED1B93512F2\";\r\n\r\n\t//readonly onAfterUpdate = new OBC.Event();\r\n\r\n\t//readonly onBeforeUpdate = new OBC.Event();\r\n\treadonly onDisposed = new OBC.Event();\r\n\r\n\tenabled = true;\r\n\r\n\tprivate _group!: BF.FragmentsGroup;\r\n\r\n\tprivate _transparentMaterial: THREE.Material;\r\n\r\n\tconstructor(components: OBC.Components) {\r\n\t\tsuper(components);\r\n\t\tcomponents.add(EgFragmentLoader.uuid, this);\r\n\r\n\t\tthis._transparentMaterial = new THREE.MeshStandardMaterial({ transparent: true, opacity: 0.4 });\r\n\t\tthis._transparentMaterial.depthWrite = false;\r\n\t\tthis._transparentMaterial.polygonOffset = true;\r\n\t\tthis._transparentMaterial.polygonOffsetFactor = 5;\r\n\t\tthis._transparentMaterial.polygonOffsetUnits = 1;\r\n\t}\r\n\r\n\tpublic get() {\r\n\t\treturn this._group;\r\n\t}\r\n\r\n\tpublic async loadFromJson(jsonData: string, id: string): Promise {\r\n\t\tlet data = JSON.parse(jsonData);\r\n\t\tconst result = await this.loadAllGeometry(data, id);\r\n\t\tthis._group = result.group;\r\n\t\treturn result;\r\n\t}\r\n\r\n\tpublic async loadFromMessagePackZip(zipData: Uint8Array, id: string) : Promise {\r\n\t\tconsole.log(`Unzipping...`);\r\n\t\tlet start = this.ms();\r\n\t\tconst unzipped: fflate.Unzipped = fflate.unzipSync(zipData);\r\n\t\tzipData = new Uint8Array();\r\n\t\tlet rawMsgPack = Object.entries(unzipped)[0][1]; //unzipped is an array of entries where 0 = filename and 1 = contents;\r\n\t\tlet time = this.ms() - start;\r\n\t\tconsole.log(`Unzip took ${time} ms`);\r\n\r\n\t\tconsole.log(`Deserializing message pack...`);\r\n\t\tstart = this.ms();\r\n\t\tlet data = mp.decode(rawMsgPack);\r\n\r\n\t\ttime = this.ms() - start;\r\n\t\tconsole.log(`Deserialize took ${time} ms`);\r\n\r\n\t\tconst result = await this.loadAllGeometry(data, id);\r\n\t\tthis._group = result.group;\r\n\t\treturn result;\r\n\t}\r\n\r\n\tpublic async loadAllGeometry(data: GeometryRootData, id: string) : Promise {\r\n\r\n\t\tlet uniqueMaterials = new Map();\r\n\r\n\t\tlet start = this.ms();\r\n\t\tconsole.log(`Loading geometry...`);\r\n\r\n\t\tlet group = new BF.FragmentsGroup();\r\n\t\tgroup.uuid = id;\r\n\r\n\t\tlet geomMap = new Map();\r\n\r\n\t\tlet props : any = {};\r\n\r\n\t\t//Flatten geometry structure for easier access to meshes\r\n\t\tfor (const item of data.items) {\r\n\t\t\tfor (const mesh of item.meshes) {\r\n\t\t\t\tconst color = new THREE.Color().setRGB(mesh.color.x, mesh.color.y, mesh.color.z, \"srgb\");\r\n\t\t\t\tlet colID = color.getHexString();\r\n\r\n\t\t\t\t//let combinedId = `${item.expressID}-${mesh.geometryExpressID}`;\r\n\t\t\t\tlet transparentId = mesh.color.w != 1 ? 1 : 0;\r\n\t\t\t\tlet combinedId = `${mesh.geometryExpressID}-${colID}-${transparentId}`;\r\n\r\n\t\t\t\tif (!geomMap.has(combinedId))\r\n\t\t\t\t\tgeomMap.set(combinedId, []);\r\n\r\n\t\t\t\tlet meshes = geomMap.get(combinedId);\r\n\t\t\t\tif (meshes)\r\n\t\t\t\t\tmeshes.push(new FlatMesh(combinedId, mesh, item, color, mesh.color.w));\r\n\t\t\t}\r\n\r\n\t\t\tprops[item.expressID] = {\r\n\t\t\t\tglobalId: item.globalID,\r\n\t\t\t\tifcType: item.ifcType\r\n\t\t\t};\r\n\r\n\t\t\tgroup.data.set(item.expressID, [[], [0, 0]]);\r\n\t\t}\r\n\r\n\t\tgroup.setLocalProperties(props);\r\n\r\n\t\tlet result = new GroupAndIdMappings(group, new Map(), new Map());\r\n\r\n\t\tlet ix = 0;\r\n\t\tfor (const ent of geomMap.entries()) {\r\n\t\t\tlet fragment : BF.Fragment|null = null; //Make one fragment per unique geometry/color\r\n\t\t\tgroup.keyFragments.set(ix, ent[0].toString());\r\n\r\n\t\t\tlet meshCount = ent[1].length;\r\n\r\n\t\t\tfor (const flatmesh of ent[1]) {\r\n\t\t\t\tlet item = flatmesh.item;\r\n\t\t\t\tlet mesh = flatmesh.mesh;\r\n\r\n\t\t\t\tlet expressId = item.expressID.toString();\r\n\t\t\t\tlet geomExpressId = flatmesh.combinedId.toString();\r\n\r\n\t\t\t\tlet groupData = group.data.get(item.expressID);\r\n\t\t\t\tif (groupData)\r\n\t\t\t\t\tgroupData[0].push(ix);\r\n\r\n\t\t\t\tif (fragment == null) {\r\n\t\t\t\t\tlet geometry = data.geometries.find(i => i.id == mesh.geometryID);\r\n\t\t\t\t\tif (!geometry) {\r\n\t\t\t\t\t\tconsole.error(\"Cannot find geometry with id: \" + mesh.geometryID);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tlet mat = this.getMeshMaterial(flatmesh, uniqueMaterials);\r\n\t\t\t\t\tlet bufGeom = this.ifcGeometryWrapperToBuffer(mesh.color, geometry);\r\n\r\n\t\t\t\t\tfragment = new BF.Fragment(bufGeom, mat, meshCount);\r\n\t\t\t\t\tfragment.id = geomExpressId;\r\n\t\t\t\t\tfragment.mesh.userData[\"ifcType\"] = item.ifcType;\r\n\t\t\t\t\tfragment.mesh.userData[\"expressID\"] = [];\r\n\t\t\t\t\t\r\n\t\t\t\t\tgroup.add(fragment.mesh);\r\n\t\t\t\t\tgroup.items.push(fragment);\r\n\t\t\t\t\tfragment.group = group;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfragment.mesh.userData[\"expressID\"].push(item.expressID);\r\n\r\n\t\t\t\t//const color = new THREE.Color().setRGB(mesh.color.x, mesh.color.y, mesh.color.z, \"srgb\");\r\n\t\t\t\tlet matrix = this.getMeshMatrix(mesh.flatTransformation);\r\n\r\n\t\t\t\tlet white = new THREE.Color(1, 1, 1);\r\n\t\t\t\tfragment.add(\r\n\t\t\t\t\t[\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\ttransforms: [matrix],\r\n\t\t\t\t\t\t\tcolors: [flatmesh.color],\r\n\t\t\t\t\t\t\t//colors: [white],\r\n\t\t\t\t\t\t\tid: item.expressID\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t]\r\n\t\t\t\t);\r\n\r\n\t\t\t\tresult.expressIdMapping.set(item.expressID, item.globalID);\r\n\t\t\t\tresult.globalIdMapping.set(item.globalID, item.expressID);\r\n\t\t\t}\r\n\r\n\t\t\tif (fragment && fragment.mesh.userData[\"ifcType\"].toUpperCase() == \"IFCSPACE\")\r\n\t\t\t\tfragment.setVisibility(false, fragment.ids);\r\n\r\n\t\t\t++ix;\r\n\t\t}\r\n\r\n\t\tlet time = this.ms() - start;\r\n\t\tconsole.log(`Loading geometry took ${time} ms`);\r\n\r\n\t\treturn result;\r\n\t}\r\n\r\n\tprivate getMeshMaterial(flatmesh: FlatMesh, uniqueMaterials: Map) : THREE.Material {\r\n\t\tlet idParts = flatmesh.combinedId.split(\"-\");\r\n\t\tlet colID = idParts[1] + idParts[2];\r\n\r\n\t\tif (uniqueMaterials.has(colID))\r\n\t\t{\r\n\t\t\tlet mat = uniqueMaterials.get(colID);\r\n\t\t\tif (mat)\r\n\t\t\t\treturn mat;\r\n\t\t}\r\n\r\n\t\tlet white = new THREE.Color(1, 1, 1);\r\n\t\tlet col = flatmesh.color;\r\n\t\tcol = white;\r\n\r\n\t\tlet material: THREE.Material;\r\n\t\tconst transparent = flatmesh.opacity !== 1;\r\n\t\tif (transparent) {\r\n\t\t\t//material = new THREE.MeshBasicMaterial({ color: white, transparent: true, opacity: flatmesh.opacity });\r\n\t\t\tmaterial = new THREE.MeshStandardMaterial({ color: col, transparent: true, opacity: flatmesh.opacity });\r\n\r\n\t\t\t//material = new THREE.MeshStandardMaterial({ color: col, transparent: false, opacity: color.w });\r\n\t\t\tmaterial.vertexColors = false;\r\n\t\t\t//material.depthWrite = false;\r\n\t\t\t//material.polygonOffset = true;\r\n\t\t\t//material.polygonOffsetFactor = 5;\r\n\t\t\t//material.polygonOffsetUnits = 1;\r\n\t\t}\r\n\t\telse {\r\n\t\t\t//material = new THREE.MeshBasicMaterial({ color: white, side: THREE.DoubleSide });\r\n\r\n\t\t\tmaterial = new THREE.MeshLambertMaterial({ color: col, side: THREE.DoubleSide, emissiveIntensity: 1.2, flatShading: true, reflectivity: 1.2 });\r\n\t\t\t//material = new THREE.MeshBasicMaterial({ color: col });\r\n\t\t\tmaterial.vertexColors = false;\r\n\t\t}\r\n\r\n\r\n\t\tuniqueMaterials.set(colID, material);\r\n\r\n\t\treturn material;\r\n\t}\r\n\r\n\tprivate getMeshMatrix(matrix: Array) {\r\n\t\tconst mat = new THREE.Matrix4();\r\n\t\tmat.fromArray(matrix);\r\n\t\treturn mat;\r\n\t}\r\n\r\n\tprivate ifcGeometryWrapperToBuffer(color: Color, wrapper: IfcGeometryWrapper) {\r\n\t\tconst geometry = new THREE.BufferGeometry();\r\n\r\n\t\tlet vertexData = wrapper.vertexData;\r\n\r\n\t\tlet posFloats = new Float32Array(vertexData.length / 2);\r\n\t\tlet normFloats = new Float32Array(vertexData.length / 2);\r\n\t\t//let colorFloats = new Float32Array(vertexData.length / 2);\r\n\r\n\t\tfor (let i = 0; i < vertexData.length; i += 6) {\r\n\t\t\tposFloats[i / 2 + 0] = vertexData[i + 0];\r\n\t\t\tposFloats[i / 2 + 1] = vertexData[i + 1];\r\n\t\t\tposFloats[i / 2 + 2] = vertexData[i + 2];\r\n\r\n\t\t\tnormFloats[i / 2 + 0] = vertexData[i + 3];\r\n\t\t\tnormFloats[i / 2 + 1] = vertexData[i + 4];\r\n\t\t\tnormFloats[i / 2 + 2] = vertexData[i + 5];\r\n\r\n\t\t\t//colorFloats[i / 2 + 0] = color.x;\r\n\t\t\t//colorFloats[i / 2 + 1] = color.y;\r\n\t\t\t//colorFloats[i / 2 + 2] = color.z;\r\n\t\t}\r\n\r\n\t\tgeometry.setAttribute(\r\n\t\t\t'position',\r\n\t\t\tnew THREE.BufferAttribute(posFloats, 3));\r\n\t\tgeometry.setAttribute(\r\n\t\t\t'normal',\r\n\t\t\tnew THREE.BufferAttribute(normFloats, 3));\r\n\t\t//geometry.setAttribute(\r\n\t\t// 'color',\r\n\t\t// new THREE.BufferAttribute(colorFloats, 3));\r\n\r\n\t\tgeometry.setIndex(Array.from(this.numToUint32Array(wrapper.indexData)));\r\n\t\treturn geometry;\r\n\t}\r\n\r\n\tnumToUint32Array(num: number[]) {\r\n\t\tlet arr = new Uint32Array(num.length);\r\n\t\tfor (let i = 0; i < num.length; i++)\r\n\t\t\tarr[i] = num[i];\r\n\t\treturn arr;\r\n\t}\r\n\r\n\tnumberOfDigits(x: number) {\r\n\t\treturn Math.max(Math.floor(Math.log10(Math.abs(x))), 0) + 1;\r\n\t}\r\n\r\n\ttoCompositeID(id: number, count: number) {\r\n\t\tconst factor = 0.1 ** this.numberOfDigits(count);\r\n\t\tid += count * factor;\r\n\t\tlet idString = id.toString();\r\n\t\t// add missing zeros\r\n\t\tif (count % 10 === 0) {\r\n\t\t\tfor (let i = 0; i < factor; i++) {\r\n\t\t\t\tidString += \"0\";\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn idString;\r\n\t}\r\n\r\n\tasync dispose() {\r\n\t\tthis.enabled = false;\r\n\t\t// Make sure to clean up the events\r\n\t\t//this.onBeforeUpdate.reset();\r\n\t\t//this.onAfterUpdate.reset();\r\n\r\n\t\tthis.onDisposed?.reset();\r\n\r\n\t\t// Use the disposer tool to easily dispose THREE.js objects\r\n\t\tconst disposer = this.components.get(OBC.Disposer);\r\n\t\tconsole.error(\"Disposing fragment loader...\")\r\n\t\tif (this._group)\r\n\t\t\tdisposer.destroy(this._group);\r\n\t}\r\n\r\n\tms(): number {\r\n\t\tconst d = new Date();\r\n\t\treturn d.getTime();\r\n\t}\r\n\r\n\t//async update() {\r\n\t// this.onBeforeUpdate.trigger();\r\n\t// console.log(\"Updated!\");\r\n\t// this.onAfterUpdate.trigger();\r\n\t//}\r\n}\r\n\r\nclass FlatMesh {\r\n\tmesh: IfcMeshWrapper;\r\n\titem: IfcDataWrapper;\r\n\tcombinedId: string;\r\n\tcolor: THREE.Color;\r\n\topacity: number;\r\n\tconstructor(combinedId: string, mesh: IfcMeshWrapper, item: IfcDataWrapper, color: THREE.Color, opacity: number) {\r\n\t\tthis.combinedId = combinedId;\r\n\t\tthis.mesh = mesh;\r\n\t\tthis.item = item;\r\n\t\tthis.color = color;\r\n\t\tthis.opacity = opacity;\r\n\t}\r\n}\r\n"],"names":["___CSS_LOADER_EXPORT___","push","module","id","IfcClean","OB","attached","params","this","my_ifc_init","console","log","worldStuff","setupLoader","comp","world","get","create","OBC_scene1","scene","container","document","getElementById","renderer","logarithmicDepthBuffer","camera","init","three","background","setup","loader","loadIfc","setupLoaderUI","loadIfc2","fragmentIfcLoader","file","fetch","data","arrayBuffer","buffer","Uint8Array","model","load","name","add","panel","prepend","setupLoaderUI_old_OpenBim2024_apr_style","GroupAndIdMappings","constructor","group","globalIdMapping","expressIdMapping","EgFragmentLoader","components","super","onDisposed","enabled","uuid","_transparentMaterial","transparent","opacity","depthWrite","polygonOffset","polygonOffsetFactor","polygonOffsetUnits","_group","loadFromJson","jsonData","JSON","parse","result","loadAllGeometry","loadFromMessagePackZip","zipData","start","ms","unzipped","rawMsgPack","Object","entries","time","uniqueMaterials","Map","geomMap","props","item","items","mesh","meshes","color","setRGB","x","y","z","colID","getHexString","transparentId","w","combinedId","geometryExpressID","has","set","FlatMesh","expressID","globalId","globalID","ifcType","setLocalProperties","ix","ent","fragment","keyFragments","toString","meshCount","length","flatmesh","geomExpressId","groupData","geometry","geometries","find","i","geometryID","error","mat","getMeshMaterial","bufGeom","ifcGeometryWrapperToBuffer","userData","matrix","getMeshMatrix","flatTransformation","transforms","colors","toUpperCase","setVisibility","ids","idParts","split","material","white","col","vertexColors","side","emissiveIntensity","flatShading","reflectivity","fromArray","wrapper","vertexData","posFloats","Float32Array","normFloats","setAttribute","setIndex","Array","from","numToUint32Array","indexData","num","arr","Uint32Array","numberOfDigits","Math","max","floor","log10","abs","toCompositeID","count","factor","idString","dispose","reset","disposer","destroy","Date","getTime"],"sourceRoot":""}