Skip to content

Commit 7ba1a01

Browse files
committed
docs(ShapeWidget): Fix computeHistogram usage
The ShapeWidget example demos computeHistogram results. However this does not work when the slice is in arbitrary plane. Relying on implicit functions to precisely compute histogram fixes the issue.
1 parent e48197e commit 7ba1a01

File tree

16 files changed

+246
-74
lines changed

16 files changed

+246
-74
lines changed

Sources/Common/DataModel/Box/index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { vtkObject } from '../../../interfaces';
22
import { Bounds, Vector3 } from '../../../types';
3+
import vtkImplicitFunction from '../ImplicitFunction';
34

45
export interface IBoxInitialValues {
56
bbox?: Bounds;
@@ -12,7 +13,7 @@ export interface IBoxIntersections {
1213
x2: Vector3;
1314
}
1415

15-
export interface vtkBox extends vtkObject {
16+
export interface vtkBox extends vtkImplicitFunction {
1617
/**
1718
* Add the bounds for the box.
1819
* @param {Bounds} bounds

Sources/Common/DataModel/Box/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import macro from 'vtk.js/Sources/macros';
22
import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox';
3+
import vtkImplicitFunction from 'vtk.js/Sources/Common/DataModel/ImplicitFunction';
34

45
// ----------------------------------------------------------------------------
56
// Global methods
@@ -209,7 +210,7 @@ export function extend(publicAPI, model, initialValues = {}) {
209210
Object.assign(model, DEFAULT_VALUES, initialValues);
210211

211212
// Object methods
212-
macro.obj(publicAPI, model);
213+
vtkImplicitFunction.extend(publicAPI, model, initialValues);
213214

214215
vtkBox(publicAPI, model);
215216
}

Sources/Common/DataModel/Cone/index.d.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export interface vtkCone extends vtkObject {
1313
* Given the point x evaluate the cone equation.
1414
* @param {Vector3} x The point coordinate.
1515
*/
16-
evaluateFunction(x: Vector3): number[];
16+
evaluateFunction(x: Vector3): number;
1717

1818
/**
1919
* Given the point x evaluate the equation for the cone gradient.
@@ -54,11 +54,7 @@ export function newInstance(initialValues?: IConeInitialValues): vtkCone;
5454

5555
/**
5656
* vtkCone computes the implicit function and/or gradient for a cone. vtkCone is
57-
* a concrete implementation of vtkImplicitFunction. TODO: Currently the cone's
58-
* axis of rotation is along the x-axis with the apex at the origin. To
59-
* transform this to a different location requires the application of a
60-
* transformation matrix. This can be performed by supporting transforms at the
61-
* implicit function level, and should be added.
57+
* a concrete implementation of vtkImplicitFunction.
6258
*/
6359
export declare const vtkCone: {
6460
newInstance: typeof newInstance;

Sources/Common/DataModel/Cone/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import macro from 'vtk.js/Sources/macros';
22
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
3+
import vtkImplicitFunction from 'vtk.js/Sources/Common/DataModel/ImplicitFunction';
34

45
// ----------------------------------------------------------------------------
56
// Global methods
@@ -45,7 +46,7 @@ export function extend(publicAPI, model, initialValues = {}) {
4546
Object.assign(model, DEFAULT_VALUES, initialValues);
4647

4748
// Object methods
48-
macro.obj(publicAPI, model);
49+
vtkImplicitFunction.extend(publicAPI, model, initialValues);
4950
macro.setGet(publicAPI, model, ['angle']);
5051

5152
vtkCone(publicAPI, model);

Sources/Common/DataModel/Cylinder/index.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { vtkObject } from '../../../interfaces';
22
import { Vector3 } from '../../../types';
3+
import vtkImplicitFunction from '../ImplicitFunction';
34

45
/**
56
*
@@ -10,13 +11,13 @@ export interface ICylinderInitialValues {
1011
axis?: number[];
1112
}
1213

13-
export interface vtkCylinder extends vtkObject {
14+
export interface vtkCylinder extends vtkImplicitFunction {
1415
/**
1516
* Given the point xyz (three floating value) evaluate the cylinder
1617
* equation.
1718
* @param {Vector3} xyz The point coordinate.
1819
*/
19-
evaluateFunction(xyz: Vector3): number[];
20+
evaluateFunction(xyz: Vector3): number;
2021

2122
/**
2223
* Given the point xyz (three floating values) evaluate the equation for the

Sources/Common/DataModel/Cylinder/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import macro from 'vtk.js/Sources/macros';
22
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
3+
import vtkImplicitFunction from 'vtk.js/Sources/Common/DataModel/ImplicitFunction';
34

45
// ----------------------------------------------------------------------------
56
// Global methods
@@ -85,7 +86,7 @@ export function extend(publicAPI, model, initialValues = {}) {
8586
Object.assign(model, DEFAULT_VALUES, initialValues);
8687

8788
// Object methods
88-
macro.obj(publicAPI, model);
89+
vtkImplicitFunction.extend(publicAPI, model, initialValues);
8990
macro.setGet(publicAPI, model, ['radius']);
9091
macro.setGetArray(publicAPI, model, ['center', 'axis'], 3);
9192

Sources/Common/DataModel/ImageData/index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export interface vtkImageData extends vtkDataSet {
2727
* `voxelFunc(index, bounds)` is an optional function that is called with
2828
* the `[i,j,k]` index and index `bounds`, expected to return truthy if the
2929
* data point should be counted in the histogram, and falsey if not.
30-
* @param {Bounds} worldBounds The bounds of the world.
3130
* @param [voxelFunc]
3231
*/
3332
computeHistogram(worldBounds: Bounds, voxelFunc?: any): IComputeHistogram;

Sources/Common/DataModel/ImageData/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ function vtkImageData(publicAPI, model) {
237237

238238
publicAPI.getCenter = () => vtkBoundingBox.getCenter(publicAPI.getBounds());
239239

240-
publicAPI.computeHistogram = (worldBounds, voxelFunc = null) => {
240+
publicAPI.computeHistogram = (worldBounds, voxelFunction = null) => {
241241
const bounds = [0, 0, 0, 0, 0, 0];
242242
publicAPI.worldToIndexBounds(worldBounds, bounds);
243243

@@ -278,7 +278,7 @@ function vtkImageData(publicAPI, model) {
278278
for (let y = point1[1]; y <= point2[1]; y++) {
279279
let index = point1[0] + y * yStride + z * zStride;
280280
for (let x = point1[0]; x <= point2[0]; x++) {
281-
if (!voxelFunc || voxelFunc([x, y, z], bounds)) {
281+
if (!voxelFunction || voxelFunction([x, y, z], bounds)) {
282282
const pixel = pixels[index];
283283

284284
if (pixel > maximum) maximum = pixel;

Sources/Common/DataModel/ImplicitBoolean/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import macro from 'vtk.js/Sources/macros';
22
import Constants from 'vtk.js/Sources/Common/DataModel/ImplicitBoolean/Constants';
3+
import vtkImplicitFunction from 'vtk.js/Sources/Common/DataModel/ImplicitFunction';
34

45
const { Operation } = Constants;
56

@@ -71,7 +72,7 @@ function vtkImplicitBoolean(publicAPI, model) {
7172
value = Number.MAX_VALUE;
7273
for (let i = 0; i < model.functions.length; ++i) {
7374
const f = model.functions[i];
74-
const v = f.evaluateFunction(xyz);
75+
const v = f.functionValue(xyz);
7576
if (v < value) {
7677
value = v;
7778
}
@@ -80,14 +81,14 @@ function vtkImplicitBoolean(publicAPI, model) {
8081
value = -Number.MAX_VALUE;
8182
for (let i = 0; i < model.functions.length; ++i) {
8283
const f = model.functions[i];
83-
const v = f.evaluateFunction(xyz);
84+
const v = f.functionValue(xyz);
8485
if (v > value) {
8586
value = v;
8687
}
8788
}
8889
} else {
8990
const firstF = model.functions[0];
90-
value = firstF.evaluateFunction(xyz);
91+
value = firstF.functionValue(xyz);
9192
for (let i = 1; i < model.functions.length; ++i) {
9293
const f = model.functions[i];
9394
const v = -1.0 * f.evaluateFunction(xyz);
@@ -133,7 +134,7 @@ export function extend(publicAPI, model, initialValues = {}) {
133134
Object.assign(model, DEFAULT_VALUES, initialValues);
134135

135136
// Object methods
136-
macro.obj(publicAPI, model);
137+
vtkImplicitFunction.extend(publicAPI, model, initialValues);
137138

138139
macro.setGet(publicAPI, model, ['operation']);
139140

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { vtkObject } from '../../../interfaces';
2+
import { Vector3 } from '../../../types';
3+
import { vtkTransform } from '../../Transform/Transform';
4+
5+
/**
6+
*
7+
*/
8+
export interface IImplicitFunctionInitialValues {
9+
transform?: vtkTransform;
10+
}
11+
12+
export interface vtkImplicitFunction extends vtkObject {
13+
/**
14+
* Given the point x evaluate the function.
15+
* @see functionValue
16+
* @param {Vector3} x The point coordinate.
17+
*/
18+
evaluateFunction(x: Vector3): number;
19+
20+
/**
21+
* Evaluate function at position x-y-z and return value. Point x[3] is
22+
* transformed through transform (if provided).
23+
* @see evaluateFunction
24+
* @param {Vector3} x The point coordinate.
25+
*/
26+
functionValue(x: Vector3): number;
27+
28+
/**
29+
* Get the transform. undefined by default
30+
*/
31+
getTransform(): vtkTransform;
32+
33+
/**
34+
* Set the transform to apply on all points.
35+
* @param {vtkTransform} transform The transform to apply
36+
*/
37+
setTransform(transform: vtkTransform): boolean;
38+
}
39+
40+
/**
41+
* Method used to decorate a given object (publicAPI+model) with vtkImplicitFunction characteristics.
42+
*
43+
* @param publicAPI object on which methods will be bounds (public)
44+
* @param model object on which data structure will be bounds (protected)
45+
* @param {IImplicitFunctionInitialValues} [initialValues] (default: {})
46+
*/
47+
export function extend(
48+
publicAPI: object,
49+
model: object,
50+
initialValues?: IImplicitFunctionInitialValues
51+
): void;
52+
53+
/**
54+
* Method used to create a new instance of vtkImplicitFunction.
55+
* @param {IImplicitFunctionInitialValues} [initialValues] for pre-setting some of its content
56+
*/
57+
export function newInstance(
58+
initialValues?: IImplicitFunctionInitialValues
59+
): vtkImplicitFunction;
60+
61+
/**
62+
* vtkImplicitFunction computes the implicit function and/or gradient for a function.
63+
*/
64+
export declare const vtkImplicitFunction: {
65+
newInstance: typeof newInstance;
66+
extend: typeof extend;
67+
};
68+
export default vtkImplicitFunction;

0 commit comments

Comments
 (0)