Skip to content

Commit

Permalink
feat(thresholdpoints): add vtkThresholdPoints filter
Browse files Browse the repository at this point in the history
This filter can threshold points with PointData criteria or point coordinates.
  • Loading branch information
finetjul authored and floryst committed Jan 2, 2025
1 parent 3c562c5 commit 8f40fc7
Show file tree
Hide file tree
Showing 6 changed files with 530 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Documentation/content/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ This will allow you to see the some live code running in your browser. Just pick
[![TubeFilter Example][TubeFilter]](./TubeFilter.html "TubeFilter")
[![Cutter Example][Cutter]](./Cutter.html "Cutter")
[![PolyDataNormals Example][PolyDataNormals]](./PolyDataNormals.html "PolyDataNormals")
[![ThresholdPoints Example][ThresholdPoints]](./ThresholdPoints.html "Cut/Treshold points with point data criteria")


</div>

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

# Sources

Expand Down
28 changes: 28 additions & 0 deletions Sources/Filters/Core/ThresholdPoints/example/controlPanel.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<table>
<tr>
<td>Arrays to threshold</td>
<td>
<select id="thresholdArray">
<option value="sine wave">sine wave</option>
<option value="x">x</option>
<option value="y">y</option>
<option value="z">z</option>
</select>
</td>
</tr>
<tr>
<td>Operation</td>
<td>
<select id="thresholdOperation">
<option value="Above">&lt;</option>
<option value="Below">&gt;</option>
</select>
</td>
</tr>
<tr>
<td>Treshold value</td>
<td>
<input id="thresholdValue" type="number" step="10" value="30" />
</td>
</tr>
</table>
176 changes: 176 additions & 0 deletions Sources/Filters/Core/ThresholdPoints/example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import '@kitware/vtk.js/favicon';

// Load the rendering pieces we want to use (for both WebGL and WebGPU)
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
import '@kitware/vtk.js/Rendering/Profiles/Glyph';

import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
import '@kitware/vtk.js/IO/Core/DataAccessHelper/HttpDataAccessHelper';

import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkHttpDataSetReader from '@kitware/vtk.js/IO/Core/HttpDataSetReader';
import vtkLookupTable from '@kitware/vtk.js/Common/Core/LookupTable';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
import vtkThresholdPoints from '@kitware/vtk.js/Filters/Core/ThresholdPoints';
import vtkCalculator from '@kitware/vtk.js/Filters/General/Calculator';
import { FieldDataTypes } from '@kitware/vtk.js/Common/DataModel/DataSet/Constants';
import { AttributeTypes } from '@kitware/vtk.js/Common/DataModel/DataSetAttributes/Constants';
import vtkScalarBarActor from '@kitware/vtk.js/Rendering/Core/ScalarBarActor';

import controlPanel from './controlPanel.html';

const { ColorMode, ScalarMode } = vtkMapper;

// ----------------------------------------------------------------------------
// Standard rendering code setup
// ----------------------------------------------------------------------------

const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
background: [0.9, 0.9, 0.9],
});
fullScreenRenderer.addController(controlPanel);

const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();

// ----------------------------------------------------------------------------
// Example code
// ----------------------------------------------------------------------------

const lookupTable = vtkLookupTable.newInstance({ hueRange: [0.666, 0] });

const reader = vtkHttpDataSetReader.newInstance({ fetchGzip: true });
reader.setUrl(`${__BASE_PATH__}/data/cow.vtp`).then(() => {
reader.loadData().then(() => {
renderer.resetCamera();
renderWindow.render();
});
});

const calc = vtkCalculator.newInstance();
calc.setInputConnection(reader.getOutputPort());
calc.setFormula({
getArrays: (inputDataSets) => ({
input: [{ location: FieldDataTypes.COORDINATE }], // Require point coordinates as input
output: [
// Generate two output arrays:
{
location: FieldDataTypes.POINT, // This array will be point-data ...
name: 'sine wave', // ... with the given name ...
dataType: 'Float64Array', // ... of this type ...
attribute: AttributeTypes.SCALARS, // ... and will be marked as the default scalars.
},
{
location: FieldDataTypes.UNIFORM, // This array will be field data ...
name: 'global', // ... with the given name ...
dataType: 'Float32Array', // ... of this type ...
numberOfComponents: 1, // ... with this many components ...
tuples: 1, // ... and this many tuples.
},
],
}),
evaluate: (arraysIn, arraysOut) => {
// Convert in the input arrays of vtkDataArrays into variables
// referencing the underlying JavaScript typed-data arrays:
const [coords] = arraysIn.map((d) => d.getData());
const [sine, glob] = arraysOut.map((d) => d.getData());

// Since we are passed coords as a 3-component array,
// loop over all the points and compute the point-data output:
for (let i = 0, sz = coords.length / 3; i < sz; ++i) {
const dx = coords[3 * i] - 0.5;
const dy = coords[3 * i + 1] - 0.5;
sine[i] = 10 * dx * dx + dy * dy;
}
// Use JavaScript's reduce method to sum the output
// point-data array and set the uniform array's value:
glob[0] = sine.reduce((result, value) => result + value, 0);
// Mark the output vtkDataArray as modified
arraysOut.forEach((x) => x.modified());
},
});

