Как стать автором
Обновить

Цифровая археология и Виртуальная реальность или как я пытался подружить BIM и VR

Время на прочтение4 мин
Количество просмотров3.7K
Все новые модные технологии имеют массивный фундамент из старых и подчас для работы с ними нужно основательно покопаться в толще исторических слоёв и с удивлением найти там удобные и весьма своевременные инструменты.



Возникла перед мной задача отображения 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 — если интересно, могу расписать как его использовать, но там нет ничего сложного.
Теги:
Хабы:
Всего голосов 6: ↑6 и ↓0+6
Комментарии6

Публикации

Истории

Ближайшие события