Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*


# AI assistant memory
memories/
32,184 changes: 21,807 additions & 10,377 deletions package-lock.json

Large diffs are not rendered by default.

128 changes: 56 additions & 72 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,101 +5,85 @@
"author": "Kitware Inc",
"license": "BSD-3-Clause",
"repository": "Kitware/react-vtk-js",
"type": "module",
"main": "dist/umd/react-vtk.js",
"module": "dist/esm/index.js",
"types": "dist/esm/src/index.d.ts",
"source": "src/index.ts",
"source": "src/index.js",
"exports": {
".": {
"import": "./dist/esm/index.js",
"browser": "./dist/cjs/react-vtk.js",
"umd": "./dist/umd/react-vtk.js",
"package.json": "./package.json",
"default": "./dist/esm/index.js"
},
"./light": {
"import": "./dist/esm/light.js",
"package.json": "./package.json",
"default": "./dist/esm/light.js"
}
},
"dependencies": {
"@babel/eslint-parser": "^7.19.1",
"@babel/runtime": "^7.19.0",
"deep-equal": "^2.0.5"
"@babel/runtime": "^7.12.5"
},
"scripts": {
"prebuild": "npm run test:lint",
"build": "rimraf dist && rollup -c",
"prebuild": "npm run fix",
"build": "rimraf dist && rollup ./src/index.ts -c",
"prepare": "npm run build",
"test": "npm run test:lint && npm run test:build && npm run test:unit",
"test": "npm run test:lint && npm run test:build",
"test:build": "npm run build",
"test:lint": "eslint src",
"test:unit": "vitest run",
"fix:prettier": "prettier --config .prettierrc --write \"src/**/*.tsx?\"",
"fix:prettier": "prettier --config .prettierrc --write \"src/**/*.{ts,tsx,jsx}\"",
"fix:eslint": "eslint --fix src",
"fix": "npm run fix:prettier && npm run fix:eslint",
"predeploy": "cd usage && npm install && npm run build",
"deploy": "gh-pages -d usage/dist -f -r $GIT_PUBLISH_URL",
"commit": "git cz",
"semantic-release": "semantic-release",
"dev": "rollup -c --watch"
"dev": "rollup ./src/index.js -c --watch"
},
"peerDependencies": {
"@kitware/vtk.js": "^35.15.2",
"react": "^18.2.0"
"@kitware/vtk.js": "^28.0.0",
"react": "^16.0.0"
},
"devDependencies": {
"@babel/plugin-transform-runtime": "^7.19.1",
"@babel/preset-env": "^7.19.1",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@kitware/vtk.js": "^35.15.2",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "24.0.1",
"@rollup/plugin-eslint": "^9.0.3",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-terser": "^1.0.0",
"@rollup/plugin-typescript": "^11.0.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^15.0.7",
"@types/deep-equal": "^1.0.1",
"@types/react": "^18.0.21",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
"commitizen": "^4.2.4",
"@babel/core": "^7.12.10",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"@kitware/vtk.js": "^28.0.0",
"@rollup/plugin-babel": "^5.2.2",
"@rollup/plugin-commonjs": "17.0.0",
"@rollup/plugin-eslint": "^8.0.1",
"@typescript-eslint/eslint-plugin": "^4.31.0",
"@typescript-eslint/parser": "^4.31.0",
"@rollup/plugin-node-resolve": "^11.1.0",
"babel-eslint": "^10.0.3",
"commitizen": "4.2.2",
"cross-env": "^7.0.2",
"eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0",
"eslint-config-standard": "^17.0.0",
"eslint-config-standard-react": "^13.0.0",
"eslint-plugin-import": "^2.27.5",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.7.0",
"eslint-config-standard": "^14.1.0",
"eslint-config-standard-react": "^9.2.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.0.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"gh-pages": "^5.0.0",
"jsdom": "^24.1.3",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-standard": "^4.0.1",
"gh-pages": "^2.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.4",
"prettier-plugin-organize-imports": "^3.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rimraf": "^4.1.2",
"rollup": "^3.17.2",
"prettier": "^2.0.4",
"prettier-plugin-organize-imports": "^3.2.4",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"rimraf": "^3.0.2",
"rollup": "^2.37.1",
"rollup-plugin-analyzer": "^4.0.0",
"semantic-release": "^25.0.3",
"typescript": "^4.9.5",
"vitest": "^4.1.6"
"rollup-plugin-terser": "^7.0.2",
"semantic-release": "17.3.1"
},
"files": [
"dist"
],
"release": {
"branches": [
"master"
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/npm",
{
"registry": "https://registry.npmjs.org/"
}
],
"@semantic-release/github"
]
},
"publishConfig": {
"access": "public"
}
]
}
148 changes: 148 additions & 0 deletions src/core/ResliceRepresentation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import vtkImageResliceMapper, {
vtkImageResliceMapper as IvtkImageResliceMapper,
} from '@kitware/vtk.js/Rendering/Core/ImageResliceMapper';
import { SlabTypes } from '@kitware/vtk.js/Rendering/Core/ImageResliceMapper/Constants';
import { forwardRef, PropsWithChildren, useRef } from 'react';
import useComparableEffect from '../utils/useComparableEffect';
import SliceRepresentation, {
SliceRepresentationProps,
} from './SliceRepresentation';