const mapper = vtkMapper.newInstance({
interpolateScalarsBeforeMapping: true,
colorMode: ColorMode.DEFAULT,
scalarMode: ScalarMode.DEFAULT,
useLookupTableScalarRange: true,
lookupTable,
});
const actor = vtkActor.newInstance();
actor.getProperty().setEdgeVisibility(true);

const scalarBarActor = vtkScalarBarActor.newInstance();
scalarBarActor.setScalarsToColors(lookupTable);
renderer.addActor(scalarBarActor);

const thresholder = vtkThresholdPoints.newInstance();
thresholder.setInputConnection(calc.getOutputPort());

mapper.setInputConnection(thresholder.getOutputPort());
actor.setMapper(mapper);
renderer.addActor(actor);

// ----------------------------------------------------------------------------
// UI control handling
// ----------------------------------------------------------------------------

const thresholdArray = document.querySelector('#thresholdArray');
const thresholdOperation = document.querySelector('#thresholdOperation');
const thresholdValue = document.querySelector('#thresholdValue');
function updateCriterias(arrayName, operation, value) {
thresholder.setCriterias([
{
arrayName,
fieldAssociation: arrayName === 'sine wave' ? 'PointData' : 'Points',
operation,
value: Number(value),
},
]);
}
function onCriteriaChanged(event) {
updateCriterias(
thresholdArray.value,
thresholdOperation.value,
thresholdValue.value
);
if (event != null) {
renderWindow.render();
}
}
onCriteriaChanged();
function onArrayChanged(event) {
if (thresholdArray.value === 'x' || thresholdArray.value === 'y') {
thresholdValue.min = '-5';
thresholdValue.max = '5';
thresholdValue.step = '1';
thresholdValue.value = '0';
} else if (thresholdArray.value === 'z') {
thresholdValue.min = '-2';
thresholdValue.max = '2';
thresholdValue.step = '0.1';
thresholdValue.value = '0';
} else {
thresholdValue.min = 0;
thresholdValue.max = 256;
thresholdValue.step = 10;
thresholdValue.value = 30;
}
onCriteriaChanged(event);
}
thresholdArray.addEventListener('change', onArrayChanged);
thresholdOperation.addEventListener('change', onCriteriaChanged);
thresholdValue.addEventListener('input', onCriteriaChanged);

// -----------------------------------------------------------
// Make some variables global so that you can inspect and
// modify objects in your browser's developer console:
// -----------------------------------------------------------

global.mapper = mapper;
global.actor = actor;
global.source = reader;
global.renderer = renderer;
global.renderWindow = renderWindow;
global.lookupTable = lookupTable;
global.thresholder = thresholder;
72 changes: 72 additions & 0 deletions Sources/Filters/Core/ThresholdPoints/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { vtkAlgorithm, vtkObject } from '../../../interfaces';

export interface ThresholdCriteria {
arrayName: string;
fieldAssociation: string;
operation: string;
value: number;
}

/**
*
*/
export interface IThresholdPointsInitialValues {
criterias?: ThresholdCriteria[];
}

type vtkThresholdPointsBase = vtkObject & vtkAlgorithm;

export interface vtkThresholdPoints extends vtkThresholdPointsBase {
/**
* Get the desired precision for the output types.
*/
getCriterias(): ThresholdCriteria[];

/**
* Set the desired precision for the output types.
* @param outputPointsPrecision
*/
setCriterias(criterias: ThresholdCriteria[]): boolean;

/**
*
* @param inData
* @param outData
*/
requestData(inData: any, outData: any): void;
}

/**
* Method used to decorate a given object (publicAPI+model) with vtkThresholdPoints characteristics.
*
* @param publicAPI object on which methods will be bounds (public)
* @param model object on which data structure will be bounds (protected)
* @param {IThresholdPointsInitialValues} [initialValues] (default: {})
*/
export function extend(
publicAPI: object,
model: object,
initialValues?: IThresholdPointsInitialValues
): void;

/**
* Method used to create a new instance of vtkThresholdPoints
* @param {IThresholdPointsInitialValues} [initialValues] for pre-setting some of its content
*/
export function newInstance(
initialValues?: IThresholdPointsInitialValues
): vtkThresholdPoints;

/**
* vtkThresholdPoints - extracts points whose scalar value satisfies threshold criterion
*
* vtkThresholdPoints is a filter that extracts points from a dataset that
* satisfy a threshold criterion. The criterion can take three forms:
* 1) greater than a particular value; 2) less than a particular value; or
* 3) between a particular value. The output of the filter is polygonal data.
*/
export declare const vtkThresholdPoints: {
newInstance: typeof newInstance;
extend: typeof extend;
};
export default vtkThresholdPoints;
Loading

0 comments on commit 8f40fc7

Please sign in to comment.