8000 feat(thresholdpoints): add vtkThresholdPoints filter · Kitware/vtk-js@8f40fc7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8f40fc7

Browse files
finetjulfloryst
authored andcommitted
feat(thresholdpoints): add vtkThresholdPoints filter
This filter can threshold points with PointData criteria or point coordinates.
1 parent 3c562c5 commit 8f40fc7

File tree

6 files changed

+530
-0
lines changed

6 files changed

+530
-0
lines changed
Loading

Documentation/content/examples/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ This will allow you to see the some live code running in your browser. Just pick
107107
[![TubeFilter Example][TubeFilter]](./TubeFilter.html "TubeFilter")
108108
[![Cutter Example][Cutter]](./Cutter.html "Cutter")
109109
[![PolyDataNormals Example][PolyDataNormals]](./PolyDataNormals.html "PolyDataNormals")
110+
[![ThresholdPoints Example][ThresholdPoints]](./ThresholdPoints.html "Cut/Treshold points with point data criteria")
111+
110112

111113
</div>
112114

@@ -125,6 +127,7 @@ This will allow you to see the some live code running in your browser. Just pick
125127
[TubeFilter]: ../docs/gallery/TubeFilter.jpg
126128
[Cutter]: ../docs/gallery/Cutter.jpg
127129
[PolyDataNormals]: ../docs/gallery/PolyDataNormals.jpg
130+
[ThresholdPoints]: ../docs/gallery/ThresholdPoints.jpg
128131