export interface ResliceRepresentationProps extends SliceRepresentationProps {
/**
* Slice plane
*/
slicePlane?: any;

/**
* Optional slice polydata
*/
slicePolyData?: any;

/**
* Slab type
*/
slabType?: number;

/**
* Slab thickness
*/
slabThickness?: number;

/**
* Slab trapezoid integration
*/
slabTrapezoidIntegration?: boolean;
}

export default forwardRef(function ResliceRepresentation(
props: PropsWithChildren<ResliceRepresentationProps>,
fwdRef
) {
const {
slicePlane,
slicePolyData,
slabType = SlabTypes.MEAN,
slabThickness = 0.0,
slabTrapezoidIntegration = false,
mapperInstance: providedMapper,
...sliceProps
} = props;

// Create reslice mapper once and reuse it across renders.
const internalMapperRef = useRef<IvtkImageResliceMapper | null>(null);
if (!internalMapperRef.current) {
internalMapperRef.current = vtkImageResliceMapper.newInstance();
}
const mapperInstance = (providedMapper ||
internalMapperRef.current) as IvtkImageResliceMapper;

// Handle reslice-specific mapper updates
useComparableEffect(
() => {
if (!providedMapper && mapperInstance) {
trackModified(true);
mapperInstance.setSlicePlane(slicePlane);
}
},
[slicePlane, providedMapper],
([cur, prevMapped], [prev, prevProvided]) =>
cur === prev && prevMapped === prevProvided
);

useComparableEffect(
() => {
if (!providedMapper && mapperInstance) {
trackModified(true);
mapperInstance.setSlicePolyData(slicePolyData);
}
},
[slicePolyData, providedMapper],
([cur, prevMapped], [prev, prevProvided]) =>
cur === prev && prevMapped === prevProvided
);

useComparableEffect(
() => {
if (!providedMapper && mapperInstance) {
trackModified(true);
if (
slabType != null &&
slabType >= SlabTypes.MIN &&
slabType <= SlabTypes.SUM
) {
mapperInstance.setSlabType(slabType);
}
}
},
[slabType, providedMapper],
([cur, prevMapped], [prev, prevProvided]) =>
cur === prev && prevMapped === prevProvided
);

useComparableEffect(
() => {
if (!providedMapper && mapperInstance) {
trackModified(true);
if (slabThickness != null) {
mapperInstance.setSlabThickness(slabThickness);
}
}
},
[slabThickness, providedMapper],
([cur, prevMapped], [prev, prevProvided]) =>
cur === prev && prevMapped === prevProvided
);

useComparableEffect(
() => {
if (!providedMapper && mapperInstance) {
trackModified(true);
if (slabTrapezoidIntegration != null) {
mapperInstance.setSlabTrapezoidIntegration(
slabTrapezoidIntegration ? 1 : 0
);
}
}
},
[slabTrapezoidIntegration, providedMapper],
([cur, prevMapped], [prev, prevProvided]) =>
cur === prev && prevMapped === prevProvided
);

function trackModified(changed: boolean) {
if (changed) {
// Trigger render
}
}

return (
<SliceRepresentation
{...sliceProps}
mapperInstance={mapperInstance as any}
ref={fwdRef}
>
{props.children}
</SliceRepresentation>
);
});
16 changes: 16 additions & 0 deletions src/core/ShareDataSet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,19 @@ export function RegisterDataSet(props: RegisterDataSetProps) {

// --- //

// Store the connection function so it can be evaluated lazily when
// dataAvailable fires (i.e. after the async data load completes).
const connRef = useRef<(() => unknown) | null>(null);

const downstream = useMemo<IDownstream>(
() => ({
setInputData(obj) {
share.register(id, obj);
},
setInputConnection(conn) {
// Persist the port function; don't evaluate it yet — the upstream
// algorithm may not have data until an async operation completes.
connRef.current = conn;
downstream.setInputData(conn());
},
}),
Expand All @@ -175,10 +182,14 @@ export function RegisterDataSet(props: RegisterDataSetProps) {
const mockRepresentation = useMemo<IRepresentation>(
() => ({
dataChanged() {
// Re-evaluate the connection to capture the latest output.
if (connRef.current) share.register(id, connRef.current());
share.dispatchDataChanged(id);
dataChangedEvent.current.dispatchEvent();
},
dataAvailable() {
// Re-evaluate the connection NOW, when the data is actually ready.
if (connRef.current) share.register(id, connRef.current());
share.dispatchDataAvailable(id);
dataAvailableEvent.current.dispatchEvent();
},
Expand Down Expand Up @@ -226,3 +237,8 @@ export function UseDataSet(props: UseDataSetProps) {

return null;
}

/**
* ShareDataSet is an alias for UseDataSet for backwards compatibility
*/
export const ShareDataSet = UseDataSet;
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ export { default as PolyData } from './core/PolyData';
export type { PolyDataProps } from './core/PolyData';
export { default as Reader } from './core/Reader';
export type { ReaderProps } from './core/Reader';
export { default as ResliceRepresentation } from './core/ResliceRepresentation';
export type { ResliceRepresentationProps } from './core/ResliceRepresentation';
export {
RegisterDataSet,
ShareDataSet,
ShareDataSetRoot,
UseDataSet,
} from './core/ShareDataSet';
Expand Down
Loading
Loading