簡體   English   中英

web-ifc-three中如何訪問IFC項目的BufferGeometry

[英]How to access the BufferGeometry of IFC items in web-ifc-three

我正在嘗試獲取與我擁有的 expressId 相對應的元素的幾何形狀,即 BufferGeometry object(不是通過挑選)。

基本上我在問如何遍歷 IFC model 並將每個 object 作為單獨的 OBJ 導出。

我會注意到我有逆向工程代碼來實現 package 的某些版本,但它使用未記錄的功能,所以它自然會在以后的版本中中斷(代碼也是 colors 根據材料的顏色幾何所以我不需要一個mtl):

不要復制此代碼,它將不起作用

Object.values(bimModel.ifcManager.state.models[bimModel.modelID].items).forEach(type => {
  Object.entries(type.geometries).forEach(([id, geometry]) => {
    const properties = bimModel.getItemProperties(Number(id))
    const numVertices = geometry.getAttribute('position').count
    const color = type.material.color.toArray().map(x => x * 255)
    const vertexColors = new Uint8Array(Array.from({ length: numVertices }, () => color).flat())
    geometry.setAttribute('color', new BufferAttribute(vertexColors, 3, true))
  })
})

使它成為 OBJ 而不是 GLTF 的任何具體原因? 我知道您可以將 ifc model 制作成幾個 GLTF 文件。

如果您不介意這是 GLTF 結果,我會跟進答案。 謝謝。

這正是我們將模型導出到 glTF 所做的。 基本工作流程是:

  • 確定您要導出的 IFC 類別。
  • 獲取每個類別的所有項目。
  • 為每個項目重建網格。
  • 使用您選擇的 Three.js 導出器導出網格。

讓我們看一個從牆上獲取所有網格的基本示例。 該過程並不像將每個 IFC 項目作為單獨的網格那樣簡單,但這是使繪制調用最少的代價(否則,瀏覽器甚至無法支持中等大小的 IFC 文件):

import { IFCWALLSTANDARDCASE } from 'web-ifc';

async function getAllWallMeshes() {

  // Get all the IDs of the walls

  const wallsIDs = manager.getAllItemsOfType(0, IFCWALL, false);
  const meshes = [];
  const customID = 'temp-gltf-subset';

  for(const wallID of wallsIDs) {
    const coordinates = [];
    const expressIDs = [];
    const newIndices = [];

    const alreadySaved = new Map();

    // Get the subset for the wall

    const subset = viewer.IFC.loader.ifcManager.createSubset({
      ids: [wallID],
        modelID,
        removePrevious: true,
        customID
     });

    // Subsets have their own index, but share the BufferAttributes 
    // with the original geometry, so we need to rebuild a new 
    // geometry with this index

    const positionAttr = subset.geometry.attributes.position;
    const expressIDAttr = subset.geometry.attributes.expressID;

    const newGroups = subset.geometry.groups
         .filter((group) => group.count !== 0);

    const newMaterials = [];
    const prevMaterials = subset.material;
    let newMaterialIndex = 0;

    newGroups.forEach((group) => {
      newMaterials.push(prevMaterials[group.materialIndex]);
      group.materialIndex = newMaterialIndex++;
    });

    let newIndex = 0;
    for (let i = 0; i < subset.geometry.index.count; i++) {
      const index = subset.geometry.index.array[i];

      if (!alreadySaved.has(index)) {
        coordinates.push(positionAttr.array[3 * index]);
        coordinates.push(positionAttr.array[3 * index + 1]);
        coordinates.push(positionAttr.array[3 * index + 2]);

        expressIDs.push(expressIDAttr.getX(index));
        alreadySaved.set(index, newIndex++);
      }

      const saved = alreadySaved.get(index);
      newIndices.push(saved);
    }

    const geometryToExport = new BufferGeometry();
    const newVerticesAttr = new BufferAttribute(Float32Array.from(coordinates), 3);
    const newExpressIDAttr = new BufferAttribute(Uint32Array.from(expressIDs), 1);

    geometryToExport.setAttribute('position', newVerticesAttr);
    geometryToExport.setAttribute('expressID', newExpressIDAttr);
    geometryToExport.setIndex(newIndices);
    geometryToExport.groups = newGroups;
    geometryToExport.computeVertexNormals();

    const mesh = new Mesh(geometryToExport, newMaterials);
    meshes.push(mesh);
  }
 
  viewer.IFC.loader.ifcManager.removeSubset(modelID, undefined, customID);
  return meshes;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM