Compare commits

..
Author SHA1 Message Date
ohif-bot 522531cc5c chore(version): Update package versions [skip ci] 2025-08-05 13:48:31 +00:00
ohif-bot 8c89d9472c chore(version): version.json [skip ci] 2025-08-05 13:48:23 +00:00
Alireza Sedghi 9d94e26d5d chore: release 3p11 2025-08-05 09:39:33 -04:00
959 changed files with 12798 additions and 53393 deletions

No files matched your search

+11 -39
View File
@@ -15,13 +15,22 @@ defaults: &defaults
commands:
install_bun:
steps:
- restore_cache:
keys:
- bun-cache-v2-{{ arch }}-latest
- run:
name: Install Bun
command: |
curl -fsSL https://bun.sh/install | bash -s "bun-v1.2.23"
if [ ! -d "$HOME/.bun" ]; then
curl -fsSL https://bun.sh/install | bash
fi
echo 'export BUN_INSTALL="$HOME/.bun"' >> $BASH_ENV
echo 'export PATH="$BUN_INSTALL/bin:$PATH"' >> $BASH_ENV
source $BASH_ENV
- save_cache:
key: bun-cache-v2-{{ arch }}-latest
paths:
- ~/.bun
jobs:
UNIT_TESTS:
@@ -112,38 +121,6 @@ jobs:
- checkout
- attach_workspace:
at: ~/repo
# SECURITY AUDIT
- run:
name: 'Security Audit - High Risk Vulnerabilities'
command: |
echo "🔍 Running bun audit for security vulnerabilities..."
echo "Checking for HIGH-RISK vulnerabilities..."
# Ignore CVE-2025-64756 (aka GHSA-5j98-mcp5-4vw2) - glob is not used on the command line
if bun audit --ignore=GHSA-5j98-mcp5-4vw2 --audit-level high; then
echo "✅ No high-risk vulnerabilities found"
echo "🎉 Security audit passed!"
else
echo ""
echo "❌ HIGH-RISK VULNERABILITIES DETECTED!"
echo "======================================"
echo ""
echo "🔧 To fix these issues:"
echo " 1. Run: bun audit"
echo " 2. Review the vulnerability details"
echo " 3. Update affected packages to secure versions"
echo " 4. Test your changes"
echo " 5. Re-run: bun audit --audit-level high"
echo ""
echo "📋 Full audit report:"
# Ignore CVE-2025-64756 (aka GHSA-5j98-mcp5-4vw2) - glob is not used on the command line
bun audit --ignore=GHSA-5j98-mcp5-4vw2 --audit-level low || true
echo ""
echo "❌ This build cannot proceed until high-risk vulnerabilities are resolved."
exit 1
fi
- run:
name: Install Dependencies
command: bun install --frozen-lockfile
@@ -375,7 +352,7 @@ jobs:
name: Export Display Variable
command: export DISPLAY=:99
- cypress/install:
install-command: yarn install --frozen-lockfile --no-save
install-command: yarn install --no-save
- cypress/run-tests:
cypress-command: |
npx wait-on@latest http://localhost:3000 && cd platform/app && npx cypress run --record --parallel
@@ -478,13 +455,8 @@ workflows:
filters:
branches:
only: master
# - HOLD_FOR_APPROVAL:
# type: approval
# requires:
# - BUILD
- NPM_PUBLISH:
requires:
# - HOLD_FOR_APPROVAL
- BUILD
- DOCKER_BETA_PUBLISH:
requires:
+21 -22
View File
@@ -51,29 +51,28 @@ body:
validations:
required: true
- type: textarea
id: system_info
- type: input
id: os
attributes:
label: 'System Information'
description: 'Please run the following command in your terminal and paste the output:'
placeholder: |
Run: npx envinfo --system --binaries --browsers
Then paste the output here. It should look something like:
System:
OS: Windows 10 10.0.19042
CPU: (8) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 15.89 GB / 31.74 GB
Shell: 1.0.0 - C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe
Binaries:
Node: 20.18.1 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.22 - C:\Users\user\AppData\Roaming\npm\yarn.CMD
npm: 10.8.2 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 83.0.4103.116
Edge: Spartan (44.19041.1266.0), Chromium (83.0.478.58)
Firefox: 77.0.1
label: 'OS'
description: 'Your operating system.'
placeholder: 'e.g., Windows 10, macOS 10.15.4'
validations:
required: true
- type: input
id: node-version
attributes:
label: 'Node version'
description: 'Your Node.js version.'
placeholder: 'e.g., 20.18.1'
validations:
required: true
- type: input
id: browser
attributes:
label: 'Browser'
description: 'Your browser.'
placeholder: 'e.g., Chrome 83.0.4103.116, Firefox 77.0.1, Safari 13.1.1'
validations:
required: true
-2
View File
@@ -23,8 +23,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.23
- uses: actions/setup-node@v4
with:
node-version: 20 # Or your desired Node version
+1 -3
View File
@@ -1,7 +1,7 @@
name: Playwright Tests
on:
pull_request:
branches: [master, release/*]
branches: [master]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -18,8 +18,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.23
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
+1 -1
View File
@@ -19,7 +19,7 @@ echo 'Web application built and copied'
# Build && Move Docusaurus Output (for the docs themselves)
cd platform/docs
yarn install --frozen-lockfile
yarn install
yarn run build
cd ../..
mkdir -p ./.netlify/www/docs
+1 -1
View File
@@ -10,6 +10,6 @@
"deploy": "netlify deploy --prod --dir ./../platform/app/dist"
},
"devDependencies": {
"netlify-cli": "2.21.0"
"netlify-cli": "^2.21.0"
}
}
+2
View File
@@ -201,6 +201,8 @@ module.exports = (env, argv, { SRC_DIR, ENTRY }) => {
'@hooks': path.resolve(__dirname, '../platform/app/src/hooks'),
'@routes': path.resolve(__dirname, '../platform/app/src/routes'),
'@state': path.resolve(__dirname, '../platform/app/src/state'),
'dicom-microscopy-viewer':
'dicom-microscopy-viewer/dist/dynamic-import/dicomMicroscopyViewer.min.js',
},
// Which directories to search when resolving modules
modules: [
+1 -954
View File
@@ -3,960 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
### Features
* tooltips for tool settings ([#5586](https://github.com/OHIF/Viewers/issues/5586)) ([411553e](https://github.com/OHIF/Viewers/commit/411553ee916b8a63b2a934a7e1274bc449041016))
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
### Bug Fixes
* **docs:** Empty commit as an attempt to fix the docs build. ([#5582](https://github.com/OHIF/Viewers/issues/5582)) ([94b0358](https://github.com/OHIF/Viewers/commit/94b0358f18f81fa2822a208d68decfce076ef577))
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
### Bug Fixes
* **DicomUpload:** Switch to use ui-next components and colors ([#5576](https://github.com/OHIF/Viewers/issues/5576)) ([62d6bf4](https://github.com/OHIF/Viewers/commit/62d6bf437b167ac3e60a0f134869c9f96d199d0f))
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
### Bug Fixes
* Remove dead code and fix rectangle roi rehydration ([#5490](https://github.com/OHIF/Viewers/issues/5490)) ([9ca02b4](https://github.com/OHIF/Viewers/commit/9ca02b4071f77600f7dcd87930fecdcf3d1c249f))
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
### Bug Fixes
* **SegmentationStyle:** Fix inactive contour visibility and styling. ([#5563](https://github.com/OHIF/Viewers/issues/5563)) ([5c17c26](https://github.com/OHIF/Viewers/commit/5c17c262eaa5c1229033cfff4b3e7709e874611f))
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
### Bug Fixes
* **segmentation:** Allow for manually added label map and contour segmentations to be used as viewport data overlays. ([#5562](https://github.com/OHIF/Viewers/issues/5562)) ([02f6744](https://github.com/OHIF/Viewers/commit/02f6744dab993f16cf2516fd5f657e0743e3fa42))
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
### Bug Fixes
* **interpolation:** Auto accept interpolation when the interpolation process is completed. ([#5555](https://github.com/OHIF/Viewers/issues/5555)) ([834ae3c](https://github.com/OHIF/Viewers/commit/834ae3c762ca309187afebdf77bad1ad9a57f03f))
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
### Bug Fixes
* **dev:** update webpack proxy config syntax for Orthanc dev mode ([#5531](https://github.com/OHIF/Viewers/issues/5531)) ([58aa0d1](https://github.com/OHIF/Viewers/commit/58aa0d1eaae2e1a8103e6096864a4e5d7baf090e))
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
### Features
* **metadata:** metadata access improvement ([#5292](https://github.com/OHIF/Viewers/issues/5292)) ([16233d9](https://github.com/OHIF/Viewers/commit/16233d980f17abfc30461b46c6b1888be10c7840))
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
### Bug Fixes
* **segmentation:** When synchronizing a segmentation representation, use the type of the source viewport segmentation to determine the type of the target viewport segmentation ([#5546](https://github.com/OHIF/Viewers/issues/5546)) ([a0556b0](https://github.com/OHIF/Viewers/commit/a0556b08be98e0bba950ad7b9b575d7b971104ba))
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
### Bug Fixes
* **SegmentationTools:** [Bug] Changes of brush/eraser radius with hotkey do not reflect on segmentation tool ([#5535](https://github.com/OHIF/Viewers/issues/5535)) ([29bd87c](https://github.com/OHIF/Viewers/commit/29bd87c8c0592a9a1350e687b862f5452627aece))
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
### Bug Fixes
* **security:** Exact versioning and docs dependabot alerts ([#5536](https://github.com/OHIF/Viewers/issues/5536)) ([000e42e](https://github.com/OHIF/Viewers/commit/000e42e9a6eaa4f0878cbf877f03b09a459ad18e))
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
### Bug Fixes
* **3DSegmentation:** [Bug] The viewports become blank when loading the seg file in advanced layout after closing the seg file from any other advanced layout ([#5505](https://github.com/OHIF/Viewers/issues/5505)) ([76f7d4e](https://github.com/OHIF/Viewers/commit/76f7d4e23aa359a3397b10adf0bf09df3763f190))
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
### Bug Fixes
* **security:** Addressed dependabot alert CVE-2025-59288 concerning playwright ([#5527](https://github.com/OHIF/Viewers/issues/5527)) ([1f11c83](https://github.com/OHIF/Viewers/commit/1f11c83006bff98cb8434f0662b4de55d5b9bf78))
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
### Bug Fixes
* **security:** For bun, enforce frozen lockfile. For yarn, strongly suggest using frozen lockfile. ([#5508](https://github.com/OHIF/Viewers/issues/5508)) ([1009c60](https://github.com/OHIF/Viewers/commit/1009c6091107d2db0768622120f916208a391343))
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
### Features
* **jpeg2000:** Add 16-bit RGB support to JPEG2000 decoder ([#5519](https://github.com/OHIF/Viewers/issues/5519)) ([a154443](https://github.com/OHIF/Viewers/commit/a1544432db42bf77864bb7df2f757cae819a4b4d))
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
### Bug Fixes
* Fixed the tooltip text of the window button, it was mistakenly written in Chinese in the en-us json ([#5513](https://github.com/OHIF/Viewers/issues/5513)) ([8b9445c](https://github.com/OHIF/Viewers/commit/8b9445c442d0a40b7e4393614313192bd006461b))
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
### Bug Fixes
* **segmentation:** Fixed the manual scrolling of the segments list and implemented automatic scrolling to the active segment. ([#5510](https://github.com/OHIF/Viewers/issues/5510)) ([1df4f84](https://github.com/OHIF/Viewers/commit/1df4f843fe3c377643938563ff9e2e4f930d8537))
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
### Bug Fixes
* **rendering:** Fix palette color LUT conversion causing black images ([#5509](https://github.com/OHIF/Viewers/issues/5509)) ([ffd9ec3](https://github.com/OHIF/Viewers/commit/ffd9ec32730580e266ffae365a10ac3e524dd6cf))
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
### Bug Fixes
* Pass the correct sop uid + frame for rehydration to prevent associating rehydrated measurements with the wrong data ([#5506](https://github.com/OHIF/Viewers/issues/5506)) ([5037802](https://github.com/OHIF/Viewers/commit/503780247ce7228c602a539fd88ea374e7d0d42f)), closes [#2404](https://github.com/OHIF/Viewers/issues/2404)
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
### Bug Fixes
* **segmentation:** Lock all rehydrated segmentation segments when panelSegmentation.disableEditing is true. ([#5503](https://github.com/OHIF/Viewers/issues/5503)) ([170e860](https://github.com/OHIF/Viewers/commit/170e860aa1b786ab6056cf31076804302a2bc462))
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
### Bug Fixes
* **ErrorBoundary:** Allow for details to be shown in production. ([#5504](https://github.com/OHIF/Viewers/issues/5504)) ([4620cc3](https://github.com/OHIF/Viewers/commit/4620cc3acf89f218c3feaaf4c153a3dc8b023b23))
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
### Bug Fixes
* **docker:** Use bun version 1.2.23 for docker build. ([#5501](https://github.com/OHIF/Viewers/issues/5501)) ([86e924f](https://github.com/OHIF/Viewers/commit/86e924fb88cc146f91c7d826ee071e451de47942))
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
### Bug Fixes
* Segmentation not displayed and unable to draw segments in volume viewport after converting Labelmap to Surface ([#5488](https://github.com/OHIF/Viewers/issues/5488)) ([faea09e](https://github.com/OHIF/Viewers/commit/faea09e7ef2667aad5cef1efc2a6516677ca2915))
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
### Bug Fixes
* **segmentationService:** prevent no representation crash ([#5495](https://github.com/OHIF/Viewers/issues/5495)) ([3137aed](https://github.com/OHIF/Viewers/commit/3137aed0170196a61e16c6dac0c15bcc41691919))
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
### Bug Fixes
* **docs:** Set exact version for glob. ([#5497](https://github.com/OHIF/Viewers/issues/5497)) ([0d2f4e7](https://github.com/OHIF/Viewers/commit/0d2f4e715a941fa458ebf8e64972088580a04952))
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
### Bug Fixes
* **security:** Run bun audit before bun install. ([#5496](https://github.com/OHIF/Viewers/issues/5496)) ([fbd9371](https://github.com/OHIF/Viewers/commit/fbd9371884d0e87376d67eb98c17a4d62e4e6dd1))
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
### Bug Fixes
* **bun:** Use fixed bun version ([#5493](https://github.com/OHIF/Viewers/issues/5493)) ([3fe67d5](https://github.com/OHIF/Viewers/commit/3fe67d5c98a22edc32cb0d3de5edc05b722dd68e))
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
### Bug Fixes
* Update Dockerfile ([#5484](https://github.com/OHIF/Viewers/issues/5484)) ([41c0287](https://github.com/OHIF/Viewers/commit/41c028781b80f0ca80f4d6cde3ca8e7958f1baed))
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
### Bug Fixes
* **segmentation:** Segmentation not displayed and unable to draw segments when switching back to volume/stack viewport from 3D viewport ([#5430](https://github.com/OHIF/Viewers/issues/5430)) ([78df8ff](https://github.com/OHIF/Viewers/commit/78df8ff03a371904a390c63a95628d5511dad136))
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
### Bug Fixes
* validation for Percentage of Max SUV input field in TMTV module ([#5417](https://github.com/OHIF/Viewers/issues/5417)) ([5040c94](https://github.com/OHIF/Viewers/commit/5040c947d2f47e5ec66285fa353e3e0ffd127ba7))
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
### Bug Fixes
* **Segmentation:** [Bug [#5420](https://github.com/OHIF/Viewers/issues/5420)] Segmentation color resets after using toggleOneUp ([#5465](https://github.com/OHIF/Viewers/issues/5465)) ([2c6ce21](https://github.com/OHIF/Viewers/commit/2c6ce21c8f79f8b3e6dc47b5aa6f717b6b5cbd2a))
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
### Bug Fixes
* **measurementTrackingMachine:** remove unreachable states ([#5460](https://github.com/OHIF/Viewers/issues/5460)) ([7f12f39](https://github.com/OHIF/Viewers/commit/7f12f398fb145a31e5557dbee51c0a9b0f40a35b))
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
### Bug Fixes
* **toolbar:** prevent duplicate command execution on repeated interactions ([#5456](https://github.com/OHIF/Viewers/issues/5456)) ([4d04dd5](https://github.com/OHIF/Viewers/commit/4d04dd5651f4cf8dcaf4732baee5e218e92bd3c1))
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
### Bug Fixes
* viewport ready event firing logic ([#5462](https://github.com/OHIF/Viewers/issues/5462)) ([d2ae13b](https://github.com/OHIF/Viewers/commit/d2ae13b03f21e3ab9545d50d7403ec52004bfbfc))
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
### Bug Fixes
* **router:** opt in to React Router v7 future flags ([#5461](https://github.com/OHIF/Viewers/issues/5461)) ([e2964bf](https://github.com/OHIF/Viewers/commit/e2964bf66947d18af06f292d9395b465545fdf9d))
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
### Bug Fixes
* Safely handle missing active viewport ([#5448](https://github.com/OHIF/Viewers/issues/5448)) ([792db26](https://github.com/OHIF/Viewers/commit/792db26ff1591f9e054486f1bee01c422e774101))
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
### Features
* **MeasurementService:** add rendering of unmapped measurements ([#5416](https://github.com/OHIF/Viewers/issues/5416)) ([851e74d](https://github.com/OHIF/Viewers/commit/851e74d7b867a806befb5d85fd71ff9a75e9f2d2))
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
### Bug Fixes
* duplicate segmentation entries on layout switch ([#5458](https://github.com/OHIF/Viewers/issues/5458)) ([9e951e8](https://github.com/OHIF/Viewers/commit/9e951e88005af505ae0c07fbcd3366de12b773dd))
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
### Bug Fixes
* study browser mode for multiple studies ([#5457](https://github.com/OHIF/Viewers/issues/5457)) ([6a1df9d](https://github.com/OHIF/Viewers/commit/6a1df9de4ad3c10a4653f18e03aff6bda4962fd1))
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
### Bug Fixes
* **studyBrowserCustomization:** fix thumbnail menu item actions in study browser ([#5283](https://github.com/OHIF/Viewers/issues/5283)) ([2f28a0d](https://github.com/OHIF/Viewers/commit/2f28a0deab5e43f432bbd9b5989928c9b0450278))
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
### Features
* Add inherit from basic/longitudinal modes ([#5435](https://github.com/OHIF/Viewers/issues/5435)) ([9ad0d7f](https://github.com/OHIF/Viewers/commit/9ad0d7fc8cf34867fa2cfc2bf2b2f63451ec03e5))
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
### Bug Fixes
* **segmentation:** Restored segment label tool in longitudinal mode. ([#5443](https://github.com/OHIF/Viewers/issues/5443)) ([dd86a8e](https://github.com/OHIF/Viewers/commit/dd86a8eabd0712d25e7652a242377fe09597e8d5))
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
### Bug Fixes
* **security:** Removed dependency on tar-fs by removing dependencies on storybook and sharp. ([#5438](https://github.com/OHIF/Viewers/issues/5438)) ([80f314a](https://github.com/OHIF/Viewers/commit/80f314a422ec45fff6cdd5869f4293a110d00125))
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
### Bug Fixes
* Improve rt handling for bulkdata ([#5415](https://github.com/OHIF/Viewers/issues/5415)) ([d88a341](https://github.com/OHIF/Viewers/commit/d88a341884f7361865bc10159c1a82633667ab5b))
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
### Bug Fixes
* **i18n:** Add and update i18n Translation for Toolbar Tool Names ([#5392](https://github.com/OHIF/Viewers/issues/5392)) ([7783d0f](https://github.com/OHIF/Viewers/commit/7783d0f558bbb7016c29513b6fe76ed069dbd75c))
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
### Features
* **Segmentation:** Segmentation highlight animation function selection ([#5401](https://github.com/OHIF/Viewers/issues/5401)) ([69dbe27](https://github.com/OHIF/Viewers/commit/69dbe2778493cdfc7a8da5e757c95217bb31edc2))
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
### Bug Fixes
* **SegmentationService:** _getSegmentCenter wrongly handling seg center availability ([#5396](https://github.com/OHIF/Viewers/issues/5396)) ([74b82bd](https://github.com/OHIF/Viewers/commit/74b82bd93442411ad68f4872992126c40321eb9e))
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
### Bug Fixes
* **ErrorBoundary:** Fixing console errors and Improving error logging for better developer experience ([#5378](https://github.com/OHIF/Viewers/issues/5378)) ([56c5828](https://github.com/OHIF/Viewers/commit/56c5828b02d53bfd17182bb8d0c126b7cd4f400e))
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
### Bug Fixes
* **cornerstone-dicom-rt:** adding caching usage to cornerstone-dicom-rt SOP Class Handler ([#5387](https://github.com/OHIF/Viewers/issues/5387)) ([d6ea179](https://github.com/OHIF/Viewers/commit/d6ea179ac43a47d4011b8dcaf59d79d99382d6c8))
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
### Bug Fixes
* **oidc:** resolve navigation throttling and blank screen during sign-in/sign-out with Keycloak + dcm4chee + Traefik ([#5373](https://github.com/OHIF/Viewers/issues/5373)) ([79473c2](https://github.com/OHIF/Viewers/commit/79473c2ea4196b758614480860a8c596730b4147))
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
### Bug Fixes
* routerBasename declaration location ([#5347](https://github.com/OHIF/Viewers/issues/5347)) ([0f6f2bb](https://github.com/OHIF/Viewers/commit/0f6f2bb432d7021d3a92b38b58de51a380d9b0c9))
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
### Bug Fixes
* seg preview ([#5338](https://github.com/OHIF/Viewers/issues/5338)) ([d91cc23](https://github.com/OHIF/Viewers/commit/d91cc230e5231ca32ee28736f661a1497f7834c5))
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
### Bug Fixes
* docker deploy ([#5359](https://github.com/OHIF/Viewers/issues/5359)) ([368a176](https://github.com/OHIF/Viewers/commit/368a176c093aa2ccf4197c46543209d5ff69939a))
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
### Bug Fixes
* Docker build failure due to missing lerna command ([#5357](https://github.com/OHIF/Viewers/issues/5357)) ([bedb185](https://github.com/OHIF/Viewers/commit/bedb1854f96928f6db5707dce74ea75b1445e9bd))
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
### Bug Fixes
* local ModalitiesInStudy check ([#5285](https://github.com/OHIF/Viewers/issues/5285)) ([d269404](https://github.com/OHIF/Viewers/commit/d2694048a47faf9028184d0272df12e2602ae674))
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
### Bug Fixes
* add back clear segmentation representations ([#5336](https://github.com/OHIF/Viewers/issues/5336)) ([21d6ba2](https://github.com/OHIF/Viewers/commit/21d6ba2bb30df5b99bf5728163caff514aaa5dcd))
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
### Bug Fixes
* Segmentation stats customization module ([#5324](https://github.com/OHIF/Viewers/issues/5324)) ([b9d6f55](https://github.com/OHIF/Viewers/commit/b9d6f558cbe5957f83e6d92305a78662a0b186ed))
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
### Bug Fixes
* Add seriesInstanceUID fallback for callByRetrieveAETitle ([#5332](https://github.com/OHIF/Viewers/issues/5332)) ([840b5d3](https://github.com/OHIF/Viewers/commit/840b5d37d15537abc38316d636da7c144e6d9223))
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
### Features
* Jump to measurement moves the camera if it is not in the viewport ([#5023](https://github.com/OHIF/Viewers/issues/5023)) ([6fe9df6](https://github.com/OHIF/Viewers/commit/6fe9df6ec93c0f37e3bb9f8bf6425bae025e75c8))
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
### Bug Fixes
* header icon logic ([#5339](https://github.com/OHIF/Viewers/issues/5339)) ([a2133ef](https://github.com/OHIF/Viewers/commit/a2133ef6cb6e47fad22908fb1338ee57c67eb8f8))
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
### Bug Fixes
* load 3dsr ([#5335](https://github.com/OHIF/Viewers/issues/5335)) ([becba78](https://github.com/OHIF/Viewers/commit/becba7861f99ae4e190caddea8b663e60a9883f5))
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
### Features
* **orientationMarkers:** improved the orientation markers with a simplified version ([#5328](https://github.com/OHIF/Viewers/issues/5328)) ([266b1f5](https://github.com/OHIF/Viewers/commit/266b1f58f01ac6742a9bb40dda28459e7cddc683))
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
### Bug Fixes
* Update Dockerfile ([#5319](https://github.com/OHIF/Viewers/issues/5319)) ([0e83f45](https://github.com/OHIF/Viewers/commit/0e83f4515c902ffa3dbab2d68ec81b93881e1768))
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
### Bug Fixes
* Guard series.instances in DicomJSONDataSource to prevent TypeError (OHI-2114) ([#5312](https://github.com/OHIF/Viewers/issues/5312)) ([f1d158b](https://github.com/OHIF/Viewers/commit/f1d158bbe81fd9f6052ce23c8588c9c93d76360c))
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package ohif-monorepo-root
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package ohif-monorepo-root
+3 -4
View File
@@ -49,8 +49,8 @@ RUN apt-get update && apt-get install -y build-essential python3
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
RUN npm install -g bun@1.2.23
RUN npm install -g lerna@7.4.2
RUN npm install -g bun
# RUN npm install -g lerna@7.4.2
ENV PATH=/usr/src/app/node_modules/.bin:$PATH
# Do an initial install and then a final install
@@ -60,7 +60,6 @@ COPY --parents ./addOns/package.json ./addOns/*/*/package.json ./extensions/*/pa
RUN bun pm cache rm
RUN bun install
RUN bun add ajv@8.12.0
# Copy the local directory
COPY --link --exclude=yarn.lock --exclude=package.json --exclude=Dockerfile . .
@@ -99,7 +98,7 @@ COPY --from=builder /usr/src/app/platform/app/dist/dicom-microscopy-viewer /usr/
# In entrypoint.sh, app-config.js might be overwritten, so chmod it to be writeable.
# The nginx user cannot chmod it, so change to root.
USER root
RUN chown -R nginx:nginx /usr/share/nginx/html && chmod -R 777 /usr/share/nginx/html
RUN chown -R nginx:nginx /usr/share/nginx/html
USER nginx
ENTRYPOINT ["/usr/src/entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
+4 -11
View File
@@ -53,7 +53,7 @@ provided by the <a href="https://ohif.org/">Open Health Imaging Foundation (OHIF
## About
The OHIF Viewer can retrieve
and load images from most sources and formats, render sets in 2D, 3D, and
and load images from most sources and formats; render sets in 2D, 3D, and
reconstructed representations; allows for the manipulation, annotation, and
serialization of observations; supports internationalization, OpenID Connect,
offline use, hotkeys, and many more features.
@@ -76,7 +76,7 @@ contributions of individuals, research groups, and commercial organizations.
After more than 8-years of integrating with many companies and organizations,
The OHIF Viewer has been rebuilt from the ground up to better address the
varying workflow and configuration needs of its many users. All of the Viewer's
core features are built using its own extension system. The same extensibility
core features are built using it's own extension system. The same extensibility
that allows us to offer:
- 2D and 3D medical image viewing
@@ -147,14 +147,7 @@ Here is a schematic representation of our development workflow:
3. Navigate to the cloned project's directory
4. Add this repo as a `remote` named `upstream`
- `git remote add upstream https://github.com/OHIF/Viewers.git`
5. `yarn install --frozen-lockfile` to restore dependencies and link projects
:::danger
In general run `yarn install` with the `--frozen-lockfile` flag to help avoid
supply chain attacks by enforcing reproducible dependencies. That is, if the
`yarn.lock` file is clean and does NOT reference compromised packages, then
no compromised packages should land on your machine by using this flag.
:::
5. `yarn install` to restore dependencies and link projects
#### To Develop
@@ -165,7 +158,7 @@ _From this repository's root directory:_
yarn config set workspaces-experimental true
# Restore dependencies
yarn install --frozen-lockfile
yarn install
```
## Commands
+1 -759
View File
@@ -3,765 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
### Bug Fixes
* **security:** Removed dependency on tar-fs by removing dependencies on storybook and sharp. ([#5438](https://github.com/OHIF/Viewers/issues/5438)) ([80f314a](https://github.com/OHIF/Viewers/commit/80f314a422ec45fff6cdd5869f4293a110d00125))
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @externals/devDependencies
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package @externals/devDependencies
+67 -67
View File
@@ -1,7 +1,7 @@
{
"name": "@externals/devDependencies",
"description": "External dev dependencies - put dev build dependencies here",
"version": "3.12.0-beta.94",
"version": "3.11.0",
"license": "MIT",
"private": true,
"engines": {
@@ -9,85 +9,85 @@
"yarn": ">=1.19.1"
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@babel/runtime": "^7.20.13",
"@kitware/vtk.js": "32.12.0",
"clsx": "2.1.1",
"core-js": "3.45.1",
"moment": "2.30.1"
"clsx": "^2.1.1",
"core-js": "^3.2.1",
"moment": "^2.30.1"
},
"peerDependencies": {
"react": "18.3.1",
"react-dom": "18.3.1"
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@babel/eslint-parser": "7.28.0",
"@pmmmwh/react-refresh-webpack-plugin": "0.5.17",
"@rsbuild/core": "1.5.1",
"@rsbuild/plugin-node-polyfill": "1.4.2",
"@rsbuild/plugin-react": "1.4.0",
"@svgr/webpack": "8.1.0",
"@swc/helpers": "0.5.17",
"@types/jest": "27.5.2",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"autoprefixer": "10.4.21",
"babel-loader": "8.4.1",
"babel-plugin-module-resolver": "5.0.2",
"clean-webpack-plugin": "3.0.0",
"copy-webpack-plugin": "9.1.0",
"cross-env": "7.0.3",
"css-loader": "6.11.0",
"dotenv": "8.6.0",
"eslint": "8.57.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
"@rsbuild/core": "^1.3.16",
"@rsbuild/plugin-node-polyfill": "^1.3.0",
"@rsbuild/plugin-react": "^1.3.1",
"@svgr/webpack": "^8.1.0",
"@swc/helpers": "^0.5.15",
"@types/jest": "^27.5.0",
"@typescript-eslint/eslint-plugin": "^6.3.0",
"@typescript-eslint/parser": "^6.3.0",
"autoprefixer": "^10.4.4",
"babel-loader": "^8.2.4",
"babel-plugin-module-resolver": "^5.0.0",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^9.0.1",
"cross-env": "^5.2.0",
"css-loader": "^6.8.1",
"dotenv": "^8.1.0",
"eslint": "^8.39.0",
"eslint-config-prettier": "7.2.0",
"eslint-config-react-app": "6.0.0",
"eslint-plugin-cypress": "2.15.2",
"eslint-plugin-flowtype": "7.0.0",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-jsx-a11y": "6.10.2",
"eslint-plugin-node": "11.1.0",
"eslint-config-react-app": "^6.0.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-flowtype": "^7.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "5.5.1",
"eslint-plugin-promise": "5.2.0",
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-tsdoc": "0.2.17",
"eslint-webpack-plugin": "2.7.0",
"execa": "8.0.1",
"extract-css-chunks-webpack-plugin": "4.10.0",
"html-webpack-plugin": "5.6.3",
"husky": "3.1.0",
"jest": "29.7.0",
"jest-canvas-mock": "2.5.2",
"jest-environment-jsdom": "29.7.0",
"jest-junit": "6.4.0",
"lerna": "7.4.2",
"lint-staged": "9.5.0",
"mini-css-extract-plugin": "2.9.2",
"optimize-css-assets-webpack-plugin": "6.0.1",
"postcss": "8.5.6",
"postcss-import": "14.1.0",
"postcss-loader": "6.2.1",
"postcss-preset-env": "7.8.3",
"eslint-plugin-promise": "^5.2.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react-hooks": "^4.4.0",
"eslint-plugin-tsdoc": "^0.2.11",
"eslint-webpack-plugin": "^2.5.3",
"execa": "^8.0.1",
"extract-css-chunks-webpack-plugin": "^4.5.4",
"html-webpack-plugin": "^5.3.2",
"husky": "^3.0.0",
"jest": "^29.5.0",
"jest-canvas-mock": "^2.1.0",
"jest-environment-jsdom": "^29.5.0",
"jest-junit": "^6.4.0",
"lerna": "^7.2.0",
"lint-staged": "^9.0.2",
"mini-css-extract-plugin": "^2.1.0",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"postcss": "^8.3.5",
"postcss-import": "^14.0.2",
"postcss-loader": "^6.1.1",
"postcss-preset-env": "^7.4.3",
"prettier": "3.6.2",
"prettier-plugin-tailwindcss": "0.6.9",
"react-refresh": "0.14.2",
"semver": "7.7.2",
"serve": "14.2.4",
"shader-loader": "1.3.1",
"shx": "0.3.4",
"source-map-loader": "4.0.2",
"style-loader": "1.3.0",
"terser-webpack-plugin": "5.3.14",
"react-refresh": "^0.14.2",
"semver": "^7.5.1",
"serve": "^14.2.4",
"shader-loader": "^1.3.1",
"shx": "^0.3.3",
"source-map-loader": "^4.0.1",
"style-loader": "^1.0.0",
"terser-webpack-plugin": "^5.1.4",
"typescript": "5.5.4",
"unused-webpack-plugin": "2.4.0",
"webpack": "5.95.0",
"webpack-bundle-analyzer": "4.10.2",
"webpack-cli": "5.1.4",
"webpack": "^5.94.0",
"webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "5.2.2",
"webpack-hot-middleware": "2.26.1",
"webpack-merge": "5.10.0",
"workbox-webpack-plugin": "6.6.1",
"worker-loader": "3.0.8"
"webpack-hot-middleware": "^2.25.0",
"webpack-merge": "^5.7.3",
"workbox-webpack-plugin": "^6.1.5",
"worker-loader": "^3.0.8"
},
"scripts": {
"build": "Included as direct dependency"
+1 -759
View File
@@ -3,765 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package @externals/dicom-microscopy-viewer
+2 -2
View File
@@ -1,9 +1,9 @@
{
"name": "@externals/dicom-microscopy-viewer",
"description": "External reference to dicom-microscopy-viewer",
"version": "3.12.0-beta.94",
"version": "3.11.0",
"license": "MIT",
"dependencies": {
"dicom-microscopy-viewer": "0.48.6"
"dicom-microscopy-viewer": "^0.46.1"
}
}
+20 -19
View File
@@ -22,29 +22,30 @@
},
"devDependencies": {
"@babel/core": "7.28.0",
"@babel/plugin-transform-class-properties": "7.27.1",
"@babel/plugin-transform-object-rest-spread": "7.28.0",
"@babel/plugin-transform-private-methods": "7.27.1",
"@babel/plugin-transform-private-property-in-object": "7.27.1",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@babel/plugin-transform-arrow-functions": "7.27.1",
"@babel/plugin-transform-regenerator": "7.28.1",
"@babel/plugin-transform-class-properties": "^7.27.1",
"@babel/plugin-transform-object-rest-spread": "^7.28.0",
"@babel/plugin-transform-private-methods": "^7.27.1",
"@babel/plugin-transform-private-property-in-object": "^7.27.1",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-arrow-functions": "^7.16.7",
"@babel/plugin-transform-regenerator": "^7.16.7",
"@babel/plugin-transform-runtime": "7.28.0",
"@babel/plugin-transform-typescript": "7.28.0",
"@babel/plugin-transform-typescript": "^7.28.0",
"@babel/preset-env": "7.28.0",
"@babel/preset-react": "7.27.1",
"@babel/preset-typescript": "7.27.1"
"@babel/preset-react": "^7.27.1",
"@babel/preset-typescript": "^7.27.1"
},
"resolutions": {
"**/@babel/runtime": "7.28.2",
"**/@babel/runtime": "^7.20.13",
"commander": "8.3.0",
"dcmjs": "0.45.0",
"dicomweb-client": "0.10.4",
"nth-check": "2.1.1",
"trim-newlines": "5.0.0",
"glob-parent": "6.0.2",
"trim": "1.0.1",
"package-json": "8.1.1",
"typescript": "5.5.4"
"dcmjs": "0.43.1",
"dicomweb-client": ">=0.10.4",
"nth-check": "^2.1.1",
"trim-newlines": "^5.0.0",
"glob-parent": "^6.0.2",
"trim": "^1.0.0",
"package-json": "^8.1.0",
"typescript": "5.5.4",
"sharp": "^0.32.6"
}
}
-1
View File
@@ -35,7 +35,6 @@ module.exports = {
'@babel/plugin-transform-typescript',
'@babel/plugin-transform-class-static-block',
'@babel/plugin-transform-for-of',
['babel-plugin-transform-import-meta', { module: 'ES6' }],
],
},
production: {
+1745 -826
View File
File diff suppressed because it is too large. Load diff
-2
View File
@@ -1,2 +0,0 @@
[install]
frozenLockfile = true
-2
View File
@@ -1,2 +0,0 @@
[install]
frozenLockfile = false
+1 -1
View File
@@ -1 +1 @@
6d6ce0ddae92751957a3b2c0ea9333b482f77be5
9d94e26d5d15ccd19f12020dbc5438364d88d253
+118
View File
@@ -0,0 +1,118 @@
diff --git a/extensions/cornerstone/src/components/ViewportOrientationMenu/ViewportOrientationMenu.tsx b/extensions/cornerstone/src/components/ViewportOrientationMenu/ViewportOrientationMenu.tsx
index 6c1e4f8f6..56dac15b5 100644
--- a/extensions/cornerstone/src/components/ViewportOrientationMenu/ViewportOrientationMenu.tsx
+++ b/extensions/cornerstone/src/components/ViewportOrientationMenu/ViewportOrientationMenu.tsx
@@ -156,65 +156,65 @@ function ViewportOrientationMenu({
>
<Button
variant="ghost"
- className="flex h-[28px] flex-shrink-0 items-center justify-start self-stretch"
+ className="flex h-7 w-full flex-shrink-0 items-center justify-start self-stretch px-1 py-0"
onClick={() => handleOrientationChange('axial')}
>
- <span className="mr-0 flex w-4 items-center justify-center">
+ <div className="mr-1 flex w-6 items-center justify-start">
{currentOrientation === 'axial' ? (
- <Icons.Checked className="text-primary h-5 w-5" />
+ <Icons.Checked className="text-primary h-6 w-6" />
) : null}
- </span>
- <span className="flex-1 text-left">Axial</span>
+ </div>
+ <div className="flex-1 text-left">Axial</div>
</Button>
<Button
variant="ghost"
- className="flex h-[28px] flex-shrink-0 items-center justify-start self-stretch"
+ className="flex h-7 w-full flex-shrink-0 items-center justify-start self-stretch px-1 py-0"
onClick={() => handleOrientationChange('sagittal')}
>
- <span className="mr-0 flex w-4 items-center justify-center">
+ <div className="mr-1 flex w-6 items-center justify-start">
{currentOrientation === 'sagittal' ? (
- <Icons.Checked className="text-primary h-5 w-5" />
+ <Icons.Checked className="text-primary h-6 w-6" />
) : null}
- </span>
- <span className="flex-1 text-left">Sagittal</span>
+ </div>
+ <div className="flex-1 text-left">Sagittal</div>
</Button>
<Button
variant="ghost"
- className="flex h-[28px] flex-shrink-0 items-center justify-start self-stretch"
+ className="flex h-7 w-full flex-shrink-0 items-center justify-start self-stretch px-1 py-0"
onClick={() => handleOrientationChange('coronal')}
>
- <span className="mr-0 flex w-4 items-center justify-center">
+ <div className="mr-1 flex w-6 items-center justify-start">
{currentOrientation === 'coronal' ? (
- <Icons.Checked className="text-primary h-5 w-5" />
+ <Icons.Checked className="text-primary h-6 w-6" />
) : null}
- </span>
- <span className="flex-1 text-left">Coronal</span>
+ </div>
+ <div className="flex-1 text-left">Coronal</div>
</Button>
<Button
variant="ghost"
- className="flex h-[28px] flex-shrink-0 items-center justify-start self-stretch"
+ className="flex h-7 w-full flex-shrink-0 items-center justify-start self-stretch px-1 py-0"
onClick={() => handleOrientationChange('acquisition')}
>
- <span className="mr-0 flex w-4 items-center justify-center">
+ <div className="mr-1 flex w-6 items-center justify-start">
{currentOrientation === 'acquisition' ? (
- <Icons.Checked className="text-primary h-5 w-5" />
+ <Icons.Checked className="text-primary h-6 w-6" />
) : null}
- </span>
- <span className="flex-1 text-left">Acquisition</span>
+ </div>
+ <div className="flex-1 text-left">Acquisition</div>
</Button>
{/* Divider */}
- <div className="my-2 border-t border-white/20" />
+ <div className="mx-1 my-2 border-t border-white/20" />
<Button
variant="ghost"
- className="flex h-[28px] flex-shrink-0 items-center justify-start self-stretch"
+ className="flex h-7 w-full flex-shrink-0 items-center justify-start self-stretch px-1 py-0"
onClick={() => handleOrientationChange('reformat')}
>
- <span className="mr-0 flex w-4 items-center justify-center">
+ <div className="mr-1 flex w-6 items-center justify-start">
{currentOrientation === 'reformat' ? (
- <Icons.Checked className="text-primary h-5 w-5" />
+ <Icons.Checked className="text-primary h-6 w-6" />
) : null}
- </span>
- <span className="flex-1 text-left">Reformat</span>
+ </div>
+ <div className="flex-1 text-left">Reformat</div>
</Button>
</PopoverContent>
</Popover>
diff --git a/platform/ui-next/src/components/Icons/Sources/Checked.tsx b/platform/ui-next/src/components/Icons/Sources/Checked.tsx
index 83c8fc57e..c88b75e0d 100644
--- a/platform/ui-next/src/components/Icons/Sources/Checked.tsx
+++ b/platform/ui-next/src/components/Icons/Sources/Checked.tsx
@@ -4,14 +4,14 @@ import type { IconProps } from '../types';
export const Checked = (props: IconProps) => (
<svg
{...props}
- width="24"
+ width="20"
height="24"
- viewBox="0 0 24 24"
+ viewBox="0 0 20 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
- d="M16 9L11.3333 15L8 12.4737"
+ d="M14 9L9.3333 15L6 12.4737"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
+1 -777
View File
@@ -3,783 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
### Bug Fixes
* **SegmentationStyle:** Fix inactive contour visibility and styling. ([#5563](https://github.com/OHIF/Viewers/issues/5563)) ([5c17c26](https://github.com/OHIF/Viewers/commit/5c17c262eaa5c1229033cfff4b3e7709e874611f))
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
### Bug Fixes
* **interpolation:** Auto accept interpolation when the interpolation process is completed. ([#5555](https://github.com/OHIF/Viewers/issues/5555)) ([834ae3c](https://github.com/OHIF/Viewers/commit/834ae3c762ca309187afebdf77bad1ad9a57f03f))
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
### Bug Fixes
* **SegmentationTools:** [Bug] Changes of brush/eraser radius with hotkey do not reflect on segmentation tool ([#5535](https://github.com/OHIF/Viewers/issues/5535)) ([29bd87c](https://github.com/OHIF/Viewers/commit/29bd87c8c0592a9a1350e687b862f5452627aece))
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
### Bug Fixes
* **3DSegmentation:** [Bug] The viewports become blank when loading the seg file in advanced layout after closing the seg file from any other advanced layout ([#5505](https://github.com/OHIF/Viewers/issues/5505)) ([76f7d4e](https://github.com/OHIF/Viewers/commit/76f7d4e23aa359a3397b10adf0bf09df3763f190))
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
### Bug Fixes
* Pass the correct sop uid + frame for rehydration to prevent associating rehydrated measurements with the wrong data ([#5506](https://github.com/OHIF/Viewers/issues/5506)) ([5037802](https://github.com/OHIF/Viewers/commit/503780247ce7228c602a539fd88ea374e7d0d42f)), closes [#2404](https://github.com/OHIF/Viewers/issues/2404)
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
### Bug Fixes
* **segmentation:** Lock all rehydrated segmentation segments when panelSegmentation.disableEditing is true. ([#5503](https://github.com/OHIF/Viewers/issues/5503)) ([170e860](https://github.com/OHIF/Viewers/commit/170e860aa1b786ab6056cf31076804302a2bc462))
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-pmap
+15 -15
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.12.0-beta.94",
"version": "3.11.0",
"description": "DICOM Parametric Map read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,22 +33,22 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.12.0-beta.94",
"@ohif/extension-cornerstone": "3.12.0-beta.94",
"@ohif/extension-default": "3.12.0-beta.94",
"@ohif/i18n": "3.12.0-beta.94",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-i18next": "12.3.1",
"react-router": "6.30.1",
"react-router-dom": "6.30.1"
"@ohif/core": "3.11.0",
"@ohif/extension-cornerstone": "3.11.0",
"@ohif/extension-default": "3.11.0",
"@ohif/i18n": "3.11.0",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^12.2.2",
"react-router": "^6.8.1",
"react-router-dom": "^6.8.1"
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.11.3",
"@cornerstonejs/core": "4.11.3",
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.32.5",
"@cornerstonejs/core": "^3.32.5",
"@kitware/vtk.js": "32.12.0",
"react-color": "2.19.3"
"react-color": "^2.19.3"
}
}
+1 -762
View File
@@ -3,768 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
### Bug Fixes
* Improve rt handling for bulkdata ([#5415](https://github.com/OHIF/Viewers/issues/5415)) ([d88a341](https://github.com/OHIF/Viewers/commit/d88a341884f7361865bc10159c1a82633667ab5b))
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
### Bug Fixes
* **cornerstone-dicom-rt:** adding caching usage to cornerstone-dicom-rt SOP Class Handler ([#5387](https://github.com/OHIF/Viewers/issues/5387)) ([d6ea179](https://github.com/OHIF/Viewers/commit/d6ea179ac43a47d4011b8dcaf59d79d99382d6c8))
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-rt
+13 -13
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.12.0-beta.94",
"version": "3.11.0",
"description": "DICOM RT read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,19 +33,19 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.12.0-beta.94",
"@ohif/extension-cornerstone": "3.12.0-beta.94",
"@ohif/extension-default": "3.12.0-beta.94",
"@ohif/i18n": "3.12.0-beta.94",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-i18next": "12.3.1",
"react-router": "6.30.1",
"react-router-dom": "6.30.1"
"@ohif/core": "3.11.0",
"@ohif/extension-cornerstone": "3.11.0",
"@ohif/extension-default": "3.11.0",
"@ohif/i18n": "3.11.0",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^10.11.0",
"react-router": "^6.23.1",
"react-router-dom": "^6.23.1"
},
"dependencies": {
"@babel/runtime": "7.28.2",
"react-color": "2.19.3"
"@babel/runtime": "^7.20.13",
"react-color": "^2.19.3"
}
}
@@ -4,11 +4,7 @@ import i18n from '@ohif/i18n';
import { SOPClassHandlerId } from './id';
import loadRTStruct from './loadRTStruct';
const { sopClassDictionary } = utils;
const sopClassUids = [sopClassDictionary.RTStructureSetStorage];
const cachedRTStructsSEG = new Set<string>();
const sopClassUids = ['1.2.840.10008.5.1.4.1.1.481.3'];
const loadPromises = {};
@@ -17,25 +13,19 @@ function _getDisplaySetsFromSeries(
servicesManager: AppTypes.ServicesManager,
extensionManager
) {
utils.sortStudyInstances(instances);
// Choose the LAST instance in the list as the most recently created one.
const instance = instances[instances.length - 1];
const instance = instances[0];
const {
StudyInstanceUID,
SeriesInstanceUID,
SOPInstanceUID,
SeriesDescription = '',
SeriesDescription,
SeriesNumber,
SeriesDate,
SeriesTime,
StructureSetDate,
StructureSetTime,
SOPClassUID,
wadoRoot,
wadoUri,
wadoUriRoot,
imageId: predecessorImageId,
} = instance;
const displaySet = {
@@ -45,13 +35,7 @@ function _getDisplaySetsFromSeries(
displaySetInstanceUID: utils.guid(),
SeriesDescription,
SeriesNumber,
/**
* The "SeriesDate" for a display set is really the display set date, which
* should be the date of the instance being used, which will be the structure
* set date in this case.
*/
SeriesDate: StructureSetDate || SeriesDate,
SeriesTime: StructureSetTime || SeriesTime,
SeriesDate,
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
@@ -66,8 +50,6 @@ function _getDisplaySetsFromSeries(
structureSet: null,
sopClassUids,
instance,
instances,
predecessorImageId,
wadoRoot,
wadoUriRoot,
wadoUri,
@@ -76,10 +58,7 @@ function _getDisplaySetsFromSeries(
};
let referencedSeriesSequence = instance.ReferencedSeriesSequence;
if (
instance.ReferencedFrameOfReferenceSequence?.RTReferencedStudySequence &&
!instance.ReferencedSeriesSequence
) {
if (instance.ReferencedFrameOfReferenceSequence && !instance.ReferencedSeriesSequence) {
instance.ReferencedSeriesSequence = _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence(
instance.ReferencedFrameOfReferenceSequence
);
@@ -87,8 +66,7 @@ function _getDisplaySetsFromSeries(
}
if (!referencedSeriesSequence) {
console.error('ReferencedSeriesSequence is missing for the RTSTRUCT');
return;
throw new Error('ReferencedSeriesSequence is missing for the RTSTRUCT');
}
const referencedSeries = referencedSeriesSequence[0];
@@ -97,13 +75,9 @@ function _getDisplaySetsFromSeries(
displaySet.referencedSeriesInstanceUID = referencedSeries.SeriesInstanceUID;
const { displaySetService } = servicesManager.services;
const referencedDisplaySets =
displaySetService.getDisplaySetsForReferences(referencedSeriesSequence);
if (referencedDisplaySets?.length > 1) {
console.warn(
'Reference applies to more than 1 display set for Contours, applying only to first display set'
);
}
const referencedDisplaySets = displaySetService.getDisplaySetsForSeries(
displaySet.referencedSeriesInstanceUID
);
if (!referencedDisplaySets || referencedDisplaySets.length === 0) {
// Instead of throwing error, subscribe to display sets added
@@ -119,7 +93,7 @@ function _getDisplaySetsFromSeries(
}
);
} else {
const [referencedDisplaySet] = referencedDisplaySets;
const referencedDisplaySet = referencedDisplaySets[0];
displaySet.referencedDisplaySetInstanceUID = referencedDisplaySet.displaySetInstanceUID;
displaySet.isReconstructable = referencedDisplaySet.isReconstructable;
}
@@ -139,45 +113,39 @@ function _load(
) {
const { SOPInstanceUID } = rtDisplaySet;
const { segmentationService } = servicesManager.services;
if (
(rtDisplaySet.loading || rtDisplaySet.isLoaded) &&
loadPromises[SOPInstanceUID] &&
cachedRTStructsSEG.has(rtDisplaySet.displaySetInstanceUID)
_segmentationExistsInCache(rtDisplaySet, segmentationService)
) {
return loadPromises[SOPInstanceUID];
}
rtDisplaySet.loading = true;
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_LOADING_COMPLETE,
(evt: { rtDisplaySet: { displaySetInstanceUID: string } }) => {
if (evt.rtDisplaySet?.displaySetInstanceUID === rtDisplaySet.displaySetInstanceUID) {
cachedRTStructsSEG.add(rtDisplaySet.displaySetInstanceUID);
unsubscribe();
}
}
);
// We don't want to fire multiple loads, so we'll wait for the first to finish
// and also return the same promise to any other callers.
loadPromises[SOPInstanceUID] = new Promise<void>(async (resolve, reject) => {
try {
if (!rtDisplaySet.structureSet) {
const structureSet = await loadRTStruct(extensionManager, rtDisplaySet, headers);
rtDisplaySet.structureSet = structureSet;
}
loadPromises[SOPInstanceUID] = new Promise(async (resolve, reject) => {
if (!rtDisplaySet.structureSet) {
const structureSet = await loadRTStruct(extensionManager, rtDisplaySet, headers);
if (createSegmentation) {
await segmentationService.createSegmentationForRTDisplaySet(rtDisplaySet);
}
rtDisplaySet.structureSet = structureSet;
}
resolve();
} catch (error) {
reject(error);
} finally {
if (createSegmentation) {
segmentationService
.createSegmentationForRTDisplaySet(rtDisplaySet)
.then(() => {
rtDisplaySet.loading = false;
resolve();
})
.catch(error => {
rtDisplaySet.loading = false;
reject(error);
});
} else {
rtDisplaySet.loading = false;
resolve();
}
});
@@ -219,6 +187,11 @@ function _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence(
return ReferencedSeriesSequence;
}
function _segmentationExistsInCache() {
// Todo: fix this
return false;
}
function getSopClassHandlerModule(params: OhifTypes.Extensions.ExtensionParams) {
const { servicesManager, extensionManager } = params;
@@ -2,34 +2,9 @@ import dcmjs from 'dcmjs';
const { DicomMessage, DicomMetaDictionary } = dcmjs.data;
const dicomlab2RGB = dcmjs.data.Colors.dicomlab2RGB;
/**
* Checks and loads contour data for RT Structure Set, handling both inline and bulk data URIs.
* Processes ROIContourSequence to extract contour data and resolve any bulk data references.
*
* @async
* @function checkAndLoadContourData
* @param {Object} params - Parameters object
* @param {Object} params.instance - Initial RT Structure instance
* @param {Object} params.dataSource - Data source for retrieving bulk data
* @param {Object} params.extensionManager - OHIF extension manager
* @param {Object} params.rtStructDisplaySet - RT Structure display set
* @param {Object} params.headers - HTTP headers for requests
* @returns {Promise<Object>} Promise that resolves to the processed RT Structure instance with loaded contour data
* @throws {Promise<string>} Rejects with error message if instance is invalid or data retrieval fails
*/
async function checkAndLoadContourData({
instance: initialInstance,
dataSource,
extensionManager,
rtStructDisplaySet,
headers,
}) {
let instance = initialInstance;
async function checkAndLoadContourData(instance, datasource) {
if (!instance || !instance.ROIContourSequence) {
instance = await getRTStructInstance({ extensionManager, rtStructDisplaySet, headers });
if (!instance || !instance.ROIContourSequence) {
return Promise.reject('Invalid instance object or ROIContourSequence');
}
return Promise.reject('Invalid instance object or ROIContourSequence');
}
const promisesMap = new Map();
@@ -55,11 +30,11 @@ async function checkAndLoadContourData({
} else if (contourData && contourData.BulkDataURI) {
const bulkDataURI = contourData.BulkDataURI;
if (!dataSource || !dataSource.retrieve || !dataSource.retrieve.bulkDataURI) {
return Promise.reject('Invalid dataSource object or retrieve function');
if (!datasource || !datasource.retrieve || !datasource.retrieve.bulkDataURI) {
return Promise.reject('Invalid datasource object or retrieve function');
}
const bulkDataPromise = dataSource.retrieve.bulkDataURI({
const bulkDataPromise = datasource.retrieve.bulkDataURI({
BulkDataURI: bulkDataURI,
StudyInstanceUID: instance.StudyInstanceUID,
SeriesInstanceUID: instance.SeriesInstanceUID,
@@ -89,12 +64,9 @@ async function checkAndLoadContourData({
ROIContour.ContourSequence.forEach((Contour, index) => {
const promise = resolvedPromises[index];
if (promise.status === 'fulfilled') {
if (
Array.isArray(promise.value) &&
promise.value.every(it => Number.isFinite(Number(it)))
) {
if (Array.isArray(promise.value) && promise.value.every(Number.isFinite)) {
// If promise.value is already an array of numbers, use it directly
Contour.ContourData = promise.value.map(Number);
Contour.ContourData = promise.value;
} else {
// If the resolved promise value is a byte array (Blob), it needs to be decoded
const uint8Array = new Uint8Array(promise.value);
@@ -115,74 +87,35 @@ async function checkAndLoadContourData({
console.error(error);
}
});
return instance;
}
/**
* Retrieves and parses RT Structure Set instance from DICOM data.
* Uses the cornerstone utility module to load DICOM data and converts it to a naturalized dataset.
*
* @async
* @function getRTStructInstance
* @param {Object} params - Parameters object
* @param {Object} params.extensionManager - OHIF extension manager
* @param {Object} params.rtStructDisplaySet - RT Structure display set
* @param {Object} params.headers - HTTP headers for requests
* @returns {Promise<Object>} Promise that resolves to the parsed RT Structure dataset
*/
const getRTStructInstance = async ({ extensionManager, rtStructDisplaySet, headers }) => {
export default async function loadRTStruct(extensionManager, rtStructDisplaySet, headers) {
const utilityModule = extensionManager.getModuleEntry(
'@ohif/extension-cornerstone.utilityModule.common'
);
const { dicomLoaderService } = utilityModule.exports;
const segArrayBuffer = await dicomLoaderService.findDicomDataPromise(
rtStructDisplaySet,
null,
headers
);
const dicomData = DicomMessage.readFile(segArrayBuffer);
const rtStructDataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
rtStructDataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
return rtStructDataset;
};
/**
* Main function to load and process RT Structure Set data.
* Creates a structure set object with ROI contours, metadata, and visualization properties.
* Handles both bulk data URI and inline contour data scenarios.
*
* @async
* @function loadRTStruct
* @param {Object} extensionManager - OHIF extension manager
* @param {Object} rtStructDisplaySet - RT Structure display set to process
* @param {Object} headers - HTTP headers for data requests
* @returns {Promise<Object>} Promise that resolves to a structure set object containing:
* - StructureSetLabel: Label of the structure set
* - SeriesInstanceUID: Series instance UID
* - ROIContours: Array of ROI contour data with points and metadata
* - visible: Visibility state
* - ReferencedSOPInstanceUIDsSet: Set of referenced SOP instance UIDs
*/
export default async function loadRTStruct(extensionManager, rtStructDisplaySet, headers) {
const dataSource = extensionManager.getActiveDataSource()[0];
const { bulkDataURI } = dataSource.getConfig?.() || {};
const { dicomLoaderService } = utilityModule.exports;
// Set here is loading is asynchronous.
// If this function throws its set back to false.
rtStructDisplaySet.isLoaded = true;
let instance = rtStructDisplaySet.instance;
if (!bulkDataURI || !bulkDataURI.enabled) {
instance = await getRTStructInstance({ extensionManager, rtStructDisplaySet, headers });
} else {
instance = await checkAndLoadContourData({
instance,
dataSource,
extensionManager,
const segArrayBuffer = await dicomLoaderService.findDicomDataPromise(
rtStructDisplaySet,
headers,
});
null,
headers
);
const dicomData = DicomMessage.readFile(segArrayBuffer);
const rtStructDataset = DicomMetaDictionary.naturalizeDataset(dicomData.dict);
rtStructDataset._meta = DicomMetaDictionary.namifyDataset(dicomData.meta);
instance = rtStructDataset;
} else {
await checkAndLoadContourData(instance, dataSource);
}
const { StructureSetROISequence, ROIContourSequence, RTROIObservationsSequence } = instance;
@@ -199,16 +132,21 @@ export default async function loadRTStruct(extensionManager, rtStructDisplaySet,
for (let i = 0; i < ROIContourSequence.length; i++) {
const ROIContour = ROIContourSequence[i];
const { ContourSequence } = ROIContour;
if (!ContourSequence) {
continue;
}
const isSupported = false;
const ContourSequenceArray = _toArray(ContourSequence);
const contourPoints = [];
for (const ContourSequenceItem of ContourSequenceArray) {
for (let c = 0; c < ContourSequenceArray.length; c++) {
const { ContourData, NumberOfContourPoints, ContourGeometricType, ContourImageSequence } =
ContourSequenceItem;
ContourSequenceArray[c];
let isSupported = false;
const points = [];
for (let p = 0; p < NumberOfContourPoints * 3; p += 3) {
@@ -219,18 +157,22 @@ export default async function loadRTStruct(extensionManager, rtStructDisplaySet,
});
}
const supportedContourTypesMap = new Map([
['CLOSED_PLANAR', false],
['OPEN_NONPLANAR', false],
['OPEN_PLANAR', false],
['POINT', true],
]);
switch (ContourGeometricType) {
case 'CLOSED_PLANAR':
case 'OPEN_PLANAR':
case 'POINT':
isSupported = true;
break;
default:
continue;
}
contourPoints.push({
numberOfPoints: NumberOfContourPoints,
points,
type: ContourGeometricType,
isSupported: supportedContourTypesMap.get(ContourGeometricType) ?? false,
isSupported,
});
if (ContourImageSequence?.ReferencedSOPInstanceUID) {
@@ -245,30 +187,20 @@ export default async function loadRTStruct(extensionManager, rtStructDisplaySet,
StructureSetROISequence,
RTROIObservationsSequence,
ROIContour,
contourPoints
contourPoints,
isSupported
);
}
return structureSet;
}
/**
* Sets metadata for ROI contour data and adds it to the structure set.
* Extracts ROI information from StructureSetROISequence and RTROIObservationsSequence,
* then creates a complete ROI contour data object with visualization properties.
*
* @function _setROIContourMetadata
* @param {Object} structureSet - The structure set object to add ROI contour to
* @param {Array} StructureSetROISequence - Array of structure set ROI definitions
* @param {Array} RTROIObservationsSequence - Array of RT ROI observations
* @param {Object} ROIContour - ROI contour object containing contour data
* @param {Array} contourPoints - Array of processed contour points
*/
function _setROIContourMetadata(
structureSet,
StructureSetROISequence,
RTROIObservationsSequence,
ROIContour,
contourPoints
contourPoints,
isSupported
) {
const StructureSetROI = StructureSetROISequence.find(
structureSetROI => structureSetROI.ROINumber === ROIContour.ReferencedROINumber
@@ -279,9 +211,9 @@ function _setROIContourMetadata(
ROIName: StructureSetROI.ROIName,
ROIGenerationAlgorithm: StructureSetROI.ROIGenerationAlgorithm,
ROIDescription: StructureSetROI.ROIDescription,
isSupported,
contourPoints,
visible: true,
colorArray: [],
};
_setROIContourDataColor(ROIContour, ROIContourData);
@@ -298,14 +230,6 @@ function _setROIContourMetadata(
structureSet.ROIContours.push(ROIContourData);
}
/**
* Sets the display color for ROI contour data.
* Uses ROIDisplayColor if available, otherwise converts RecommendedDisplayCIELabValue to RGB.
*
* @function _setROIContourDataColor
* @param {Object} ROIContour - ROI contour object containing color information
* @param {Object} ROIContourData - ROI contour data object to set color on
*/
function _setROIContourDataColor(ROIContour, ROIContourData) {
let { ROIDisplayColor, RecommendedDisplayCIELabValue } = ROIContour;
@@ -319,15 +243,6 @@ function _setROIContourDataColor(ROIContour, ROIContourData) {
}
}
/**
* Sets RT ROI observations metadata for ROI contour data.
* Finds matching RTROIObservations by ROINumber and adds observation details to contour data.
*
* @function _setROIContourRTROIObservations
* @param {Object} ROIContourData - ROI contour data object to add observations to
* @param {Array} RTROIObservationsSequence - Array of RT ROI observations
* @param {number} ROINumber - ROI number to match observations
*/
function _setROIContourRTROIObservations(ROIContourData, RTROIObservationsSequence, ROINumber) {
const RTROIObservations = RTROIObservationsSequence.find(
RTROIObservations => RTROIObservations.ReferencedROINumber === ROINumber
@@ -347,14 +262,6 @@ function _setROIContourRTROIObservations(ROIContourData, RTROIObservationsSequen
}
}
/**
* Converts a single object or array to an array.
* Utility function to ensure consistent array handling for DICOM sequences.
*
* @function _toArray
* @param {*} objOrArray - Object or array to convert
* @returns {Array} Array containing the input (if already array) or wrapped in array
*/
function _toArray(objOrArray) {
return Array.isArray(objOrArray) ? objOrArray : [objOrArray];
}
@@ -103,7 +103,7 @@ function OHIFCornerstoneRTViewport(props: withAppTypes) {
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_LOADING_COMPLETE,
evt => {
if (evt.rtDisplaySet?.displaySetInstanceUID === rtDisplaySet.displaySetInstanceUID) {
if (evt.rtDisplaySet.displaySetInstanceUID === rtDisplaySet.displaySetInstanceUID) {
setRtIsLoading(false);
}
+1 -777
View File
@@ -3,783 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
### Bug Fixes
* **SegmentationStyle:** Fix inactive contour visibility and styling. ([#5563](https://github.com/OHIF/Viewers/issues/5563)) ([5c17c26](https://github.com/OHIF/Viewers/commit/5c17c262eaa5c1229033cfff4b3e7709e874611f))
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
### Bug Fixes
* **interpolation:** Auto accept interpolation when the interpolation process is completed. ([#5555](https://github.com/OHIF/Viewers/issues/5555)) ([834ae3c](https://github.com/OHIF/Viewers/commit/834ae3c762ca309187afebdf77bad1ad9a57f03f))
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
### Bug Fixes
* **SegmentationTools:** [Bug] Changes of brush/eraser radius with hotkey do not reflect on segmentation tool ([#5535](https://github.com/OHIF/Viewers/issues/5535)) ([29bd87c](https://github.com/OHIF/Viewers/commit/29bd87c8c0592a9a1350e687b862f5452627aece))
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
### Bug Fixes
* **3DSegmentation:** [Bug] The viewports become blank when loading the seg file in advanced layout after closing the seg file from any other advanced layout ([#5505](https://github.com/OHIF/Viewers/issues/5505)) ([76f7d4e](https://github.com/OHIF/Viewers/commit/76f7d4e23aa359a3397b10adf0bf09df3763f190))
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
### Bug Fixes
* Pass the correct sop uid + frame for rehydration to prevent associating rehydrated measurements with the wrong data ([#5506](https://github.com/OHIF/Viewers/issues/5506)) ([5037802](https://github.com/OHIF/Viewers/commit/503780247ce7228c602a539fd88ea374e7d0d42f)), closes [#2404](https://github.com/OHIF/Viewers/issues/2404)
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
### Bug Fixes
* **segmentation:** Lock all rehydrated segmentation segments when panelSegmentation.disableEditing is true. ([#5503](https://github.com/OHIF/Viewers/issues/5503)) ([170e860](https://github.com/OHIF/Viewers/commit/170e860aa1b786ab6056cf31076804302a2bc462))
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-seg
+15 -15
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.12.0-beta.94",
"version": "3.11.0",
"description": "DICOM SEG read workflow",
"author": "OHIF",
"license": "MIT",
@@ -33,22 +33,22 @@
"start": "yarn run dev"
},
"peerDependencies": {
"@ohif/core": "3.12.0-beta.94",
"@ohif/extension-cornerstone": "3.12.0-beta.94",
"@ohif/extension-default": "3.12.0-beta.94",
"@ohif/i18n": "3.12.0-beta.94",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-i18next": "12.3.1",
"react-router": "6.30.1",
"react-router-dom": "6.30.1"
"@ohif/core": "3.11.0",
"@ohif/extension-cornerstone": "3.11.0",
"@ohif/extension-default": "3.11.0",
"@ohif/i18n": "3.11.0",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^12.2.2",
"react-router": "^6.23.1",
"react-router-dom": "^6.23.1"
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.11.3",
"@cornerstonejs/core": "4.11.3",
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.32.5",
"@cornerstonejs/core": "^3.32.5",
"@kitware/vtk.js": "32.12.0",
"react-color": "2.19.3"
"react-color": "^2.19.3"
}
}
@@ -1,13 +1,15 @@
import dcmjs from 'dcmjs';
import { classes, Types, utils } from '@ohif/core';
import { classes, Types } from '@ohif/core';
import { cache, metaData } from '@cornerstonejs/core';
import { segmentation as cornerstoneToolsSegmentation } from '@cornerstonejs/tools';
import { adaptersRT, helpers, adaptersSEG } from '@cornerstonejs/adapters';
import { createReportDialogPrompt, useUIStateStore } from '@ohif/extension-default';
import { createReportDialogPrompt } from '@ohif/extension-default';
import { DicomMetadataStore } from '@ohif/core';
import PROMPT_RESPONSES from '../../default/src/utils/_shared/PROMPT_RESPONSES';
const { datasetToBlob } = dcmjs.data;
const getTargetViewport = ({ viewportId, viewportGridService }) => {
const { viewports, activeViewportId } = viewportGridService.getState();
const targetViewportId = viewportId || activeViewportId;
@@ -25,7 +27,7 @@ const {
const {
Cornerstone3D: {
RTSS: { generateRTSSFromRepresentation },
RTSS: { generateRTSSFromSegmentations },
},
} = adaptersRT;
@@ -35,7 +37,7 @@ const commandsModule = ({
servicesManager,
extensionManager,
}: Types.Extensions.ExtensionParams): Types.Extensions.CommandsModule => {
const { segmentationService, displaySetService, viewportGridService } =
const { segmentationService, displaySetService, viewportGridService, toolGroupService } =
servicesManager.services as AppTypes.Services;
const actions = {
@@ -90,7 +92,6 @@ const commandsModule = ({
*/
generateSegmentation: ({ segmentationId, options = {} }) => {
const segmentation = cornerstoneToolsSegmentation.state.getSegmentation(segmentationId);
const predecessorImageId = options.predecessorImageId ?? segmentation.predecessorImageId;
const { imageIds } = segmentation.representationData.Labelmap;
@@ -172,10 +173,12 @@ const commandsModule = ({
labelmap3D.metadata[segmentIndex] = segmentMetadata;
});
const generatedSegmentation = generateSegmentation(referencedImages, labelmap3D, metaData, {
predecessorImageId,
...options,
});
const generatedSegmentation = generateSegmentation(
referencedImages,
labelmap3D,
metaData,
options
);
return generatedSegmentation;
},
@@ -209,28 +212,24 @@ const commandsModule = ({
* @returns {Object|void} Returns the naturalized report if successfully stored,
* otherwise throws an error.
*/
storeSegmentation: async ({ segmentationId, dataSource, modality = 'SEG' }) => {
storeSegmentation: async ({ segmentationId, dataSource }) => {
const segmentation = segmentationService.getSegmentation(segmentationId);
if (!segmentation) {
throw new Error('No segmentation found');
}
const { label, predecessorImageId } = segmentation;
const { label } = segmentation;
const defaultDataSource = dataSource ?? extensionManager.getActiveDataSource()[0];
const {
value: reportName,
dataSourceName: selectedDataSource,
series,
priorSeriesNumber,
action,
} = await createReportDialogPrompt({
servicesManager,
extensionManager,
predecessorImageId,
title: 'Store Segmentation',
modality,
});
if (action === PROMPT_RESPONSES.CREATE_REPORT) {
@@ -239,18 +238,12 @@ const commandsModule = ({
? extensionManager.getDataSources(selectedDataSource)[0]
: defaultDataSource;
const args = {
const generatedData = actions.generateSegmentation({
segmentationId,
options: {
SeriesDescription: series ? undefined : reportName || label || 'Contour Series',
SeriesNumber: series ? undefined : 1 + priorSeriesNumber,
predecessorImageId: series,
SeriesDescription: reportName || label || 'Research Derived Series',
},
};
const generatedDataAsync =
(modality === 'SEG' && actions.generateSegmentation(args)) ||
(modality === 'RTSTRUCT' && actions.generateContour(args));
const generatedData = await generatedDataAsync;
});
if (!generatedData || !generatedData.dataset) {
throw new Error('Error during segmentation generation');
@@ -277,9 +270,14 @@ const commandsModule = ({
}
}
},
generateContour: async args => {
const { segmentationId, options } = args;
/**
* Converts segmentations into RTSS for download.
* This sample function retrieves all segentations and passes to
* cornerstone tool adapter to convert to DICOM RTSS format. It then
* converts dataset to downloadable blob.
*
*/
downloadRTSS: async ({ segmentationId }) => {
const segmentations = segmentationService.getSegmentation(segmentationId);
// inject colors to the segmentIndex
@@ -289,54 +287,45 @@ const commandsModule = ({
segment.color = segmentationService.getSegmentColor(
firstRepresentation.viewportId,
segmentationId,
Number(segmentIndex)
segmentIndex
);
});
const predecessorImageId = options?.predecessorImageId ?? segmentations.predecessorImageId;
const dataset = await generateRTSSFromRepresentation(segmentations, {
predecessorImageId,
...options,
});
return { dataset };
},
/**
* Downloads an RTSS instance from a segmentation or contour
* representation.
*/
downloadRTSS: async args => {
const { dataset } = await actions.generateContour(args);
const { InstanceNumber: instanceNumber = 1, SeriesInstanceUID: seriesUID } = dataset;
const RTSS = await generateRTSSFromSegmentations(
segmentations,
classes.MetadataProvider,
DicomMetadataStore
);
try {
const reportBlob = datasetToBlob(RTSS);
//Create a URL for the binary.
const filename = `rtss-${seriesUID}-${instanceNumber}.dcm`;
downloadDICOMData(dataset, filename);
const objectUrl = URL.createObjectURL(reportBlob);
window.location.assign(objectUrl);
} catch (e) {
console.warn(e);
}
},
toggleActiveSegmentationUtility: ({ itemId: buttonId }) => {
const { uiState, setUIState } = useUIStateStore.getState();
const isButtonActive = uiState['activeSegmentationUtility'] === buttonId;
console.log('toggleActiveSegmentationUtility', isButtonActive, buttonId);
// if the button is active, clear the active segmentation utility
if (isButtonActive) {
setUIState('activeSegmentationUtility', null);
} else {
setUIState('activeSegmentationUtility', buttonId);
}
},
};
const definitions = {
loadSegmentationsForViewport: actions.loadSegmentationsForViewport,
generateSegmentation: actions.generateSegmentation,
downloadSegmentation: actions.downloadSegmentation,
storeSegmentation: actions.storeSegmentation,
downloadRTSS: actions.downloadRTSS,
toggleActiveSegmentationUtility: actions.toggleActiveSegmentationUtility,
loadSegmentationsForViewport: {
commandFn: actions.loadSegmentationsForViewport,
},
generateSegmentation: {
commandFn: actions.generateSegmentation,
},
downloadSegmentation: {
commandFn: actions.downloadSegmentation,
},
storeSegmentation: {
commandFn: actions.storeSegmentation,
},
downloadRTSS: {
commandFn: actions.downloadRTSS,
},
};
return {
@@ -1,243 +0,0 @@
import React, { useCallback, useEffect, useState } from 'react';
import { useRunCommand, useSystem } from '@ohif/core';
import { useActiveViewportSegmentationRepresentations } from '@ohif/extension-cornerstone';
import {
Button,
cn,
Input,
Label,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
Separator,
Switch,
Tabs,
TabsList,
TabsTrigger,
} from '@ohif/ui-next';
import { Icons } from '@ohif/ui-next';
import { contourSegmentation } from '@cornerstonejs/tools/utilities';
import { Segment } from '@cornerstonejs/tools/types';
const { LogicalOperation } = contourSegmentation;
const options = [
{
value: 'merge',
logicalOperation: LogicalOperation.Union,
label: 'Merge',
icon: 'actions-combine-merge',
helperIcon: 'helper-combine-merge',
},
{
value: 'intersect',
logicalOperation: LogicalOperation.Intersect,
label: 'Intersect',
icon: 'actions-combine-intersect',
helperIcon: 'helper-combine-intersect',
},
{
value: 'subtract',
logicalOperation: LogicalOperation.Subtract,
label: 'Subtract',
icon: 'actions-combine-subtract',
helperIcon: 'helper-combine-subtract',
},
];
// Shared component for segment selection
function SegmentSelector({
label,
value,
onValueChange,
segments,
placeholder = 'Select a segment',
}: {
label: string;
value: string;
onValueChange: (value: string) => void;
segments: Segment[];
placeholder?: string;
}) {
return (
<div className="flex justify-between gap-6">
<div>{label}</div>
<Select
key={`select-segment-${label}`}
onValueChange={onValueChange}
value={value}
>
<SelectTrigger className="overflow-hidden">
<SelectValue placeholder={placeholder} />
</SelectTrigger>
<SelectContent>
{segments.map(segment => (
<SelectItem
key={segment.segmentIndex}
value={segment.segmentIndex.toString()}
>
{segment.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
);
}
function LogicalContourOperationOptions() {
const { servicesManager } = useSystem();
const { segmentationService } = servicesManager.services;
const { segmentationsWithRepresentations } = useActiveViewportSegmentationRepresentations();
const activeRepresentation = segmentationsWithRepresentations?.find(
({ representation }) => representation?.active
);
const segments = activeRepresentation
? Object.values(activeRepresentation.segmentation.segments)
: [];
// Calculate the next available segment index
const nextSegmentIndex = activeRepresentation
? segmentationService.getNextAvailableSegmentIndex(
activeRepresentation.segmentation.segmentationId
)
: 1;
const activeSegment = segments.find(segment => segment.active);
const activeSegmentIndex = activeSegment?.segmentIndex || 0;
const [operation, setOperation] = useState(options[0]);
const [segmentA, setSegmentA] = useState<string>(activeSegmentIndex?.toString() || '');
const [segmentB, setSegmentB] = useState<string>('');
const [createNewSegment, setCreateNewSegment] = useState<boolean>(false);
const [newSegmentName, setNewSegmentName] = useState<string>('');
useEffect(() => {
setSegmentA(activeSegmentIndex?.toString() || null);
}, [activeSegmentIndex]);
useEffect(() => {
setNewSegmentName(`Segment ${nextSegmentIndex}`);
}, [nextSegmentIndex]);
const runCommand = useRunCommand();
const applyLogicalContourOperation = useCallback(() => {
let resultSegmentIndex = segmentA;
if (createNewSegment) {
resultSegmentIndex = nextSegmentIndex.toString();
runCommand('addSegment', {
segmentationId: activeRepresentation.segmentation.segmentationId,
config: {
label: newSegmentName,
segmentIndex: nextSegmentIndex,
},
});
}
runCommand('applyLogicalContourOperation', {
segmentAInfo: {
segmentationId: activeRepresentation.segmentation.segmentationId,
segmentIndex: parseInt(segmentA),
},
segmentBInfo: {
segmentationId: activeRepresentation.segmentation.segmentationId,
segmentIndex: parseInt(segmentB),
},
resultSegmentInfo: {
segmentationId: activeRepresentation.segmentation.segmentationId,
segmentIndex: parseInt(resultSegmentIndex),
},
logicalOperation: operation.logicalOperation,
});
}, [
activeRepresentation?.segmentation?.segmentationId,
createNewSegment,
newSegmentName,
nextSegmentIndex,
operation.logicalOperation,
runCommand,
segmentA,
segmentB,
]);
return (
<div className="flex w-[245px] flex-col gap-4">
<div className="flex items-start justify-between">
<div className="flex w-auto flex-col items-center gap-2 text-base font-normal leading-none">
<Tabs value={operation.value}>
<TabsList className="inline-flex space-x-1">
{options.map(option => {
const { value, icon } = option;
return (
<TabsTrigger
value={value}
key={`logical-contour-operation-${value}`}
onClick={() => setOperation(option)}
>
<Icons.ByName name={icon}></Icons.ByName>
</TabsTrigger>
);
})}
</TabsList>
</Tabs>
<div>{operation.label}</div>
</div>
<div className="bg-primary-dark flex h-[62px] w-[88px] items-center justify-center rounded-lg">
<Icons.ByName name={operation.helperIcon}></Icons.ByName>
</div>
</div>
<SegmentSelector
label="A"
value={segmentA}
onValueChange={setSegmentA}
segments={segments}
/>
<SegmentSelector
label="B"
value={segmentB}
onValueChange={setSegmentB}
segments={segments}
/>
<div className="flex justify-end pl-[34px]">
<Button
className="border-primary/60 grow border"
variant="ghost"
onClick={() => {
applyLogicalContourOperation();
}}
>
{operation.label}
</Button>
</div>
<Separator className="bg-input mt-2 h-[1px]" />
<div className="flex flex-col gap-2">
<div className="flex items-center justify-start gap-2">
<Switch
id="logical-contour-operations-create-new-segment-switch"
onCheckedChange={setCreateNewSegment}
></Switch>
<Label htmlFor="logical-contour-operations-create-new-segment-switch">
Create a new segment
</Label>
</div>
<div className="pl-9">
<Input
className={cn(createNewSegment ? 'visible' : 'hidden')}
disabled={!createNewSegment}
id="logical-contour-operations-create-new-segment-input"
type="text"
placeholder="New segment name"
value={newSegmentName}
onChange={e => setNewSegmentName(e.target.value)}
/>
</div>
</div>
</div>
);
}
export default LogicalContourOperationOptions;
@@ -1,71 +0,0 @@
import React, { useState } from 'react';
import { Button, Input, Label, Separator } from '@ohif/ui-next';
import { useRunCommand } from '@ohif/core';
function SimplifyContourOptions() {
const [areaThreshold, setAreaThreshold] = useState(10);
const runCommand = useRunCommand();
return (
<div className="flex w-auto w-[252px] flex-col gap-[8px] text-base font-normal leading-none">
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
<div>Fill contour holes</div>
<Button
className="border-primary/60 border"
variant="ghost"
onClick={() => {
runCommand('removeContourHoles');
}}
>
Fill Holes
</Button>
<Separator className="bg-input mt-[20px] h-[1px]" />
</div>
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
<div>Remove Small Contours</div>
<div className="flex items-center gap-2 self-end">
<Label
htmlFor="simplify-contour-options"
className="text-muted-foreground"
>
Area Threshold
</Label>
<Input
id="simplify-contour-options"
className="w-20"
type="number"
value={areaThreshold}
onChange={e => setAreaThreshold(Number(e.target.value))}
/>
</div>
<Button
className="border-primary/60 border"
variant="ghost"
onClick={() => {
runCommand('removeSmallContours', {
areaThreshold,
});
}}
>
Remove Small Contours
</Button>
<Separator className="bg-input mt-[20px] h-[1px]" />
</div>
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
<div>Create New Segment from Holes</div>
<Button
className="border-primary/60 border"
variant="ghost"
onClick={() => {
runCommand('convertContourHoles');
}}
>
Create New Segment
</Button>
</div>
</div>
);
}
export default SimplifyContourOptions;
@@ -1,39 +0,0 @@
import React from 'react';
import { Button, Separator } from '@ohif/ui-next';
import { useRunCommand } from '@ohif/core';
function SmoothContoursOptions() {
const runCommand = useRunCommand();
return (
<div className="flex w-auto w-[245px] flex-col gap-[8px] text-base font-normal leading-none">
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
<div>Smooth all edges</div>
<Button
className="border-primary/60 border"
variant="ghost"
onClick={() => {
runCommand('smoothContours');
}}
>
Smooth Edges
</Button>
<Separator className="bg-input mt-[20px] h-[1px]" />
</div>
<div className="flex w-auto flex-col gap-[10px] text-base font-normal leading-none">
<div>Remove extra points</div>
<Button
className="border-primary/60 border"
variant="ghost"
onClick={() => {
runCommand('decimateContours');
}}
>
Remove Points
</Button>
</div>
</div>
);
}
export default SmoothContoursOptions;
@@ -16,24 +16,19 @@ function _getDisplaySetsFromSeries(
servicesManager: AppTypes.ServicesManager,
extensionManager
) {
utils.sortStudyInstances(instances);
// Choose the LAST instance in the list as the most recently created one.
const instance = instances[instances.length - 1];
const instance = instances[0];
const {
StudyInstanceUID,
SeriesInstanceUID,
SOPInstanceUID,
SeriesDescription = '',
SeriesDescription,
SeriesNumber,
SeriesDate,
StructureSetDate,
SOPClassUID,
wadoRoot,
wadoUri,
wadoUriRoot,
imageId: predecessorImageId,
} = instance;
const displaySet = {
@@ -43,7 +38,7 @@ function _getDisplaySetsFromSeries(
displaySetInstanceUID: utils.guid(),
SeriesDescription,
SeriesNumber,
SeriesDate: SeriesDate || StructureSetDate || '',
SeriesDate,
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
@@ -58,7 +53,6 @@ function _getDisplaySetsFromSeries(
segments: {},
sopClassUids,
instance,
predecessorImageId,
instances: [instance],
wadoRoot,
wadoUriRoot,
@@ -79,16 +73,10 @@ function _getDisplaySetsFromSeries(
displaySet.referencedImages = instance.ReferencedSeriesSequence.ReferencedInstanceSequence;
displaySet.referencedSeriesInstanceUID = referencedSeries.SeriesInstanceUID;
const { displaySetService } = servicesManager.services;
const referencedDisplaySets = displaySetService.getDisplaySetsForReferences(
instance.ReferencedSeriesSequence
const referencedDisplaySets = displaySetService.getDisplaySetsForSeries(
displaySet.referencedSeriesInstanceUID
);
if (referencedDisplaySets?.length > 1) {
console.warn(
'Segmentation does not currently handle references to multiple series, defaulting to first series'
);
}
const referencedDisplaySet = referencedDisplaySets[0];
if (!referencedDisplaySet) {
@@ -1,34 +1,6 @@
import { utilities as cstUtils } from '@cornerstonejs/tools';
import { useUIStateStore } from '@ohif/extension-default';
import LogicalContourOperationsOptions from './components/LogicalContourOperationsOptions';
import SimplifyContourOptions from './components/SimplifyContourOptions';
import SmoothContoursOptions from './components/SmoothContoursOptions';
export function getToolbarModule({ servicesManager }: withAppTypes) {
const { segmentationService, toolbarService, toolGroupService } = servicesManager.services;
return [
{
name: 'cornerstone.SimplifyContourOptions',
defaultComponent: SimplifyContourOptions,
},
{
name: 'cornerstone.LogicalContourOperationsOptions',
defaultComponent: LogicalContourOperationsOptions,
},
{
name: 'cornerstone.SmoothContoursOptions',
defaultComponent: SmoothContoursOptions,
},
{
name: 'cornerstone.isActiveSegmentationUtility',
evaluate: ({ button }) => {
const { uiState } = useUIStateStore.getState();
return {
isActive: uiState[`activeSegmentationUtility`] === button.id,
};
},
},
{
name: 'evaluate.cornerstone.hasSegmentation',
evaluate: ({ viewportId }) => {
@@ -38,30 +10,6 @@ export function getToolbarModule({ servicesManager }: withAppTypes) {
};
},
},
{
name: 'evaluate.cornerstone.hasSegmentationOfType',
evaluate: ({ viewportId, segmentationRepresentationType }) => {
const segmentations = segmentationService.getSegmentationRepresentations(viewportId);
if (!segmentations?.length) {
return {
disabled: true,
disabledText: 'No segmentations available',
};
}
if (
!segmentations.some(segmentation =>
Boolean(segmentation.type === segmentationRepresentationType)
)
) {
return {
disabled: true,
disabledText: `No ${segmentationRepresentationType} segmentations available`,
};
}
},
},
{
name: 'evaluate.cornerstone.segmentation',
evaluate: ({ viewportId, button, toolNames, disabledText }) => {
@@ -120,23 +68,5 @@ export function getToolbarModule({ servicesManager }: withAppTypes) {
};
},
},
{
name: 'evaluate.cornerstone.segmentation.synchronizeDrawingRadius',
evaluate: ({ button, radiusOptionId }) => {
const toolGroupIds = toolGroupService.getToolGroupIds();
if (!toolGroupIds?.length) {
return;
}
for (const toolGroupId of toolGroupIds) {
const brushSize = cstUtils.segmentation.getBrushSizeForToolGroup(toolGroupId);
if (brushSize) {
const option = toolbarService.getOptionById(button, radiusOptionId);
option.value = brushSize;
}
}
},
},
];
}
@@ -134,7 +134,7 @@ function OHIFCornerstoneSEGViewport(props: withAppTypes) {
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_LOADING_COMPLETE,
evt => {
if (evt.segDisplaySet?.displaySetInstanceUID === segDisplaySet?.displaySetInstanceUID) {
if (evt.segDisplaySet.displaySetInstanceUID === segDisplaySet.displaySetInstanceUID) {
setSegIsLoading(false);
}
+1 -786
View File
@@ -3,792 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
### Bug Fixes
* Remove dead code and fix rectangle roi rehydration ([#5490](https://github.com/OHIF/Viewers/issues/5490)) ([9ca02b4](https://github.com/OHIF/Viewers/commit/9ca02b4071f77600f7dcd87930fecdcf3d1c249f))
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
### Bug Fixes
* **SegmentationStyle:** Fix inactive contour visibility and styling. ([#5563](https://github.com/OHIF/Viewers/issues/5563)) ([5c17c26](https://github.com/OHIF/Viewers/commit/5c17c262eaa5c1229033cfff4b3e7709e874611f))
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
### Bug Fixes
* **interpolation:** Auto accept interpolation when the interpolation process is completed. ([#5555](https://github.com/OHIF/Viewers/issues/5555)) ([834ae3c](https://github.com/OHIF/Viewers/commit/834ae3c762ca309187afebdf77bad1ad9a57f03f))
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
### Bug Fixes
* **SegmentationTools:** [Bug] Changes of brush/eraser radius with hotkey do not reflect on segmentation tool ([#5535](https://github.com/OHIF/Viewers/issues/5535)) ([29bd87c](https://github.com/OHIF/Viewers/commit/29bd87c8c0592a9a1350e687b862f5452627aece))
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
### Bug Fixes
* **3DSegmentation:** [Bug] The viewports become blank when loading the seg file in advanced layout after closing the seg file from any other advanced layout ([#5505](https://github.com/OHIF/Viewers/issues/5505)) ([76f7d4e](https://github.com/OHIF/Viewers/commit/76f7d4e23aa359a3397b10adf0bf09df3763f190))
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
### Bug Fixes
* Pass the correct sop uid + frame for rehydration to prevent associating rehydrated measurements with the wrong data ([#5506](https://github.com/OHIF/Viewers/issues/5506)) ([5037802](https://github.com/OHIF/Viewers/commit/503780247ce7228c602a539fd88ea374e7d0d42f)), closes [#2404](https://github.com/OHIF/Viewers/issues/2404)
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
### Bug Fixes
* **segmentation:** Lock all rehydrated segmentation segments when panelSegmentation.disableEditing is true. ([#5503](https://github.com/OHIF/Viewers/issues/5503)) ([170e860](https://github.com/OHIF/Viewers/commit/170e860aa1b786ab6056cf31076804302a2bc462))
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
### Features
* **MeasurementService:** add rendering of unmapped measurements ([#5416](https://github.com/OHIF/Viewers/issues/5416)) ([851e74d](https://github.com/OHIF/Viewers/commit/851e74d7b867a806befb5d85fd71ff9a75e9f2d2))
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
### Bug Fixes
* load 3dsr ([#5335](https://github.com/OHIF/Viewers/issues/5335)) ([becba78](https://github.com/OHIF/Viewers/commit/becba7861f99ae4e190caddea8b663e60a9883f5))
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dicom-sr
+15 -15
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.12.0-beta.94",
"version": "3.11.0",
"description": "OHIF extension for an SR Cornerstone Viewport",
"author": "OHIF",
"license": "MIT",
@@ -34,21 +34,21 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "3.12.0-beta.94",
"@ohif/extension-cornerstone": "3.12.0-beta.94",
"@ohif/extension-measurement-tracking": "3.12.0-beta.94",
"@ohif/ui": "3.12.0-beta.94",
"dcmjs": "0.45.0",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
"prop-types": "15.8.1",
"react": "18.3.1"
"@ohif/core": "3.11.0",
"@ohif/extension-cornerstone": "3.11.0",
"@ohif/extension-measurement-tracking": "3.11.0",
"@ohif/ui": "3.11.0",
"dcmjs": "0.43.1",
"dicom-parser": "^1.8.9",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
"react": "^18.3.1"
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.11.3",
"@cornerstonejs/core": "4.11.3",
"@cornerstonejs/tools": "4.11.3",
"classnames": "2.5.1"
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.32.5",
"@cornerstonejs/core": "^3.32.5",
"@cornerstonejs/tools": "^3.32.5",
"classnames": "^2.3.2"
}
}
@@ -1,14 +1,12 @@
import { metaData } from '@cornerstonejs/core';
import { metaData, utilities } from '@cornerstonejs/core';
import OHIF, { DicomMetadataStore, utils } from '@ohif/core';
import OHIF, { DicomMetadataStore } from '@ohif/core';
import dcmjs from 'dcmjs';
import { adaptersSR } from '@cornerstonejs/adapters';
import getFilteredCornerstoneToolState from './utils/getFilteredCornerstoneToolState';
import hydrateStructuredReport from './utils/hydrateStructuredReport';
const { downloadBlob } = utils;
const { MeasurementReport } = adaptersSR.Cornerstone3D;
const { log } = OHIF;
@@ -44,6 +42,8 @@ const _generateReport = (measurementData, additionalFindingTypes, options: Optio
dataset.SpecificCharacterSet = 'ISO_IR 192';
}
dataset.InstanceNumber = options.InstanceNumber ?? 1;
return dataset;
};
@@ -85,7 +85,8 @@ const commandsModule = (props: withAppTypes) => {
const reportBlob = dcmjs.data.datasetToBlob(srDataset);
//Create a URL for the binary.
downloadBlob(reportBlob, { filename: 'dicom-sr.dcm' });
const objectUrl = URL.createObjectURL(reportBlob);
window.location.assign(objectUrl);
},
/**
@@ -86,7 +86,7 @@ function OHIFCornerstoneSRMeasurementViewport(props) {
const { presentationIds } = viewportOptions;
const measurement = srDisplaySet.measurements[newMeasurementSelected];
setPositionPresentation(presentationIds.positionPresentationId, {
viewReference: measurement.viewReference || {
viewReference: {
referencedImageId: measurement.imageId,
},
});
@@ -22,7 +22,7 @@ const {
CodeScheme: Cornerstone3DCodeScheme,
} = adaptersSR.Cornerstone3D;
type InstanceMetadata = OhifTypes.InstanceMetadata;
type InstanceMetadata = Types.InstanceMetadata;
/**
* TODO
@@ -35,7 +35,6 @@ const sopClassUids = [
sopClassDictionary.BasicTextSR,
sopClassDictionary.EnhancedSR,
sopClassDictionary.ComprehensiveSR,
sopClassDictionary.Comprehensive3DSR,
];
const validateSameStudyUID = (uid: string, instances): void => {
@@ -54,7 +53,7 @@ const validateSameStudyUID = (uid: string, instances): void => {
* @param instances is a list of instances from THIS series that are not
* in this DICOM SR Display Set already.
*/
function addInstances(instances: InstanceMetadata[], _displaySetService: DisplaySetService) {
function addInstances(instances: InstanceMetadata[], displaySetService: DisplaySetService) {
this.instances.push(...instances);
utils.sortStudyInstances(this.instances);
// The last instance is the newest one, so is the one most interesting.
@@ -69,10 +68,9 @@ function addInstances(instances: InstanceMetadata[], _displaySetService: Display
* DICOM SR SOP Class Handler
* For all referenced images in the TID 1500/300 sections, add an image to the
* display.
* @param {InstanceMetadata[]} instances - A set of instances all from the same series
* @param {AppTypes.ServicesManager} servicesManager - The services that can be used for creating
* @param {AppTypes.ExtensionManager} extensionManager - The extension manager
* @returns {Types.DisplaySet[]} The list of display sets created for the given instances object
* @param instances is a set of instances all from the same series
* @param servicesManager is the services that can be used for creating
* @returns The list of display sets created for the given instances object
*/
function _getDisplaySetsFromSeries(
instances,
@@ -100,7 +98,6 @@ function _getDisplaySetsFromSeries(
SeriesTime,
ConceptNameCodeSequence,
SOPClassUID,
imageId: predecessorImageId,
} = instance;
validateSameStudyUID(instance.StudyInstanceUID, instances);
@@ -129,7 +126,6 @@ function _getDisplaySetsFromSeries(
isImagingMeasurementReport,
sopClassUids,
instance,
predecessorImageId,
addInstances,
label: SeriesDescription || `${i18n.t('Series')} ${SeriesNumber} - ${i18n.t('SR')}`,
};
@@ -146,7 +142,7 @@ function _getDisplaySetsFromSeries(
* @param extensionManager - The extension manager containing data sources.
*/
async function _load(
srDisplaySet: OhifTypes.DisplaySet,
srDisplaySet: Types.DisplaySet,
servicesManager: AppTypes.ServicesManager,
extensionManager: AppTypes.ExtensionManager
) {
@@ -186,10 +182,6 @@ async function _load(
srDisplaySet.referencedImages = [];
srDisplaySet.measurements = [];
}
const { predecessorImageId } = srDisplaySet;
for (const measurement of srDisplaySet.measurements) {
measurement.predecessorImageId = predecessorImageId;
}
const mappings = measurementService.getSourceMappings(
CORNERSTONE_3D_TOOLS_SOURCE_NAME,
@@ -234,9 +226,17 @@ function _measurementBelongsToDisplaySet({ measurement, displaySet }) {
);
}
/**
* Checks if measurements can be added to a display set.
*
* @param srDisplaySet - The source display set containing measurements.
* @param newDisplaySet - The new display set to check if measurements can be added.
* @param dataSource - The data source used to retrieve image IDs.
* @param servicesManager - The services manager.
*/
function _checkIfCanAddMeasurementsToDisplaySet(
srDisplaySet: OhifTypes.DisplaySet,
newDisplaySet: OhifTypes.DisplaySet,
srDisplaySet,
newDisplaySet,
dataSource,
servicesManager: AppTypes.ServicesManager
) {
@@ -288,7 +288,7 @@ function _checkIfCanAddMeasurementsToDisplaySet(
is3DMeasurement &&
_measurementBelongsToDisplaySet({ measurement, displaySet: newDisplaySet })
) {
addSRAnnotation({ measurement, displaySet: newDisplaySet });
addSRAnnotation(measurement, null, null);
measurement.loaded = true;
measurement.displaySetInstanceUID = newDisplaySet.displaySetInstanceUID;
unloadedMeasurements.splice(j, 1);
@@ -309,12 +309,15 @@ function _checkIfCanAddMeasurementsToDisplaySet(
imageId &&
_measurementReferencesSOPInstanceUID(measurement, ReferencedSOPInstanceUID, frame)
) {
addSRAnnotation({ measurement, imageId, frameNumber: frame, displaySet: newDisplaySet });
addSRAnnotation(measurement, imageId, frame);
// Update measurement properties
measurement.loaded = true;
measurement.imageId = imageId;
measurement.displaySetInstanceUID = newDisplaySet.displaySetInstanceUID;
measurement.ReferencedSOPInstanceUID = ReferencedSOPInstanceUID;
measurement.frameNumber = frame;
unloadedMeasurements.splice(j, 1);
}
}
@@ -322,10 +325,10 @@ function _checkIfCanAddMeasurementsToDisplaySet(
/**
* Checks if a measurement references a specific SOP Instance UID.
* @param {any} measurement - The measurement object.
* @param {string} sopInstanceUID - The SOP Instance UID to check against.
* @param {number} frameNumber - The frame number to check against (optional).
* @returns {boolean} True if the measurement references the specified SOP Instance UID, false otherwise.
* @param measurement - The measurement object.
* @param SOPInstanceUID - The SOP Instance UID to check against.
* @param frameNumber - The frame number to check against (optional).
* @returns True if the measurement references the specified SOP Instance UID, false otherwise.
*/
function _measurementReferencesSOPInstanceUID(measurement, SOPInstanceUID, frameNumber) {
const { coords } = measurement;
@@ -357,8 +360,10 @@ function _measurementReferencesSOPInstanceUID(measurement, SOPInstanceUID, frame
/**
* Retrieves the SOP class handler module.
*
* @param {OhifTypes.Extensions.ExtensionParams} params - The extension parameters.
* @returns {Array} An array containing the SOP class handler modules.
* @param {Object} options - The options for retrieving the SOP class handler module.
* @param {Object} options.servicesManager - The services manager.
* @param {Object} options.extensionManager - The extension manager.
* @returns {Array} An array containing the SOP class handler module.
*/
function getSopClassHandlerModule(params: OhifTypes.Extensions.ExtensionParams) {
const { servicesManager, extensionManager } = params;
@@ -382,8 +387,8 @@ function getSopClassHandlerModule(params: OhifTypes.Extensions.ExtensionParams)
/**
* Retrieves the measurements from the ImagingMeasurementReportContentSequence.
*
* @param {any[]} imagingMeasurementReportContentSequence - The ImagingMeasurementReportContentSequence array.
* @returns {any[]} The array of measurements.
* @param {Array} ImagingMeasurementReportContentSequence - The ImagingMeasurementReportContentSequence array.
* @returns {Array} - The array of measurements.
*/
function _getMeasurements(ImagingMeasurementReportContentSequence) {
const ImagingMeasurements = ImagingMeasurementReportContentSequence.find(
@@ -421,8 +426,8 @@ function _getMeasurements(ImagingMeasurementReportContentSequence) {
/**
* Retrieves merged content sequences by tracking unique identifiers.
*
* @param {any[]} measurementGroups - The measurement groups.
* @returns {Object} The merged content sequences by tracking unique identifiers.
* @param {Array} MeasurementGroups - The measurement groups.
* @returns {Object} - The merged content sequences by tracking unique identifiers.
*/
function _getMergedContentSequencesByTrackingUniqueIdentifiers(MeasurementGroups) {
const mergedContentSequencesByTrackingUniqueIdentifiers = {};
@@ -469,8 +474,8 @@ function _getMergedContentSequencesByTrackingUniqueIdentifiers(MeasurementGroups
* it calls the _processTID1410Measurement function.
* Otherwise, it calls the _processNonGeometricallyDefinedMeasurement function.
*
* @param {any[]} mergedContentSequence - The merged content sequence to process.
* @returns {any} The processed measurement result.
* @param {Array<Object>} mergedContentSequence - The merged content sequence to process.
* @returns {any} - The processed measurement result.
*/
function _processMeasurement(mergedContentSequence) {
if (mergedContentSequence.some(group => isScoordOr3d(group) && !isTextPosition(group))) {
@@ -485,8 +490,8 @@ function _processMeasurement(mergedContentSequence) {
* TID 1410 style measurements have a SCOORD or SCOORD3D at the top level,
* and non-geometric representations where each NUM has "INFERRED FROM" SCOORD/SCOORD3D.
*
* @param {any[]} mergedContentSequence - The merged content sequence containing the measurements.
* @returns {any} The measurement object containing the loaded status, labels, coordinates, tracking unique identifier, and tracking identifier.
* @param mergedContentSequence - The merged content sequence containing the measurements.
* @returns The measurement object containing the loaded status, labels, coordinates, tracking unique identifier, and tracking identifier.
*/
function _processTID1410Measurement(mergedContentSequence) {
// Need to deal with TID 1410 style measurements, which will have a SCOORD or SCOORD3D at the top level,
@@ -559,8 +564,8 @@ function _processTID1410Measurement(mergedContentSequence) {
/**
* Processes the non-geometrically defined measurement from the merged content sequence.
*
* @param {any[]} mergedContentSequence The merged content sequence containing the measurement data.
* @returns {any} The processed measurement object.
* @param mergedContentSequence The merged content sequence containing the measurement data.
* @returns The processed measurement object.
*/
function _processNonGeometricallyDefinedMeasurement(mergedContentSequence) {
const NUMContentItems = mergedContentSequence.filter(group => group.ValueType === 'NUM');
@@ -660,8 +665,8 @@ function _processNonGeometricallyDefinedMeasurement(mergedContentSequence) {
/**
* Extracts coordinates from a graphic item of type SCOORD or SCOORD3D.
* @param {any} graphicItem - The graphic item containing the coordinates.
* @returns {any} The extracted coordinates.
* @param {object} graphicItem - The graphic item containing the coordinates.
* @returns {object} - The extracted coordinates.
*/
const _getCoordsFromSCOORDOrSCOORD3D = graphicItem => {
const { ValueType, GraphicType, GraphicData } = graphicItem;
@@ -675,9 +680,9 @@ const _getCoordsFromSCOORDOrSCOORD3D = graphicItem => {
/**
* Retrieves the label and value from the provided ConceptNameCodeSequence and MeasuredValueSequence.
* @param {any} conceptNameCodeSequence - The ConceptNameCodeSequence object.
* @param {any} measuredValueSequence - The MeasuredValueSequence object.
* @returns {Object} An object containing the label and value.
* @param {Object} ConceptNameCodeSequence - The ConceptNameCodeSequence object.
* @param {Object} MeasuredValueSequence - The MeasuredValueSequence object.
* @returns {Object} - An object containing the label and value.
* The label represents the CodeMeaning from the ConceptNameCodeSequence.
* The value represents the formatted NumericValue and CodeValue from the MeasuredValueSequence.
* Example: { label: 'Long Axis', value: '31.00 mm' }
@@ -696,8 +701,8 @@ function _getLabelFromMeasuredValueSequence(ConceptNameCodeSequence, MeasuredVal
/**
* Retrieves a list of referenced images from the Imaging Measurement Report Content Sequence.
*
* @param {any[]} imagingMeasurementReportContentSequence - The Imaging Measurement Report Content Sequence.
* @returns {any[]} The list of referenced images.
* @param {Array} ImagingMeasurementReportContentSequence - The Imaging Measurement Report Content Sequence.
* @returns {Array} - The list of referenced images.
*/
function _getReferencedImagesList(ImagingMeasurementReportContentSequence) {
const ImageLibrary = ImagingMeasurementReportContentSequence.find(
@@ -744,7 +749,7 @@ function _getReferencedImagesList(ImagingMeasurementReportContentSequence) {
* Otherwise, the sequence is wrapped in an array and returned.
*
* @param {any} sequence - The DICOM sequence to convert.
* @returns {any[]} The converted array.
* @returns {any[]} - The converted array.
*/
function _getSequenceAsArray(sequence) {
if (!sequence) {
+25 -2
View File
@@ -9,13 +9,18 @@ import {
LengthTool,
PlanarFreehandROITool,
RectangleROITool,
utilities as csToolsUtils,
} from '@cornerstonejs/tools';
import { Types } from '@ohif/core';
import { Types, MeasurementService } from '@ohif/core';
import { Enums as CSExtensionEnums } from '@ohif/extension-cornerstone';
import DICOMSRDisplayTool from './tools/DICOMSRDisplayTool';
import SCOORD3DPointTool from './tools/SCOORD3DPointTool';
import SRSCOOR3DProbeMapper from './utils/SRSCOOR3DProbeMapper';
import addToolInstance from './utils/addToolInstance';
import toolNames from './tools/toolNames';
const { CORNERSTONE_3D_TOOLS_SOURCE_NAME, CORNERSTONE_3D_TOOLS_SOURCE_VERSION } = CSExtensionEnums;
/**
* @param {object} configuration
*/
@@ -23,6 +28,8 @@ export default function init({
configuration = {},
servicesManager,
}: Types.Extensions.ExtensionParams): void {
const { measurementService, cornerstoneViewportService } = servicesManager.services;
addToolInstance(toolNames.DICOMSRDisplay, DICOMSRDisplayTool);
addToolInstance(toolNames.SRLength, LengthTool);
addToolInstance(toolNames.SRBidirectional, BidirectionalTool);
@@ -32,10 +39,26 @@ export default function init({
addToolInstance(toolNames.SRAngle, AngleTool);
addToolInstance(toolNames.SRPlanarFreehandROI, PlanarFreehandROITool);
addToolInstance(toolNames.SRRectangleROI, RectangleROITool);
addToolInstance(toolNames.SRSCOORD3DPoint, SCOORD3DPointTool);
// TODO - fix the SR display of Cobb Angle, as it joins the two lines
addToolInstance(toolNames.SRCobbAngle, CobbAngleTool);
const csTools3DVer1MeasurementSource = measurementService.getSource(
CORNERSTONE_3D_TOOLS_SOURCE_NAME,
CORNERSTONE_3D_TOOLS_SOURCE_VERSION
);
const { POINT } = measurementService.VALUE_TYPES;
measurementService.addMapping(
csTools3DVer1MeasurementSource,
'SRSCOORD3DPoint',
POINT,
SRSCOOR3DProbeMapper.toAnnotation,
SRSCOOR3DProbeMapper.toMeasurement.bind(null, { servicesManager })
);
// Modify annotation tools to use dashed lines on SR
const dashedLine = {
lineDash: '4,4',
@@ -0,0 +1,203 @@
import { type Types } from '@cornerstonejs/core';
import {
annotation,
drawing,
utilities,
Types as cs3DToolsTypes,
AnnotationDisplayTool,
} from '@cornerstonejs/tools';
import toolNames from './toolNames';
import { Annotation } from '@cornerstonejs/tools/dist/types/types';
export default class SCOORD3DPointTool extends AnnotationDisplayTool {
static toolName = toolNames.SRSCOORD3DPoint;
constructor(
toolProps = {},
defaultToolProps = {
configuration: {},
}
) {
super(toolProps, defaultToolProps);
}
_getTextBoxLinesFromLabels(labels) {
// TODO -> max 5 for now (label + shortAxis + longAxis), need a generic solution for this!
const labelLength = Math.min(labels.length, 5);
const lines = [];
return lines;
}
// This tool should not inherit from AnnotationTool and we should not need
// to add the following lines.
isPointNearTool = () => null;
getHandleNearImagePoint = () => null;
renderAnnotation = (enabledElement: Types.IEnabledElement, svgDrawingHelper: any): void => {
const { viewport } = enabledElement;
const { element } = viewport;
const annotations = annotation.state.getAnnotations(this.getToolName(), element);
// Todo: We don't need this anymore, filtering happens in triggerAnnotationRender
if (!annotations?.length) {
return;
}
// Filter toolData to only render the data for the active SR.
const filteredAnnotations = annotations;
if (!viewport._actors?.size) {
return;
}
const styleSpecifier: cs3DToolsTypes.AnnotationStyle.StyleSpecifier = {
toolGroupId: this.toolGroupId,
toolName: this.getToolName(),
viewportId: enabledElement.viewport.id,
};
for (let i = 0; i < filteredAnnotations.length; i++) {
const annotation = filteredAnnotations[i];
const annotationUID = annotation.annotationUID;
const { renderableData } = annotation.data;
const { POINT: points } = renderableData;
styleSpecifier.annotationUID = annotationUID;
const lineWidth = this.getStyle('lineWidth', styleSpecifier, annotation);
const lineDash = this.getStyle('lineDash', styleSpecifier, annotation);
const color = this.getStyle('color', styleSpecifier, annotation);
const options = {
color,
lineDash,
lineWidth,
};
const point = points[0][0];
// check if viewport can render it
const viewable = viewport.isReferenceViewable(
{ FrameOfReferenceUID: annotation.metadata.FrameOfReferenceUID, cameraFocalPoint: point },
{ asNearbyProjection: true }
);
if (!viewable) {
continue;
}
// render the point
const arrowPointCanvas = viewport.worldToCanvas(point);
// Todo: configure this
const arrowEndCanvas = [arrowPointCanvas[0] + 20, arrowPointCanvas[1] + 20];
const canvasCoordinates = [arrowPointCanvas, arrowEndCanvas];
drawing.drawArrow(
svgDrawingHelper,
annotationUID,
'1',
canvasCoordinates[1],
canvasCoordinates[0],
{
color: options.color,
width: options.lineWidth,
}
);
this.renderTextBox(
svgDrawingHelper,
viewport,
canvasCoordinates,
annotation,
styleSpecifier,
options
);
}
};
renderTextBox(
svgDrawingHelper,
viewport,
canvasCoordinates,
annotation,
styleSpecifier,
options = {}
) {
if (!canvasCoordinates || !annotation) {
return;
}
const { annotationUID, data = {} } = annotation;
const { labels } = data;
const textLines = [];
for (const label of labels) {
// make this generic
// fix this
if (label.label === '363698007') {
textLines.push(`Finding Site: ${label.value}`);
}
}
const { color } = options;
const adaptedCanvasCoordinates = canvasCoordinates;
// adapt coordinates if there is an adapter
const canvasTextBoxCoords = utilities.drawing.getTextBoxCoordsCanvas(adaptedCanvasCoordinates);
if (!annotation.data?.handles?.textBox?.worldPosition) {
annotation.data.handles.textBox.worldPosition = viewport.canvasToWorld(canvasTextBoxCoords);
}
const textBoxPosition = viewport.worldToCanvas(annotation.data.handles.textBox.worldPosition);
const textBoxUID = '1';
const textBoxOptions = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
const boundingBox = drawing.drawLinkedTextBox(
svgDrawingHelper,
annotationUID,
textBoxUID,
textLines,
textBoxPosition,
canvasCoordinates,
{},
{
...textBoxOptions,
color,
}
);
const { x: left, y: top, width, height } = boundingBox;
annotation.data.handles.textBox.worldBoundingBox = {
topLeft: viewport.canvasToWorld([left, top]),
topRight: viewport.canvasToWorld([left + width, top]),
bottomLeft: viewport.canvasToWorld([left, top + height]),
bottomRight: viewport.canvasToWorld([left + width, top + height]),
};
}
public getLinkedTextBoxStyle(
specifications: cs3DToolsTypes.AnnotationStyle.StyleSpecifier,
annotation?: Annotation
): Record<string, unknown> {
// Todo: this function can be used to set different styles for different toolMode
// for the textBox.
return {
visibility: this.getStyle('textBoxVisibility', specifications, annotation),
fontFamily: this.getStyle('textBoxFontFamily', specifications, annotation),
fontSize: this.getStyle('textBoxFontSize', specifications, annotation),
color: this.getStyle('textBoxColor', specifications, annotation),
shadow: this.getStyle('textBoxShadow', specifications, annotation),
background: this.getStyle('textBoxBackground', specifications, annotation),
lineWidth: this.getStyle('textBoxLinkLineWidth', specifications, annotation),
lineDash: this.getStyle('textBoxLinkLineDash', specifications, annotation),
};
}
}
@@ -9,6 +9,7 @@ const toolNames = {
SRCobbAngle: 'SRCobbAngle',
SRRectangleROI: 'SRRectangleROI',
SRPlanarFreehandROI: 'SRPlanarFreehandROI',
SRSCOORD3DPoint: 'SRSCOORD3DPoint',
};
export default toolNames;
@@ -0,0 +1,71 @@
const SRSCOOR3DProbe = {
toAnnotation: measurement => {},
/**
* Maps cornerstone annotation event data to measurement service format.
*
* @param {Object} cornerstone Cornerstone event data
* @return {Measurement} Measurement instance
*/
toMeasurement: ({ servicesManager, getValueTypeFromToolType }, csToolsEventDetail) => {
const { displaySetService } = servicesManager.services;
const { annotation } = csToolsEventDetail;
const { metadata, data, annotationUID } = annotation;
if (!metadata || !data) {
console.warn('Probe tool: Missing metadata or data');
return null;
}
const { toolName, FrameOfReferenceUID } = metadata;
const { points } = data.handles;
const displaySets = displaySetService
.getActiveDisplaySets()
.filter(ds => ds.FrameOfReferenceUID === FrameOfReferenceUID);
const displaySet = displaySets.filter(ds => ds.isReconstructable)[0] || displaySets[0];
const { StudyInstanceUID: referenceStudyUID, SeriesInstanceUID: referenceSeriesUID } =
displaySets[0] || {};
const displayText = getDisplayText(annotation);
return {
uid: annotationUID,
points,
metadata,
referenceStudyUID,
referenceSeriesUID,
displaySetInstanceUID: displaySet?.displaySetInstanceUID,
toolName: metadata.toolName,
label: data.label,
displayText: displayText,
data: data.cachedStats,
type: getValueTypeFromToolType?.(toolName) ?? null,
};
},
};
function getDisplayText(annotation) {
const { data } = annotation;
if (!data) {
return [''];
}
const { labels } = data;
const displayText = [];
for (const label of labels) {
// make this generic
if (label.label === '33636980076') {
displayText.push(`Finding Site: ${label.value}`);
}
}
return {
primary: displayText,
secondary: [],
};
}
export default SRSCOOR3DProbe;
@@ -7,53 +7,8 @@ import toolNames from '../tools/toolNames';
const { MeasurementReport } = adaptersSR.Cornerstone3D;
/**
* Adds a DICOM SR (Structured Report) annotation to the annotation manager.
* This function processes measurement data from DICOM SR and converts it into
* a format suitable for display in the Cornerstone3D viewer.
*
* @param {Object} params - The parameters object
* @param {Object} params.measurement - The DICOM SR measurement data containing coordinates, labels, and metadata
* @param {Array} params.measurement.coords - Array of coordinate objects with GraphicType, ValueType, and other properties
* @param {string} params.measurement.TrackingUniqueIdentifier - Unique identifier for the measurement
* @param {string} params.measurement.TrackingIdentifier - Tracking identifier for adapter lookup
* @param {Array} [params.measurement.labels] - Optional array of label objects
* @param {string} [params.measurement.displayText] - Optional display text for the annotation
* @param {Object} [params.measurement.textBox] - Optional text box configuration
* @param {string|null} [params.imageId] - Optional image ID for the referenced image (defaults to null)
* @param {number|null} [params.frameNumber] - Optional frame number for multi-frame images (defaults to null)
* @param {Object} params.displaySet - The display set containing the image
* @param {string} params.displaySet.displaySetInstanceUID - Unique identifier for the display set
* @returns {void}
*
* @example
* ```typescript
* addSRAnnotation({
* measurement: {
* TrackingUniqueIdentifier: '1.2.3.4.5',
* TrackingIdentifier: 'POINT',
* coords: [{
* GraphicType: 'POINT',
* ValueType: 'SCOORD',
* // ... other coordinate properties
* }],
* labels: [{ value: 'Measurement Point' }],
* displayText: 'Point measurement'
* },
* imageId: 'wadouri:file://path/to/image.dcm', // Optional
* frameNumber: 0, // Optional
* displaySet: { displaySetInstanceUID: '1.2.3.4' }
* });
* ```
*/
export default function addSRAnnotation({ measurement, imageId = null, frameNumber = null, displaySet }) {
/** @type {string} The tool name to use for the annotation, defaults to DICOMSRDisplay */
export default function addSRAnnotation(measurement, imageId, frameNumber) {
let toolName = toolNames.DICOMSRDisplay;
/**
* @type {Object} Renderable data organized by graphic type
* Groups coordinate data by GraphicType for efficient rendering
*/
const renderableData = measurement.coords.reduce((acc, coordProps) => {
acc[coordProps.GraphicType] = acc[coordProps.GraphicType] || [];
acc[coordProps.GraphicType].push(getRenderableData({ ...coordProps, imageId }));
@@ -64,58 +19,37 @@ export default function addSRAnnotation({ measurement, imageId = null, frameNumb
const { ValueType: valueType, GraphicType: graphicType } = measurement.coords[0];
const graphicTypePoints = renderableData[graphicType];
/**
* TODO: Read the tool name from the DICOM SR identification type in the future.
*/
/** TODO: Read the tool name from the DICOM SR identification type in the future. */
let frameOfReferenceUID = null;
let planeRestriction = null;
/**
* Store the view reference for use in initial navigation
*/
if (imageId) {
const imagePlaneModule = metaData.get('imagePlaneModule', imageId);
frameOfReferenceUID = imagePlaneModule?.frameOfReferenceUID;
}
/**
* Store the view reference for use in initial navigation
*/
if (valueType === 'SCOORD3D') {
const adapter = MeasurementReport.getAdapterForTrackingIdentifier(
measurement.TrackingIdentifier
);
if (!adapter) {
toolName = toolNames.SRSCOORD3DPoint;
}
// get the ReferencedFrameOfReferenceUID from the measurement
frameOfReferenceUID = measurement.coords[0].ReferencedFrameOfReferenceSequence;
planeRestriction = {
FrameOfReferenceUID: frameOfReferenceUID,
point: graphicTypePoints[0][0],
};
}
/**
* Store the view reference for use in initial navigation
*/
measurement.viewReference = {
planeRestriction,
FrameOfReferenceUID: frameOfReferenceUID,
referencedImageId: imageId,
};
/**
* @type {Types.Annotation} The annotation object to be added to the annotation manager
* Contains all necessary metadata and data for rendering the DICOM SR measurement
*/
const SRAnnotation: Types.Annotation = {
annotationUID: TrackingUniqueIdentifier,
highlighted: false,
isLocked: false,
isPreview: toolName === toolNames.DICOMSRDisplay,
invalidated: false,
metadata: {
toolName,
planeRestriction,
valueType,
graphicType,
FrameOfReferenceUID: frameOfReferenceUID,
referencedImageId: imageId,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
},
data: {
label: measurement.labels?.[0]?.value || undefined,
@@ -133,11 +67,8 @@ export default function addSRAnnotation({ measurement, imageId = null, frameNumb
};
/**
* Add the annotation to the annotation state manager.
* Note: Using annotation.state.addAnnotation() instead of annotationManager.addAnnotation()
* because the latter was not triggering annotation_added events properly.
*
* @param {Types.Annotation} SRAnnotation - The annotation to add
* const annotationManager = annotation.annotationState.getAnnotationManager();
* was not triggering annotation_added events.
*/
annotation.state.addAnnotation(SRAnnotation);
}
@@ -54,11 +54,6 @@ export default function hydrateStructuredReport(
const disableEditing = customizationService.getCustomization('panelMeasurement.disableEditing');
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
const {
StudyInstanceUID: studyUID,
SeriesInstanceUID: seriesUID,
instance: { SOPInstanceUID: sopUID },
} = displaySet;
// TODO -> We should define a strict versioning somewhere.
const mappings = measurementService.getSourceMappings(
@@ -72,16 +67,24 @@ export default function hydrateStructuredReport(
);
}
const instance = DicomMetadataStore.getInstance(studyUID, seriesUID, sopUID);
const instance = DicomMetadataStore.getInstance(
displaySet.StudyInstanceUID,
displaySet.SeriesInstanceUID,
displaySet.SOPInstanceUID
);
const sopInstanceUIDToImageId = {};
const imageIdsForToolState = {};
displaySet.measurements.forEach(measurement => {
const { ReferencedSOPInstanceUID, imageId, frameNumber = 1 } = measurement;
const key = `${ReferencedSOPInstanceUID}:${frameNumber}`;
const { ReferencedSOPInstanceUID, imageId, frameNumber } = measurement;
if (!sopInstanceUIDToImageId[key]) {
sopInstanceUIDToImageId[key] = imageId;
if (!sopInstanceUIDToImageId[ReferencedSOPInstanceUID]) {
sopInstanceUIDToImageId[ReferencedSOPInstanceUID] = imageId;
imageIdsForToolState[ReferencedSOPInstanceUID] = [];
}
if (!imageIdsForToolState[ReferencedSOPInstanceUID][frameNumber]) {
imageIdsForToolState[ReferencedSOPInstanceUID][frameNumber] = imageId;
}
});
@@ -130,8 +133,10 @@ export default function hydrateStructuredReport(
// dcmjs and Cornerstone3D has structural defect in supporting multi-frame
// files, and looking up the imageId from sopInstanceUIDToImageId results
// in the wrong value.
const frameNumber = toolData.annotation.data?.frameNumber || 1;
const imageId = sopInstanceUIDToImageId[`${toolData.sopInstanceUid}:${frameNumber}`];
const frameNumber = (toolData.annotation.data && toolData.annotation.data.frameNumber) || 1;
const imageId =
imageIdsForToolState[toolData.sopInstanceUid][frameNumber] ||
sopInstanceUIDToImageId[toolData.sopInstanceUid];
if (!imageIds.includes(imageId)) {
imageIds.push(imageId);
@@ -170,7 +175,9 @@ export default function hydrateStructuredReport(
// files, and looking up the imageId from sopInstanceUIDToImageId results
// in the wrong value.
const frameNumber = (toolData.annotation.data && toolData.annotation.data.frameNumber) || 1;
const imageId = sopInstanceUIDToImageId[`${toolData.sopInstanceUid}:${frameNumber}`];
const imageId =
imageIdsForToolState[toolData.sopInstanceUid][frameNumber] ||
sopInstanceUIDToImageId[toolData.sopInstanceUid];
if (!imageId) {
return getReferenceData3D(toolData, servicesManager);
@@ -201,7 +208,6 @@ export default function hydrateStructuredReport(
const annotation = {
annotationUID: toolData.annotation.annotationUID,
data: toolData.annotation.data,
predecessorImageId: toolData.predecessorImageId,
metadata: {
...referenceData,
toolName: annotationType,
@@ -3,783 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
### Bug Fixes
* **SegmentationStyle:** Fix inactive contour visibility and styling. ([#5563](https://github.com/OHIF/Viewers/issues/5563)) ([5c17c26](https://github.com/OHIF/Viewers/commit/5c17c262eaa5c1229033cfff4b3e7709e874611f))
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
### Bug Fixes
* **interpolation:** Auto accept interpolation when the interpolation process is completed. ([#5555](https://github.com/OHIF/Viewers/issues/5555)) ([834ae3c](https://github.com/OHIF/Viewers/commit/834ae3c762ca309187afebdf77bad1ad9a57f03f))
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
### Bug Fixes
* **SegmentationTools:** [Bug] Changes of brush/eraser radius with hotkey do not reflect on segmentation tool ([#5535](https://github.com/OHIF/Viewers/issues/5535)) ([29bd87c](https://github.com/OHIF/Viewers/commit/29bd87c8c0592a9a1350e687b862f5452627aece))
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
### Bug Fixes
* **3DSegmentation:** [Bug] The viewports become blank when loading the seg file in advanced layout after closing the seg file from any other advanced layout ([#5505](https://github.com/OHIF/Viewers/issues/5505)) ([76f7d4e](https://github.com/OHIF/Viewers/commit/76f7d4e23aa359a3397b10adf0bf09df3763f190))
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
### Bug Fixes
* Pass the correct sop uid + frame for rehydration to prevent associating rehydrated measurements with the wrong data ([#5506](https://github.com/OHIF/Viewers/issues/5506)) ([5037802](https://github.com/OHIF/Viewers/commit/503780247ce7228c602a539fd88ea374e7d0d42f)), closes [#2404](https://github.com/OHIF/Viewers/issues/2404)
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
### Bug Fixes
* **segmentation:** Lock all rehydrated segmentation segments when panelSegmentation.disableEditing is true. ([#5503](https://github.com/OHIF/Viewers/issues/5503)) ([170e860](https://github.com/OHIF/Viewers/commit/170e860aa1b786ab6056cf31076804302a2bc462))
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone-dynamic-volume
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.12.0-beta.94",
"version": "3.11.0",
"description": "OHIF extension for 4D volumes data",
"author": "OHIF",
"license": "MIT",
@@ -29,21 +29,21 @@
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
},
"peerDependencies": {
"@ohif/core": "3.12.0-beta.94",
"@ohif/extension-cornerstone": "3.12.0-beta.94",
"@ohif/extension-default": "3.12.0-beta.94",
"@ohif/i18n": "3.12.0-beta.94",
"@ohif/ui": "3.12.0-beta.94",
"dcmjs": "0.45.0",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
"prop-types": "15.8.1",
"react": "18.3.1"
"@ohif/core": "3.11.0",
"@ohif/extension-cornerstone": "3.11.0",
"@ohif/extension-default": "3.11.0",
"@ohif/i18n": "3.11.0",
"@ohif/ui": "3.11.0",
"dcmjs": "0.43.1",
"dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
"react": "^18.3.1"
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.11.3",
"@cornerstonejs/tools": "4.11.3",
"classnames": "2.5.1"
"@babel/runtime": "^7.20.13",
"@cornerstonejs/core": "^3.32.5",
"@cornerstonejs/tools": "^3.32.5",
"classnames": "^2.3.2"
}
}
@@ -1,10 +1,8 @@
import * as importedActions from './actions';
import { utilities, Enums } from '@cornerstonejs/tools';
import { cache } from '@cornerstonejs/core';
import { utils } from '@ohif/core';
import * as importedActions from './actions';
const { downloadCsv } = utils;
const LABELMAP = Enums.SegmentationRepresentations.Labelmap;
const commandsModule = ({ commandsManager, servicesManager }: withAppTypes) => {
const services = servicesManager.services;
@@ -39,7 +37,7 @@ const commandsModule = ({ commandsManager, servicesManager }: withAppTypes) => {
});
return computedDisplaySets;
},
exportTimeReportCSV: ({ segmentations, summaryStats }) => {
exportTimeReportCSV: ({ segmentations, config, options, summaryStats }) => {
const dynamic4DDisplaySet = actions.getDynamic4DDisplaySet();
const volumeId = dynamic4DDisplaySet?.displaySetInstanceUID;
@@ -205,7 +203,15 @@ const commandsModule = ({ commandsManager, servicesManager }: withAppTypes) => {
// Generate filename and trigger download
const filename = `${instance.PatientID}.csv`;
downloadCsv(csvContent, { filename });
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
swapDynamicWithComputedDisplaySet: ({ displaySet }) => {
const computedDisplaySet = displaySet;
+1 -840
View File
@@ -3,846 +3,7 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)
### Bug Fixes
* **DicomUpload:** Switch to use ui-next components and colors ([#5576](https://github.com/OHIF/Viewers/issues/5576)) ([62d6bf4](https://github.com/OHIF/Viewers/commit/62d6bf437b167ac3e60a0f134869c9f96d199d0f))
# [3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)
### Bug Fixes
* Remove dead code and fix rectangle roi rehydration ([#5490](https://github.com/OHIF/Viewers/issues/5490)) ([9ca02b4](https://github.com/OHIF/Viewers/commit/9ca02b4071f77600f7dcd87930fecdcf3d1c249f))
# [3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)
### Bug Fixes
* **SegmentationStyle:** Fix inactive contour visibility and styling. ([#5563](https://github.com/OHIF/Viewers/issues/5563)) ([5c17c26](https://github.com/OHIF/Viewers/commit/5c17c262eaa5c1229033cfff4b3e7709e874611f))
# [3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)
### Bug Fixes
* **segmentation:** Allow for manually added label map and contour segmentations to be used as viewport data overlays. ([#5562](https://github.com/OHIF/Viewers/issues/5562)) ([02f6744](https://github.com/OHIF/Viewers/commit/02f6744dab993f16cf2516fd5f657e0743e3fa42))
# [3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)
### Bug Fixes
* **interpolation:** Auto accept interpolation when the interpolation process is completed. ([#5555](https://github.com/OHIF/Viewers/issues/5555)) ([834ae3c](https://github.com/OHIF/Viewers/commit/834ae3c762ca309187afebdf77bad1ad9a57f03f))
# [3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)
### Bug Fixes
* **segmentation:** When synchronizing a segmentation representation, use the type of the source viewport segmentation to determine the type of the target viewport segmentation ([#5546](https://github.com/OHIF/Viewers/issues/5546)) ([a0556b0](https://github.com/OHIF/Viewers/commit/a0556b08be98e0bba950ad7b9b575d7b971104ba))
# [3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)
### Bug Fixes
* **SegmentationTools:** [Bug] Changes of brush/eraser radius with hotkey do not reflect on segmentation tool ([#5535](https://github.com/OHIF/Viewers/issues/5535)) ([29bd87c](https://github.com/OHIF/Viewers/commit/29bd87c8c0592a9a1350e687b862f5452627aece))
# [3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)
### Bug Fixes
* **3DSegmentation:** [Bug] The viewports become blank when loading the seg file in advanced layout after closing the seg file from any other advanced layout ([#5505](https://github.com/OHIF/Viewers/issues/5505)) ([76f7d4e](https://github.com/OHIF/Viewers/commit/76f7d4e23aa359a3397b10adf0bf09df3763f190))
# [3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)
### Features
* **jpeg2000:** Add 16-bit RGB support to JPEG2000 decoder ([#5519](https://github.com/OHIF/Viewers/issues/5519)) ([a154443](https://github.com/OHIF/Viewers/commit/a1544432db42bf77864bb7df2f757cae819a4b4d))
# [3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)
### Bug Fixes
* Pass the correct sop uid + frame for rehydration to prevent associating rehydrated measurements with the wrong data ([#5506](https://github.com/OHIF/Viewers/issues/5506)) ([5037802](https://github.com/OHIF/Viewers/commit/503780247ce7228c602a539fd88ea374e7d0d42f)), closes [#2404](https://github.com/OHIF/Viewers/issues/2404)
# [3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)
### Bug Fixes
* **segmentation:** Lock all rehydrated segmentation segments when panelSegmentation.disableEditing is true. ([#5503](https://github.com/OHIF/Viewers/issues/5503)) ([170e860](https://github.com/OHIF/Viewers/commit/170e860aa1b786ab6056cf31076804302a2bc462))
# [3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)
### Bug Fixes
* Segmentation not displayed and unable to draw segments in volume viewport after converting Labelmap to Surface ([#5488](https://github.com/OHIF/Viewers/issues/5488)) ([faea09e](https://github.com/OHIF/Viewers/commit/faea09e7ef2667aad5cef1efc2a6516677ca2915))
# [3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)
### Bug Fixes
* **segmentationService:** prevent no representation crash ([#5495](https://github.com/OHIF/Viewers/issues/5495)) ([3137aed](https://github.com/OHIF/Viewers/commit/3137aed0170196a61e16c6dac0c15bcc41691919))
# [3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)
### Bug Fixes
* **security:** Use exact versioning for dependencies in package.json files. ([#5494](https://github.com/OHIF/Viewers/issues/5494)) ([c7d2017](https://github.com/OHIF/Viewers/commit/c7d2017f081c5803a70bab6c75bba0c975028125))
# [3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)
### Bug Fixes
* **segmentation:** Segmentation not displayed and unable to draw segments when switching back to volume/stack viewport from 3D viewport ([#5430](https://github.com/OHIF/Viewers/issues/5430)) ([78df8ff](https://github.com/OHIF/Viewers/commit/78df8ff03a371904a390c63a95628d5511dad136))
# [3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)
### Bug Fixes
* **Segmentation:** [Bug [#5420](https://github.com/OHIF/Viewers/issues/5420)] Segmentation color resets after using toggleOneUp ([#5465](https://github.com/OHIF/Viewers/issues/5465)) ([2c6ce21](https://github.com/OHIF/Viewers/commit/2c6ce21c8f79f8b3e6dc47b5aa6f717b6b5cbd2a))
# [3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)
### Features
* **MeasurementService:** add rendering of unmapped measurements ([#5416](https://github.com/OHIF/Viewers/issues/5416)) ([851e74d](https://github.com/OHIF/Viewers/commit/851e74d7b867a806befb5d85fd71ff9a75e9f2d2))
# [3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)
### Bug Fixes
* duplicate segmentation entries on layout switch ([#5458](https://github.com/OHIF/Viewers/issues/5458)) ([9e951e8](https://github.com/OHIF/Viewers/commit/9e951e88005af505ae0c07fbcd3366de12b773dd))
# [3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)
### Bug Fixes
* **segmentation:** Restored segment label tool in longitudinal mode. ([#5443](https://github.com/OHIF/Viewers/issues/5443)) ([dd86a8e](https://github.com/OHIF/Viewers/commit/dd86a8eabd0712d25e7652a242377fe09597e8d5))
# [3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)
### Bug Fixes
* **i18n:** Add and update i18n Translation for Toolbar Tool Names ([#5392](https://github.com/OHIF/Viewers/issues/5392)) ([7783d0f](https://github.com/OHIF/Viewers/commit/7783d0f558bbb7016c29513b6fe76ed069dbd75c))
# [3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)
### Features
* **Segmentation:** Segmentation highlight animation function selection ([#5401](https://github.com/OHIF/Viewers/issues/5401)) ([69dbe27](https://github.com/OHIF/Viewers/commit/69dbe2778493cdfc7a8da5e757c95217bb31edc2))
# [3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)
### Bug Fixes
* **SegmentationService:** _getSegmentCenter wrongly handling seg center availability ([#5396](https://github.com/OHIF/Viewers/issues/5396)) ([74b82bd](https://github.com/OHIF/Viewers/commit/74b82bd93442411ad68f4872992126c40321eb9e))
# [3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)
### Bug Fixes
* **cornerstone-dicom-rt:** adding caching usage to cornerstone-dicom-rt SOP Class Handler ([#5387](https://github.com/OHIF/Viewers/issues/5387)) ([d6ea179](https://github.com/OHIF/Viewers/commit/d6ea179ac43a47d4011b8dcaf59d79d99382d6c8))
# [3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)
### Bug Fixes
* seg preview ([#5338](https://github.com/OHIF/Viewers/issues/5338)) ([d91cc23](https://github.com/OHIF/Viewers/commit/d91cc230e5231ca32ee28736f661a1497f7834c5))
# [3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)
### Bug Fixes
* add back clear segmentation representations ([#5336](https://github.com/OHIF/Viewers/issues/5336)) ([21d6ba2](https://github.com/OHIF/Viewers/commit/21d6ba2bb30df5b99bf5728163caff514aaa5dcd))
# [3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)
### Bug Fixes
* Segmentation stats customization module ([#5324](https://github.com/OHIF/Viewers/issues/5324)) ([b9d6f55](https://github.com/OHIF/Viewers/commit/b9d6f558cbe5957f83e6d92305a78662a0b186ed))
# [3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)
### Features
* Jump to measurement moves the camera if it is not in the viewport ([#5023](https://github.com/OHIF/Viewers/issues/5023)) ([6fe9df6](https://github.com/OHIF/Viewers/commit/6fe9df6ec93c0f37e3bb9f8bf6425bae025e75c8))
# [3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)
### Features
* Add WSI bulk data annotations support (ANN) ([#4972](https://github.com/OHIF/Viewers/issues/4972)) ([2ed6818](https://github.com/OHIF/Viewers/commit/2ed681817142b13971bb17b3058be26bbab6b90b))
# [3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)
### Features
* **orientationMarkers:** improved the orientation markers with a simplified version ([#5328](https://github.com/OHIF/Viewers/issues/5328)) ([266b1f5](https://github.com/OHIF/Viewers/commit/266b1f58f01ac6742a9bb40dda28459e7cddc683))
# [3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
# [3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)
# [3.11.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.11.0) (2025-08-05)
**Note:** Version bump only for package @ohif/extension-cornerstone
+2 -6
View File
@@ -1,13 +1,9 @@
const base = require('../../jest.config.base.js');
const pkg = require('./package');
module.exports = {
...base,
moduleNameMapper: {
...base.moduleNameMapper,
'@ohif/(.*)': '<rootDir>/../../platform/$1/src',
'^@cornerstonejs/([^/]+)/(.*)$': '<rootDir>/../../node_modules/@cornerstonejs/$1/dist/esm/$2',
'^@cornerstonejs/([^/]+)$': '<rootDir>/../../node_modules/@cornerstonejs/$1/dist/esm',
},
displayName: pkg.name,
// rootDir: "../.."
// testMatch: [
// //`<rootDir>/platform/${pack.name}/**/*.spec.js`
+31 -33
View File
@@ -1,6 +1,6 @@
{
"name": "@ohif/extension-cornerstone",
"version": "3.12.0-beta.94",
"version": "3.11.0",
"description": "OHIF extension for Cornerstone",
"author": "OHIF",
"license": "MIT",
@@ -31,43 +31,41 @@
"dev:cornerstone": "yarn run dev",
"build": "cross-env NODE_ENV=production webpack --progress --config .webpack/webpack.prod.js",
"build:package-1": "yarn run build",
"start": "yarn run dev",
"test:unit": "jest --watchAll",
"test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests"
"start": "yarn run dev"
},
"peerDependencies": {
"@cornerstonejs/codec-charls": "1.2.3",
"@cornerstonejs/codec-libjpeg-turbo-8bit": "1.2.2",
"@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.11.3",
"@ohif/core": "3.12.0-beta.94",
"@ohif/ui": "3.12.0-beta.94",
"dcmjs": "0.45.0",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-resize-detector": "10.0.1"
"@cornerstonejs/codec-charls": "^1.2.3",
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^3.32.5",
"@ohif/core": "3.11.0",
"@ohif/ui": "3.11.0",
"dcmjs": "0.43.1",
"dicom-parser": "^1.8.21",
"hammerjs": "^2.0.8",
"prop-types": "^15.6.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-resize-detector": "^10.0.1"
},
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.11.3",
"@cornerstonejs/ai": "4.11.3",
"@cornerstonejs/core": "4.11.3",
"@cornerstonejs/labelmap-interpolation": "4.11.3",
"@cornerstonejs/polymorphic-segmentation": "4.11.3",
"@cornerstonejs/tools": "4.11.3",
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^3.32.5",
"@cornerstonejs/ai": "^3.32.5",
"@cornerstonejs/core": "^3.32.5",
"@cornerstonejs/labelmap-interpolation": "^3.32.5",
"@cornerstonejs/polymorphic-segmentation": "^3.32.5",
"@cornerstonejs/tools": "^3.32.5",
"@itk-wasm/morphological-contour-interpolation": "1.1.0",
"@kitware/vtk.js": "32.12.0",
"html2canvas": "1.4.1",
"lodash.compact": "3.0.1",
"lodash.debounce": "4.0.8",
"lodash.flatten": "4.4.0",
"lodash.merge": "4.6.2",
"lodash.zip": "4.2.0",
"shader-loader": "1.3.1",
"worker-loader": "3.0.8"
"html2canvas": "^1.4.1",
"lodash.compact": "^3.0.1",
"lodash.debounce": "^4.0.8",
"lodash.flatten": "^4.4.0",
"lodash.merge": "^4.6.2",
"lodash.zip": "^4.2.0",
"shader-loader": "^1.3.1",
"worker-loader": "^3.0.8"
}
}
@@ -1,6 +1,12 @@
import React, { useEffect, useState, useMemo } from 'react';
import React, { useEffect, useState, useMemo, useRef } from 'react';
import classNames from 'classnames';
import { metaData, Enums, getEnabledElement } from '@cornerstonejs/core';
import {
metaData,
Enums,
Types,
getEnabledElement,
utilities as coreUtilities,
} from '@cornerstonejs/core';
import { utilities } from '@cornerstonejs/tools';
import { vec3 } from 'gl-matrix';
@@ -16,36 +22,75 @@ function ViewportOrientationMarkers({
servicesManager,
orientationMarkers = ['top', 'left'],
}: withAppTypes) {
const [cameraModifiedTime, setCameraModifiedTime] = useState(0);
// Rotation is in degrees
const [rotation, setRotation] = useState(0);
const [flipHorizontal, setFlipHorizontal] = useState(false);
const [flipVertical, setFlipVertical] = useState(false);
const { isViewportBackgroundLight: isLight } = useViewportRendering(viewportId);
const { cornerstoneViewportService } = servicesManager.services;
// Store initial viewUp and viewRight for volume viewports
const initialVolumeOrientationRef = useRef<{
initialViewUp: number[] | null;
initialViewRight: number[] | null;
}>({
initialViewUp: null,
initialViewRight: null,
});
useEffect(() => {
const cameraModifiedListener = () => setCameraModifiedTime(Date.now());
initialVolumeOrientationRef.current.initialViewUp = null;
initialVolumeOrientationRef.current.initialViewRight = null;
if (viewportData?.viewportType !== 'stack' && element && getEnabledElement(element)) {
const { viewport } = getEnabledElement(element);
const { viewUp, viewPlaneNormal } = viewport.getCamera();
const viewRight = vec3.create();
vec3.cross(viewRight, viewUp, viewPlaneNormal);
initialVolumeOrientationRef.current.initialViewUp = [...viewUp];
initialVolumeOrientationRef.current.initialViewRight = [...viewRight];
}
}, [element, viewportData]);
useEffect(() => {
const cameraModifiedListener = (evt: Types.EventTypes.CameraModifiedEvent) => {
const { previousCamera, camera } = evt.detail;
const { rotation } = camera;
if (rotation !== undefined) {
setRotation(rotation);
}
if (
camera.flipHorizontal !== undefined &&
previousCamera.flipHorizontal !== camera.flipHorizontal
) {
setFlipHorizontal(camera.flipHorizontal);
}
if (
camera.flipVertical !== undefined &&
previousCamera.flipVertical !== camera.flipVertical
) {
setFlipVertical(camera.flipVertical);
}
};
element.addEventListener(Enums.Events.CAMERA_MODIFIED, cameraModifiedListener);
return () => {
element.removeEventListener(Enums.Events.CAMERA_MODIFIED, cameraModifiedListener);
};
}, [element]);
}, []);
const markers = useMemo(() => {
if (!viewportData || cameraModifiedTime === 0) {
return '';
}
if (!element || !getEnabledElement(element)) {
console.log(`ViewportOrientationMarkers :: Viewport element not enabled (${viewportId})`);
return '';
}
const ohifViewport = cornerstoneViewportService.getViewportInfo(viewportId);
if (!ohifViewport) {
console.log(`ViewportOrientationMarkers :: No viewport (${viewportId})`);
if (!viewportData) {
return '';
}
let rowCosines, columnCosines, isDefaultValueSetForRowCosine, isDefaultValueSetForColumnCosine;
if (viewportData.viewportType === 'stack') {
const imageIndex = imageSliceData.imageIndex;
const imageId = viewportData.data[0].imageIds?.[imageIndex];
@@ -55,25 +100,58 @@ function ViewportOrientationMarkers({
return false;
}
const { isDefaultValueSetForRowCosine, isDefaultValueSetForColumnCosine } =
metaData.get('imagePlaneModule', imageId) || {};
({
rowCosines,
columnCosines,
isDefaultValueSetForColumnCosine,
isDefaultValueSetForColumnCosine,
} = metaData.get('imagePlaneModule', imageId) || {});
} else {
if (!element || !getEnabledElement(element)) {
return '';
}
if (isDefaultValueSetForColumnCosine || isDefaultValueSetForRowCosine) {
if (
initialVolumeOrientationRef.current.initialViewUp &&
initialVolumeOrientationRef.current.initialViewRight
) {
// Use initial orientation values for consistency, even as the camera changes
columnCosines = [
-initialVolumeOrientationRef.current.initialViewUp[0],
-initialVolumeOrientationRef.current.initialViewUp[1],
-initialVolumeOrientationRef.current.initialViewUp[2],
];
rowCosines = initialVolumeOrientationRef.current.initialViewRight;
} else {
console.warn('ViewportOrientationMarkers::No initial orientation values');
return '';
}
}
const { viewport } = getEnabledElement(element);
const p00 = viewport.canvasToWorld([0, 0]);
const p10 = viewport.canvasToWorld([1, 0]);
const p01 = viewport.canvasToWorld([0, 1]);
const rowCosines = vec3.sub(vec3.create(), p10, p00);
const columnCosines = vec3.sub(vec3.create(), p01, p00);
if (
!rowCosines ||
!columnCosines ||
rotation === undefined ||
isDefaultValueSetForRowCosine ||
isDefaultValueSetForColumnCosine
) {
return '';
}
vec3.normalize(rowCosines, rowCosines);
vec3.normalize(columnCosines, columnCosines);
const markers = _getOrientationMarkers(
rowCosines,
columnCosines,
rotation,
flipVertical,
flipHorizontal
);
const markers = _getOrientationMarkers(rowCosines, columnCosines);
const ohifViewport = cornerstoneViewportService.getViewportInfo(viewportId);
if (!ohifViewport) {
console.log('ViewportOrientationMarkers::No viewport');
return null;
}
return orientationMarkers.map((m, index) => (
<div
@@ -90,7 +168,16 @@ function ViewportOrientationMarkers({
<div className="orientation-marker-value">{markers[m]}</div>
</div>
));
}, [viewportData, imageSliceData, cameraModifiedTime, orientationMarkers, element, isLight]);
}, [
viewportData,
imageSliceData,
rotation,
flipVertical,
flipHorizontal,
orientationMarkers,
element,
isLight,
]);
return <div className="ViewportOrientationMarkers select-none">{markers}</div>;
}
@@ -102,13 +189,18 @@ function ViewportOrientationMarkers({
*
* @param {*} rowCosines
* @param {*} columnCosines
* @param {*} rotation in degrees
* @returns
*/
function _getOrientationMarkers(rowCosines, columnCosines) {
function _getOrientationMarkers(rowCosines, columnCosines, rotation, flipVertical, flipHorizontal) {
const rowString = getOrientationStringLPS(rowCosines);
const columnString = getOrientationStringLPS(columnCosines);
const oppositeRowString = invertOrientationStringLPS(rowString);
const oppositeColumnString = invertOrientationStringLPS(columnString);
// Round to 4 decimal places (after rotate right 3 times and flip horizontally -> rotation is 90.00000000000001)
rotation = Math.round(rotation * 10000) / 10000;
const markers = {
top: oppositeColumnString,
left: oppositeRowString,
@@ -116,6 +208,43 @@ function _getOrientationMarkers(rowCosines, columnCosines) {
bottom: columnString,
};
// If any vertical or horizontal flips are applied, change the orientation strings ahead of
// the rotation applications
if (flipVertical) {
markers.top = invertOrientationStringLPS(markers.top);
markers.bottom = invertOrientationStringLPS(markers.bottom);
}
if (flipHorizontal) {
markers.left = invertOrientationStringLPS(markers.left);
markers.right = invertOrientationStringLPS(markers.right);
}
// Swap the labels accordingly if the viewport has been rotated
// This could be done in a more complex way for intermediate rotation values (e.g. 45 degrees)
if (rotation === 90 || rotation === -270) {
return {
top: markers.left,
left: invertOrientationStringLPS(markers.top),
right: invertOrientationStringLPS(markers.bottom),
bottom: markers.right, // left
};
} else if (rotation === -90 || rotation === 270) {
return {
top: invertOrientationStringLPS(markers.left),
left: markers.top,
bottom: markers.left,
right: markers.bottom,
};
} else if (rotation === 180 || rotation === -180) {
return {
top: invertOrientationStringLPS(markers.top),
left: invertOrientationStringLPS(markers.left),
bottom: invertOrientationStringLPS(markers.bottom),
right: invertOrientationStringLPS(markers.right),
};
}
return markers;
}
+113 -438
View File
@@ -14,18 +14,13 @@ import {
utilities as cstUtils,
annotation,
Types as ToolTypes,
SplineContourSegmentationTool,
} from '@cornerstonejs/tools';
import {
SegmentInfo,
LogicalOperation,
OperatorOptions,
} from '@cornerstonejs/tools/utilities/contourSegmentation/logicalOperators';
import * as cornerstoneTools from '@cornerstonejs/tools';
import * as labelmapInterpolation from '@cornerstonejs/labelmap-interpolation';
import { ONNXSegmentationController } from '@cornerstonejs/ai';
import { Types as OhifTypes, utils } from '@ohif/core';
import i18n from '@ohif/i18n';
import {
callInputDialogAutoComplete,
createReportAsync,
@@ -38,25 +33,13 @@ import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/u
import { getViewportEnabledElement } from './utils/getViewportEnabledElement';
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
import toggleVOISliceSync from './utils/toggleVOISliceSync';
import {
usePositionPresentationStore,
useSegmentationPresentationStore,
useSelectedSegmentationsForViewportStore,
} from './stores';
import { usePositionPresentationStore, useSegmentationPresentationStore } from './stores';
import { toolNames } from './initCornerstoneTools';
import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownloadForm';
import { updateSegmentBidirectionalStats } from './utils/updateSegmentationStats';
import { generateSegmentationCSVReport } from './utils/generateSegmentationCSVReport';
import { getUpdatedViewportsForSegmentation } from './utils/hydrationUtils';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import { isMeasurementWithinViewport } from './utils/isMeasurementWithinViewport';
import { getCenterExtent } from './utils/getCenterExtent';
import { EasingFunctionEnum } from './utils/transitions';
import { createSegmentationForViewport } from './utils/createSegmentationForViewport';
import { utilities as segmentationUtilities } from '@cornerstonejs/tools/segmentation';
import i18n from '@ohif/i18n';
const { add, intersect, subtract, copy } = cstUtils.contourSegmentation;
const { DefaultHistoryMemo } = csUtils.HistoryMemo;
const toggleSyncFunctions = {
@@ -75,7 +58,10 @@ const getLabelmapTools = ({ toolGroupService }) => {
// tools is an object with toolName as the key and tool as the value
Object.keys(tools).forEach(toolName => {
const tool = tools[toolName];
if (tool instanceof cornerstoneTools.LabelmapBaseTool) {
if (
tool instanceof cornerstoneTools.LabelmapBaseTool &&
tool.shouldResolvePreviewRequests()
) {
labelmapTools.push(tool);
}
});
@@ -120,7 +106,6 @@ function commandsModule({
}: OhifTypes.Extensions.ExtensionParams): OhifTypes.Extensions.CommandsModule {
const {
viewportGridService,
toolbarService,
toolGroupService,
cineService,
uiDialogService,
@@ -160,25 +145,6 @@ function commandsModule({
};
}
function _handleBrushSizeAction(action: 'increase' | 'decrease') {
const toolGroupIds = toolGroupService.getToolGroupIds();
if (!toolGroupIds?.length) {
return;
}
for (const toolGroupId of toolGroupIds) {
const brushSize = segmentationUtils.getBrushSizeForToolGroup(toolGroupId);
const newBrushSize = action === 'increase' ? brushSize + 3 : brushSize - 3;
if (brushSize) {
segmentationUtils.setBrushSizeForToolGroup(toolGroupId, newBrushSize);
toolbarService.refreshToolbarState({ toolGroupId });
}
}
}
const actions = {
jumpToMeasurementViewport: ({ annotationUID, measurement }) => {
cornerstoneTools.annotation.selection.setAnnotationSelected(annotationUID, true);
@@ -195,27 +161,6 @@ function commandsModule({
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
viewport.setViewReference(metadata);
viewport.render();
/**
* If the measurement is not visible inside the current viewport,
* we need to move the camera to the measurement.
*/
if (!isMeasurementWithinViewport(viewport, measurement)) {
const camera = viewport.getCamera();
const { focalPoint: cameraFocalPoint, position: cameraPosition } = camera;
const { center, extent } = getCenterExtent(measurement);
const position = vec3.sub(vec3.create(), cameraPosition, cameraFocalPoint);
vec3.add(position, position, center);
viewport.setCamera({ focalPoint: center, position: position as any });
/** Zoom out if the measurement is too large */
const measurementSize = vec3.dist(extent.min, extent.max);
if (measurementSize > camera.parallelScale) {
const scaleFactor = measurementSize / camera.parallelScale;
viewport.setZoom(viewport.getZoom() / scaleFactor);
}
viewport.render();
}
return;
}
@@ -270,28 +215,16 @@ function commandsModule({
return;
}
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
if (!viewport) {
return;
}
if (displaySet.isOverlayDisplaySet) {
// update the previously stored segmentationPresentation with the new viewportId
// presentation so that when we put the referencedDisplaySet back in the viewport
// it will have the correct segmentation representation hydrated
const segmentationType =
// Todo: check if PMAP modality should be handled such as SEG
displaySet.Modality !== 'SEG'
? SegmentationRepresentations.Contour
: viewport.type === CoreEnums.ViewportType.VOLUME_3D
? SegmentationRepresentations.Surface
: SegmentationRepresentations.Labelmap;
commandsManager.runCommand('updateStoredSegmentationPresentation', {
displaySet,
type: segmentationType,
type:
displaySet.Modality === 'SEG'
? SegmentationRepresentations.Labelmap
: SegmentationRepresentations.Contour,
});
}
@@ -312,35 +245,10 @@ function commandsModule({
referencedDisplaySetInstanceUID
);
storePositionPresentation(referencedDisplaySet);
const results = commandsManager.runCommand('loadSegmentationDisplaySetsForViewport', {
return commandsManager.runCommand('loadSegmentationDisplaySetsForViewport', {
viewportId,
displaySetInstanceUIDs: [referencedDisplaySet.displaySetInstanceUID],
});
const disableEditing = customizationService.getCustomization(
'panelSegmentation.disableEditing'
);
if (disableEditing) {
const segmentationRepresentations = segmentationService.getSegmentationRepresentations(
viewportId,
{
segmentationId: displaySet.displaySetInstanceUID,
}
);
segmentationRepresentations.forEach(representation => {
const segmentIndices = Object.keys(representation.segments);
segmentIndices.forEach(segmentIndex => {
segmentationService.setSegmentLocked(
representation.segmentationId,
parseInt(segmentIndex),
true
);
});
});
}
return results;
} else if (displaySet.Modality === 'SR') {
const results = commandsManager.runCommand('hydrateStructuredReport', {
displaySetInstanceUID: displaySet.displaySetInstanceUID,
@@ -589,8 +497,8 @@ function commandsModule({
if (!labelConfig) {
const label = await callInputDialog({
uiDialogService,
title: i18n.t('Tools:Edit Measurement Label'),
placeholder: measurement.label || i18n.t('Tools:Enter new label'),
title: 'Edit Measurement Label',
placeholder: measurement.label || 'Enter new label',
defaultValue: measurement.label,
});
@@ -804,8 +712,8 @@ function commandsModule({
if (!labelConfig) {
const label = await callInputDialog({
uiDialogService,
title: i18n.t('Tools:Edit Arrow Text'),
placeholder: data?.data?.label || i18n.t('Tools:Enter new text'),
title: 'Edit Arrow Text',
placeholder: data?.data?.label || 'Enter new text',
defaultValue: data?.data?.label || '',
});
@@ -997,21 +905,17 @@ function commandsModule({
}
}
},
setToolActiveToolbar: ({ value, itemId, toolName, toolGroupIds = [], bindings }) => {
setToolActiveToolbar: ({ value, itemId, toolName, toolGroupIds = [] }) => {
// Sometimes it is passed as value (tools with options), sometimes as itemId (toolbar buttons)
toolName = toolName || itemId || value;
toolGroupIds = toolGroupIds.length ? toolGroupIds : toolGroupService.getToolGroupIds();
toolGroupIds.forEach(toolGroupId => {
actions.setToolActive({ toolName, toolGroupId, bindings });
actions.setToolActive({ toolName, toolGroupId });
});
},
setToolActive: ({
toolName,
toolGroupId = null,
bindings = [{ mouseButton: Enums.MouseBindings.Primary }],
}) => {
setToolActive: ({ toolName, toolGroupId = null }) => {
const { viewports } = viewportGridService.getState();
if (!viewports.size) {
@@ -1039,7 +943,11 @@ function commandsModule({
// Set the new toolName to be active
toolGroup.setToolActive(toolName, {
bindings,
bindings: [
{
mouseButton: Enums.MouseBindings.Primary,
},
],
});
},
// capture viewport
@@ -1049,8 +957,8 @@ function commandsModule({
if (!cornerstoneViewportService.getCornerstoneViewport(activeViewportId)) {
// Cannot download a non-cornerstone viewport (image).
uiNotificationService.show({
title: i18n.t('Tools:Download Image'),
message: i18n.t('Tools:Image cannot be downloaded'),
title: 'Download Image',
message: 'Image cannot be downloaded',
type: 'error',
});
return;
@@ -1061,7 +969,7 @@ function commandsModule({
if (uiModalService) {
uiModalService.show({
content: CornerstoneViewportDownloadForm,
title: i18n.t('Tools:Download High Quality Image'),
title: 'Download High Quality Image',
contentProps: {
activeViewportId,
cornerstoneViewportService,
@@ -1512,24 +1420,48 @@ function commandsModule({
* as a segmentation representation to the viewport.
*/
createLabelmapForViewport: async ({ viewportId, options = {} }) => {
return createSegmentationForViewport(servicesManager, {
viewportId,
options,
segmentationType: SegmentationRepresentations.Labelmap,
});
},
/**
* Creates a contour for the active viewport
*
* The created contour will be registered as a display set and also added
* as a segmentation representation to the viewport.
*/
createContourForViewport: async ({ viewportId, options = {} }) => {
return createSegmentationForViewport(servicesManager, {
viewportId,
options,
segmentationType: SegmentationRepresentations.Contour,
const { viewportGridService, displaySetService, segmentationService } =
servicesManager.services;
const { viewports } = viewportGridService.getState();
const targetViewportId = viewportId;
const viewport = viewports.get(targetViewportId);
// Todo: add support for multiple display sets
const displaySetInstanceUID =
options.displaySetInstanceUID || viewport.displaySetInstanceUIDs[0];
const segs = segmentationService.getSegmentations();
const label = options.label || `Segmentation ${segs.length + 1}`;
const segmentationId = options.segmentationId || `${csUtils.uuidv4()}`;
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
// This will create the segmentation and register it as a display set
const generatedSegmentationId = await segmentationService.createLabelmapForDisplaySet(
displaySet,
{
label,
segmentationId,
segments: options.createInitialSegment
? {
1: {
label: `${i18n.t('Segment')} 1`,
active: true,
},
}
: {},
}
);
// Also add the segmentation representation to the viewport
await segmentationService.addSegmentationRepresentation(viewportId, {
segmentationId,
type: Enums.SegmentationRepresentations.Labelmap,
});
return generatedSegmentationId;
},
/**
@@ -1548,9 +1480,9 @@ function commandsModule({
* Adds a new segment to a segmentation
* @param props.segmentationId - The ID of the segmentation to add the segment to
*/
addSegmentCommand: ({ segmentationId, config }) => {
addSegmentCommand: ({ segmentationId }) => {
const { segmentationService } = servicesManager.services;
segmentationService.addSegment(segmentationId, config);
segmentationService.addSegment(segmentationId);
},
/**
@@ -1566,33 +1498,7 @@ function commandsModule({
segmentationId
);
segmentationService.setActiveSegment(segmentationId, segmentIndex);
const { highlightAlpha, highlightSegment, animationLength, animationFunctionType } =
(customizationService.getCustomization(
'panelSegmentation.jumpToSegmentHighlightAnimationConfig'
) as Object as {
highlightAlpha?: number;
highlightSegment?: boolean;
animationLength?: number;
animationFunctionType?: EasingFunctionEnum;
}) ?? {};
const validAnimationFunctionType = Object.values(EasingFunctionEnum).includes(
animationFunctionType
)
? animationFunctionType
: undefined;
segmentationService.jumpToSegmentCenter(
segmentationId,
segmentIndex,
undefined,
highlightAlpha,
highlightSegment,
animationLength,
undefined,
validAnimationFunctionType
);
segmentationService.jumpToSegmentCenter(segmentationId, segmentIndex);
},
/**
@@ -1647,13 +1553,15 @@ function commandsModule({
* Stores a segmentation and shows it in the viewport
* @param props.segmentationId - The ID of the segmentation to store
*/
storeSegmentationCommand: async args => {
const { segmentationId } = args;
storeSegmentationCommand: async ({ segmentationId }) => {
const { segmentationService, viewportGridService } = servicesManager.services;
const displaySetInstanceUIDs = await createReportAsync({
servicesManager,
getReport: () => commandsManager.runCommand('storeSegmentation', args),
getReport: () =>
commandsManager.runCommand('storeSegmentation', {
segmentationId,
}),
reportType: 'Segmentation',
});
@@ -1758,16 +1666,6 @@ function commandsModule({
segmentationService.setStyle({ type }, { renderFill: value });
},
/**
* Sets whether to render fill for inactive segmentations of a segmentation type
* @param props.type - The type of segmentation
* @param props.value - Whether to render fill for inactive segmentations
*/
setRenderFillInactiveCommand: ({ type, value }) => {
const { segmentationService } = servicesManager.services;
segmentationService.setStyle({ type }, { renderFillInactive: value });
},
/**
* Sets whether to render outline for a segmentation type
* @param props.type - The type of segmentation
@@ -1779,36 +1677,13 @@ function commandsModule({
},
/**
* Sets whether to render outline for inactive segmentations of a segmentation type
* @param props.type - The type of segmentation
* @param props.value - Whether to render outline for inactive segmentations
*/
setRenderOutlineInactiveCommand: ({ type, value }) => {
const { segmentationService } = servicesManager.services;
segmentationService.setStyle({ type }, { renderOutlineInactive: value });
},
/**
* Sets the fill alpha for inactive segmentations.
* If no type is provided, the fill alpha for all types will be set.
* Sets the fill alpha for inactive segmentations
* @param props.type - The type of segmentation
* @param props.value - The alpha value to set
*/
setFillAlphaInactiveCommand: ({ type, value }) => {
const { segmentationService } = servicesManager.services;
if (type) {
segmentationService.setStyle({ type }, { fillAlphaInactive: value });
} else {
segmentationService.setStyle(
{ type: SegmentationRepresentations.Labelmap },
{ fillAlphaInactive: value }
);
segmentationService.setStyle(
{ type: SegmentationRepresentations.Contour },
{ fillAlphaInactive: value }
);
}
segmentationService.setStyle({ type }, { fillAlphaInactive: value });
},
editSegmentLabel: async ({ segmentationId, segmentIndex }) => {
@@ -1823,8 +1698,8 @@ function commandsModule({
callInputDialog({
uiDialogService,
title: i18n.t('Tools:Edit Segment Label'),
placeholder: i18n.t('Tools:Enter new label'),
title: 'Edit Segment Label',
placeholder: 'Enter new label',
defaultValue: segment.label,
}).then(label => {
segmentationService.setSegmentLabel(segmentationId, segmentIndex, label);
@@ -1843,8 +1718,8 @@ function commandsModule({
callInputDialog({
uiDialogService,
title: i18n.t('Tools:Edit Segmentation Label'),
placeholder: i18n.t('Tools:Enter new label'),
title: 'Edit Segmentation Label',
placeholder: 'Enter new label',
defaultValue: label,
}).then(label => {
segmentationService.addOrUpdateSegmentation({ segmentationId, label });
@@ -1866,7 +1741,7 @@ function commandsModule({
uiDialogService.show({
content: colorPickerDialog,
title: i18n.t('Tools:Segment Color'),
title: 'Segment Color',
contentProps: {
value: rgbaColor,
onSave: newRgbaColor => {
@@ -1936,24 +1811,22 @@ function commandsModule({
}
});
},
toggleSegmentLabel: ({ enabled }: { enabled?: boolean }) => {
toggleSegmentLabel: () => {
const toolName = cornerstoneTools.SegmentLabelTool.toolName;
const toolGroupIds = toolGroupService.getToolGroupIds();
const isToolOn = toolGroupIds.some(toolGroupId => {
const isOn = toolGroupIds.some(toolGroupId => {
const toolGroup = cornerstoneTools.ToolGroupManager.getToolGroup(toolGroupId);
const mode = toolGroup.getToolInstance(toolName)?.mode;
return mode === 'Active';
});
const enableTool = enabled !== undefined ? enabled : !isToolOn;
toolGroupIds.forEach(toolGroupId => {
const toolGroup = cornerstoneTools.ToolGroupManager.getToolGroup(toolGroupId);
if (enableTool) {
toolGroup.setToolActive(toolName);
} else {
if (isOn) {
toolGroup.setToolDisabled(toolName);
} else {
toolGroup.setToolActive(toolName);
}
});
},
@@ -2076,11 +1949,17 @@ function commandsModule({
segmentAI.initViewport(viewport);
}
},
setBrushSize: ({ value }) => {
setBrushSize: ({ value, toolNames }) => {
const brushSize = Number(value);
toolGroupService.getToolGroupIds()?.forEach(toolGroupId => {
segmentationUtils.setBrushSizeForToolGroup(toolGroupId, brushSize);
if (toolNames?.length === 0) {
segmentationUtils.setBrushSizeForToolGroup(toolGroupId, brushSize);
} else {
toolNames?.forEach(toolName => {
segmentationUtils.setBrushSizeForToolGroup(toolGroupId, brushSize, toolName);
});
}
});
},
setThresholdRange: ({
@@ -2109,10 +1988,26 @@ function commandsModule({
}
},
increaseBrushSize: () => {
_handleBrushSizeAction('increase');
const toolGroupIds = toolGroupService.getToolGroupIds();
if (!toolGroupIds?.length) {
return;
}
for (const toolGroupId of toolGroupIds) {
const brushSize = segmentationUtils.getBrushSizeForToolGroup(toolGroupId);
segmentationUtils.setBrushSizeForToolGroup(toolGroupId, brushSize + 3);
}
},
decreaseBrushSize: () => {
_handleBrushSizeAction('decrease');
const toolGroupIds = toolGroupService.getToolGroupIds();
if (!toolGroupIds?.length) {
return;
}
for (const toolGroupId of toolGroupIds) {
const brushSize = segmentationUtils.getBrushSizeForToolGroup(toolGroupId);
segmentationUtils.setBrushSizeForToolGroup(toolGroupId, brushSize - 3);
}
},
addNewSegment: () => {
const { segmentationService } = servicesManager.services;
@@ -2288,205 +2183,6 @@ function commandsModule({
deleting,
});
},
activateSelectedSegmentationOfType: ({ segmentationRepresentationType }) => {
const { segmentationService, viewportGridService } = servicesManager.services;
const activeViewportId = viewportGridService.getActiveViewportId();
const { selectedSegmentationsForViewport } =
useSelectedSegmentationsForViewportStore.getState();
const segmentationId = selectedSegmentationsForViewport[activeViewportId]?.get(
segmentationRepresentationType
);
if (!segmentationId) {
return;
}
segmentationService.setActiveSegmentation(activeViewportId, segmentationId);
},
setDynamicCursorSizeForSculptorTool: ({ value: isDynamicCursorSize }) => {
const viewportId = viewportGridService.getActiveViewportId();
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
const sculptorToolInstance = toolGroup.getToolInstance(toolNames.SculptorTool);
const oldConfiguration = sculptorToolInstance.configuration;
sculptorToolInstance.configuration = {
...oldConfiguration,
updateCursorSize: isDynamicCursorSize ? 'dynamic' : '',
};
},
setInterpolationToolConfiguration: ({ value: interpolateContours, toolNames }) => {
const viewportId = viewportGridService.getActiveViewportId();
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
// Set the interpolation configuration for the active tool.
const activeTool = toolGroupService.getActiveToolForViewport(viewportId);
const interpolationConfig = {
interpolation: {
enabled: interpolateContours,
},
};
toolGroup.setToolConfiguration(activeTool, interpolationConfig);
// Now set the interpolation configuration for the other tools specified.
if (toolNames) {
Object.values(toolGroup.getToolInstances()).forEach(toolInstance => {
if (toolNames?.includes(toolInstance.toolName)) {
toolGroup.setToolConfiguration(toolInstance.toolName, interpolationConfig);
}
});
}
},
setSimplifiedSplineForSplineContourSegmentationTool: ({ value: simplifiedSpline }) => {
const viewportId = viewportGridService.getActiveViewportId();
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
Object.values(toolGroup.getToolInstances()).forEach(toolInstance => {
if (toolInstance instanceof SplineContourSegmentationTool) {
const oldConfiguration = toolInstance.configuration;
toolInstance.configuration = {
...oldConfiguration,
simplifiedSpline,
};
}
});
},
removeSmallContours: ({ areaThreshold: threshold }) => {
const viewportId = viewportGridService.getActiveViewportId();
const activeSegmentation = segmentationService.getActiveSegmentation(viewportId);
const activeSegment = segmentationService.getActiveSegment(viewportId);
if (!activeSegmentation || !activeSegment) {
return;
}
const { removeContourIslands } = segmentationUtilities;
removeContourIslands(activeSegmentation.segmentationId, activeSegment.segmentIndex, {
threshold,
});
const renderingEngine = cornerstoneViewportService.getRenderingEngine();
renderingEngine.render();
},
applyLogicalContourOperation: ({
segmentAInfo,
segmentBInfo,
resultSegmentInfo,
logicalOperation,
}: {
segmentAInfo: SegmentInfo;
segmentBInfo: SegmentInfo;
resultSegmentInfo: OperatorOptions;
logicalOperation: LogicalOperation;
}) => {
switch (logicalOperation) {
case LogicalOperation.Union:
add(segmentAInfo, segmentBInfo, resultSegmentInfo);
break;
case LogicalOperation.Intersect:
intersect(segmentAInfo, segmentBInfo, resultSegmentInfo);
break;
case LogicalOperation.Subtract:
subtract(segmentAInfo, segmentBInfo, resultSegmentInfo);
break;
default:
throw new Error('Unsupported logical operation');
}
},
copyContourSegment: ({
sourceSegmentInfo,
targetSegmentInfo,
}: {
sourceSegmentInfo: SegmentInfo;
targetSegmentInfo?: SegmentInfo;
}) => {
if (!targetSegmentInfo) {
targetSegmentInfo = {
segmentationId: sourceSegmentInfo.segmentationId,
segmentIndex: segmentationService.getNextAvailableSegmentIndex(
sourceSegmentInfo.segmentationId
),
};
segmentationService.addSegment(targetSegmentInfo.segmentationId, {
segmentIndex: targetSegmentInfo.segmentIndex,
});
}
copy(sourceSegmentInfo, targetSegmentInfo);
},
smoothContours: () => {
const viewportId = viewportGridService.getActiveViewportId();
const activeSegmentation = segmentationService.getActiveSegmentation(viewportId);
const activeSegment = segmentationService.getActiveSegment(viewportId);
if (!activeSegmentation || !activeSegment) {
return;
}
const { smoothContours } = segmentationUtilities;
smoothContours(activeSegmentation.segmentationId, activeSegment.segmentIndex);
const renderingEngine = cornerstoneViewportService.getRenderingEngine();
renderingEngine.render();
},
removeContourHoles: () => {
const viewportId = viewportGridService.getActiveViewportId();
const activeSegmentation = segmentationService.getActiveSegmentation(viewportId);
const activeSegment = segmentationService.getActiveSegment(viewportId);
if (!activeSegmentation || !activeSegment) {
return;
}
const { removeContourHoles } = segmentationUtilities;
removeContourHoles(activeSegmentation.segmentationId, activeSegment.segmentIndex);
const renderingEngine = cornerstoneViewportService.getRenderingEngine();
renderingEngine.render();
},
decimateContours: () => {
const viewportId = viewportGridService.getActiveViewportId();
const activeSegmentation = segmentationService.getActiveSegmentation(viewportId);
const activeSegment = segmentationService.getActiveSegment(viewportId);
if (!activeSegmentation || !activeSegment) {
return;
}
const { decimateContours } = segmentationUtilities;
decimateContours(activeSegmentation.segmentationId, activeSegment.segmentIndex);
const renderingEngine = cornerstoneViewportService.getRenderingEngine();
renderingEngine.render();
},
convertContourHoles: () => {
const viewportId = viewportGridService.getActiveViewportId();
const activeSegmentation = segmentationService.getActiveSegmentation(viewportId);
const activeSegment = segmentationService.getActiveSegment(viewportId);
if (!activeSegmentation || !activeSegment) {
return;
}
const targetSegmentInfo = {
segmentationId: activeSegmentation.segmentationId,
segmentIndex: segmentationService.getNextAvailableSegmentIndex(
activeSegmentation.segmentationId
),
};
segmentationService.addSegment(targetSegmentInfo.segmentationId, {
segmentIndex: targetSegmentInfo.segmentIndex,
});
const { convertContourHoles } = segmentationUtilities;
convertContourHoles(
activeSegmentation.segmentationId,
activeSegment.segmentIndex,
targetSegmentInfo.segmentationId,
targetSegmentInfo.segmentIndex
);
const renderingEngine = cornerstoneViewportService.getRenderingEngine();
renderingEngine.render();
},
};
const definitions = {
@@ -2685,9 +2381,6 @@ function commandsModule({
createLabelmapForViewport: {
commandFn: actions.createLabelmapForViewport,
},
createContourForViewport: {
commandFn: actions.createContourForViewport,
},
setActiveSegmentation: {
commandFn: actions.setActiveSegmentation,
},
@@ -2739,15 +2432,9 @@ function commandsModule({
setRenderFill: {
commandFn: actions.setRenderFillCommand,
},
setRenderFillInactive: {
commandFn: actions.setRenderFillInactiveCommand,
},
setRenderOutline: {
commandFn: actions.setRenderOutlineCommand,
},
setRenderOutlineInactive: {
commandFn: actions.setRenderOutlineInactiveCommand,
},
setFillAlphaInactive: {
commandFn: actions.setFillAlphaInactiveCommand,
},
@@ -2795,18 +2482,6 @@ function commandsModule({
toggleSegmentLabel: actions.toggleSegmentLabel,
jumpToMeasurementViewport: actions.jumpToMeasurementViewport,
initializeSegmentLabelTool: actions.initializeSegmentLabelTool,
activateSelectedSegmentationOfType: actions.activateSelectedSegmentationOfType,
setDynamicCursorSizeForSculptorTool: actions.setDynamicCursorSizeForSculptorTool,
setSimplifiedSplineForSplineContourSegmentationTool:
actions.setSimplifiedSplineForSplineContourSegmentationTool,
removeSmallContours: actions.removeSmallContours,
applyLogicalContourOperation: actions.applyLogicalContourOperation,
copyContourSegment: actions.copyContourSegment,
smoothContours: actions.smoothContours,
removeContourHoles: actions.removeContourHoles,
decimateContours: actions.decimateContours,
convertContourHoles: actions.convertContourHoles,
setInterpolationToolConfiguration: actions.setInterpolationToolConfiguration,
};
return {
@@ -55,7 +55,7 @@ const DEFAULT_TYPES = [GroupAccordion, Content, Trigger];
* measurements panel for a practical, working example.
*/
export function AccordionGroup(props) {
const { grouping, items, children, sourceChildren } = props;
const { grouping, items, children, sourceChildren, type } = props;
const childProps = useSystem();
let defaultValue = props.defaultValue;
const groups = grouping.groupingFunction(items, grouping, childProps);
@@ -0,0 +1,23 @@
.dicom-upload-drop-area-border-dash {
background-image: repeating-linear-gradient(
to right,
#7bb2ce 0%,
#7bb2ce 50%,
transparent 50%,
transparent 100%
),
repeating-linear-gradient(to right, #7bb2ce 0%, #7bb2ce 50%, transparent 50%, transparent 100%),
repeating-linear-gradient(to bottom, #7bb2ce 0%, #7bb2ce 50%, transparent 50%, transparent 100%),
repeating-linear-gradient(to bottom, #7bb2ce 0%, #7bb2ce 50%, transparent 50%, transparent 100%);
background-position:
left top,
left bottom,
left top,
right top;
background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
background-size:
20px 3px,
20px 3px,
3px 20px,
3px 20px;
}
@@ -5,8 +5,8 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';
import DicomFileUploader from '../../utils/DicomFileUploader';
import DicomUploadProgress from './DicomUploadProgress';
import { Button } from '@ohif/ui-next';
// Removed dashed border CSS; using simple 1px solid border with muted foreground color
import { Button, ButtonEnums } from '@ohif/ui';
import './DicomUpload.css';
type DicomUploadProps = {
dataSource;
@@ -15,8 +15,7 @@ type DicomUploadProps = {
};
function DicomUpload({ dataSource, onComplete, onStarted }: DicomUploadProps): ReactElement {
const baseClassNames =
'min-h-[375px] flex flex-col bg-black select-none rounded-lg overflow-hidden';
const baseClassNames = 'min-h-[480px] flex flex-col bg-black select-none';
const [dicomFileUploaderArr, setDicomFileUploaderArr] = useState([]);
const onDrop = useCallback(async acceptedFiles => {
@@ -35,10 +34,9 @@ function DicomUpload({ dataSource, onComplete, onStarted }: DicomUploadProps): R
{({ getRootProps }) => (
<div
{...getRootProps()}
className="m-5 flex h-full flex-col items-center justify-center rounded-2xl border"
style={{ borderColor: 'hsl(var(--muted-foreground) / 0.25)' }}
className="dicom-upload-drop-area-border-dash m-5 flex h-full flex-col items-center justify-center"
>
<div className="flex gap-2">
<div className="flex gap-3">
<Dropzone
onDrop={onDrop}
noDrag
@@ -46,16 +44,11 @@ function DicomUpload({ dataSource, onComplete, onStarted }: DicomUploadProps): R
{({ getRootProps, getInputProps }) => (
<div {...getRootProps()}>
<Button
variant="default"
size="lg"
disabled={false}
onClick={() => {}}
>
{'Add files'}
<input
{...getInputProps()}
style={{ display: 'none' }}
/>
<input {...getInputProps()} />
</Button>
</div>
)}
@@ -67,8 +60,7 @@ function DicomUpload({ dataSource, onComplete, onStarted }: DicomUploadProps): R
{({ getRootProps, getInputProps }) => (
<div {...getRootProps()}>
<Button
variant="secondary"
size="lg"
type={ButtonEnums.type.secondary}
disabled={false}
onClick={() => {}}
>
@@ -77,15 +69,14 @@ function DicomUpload({ dataSource, onComplete, onStarted }: DicomUploadProps): R
{...getInputProps()}
webkitdirectory="true"
mozdirectory="true"
style={{ display: 'none' }}
/>
</Button>
</div>
)}
</Dropzone>
</div>
<div className="text-foreground pt-6 text-base">or drag images or folders here</div>
<div className="text-muted-foreground pt-1 text-base">(DICOM files supported)</div>
<div className="pt-5">or drag images or folders here</div>
<div className="text-aqua-pale pt-3 text-lg">(DICOM files supported)</div>
</div>
)}
</Dropzone>
@@ -1,7 +1,7 @@
import React, { useCallback, useEffect, useRef, useState, ReactElement } from 'react';
import PropTypes from 'prop-types';
import { useSystem } from '@ohif/core';
import { Button } from '@ohif/ui-next';
import { Button } from '@ohif/ui';
import { Icons } from '@ohif/ui-next';
import DicomFileUploader, {
EVENTS,
@@ -276,7 +276,7 @@ function DicomUploadProgress({
const getNumCompletedAndTimeRemainingComponent = (): ReactElement => {
return (
<div className="bg-muted flex h-14 items-center px-1 pb-4 text-lg text-white">
<div className="bg-primary-dark flex h-14 items-center px-1 pb-4 text-lg text-white">
{numFilesCompleted === dicomFileUploaderArr.length ? (
<>
<span className={NO_WRAP_ELLIPSIS_CLASS_NAMES}>{`${dicomFileUploaderArr.length} ${
@@ -308,7 +308,7 @@ function DicomUploadProgress({
<span
className={
'text-primary hover:text-highlight active:text-muted-foreground ml-auto cursor-pointer whitespace-nowrap'
'text-primary hover:text-primary-lightactive:text-aqua-pale ml-auto cursor-pointer whitespace-nowrap'
}
onClick={cancelAllUploads}
>
@@ -337,11 +337,11 @@ function DicomUploadProgress({
const getPercentCompleteComponent = (): ReactElement => {
return (
<div className="ohif-scrollbar border-input overflow-y-scroll border-b px-2">
<div className="ohif-scrollbar border-secondary-light overflow-y-scroll border-b px-2">
<div className="min-h-14 flex w-full items-center p-2.5">
{numFilesCompleted === dicomFileUploaderArr.length ? (
<>
<div className="text-highlight text-xl">
<div className="text-primary-light text-xl">
{numFails > 0
? `Completed with ${numFails} ${numFails > 1 ? 'errors' : 'error'}!`
: 'Completed!'}
@@ -359,7 +359,7 @@ function DicomUploadProgress({
></ProgressLoadingBar>
</div>
<div className="ml-1 flex w-24 items-center">
<div className="text-foreground w-10 text-right">{`${getPercentCompleteRounded()}%`}</div>
<div className="w-10 text-right text-foreground">{`${getPercentCompleteRounded()}%`}</div>
{getShowFailedOnlyIconComponent()}
</div>
</>
@@ -56,7 +56,7 @@ const DicomUploadProgressItem = memo(
return (
<Icons.ByName
name="status-tracked"
className="text-highlight"
className="text-primary-light"
/>
);
case UploadStatus.InProgress:
@@ -71,7 +71,7 @@ const DicomUploadProgressItem = memo(
};
return (
<div className="min-h-14 border-input flex w-full items-center overflow-hidden border-b p-2.5 text-lg">
<div className="min-h-14 border-secondary-light flex w-full items-center overflow-hidden border-b p-2.5 text-lg">
<div className="self-top flex w-0 shrink grow flex-col gap-1">
<div className="flex gap-4">
<div className="flex w-6 shrink-0 items-center justify-center">{getStatusIcon()}</div>
@@ -1,108 +0,0 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import {
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuPortal,
DropdownMenuSubContent,
DropdownMenuLabel,
DropdownMenuItem,
DropdownMenuSeparator,
Icons,
} from '@ohif/ui-next';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
interface ExportSegmentationSubMenuItemProps {
segmentationId: string;
segmentationRepresentationType: string;
allowExport: boolean;
actions: {
storeSegmentation: (segmentationId: string, modality?: string) => Promise<unknown>;
onSegmentationDownloadRTSS: (segmentationId: string) => void;
onSegmentationDownload: (segmentationId: string) => void;
downloadCSVSegmentationReport: (segmentationId: string) => void;
};
}
export const ExportSegmentationSubMenuItem: React.FC<ExportSegmentationSubMenuItemProps> = ({
segmentationId,
segmentationRepresentationType,
allowExport,
actions,
}) => {
const { t } = useTranslation('SegmentationTable');
return (
<DropdownMenuSub>
<DropdownMenuSubTrigger className="pl-1">
<Icons.Export className="text-foreground" />
<span className="pl-2">{t('Download & Export')}</span>
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuLabel className="flex items-center pl-0">
<Icons.Download className="h-5 w-5" />
<span className="pl-1">{t('Download')}</span>
</DropdownMenuLabel>
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.downloadCSVSegmentationReport(segmentationId);
}}
disabled={!allowExport}
>
{t('CSV Report')}
</DropdownMenuItem>
)}
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.onSegmentationDownload(segmentationId);
}}
disabled={!allowExport}
>
{t('DICOM SEG')}
</DropdownMenuItem>
)}
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.onSegmentationDownloadRTSS(segmentationId);
}}
disabled={!allowExport}
>
{t('DICOM RTSS')}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel className="flex items-center pl-0">
<Icons.Export className="h-5 w-5" />
<span className="pl-1 pt-1">{t('Export')}</span>
</DropdownMenuLabel>
{segmentationRepresentationType === SegmentationRepresentations.Labelmap && (
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.storeSegmentation(segmentationId, 'SEG');
}}
disabled={!allowExport}
>
{t('DICOM SEG')}
</DropdownMenuItem>
)}
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.storeSegmentation(segmentationId, 'RTSTRUCT');
}}
disabled={!allowExport}
>
{t('DICOM RTSS')}
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
);
};
@@ -1,69 +0,0 @@
import React, { useState } from 'react';
import { Switch } from '@ohif/ui-next';
import { useSystem } from '@ohif/core';
export default function SegmentationToolConfig() {
const { commandsManager } = useSystem();
// Get initial states based on current configuration
const [previewEdits, setPreviewEdits] = useState(false);
const [segmentLabelEnabled, setSegmentLabelEnabled] = useState(false);
const [toggleSegmentEnabled, setToggleSegmentEnabled] = useState(false);
const [useCenterAsSegmentIndex, setUseCenterAsSegmentIndex] = useState(false);
const handlePreviewEditsChange = checked => {
setPreviewEdits(checked);
commandsManager.run('toggleSegmentPreviewEdit', { toggle: checked });
};
const handleToggleSegmentEnabledChange = checked => {
setToggleSegmentEnabled(checked);
commandsManager.run('toggleSegmentSelect', { toggle: checked });
};
const handleUseCenterAsSegmentIndexChange = checked => {
setUseCenterAsSegmentIndex(checked);
commandsManager.run('toggleUseCenterSegmentIndex', { toggle: checked });
};
const handleSegmentLabelEnabledChange = checked => {
setSegmentLabelEnabled(checked);
commandsManager.run('toggleSegmentLabel', { enabled: checked });
};
return (
<div className="bg-muted flex flex-col gap-2 border-b border-b-[2px] border-black px-2 py-3">
<div className="flex items-center gap-2">
<Switch
checked={previewEdits}
onCheckedChange={handlePreviewEditsChange}
/>
<span className="text-foreground text-base">Preview edits before creating</span>
</div>
<div className="flex items-center gap-2">
<Switch
checked={useCenterAsSegmentIndex}
onCheckedChange={handleUseCenterAsSegmentIndexChange}
/>
<span className="text-foreground text-base">Use center as segment index</span>
</div>
<div className="flex items-center gap-2">
<Switch
checked={toggleSegmentEnabled}
onCheckedChange={handleToggleSegmentEnabledChange}
/>
<span className="text-foreground text-base">Hover on segment border to activate</span>
</div>
<div className="flex items-center gap-2">
<Switch
checked={segmentLabelEnabled}
onCheckedChange={handleSegmentLabelEnabledChange}
/>
<span className="text-foreground text-base">Show segment name on hover</span>
</div>
</div>
);
}
@@ -1,64 +0,0 @@
import React, { useCallback } from 'react';
import { cn, ToolButton } from '@ohif/ui-next';
import { useUIStateStore } from '@ohif/extension-default';
interface SegmentationUtilityButtonProps {
className?: string;
isActive?: boolean;
id: string;
}
/**
* A button that represents a segmentation utility.
* It is implicitly the PopoverTrigger for the options Popover panel that is
* opened in the PanelSegmentation component. It in essence is the PopoverTrigger
* because typically this button has the associated options to display in the Popover.
* Furthermore it also typically has a command for toggling the activeSegmentationUtility
* value in the UIStateStore that triggers the fetching of its options.
* @param props - The props for the button.
* @param props.className - The class name for the button.
* @param props.isActive - Whether the button is active
* @param props.id - The id of the button.
*/
function SegmentationUtilityButton(props: SegmentationUtilityButtonProps) {
const { className, isActive, id } = props;
const activeSegmentationUtility = useUIStateStore(
store => store.uiState.activeSegmentationUtility
);
const toolButtonClassName = cn(
'w-7 h-7 text-primary hover:text-primary hover:!bg-primary/30',
className,
isActive && 'bg-primary/30'
);
const handleMouseDownCapture = useCallback(
event => {
if (activeSegmentationUtility === id) {
// If this active button is clicked, prevent the default Popover
// behaviour of closing the Popover on a pointer/mouse down.
// Not doing this will cause the Popover to close and then reopen again.
// Why? Because propagating this event will cause PanelSegmentation to
// close the Popover by clearing the activeSegmentationUtility. Then
// this button will set the activeSegmentationUtility again and the
// Popover will reopen.
event.preventDefault();
event.stopPropagation();
}
},
[activeSegmentationUtility, id]
);
return (
<div onPointerDownCapture={handleMouseDownCapture}>
<ToolButton
{...props}
className={toolButtonClassName}
/>
</div>
);
}
export default SegmentationUtilityButton;
@@ -1,5 +1,6 @@
import React from 'react';
import { useActiveViewportDisplaySets, utils } from '@ohif/core';
import { useActiveViewportDisplaySets, useSystem, utils } from '@ohif/core';
// import { AccordionContent, AccordionItem, AccordionTrigger } from '@ohif/ui-next';
import { AccordionGroup } from './AccordionGroup';
import MeasurementsOrAdditionalFindings from './MeasurementsOrAdditionalFindings';
@@ -62,7 +63,8 @@ export const groupByStudy = (items, grouping, childProps) => {
export function StudyMeasurements(props): React.ReactNode {
const { items, grouping = {}, children } = props;
const activeDisplaySets = useActiveViewportDisplaySets();
const system = useSystem();
const activeDisplaySets = useActiveViewportDisplaySets(system);
const activeStudyUID = activeDisplaySets?.[0]?.StudyInstanceUID;
return (
@@ -1,11 +1,9 @@
import React, { ReactElement, useCallback } from 'react';
import { Switch } from '@ohif/ui-next';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import { useTranslation } from 'react-i18next';
export function Colorbar({ viewportId }: { viewportId?: string } = {}): ReactElement {
const { hasColorbar, toggleColorbar } = useViewportRendering(viewportId);
const { t } = useTranslation('WindowLevelActionMenu');
const handleToggle = useCallback(() => {
toggleColorbar();
@@ -18,7 +16,7 @@ export function Colorbar({ viewportId }: { viewportId?: string } = {}): ReactEle
className="flex-grow"
onClick={handleToggle}
>
{t('Display Color bar')}
Display Color bar
</span>
<Switch
className="ml-2 flex-shrink-0"
@@ -1,11 +1,9 @@
import React, { ReactElement, useEffect, useRef, useState } from 'react';
import { AllInOneMenu, ScrollArea, Switch, Tabs, TabsList, TabsTrigger } from '@ohif/ui-next';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import { useTranslation } from 'react-i18next';
export function Colormap({ viewportId }: { viewportId?: string } = {}): ReactElement {
const { viewportDisplaySets } = useViewportRendering(viewportId);
const { t } = useTranslation('WindowLevelActionMenu');
const [activeDisplaySetUID, setActiveDisplaySetUID] = useState<string | undefined>(
viewportDisplaySets?.[0]?.displaySetInstanceUID
@@ -76,7 +74,7 @@ export function Colormap({ viewportId }: { viewportId?: string } = {}): ReactEle
className="hover:bg-accent flex h-8 w-full flex-shrink-0 cursor-pointer items-center px-2 text-base hover:rounded"
onClick={() => setShowPreview(!showPreview)}
>
<span className="flex-shrink-0">{t('Preview in viewport')}</span>
<span className="flex-shrink-0">Preview in viewport</span>
<Switch
className="ml-auto flex-shrink-0"
checked={showPreview}
@@ -7,7 +7,6 @@ import { WindowLevel } from './WindowLevel';
import { VolumeRenderingPresets } from './VolumeRenderingPresets';
import { VolumeRenderingOptions } from './VolumeRenderingOptions';
import { useViewportRendering } from '../../hooks/useViewportRendering';
import i18n from 'i18next';
export type WindowLevelActionMenuProps = {
viewportId: string;
@@ -59,7 +58,6 @@ export function WindowLevelActionMenuContent({
isVisible={true}
align={align}
side={side}
backLabel={i18n.t('WindowLevelActionMenu:Back to Display Options')}
>
<AllInOneMenu.ItemPanel>
{!is3DVolume && <Colorbar viewportId={viewportId} />}
@@ -67,7 +65,7 @@ export function WindowLevelActionMenuContent({
{colorbarProperties?.colormaps && !is3DVolume && (
<AllInOneMenu.SubMenu
key="colorLUTPresets"
itemLabel={t('Color LUT')}
itemLabel="Color LUT"
itemIcon="icon-color-lut"
className="flex h-[calc(100%-32px)] flex-col"
>
@@ -88,7 +86,7 @@ export function WindowLevelActionMenuContent({
{volumeRenderingPresets && is3DVolume && <VolumeRenderingPresets viewportId={viewportId} />}
{volumeRenderingQualityRange && is3DVolume && (
<AllInOneMenu.SubMenu itemLabel={t('Rendering Options')}>
<AllInOneMenu.SubMenu itemLabel="Rendering Options">
<VolumeRenderingOptions viewportId={viewportId} />
</AllInOneMenu.SubMenu>
)}
@@ -3,14 +3,17 @@ import {
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
Icons,
useSegmentationTableContext,
useSegmentationExpanded,
} from '@ohif/ui-next';
import { useTranslation } from 'react-i18next';
import { useSystem } from '@ohif/core/src';
import { ExportSegmentationSubMenuItem } from '../components/ExportSegmentationSubMenuItem';
/**
* Custom dropdown menu component for segmentation panel that uses context for data
@@ -26,8 +29,6 @@ export const CustomDropdownMenuContent = () => {
exportOptions,
activeSegmentation,
activeSegmentationId,
segmentationRepresentationType,
disableEditing,
} = useSegmentationTableContext('CustomDropdownMenu');
// Try to get segmentation data from expanded context first, fall back to table context
@@ -46,21 +47,21 @@ export const CustomDropdownMenuContent = () => {
segmentationId = activeSegmentationId;
}
if (!segmentation || !segmentationId) {
return null;
}
// Determine if export is allowed for this segmentation
if (exportOptions) {
if (exportOptions && segmentationId) {
const exportOption = exportOptions.find(opt => opt.segmentationId === segmentationId);
allowExport = exportOption?.isExportable || false;
}
if (!segmentation || !segmentationId) {
return null;
}
const actions = {
storeSegmentation: async (segmentationId, modality = 'SEG') => {
storeSegmentation: async segmentationId => {
commandsManager.run({
commandName: 'storeSegmentation',
commandOptions: { segmentationId, modality },
commandOptions: { segmentationId },
context: 'CORNERSTONE',
});
},
@@ -77,14 +78,10 @@ export const CustomDropdownMenuContent = () => {
return (
<DropdownMenuContent align="start">
{!disableEditing && (
<DropdownMenuItem
onClick={() => onSegmentationAdd({ segmentationId, segmentationRepresentationType })}
>
<Icons.Add className="text-foreground" />
<span className="pl-2">{t('Create New Segmentation')}</span>
</DropdownMenuItem>
)}
<DropdownMenuItem onClick={() => onSegmentationAdd(segmentationId)}>
<Icons.Add className="text-foreground" />
<span className="pl-2">{t('Create New Segmentation')}</span>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel>{t('Manage Current Segmentation')}</DropdownMenuLabel>
<DropdownMenuItem onClick={() => onSegmentationRemoveFromViewport(segmentationId)}>
@@ -95,12 +92,61 @@ export const CustomDropdownMenuContent = () => {
<Icons.Rename className="text-foreground" />
<span className="pl-2">{t('Rename')}</span>
</DropdownMenuItem>
<ExportSegmentationSubMenuItem
segmentationId={segmentationId}
segmentationRepresentationType={segmentationRepresentationType}
allowExport={allowExport}
actions={actions}
/>
<DropdownMenuSub>
<DropdownMenuSubTrigger className="pl-1">
<Icons.Export className="text-foreground" />
<span className="pl-2">{t('Download & Export')}</span>
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuLabel className="flex items-center pl-0">
<Icons.Download className="h-5 w-5" />
<span className="pl-1">{t('Download')}</span>
</DropdownMenuLabel>
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.downloadCSVSegmentationReport(segmentationId);
}}
disabled={!allowExport}
>
{t('CSV Report')}
</DropdownMenuItem>
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.onSegmentationDownload(segmentationId);
}}
disabled={!allowExport}
>
{t('DICOM SEG')}
</DropdownMenuItem>
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.onSegmentationDownloadRTSS(segmentationId);
}}
disabled={!allowExport}
>
{t('DICOM RTSS')}
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel className="flex items-center pl-0">
<Icons.Export className="h-5 w-5" />
<span className="pl-1 pt-1">{t('Export')}</span>
</DropdownMenuLabel>
<DropdownMenuItem
onClick={e => {
e.preventDefault();
actions.storeSegmentation(segmentationId);
}}
disabled={!allowExport}
>
{t('DICOM SEG')}
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => onSegmentationDelete(segmentationId)}>
<Icons.Delete className="text-red-600" />
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { ImageModal, FooterAction } from '@ohif/ui-next';
import { useTranslation } from 'react-i18next';
const MAX_TEXTURE_SIZE = 10000;
const DEFAULT_FILENAME = 'image';
@@ -37,7 +37,6 @@ function ViewportDownloadFormNew({
const [showWarningMessage, setShowWarningMessage] = useState(true);
const [filename, setFilename] = useState(DEFAULT_FILENAME);
const [fileType, setFileType] = useState('jpg');
const { t } = useTranslation('CaptureViewportModal');
useEffect(() => {
if (!viewportElement) {
@@ -83,7 +82,7 @@ function ViewportDownloadFormNew({
value={filename}
onChange={e => setFilename(e.target.value)}
>
{t('File name')}
File name
</ImageModal.Filename>
<ImageModal.Filetype
selected={fileType}
@@ -110,7 +109,7 @@ function ViewportDownloadFormNew({
maxWidth={MAX_TEXTURE_SIZE.toString()}
maxHeight={MAX_TEXTURE_SIZE.toString()}
>
{t('Image size')} <span className="text-muted-foreground">px</span>
Image size <span className="text-muted-foreground">px</span>
</ImageModal.ImageSize>
<ImageModal.SwitchOption
@@ -118,7 +117,7 @@ function ViewportDownloadFormNew({
checked={showAnnotations}
onCheckedChange={onAnnotationsChange}
>
{t('Include annotations')}
Include annotations
</ImageModal.SwitchOption>
{warningState.enabled && (
<ImageModal.SwitchOption
@@ -126,21 +125,19 @@ function ViewportDownloadFormNew({
checked={showWarningMessage}
onCheckedChange={setShowWarningMessage}
>
{t('Include warning message')}
Include warning message
</ImageModal.SwitchOption>
)}
<FooterAction className="mt-2">
<FooterAction.Right>
<FooterAction.Secondary onClick={onClose}>
{t('Common:Cancel')}
</FooterAction.Secondary>
<FooterAction.Secondary onClick={onClose}>Cancel</FooterAction.Secondary>
<FooterAction.Primary
onClick={() => {
onDownload(filename || DEFAULT_FILENAME, fileType);
onClose();
}}
>
{t('Common:Save')}
Save
</FooterAction.Primary>
</FooterAction.Right>
</FooterAction>
@@ -1,12 +1,6 @@
import { CinePlayer } from '@ohif/ui-next';
import DicomUpload from '../components/DicomUpload/DicomUpload';
// Provide a wider default container for the DICOM Upload modal, without
// affecting other dialogs. We attach a static property that WorkList reads.
const DicomUploadWithSize = Object.assign(DicomUpload, {
containerClassName: 'max-w-3xl',
});
export default {
cinePlayer: CinePlayer,
autoCineModalities: ['OT', 'US'],
@@ -17,6 +11,6 @@ export default {
onBeforeDicomStore: ({ dicomDict, measurementData, naturalizedReport }) => {
return dicomDict;
},
dicomUploadComponent: DicomUploadWithSize,
dicomUploadComponent: DicomUpload,
codingValues: {},
};
@@ -1,94 +1,18 @@
import { CustomDropdownMenuContent } from './CustomDropdownMenuContent';
import { CustomSegmentStatisticsHeader } from './CustomSegmentStatisticsHeader';
import SegmentationToolConfig from '../components/SegmentationToolConfig';
import React from 'react';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import React, { useState } from 'react';
import { Switch } from '@ohif/ui-next';
export default function getSegmentationPanelCustomization({ commandsManager, servicesManager }) {
const { segmentationService } = servicesManager.services;
let contourRenderFillChangedGlobally = false;
// Listen to when the global CONTOUR type renderFill style property is changed.
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_STYLE_MODIFIED,
({ specifier, style }) => {
if (
specifier.type === SegmentationRepresentations.Contour &&
specifier.segmentationId == null &&
specifier.viewportId == null &&
style.renderFill != null
) {
unsubscribe();
contourRenderFillChangedGlobally = true;
}
}
);
return {
'panelSegmentation.customDropdownMenuContent': CustomDropdownMenuContent,
'panelSegmentation.customSegmentStatisticsHeader': CustomSegmentStatisticsHeader,
'panelSegmentation.disableEditing': false,
'panelSegmentation.showAddSegment': true,
'panelSegmentation.onSegmentationAdd': async ({
segmentationRepresentationType = SegmentationRepresentations.Labelmap,
}) => {
'panelSegmentation.onSegmentationAdd': () => {
const { viewportGridService } = servicesManager.services;
const viewportId = viewportGridService.getState().activeViewportId;
if (segmentationRepresentationType === SegmentationRepresentations.Labelmap) {
commandsManager.run('createLabelmapForViewport', { viewportId });
} else if (segmentationRepresentationType === SegmentationRepresentations.Contour) {
const segmentationId = await commandsManager.run('createContourForViewport', {
viewportId,
});
// Override the default (i.e. hydrated RTSTRUCT) style for contours if the global CONTOUR type
// renderFill style property has not been changed.
if (!contourRenderFillChangedGlobally) {
segmentationService.setStyle(
{ segmentationId, type: SegmentationRepresentations.Contour },
{
renderFill: true,
renderFillInactive: true,
},
// Do not merge so that these created contours inherit other type-specific style properties like the fill alpha.
// Merging would otherwise permanently inherit the fill alpha and any inheritance from the type level would be lost.
false
);
}
// If the global CONTOUR type renderFill style property is already set, do not subscribe to the SEGMENTATION_STYLE_MODIFIED event.
if (contourRenderFillChangedGlobally) {
return;
}
// Subscribe to the SEGMENTATION_STYLE_MODIFIED event to listen for changes to the CONTOUR type renderFill style property.
const { unsubscribe } = segmentationService.subscribe(
segmentationService.EVENTS.SEGMENTATION_STYLE_MODIFIED,
({ specifier, style }) => {
if (
specifier.type === SegmentationRepresentations.Contour &&
specifier.segmentationId == null &&
specifier.viewportId == null &&
style.renderFill != null
) {
// We are here because the renderFill style property is globally being changed for ALL contours.
// When this occurs, the desire is for ALL contours to inherit the property. To make this happen,
// we have to clear the style property that was set for this specific segmentation
// when it was created above.
// We can now also unsubscribe because this change only needs to be made when the global CONTOUR type
// renderFill style property is first changed.
contourRenderFillChangedGlobally = true;
unsubscribe();
segmentationService.setStyle(
{ segmentationId, type: SegmentationRepresentations.Contour },
{},
false
);
}
}
);
}
commandsManager.run('createLabelmapForViewport', { viewportId });
},
'panelSegmentation.tableMode': 'collapsed',
'panelSegmentation.readableText': {
@@ -109,11 +33,53 @@ export default function getSegmentationPanelCustomization({ commandsManager, ser
lesionGlycolysis: 'Lesion Glycolysis',
center: 'Center',
},
'labelMapSegmentationToolbox.config': () => {
return <SegmentationToolConfig />;
},
'contourSegmentationToolbox.config': () => {
return <SegmentationToolConfig />;
'segmentationToolbox.config': () => {
// Get initial states based on current configuration
const [previewEdits, setPreviewEdits] = useState(false);
const [toggleSegmentEnabled, setToggleSegmentEnabled] = useState(false);
const [useCenterAsSegmentIndex, setUseCenterAsSegmentIndex] = useState(false);
const handlePreviewEditsChange = checked => {
setPreviewEdits(checked);
commandsManager.run('toggleSegmentPreviewEdit', { toggle: checked });
};
const handleToggleSegmentEnabledChange = checked => {
setToggleSegmentEnabled(checked);
commandsManager.run('toggleSegmentSelect', { toggle: checked });
};
const handleUseCenterAsSegmentIndexChange = checked => {
setUseCenterAsSegmentIndex(checked);
commandsManager.run('toggleUseCenterSegmentIndex', { toggle: checked });
};
return (
<div className="bg-muted flex flex-col gap-4 border-b border-b-[2px] border-black px-2 py-3">
<div className="flex items-center gap-2">
<Switch
checked={previewEdits}
onCheckedChange={handlePreviewEditsChange}
/>
<span className="text-base text-white">Preview edits before creating</span>
</div>
<div className="flex items-center gap-2">
<Switch
checked={useCenterAsSegmentIndex}
onCheckedChange={handleUseCenterAsSegmentIndexChange}
/>
<span className="text-base text-white">Use center as segment index</span>
</div>
<div className="flex items-center gap-2">
<Switch
checked={toggleSegmentEnabled}
onCheckedChange={handleToggleSegmentEnabledChange}
/>
<span className="text-base text-white">Hover on segment border to activate</span>
</div>
</div>
);
},
};
}
+13 -42
View File
@@ -1,67 +1,53 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Toolbox } from '@ohif/extension-default';
import PanelSegmentation from './panels/PanelSegmentation';
import ActiveViewportWindowLevel from './components/ActiveViewportWindowLevel';
import PanelMeasurement from './panels/PanelMeasurement';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import i18n from '@ohif/i18n';
const getPanelModule = ({ commandsManager, servicesManager, extensionManager }: withAppTypes) => {
const { toolbarService } = servicesManager.services;
const toolSectionMap = {
[SegmentationRepresentations.Labelmap]: toolbarService.sections.labelMapSegmentationToolbox,
[SegmentationRepresentations.Contour]: toolbarService.sections.contourSegmentationToolbox,
};
const wrappedPanelSegmentation = props => {
const wrappedPanelSegmentation = ({ configuration }) => {
return (
<PanelSegmentation
commandsManager={commandsManager}
servicesManager={servicesManager}
extensionManager={extensionManager}
configuration={{
...props?.configuration,
...configuration,
}}
segmentationRepresentationType={props?.segmentationRepresentationType}
/>
);
};
const wrappedPanelSegmentationNoHeader = props => {
const wrappedPanelSegmentationNoHeader = ({ configuration }) => {
return (
<PanelSegmentation
commandsManager={commandsManager}
servicesManager={servicesManager}
extensionManager={extensionManager}
configuration={{
...props?.configuration,
...configuration,
}}
segmentationRepresentationType={props?.segmentationRepresentationType}
/>
);
};
const wrappedPanelSegmentationWithTools = props => {
const { t } = useTranslation('SegmentationTable');
const tKey = `${props.segmentationRepresentationType ?? 'Segmentation'} tools`;
const tValue = t(tKey);
const wrappedPanelSegmentationWithTools = ({ configuration }) => {
const { toolbarService } = servicesManager.services;
return (
<>
<Toolbox
buttonSectionId={toolSectionMap[props.segmentationRepresentationType]}
title={tValue}
buttonSectionId={toolbarService.sections.segmentationToolbox}
title="Segmentation Tools"
/>
<PanelSegmentation
commandsManager={commandsManager}
servicesManager={servicesManager}
extensionManager={extensionManager}
configuration={{
...props?.configuration,
...configuration,
}}
segmentationRepresentationType={props?.segmentationRepresentationType}
/>
</>
);
@@ -96,26 +82,11 @@ const getPanelModule = ({ commandsManager, servicesManager, extensionManager }:
component: wrappedPanelSegmentationNoHeader,
},
{
name: 'panelSegmentationWithToolsLabelMap',
name: 'panelSegmentationWithTools',
iconName: 'tab-segmentation',
iconLabel: 'Segmentation',
label: i18n.t('SegmentationTable:Labelmap'),
component: props =>
wrappedPanelSegmentationWithTools({
...props,
segmentationRepresentationType: SegmentationRepresentations.Labelmap,
}),
},
{
name: 'panelSegmentationWithToolsContour',
iconName: 'tab-contours',
iconLabel: 'Segmentation',
label: i18n.t('SegmentationTable:Contour'),
component: props =>
wrappedPanelSegmentationWithTools({
...props,
segmentationRepresentationType: SegmentationRepresentations.Contour,
}),
label: 'Segmentation',
component: wrappedPanelSegmentationWithTools,
},
];
};
@@ -1,7 +1,6 @@
import { useState, useEffect } from 'react';
import debounce from 'lodash.debounce';
import { useSystem } from '@ohif/core';
function mapMeasurementToDisplay(measurement, displaySetService) {
const { referenceSeriesUID } = measurement;
@@ -682,7 +682,7 @@ export function useViewportRendering(
const actorEntries = viewport.getActors();
const actorEntry = actorEntries?.find(entry =>
entry.referencedId?.includes(activeDisplaySetInstanceUID)
entry.referencedId.includes(activeDisplaySetInstanceUID)
);
if (!actorEntry) {
@@ -152,27 +152,15 @@ export function useViewportSegmentations({
const representations = segmentationService.getSegmentationRepresentations(viewportId);
// Deduplicate representations by segmentationId to prevent showing
// the same segmentation multiple times in the panel when it has
// multiple representation types (e.g., labelmap and surface)
const uniqueSegmentationMap = new Map();
representations.forEach(representation => {
if (!uniqueSegmentationMap.has(representation.segmentationId)) {
uniqueSegmentationMap.set(representation.segmentationId, representation);
}
const newSegmentationsWithRepresentations = representations.map(representation => {
const segmentation = segmentationService.getSegmentation(representation.segmentationId);
const mappedSegmentation = mapSegmentationToDisplay(segmentation, customizationService);
return {
representation,
segmentation: mappedSegmentation,
};
});
const newSegmentationsWithRepresentations = Array.from(uniqueSegmentationMap.values()).map(
representation => {
const segmentation = segmentationService.getSegmentation(representation.segmentationId);
const mappedSegmentation = mapSegmentationToDisplay(segmentation, customizationService);
return {
representation,
segmentation: mappedSegmentation,
};
}
);
setSegmentationsWithRepresentations({
segmentationsWithRepresentations: newSegmentationsWithRepresentations,
disabled: false,
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const fourUp = {
id: 'fourUp',
locked: true,
name: i18n.t('Hps:3D four up'),
name: '3D four up',
icon: 'layout-advanced-3d-four-up',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+3 -3
View File
@@ -1,9 +1,9 @@
import { Types } from '@ohif/core';
import i18n from 'i18next';
const frameView: Types.HangingProtocol.Protocol = {
id: '@ohif/frameView',
description: i18n.t('Hps:Frame view for the active series'),
name: i18n.t('Hps:Frame View'),
description: 'Frame view for the active series',
name: 'Frame View',
icon: 'tool-stack-scroll',
isPreset: true,
toolGroupIds: ['default'],
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const main3D = {
id: 'main3D',
locked: true,
name: i18n.t('Hps:3D main'),
name: '3D main',
icon: 'layout-advanced-3d-main',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+2 -2
View File
@@ -1,5 +1,5 @@
import { Types } from '@ohif/core';
import i18n from 'i18next';
export const VOI_SYNC_GROUP = {
type: 'voi',
id: 'mpr',
@@ -22,7 +22,7 @@ export const HYDRATE_SEG_SYNC_GROUP = {
export const mpr: Types.HangingProtocol.Protocol = {
id: 'mpr',
name: i18n.t('Hps:MPR'),
name: 'MPR',
locked: true,
icon: 'layout-advanced-mpr',
isPreset: true,
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const mprAnd3DVolumeViewport = {
id: 'mprAnd3DVolumeViewport',
locked: true,
name: i18n.t('Hps:mpr'),
name: 'mpr',
createdDate: '2023-03-15T10:29:44.894Z',
modifiedDate: '2023-03-15T10:29:44.894Z',
availableTo: {},
+1 -2
View File
@@ -1,10 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const only3D = {
id: 'only3D',
locked: true,
name: i18n.t('Hps:3D only'),
name: '3D only',
icon: 'layout-advanced-3d-only',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
+2 -2
View File
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const primary3D = {
id: 'primary3D',
locked: true,
name: i18n.t('Hps:3D primary'),
name: '3D primary',
icon: 'layout-advanced-3d-primary',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
@@ -1,9 +1,9 @@
import { HYDRATE_SEG_SYNC_GROUP, VOI_SYNC_GROUP } from './mpr';
import i18n from 'i18next';
export const primaryAxial = {
id: 'primaryAxial',
locked: true,
name: i18n.t('Hps:Axial Primary'),
name: 'Axial Primary',
icon: 'layout-advanced-axial-primary',
isPreset: true,
createdDate: '2023-03-15T10:29:44.894Z',
-10
View File
@@ -44,7 +44,6 @@ import {
usePositionPresentationStore,
useSegmentationPresentationStore,
useSynchronizersStore,
useSelectedSegmentationsForViewportStore,
} from './stores';
import { useToggleOneUpViewportGridStore } from '@ohif/extension-default';
import { useActiveViewportSegmentationRepresentations } from './hooks/useActiveViewportSegmentationRepresentations';
@@ -58,7 +57,6 @@ import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownload
import utils from './utils';
import { useMeasurementTracking } from './hooks/useMeasurementTracking';
import { setUpSegmentationEventHandlers } from './utils/setUpSegmentationEventHandlers';
import { setUpAnnotationEventHandlers } from './utils/setUpAnnotationEventHandlers';
export * from './components';
const { imageRetrieveMetadataProvider } = cornerstone.utilities;
@@ -104,9 +102,6 @@ const cornerstoneExtension: Types.Extensions.Extension = {
});
unsubscriptions.push(...segmentationUnsubscriptions);
const annotationUnsubscriptions = setUpAnnotationEventHandlers();
unsubscriptions.push(...annotationUnsubscriptions);
toolbarService.registerEventForToolbarUpdate(cornerstoneViewportService, [
cornerstoneViewportService.EVENTS.VIEWPORT_DATA_CHANGED,
]);
@@ -114,7 +109,6 @@ const cornerstoneExtension: Types.Extensions.Extension = {
toolbarService.registerEventForToolbarUpdate(segmentationService, [
segmentationService.EVENTS.SEGMENTATION_REMOVED,
segmentationService.EVENTS.SEGMENTATION_MODIFIED,
segmentationService.EVENTS.SEGMENTATION_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED,
]);
toolbarService.registerEventForToolbarUpdate(cornerstone.eventTarget, [
@@ -159,9 +153,6 @@ const cornerstoneExtension: Types.Extensions.Extension = {
useSynchronizersStore.getState().clearSynchronizersStore();
useToggleOneUpViewportGridStore.getState().clearToggleOneUpViewportGridStore();
useSegmentationPresentationStore.getState().clearSegmentationPresentationStore();
useSelectedSegmentationsForViewportStore
.getState()
.clearSelectedSegmentationsForViewportStore();
segmentationService.removeAllSegmentations();
},
@@ -265,7 +256,6 @@ export {
usePositionPresentationStore,
useSegmentationPresentationStore,
useSynchronizersStore,
useSelectedSegmentationsForViewportStore,
Enums,
useMeasurements,
useActiveViewportSegmentationRepresentations,
+2 -19
View File
@@ -55,10 +55,6 @@ export default async function init({
extensionManager,
appConfig,
}: withAppTypes): Promise<void> {
// Use a public library path of PUBLIC_URL plus the component name
// This safely separates components that are loaded as-is.
window.PUBLIC_LIB_URL ||= './${component}/';
// Note: this should run first before initializing the cornerstone
// DO NOT CHANGE THE ORDER
@@ -106,12 +102,6 @@ export default async function init({
colorbarService.EVENTS.STATE_CHANGED,
]);
toolbarService.registerEventForToolbarUpdate(segmentationService, [
segmentationService.EVENTS.SEGMENTATION_MODIFIED,
segmentationService.EVENTS.SEGMENTATION_REPRESENTATION_MODIFIED,
segmentationService.EVENTS.SEGMENTATION_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED,
]);
window.services = servicesManager.services;
window.extensionManager = extensionManager;
window.commandsManager = commandsManager;
@@ -137,18 +127,10 @@ export default async function init({
getSegmentationPresentationId
);
segmentationService.setStyle(
cornerstoneTools.segmentation.config.style.setStyle(
{ type: SegmentationRepresentations.Contour },
{
// Declare these alpha values at the Contour type level so that they can be set/changed/inherited for all contour segmentations.
fillAlpha: 0.5,
fillAlphaInactive: 0.4,
// In general do not fill contours so that hydrated RTSTRUCTs are not filled in when active or inactive by default.
// However, hydrated RTSTRUCTs are filled in when active or inactive if the user chooses to fill ALL contours.
// Those Contours created in OHIF (i.e. using the Segmentation Panel) will override both fill properties upon creation.
renderFill: false,
renderFillInactive: false,
}
);
@@ -213,6 +195,7 @@ export default async function init({
commandsManager.runCommand('jumpToMeasurementViewport', { measurement, annotationUID, evt });
});
// When a custom image load is performed, update the relevant viewports
hangingProtocolService.subscribe(
hangingProtocolService.EVENTS.CUSTOM_IMAGE_LOAD_PERFORMED,
@@ -41,10 +41,6 @@ import {
SegmentSelectTool,
RegionSegmentPlusTool,
SegmentLabelTool,
LivewireContourSegmentationTool,
SculptorTool,
SplineContourSegmentationTool,
LabelMapEditWithContourTool,
} from '@cornerstonejs/tools';
import { LabelmapSlicePropagationTool, MarkerLabelmapTool } from '@cornerstonejs/ai';
import * as polySeg from '@cornerstonejs/polymorphic-segmentation';
@@ -113,10 +109,6 @@ export default function initCornerstoneTools(configuration = {}) {
addTool(LabelmapSlicePropagationTool);
addTool(MarkerLabelmapTool);
addTool(RegionSegmentPlusTool);
addTool(LivewireContourSegmentationTool);
addTool(SculptorTool);
addTool(SplineContourSegmentationTool);
addTool(LabelMapEditWithContourTool);
// Modify annotation tools to use dashed lines on SR
const annotationStyle = {
textBoxFontSize: '15px',
@@ -176,10 +168,6 @@ const toolNames = {
LabelmapSlicePropagation: LabelmapSlicePropagationTool.toolName,
MarkerLabelmap: MarkerLabelmapTool.toolName,
RegionSegmentPlus: RegionSegmentPlusTool.toolName,
LivewireContourSegmentation: LivewireContourSegmentationTool.toolName,
SculptorTool: SculptorTool.toolName,
SplineContourSegmentation: SplineContourSegmentationTool.toolName,
LabelMapEditWithContourTool: LabelMapEditWithContourTool.toolName,
};
export { toolNames };
@@ -450,7 +450,7 @@ const connectMeasurementServiceToTools = ({
if (measurement?.metadata?.referencedImageId) {
imageId = measurement.metadata.referencedImageId;
frameNumber = getSOPInstanceAttributes(measurement.metadata.referencedImageId).frameNumber;
} else if (instance) {
} else {
imageId = dataSource.getImageIdsForInstance({ instance });
}
@@ -461,9 +461,6 @@ const connectMeasurementServiceToTools = ({
const annotationManager = annotation.state.getAnnotationManager();
const newAnnotation = {
annotationUID: measurement.uid,
// Not used in CS3D but stored in the CS3D state so that saving
// can apply the predecessor consistently.
predecessorImageId: measurement?.predecessorImageId,
highlighted: false,
isLocked: false,
// This is used to force a re-render of the annotation to
@@ -506,15 +503,11 @@ const connectMeasurementServiceToTools = ({
}
const removedAnnotation = annotation.state.getAnnotation(removedMeasurementId);
removeAnnotation(removedMeasurementId);
// Ensure `removedAnnotation` is available before triggering the memo,
// as it can be undefined during an undo operation
if (removedAnnotation) {
commandsManager.run('triggerCreateAnnotationMemo', {
annotation: removedAnnotation,
FrameOfReferenceUID: removedAnnotation.metadata.FrameOfReferenceUID,
options: { deleting: true },
});
}
commandsManager.run('triggerCreateAnnotationMemo', {
annotation: removedAnnotation,
FrameOfReferenceUID: removedAnnotation.metadata.FrameOfReferenceUID,
options: { deleting: true },
});
const renderingEngine = cornerstoneViewportService.getRenderingEngine();
// Note: We could do a better job by triggering the render on the
// viewport itself, but the removeAnnotation does not include that info...
@@ -78,7 +78,6 @@ export default function PanelMeasurement(props): React.ReactNode {
);
return cloned;
}
// Need to merge defaults on the content props to ensure they get passed to children
return <StudyMeasurements items={displayMeasurements} />;
}
@@ -1,92 +1,16 @@
import React, { useCallback, useEffect } from 'react';
import {
IconPresentationProvider,
Popover,
PopoverAnchor,
PopoverContent,
SegmentationTable,
ToolSettings,
} from '@ohif/ui-next';
import React from 'react';
import { SegmentationTable } from '@ohif/ui-next';
import { useActiveViewportSegmentationRepresentations } from '../hooks/useActiveViewportSegmentationRepresentations';
import { useActiveToolOptions, useSystem } from '@ohif/core/src';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import { Toolbar, useUIStateStore } from '@ohif/extension-default';
import SegmentationUtilityButton from '../components/SegmentationUtilityButton';
import { useSelectedSegmentationsForViewportStore } from '../stores';
import {
hasExportableLabelMapData,
hasExportableContourData,
} from '../utils/segmentationExportUtils';
import { metaData, cache } from '@cornerstonejs/core';
import { useSystem } from '@ohif/core/src';
type PanelSegmentationProps = {
children?: React.ReactNode;
// The representation type for this segmentation panel. Undefined means all types.
segmentationRepresentationType?: SegmentationRepresentations;
} & withAppTypes;
export default function PanelSegmentation({
children,
segmentationRepresentationType,
}: PanelSegmentationProps) {
export default function PanelSegmentation({ children }: withAppTypes) {
const { commandsManager, servicesManager } = useSystem();
const {
customizationService,
displaySetService,
viewportGridService,
toolbarService,
segmentationService,
} = servicesManager.services;
const { activeViewportId } = viewportGridService.getState();
const utilitiesSectionMap = {
[SegmentationRepresentations.Labelmap]: toolbarService.sections.labelMapSegmentationUtilities,
[SegmentationRepresentations.Contour]: toolbarService.sections.contourSegmentationUtilities,
};
const selectedSegmentationsForViewportMap = useSelectedSegmentationsForViewportStore(
store => store.selectedSegmentationsForViewport[activeViewportId]
);
const selectedSegmentationIdForType = segmentationRepresentationType
? selectedSegmentationsForViewportMap?.get(segmentationRepresentationType)
: segmentationService?.getActiveSegmentation(activeViewportId)?.segmentationId;
const buttonSection = utilitiesSectionMap[segmentationRepresentationType];
const { activeToolOptions: activeUtilityOptions } = useActiveToolOptions({
buttonSectionId: buttonSection,
});
const { customizationService, displaySetService } = servicesManager.services;
const { segmentationsWithRepresentations, disabled } =
useActiveViewportSegmentationRepresentations();
const setUIState = useUIStateStore(store => store.setUIState);
// useEffect for handling clicks on any of the non-active viewports.
// The ViewportGrid stops the propagation of pointer/mouse events
// for non-active viewports so the Popover below
// is not closed when clicking on any of the non-active viewports.
useEffect(() => {
setUIState('activeSegmentationUtility', null);
toolbarService.refreshToolbarState({ viewportId: activeViewportId });
}, [activeViewportId, setUIState, toolbarService]);
// The callback for handling clicks outside of the Popover and, the SegmentationUtilityButton
// that triggered it to open. Clicks outside those components must close the Popover.
// The Popover is made visible whenever the options associated with the
// activeSegmentationUtility exist. Thus clearing the activeSegmentationUtility
// clears the associated options and will keep the Popover closed.
const handlePopoverOpenChange = useCallback(
(open: boolean) => {
if (!open) {
setUIState('activeSegmentationUtility', null);
toolbarService.refreshToolbarState({ viewportId: activeViewportId });
}
},
[activeViewportId, setUIState, toolbarService]
);
// Extract customization options
const segmentationTableMode = customizationService.getCustomization(
'panelSegmentation.tableMode'
@@ -111,7 +35,6 @@ export default function PanelSegmentation({
},
onSegmentAdd: segmentationId => {
commandsManager.run('addSegment', { segmentationId });
commandsManager.run('setActiveSegmentation', { segmentationId });
},
onSegmentClick: (segmentationId, segmentIndex) => {
commandsManager.run('setActiveSegmentAndCenter', { segmentationId, segmentIndex });
@@ -128,14 +51,6 @@ export default function PanelSegmentation({
onSegmentDelete: (segmentationId, segmentIndex) => {
commandsManager.run('deleteSegment', { segmentationId, segmentIndex });
},
onSegmentCopy:
segmentationRepresentationType === SegmentationRepresentations.Contour
? (segmentationId, segmentIndex) => {
commandsManager.run('copyContourSegment', {
sourceSegmentInfo: { segmentationId, segmentIndex },
});
}
: undefined,
onToggleSegmentVisibility: (segmentationId, segmentIndex, type) => {
commandsManager.run('toggleSegmentVisibility', { segmentationId, segmentIndex, type });
},
@@ -161,36 +76,18 @@ export default function PanelSegmentation({
commandsManager.run('deleteSegmentation', { segmentationId });
},
setFillAlpha: ({ type }, value) => {
commandsManager.run('activateSelectedSegmentationOfType', {
segmentationRepresentationType: type,
});
commandsManager.run('setFillAlpha', { type, value });
},
setOutlineWidth: ({ type }, value) => {
commandsManager.run('activateSelectedSegmentationOfType', {
segmentationRepresentationType: type,
});
commandsManager.run('setOutlineWidth', { type, value });
},
setRenderFill: ({ type }, value) => {
commandsManager.run('activateSelectedSegmentationOfType', {
segmentationRepresentationType: type,
});
commandsManager.run('setRenderFill', { type, value });
},
setRenderFillInactive: ({ type }, value) => {
commandsManager.run('setRenderFillInactive', { type, value });
},
setRenderOutline: ({ type }, value) => {
commandsManager.run('activateSelectedSegmentationOfType', {
segmentationRepresentationType: type,
});
commandsManager.run('setRenderOutline', { type, value });
},
setRenderOutlineInactive: ({ type }, value) => {
commandsManager.run('setRenderOutlineInactive', { type, value });
},
setFillAlphaInactive: ({ type }: { type?: string }, value) => {
setFillAlphaInactive: ({ type }, value) => {
commandsManager.run('setFillAlphaInactive', { type, value });
},
getRenderInactiveSegmentations: () => {
@@ -199,26 +96,52 @@ export default function PanelSegmentation({
};
// Generate export options
// Map each segmentation to an export option for it.
// A segmentation is exportable if it has any labelmap or contour data.
const exportOptions = segmentationsWithRepresentations.map(({ segmentation }) => {
const { representationData, segmentationId } = segmentation;
const { Labelmap, Contour } = representationData;
const { Labelmap } = representationData;
if (!Labelmap && !Contour) {
if (!Labelmap) {
return { segmentationId, isExportable: true };
}
if (
!hasExportableLabelMapData(Labelmap, displaySetService) &&
!hasExportableContourData(Contour)
) {
// Check if any segments have anything drawn in any of the viewports
const hasAnySegmentData = (() => {
const imageIds = Labelmap.imageIds;
if (!imageIds?.length) return false;
for (const imageId of imageIds) {
const pixelData = cache.getImage(imageId)?.getPixelData();
if (!pixelData) continue;
for (let i = 0; i < pixelData.length; i++) {
if (pixelData[i] !== 0) return true;
}
}
return false;
})();
if (!hasAnySegmentData) {
return { segmentationId, isExportable: false };
}
const referencedImageIds = Labelmap.referencedImageIds;
const firstImageId = referencedImageIds[0];
const instance = metaData.get('instance', firstImageId);
if (!instance) {
return { segmentationId, isExportable: false };
}
const SOPInstanceUID = instance.SOPInstanceUID || instance.SopInstanceUID;
const SeriesInstanceUID = instance.SeriesInstanceUID;
const displaySet = displaySetService.getDisplaySetForSOPInstanceUID(
SOPInstanceUID,
SeriesInstanceUID
);
return {
segmentationId,
isExportable: true,
isExportable: displaySet?.isReconstructable,
};
});
@@ -227,34 +150,15 @@ export default function PanelSegmentation({
disabled,
data: segmentationsWithRepresentations,
mode: segmentationTableMode,
title: `${segmentationRepresentationType ? `${segmentationRepresentationType} ` : ''}Segmentations`,
title: 'Segmentations',
exportOptions,
disableEditing,
onSegmentationAdd,
showAddSegment,
renderInactiveSegmentations: handlers.getRenderInactiveSegmentations(),
segmentationRepresentationType,
selectedSegmentationIdForType,
...handlers,
};
const renderUtilitiesToolbar = () => {
if (!buttonSection) {
return null;
}
return (
<IconPresentationProvider
size="large"
IconContainer={SegmentationUtilityButton}
>
<div className="flex flex-wrap gap-[3px] bg-transparent pb-[2px] pl-[8px] pt-[6px]">
<Toolbar buttonSection={buttonSection} />
</div>
</IconPresentationProvider>
);
};
const renderSegments = () => {
return (
<SegmentationTable.Segments>
@@ -271,7 +175,6 @@ export default function PanelSegmentation({
if (tableProps.mode === 'collapsed') {
return (
<SegmentationTable.Collapsed>
{renderUtilitiesToolbar()}
<SegmentationTable.Collapsed.Header>
<SegmentationTable.Collapsed.DropdownMenu>
<CustomDropdownMenuContent />
@@ -290,7 +193,6 @@ export default function PanelSegmentation({
return (
<>
<SegmentationTable.Expanded>
{renderUtilitiesToolbar()}
<SegmentationTable.Expanded.Header>
<SegmentationTable.Expanded.DropdownMenu>
<CustomDropdownMenuContent />
@@ -309,27 +211,11 @@ export default function PanelSegmentation({
};
return (
<Popover
open={!!activeUtilityOptions}
onOpenChange={handlePopoverOpenChange}
>
<PopoverAnchor>
<SegmentationTable {...tableProps}>
{children}
<SegmentationTable.Config />
<SegmentationTable.AddSegmentationRow />
{renderModeContent()}
</SegmentationTable>
</PopoverAnchor>
{activeUtilityOptions && (
<PopoverContent
side="left"
align="start"
className="w-auto"
>
<ToolSettings options={activeUtilityOptions} />
</PopoverContent>
)}
</Popover>
<SegmentationTable {...tableProps}>
{children}
<SegmentationTable.Config />
<SegmentationTable.AddSegmentationRow />
{renderModeContent()}
</SegmentationTable>
);
}
@@ -233,7 +233,7 @@ class CornerstoneCacheService {
for (const displaySet of displaySets) {
const { Modality } = displaySet;
const isParametricMap = Modality === 'PMAP';
const isSegOrRtstruct = Modality === 'SEG' || Modality === 'RTSTRUCT';
const isSeg = Modality === 'SEG';
// Don't create volumes for the displaySets that have custom load
// function (e.g., SEG, RT, since they rely on the reference volumes
@@ -276,7 +276,7 @@ class CornerstoneCacheService {
// Parametric maps do not have image ids but they already have volume data
// therefore a new volume should not be created.
if (!isParametricMap && !isSegOrRtstruct && (!volumeImageIds || !volume)) {
if (!isParametricMap && !isSeg && (!volumeImageIds || !volume)) {
volumeImageIds = this._getCornerstoneVolumeImageIds(displaySet, dataSource);
volume = await volumeLoader.createAndCacheVolume(volumeId, {
@@ -9,34 +9,30 @@ import {
utilities as csUtils,
metaData,
} from '@cornerstonejs/core';
import { ViewportType } from '@cornerstonejs/core/enums';
import {
Enums as csToolsEnums,
segmentation as cstSegmentation,
Types as cstTypes,
} from '@cornerstonejs/tools';
import { PubSubService, Types as OHIFTypes } from '@ohif/core';
import i18n from '@ohif/i18n';
import { VOLUME_LOADER_SCHEME } from '../../constants';
import { easeInOutBell, easeInOutBellRelative } from '../../utils/transitions';
import { mapROIContoursToRTStructData } from './RTSTRUCT/mapROIContoursToRTStructData';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import { addColorLUT } from '@cornerstonejs/tools/segmentation/addColorLUT';
import { getNextColorLUTIndex } from '@cornerstonejs/tools/segmentation/getNextColorLUTIndex';
import { Segment } from '@cornerstonejs/tools/types/SegmentationStateTypes';
import { ContourStyle, LabelmapStyle, SurfaceStyle } from '@cornerstonejs/tools/types';
import { ViewportType } from '@cornerstonejs/core/enums';
import { SegmentationPresentation, SegmentationPresentationItem } from '../../types/Presentation';
import { EasingFunctionEnum, EasingFunctionMap } from '../../utils/transitions';
import { updateLabelmapSegmentationImageReferences } from '@cornerstonejs/tools/segmentation/updateLabelmapSegmentationImageReferences';
import { triggerSegmentationRepresentationModified } from '@cornerstonejs/tools/segmentation/triggerSegmentationEvents';
import { convertStackToVolumeLabelmap } from '@cornerstonejs/tools/segmentation/helpers/convertStackToVolumeLabelmap';
import { getLabelmapImageIds } from '@cornerstonejs/tools/segmentation';
import { VOLUME_LOADER_SCHEME } from '../../constants';
const {
Labelmap: LABELMAP,
Contour: CONTOUR,
Surface: SURFACE,
} = csToolsEnums.SegmentationRepresentations;
const {
getLabelmapImageIds,
helpers: { convertStackToVolumeLabelmap },
state: { addColorLUT, updateLabelmapSegmentationImageReferences },
triggerSegmentationEvents: { triggerSegmentationRepresentationModified },
} = cstSegmentation;
const LABELMAP = csToolsEnums.SegmentationRepresentations.Labelmap;
const CONTOUR = csToolsEnums.SegmentationRepresentations.Contour;
export type SegmentRepresentation = {
segmentIndex: number;
@@ -81,10 +77,6 @@ const EVENTS = {
SEGMENT_LOADING_COMPLETE: 'event::segment_loading_complete',
// loading completed for all segments
SEGMENTATION_LOADING_COMPLETE: 'event::segmentation_loading_complete',
// fired when a contour annotation cut merge process is completed
SEGMENTATION_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED:
'event::annotation_cut_merge_process_completed',
SEGMENTATION_STYLE_MODIFIED: 'event::segmentation_style_modified',
};
const VALUE_TYPES = {};
@@ -157,11 +149,13 @@ class SegmentationService extends PubSubService {
const representations = this.getSegmentationRepresentations(viewportId);
for (const representation of representations) {
const { segmentationId } = representation;
if (!representation) {
continue;
}
const { segmentationId, type } = representation;
const { type } = representation;
segmentationsMap.set(segmentationId, {
segmentationId,
@@ -218,7 +212,7 @@ class SegmentationService extends PubSubService {
viewportId: string,
specifier: {
segmentationId?: string;
type?: csToolsEnums.SegmentationRepresentations;
type?: SegmentationRepresentations;
} = {}
): SegmentationRepresentation[] {
// Get all representations for the viewportId
@@ -251,19 +245,9 @@ class SegmentationService extends PubSubService {
this._onSegmentationDataModifiedFromSource
);
eventTarget.removeEventListener(
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_MODIFIED,
this._onSegmentationRepresentationModifiedFromSource
);
eventTarget.removeEventListener(
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_ADDED,
this._onSegmentationRepresentationModifiedFromSource
);
eventTarget.removeEventListener(
csToolsEnums.Events.SEGMENTATION_REPRESENTATION_REMOVED,
this._onSegmentationRepresentationModifiedFromSource
this._onSegmentationModifiedFromSource
);
eventTarget.removeEventListener(
@@ -278,13 +262,11 @@ class SegmentationService extends PubSubService {
viewportId: string,
{
segmentationId,
predecessorImageId,
type,
config,
suppressEvents = false,
}: {
segmentationId: string;
predecessorImageId?: string;
type?: csToolsEnums.SegmentationRepresentations;
config?: {
blendMode?: csEnums.BlendModes;
@@ -293,9 +275,6 @@ class SegmentationService extends PubSubService {
}
): Promise<void> {
const segmentation = this.getSegmentation(segmentationId);
if (segmentation && !segmentation.predecessorImageId && predecessorImageId) {
segmentation.predecessorImageId = predecessorImageId;
}
const csViewport = this.getAndValidateViewport(viewportId);
if (!csViewport) {
@@ -304,13 +283,11 @@ class SegmentationService extends PubSubService {
const colorLUTIndex = this._segmentationIdToColorLUTIndexMap.get(segmentationId);
const defaultRepresentationType = csToolsEnums.SegmentationRepresentations.Labelmap;
let representationTypeToUse = type || defaultRepresentationType;
let isConverted = false;
const defaultRepresentationType: csToolsEnums.SegmentationRepresentations =
csViewport.type === ViewportType.VOLUME_3D ? SURFACE : LABELMAP;
let representationTypeToUse = type || defaultRepresentationType;
if (representationTypeToUse === LABELMAP) {
if (type === csToolsEnums.SegmentationRepresentations.Labelmap) {
const { isVolumeViewport, isVolumeSegmentation } = this.determineViewportAndSegmentationType(
csViewport,
segmentation
@@ -359,39 +336,6 @@ class SegmentationService extends PubSubService {
FrameOfReferenceUID?: string;
label?: string;
}
): Promise<string> {
return this._createSegmentationForDisplaySet(displaySet, LABELMAP, options);
}
public async createContourForDisplaySet(
displaySet: AppTypes.DisplaySet,
options?: {
segmentationId?: string;
segments?: { [segmentIndex: number]: Partial<cstTypes.Segment> };
FrameOfReferenceUID?: string;
label?: string;
}
): Promise<string> {
return this._createSegmentationForDisplaySet(displaySet, CONTOUR, options);
}
/**
* Private method to create segmentation for a display set with the specified type
*
* @param displaySet - The display set to create the segmentation for
* @param segmentationType - The type of segmentation (SegmentationRepresentations enum)
* @param options - Optional parameters for creating the segmentation
* @returns A promise that resolves to the created segmentation ID
*/
private async _createSegmentationForDisplaySet(
displaySet: AppTypes.DisplaySet,
segmentationType: SegmentationRepresentations,
options?: {
segmentationId?: string;
segments?: { [segmentIndex: number]: Partial<cstTypes.Segment> };
FrameOfReferenceUID?: string;
label?: string;
}
): Promise<string> {
// Todo: random does not makes sense, make this better, like
// labelmap 1, 2, 3 etc
@@ -410,14 +354,14 @@ class SegmentationService extends PubSubService {
const derivedImages = await imageLoader.createAndCacheDerivedLabelmapImages(referenceImageIds);
const segs = this.getSegmentations();
const label = options?.label || `Segmentation ${segs.length + 1}`;
const label = options.label || `Segmentation ${segs.length + 1}`;
const segImageIds = derivedImages.map(image => image.imageId);
const segmentationPublicInput: cstTypes.SegmentationPublicInput = {
segmentationId,
representation: {
type: segmentationType,
type: LABELMAP,
data: {
imageIds: segImageIds,
// referencedVolumeId: this._getVolumeIdForDisplaySet(displaySet),
@@ -427,7 +371,7 @@ class SegmentationService extends PubSubService {
config: {
label,
segments:
options?.segments && Object.keys(options.segments).length > 0
options.segments && Object.keys(options.segments).length > 0
? options.segments
: {
1: {
@@ -449,7 +393,7 @@ class SegmentationService extends PubSubService {
segDisplaySet,
options: {
segmentationId?: string;
type: csToolsEnums.SegmentationRepresentations;
type: SegmentationRepresentations;
} = {
type: LABELMAP,
}
@@ -559,7 +503,9 @@ class SegmentationService extends PubSubService {
};
});
const colorLUTIndex = addColorLUT(colorLUT);
// get next color lut index
const colorLUTIndex = getNextColorLUTIndex();
addColorLUT(colorLUT, colorLUTIndex);
this._segmentationIdToColorLUTIndexMap.set(segmentationId, colorLUTIndex);
this._broadcastEvent(EVENTS.SEGMENTATION_LOADING_COMPLETE, {
@@ -594,7 +540,7 @@ class SegmentationService extends PubSubService {
rtDisplaySet,
options: {
segmentationId?: string;
type: csToolsEnums.SegmentationRepresentations;
type: SegmentationRepresentations;
} = {
type: CONTOUR,
}
@@ -628,19 +574,10 @@ class SegmentationService extends PubSubService {
// find the first image id that contains a referenced SOP instance UID
const firstSegmentedSliceImageId =
referencedImageIds?.find(imageId =>
referencedImageIdsWithGeometry.some(referencedId =>
imageId.includes(referencedId as string)
)
referencedImageIdsWithGeometry.some(referencedId => imageId.includes(referencedId))
) || null;
rtDisplaySet.firstSegmentedSliceImageId = firstSegmentedSliceImageId;
if (!structureSet.ROIContours?.length) {
throw new Error(
'The structureSet does not contain any ROIContours. Please ensure the structureSet is loaded first.'
);
}
// Map ROI contours to RT Struct Data
const allRTStructData = mapROIContoursToRTStructData(structureSet, rtDisplaySetUID);
@@ -663,6 +600,12 @@ class SegmentationService extends PubSubService {
},
};
if (!structureSet.ROIContours?.length) {
throw new Error(
'The structureSet does not contain any ROIContours. Please ensure the structureSet is loaded first.'
);
}
const segments: { [segmentIndex: string]: cstTypes.Segment } = {};
let segmentsCachedStats = {};
@@ -670,9 +613,7 @@ class SegmentationService extends PubSubService {
const colorLUT = [[0, 0, 0, 0]]; // First entry is transparent for index 0
// Process each segment similarly to the SEG function
for (let i = 0; i < allRTStructData.length; i++) {
const rtStructData = allRTStructData[i];
for (const rtStructData of allRTStructData) {
const { data, id, color, segmentIndex, geometryId, group } = rtStructData;
// Add the color to the colorLUT array
@@ -721,7 +662,8 @@ class SegmentationService extends PubSubService {
}
// Create and register the colorLUT
const colorLUTIndex = addColorLUT(colorLUT);
const colorLUTIndex = getNextColorLUTIndex();
addColorLUT(colorLUT, colorLUTIndex);
this._segmentationIdToColorLUTIndexMap.set(segmentationId, colorLUTIndex);
// Assign processed segments to segmentation config
@@ -818,7 +760,7 @@ class SegmentationService extends PubSubService {
public hasCustomStyles(specifier: {
viewportId: string;
segmentationId: string;
type: csToolsEnums.SegmentationRepresentations;
type: SegmentationRepresentations;
}): boolean {
return cstSegmentation.config.style.hasCustomStyle(specifier);
}
@@ -826,7 +768,7 @@ class SegmentationService extends PubSubService {
public getStyle = (specifier: {
viewportId: string;
segmentationId: string;
type: csToolsEnums.SegmentationRepresentations;
type: SegmentationRepresentations;
segmentIndex?: number;
}) => {
const style = cstSegmentation.config.style.getStyle(specifier);
@@ -836,35 +778,20 @@ class SegmentationService extends PubSubService {
public setStyle = (
specifier: {
type: csToolsEnums.SegmentationRepresentations;
type: SegmentationRepresentations;
viewportId?: string;
segmentationId?: string;
segmentIndex?: number;
},
style: cstTypes.LabelmapStyle | cstTypes.ContourStyle | cstTypes.SurfaceStyle,
merge: boolean = true
style: LabelmapStyle | ContourStyle | SurfaceStyle
) => {
cstSegmentation.config.style.setStyle(specifier, style, merge);
this._broadcastEvent(EVENTS.SEGMENTATION_STYLE_MODIFIED, {
specifier,
style,
merge,
});
cstSegmentation.config.style.setStyle(specifier, style);
};
public resetToGlobalStyle = () => {
cstSegmentation.config.style.resetToGlobalStyle();
};
public getNextAvailableSegmentIndex(segmentationId: string): number {
const csSegmentation = this.getCornerstoneSegmentation(segmentationId);
// grab the next available segment index based on the object keys,
// so basically get the highest segment index value + 1
const segmentKeys = Object.keys(csSegmentation.segments);
return segmentKeys.length === 0 ? 1 : Math.max(...segmentKeys.map(Number)) + 1;
}
/**
* Adds a new segment to the specified segmentation.
* @param segmentationId - The ID of the segmentation to add the segment to.
@@ -898,7 +825,10 @@ class SegmentationService extends PubSubService {
let segmentIndex = config.segmentIndex;
if (!segmentIndex) {
segmentIndex = this.getNextAvailableSegmentIndex(segmentationId);
// grab the next available segment index based on the object keys,
// so basically get the highest segment index value + 1
const segmentKeys = Object.keys(csSegmentation.segments);
segmentIndex = segmentKeys.length === 0 ? 1 : Math.max(...segmentKeys.map(Number)) + 1;
}
// update the segmentation
@@ -971,7 +901,7 @@ class SegmentationService extends PubSubService {
segmentationId: string,
segmentIndex: number,
isVisible: boolean,
type?: csToolsEnums.SegmentationRepresentations
type?: SegmentationRepresentations
): void {
this._setSegmentVisibility(viewportId, segmentationId, segmentIndex, isVisible, type);
}
@@ -1008,7 +938,7 @@ class SegmentationService extends PubSubService {
viewportId: string,
segmentationId: string,
segmentIndex: number,
type: csToolsEnums.SegmentationRepresentations
type: SegmentationRepresentations
): void {
const isVisible = cstSegmentation.config.visibility.getSegmentIndexVisibility(
viewportId,
@@ -1039,12 +969,6 @@ class SegmentationService extends PubSubService {
segmentIndex: number,
color: csTypes.Color
): void {
const segmentationRepresentations = this.getSegmentationRepresentations(viewportId, {
segmentationId,
});
const { colorLUTIndex } = segmentationRepresentations[0];
this._segmentationIdToColorLUTIndexMap.set(segmentationId, colorLUTIndex);
cstSegmentation.config.color.setSegmentIndexColor(
viewportId,
segmentationId,
@@ -1086,7 +1010,7 @@ class SegmentationService extends PubSubService {
public getLabelmapVolume(segmentationId: string) {
const csSegmentation = cstSegmentation.state.getSegmentation(segmentationId);
const labelmapData = csSegmentation.representationData[
LABELMAP
SegmentationRepresentations.Labelmap
] as cstTypes.LabelmapToolOperationDataVolume;
if (!labelmapData || !labelmapData.volumeId) {
@@ -1188,10 +1112,7 @@ class SegmentationService extends PubSubService {
*/
public toggleSegmentationRepresentationVisibility = (
viewportId: string,
{
segmentationId,
type,
}: { segmentationId: string; type: csToolsEnums.SegmentationRepresentations }
{ segmentationId, type }: { segmentationId: string; type: SegmentationRepresentations }
): void => {
this._toggleSegmentationRepresentationVisibility(viewportId, segmentationId, type);
};
@@ -1240,7 +1161,7 @@ class SegmentationService extends PubSubService {
viewportId: string,
specifier: {
segmentationId?: string;
type?: csToolsEnums.SegmentationRepresentations;
type?: SegmentationRepresentations;
} = {}
): void {
cstSegmentation.removeSegmentationRepresentations(viewportId, specifier);
@@ -1254,7 +1175,7 @@ class SegmentationService extends PubSubService {
highlightSegment = true,
animationLength = 750,
highlightHideOthers = false,
animationFunctionType: EasingFunctionEnum = EasingFunctionEnum.EASE_IN_OUT
highlightFunctionType = 'ease-in-out' // todo: make animation functions configurable from outside
): void {
const center = this._getSegmentCenter(segmentationId, segmentIndex);
if (!center) {
@@ -1280,8 +1201,7 @@ class SegmentationService extends PubSubService {
viewportId,
highlightAlpha,
animationLength,
highlightHideOthers,
animationFunctionType
highlightHideOthers
);
});
}
@@ -1293,7 +1213,7 @@ class SegmentationService extends PubSubService {
alpha = 0.9,
animationLength = 750,
hideOthers = true,
animationFunctionType: EasingFunctionEnum = EasingFunctionEnum.EASE_IN_OUT
highlightFunctionType = 'ease-in-out'
): void {
if (this.highlightIntervalId) {
clearInterval(this.highlightIntervalId);
@@ -1326,8 +1246,7 @@ class SegmentationService extends PubSubService {
segments,
viewportId,
animationLength,
representation,
animationFunctionType
representation
);
});
}
@@ -1352,7 +1271,7 @@ class SegmentationService extends PubSubService {
private _setSegmentationRepresentationVisibility(
viewportId: string,
segmentationId: string,
type: csToolsEnums.SegmentationRepresentations,
type: SegmentationRepresentations,
isVisible: boolean
): void {
const representations = this.getSegmentationRepresentations(viewportId, {
@@ -1412,17 +1331,14 @@ class SegmentationService extends PubSubService {
private async handleVolumeViewportCase(csViewport, segmentation, isVolumeSegmentation) {
if (csViewport.type === ViewportType.VOLUME_3D) {
return {
representationTypeToUse: SURFACE,
isConverted: false,
};
return { representationTypeToUse: SegmentationRepresentations.Surface, isConverted: false };
} else {
await this.handleVolumeViewport(
csViewport as csTypes.IVolumeViewport,
segmentation,
isVolumeSegmentation
);
return { representationTypeToUse: LABELMAP, isConverted: false };
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted: false };
}
}
@@ -1432,17 +1348,14 @@ class SegmentationService extends PubSubService {
isVolumeSegmentation: boolean,
viewportId: string,
segmentationId: string
): Promise<{
representationTypeToUse: csToolsEnums.SegmentationRepresentations;
isConverted: boolean;
}> {
): Promise<{ representationTypeToUse: SegmentationRepresentations; isConverted: boolean }> {
if (isVolumeSegmentation) {
const isConverted = await this.convertStackToVolumeViewport(csViewport);
return { representationTypeToUse: LABELMAP, isConverted };
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted };
}
if (updateLabelmapSegmentationImageReferences(viewportId, segmentationId)) {
return { representationTypeToUse: LABELMAP, isConverted: false };
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted: false };
}
const isConverted = await this.attemptStackToVolumeConversion(
@@ -1452,7 +1365,7 @@ class SegmentationService extends PubSubService {
segmentationId
);
return { representationTypeToUse: LABELMAP, isConverted };
return { representationTypeToUse: SegmentationRepresentations.Labelmap, isConverted };
}
private async _addSegmentationRepresentation(
@@ -1563,7 +1476,11 @@ class SegmentationService extends PubSubService {
segImage.FrameOfReferenceUID === frameOfReferenceUID
) {
const isConverted = await this.convertStackToVolumeViewport(viewport);
triggerSegmentationRepresentationModified(viewportId, segmentationId, LABELMAP);
triggerSegmentationRepresentationModified(
viewportId,
segmentationId,
SegmentationRepresentations.Labelmap
);
return isConverted;
}
@@ -1681,11 +1598,6 @@ class SegmentationService extends PubSubService {
csToolsEnums.Events.SEGMENTATION_ADDED,
this._onSegmentationAddedFromSource
);
eventTarget.addEventListener(
csToolsEnums.Events.ANNOTATION_CUT_MERGE_PROCESS_COMPLETED,
this._onAnnotationCutMergeProcessCompletedFromSource
);
}
private getCornerstoneSegmentation(segmentationId: string) {
@@ -1696,11 +1608,10 @@ class SegmentationService extends PubSubService {
segmentIndex: number,
alpha: number,
hideOthers: boolean,
segments: cstTypes.Segment[],
segments: Segment[],
viewportId: string,
animationLength: number,
representation: cstTypes.SegmentationRepresentation,
animationFunctionType: EasingFunctionEnum
representation: cstTypes.SegmentationRepresentation
) {
const { segmentationId } = representation;
const newSegmentSpecificConfig = {
@@ -1709,6 +1620,13 @@ class SegmentationService extends PubSubService {
if (hideOthers) {
throw new Error('hideOthers is not working right now');
for (let i = 0; i < segments.length; i++) {
if (i !== segmentIndex) {
newSegmentSpecificConfig[i] = {
fillAlpha: 0,
};
}
}
}
const { fillAlpha } = this.getStyle({
@@ -1727,8 +1645,6 @@ class SegmentationService extends PubSubService {
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / animationLength, 1);
const easingFunction = EasingFunctionMap.get(animationFunctionType);
cstSegmentation.config.style.setStyle(
{
segmentationId,
@@ -1736,7 +1652,7 @@ class SegmentationService extends PubSubService {
type: LABELMAP,
},
{
fillAlpha: easingFunction(progress, fillAlpha),
fillAlpha: easeInOutBell(progress, fillAlpha),
}
);
@@ -1749,8 +1665,7 @@ class SegmentationService extends PubSubService {
segmentIndex,
type: LABELMAP,
},
{},
false
{}
);
}
};
@@ -1762,20 +1677,21 @@ class SegmentationService extends PubSubService {
segmentIndex: number,
alpha: number,
hideOthers: boolean,
segments: cstTypes.Segment[],
segments: Segment[],
viewportId: string,
animationLength: number,
representation: cstTypes.SegmentationRepresentation,
animationFunctionType: EasingFunctionEnum
representation: cstTypes.SegmentationRepresentation
) {
const { segmentationId } = representation;
const startTime = performance.now();
const prevStyle = cstSegmentation.config.style.getStyle({
type: CONTOUR,
}) as cstTypes.ContourStyle;
}) as ContourStyle;
const prevOutlineWidth = prevStyle.outlineWidth;
// make this configurable
const baseline = Math.max(prevOutlineWidth * 3.5, 5);
const animate = (currentTime: number) => {
const progress = (currentTime - startTime) / animationLength;
@@ -1784,8 +1700,7 @@ class SegmentationService extends PubSubService {
return;
}
const OUTLINE_ANIMATION_SCALE_FACTOR = 5;
const easingFunction = EasingFunctionMap.get(animationFunctionType);
const reversedProgress = easeInOutBellRelative(progress, baseline, prevOutlineWidth);
cstSegmentation.config.style.setStyle(
{
@@ -1794,7 +1709,7 @@ class SegmentationService extends PubSubService {
type: CONTOUR,
},
{
outlineWidth: easingFunction(progress, prevOutlineWidth, OUTLINE_ANIMATION_SCALE_FACTOR),
outlineWidth: reversedProgress,
}
);
@@ -1807,18 +1722,24 @@ class SegmentationService extends PubSubService {
private _toggleSegmentationRepresentationVisibility = (
viewportId: string,
segmentationId: string,
type: csToolsEnums.SegmentationRepresentations
type: SegmentationRepresentations
): void => {
const segmentsHidden = cstSegmentation.config.visibility.getHiddenSegmentIndices(viewportId, {
const representations = this.getSegmentationRepresentations(viewportId, {
segmentationId,
type,
});
const representation = representations[0];
const segmentsHidden = cstSegmentation.config.visibility.getHiddenSegmentIndices(viewportId, {
segmentationId,
type: representation.type,
});
const currentVisibility = segmentsHidden.size === 0;
this._setSegmentationRepresentationVisibility(
viewportId,
segmentationId,
type,
representation.type,
!currentVisibility
);
};
@@ -1833,10 +1754,7 @@ class SegmentationService extends PubSubService {
return `${volumeLoaderSchema}:${displaySet.displaySetInstanceUID}`;
}
private _getSegmentCenter(
segmentationId: string,
segmentIndex: number
): { image?: csTypes.Point3; world: csTypes.Point3 } | undefined {
private _getSegmentCenter(segmentationId, segmentIndex) {
const segmentation = this.getSegmentation(segmentationId);
if (!segmentation) {
@@ -1847,17 +1765,19 @@ class SegmentationService extends PubSubService {
const { cachedStats } = segments[segmentIndex];
if (cachedStats?.center) {
const { center } = cachedStats;
return center as { image: csTypes.Point3; world: csTypes.Point3 };
if (!cachedStats || !cachedStats?.center || !cachedStats?.namedStats?.center) {
return;
}
if (cachedStats?.namedStats?.center) {
const { center } = cachedStats;
if (!center) {
return {
world: cachedStats.namedStats.center.value,
};
}
return center;
}
private _setSegmentLockedStatus(segmentationId: string, segmentIndex: number, isLocked: boolean) {
@@ -1869,7 +1789,7 @@ class SegmentationService extends PubSubService {
segmentationId: string,
segmentIndex: number,
isVisible: boolean,
type?: csToolsEnums.SegmentationRepresentations
type?: SegmentationRepresentations
) {
cstSegmentation.config.visibility.setSegmentIndexVisibility(
viewportId,
@@ -1932,13 +1852,6 @@ class SegmentationService extends PubSubService {
segmentationId,
});
};
private _onAnnotationCutMergeProcessCompletedFromSource = evt => {
const { segmentationId } = evt.detail;
this._broadcastEvent(this.EVENTS.SEGMENTATION_ANNOTATION_CUT_MERGE_PROCESS_COMPLETED, {
segmentationId,
});
};
}
export default SegmentationService;
@@ -43,7 +43,7 @@ const segmentationRepresentationModifiedCallback = async (
) => {
const event = sourceEvent as ToolsTypes.EventTypes.SegmentationRepresentationModifiedEventType;
const { segmentationId, type: segmentationRepresentationType } = event.detail;
const { segmentationId } = event.detail;
const { segmentationService } = servicesManager.services;
const targetViewportId = targetViewport.viewportId;
@@ -65,12 +65,13 @@ const segmentationRepresentationModifiedCallback = async (
return;
}
// Ensure the segmentation representation aligns with the target viewport type.
const type: Enums.SegmentationRepresentations =
viewport.type === CoreEnums.ViewportType.VOLUME_3D
? Enums.SegmentationRepresentations.Surface
: ((segmentationRepresentationType as Enums.SegmentationRepresentations) ??
Enums.SegmentationRepresentations.Labelmap);
// whatever type the source viewport has, we need to add that to the target viewport
const sourceViewportRepresentation = segmentationService.getSegmentationRepresentations(
sourceViewport.viewportId,
{ segmentationId }
);
const type = sourceViewportRepresentation[0].type;
await segmentationService.addSegmentationRepresentation(targetViewportId, {
segmentationId,
@@ -417,11 +417,6 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
// and we would lose the presentation.
this.storePresentation({ viewportId: viewportInfo.getViewportId() });
// Todo: i don't like this here, move it
this.servicesManager.services.segmentationService.clearSegmentationRepresentations(
viewportInfo.getViewportId()
);
if (!viewportInfo) {
throw new Error('element is not enabled for the given viewportId');
}
@@ -714,7 +709,7 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
// is being used to navigate to the initial view position for measurement
// navigation and other navigation forcing specific views.
let initialImageIndexToUse =
presentations?.positionPresentation?.initialImageIndex ?? (initialImageIndex as number);
presentations?.positionPresentation?.initialImageIndex ?? <number>initialImageIndex;
const { rotation, flipHorizontal, displayArea } = viewportInfo.getViewportOptions();
@@ -933,10 +928,6 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
const displaySet = displaySetService.getDisplaySetByUID(displaySetUIDs[0]);
const displaySetModality = displaySet?.Modality;
// seems like a hack but we need the actor to be ready first before
// we set the properties
const timeoutViewportCallback = (callback: () => void) => setTimeout(callback, 0);
// filter overlay display sets (e.g. segmentation) since they will get handled below via the segmentation service
const filteredVolumeInputArray = volumeInputArray
.map((volumeInput, index) => {
@@ -988,21 +979,12 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
const backgroundDisplaySet = displaySetService.getDisplaySetsBy(
displaySet =>
!displaySet.isOverlayDisplaySet &&
displaySet.images?.some(image => image.imageId === sampleImageId)
displaySet.images.some(image => image.imageId === sampleImageId)
);
if (backgroundDisplaySet.length !== 1) {
throw new Error('Background display set not found');
}
if (viewport.type === csEnums.ViewportType.VOLUME_3D) {
timeoutViewportCallback(() => {
viewportGridService.setDisplaySetsForViewport({
viewportId: viewport.id,
displaySetInstanceUIDs: [backgroundDisplaySet[0].displaySetInstanceUID],
});
});
}
}
});
}
@@ -1019,13 +1001,15 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
viewport.render();
volumesProperties.forEach(({ properties, volumeId }) => {
timeoutViewportCallback(() => {
setTimeout(() => {
// seems like a hack but we need the actor to be ready first before
// we set the properties
viewport.setProperties(properties, volumeId);
viewport.render();
});
}, 0);
});
this.setPresentations(viewport.id, presentations);
this.setPresentations(viewport.id, presentations, viewportInfo);
if (!presentations.positionPresentation) {
const imageIndex = this._getInitialImageIndexForViewport(viewportInfo);
@@ -1090,10 +1074,8 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
? csToolsEnums.SegmentationRepresentations.Labelmap
: csToolsEnums.SegmentationRepresentations.Contour;
const { predecessorImageId } = displaySet;
segmentationService.addSegmentationRepresentation(viewport.id, {
segmentationId,
predecessorImageId,
type: representationType,
});
@@ -1348,18 +1330,10 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
segmentationPresentation.forEach((presentationItem: SegmentationPresentationItem) => {
const { segmentationId, type, hydrated } = presentationItem;
const { Labelmap, Surface } = csToolsEnums.SegmentationRepresentations;
const isVolume3D = viewport.type === csEnums.ViewportType.VOLUME_3D;
// Determine the appropriate segmentation representation for the viewport.
// If the current type is Surface but the viewport is not 3D, fallback to Labelmap.
// Otherwise, use the existing type.
const representationType = type === Surface && !isVolume3D ? Labelmap : type;
if (hydrated) {
segmentationService.addSegmentationRepresentation(viewport.id, {
segmentationId,
type: representationType,
type,
});
}
});
@@ -2,4 +2,3 @@ export { useLutPresentationStore } from './useLutPresentationStore';
export { usePositionPresentationStore } from './usePositionPresentationStore';
export { useSegmentationPresentationStore } from './useSegmentationPresentationStore';
export { useSynchronizersStore } from './useSynchronizersStore';
export { useSelectedSegmentationsForViewportStore } from './useSelectedSegmentationsForViewportStore';
@@ -1,85 +0,0 @@
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import { SelectedSegmentationByTypeMap } from '../types/SelectedSegmentationByTypeMap';
const PRESENTATION_TYPE_ID = 'selectedSegmentationsForViewportId';
const DEBUG_STORE = false;
/**
* Represents the state and actions for managing selected segmentations for a viewport by representation type.
*/
type SelectedSegmentationsForViewportState = {
/**
* Stores a mapping from viewport id to a map of representation type to segmentation id.
*/
selectedSegmentationsForViewport: Record<string, SelectedSegmentationByTypeMap>;
/**
* Sets the selected segmentations for a given viewport id.
*
* @param key - The viewport id.
* @param value - The `SelectedSegmentationByTypeMap` to associate with the viewport id.
*/
setSelectedSegmentationsForViewport: (key: string, value: SelectedSegmentationByTypeMap) => void;
/**
* Clears all selected segmentations for all viewports.
*/
clearSelectedSegmentationsForViewportStore: () => void;
/**
* Type identifier for the store.
*/
type: string;
};
/**
* Creates the Selected Segmentations For Viewport store.
*
* @param set - The zustand set function.
* @returns The selected segmentations for viewport store state and actions.
*/
const createSelectedSegmentationsForViewportStore = (
set
): SelectedSegmentationsForViewportState => ({
selectedSegmentationsForViewport: {},
type: PRESENTATION_TYPE_ID,
/**
* Sets the selected segmentations for a given viewport id.
*/
setSelectedSegmentationsForViewport: (key, value) =>
set(
state => ({
selectedSegmentationsForViewport: {
...state.selectedSegmentationsForViewport,
[key]: value,
},
}),
false,
'setSelectedSegmentationsForViewport'
),
/**
* Clears all selected segmentations for all viewports.
*/
clearSelectedSegmentationsForViewportStore: () =>
set(
{ selectedSegmentationsForViewport: {} },
false,
'clearSelectedSegmentationsForViewportStore'
),
});
/**
* Zustand store for managing selected segmentations for a viewport by representation type.
* Applies devtools middleware when DEBUG_STORE is enabled.
*/
export const useSelectedSegmentationsForViewportStore =
create<SelectedSegmentationsForViewportState>()(
DEBUG_STORE
? devtools(createSelectedSegmentationsForViewportStore, {
name: 'SelectedSegmentationsForViewportStore',
})
: createSelectedSegmentationsForViewportStore
);
@@ -1,3 +0,0 @@
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
export type SelectedSegmentationByTypeMap = Map<SegmentationRepresentations, string>;
@@ -1,4 +1,3 @@
import { utils } from '@ohif/core';
import React, { useEffect, useState } from 'react';
import html2canvas from 'html2canvas';
import { getEnabledElement, StackViewport, BaseVolumeViewport } from '@cornerstonejs/core';
@@ -6,8 +5,6 @@ import { ToolGroupManager, segmentation, Enums } from '@cornerstonejs/tools';
import { getEnabledElement as OHIFgetEnabledElement } from '../state';
import { useSystem } from '@ohif/core/src';
const { downloadUrl } = utils;
const DEFAULT_SIZE = 512;
const MAX_TEXTURE_SIZE = 10000;
const VIEWPORT_ID = 'cornerstone-viewport-download-form';
@@ -221,7 +218,10 @@ const CornerstoneViewportDownloadForm = ({
}
const canvas = await html2canvas(divForDownloadViewport as HTMLElement);
downloadUrl(canvas.toDataURL(`image/${fileType}`, 1.0));
const link = document.createElement('a');
link.download = `${filename}.${fileType}`;
link.href = canvas.toDataURL(`image/${fileType}`, 1.0);
link.click();
};
const ViewportDownloadFormNew = customizationService.getCustomization(
@@ -1,74 +0,0 @@
import { utilities as csUtils } from '@cornerstonejs/core';
import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import i18n from '@ohif/i18n';
import { ServicesManager } from '@ohif/core';
function _createDefaultSegments(createInitialSegment?: boolean) {
return createInitialSegment
? {
1: {
label: `${i18n.t('Tools:Segment')} 1`,
active: true,
},
}
: {};
}
type CreateSegmentationForViewportOptions = {
displaySetInstanceUID?: string;
label?: string;
segmentationId?: string;
createInitialSegment?: boolean;
};
type CreateSegmentationForViewportParams = {
viewportId: string;
options?: CreateSegmentationForViewportOptions;
segmentationType: SegmentationRepresentations;
};
/**
* Creates a segmentation for the active viewport
*
* The created segmentation will be registered as a display set and also added
* as a segmentation representation to the viewport.
*/
export async function createSegmentationForViewport(
servicesManager: ServicesManager,
{ viewportId, options = {}, segmentationType }: CreateSegmentationForViewportParams
): Promise<string> {
const { viewportGridService, displaySetService, segmentationService } = servicesManager.services;
const { viewports } = viewportGridService.getState();
const targetViewportId = viewportId;
const viewport = viewports.get(targetViewportId);
// Todo: add support for multiple display sets
const displaySetInstanceUID = options.displaySetInstanceUID || viewport.displaySetInstanceUIDs[0];
const segs = segmentationService.getSegmentations();
const label = options.label || `${i18n.t('Tools:Segmentation')} ${segs.length + 1}`;
const segmentationId = options.segmentationId || `${csUtils.uuidv4()}`;
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
const segmentationCreationOptions = {
label,
segmentationId,
segments: _createDefaultSegments(options.createInitialSegment),
};
// This will create the segmentation and register it as a display set
const generatedSegmentationId = await (segmentationType === SegmentationRepresentations.Labelmap
? segmentationService.createLabelmapForDisplaySet(displaySet, segmentationCreationOptions)
: segmentationService.createContourForDisplaySet(displaySet, segmentationCreationOptions));
// Also add the segmentation representation to the viewport
await segmentationService.addSegmentationRepresentation(viewportId, {
segmentationId,
type: segmentationType,
});
return generatedSegmentationId;
}
Loaded 100 of 959 files, more files were not shown because too many files have changed in this diff. Show more