All files / core/src/RenderingEngine/helpers vtkCanvasCoordinateTransforms.ts

0% Statements 0/41
0% Branches 0/6
0% Functions 0/5
0% Lines 0/41

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 112 113 114 115 116 117 118 119 120 121 122 123                                                                                                                                                                                                                                                     
import type vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';
import type { Point2, Point3 } from '../../types';
 
export function canvasToWorldContextPool(args: {
  canvas: HTMLCanvasElement;
  renderer: vtkRenderer;
  canvasPos: Point2;
}): Point3 {
  const { canvas, renderer, canvasPos } = args;
  const vtkCamera = renderer.getActiveCamera() as {
    getClippingRange(): [number, number];
    getDistance(): number;
    setClippingRange(near: number, far: number): void;
    setIsPerformingCoordinateTransformation?(flag: boolean): void;
  };
  const restoreCamera = prepareCameraForCoordinateTransforms(vtkCamera);
  const devicePixelRatio = window.devicePixelRatio || 1;
  const { width, height } = canvas;
  const aspectRatio = width / height;
  const canvasPosWithDPR = [
    canvasPos[0] * devicePixelRatio,
    canvasPos[1] * devicePixelRatio,
  ];
  const [xStart, yStart, xEnd, yEnd] =
    renderer.getViewport() as unknown as number[];
  const viewportWidth = xEnd - xStart;
  const viewportHeight = yEnd - yStart;
  const normalizedDisplay = [
    xStart + (canvasPosWithDPR[0] / width) * viewportWidth,
    yStart + (1 - canvasPosWithDPR[1] / height) * viewportHeight,
    0,
  ];
  const projCoords = renderer.normalizedDisplayToProjection(
    normalizedDisplay[0],
    normalizedDisplay[1],
    normalizedDisplay[2]
  );
  const viewCoords = renderer.projectionToView(
    projCoords[0],
    projCoords[1],
    projCoords[2],
    aspectRatio
  );
  const worldCoord = renderer.viewToWorld(
    viewCoords[0],
    viewCoords[1],
    viewCoords[2]
  );
 
  restoreCamera();
 
  return [worldCoord[0], worldCoord[1], worldCoord[2]];
}
 
export function worldToCanvasContextPool(args: {
  canvas: HTMLCanvasElement;
  renderer: vtkRenderer;
  worldPos: Point3;
}): Point2 {
  const { canvas, renderer, worldPos } = args;
  const vtkCamera = renderer.getActiveCamera() as {
    getClippingRange(): [number, number];
    getDistance(): number;
    setClippingRange(near: number, far: number): void;
    setIsPerformingCoordinateTransformation?(flag: boolean): void;
  };
  const restoreCamera = prepareCameraForCoordinateTransforms(vtkCamera);
  const devicePixelRatio = window.devicePixelRatio || 1;
  const { width, height } = canvas;
  const aspectRatio = width / height;
  const viewCoords = renderer.worldToView(
    worldPos[0],
    worldPos[1],
    worldPos[2]
  );
  const projCoords = renderer.viewToProjection(
    viewCoords[0],
    viewCoords[1],
    viewCoords[2],
    aspectRatio
  );
  const normalizedDisplay = renderer.projectionToNormalizedDisplay(
    projCoords[0],
    projCoords[1],
    projCoords[2]
  );
  const [xStart, yStart, xEnd, yEnd] =
    renderer.getViewport() as unknown as number[];
  const viewportWidth = xEnd - xStart;
  const viewportHeight = yEnd - yStart;
  const canvasX = ((normalizedDisplay[0] - xStart) / viewportWidth) * width;
  const canvasY =
    (1 - (normalizedDisplay[1] - yStart) / viewportHeight) * height;
 
  restoreCamera();
 
  return [canvasX / devicePixelRatio, canvasY / devicePixelRatio];
}
 
function prepareCameraForCoordinateTransforms(vtkCamera: {
  getClippingRange(): [number, number];
  getDistance(): number;
  setClippingRange(near: number, far: number): void;
  setIsPerformingCoordinateTransformation?(flag: boolean): void;
}): () => void {
  if (vtkCamera.setIsPerformingCoordinateTransformation) {
    vtkCamera.setIsPerformingCoordinateTransformation(true);
 
    return () => {
      vtkCamera.setIsPerformingCoordinateTransformation?.(false);
    };
  }
 
  const clippingRange = vtkCamera.getClippingRange();
  const distance = vtkCamera.getDistance();
 
  vtkCamera.setClippingRange(distance, distance + 0.1);
 
  return () => {
    vtkCamera.setClippingRange(clippingRange[0], clippingRange[1]);
  };
}