createUpdatableVolumeTex()

in src/engine/actvolume/setvolume.js [255:390]


  createUpdatableVolumeTex(volume, isRoiVolume, roiColors) {
    //
    // Some notes about tetxure layout.
    // Actually we have replaces3d texture with 2d texture (large size).
    // Idea: pack 2d slices of original texture into single 2d texture, looking
    // like tile map
    //
    // Let we have 7 slices on z direction and want to create
    // 2d visualization in (x,y) plane.
    // We can arrange 7 slices in a following manner (ooo - means unused)
    //
    // +-----+-----+-----+
    // |     |     |     |
    // |  0  |  1  |  2  |
    // |     |     |     |
    // +-----+-----+-----+
    // |     |     |     |
    // |  3  |  4  |  5  |
    // |     |     |     |
    // +-----+-----+-----+
    // |     |00000|00000|
    // |  6  |00000|00000|
    // |     |00000|00000|
    // +-----+-----+-----+
    //
    // Numbers 0..6 inside tiles shows original tiles indices
    //
    // Shader parameter
    // tileCointX: number of tiles in hor direction
    // volumeSizeZ: number of slices in z directiion
    //
    // console.log(roiColors);
    this.isWebGL2 = 1;
    this.arrPixels = volume.m_dataArray;
    const xDim = volume.m_xDim;
    const yDim = volume.m_yDim;
    const zDim = volume.m_zDim;
    const TWO = 2;
    const ONE = 1;
    const zDimSqrt = TWO ** (ONE + Math.floor(Math.log(Math.sqrt(zDim)) / Math.log(TWO)));
    if (!Number.isInteger(zDimSqrt)) {
      console.log(`!!! zDimSqrt should be integer, but = ${zDimSqrt}`);
    }
    const xTex = xDim * zDimSqrt;
    const yTex = yDim * zDimSqrt;
    const numPixelsBuffer = xTex * yTex;
    this.numPixelsBuffer = numPixelsBuffer;
    this.xTex = xTex;
    this.yTex = yTex;
    this.xDim = xDim;
    this.yDim = yDim;
    this.zDim = zDim;
    this.zDimSqrt = zDimSqrt;
    this.isRoiVolume = isRoiVolume;

    this.RoiVolumeTex = null;
    if (!isRoiVolume) {
      if (this.isWebGL2 === 0) {
        this.setBufferRgbaFrom1Byte();
      } else {
        this.set3DTextureFrom1Byte();
      }
    } else {
      if (this.isWebGL2 === 0) {
        this.setBufferRgbaFrom4Bytes();
        this.RoiVolumeTex = new THREE.DataTexture(this.bufferRoi, this.xTex, this.yTex, THREE.AlphaFormat);
      } else {
        this.set3DTextureFrom4Bytes();
        this.RoiVolumeTex = new THREE.DataTexture3D(this.bufferRoi, this.xDim, this.yDim, this.zDim);
        this.RoiVolumeTex.format = THREE.RedFormat; //RedFormat?
        this.RoiVolumeTex.type = THREE.UnsignedByteType;
      }
      this.RoiVolumeTex.wrapS = THREE.ClampToEdgeWrapping;
      this.RoiVolumeTex.wrapT = THREE.ClampToEdgeWrapping;
      this.RoiVolumeTex.magFilter = THREE.NearestFilter;
      this.RoiVolumeTex.minFilter = THREE.NearestFilter;
      this.RoiVolumeTex.needsUpdate = true;
    }
    let rtFormat = THREE.RGBAFormat;
    if (this.isWebGL2 === 1) {
      rtFormat = THREE.RGBAFormat; // can we use ALPHA?
    }
    this.bufferTexture = new THREE.WebGLRenderTarget(this.xDim, this.yDim, {
      minFilter: THREE.LinearFilter,
      magFilter: THREE.LinearFilter,
      format: rtFormat,
      type: THREE.UnsignedByteType,
      depthBuffer: false,
    });

    if (this.origVolumeTex) {
      this.origVolumeTex.dispose();
    }

    if (this.isWebGL2 === 0) {
      this.origVolumeTex = new THREE.DataTexture(this.bufferR, this.xTex, this.yTex, THREE.AlphaFormat);
    } else {
      this.origVolumeTex = new THREE.DataTexture3D(this.bufferR, this.xDim, this.yDim, this.zDim);
      this.origVolumeTex.format = THREE.RedFormat;
      this.origVolumeTex.type = THREE.UnsignedByteType;
      this.origVolumeTex.wrapR = THREE.ClampToEdgeWrapping;
    }
    this.origVolumeTex.wrapS = THREE.ClampToEdgeWrapping;
    this.origVolumeTex.wrapT = THREE.ClampToEdgeWrapping;

    this.origVolumeTex.magFilter = THREE.NearestFilter; //THREE.LinearFilter;
    this.origVolumeTex.minFilter = THREE.NearestFilter; //THREE.LinearFilter;

    this.origVolumeTex.needsUpdate = true;
    if (this.origVolumeTex) {
      this.origVolumeTex.dispose();
    }

    if (this.isWebGL2 === 0) {
      this.updatableTexture = new THREE.DataTexture(this.bufferTextureCPU, this.xTex, this.yTex, THREE.AlphaFormat);
    } else {
      let volTexFormat = THREE.RedFormat;
      if (isRoiVolume) {
        volTexFormat = THREE.RGBAFormat;
      }
      this.updatableTexture = new THREE.DataTexture3D(this.bufferTextureCPU, this.xDim, this.yDim, this.zDim);
      this.updatableTexture.format = volTexFormat;
      this.updatableTexture.type = THREE.UnsignedByteType;
      this.updatableTexture.wrapR = THREE.ClampToEdgeWrapping;
    }
    this.updatableTexture.wrapS = THREE.ClampToEdgeWrapping;
    this.updatableTexture.wrapT = THREE.ClampToEdgeWrapping;
    this.updatableTexture.magFilter = THREE.LinearFilter;
    this.updatableTexture.minFilter = THREE.LinearFilter;
    if (this.zDim > 1) {
      this.initRenderer(isRoiVolume, roiColors);
    }
    this.updatableTexture.needsUpdate = true;
    this.eraser = new Eraser();
    return this.updatableTexture;
  }