@kitware/vtk.js
Version:
Visualization Toolkit for the Web
148 lines (129 loc) • 5.48 kB
JavaScript
import { m as macro } from '../../macros2.js';
import vtkImageData from '../../Common/DataModel/ImageData.js';
import vtkDataArray from '../../Common/Core/DataArray.js';
// ----------------------------------------------------------------------------
// Global methods
// ----------------------------------------------------------------------------
function generateCoordinates(origin, dimensions, spacing) {
const coordinates = new Float64Array(dimensions[0] * dimensions[1] * dimensions[2] * 3);
let offset = 0;
for (let k = 0; k < dimensions[2]; k++) {
const z = origin[2] + spacing[2] * k;
for (let j = 0; j < dimensions[1]; j++) {
const y = origin[1] + spacing[1] * j;
for (let i = 0; i < dimensions[0]; i++) {
const x = origin[0] + spacing[0] * i;
coordinates[offset++] = x;
coordinates[offset++] = y;
coordinates[offset++] = z;
}
}
}
return coordinates;
}
// ----------------------------------------------------------------------------
// vtkSLICSource methods
// ----------------------------------------------------------------------------
function vtkSLICSource(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkSLICSource');
publicAPI.addCluster = (centerX, centerY, centerZ, fnConst, fnDfDx, fnDfDy, fnDfDz) => {
const id = model.clusters.length;
model.clusters.push(new Float64Array([centerX, centerY, centerZ, fnConst, fnDfDx, fnDfDy, fnDfDz]));
publicAPI.modified();
return id;
};
publicAPI.removeCluster = id => {
model.clusters.splice(id, 1);
publicAPI.modified();
};
publicAPI.removeAllClusters = () => {
model.clusters = [];
publicAPI.modified();
};
publicAPI.updateCluster = (id, centerX, centerY, centerZ, fnConst, fnDfDx, fnDfDy, fnDfDz) => {
if (!model.clusters[id]) {
model.clusters[id] = new Float64Array(7);
}
model.clusters[id][0] = centerX;
model.clusters[id][1] = centerY;
model.clusters[id][2] = centerZ;
model.clusters[id][3] = fnConst;
model.clusters[id][4] = fnDfDx;
model.clusters[id][5] = fnDfDy;
model.clusters[id][6] = fnDfDz;
publicAPI.modified();
};
publicAPI.getNumberOfClusters = () => model.clusters.length;
publicAPI.requestData = (inData, outData) => {
const dataSize = model.dimensions[0] * model.dimensions[1] * model.dimensions[2];
const imageData = outData[0]?.initialize() || vtkImageData.newInstance();
imageData.setSpacing(...model.spacing);
imageData.setExtent(0, model.dimensions[0] - 1, 0, model.dimensions[1] - 1, 0, model.dimensions[2] - 1);
imageData.setOrigin(...model.origin);
// Pixel centers
const centers = generateCoordinates(model.origin, model.dimensions, model.spacing);
// Fill clusterIdxValues
const nbBytes = (model.clusters.length < 256 ? 8 : 0) || (model.clusters.length < 65536 ? 16 : 32);
const clusterIdxValues = macro.newTypedArray(`Uint${nbBytes}Array`, dataSize);
for (let i = 0; i < dataSize; i++) {
let clusterDistance = Number.MAX_VALUE;
model.clusters.forEach((cluster, idx) => {
const dist = (cluster[0] - centers[i * 3]) * (cluster[0] - centers[i * 3]) + (cluster[1] - centers[i * 3 + 1]) * (cluster[1] - centers[i * 3 + 1]) + (cluster[2] - centers[i * 3 + 2]) * (cluster[2] - centers[i * 3 + 2]);
if (dist < clusterDistance) {
clusterDistance = dist;
clusterIdxValues[i] = idx;
}
});
}
const clusters = vtkDataArray.newInstance({
name: model.clusterArrayName,
numberOfComponents: 1,
values: clusterIdxValues
});
imageData.getPointData().addArray(clusters);
// Fill scalarValues
const scalarValues = new Float32Array(dataSize);
for (let i = 0; i < dataSize; i++) {
const cluster = model.clusters[clusterIdxValues[i]];
scalarValues[i] = cluster[3] + cluster[4] * (centers[i * 3 + 0] - cluster[0]) + cluster[5] * (centers[i * 3 + 1] - cluster[1]) + cluster[6] * (centers[i * 3 + 2] - cluster[2]);
}
const scalars = vtkDataArray.newInstance({
name: model.scalarArrayName,
numberOfComponents: 1,
values: scalarValues
});
imageData.getPointData().addArray(scalars);
// Update output
outData[0] = imageData;
};
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
clusters: [],
spacing: [1.0, 1.0, 1.0],
origin: [0.0, 0.0, 0.0],
dimensions: [10, 10, 10],
clusterArrayName: 'cluster',
scalarArrayName: 'field'
};
// ----------------------------------------------------------------------------
function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
// Build VTK API
macro.obj(publicAPI, model);
macro.setGet(publicAPI, model, ['clusterArrayName', 'scalarArrayName']);
macro.setGetArray(publicAPI, model, ['origin', 'spacing', 'dimensions'], 3);
macro.algo(publicAPI, model, 0, 1);
vtkSLICSource(publicAPI, model);
}
// ----------------------------------------------------------------------------
const newInstance = macro.newInstance(extend, 'vtkSLICSource');
// ----------------------------------------------------------------------------
var vtkSLICSource$1 = {
newInstance,
extend
};
export { vtkSLICSource$1 as default, extend, newInstance };