Reputation: 59
I need to get dimensions from an IFC file using Autodesk Forge so I could caluclate area, mass and other properties of the building (building storey). Is this possible with Autodesk Forge?
Upvotes: 2
Views: 1102
Reputation: 7070
Unfortunately, Forge Viewer will convert any supported geometry representation into the Mesh-based one as I know, so you could not obtain any solid information from Forge Viewer fragments.
If your raw source model is from any supported BIM software, each element in the IFC file should have properties contained data of the area, mass and building storey(level), and you can read those properties via Viewer APIs:
viewer.search(text, onSuccessCallback, onErrorCallback, attributeNames)
viewer.model.getBulkProperties(dbIds, options, onSuccessCallback, onErrorCallback)
The usage of these APIs in combination:
viewer.search('Steel',
function( dbIds ){
viewer.model.getBulkProperties(dbIds, ['Mass'],
function(elements){
var totalMass = 0;
for(var i=0; i<elements.length; i++){
totalMass += elements[i].properties[0].displayValue;
}
console.log(totalMass);
})
}, null, ['Material'])
However,
you can calculate area, volume, and mass via accessing Forge Viewer fragments' mesh data. Here is a blog showing how to access the mesh, and its key content is shown below. These codes are used to rebuild the relationship of a triangular mesh from flattening arrays:
var fragProxy = viewer.impl.getFragmentProxy(
viewer.model,
fragId);
var renderProxy = viewer.impl.getRenderProxy(
viewer.model,
fragId);
fragProxy.updateAnimTransform();
var matrix = new THREE.Matrix4();
fragProxy.getWorldMatrix(matrix);
var geometry = renderProxy.geometry;
var attributes = geometry.attributes;
var vA = new THREE.Vector3();
var vB = new THREE.Vector3();
var vC = new THREE.Vector3();
if (attributes.index !== undefined) {
var indices = attributes.index.array || geometry.ib;
var positions = geometry.vb ? geometry.vb : attributes.position.array;
var stride = geometry.vb ? geometry.vbstride : 3;
var offsets = geometry.offsets;
if (!offsets || offsets.length === 0) {
offsets = [{start: 0, count: indices.length, index: 0}];
}
for (var oi = 0, ol = offsets.length; oi < ol; ++oi) {
var start = offsets[oi].start;
var count = offsets[oi].count;
var index = offsets[oi].index;
for (var i = start, il = start + count; i < il; i += 3) {
var a = index + indices[i];
var b = index + indices[i + 1];
var c = index + indices[i + 2];
vA.fromArray(positions, a * stride);
vB.fromArray(positions, b * stride);
vC.fromArray(positions, c * stride);
vA.applyMatrix4(matrix);
vB.applyMatrix4(matrix);
vC.applyMatrix4(matrix);
}
}
} else {
var positions = geometry.vb ? geometry.vb : attributes.position.array;
var stride = geometry.vb ? geometry.vbstride : 3;
for (var i = 0, j = 0, il = positions.length; i < il; i += 3, j += 9)
{
var a = i;
var b = i + 1;
var c = i + 2;
vA.fromArray(positions, a * stride);
vB.fromArray(positions, b * stride);
vC.fromArray(positions, c * stride);
vA.applyMatrix4(matrix);
vB.applyMatrix4(matrix);
vC.applyMatrix4(matrix);
}
}
In addition,
There is an awesome demo showing how to split models by its building storey(level: https://forge-rcdb.autodesk.io/configurator?id=5a7185a92a0a7aeb152725d5
Its source code is put here: https://github.com/Autodesk-Forge/forge-rcdb.nodejs/tree/master/src/client/viewer.components/Viewer.Extensions.Dynamic/Viewing.Extension.LevelFilter
The main concepts of this demo are:
Upvotes: 2