All files / src/datasources/cognitesdk/cad createCadModel.ts

12% Statements 6/50
0% Branches 0/6
0% Functions 0/12
12% Lines 6/50

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111            1x 1x 1x   1x     1x   1x                                                                                                                                                                                              
/*!
 * Copyright 2020 Cognite AS
 */
 
import { FetchSectorMetadataDelegate, FetchSectorDelegate, FetchCtmDelegate } from '../../../models/cad/delegates';
import { CogniteClient, RevealSector3D, Versioned3DFile } from '@cognite/sdk';
import { buildSectorMetadata } from './buildSectorMetadata';
import { constructMatrixFromRotation } from '../../constructMatrixFromRotation';
import { getNewestVersionedFile } from '../utilities';
import { SectorModelTransformation } from '../../../models/cad/types';
import { mat4 } from 'gl-matrix';
import { LocalSimpleCadMetadataResponse } from '../../local/cad/loadLocalSimpleSectorMetadata';
import { CadModel } from '../../../models/cad/CadModel';
import { createParser, createQuadsParser } from '../../../models/cad/parseSectorData';
 
export async function createCadModel(sdk: CogniteClient, modelId: number, revisionId: number): Promise<CadModel> {
  const metadataPromise = loadSectorMetadata(sdk, modelId, revisionId);
 
  // TODO replace this with actually fetching metadata about simple sectors
  const simpleMetadataPromise: Promise<Map<number, LocalSimpleCadMetadataResponse>> = new Promise(_ => {
    throw new Error('Not implemented');
  });
 
  const rotationPromise = loadRotation(sdk, modelId, revisionId);
  const sectorFilemapPromise = (async () => {
    return createSectorFilemap(await metadataPromise);
  })();
 
  const fetchSectorMetadata: FetchSectorMetadataDelegate = async () => {
    const modelMatrix = constructMatrixFromRotation(await rotationPromise);
    const inverseModelMatrix = mat4.invert(mat4.create(), modelMatrix);
    if (!inverseModelMatrix) {
      throw new Error('Model rotation resulted in non-invertible model matrix');
    }
    const modelTransform: SectorModelTransformation = {
      modelMatrix,
      inverseModelMatrix
    };
    return [buildSectorMetadata(await metadataPromise, await simpleMetadataPromise), modelTransform];
  };
  const fetchSectorDetailed: FetchSectorDelegate = async sectorId => {
    const sectorFilemap = await sectorFilemapPromise;
    const file = sectorFilemap.get(sectorId);
    if (!file) {
      throw new Error(`Could not find a file mapping for sector ${sectorId}`);
    }
    return loadSectorGeometry(sdk, sectorId, file);
  };
  const fetchSectorSimple: FetchSectorDelegate = async _sectorId => {
    // TODO implement
    throw new Error('Not implemeted');
  };
  const fetchCtm: FetchCtmDelegate = async fileId => {
    return loadCtmFile(sdk, fileId);
  };
 
  // Fetch metadata
  const [scene, modelTransformation] = await fetchSectorMetadata();
  const parseDetailed = await createParser(fetchCtm);
  const parseSimple = await createQuadsParser();
  return {
    fetchSectorMetadata,
    fetchSectorDetailed,
    fetchSectorSimple,
    fetchCtm,
    parseDetailed,
    parseSimple,
    scene,
    modelTransformation
  };
}
 
async function loadSectorMetadata(sdk: CogniteClient, modelId: number, revisionId: number): Promise<RevealSector3D[]> {
  let cursor: string | undefined;
  let sectors: RevealSector3D[] = [];
  do {
    const result = await sdk.viewer3D.listRevealSectors3D(modelId, revisionId, { cursor });
    sectors = sectors.concat(result.items);
    cursor = result.nextCursor;
  } while (cursor !== undefined);
  return sectors;
}
 
async function loadRotation(
  sdk: CogniteClient,
  modelId: number,
  revisionId: number
): Promise<[number, number, number] | null> {
  const result = await sdk.viewer3D.retrieveRevealRevision3D(modelId, revisionId);
  return result.rotation ? result.rotation : null;
}
 
function createSectorFilemap(sectors: RevealSector3D[]): Map<number, Versioned3DFile> {
  const sectorIdToFile = new Map<number, Versioned3DFile>();
  for (const sector of sectors) {
    const file = getNewestVersionedFile(sector.threedFiles);
    sectorIdToFile.set(sector.id, file);
  }
  return sectorIdToFile;
}
 
async function loadSectorGeometry(sdk: CogniteClient, _sectorId: number, file: Versioned3DFile): Promise<Uint8Array> {
  const buffer = await sdk.files3D.retrieve(file!.fileId);
  return new Uint8Array(buffer);
}
 
async function loadCtmFile(sdk: CogniteClient, fileId: number): Promise<Uint8Array> {
  const buffer = await sdk.files3D.retrieve(fileId);
  return new Uint8Array(buffer);
}