Введение.
BIM (англ. Building Information Model или Информационное моделирование строительных объектов) — это объектно-ориентированная модель строительного объекта, как правило, в трёхмерном представлении, элементы которой содержат данные геометрических, физических и функциональных характеристик будущего здания или сооружения.
BIM-технология — организованный процесс, в результате которого формируется BIM-модель, отвечающая задачам и потребностям конкретной стадии жизненного цикла здания или сооружения.
Open BIM — подход к объединению проектов зданий и сооружений в согласованную модель. Методология, позволяющая участникам проектирования коммуницировать, невзирая на используемое программное обеспечение.
IFC (Industry Foundation Classes) — открытый стандарт для формата представления данных BIM. Формат файлов разработан buildingSMART (International Alliance for Interoperability, IAI) для упрощения взаимодействия в строительной сфере и приведению к общему знаменателю.
Сектор AEC традиционно был рынком нескольких богатых ресурсами игроков. Крупные компании годами создавали свои собственные продукты: миллионы строк кода, решающие проблемы и в конечном итоге составляют приложения для реализации BIM и которые мы знаем из повседневной жизни.
Проблема в этой ситуации заключается в том, что новым разработчикам и компаниям очень трудно предлагать свои идеи и конкурировать на равных условиях на этом рынке. И получается, что доступ к "высшей лиге" имеют те, кто может себе это позволить.
Это не относится к таким секторам, как видеоигры, где существует множество инструментов и технологий (видеоигровых движков), которые позволяют любому создать продукт высокого уровня с минимальными затратами времени и ресурсов. Было бы здорово иметь то же самое в секторе AEC?
Вот почему мы запустили IFC.js. Вместо того чтобы создавать решение для реализации технологии BIM и продавать его как продукт, мы делаем его свободно доступным, чтобы каждый мог создавать свои собственные BIM-продукты высокого уровня. Таким образом, мы все можем конкурировать на рынке программного обеспечения с одним и тем же инструментом, где каждый может предложить свои идеи по улучшению.
IFC.js — молодой проект, который развивается и растет с каждым днем. Наша цель — позволить каждому разрабатывать программное обеспечение BIM с такой же легкостью, с какой разрабатываются видеоигры. IFC.js бесплатен, у него нет владельца, и любой может использовать его или участвовать в проекте.
Для работы с IFC.js требуются базовые знания веб-разработки (HTML, CSS, JavaScript) и библиотеки Three.js
Все вышеперечисленные свойства можно сразу заполнить, либо прожав Enter и использовать значения по умолчанию.
//Install IFC.js
npm i web-ifc-three
// Install a bundler: we will use rollup.js for this guide
npm i rollup --save-dev
npm i @rollup/plugin-node-resolve --save-dev<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="styles.css"/>
<title>Document</title>
</head>
<body>
<input type="file" name="load" id="file-input"/>
<canvas id="three-canvas"></canvas>
<script src="bundle.js"></script>
</body>
</html>Для удобства импорта нашей будущей IFC-модели для тэга <input> можно добавить атрибут accept=".ifc" и видеть только файлы с расширением .ifc в директории, откуда загружаем модель.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
overflow: hidden;
}
#three-canvas {
position: fixed;
top: 0;
left: 0;
outline: none;
}
#file-input {
z-index: 1;
position: absolute;
}Rollup — популярная библиотека пакетов. К примеру, это сборщик, используемый Three.js. Чтобы узнать больше, ознакомьтесь с документацией.
import resolve from "@rollup/plugin-node-resolve";
export default {
input: "app.js",
output: [
{
format: "esm",
file: "bundle.js",
},
],
plugins: [resolve()],
};{
"name": "example",
"version": "1.0.0",
"description": "-",
"main": "app.js",
"scripts": {
"build": "rollup -c ./rollup.config.js",
"watch": "rollup -w -c ./rollup.config.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@rollup/plugin-node-resolve": "^11.2.1",
"rollup": "^2.45.2"
},
"dependencies": {
"three": "^0.128.0",
"web-ifc-three": "0.0.102"
}
}import { AmbientLight, AxesHelper, DirectionalLight, GridHelper, PerspectiveCamera, Scene, WebGLRenderer } from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
//Creates the Three.js scene
const scene = new Scene();
//Object to store the size of the viewport
const size = {
width: window.innerWidth,
height: window.innerHeight,
};
//Creates the camera (point of view of the user)
const aspect = size.width / size.height;
const camera = new PerspectiveCamera(75, aspect);
camera.position.z = 15;
camera.position.y = 13;
camera.position.x = 8;
//Creates the lights of the scene
const lightColor = 0xffffff;
const ambientLight = new AmbientLight(lightColor, 0.5);
scene.add(ambientLight);
const directionalLight = new DirectionalLight(lightColor, 1);
directionalLight.position.set(0, 10, 0);
directionalLight.target.position.set(-5, 0, 0);
scene.add(directionalLight);
scene.add(directionalLight.target);
//Sets up the renderer, fetching the canvas of the HTML
const threeCanvas = document.getElementById("three-canvas");
const renderer = new WebGLRenderer({
canvas: threeCanvas,
alpha: true,
});
renderer.setSize(size.width, size.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
//Creates grids and axes in the scene
const grid = new GridHelper(50, 30);
scene.add(grid);
const axes = new AxesHelper();
axes.material.depthTest = false;
axes.renderOrder = 1;
scene.add(axes);
//Creates the orbit controls (to navigate the scene)
const controls = new OrbitControls(camera, threeCanvas);
controls.enableDamping = true;
controls.target.set(-2, 0, 0);
//Animation loop
const animate = () => {
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
animate();
//Adjust the viewport to the size of the browser
window.addEventListener("resize", () => {
size.width = window.innerWidth;
size.height = window.innerHeight;
camera.aspect = size.width / size.height;
camera.updateProjectionMatrix();
renderer.setSize(size.width, size.height);
});import { IFCLoader } from "web-ifc-three/IFCLoader";
// Sets up the IFC loading
const ifcLoader = new IFCLoader();
const input = document.getElementById("file-input");
input.addEventListener(
"change",
(changed) => {
const file = changed.target.files[0];
var ifcURL = URL.createObjectURL(file);
ifcLoader.load(ifcURL, (ifcModel) => scene.add(ifcModel));
},
false
);import {
AmbientLight,
AxesHelper,
DirectionalLight,
GridHelper,
PerspectiveCamera,
Scene,
WebGLRenderer,
} from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { IFCLoader } from "web-ifc-three/IFCLoader";
//Creates the Three.js scene
const scene = new Scene();
//Object to store the size of the viewport
const size = {
width: window.innerWidth,
height: window.innerHeight,
};
//Creates the camera (point of view of the user)
const aspect = size.width / size.height;
const camera = new PerspectiveCamera(75, aspect);
camera.position.z = 15;
camera.position.y = 13;
camera.position.x = 8;
//Creates the lights of the scene
const lightColor = 0xffffff;
const ambientLight = new AmbientLight(lightColor, 0.5);
scene.add(ambientLight);
const directionalLight = new DirectionalLight(lightColor, 1);
directionalLight.position.set(0, 10, 0);
directionalLight.target.position.set(-5, 0, 0);
scene.add(directionalLight);
scene.add(directionalLight.target);
//Sets up the renderer, fetching the canvas of the HTML
const threeCanvas = document.getElementById("three-canvas");
const renderer = new WebGLRenderer({
canvas: threeCanvas,
alpha: true,
});
renderer.setSize(size.width, size.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
//Creates grids and axes in the scene
const grid = new GridHelper(50, 30);
scene.add(grid);
const axes = new AxesHelper();
axes.material.depthTest = false;
axes.renderOrder = 1;
scene.add(axes);
//Creates the orbit controls (to navigate the scene)
const controls = new OrbitControls(camera, threeCanvas);
controls.enableDamping = true;
controls.target.set(-2, 0, 0);
//Animation loop
const animate = () => {
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
animate();
//Adjust the viewport to the size of the browser
window.addEventListener("resize", () => {
size.width = window.innerWidth;
size.height = window.innerHeight;
camera.aspect = size.width / size.height;
camera.updateProjectionMatrix();
renderer.setSize(size.width, size.height);
});
// Sets up the IFC loading
const ifcLoader = new IFCLoader();
const input = document.getElementById("file-input");
input.addEventListener(
"change",
(changed) => {
const file = changed.target.files[0];
var ifcURL = URL.createObjectURL(file);
ifcLoader.load(ifcURL, (ifcModel) => scene.add(ifcModel));
},
false
);tURL(file);
ifcLoader.load(ifcURL, (ifcModel) => scene.add(ifcModel));
},
false
);