129132
# Sources
130133

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<table>
2+
<tr>
3+
<td>Arrays to threshold</td>
4+
<td>
5+
<select id="thresholdArray">
6+
<option value="sine wave">sine wave</option>
7+
<option value="x">x</option>
8+
<option value="y">y</option>
9+
<option value="z">z</option>
10+
</select>
11+
</td>
12+
</tr>
13+
<tr>
14+
<td>Operation</td>
15+
<td>
16+
<select id="thresholdOperation">
17+
<option value="Above">&lt;</option>
18+
<option value="Below">&gt;</option>
19+
</select>
20+
</td>
21+
</tr>
22+
<tr>
23+
<td>Treshold value</td>
24+
<td>
25+
<input id="thresholdValue" type="number" step="10" value="30" />
26+
</td>
27+
</tr>
28+
</table>
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import '@kitware/vtk.js/favicon';
2+
3+
// Load the rendering pieces we want to use (for both WebGL and WebGPU)
4+
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
5+
import '@kitware/vtk.js/Rendering/Profiles/Glyph';
6+
7+
import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
8+
import '@kitware/vtk.js/IO/Core/DataAccessHelper/HttpDataAccessHelper';
9+
10+
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
11+
import vtkHttpDataSetReader from '@kitware/vtk.js/IO/Core/HttpDataSetReader';
12+
import vtkLookupTable from '@kitware/vtk.js/Common/Core/LookupTable';
13+
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
14+
import vtkThresholdPoints from '@kitware/vtk.js/Filters/Core/ThresholdPoints';
15+
import vtkCalculator from '@kitware/vtk.js/Filters/General/Calculator';
16+
import { FieldDataTypes } from '@kitware/vtk.js/Common/DataModel/DataSet/Constants';
17+
import { AttributeTypes } from '@kitware/vtk.js/Common/DataModel/DataSetAttributes/Constants';
18+
import vtkScalarBarActor from '@kitware/vtk.js/Rendering/Core/ScalarBarActor';
19+
20+
import controlPanel from './controlPanel.html';
21+
22+
const { ColorMode, ScalarMode } = vtkMapper;
23+
24+
// ----------------------------------------------------------------------------
25+
// Standard rendering code setup
26+
// ---- F438 ------------------------------------------------------------------------
27+
28+
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
29+
background: [0.9, 0.9, 0.9],
30+
});
31+
fullScreenRenderer.addController(controlPanel);
32+
33+
const renderer = fullScreenRenderer.getRenderer();
34+
const renderWindow = fullScreenRenderer.getRenderWindow();
35+
36+
// ----------------------------------------------------------------------------
37+
// Example code
38+
// ----------------------------------------------------------------------------
39+
40+
const lookupTable = vtkLookupTable.newInstance({ hueRange: [0.666, 0] });
41+
42+
const reader = vtkHttpDataSetReader.newInstance({ fetchGzip: true });
43+
reader.setUrl(`${__BASE_PATH__}/data/cow.vtp`).then(() => {
44+
reader.loadData().then(() => {
45+
renderer.resetCamera();
46+
renderWindow.render();
47+
});
48+
});
49+
50+
const calc = vtkCalculator.newInstance();
51+
calc.setInputConnection(reader.getOutputPort());
52+
calc.setFormula({
53+
getArrays: (inputDataSets) => ({
54+
input: [{ location: FieldDataTypes.COORDINATE }], // Require point coordinates as input
55+
output: [
56+
// Generate two output arrays:
57+
{
58+
location: FieldDataTypes.POINT, // This array will be point-data ...
59+
name: 'sine wave', // ... with the given name ...
60+
dataType: 'Float64Array', // ... of this type ...
61+
attribute: AttributeTypes.SCALARS, // ... and will be marked as the default scalars.
62+
},
63+
{
64+
location: FieldDataTypes.UNIFORM, // This array will be field data ...
65+
name: 'global', // ... with the given name ...
66+
dataType: 'Float32Array', // ... of this type ...
67+
numberOfComponents: 1, // ... with this many components ...
68+
tuples: 1, // ... and this many tuples.
69+
},
70+
],
71+
}),
72+
evaluate: (arraysIn, arraysOut) => {
73+
// Convert in the input arrays of vtkDataArrays into variables
74+
// referencing the underlying JavaScript typed-data arrays:
75+
const [coords] = arraysIn.map((d) => d.getData());
76+
const [sine, glob] = arraysOut.map((d) => d.getData());
77+
78+
// Since we are passed coords as a 3-component array,
79+
// loop over all the points and compute the point-data output:
80+
for (let i = 0, sz = coords.length / 3; i < sz; ++i) {
81+
const dx = coords[3 * i] - 0.5;
82+
const dy = coords[3 * i + 1] - 0.5;
83+
sine[i] = 10 * dx * dx + dy * dy;
84+
}
85+
// Use JavaScript's reduce method to sum the output
86+
// point-data array and set the uniform array's value:
87+
glob[0] = sine.reduce((result, value) => result + value, 0);
88+
// Mark the output vtkDataArray as modified
89+
arraysOut.forEach((x) => x.modified());
90+
},
91+
});
92+
93+
const mapper = vtkMapper.newInstance({
94+
interpolateScalarsBeforeMapping: true,
95+
colorMode: ColorMode.DEFAULT,
96+
scalarMode: ScalarMode.DEFAULT,
97+
useLookupTableScalarRange: true,
98+
lookupTable,
99+
});
100+
const actor = vtkActor.newInstance();
101+
actor.getProperty().setEdgeVisibility(true);
102+
103+
const scalarBarActor = vtkScalarBarActor.newInstance();
104+
scalarBarActor.setScalarsToColors(lookupTable);
105+
renderer.addActor(scalarBarActor);
106+
107+
const thresholder = vtkThresholdPoints.newInstance();
108+
thresholder.setInputConnection(calc.getOutputPort());
109+
110+
mapper.setInputConnection(thresholder.getOutputPort());
111+
actor.setMapper(mapper);
112+
renderer.addActor(actor);
113+
114+
// ----------------------------------------------------------------------------
115+
// UI control handling
116+
// ----------------------------------------------------------------------------
117+
118+
const thresholdArray = document.querySelector('#thresholdArray');
119+
const thresholdOperation = document.querySelector('#thresholdOperation');
120+
const thresholdValue = document.querySelector('#thresholdValue');
121+
function updateCriterias(arrayName, operation, value) {
122+
thresholder.setCriterias([
123+
{
124+
arrayName,
125+
fieldAssociation: arrayName === 'sine wave' ? 'PointData' : 'Points',
126+
operation,
127+
value: Number(value),
128+
},
129+
]);
130+
}
131+
function onCriteriaChanged(event) {
132+
updateCriterias(
133+
thresholdArray.value,
134+
thresholdOperation.value,
135+
thresholdValue.value
136+
);
137+
if (event != null) {
138+
renderWindow.render();
139+
}
140+
}
141+
onCriteriaChanged();
142+
function onArrayChanged(event) {
143+
if (thresholdArray.value === 'x' || thresholdArray.value === 'y') {
144+
thresholdValue.min = '-5';
145+
thresholdValue.max = '5';
146+
thresholdValue.step = '1';
147+
thresholdValue.value = '0';
148+
} else if (thresholdArray.value === 'z') {
149+
thresholdValue.min = '-2';
150+
thresholdValue.max = '2';
151+
thresholdValue.step = '0.1';
152+
thresholdValue.value = '0';
153+
} else {
154+
thresholdValue.min = 0;
155+
thresholdValue.max = 256;
156+
thresholdValue.step = 10;
157+
thresholdValue.value = 30;
158+
}
159+
onCriteriaChanged(event);
160+
}
161+
thresholdArray.addEventListener('change', onArrayChanged);
162+
thresholdOperation.addEventListener('change', onCriteriaChanged);
163+
thresholdValue.addEventListener('input', onCriteriaChanged);
164+
165+
// -----------------------------------------------------------
166+
// Make some variables global so that you can inspect and
167+
// modify objects in your browser's developer console:
168+
// -----------------------------------------------------------
169+
170+
global.mapper = mapper;
171+
global.actor = actor;
172+
global.source = reader;
173+
global.renderer = renderer;
174+
global.renderWindow = renderWindow;
175+
global.lookupTable = lookupTable;
176+
global.thresholder = thresholder;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { vtkAlgorithm, vtkObject } from '../../../interfaces';
2+
3+
export interface ThresholdCriteria {
4+
arrayName: string;
5+
fieldAssociation: string;
6+
operation: string;
7+
value: number;
8+
}
9+
10+
/**
11+
*
12+
*/
13+
export interface IThresholdPointsInitialValues {
14+
criterias?: ThresholdCriteria[];
15< F438 span class="diff-text-marker">+
}
16+
17+
type vtkThresholdPointsBase = vtkObject & vtkAlgorithm;
18+
19+
export interface vtkThresholdPoints extends vtkThresholdPointsBase {
20+
/**
21+
* Get the desired precision for the output types.
22+
*/
23+
getCriterias(): ThresholdCriteria[];
24+
25+
/**
26+
* Set the desired precision for the output types.
27+
* @param outputPointsPrecision
28+
*/
29+
setCriterias(criterias: ThresholdCriteria[]): boolean;
30+
31+
/**
32+
*
33+
* @param inData
34+
* @param outData
35+
*/
36+
requestData(inData: any, outData: any): void;
37+
}
38+
39+
/**
40+
* Method used to decorate a given object (publicAPI+model) with vtkThresholdPoints characteristics.
41+
*
42+
* @param publicAPI object on which methods will be bounds (public)
43+
* @param model object on which data structure will be bounds (protected)
44+
* @param {IThresholdPointsInitialValues} [initialValues] (default: {})
45+
*/
46+
export function extend(
47+
publicAPI: object,
48+
model: object,
49+
initialValues?: IThresholdPointsInitialValues
50+
): void;
51+
52+
/**
53+
* Method used to create a new instance of vtkThresholdPoints
54+
* @param {IThresholdPointsInitialValues} [initialValues] for pre-setting some of its content
55+
*/
56+
export function newInstance(
57+
initialValues?: IThresholdPointsInitialValues
58+
): vtkThresholdPoints;
59+
60+
/**
61+
* vtkThresholdPoints - extracts points whose scalar value satisfies threshold criterion
62+
*
63+
* vtkThresholdPoints is a filter that extracts points from a dataset that
64+
* satisfy a threshold criterion. The criterion can take three forms:
65+
* 1) greater than a particular value; 2) less than a particular value; or
66+
* 3) between a particular value. The output of the filter is polygonal data.
67+
*/
68+
export declare const vtkThresholdPoints: {
69+
newInstance: typeof newInstance;
70+
extend: typeof extend;
71+
};
72+
export default vtkThresholdPoints;

0 commit comments

Comments
 (0)
0