Skip to content

Commit

Permalink
feat: Enhanced crosshairs architecture (#280)
Browse files Browse the repository at this point in the history
* feat: Crosshairs major re-architecture

* fix: Crosshairs tests

* feat: Add two viewports crosshair support with new tool architecture

* fix: Remove unnecessary viewport focal point caching

* feat: Add prostate study demo

* review comments

* feat: refactored math computations

* fix: Final render upon slabThickness reset

* feat: Add docs to crosshairs

* review comments

* fix crosshair tests
  • Loading branch information
sedghi authored and swederik committed Mar 22, 2022
1 parent dd2bfc8 commit f064a37
Show file tree
Hide file tree
Showing 27 changed files with 988 additions and 312 deletions.
4 changes: 2 additions & 2 deletions packages/cornerstone-render/src/RenderingEngine/Viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ class Viewport {
this._suppressCameraModifiedEvents = false
}

protected setCameraNoEvent(camera: ICamera) {
protected setCameraNoEvent(camera: ICamera): void {
this._suppressCameraModifiedEvents = true
this.setCamera(camera)
this._suppressCameraModifiedEvents = false
Expand Down Expand Up @@ -621,7 +621,7 @@ class Viewport {
//
// Compensating for the flipped viewport. Since our method for flipping is
// flipping the actor matrix itself, the focal point won't change; therefore,
// we need to accomodate for this required change elsewhere
// we need to accommodate for this required change elsewhere
// vec3.sub(dir, viewport.applyFlipTx(focalPoint), point)
position: <Point3>this.applyFlipTx(vtkCamera.getPosition() as Point3),
focalPoint: <Point3>this.applyFlipTx(vtkCamera.getFocalPoint() as Point3),
Expand Down
4 changes: 4 additions & 0 deletions packages/cornerstone-render/src/types/Plane.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Plane equation Ax+By+Cz=D, plane is defined by [A, B, C, D]
type Plane = [number, number, number, number]

export default Plane
2 changes: 2 additions & 0 deletions packages/cornerstone-render/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type Orientation from './Orientation'
import type Point2 from './Point2'
import type Point3 from './Point3'
import type Point4 from './Point4'
import type Plane from './Plane'
import type IStreamingImageVolume from './IStreamingImageVolume'
import type ViewportInputOptions from './ViewportInputOptions'
import type IImageData from './IImageData'
Expand Down Expand Up @@ -85,6 +86,7 @@ export type {
Point2,
Point3,
Point4,
Plane,
ViewportInputOptions,
VOIRange,
VOI,
Expand Down
52 changes: 45 additions & 7 deletions packages/cornerstone-render/src/utilities/planar.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { Point3 } from '../types'
import { Point3, Plane } from '../types'
import { vec3, mat3 } from 'gl-matrix'

/**
* It calculates the intersection of a line and a plane.
* Plane equation is Ax+By+Cz=D
* @param p0 [x,y,z] of the first point of the line
* @param p1 [x,y,z] of the second point of the line
* @param plane [A, B, C, D] Plane parameter
* @param plane [A, B, C, D] Plane parameter: Ax+By+Cz=D
* @returns [X,Y,Z] coordinates of the intersection
*/
function linePlaneIntersection(
p0: Point3,
p1: Point3,
plane: [number, number, number, number]
): Point3 {
function linePlaneIntersection(p0: Point3, p1: Point3, plane: Plane): Point3 {
const [x0, y0, z0] = p0
const [x1, y1, z1] = p1
const [A, B, C, D] = plane
Expand All @@ -27,8 +24,49 @@ function linePlaneIntersection(
return [X, Y, Z]
}

/**
*
* @param normal normal vector
* @param point a point on the plane
* @returns [A, B,C, D] of plane equation A*X + B*Y + C*Z = D
*/
function planeEquation(normal: Point3, point: Point3 | vec3): Plane {
const [A, B, C] = normal
const D = A * point[0] + B * point[1] + C * point[2]
return [A, B, C, D]
}

/**
* Computes the intersection of three planes in 3D space with equations:
* A1*X + B1*Y + C1*Z = D1
* A2*X + B2*Y + C2*Z = D2
* A3*X + B3*Y + C3*Z = D3
* @returns {x, y, z} the intersection in the world coordinate
*/
function threePlaneIntersection(
firstPlane: Plane,
secondPlane: Plane,
thirdPlane: Plane
): Point3 {
const [A1, B1, C1, D1] = firstPlane
const [A2, B2, C2, D2] = secondPlane
const [A3, B3, C3, D3] = thirdPlane
const m0 = mat3.fromValues(A1, A2, A3, B1, B2, B3, C1, C2, C3)
const m1 = mat3.fromValues(D1, D2, D3, B1, B2, B3, C1, C2, C3)
const m2 = mat3.fromValues(A1, A2, A3, D1, D2, D3, C1, C2, C3)
const m3 = mat3.fromValues(A1, A2, A3, B1, B2, B3, D1, D2, D3)

// TODO: handle no intersection scenario
const x = mat3.determinant(m1) / mat3.determinant(m0)
const y = mat3.determinant(m2) / mat3.determinant(m0)
const z = mat3.determinant(m3) / mat3.determinant(m0)
return [x, y, z]
}

const planar = {
linePlaneIntersection,
planeEquation,
threePlaneIntersection,
}

export default planar
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ const onCameraModified = function (evt) {
Enabled,
])

// todo: this will trigger crosshair tool onCameraModified in cases
// where crosshair is not active, shall we only filter active?
enabledTools.forEach((tool) => {
if (tool.onCameraModified) {
tool.onCameraModified(evt)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ToolBindings } from '../../enums'
import { ToolBindings, ToolModes } from '../../enums'
import { getRenderingEngine } from '@ohif/cornerstone-render'
import { state } from '../index'
import IToolGroup from './IToolGroup'
import ISetToolModeOptions from '../../types/ISetToolModeOptions'
import ToolModes from '../../enums/ToolModes'
import deepmerge from '../../util/deepMerge'

import { MouseCursor, SVGMouseCursor } from '../../cursors'
import { initElementCursor } from '../../cursors/elementCursor'

Expand Down Expand Up @@ -154,6 +154,10 @@ function createToolGroup(toolGroupId: string): IToolGroup | undefined {
if (this.isPrimaryButtonBinding(toolModeOptions)) {
this.resetViewportsCursor(this._toolInstances[toolName])
}

if (typeof this._toolInstances[toolName].init === 'function') {
this._toolInstances[toolName].init(this.viewports)
}
this.refreshViewports()
},
setToolPassive: function (
Expand Down
Loading

0 comments on commit f064a37

Please sign in to comment.