Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vtk threshold point #3081

Merged
merged 1 commit into from
Jan 2, 2025
Merged
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
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
Loading