Arqueologia digital e realidade virtual ou como tentei fazer amizade com BIM e VR

Todas as novas tecnologias da moda têm uma base maciça em relação às antigas e, algumas vezes, para trabalhar com elas, é necessário aprofundar-se na espessura das camadas históricas e, com surpresa, encontrar ferramentas convenientes e oportunas.



Tive a tarefa de exibir um modelo BIM em VR, ou melhor, exportar do Revit. Do ponto de vista do resultado final, havia duas opções: Unity ou A-Frame. Para exportação, eu queria um formato aberto, dos quais apenas a IFC era. Portanto, examinei o projeto xBIM pela primeira vez - eles tinham um projeto visualizador da web xBIM WeXplorer com seu próprio formato wexBIM. Mas lá usamos nossa própria renderização via WebGL, e a exportação para o wexBIM não funcionou na versão atual do XbimXplorer e não encontrei uma descrição do formato.

Então, tive a ideia de usar a exportação no Tree.js, uma vez que experimentamos muito com ele, e o A-Frame é apenas um invólucro no Tree.js. Eu descobri que Jeremy Tammik e colegas já implementaram um similar - exportar do Revit para o Tree.js através do seu formato json, no github existem dois repositórios para exportação do Revit - CustomExporterAdnMeshJson e 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

meu resultado dessa discussão

Mas, além da exportação, eu precisava escrever um código para importação, pareceu-me excessivo e procurei um formato aberto adequado e o encontrei rapidamente - gltf / glb do Khronos Group, a importação para o A-Frame é fundamental:

<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> 

Para criar gltf / glb, vários utilitários foram escritos no Khronos Group, incluindo C # - SharpGLTF .

Criar gltf requer a criação dos seguintes objetos: Model <= Scene <= Nodes <= Mesh <= Material

  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"); 

Resta apenas escrever exportação do Revit, por isso estudei os utilitários Jeremy Tammik. Para exportar, é necessário criar uma classe que implemente a interface IExportContext, seus métodos são chamados em uma determinada ordem quando o modelo é exportado, estamos interessados ​​na cadeia principal Iniciar => OnViewBegin => OnElementBegin => OnPolymesh. No método Start, criaremos um modelo gltf, no método OnElementBegin, eu crio uma malha - aqui você pode obter a geometria do elemento, mas será um modelo de brep e não é adequado para gltf. No próximo método OnPolymesh, obtemos a mesma geometria de uma malha que já pode ser salva em gltf.

O método OnInstanceBegin é executado - se o elemento for uma inserção da família, sua geometria será obtida em seu próprio sistema de coordenadas e será necessário transformá-lo em um mundo. Precisamos de uma pilha para armazenar esses sistemas de coordenadas.

O método OnMaterial é executado ao alterar o material; é melhor criar um dicionário de materiais e retirar o material necessário, em vez de criar um novo a cada vez.

O método OnLinkBegin é executado ao processar um link externo - na verdade, um modelo aninhado.

O método OnLight é executado ao processar uma fonte de luz

O método OnFaceBegin é executado ao processar faces individuais de um elemento; é chamado apenas se a propriedade IncludeGeometricObjects = true

Em princípio, você pode escrever o modelo inteiro em um nó, mas quero associar elementos com dados de atributos no futuro e, portanto, escrevo cada elemento no meu nó usando seu ElementId como um nome.

Código do utilitário no git-hub

No Windows 10, existem dois programas regulares para exibir glb (mas não gltf), este é um "Visualizador de realidade mista" para exibir



E o Paint 3D para edição



Como você pode ver, eles renderizam os materiais de maneira diferente e, em particular, lidam com a transparência de maneira diferente (ambos não estão corretos)

Mas para mim - o melhor é o VS Code + glTF Tools



O A-Frame funciona em todos os navegadores modernos, mas você só pode usar o capacete no Firefox (e Supermedium, é claro). Precisamos organizar o controle, no A-Frame você pode usar controles wasd para controlar o mouse, mas é melhor usar controles de movimento da extensão A-Frame Extras . Para usar os controladores do vive, você precisa adicionar controles do vive. Código de página inteira no 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> 



A propósito, o git-hub é adequado para hospedagem de VR; =)

Você pode usar o plug-in UnityGLTF para importar glb para o Unity - se estiver interessado, posso pintar como usá-lo, mas não há nada complicado.

Source: https://habr.com/ru/post/pt472264/


All Articles