187 lines
5.8 KiB
JavaScript
187 lines
5.8 KiB
JavaScript
import { IsObjectEmpty } from '../core/core.js';
|
|
import { Coord3D } from '../geometry/coord3d.js';
|
|
import { Direction } from '../geometry/geometry.js';
|
|
import { ArrayBufferToUtf8String } from '../io/bufferutils.js';
|
|
import { Node } from '../model/node.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 { ColorToMaterialConverter } from './importerutils.js';
|
|
import { Property, PropertyGroup, PropertyType } from '../model/property.js';
|
|
import { Unit } from '../model/unit.js';
|
|
import { Loc } from '../core/localization.js';
|
|
|
|
export class ImporterBim extends ImporterBase
|
|
{
|
|
constructor ()
|
|
{
|
|
super ();
|
|
}
|
|
|
|
CanImportExtension (extension)
|
|
{
|
|
return extension === 'bim';
|
|
}
|
|
|
|
GetUpDirection ()
|
|
{
|
|
return Direction.Z;
|
|
}
|
|
|
|
ClearContent ()
|
|
{
|
|
this.meshIdToMesh = null;
|
|
this.colorToMaterial = null;
|
|
}
|
|
|
|
ResetContent ()
|
|
{
|
|
this.meshIdToMesh = new Map ();
|
|
this.colorToMaterial = new ColorToMaterialConverter (this.model);
|
|
}
|
|
|
|
ImportContent (fileContent, onFinish)
|
|
{
|
|
this.model.SetUnit (Unit.Meter);
|
|
|
|
let textContent = ArrayBufferToUtf8String (fileContent);
|
|
let bimJson = null;
|
|
try {
|
|
bimJson = JSON.parse (textContent);
|
|
} catch (err) {
|
|
this.SetError (Loc ('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 defaultMaterialIndex = null;
|
|
if (bimElement.color)
|
|
{
|
|
defaultMaterialIndex = this.colorToMaterial.GetMaterialIndex (
|
|
bimElement.color.r,
|
|
bimElement.color.g,
|
|
bimElement.color.b,
|
|
bimElement.color.a
|
|
);
|
|
}
|
|
|
|
let rootNode = this.model.GetRootNode ();
|
|
|
|
let bimMesh = this.meshIdToMesh.get (bimElement.mesh_id);
|
|
let mesh = this.ImportMesh (bimMesh, (triangleIndex) => {
|
|
if (bimElement.face_colors) {
|
|
let faceMaterialIndex = this.colorToMaterial.GetMaterialIndex (
|
|
bimElement.face_colors[triangleIndex * 4 + 0],
|
|
bimElement.face_colors[triangleIndex * 4 + 1],
|
|
bimElement.face_colors[triangleIndex * 4 + 2],
|
|
bimElement.face_colors[triangleIndex * 4 + 3]
|
|
);
|
|
return faceMaterialIndex;
|
|
} else {
|
|
return defaultMaterialIndex;
|
|
}
|
|
});
|
|
let meshIndex = this.model.AddMesh (mesh);
|
|
|
|
let elementNode = new Node ();
|
|
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, getMaterialIndex)
|
|
{
|
|
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]
|
|
);
|
|
triangle.SetMaterial (getMaterialIndex (i / 3));
|
|
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 || IsObjectEmpty (source.info)) {
|
|
return;
|
|
}
|
|
|
|
let info = source.info;
|
|
let propertyGroup = new PropertyGroup (Loc ('Info'));
|
|
AddProperty (propertyGroup, Loc ('Guid'), source.guid);
|
|
AddProperty (propertyGroup, Loc ('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);
|
|
}
|
|
}
|