@kitware/vtk.js
Version:
Visualization Toolkit for the Web
164 lines (157 loc) • 5.33 kB
JavaScript
import { m as macro } from '../../macros2.js';
import vtkPoints from '../../Common/Core/Points.js';
import vtkCellArray from '../../Common/Core/CellArray.js';
import vtkPolyData from '../../Common/DataModel/PolyData.js';
import Constants from './BFSConnectivityFilter/Constants.js';
const {
ExtractionMode
} = Constants;
function runBFS(polyData) {
if (!polyData.getLinks()) {
polyData.buildLinks();
}
const polys = polyData.getPolys().getData();
const numCells = polyData.getNumberOfCells();
const cellOffsets = new Uint32Array(numCells);
let offset = 0;
for (let i = 0; i < numCells; i++) {
cellOffsets[i] = offset;
const n = polys[offset];
offset += n + 1;
}
const visited = new Uint8Array(numCells);
const regions = [];
for (let i = 0; i < numCells; i++) {
if (!visited[i]) {
const component = [];
const queue = [i];
visited[i] = 1;
let head = 0;
while (head < queue.length) {
const cellId = queue[head++];
component.push(cellId);
const pts = polyData.getCellPoints(cellId).cellPointIds;
for (let j = 0; j < pts.length; j++) {
const neighborCells = polyData.getPointCells(pts[j]);
for (let k = 0; k < neighborCells.length; k++) {
const neighborId = neighborCells[k];
if (!visited[neighborId]) {
visited[neighborId] = 1;
queue.push(neighborId);
}
}
}
}
regions.push(new Uint32Array(component));
}
}
return {
regions,
cellOffsets
};
}
function vtkBFSConnectivityFilter(publicAPI, model) {
model.classHierarchy.push('vtkBFSConnectivityFilter');
publicAPI.requestData = (inData, outData) => {
const input = inData[0];
if (!input) {
return;
}
console.time(`BFSConnectivityFilter`);
const output = outData[0] || vtkPolyData.newInstance();
// 1. BFS
const {
regions,
cellOffsets
} = runBFS(input);
if (regions.length === 0) return;
// 2. sort regions
const sortRegions = regions.sort((a, b) => b.length - a.length);
model.regionsCount = sortRegions.length;
// 3. select region
let cells = null;
if (model.extractionMode === ExtractionMode.ExtractionMode_ALL) {
cells = sortRegions.flatMap(arr => Array.from(arr));
} else if (model.extractionMode === ExtractionMode.ExtractionMode_SMALLEST) {
cells = sortRegions[sortRegions.length - 1];
} else if (model.extractionMode === ExtractionMode.ExtractionMode_CUSTOM) {
if (model.extractionIndex >= 0 && model.extractionIndex < model.regionsCount) {
cells = sortRegions[model.extractionIndex];
}
} else {
// Largest
cells = sortRegions[0];
}
// 4. build ouput
const oldPolys = input.getPolys().getData();
const polyType = input.getPolys().getDataType();
const oldPoints = input.getPoints().getData();
const pointType = input.getPoints().getDataType();
const newPointsData = [];
const newPolysData = [];
const pointMap = new Map();
let pointCounter = 0;
for (let i = 0; i < cells.length; i++) {
const cellId = cells[i];
const offset = cellOffsets[cellId];
const n = oldPolys[offset];
newPolysData.push(n);
for (let j = 0; j < n; j++) {
const oldPtId = oldPolys[offset + 1 + j];
if (!pointMap.has(oldPtId)) {
pointMap.set(oldPtId, pointCounter);
const pIdx = oldPtId * 3;
newPointsData.push(oldPoints[pIdx], oldPoints[pIdx + 1], oldPoints[pIdx + 2]);
pointCounter++;
}
newPolysData.push(pointMap.get(oldPtId));
}
}
output.setPoints(vtkPoints.newInstance({
values: newPointsData,
numberOfComponents: 3,
dataType: pointType
}));
const polys = vtkCellArray.newInstance({
values: newPolysData,
dataType: polyType
});
output.setPolys(polys);
outData[0] = output;
console.timeEnd(`BFSConnectivityFilter`);
};
publicAPI.setExtractionModeToAll = () => {
publicAPI.setExtractionMode(ExtractionMode.ExtractionMode_ALL);
};
publicAPI.setExtractionModeToLargest = () => {
publicAPI.setExtractionMode(ExtractionMode.ExtractionMode_LARGEST);
};
publicAPI.setExtractionModeToSmallest = () => {
publicAPI.setExtractionMode(ExtractionMode.ExtractionMode_SMALLEST);
};
publicAPI.setExtractionModeToCustom = () => {
publicAPI.setExtractionMode(ExtractionMode.ExtractionMode_CUSTOM);
};
publicAPI.getRegionsCount = () => model.regionsCount;
publicAPI.setRegionsCount = () => {
console.log('can not set RegionsCount');
};
}
const DEFAULT_VALUES = {
extractionMode: ExtractionMode.ExtractionMode_ALL,
extractionIndex: 0,
regionsCount: 0
};
function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
macro.obj(publicAPI, model);
macro.algo(publicAPI, model, 1, 1);
macro.setGet(publicAPI, model, ['extractionMode', 'extractionIndex', 'regionsCount']);
vtkBFSConnectivityFilter(publicAPI, model);
}
const newInstance = macro.newInstance(extend, 'vtkBFSConnectivityFilter');
var vtkBFSConnectivityFilter$1 = {
newInstance,
extend
};
export { vtkBFSConnectivityFilter$1 as default, extend, newInstance };