Все новые модные технологии имеют массивный фундамент из старых и подчас для работы с ними нужно основательно покопаться в толще исторических слоёв и с удивлением найти там удобные и весьма своевременные инструменты.
Возникла перед мной задача отображения BIM-модели в VR, а точнее экспорт из Revit’а. С точки зрения конечного результат было два варианта: Unity или A-Frame. Для экспорта хотелось открытый формат из которых был только IFC. По этому, я первым делом посмотрел на проект xBIM – у них был проект веб-вьювера xBIM WeXplorer с собственным форматом wexBIM. Но там использовался собственный рендер через WebGL, а экспорт в wexBIM не работал в текущей версии XbimXplorer и описание формата я не нашёл.
Тогда у меня возникла идея использования экспорта в Tree.js, одно время с ним много экспериментировали, а A-Frame это просто обёртка над Tree.js. Я обнаружил, что Jeremy Tammik с коллегами уже реализовали подобное – экспорт из Revit’а в Tree.js через свой json-формат, на github’е есть два репозитория для экспорта из Revit’а – CustomExporterAdnMeshJson и RvtVa3c.
github.com/va3c/RvtVa3c
github.com/jeremytammik/CustomExporterAdnMeshJson
thebuildingcoder.typepad.com/blog/2013/07/adn-mesh-data-custom-exporter-to-json.html
thebuildingcoder.typepad.com/blog/2014/08/threejs-aec-viewer-progress-on-two-fronts.html
мой итог этой ветки
Но помимо экспорта нужно писать код для импорта, мне показалось это чрезмерным и я отправился на поиски подходящего открытого формата и быстро нашёл его — gltf/glb от Khronos Group, импорт в A-Frame элементарен:
Для создания gltf/glb в Khronos Group было написана куча утилит, в том числе и на C# — SharpGLTF.
Создание gltf требует создать следующие объекты: Модель<=Сцена<=Узлы<=Меш<=Материал
Осталось лишь написать экспорт из Revit’а, для этого я изучил утилиты Jeremy Tammik. Для экспорта необходимо создать класс реализующий интерфейс IExportContext, его методы вызываются в определённом порядке при экспорте модели, нас интересует основная цепочка Start=> OnViewBegin=> OnElementBegin=> OnPolymesh. В методе Start мы создадим модель gltf, в методе OnElementBegin я создаю меш – здесь можно получить геометрию элемента, но это будет brep-модель и она не подходит для gltf, в следующем методе OnPolymesh мы получаем туже геометрию в виде меша которую уже можно сохранить в gltf.
Метод OnInstanceBegin выполняется – если элемент является вставкой семейства, его геометрия будет получена в его собственной системе координат и нужно будет трансформировать её в мировую. Нам потребуется стек для хранения этих систем координат.
Метод OnMaterial выполняется при смене материала, лучше завести словарь материалов и брать нужный материал из него, а не создавать каждый раз новый.
Метод OnLinkBegin выполняется при обработке внешней ссылки – фактически вложенная модель.
Метод OnLight выполняется при обработке источника света
Метод OnFaceBegin выполняется при обработке отдельных граней элемента, вызывается только если свойство IncludeGeometricObjects = true
В принципе можно записать всё модель в одну ноду, но я хочу в будущем связать элементы с атрибутивными данными и поэтому записываю каждый элемент в свой узел используя его ElementId в качестве названия
Код утилиты на git-hub'е
В Windows 10 есть две штатных программы для просмотра glb (но не gltf), это «Средство просмотра смешанной реальности» для просмотра
И Paint 3D для редактирования
Как видим они по разному рендерят материалы и в частности по разному обрабатывают прозрачность (оба не правильно)
Но по мне — лучше всего VS Code + glTF Tools
A-Frame работает во всех современных браузерах, но использовать шлем удастся только в Firefox (и Supermedium конечно). Нам понадобится организовать управление, в A-Frame для управления мышкой можно использовать wasd-controls, но лучше использовать movement-controls из расширения A-Frame Extras. Для использования контролеров vive нужно добавить vive-controls. Полный код страницы на git-hub'e.
Между прочим git-hub подходит для хостинга VR ;=)
Для импорта glb в Unity можно использовать плагин UnityGLTF — если интересно, могу расписать как его использовать, но там нет ничего сложного.
Возникла перед мной задача отображения BIM-модели в VR, а точнее экспорт из Revit’а. С точки зрения конечного результат было два варианта: Unity или A-Frame. Для экспорта хотелось открытый формат из которых был только IFC. По этому, я первым делом посмотрел на проект xBIM – у них был проект веб-вьювера xBIM WeXplorer с собственным форматом wexBIM. Но там использовался собственный рендер через WebGL, а экспорт в wexBIM не работал в текущей версии XbimXplorer и описание формата я не нашёл.
Тогда у меня возникла идея использования экспорта в Tree.js, одно время с ним много экспериментировали, а A-Frame это просто обёртка над Tree.js. Я обнаружил, что Jeremy Tammik с коллегами уже реализовали подобное – экспорт из Revit’а в Tree.js через свой json-формат, на github’е есть два репозитория для экспорта из Revit’а – CustomExporterAdnMeshJson и RvtVa3c.
github.com/va3c/RvtVa3c
github.com/jeremytammik/CustomExporterAdnMeshJson
thebuildingcoder.typepad.com/blog/2013/07/adn-mesh-data-custom-exporter-to-json.html
thebuildingcoder.typepad.com/blog/2014/08/threejs-aec-viewer-progress-on-two-fronts.html
мой итог этой ветки
Но помимо экспорта нужно писать код для импорта, мне показалось это чрезмерным и я отправился на поиски подходящего открытого формата и быстро нашёл его — gltf/glb от Khronos Group, импорт в A-Frame элементарен:
<a-scene>
<a-assets>
<a-asset-item id="tree" src="/path/to/tree.gltf"></a-asset-item>
</a-assets>
<a-entity gltf-model="#tree"></a-entity>
</a-scene>
Для создания gltf/glb в Khronos Group было написана куча утилит, в том числе и на C# — SharpGLTF.
Создание gltf требует создать следующие объекты: Модель<=Сцена<=Узлы<=Меш<=Материал
var material1 = new MaterialBuilder()
.WithAlpha(AlphaMode.MASK)
.WithDoubleSide(true)
.WithSpecularGlossinessShader()
.WithChannelParam("BaseColor", new Vector4(1, 0, 0, 0.1f));
var ch = material1.UseChannel("MetallicRoughness");
var mesh = new MeshBuilder<VERTEX>("mesh");
var prim = mesh.UsePrimitive(material1);
VERTEX tv = new VERTEX(-10, 0, 0);
prim.AddTriangle(tv, new VERTEX(10, 0, 0), new VERTEX(0, 10, 0));
prim.AddTriangle(new VERTEX(10, 0, 0), tv, new VERTEX(0, -10, 0));
var mesh2 = new MeshBuilder<VERTEX>("mesh");
// create a new gltf model
var model = ModelRoot.CreateModel();
// create a scene, a node, and assign the first mesh
Scene scene = model.UseScene("Default");
scene.CreateNode().WithMesh(model.CreateMeshes(mesh)[0]);
// save the model in different formats
model.SaveAsWavefront("mesh.obj");
model.SaveGLB("mesh.glb");
model.SaveGLTF("mesh.gltf");
Осталось лишь написать экспорт из Revit’а, для этого я изучил утилиты Jeremy Tammik. Для экспорта необходимо создать класс реализующий интерфейс IExportContext, его методы вызываются в определённом порядке при экспорте модели, нас интересует основная цепочка Start=> OnViewBegin=> OnElementBegin=> OnPolymesh. В методе Start мы создадим модель gltf, в методе OnElementBegin я создаю меш – здесь можно получить геометрию элемента, но это будет brep-модель и она не подходит для gltf, в следующем методе OnPolymesh мы получаем туже геометрию в виде меша которую уже можно сохранить в gltf.
Метод OnInstanceBegin выполняется – если элемент является вставкой семейства, его геометрия будет получена в его собственной системе координат и нужно будет трансформировать её в мировую. Нам потребуется стек для хранения этих систем координат.
Метод OnMaterial выполняется при смене материала, лучше завести словарь материалов и брать нужный материал из него, а не создавать каждый раз новый.
Метод OnLinkBegin выполняется при обработке внешней ссылки – фактически вложенная модель.
Метод OnLight выполняется при обработке источника света
Метод OnFaceBegin выполняется при обработке отдельных граней элемента, вызывается только если свойство IncludeGeometricObjects = true
В принципе можно записать всё модель в одну ноду, но я хочу в будущем связать элементы с атрибутивными данными и поэтому записываю каждый элемент в свой узел используя его ElementId в качестве названия
Код утилиты на git-hub'е
В Windows 10 есть две штатных программы для просмотра glb (но не gltf), это «Средство просмотра смешанной реальности» для просмотра
И Paint 3D для редактирования
Как видим они по разному рендерят материалы и в частности по разному обрабатывают прозрачность (оба не правильно)
Но по мне — лучше всего VS Code + glTF Tools
A-Frame работает во всех современных браузерах, но использовать шлем удастся только в Firefox (и Supermedium конечно). Нам понадобится организовать управление, в A-Frame для управления мышкой можно использовать wasd-controls, но лучше использовать movement-controls из расширения A-Frame Extras. Для использования контролеров vive нужно добавить vive-controls. Полный код страницы на git-hub'e.
<a-scene background="color: #ECECEC">
<a-assets>
<a-asset-item id="ar1" src="house5.glb"></a-asset-item>
</a-assets>
<a-gltf-model src="#ar1" rotation="0 0 0"></a-gltf-model>
<a-entity position="0 0 4" movement-controls="acceleration: 2000; fly: true" >
<a-camera></a-camera>
<a-entity vive-controls="hand: left"></a-entity>
<a-entity vive-controls="hand: right"></a-entity>
</a-entity>
</a-scene>
Между прочим git-hub подходит для хостинга VR ;=)
Для импорта glb в Unity можно использовать плагин UnityGLTF — если интересно, могу расписать как его использовать, но там нет ничего сложного.