From dd8360fd92cdb129116df6b690048b53219751ad Mon Sep 17 00:00:00 2001 From: kovacsv Date: Sat, 19 Feb 2022 16:45:31 +0100 Subject: [PATCH] Add bim importer #219 --- source/engine/import/importer.js | 2 + source/engine/import/importerbim.js | 185 ++++++++++++++++++++++++++++ source/engine/main.js | 2 + 3 files changed, 189 insertions(+) create mode 100644 source/engine/import/importerbim.js diff --git a/source/engine/import/importer.js b/source/engine/import/importer.js index 6d47430..079c8fd 100644 --- a/source/engine/import/importer.js +++ b/source/engine/import/importer.js @@ -14,6 +14,7 @@ import { ImporterOff } from './importeroff.js'; import { ImporterPly } from './importerply.js'; import { ImporterStp } from './importerstp.js'; import { ImporterStl } from './importerstl.js'; +import { ImporterBim } from './importerbim.js'; import { ImporterThree3mf, ImporterThreeDae, ImporterThreeFbx, ImporterThreeWrl } from './importerthree.js'; export class ImportSettings @@ -105,6 +106,7 @@ export class Importer new Importer3ds (), new ImporterGltf (), new ImporterO3dv (), + new ImporterBim (), new Importer3dm (), new ImporterIfc (), new ImporterStp (), diff --git a/source/engine/import/importerbim.js b/source/engine/import/importerbim.js new file mode 100644 index 0000000..ac597aa --- /dev/null +++ b/source/engine/import/importerbim.js @@ -0,0 +1,185 @@ +import { Coord3D } from '../geometry/coord3d.js'; +import { Direction } from '../geometry/geometry.js'; +import { ArrayBufferToUtf8String } from '../io/bufferutils.js'; +import { Node, NodeType } from '../model/node.js'; +import { PhongMaterial } from '../model/material.js'; +import { Color, IntegerToHexString } from '../model/color.js'; +import { Mesh } from '../model/mesh.js'; +import { Triangle } from '../model/triangle.js'; +import { ImporterBase } from './importerbase.js'; +import { Quaternion } from '../geometry/quaternion.js'; +import { Matrix } from '../geometry/matrix.js'; +import { Transformation } from '../geometry/transformation.js'; +import { UpdateMaterialTransparency } from './importerutils.js'; +import { Property, PropertyGroup, PropertyType } from '../model/property.js'; + +export class ImporterBim extends ImporterBase +{ + constructor () + { + super (); + } + + CanImportExtension (extension) + { + return extension === 'bim'; + } + + GetUpDirection () + { + return Direction.Z; + } + + ClearContent () + { + this.meshIdToMesh = null; + this.colorToMaterialIndex = null; + } + + ResetContent () + { + this.meshIdToMesh = new Map (); + this.colorToMaterialIndex = new Map (); + } + + ImportContent (fileContent, onFinish) + { + let textContent = ArrayBufferToUtf8String (fileContent); + let bimJson = null; + try { + bimJson = JSON.parse (textContent); + } catch (err) { + this.SetError ('Failed to parse bim file.'); + onFinish (); + return; + } + + for (let bimMesh of bimJson.meshes) { + this.meshIdToMesh.set (bimMesh.mesh_id, bimMesh); + } + + this.ImportProperties (bimJson, this.model); + for (let bimElement of bimJson.elements) { + let mesh = this.ImportElement (bimElement); + mesh.SetName (bimElement.type); + this.ImportProperties (bimElement, mesh); + } + + onFinish (); + } + + ImportElement (bimElement) + { + let materialIndex = null; + if (bimElement.color) { + let colorKey = + IntegerToHexString (bimElement.color.r) + + IntegerToHexString (bimElement.color.g) + + IntegerToHexString (bimElement.color.b) + + IntegerToHexString (bimElement.color.a); + if (this.colorToMaterialIndex.has (colorKey)) { + materialIndex = this.colorToMaterialIndex.get (colorKey); + } else { + let material = new PhongMaterial (); + material.name = colorKey; + material.color = new Color (bimElement.color.r, bimElement.color.g, bimElement.color.b); + if (bimElement.color.a < 255) { + material.opacity = bimElement.color.a / 255.0; + UpdateMaterialTransparency (material); + } + materialIndex = this.model.AddMaterial (material); + this.colorToMaterialIndex.set (colorKey, materialIndex); + } + } + + let rootNode = this.model.GetRootNode (); + + let bimMesh = this.meshIdToMesh.get (bimElement.mesh_id); + let mesh = this.ImportMesh (bimMesh, materialIndex); + let meshIndex = this.model.AddMesh (mesh); + + let elementNode = new Node (); + elementNode.SetType (NodeType.MeshNode); + elementNode.AddMeshIndex (meshIndex); + + let translation = new Coord3D (0.0, 0.0, 0.0); + if (bimElement.vector) { + translation = new Coord3D ( + bimElement.vector.x, + bimElement.vector.y, + bimElement.vector.z + ); + } + let rotation = new Quaternion (0.0, 0.0, 0.0, 1.0); + if (bimElement.rotation) { + rotation = new Quaternion ( + bimElement.rotation.qx, + bimElement.rotation.qy, + bimElement.rotation.qz, + bimElement.rotation.qw + ); + } + let scale = new Coord3D (1.0, 1.0, 1.0); + let matrix = new Matrix ().ComposeTRS (translation, rotation, scale); + elementNode.SetTransformation (new Transformation (matrix)); + + rootNode.AddChildNode (elementNode); + return mesh; + } + + ImportMesh (bimMesh, materialIndex) + { + let mesh = new Mesh (); + + for (let i = 0; i < bimMesh.coordinates.length; i += 3) { + mesh.AddVertex (new Coord3D ( + bimMesh.coordinates[i + 0], + bimMesh.coordinates[i + 1], + bimMesh.coordinates[i + 2] + )); + } + + for (let i = 0; i < bimMesh.indices.length; i += 3) { + let triangle = new Triangle ( + bimMesh.indices[i + 0], + bimMesh.indices[i + 1], + bimMesh.indices[i + 2] + ); + if (materialIndex !== null) { + triangle.SetMaterial (materialIndex); + } + mesh.AddTriangle (triangle); + } + + return mesh; + } + + ImportProperties (source, target) + { + function AddProperty (group, name, value) + { + if (value === undefined || value === null) { + return; + } + let property = new Property (PropertyType.Text, name, value); + group.AddProperty (property); + } + + if (!source.info) { + return; + } + + let info = source.info; + let propertyGroup = new PropertyGroup ('Info'); + AddProperty (propertyGroup, 'Guid', source.guid); + AddProperty (propertyGroup, 'Type', source.type); + for (let propertyName in info) { + if (Object.prototype.hasOwnProperty.call (info, propertyName)) { + if (typeof info[propertyName] === 'string') { + AddProperty (propertyGroup, propertyName, info[propertyName]); + } + } + } + target.AddPropertyGroup (propertyGroup); + } +} diff --git a/source/engine/main.js b/source/engine/main.js index 4a39e25..4f29d50 100644 --- a/source/engine/main.js +++ b/source/engine/main.js @@ -24,6 +24,7 @@ import { ImportSettings, ImportError, ImportResult, ImporterFileAccessor, Import import { Importer3dm } from './import/importer3dm.js'; import { Importer3ds } from './import/importer3ds.js'; import { ImporterBase } from './import/importerbase.js'; +import { ImporterBim } from './import/importerbim.js'; import { ImporterGltf } from './import/importergltf.js'; import { ImporterIfc } from './import/importerifc.js'; import { ImporterO3dv } from './import/importero3dv.js'; @@ -147,6 +148,7 @@ export { Importer3dm, Importer3ds, ImporterBase, + ImporterBim, ImporterGltf, ImporterIfc, ImporterO3dv,