Skip to content
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.
2 changes: 2 additions & 0 deletions Documentation/content/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ This will allow you to see the some live code running in your browser. Just pick
[![PolyDataNormals Example][PolyDataNormals]](./PolyDataNormals.html "PolyDataNormals")
[![ThresholdPoints Example][ThresholdPoints]](./ThresholdPoints.html "Cut/Treshold points with point data criteria")
[![ShrinkPolyData Example][ShrinkPolyData]](./ShrinkPolyData.html "ShrinkPolyData")
[![CleanPolyData Example][CleanPolyData]](./CleanPolyData.html "CleanPolyData")

</div>

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

# Sources

Expand Down
5 changes: 5 additions & 0 deletions Sources/Common/Core/CellArray/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ export interface vtkCellArray extends vtkDataArray {
* @returns {Number} Idx of where the cell was inserted
*/
insertNextCell(cellPointIds: number[]): number;

/**
* Get the maximum cell size.
*/
getMaxCellSize(): number;
}

/**
Expand Down
3 changes: 3 additions & 0 deletions Sources/Common/Core/CellArray/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ function vtkCellArray(publicAPI, model) {
}
return cellId;
};

publicAPI.getMaxCellSize = () =>
publicAPI.getCellSizes().reduce((a, b) => Math.max(a, b), 0);
}

// ----------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions Sources/Common/DataModel/BoundingBox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,7 @@ export const STATIC = {
getLengths,
getMaxLength,
getDiagonalLength,
getDiagonalLength2,
getMinPoint,
getMaxPoint,
getXRange,
Expand Down
102 changes: 70 additions & 32 deletions Sources/Common/DataModel/DataSet/index.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
import macro from 'vtk.js/Sources/macros';
import vtk from 'vtk.js/Sources/vtk';
import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox';
import vtkDataSetAttributes from 'vtk.js/Sources/Common/DataModel/DataSetAttributes';
import vtkMath from 'vtk.js/Sources/Common/Core/Math';
import Constants from 'vtk.js/Sources/Common/DataModel/DataSet/Constants';

// import vtkBoundingBox from '../BoundingBox';
// import * as vtkMath from '../../Core/Math';
//
// function getBounds(dataset) {
// if (dataset.bounds) {
// return dataset.bounds;
// }
// if (dataset.type && dataset[dataset.type]) {
// const ds = dataset[dataset.type];
// if (ds.bounds) {
// return ds.bounds;
// }
// if (ds.Points && ds.Points.bounds) {
// return ds.Points.bounds;
// }

// if (ds.Points && ds.Points.values) {
// const array = ds.Points.values;
// const bbox = [...vtkBoundingBox.INIT_BOUNDS];
// const size = array.length;
// const delta = ds.Points.numberOfComponents ? ds.Points.numberOfComponents : 3;
// for (let idx = 0; idx < size; idx += delta) {
// vtkBoundingBox.addPoint(bbox, array[idx * delta], array[(idx * delta) + 1], array[(idx * delta) + 2]);
// }
// ds.Points.bounds = bbox;
// return ds.Points.bounds;
// }
// }
// return vtkMath.createUninitializedBounds();
// }

// ----------------------------------------------------------------------------
// Global methods
// ----------------------------------------------------------------------------
Expand All @@ -57,6 +28,73 @@ function vtkDataSet(publicAPI, model) {
}
});

//------------------------------------------------------------------------------
// Compute the data bounding box from data points.
publicAPI.computeBounds = () => {
if (
(model.modifiedTime &&
model.computeTime &&
model.modifiedTime > model.computeTime) ||
!model.computeTime
) {
const points = publicAPI.getPoints();
if (points?.getNumberOfPoints()) {
// Compute bounds from points
vtkBoundingBox.setBounds(model.bounds, points.getBoundsByReference());
} else {
model.bounds = vtkMath.createUninitializedBounds();
}
// Update computeTime
model.computeTime = macro.getCurrentGlobalMTime();
}
};

/**
* Returns the squared length of the diagonal of the bounding box
*/
publicAPI.getLength2 = () => {
const bounds = publicAPI.getBoundsByReference();
if (!bounds || bounds.length !== 6) return 0;
return vtkBoundingBox.getDiagonalLength2(bounds);
};

/**
* Returns the length of the diagonal of the bounding box
*/
publicAPI.getLength = () => Math.sqrt(publicAPI.getLength2());

/**
* Returns the center of the bounding box as [x, y, z]
*/
publicAPI.getCenter = () => {
const bounds = publicAPI.getBoundsByReference();
if (!bounds || bounds.length !== 6) return [0, 0, 0];
return vtkBoundingBox.getCenter(bounds);
};

/**
* Get the bounding box of a cell with the given cellId
* @param {Number} cellId - The id of the cell
* @returns {Number[]} - The bounds as [xmin, xmax, ymin, ymax, zmin, zmax]
*/
publicAPI.getCellBounds = (cellId) => {
const cell = publicAPI.getCell(cellId);
if (cell) {
return cell.getBounds();
}
return vtkMath.createUninitializedBounds();
};

publicAPI.getBounds = macro.chain(
() => publicAPI.computeBounds,
publicAPI.getBounds
);

publicAPI.getBoundsByReference = macro.chain(
() => publicAPI.computeBounds,
publicAPI.getBoundsByReference
);

const superShallowCopy = publicAPI.shallowCopy;
publicAPI.shallowCopy = (other, debug = false) => {
superShallowCopy(other, debug);
Expand Down Expand Up @@ -98,7 +136,7 @@ export function extend(publicAPI, model, initialValues = {}) {
// Object methods
macro.obj(publicAPI, model);
macro.setGet(publicAPI, model, DATASET_FIELDS);

macro.getArray(publicAPI, model, ['bounds'], 6);
// Object specific methods
vtkDataSet(publicAPI, model);
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Common/DataModel/DataSetAttributes/FieldData.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function vtkFieldData(publicAPI, model) {
publicAPI.copyStructure = (other) => {
publicAPI.initializeFields();
model.copyFieldFlags = other.getCopyFieldFlags().map((x) => x); // Deep-copy
model.arrays = other.arrays().map((x) => ({ array: x })); // Deep-copy
model.arrays = other.getArrays().map((x) => ({ data: x })); // Deep-copy
// TODO: Copy array information objects (once we support information objects)
};

Expand Down
12 changes: 9 additions & 3 deletions Sources/Common/DataModel/PolyData/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,15 @@ export interface vtkPolyData extends vtkPointSet {
getLines(): vtkCellArray;

/**
*
* Get the links between points and cells.
*/
getLinks(): any;
getLinks(): any; // vtkCellLinks

/**
* Get the maximum cell size.
* Returns 0 if there is no cell.
*/
getMaxCellSize(): number;

/**
* Determine the number of cells composing the polydata.
Expand Down Expand Up @@ -104,7 +110,7 @@ export interface vtkPolyData extends vtkPointSet {
* Topological inquiry to get cells using point.
* @param ptId
*/
getPointCells(ptId: any): void;
getPointCells(ptId: number): void;

/**
* Get the cell array defining polys.
Expand Down
15 changes: 14 additions & 1 deletion Sources/Common/DataModel/PolyData/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,24 @@ import vtkCellLinks from 'vtk.js/Sources/Common/DataModel/CellLinks';
import vtkCellTypes from 'vtk.js/Sources/Common/DataModel/CellTypes';
import vtkLine from 'vtk.js/Sources/Common/DataModel/Line';
import vtkPointSet from 'vtk.js/Sources/Common/DataModel/PointSet';
import vtkPolyLine from 'vtk.js/Sources/Common/DataModel/PolyLine';
import vtkPolygon from 'vtk.js/Sources/Common/DataModel/Polygon';
import vtkQuad from 'vtk.js/Sources/Common/DataModel/Quad';
import vtkTriangle from 'vtk.js/Sources/Common/DataModel/Triangle';

import vtkTriangleStrip from 'vtk.js/Sources/Common/DataModel/TriangleStrip';
import { CellType } from 'vtk.js/Sources/Common/DataModel/CellTypes/Constants';
import { POLYDATA_FIELDS } from 'vtk.js/Sources/Common/DataModel/PolyData/Constants';

const { vtkWarningMacro } = macro;

export const CELL_FACTORY = {
[CellType.VTK_LINE]: vtkLine,
[CellType.VTK_QUAD]: vtkQuad,
[CellType.VTK_POLY_LINE]: vtkLine,
[CellType.VTK_TRIANGLE]: vtkTriangle,
[CellType.VTK_TRIANGLE_STRIP]: vtkTriangleStrip,
[CellType.VTK_POLY_LINE]: vtkPolyLine,
[CellType.VTK_POLYGON]: vtkPolygon,
};

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -242,6 +249,12 @@ function vtkPolyData(publicAPI, model) {
cell.initialize(publicAPI.getPoints(), cellInfo.cellPointIds);
return cell;
};

publicAPI.getMaxCellSize = () =>
POLYDATA_FIELDS.reduce(
(max, type) => Math.max(max, model[type]?.getMaxCellSize?.() ?? 0),
0
);
}

// ----------------------------------------------------------------------------
Expand Down
22 changes: 22 additions & 0 deletions Sources/Filters/Core/CleanPolyData/example/controlPanel.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<table>
<tr>
<td colspan="5"><b>Before(Left Cube)<b></td>
</tr>
<tr>
<td style="padding: 5px;">Points : <span class="initial-points">0</span></td>
<td style="padding: 5px;">Cells : <span class="initial-cells">0</span></td>
<td style="padding: 5px;">Lines : <span class="initial-lines">0</span></td>
<td style="padding: 5px;">Polys : <span class="initial-polys">0</span></td>
<td style="padding: 5px;">Strips : <span class="initial-strips">0</span></td>
</tr>
<tr>
<td colspan="5"><b>After(Right Cube)<b></td>
</tr>
<tr>
<td style="padding: 5px;">Points : <span class="final-points">0</span></td>
<td style="padding: 5px;">Cells : <span class="final-cells">0</span></td>
<td style="padding: 5px;">Lines : <span class="final-lines">0</span></td>
<td style="padding: 5px;">Polys : <span class="final-polys">0</span></td>
<td style="padding: 5px;">Strips : <span class="final-strips">0</span></td>
</tr>
</table>
116 changes: 116 additions & 0 deletions Sources/Filters/Core/CleanPolyData/example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
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 '@kitware/vtk.js/IO/Core/DataAccessHelper/HttpDataAccessHelper';

import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkCleanPolyData from '@kitware/vtk.js/Filters/Core/CleanPolyData';
import vtkCubeSource from '@kitware/vtk.js/Filters/Sources/CubeSource';
import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
import vtkGlyph3DMapper from '@kitware/vtk.js/Rendering/Core/Glyph3DMapper';
import vtkArrowSource from '@kitware/vtk.js/Filters/Sources/ArrowSource';

import controlPanel from './controlPanel.html';

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

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

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

fullScreenRenderer.addController(controlPanel);

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

const cubeSource1 = vtkCubeSource.newInstance();
const cubeActor1 = vtkActor.newInstance();
const cubeMapper1 = vtkMapper.newInstance();
cubeActor1.setMapper(cubeMapper1);
cubeMapper1.setInputConnection(cubeSource1.getOutputPort());
renderer.addActor(cubeActor1);

const arrowSource1 = vtkArrowSource.newInstance();
const glyphMapper1 = vtkGlyph3DMapper.newInstance();
glyphMapper1.setInputConnection(cubeSource1.getOutputPort());
glyphMapper1.setSourceConnection(arrowSource1.getOutputPort());
glyphMapper1.setOrientationModeToDirection();
glyphMapper1.setOrientationArray('Normals');
glyphMapper1.setScaleModeToScaleByMagnitude();
glyphMapper1.setScaleArray('Normals');
glyphMapper1.setScaleFactor(0.1);

const glyphActor1 = vtkActor.newInstance();
glyphActor1.setMapper(glyphMapper1);
renderer.addActor(glyphActor1);

const cubeSource2 = vtkCubeSource.newInstance();
const cubeActor2 = vtkActor.newInstance();
const cubeMapper2 = vtkMapper.newInstance();

cubeActor2.setMapper(cubeMapper2);
cubeMapper2.setInputConnection(cubeSource2.getOutputPort());
cubeActor2.setPosition(2, 0, 0);
renderer.addActor(cubeActor2);

const cleanPolyData = vtkCleanPolyData.newInstance();
cleanPolyData.setInputConnection(cubeSource2.getOutputPort());

const arrowSource2 = vtkArrowSource.newInstance();
const glyphMapper2 = vtkGlyph3DMapper.newInstance();
glyphMapper2.setInputConnection(cleanPolyData.getOutputPort());
glyphMapper2.setSourceConnection(arrowSource2.getOutputPort());
glyphMapper2.setOrientationModeToDirection();
glyphMapper2.setOrientationArray('Normals');
glyphMapper2.setScaleModeToScaleByMagnitude();
glyphMapper2.setScaleArray('Normals');
glyphMapper2.setScaleFactor(0.1);

const glyphActor2 = vtkActor.newInstance();
glyphActor2.setMapper(glyphMapper2);
glyphActor2.setPosition(2, 0, 0);
renderer.addActor(glyphActor2);

// --- Render ---
renderer.resetCamera();
renderWindow.render();

// -----------------------------------------------------------
// Display initial and final polydata stats
// -----------------------------------------------------------
const initialPolyData = cubeSource1.getOutputData();
const initialPoints = initialPolyData.getNumberOfPoints();
const initialCells = initialPolyData.getNumberOfCells();
const initialLines = initialPolyData.getLines().getNumberOfCells();
const initialPolys = initialPolyData.getPolys().getNumberOfCells();
const initialStrips = initialPolyData.getStrips().getNumberOfCells();

document.querySelector('.initial-points').textContent = initialPoints;
document.querySelector('.initial-cells').textContent = initialCells;
document.querySelector('.initial-lines').textContent = initialLines;
document.querySelector('.initial-polys').textContent = initialPolys;
document.querySelector('.initial-strips').textContent = initialStrips;

const finalPolyData = cleanPolyData.getOutputData();
const finalPoints = finalPolyData.getNumberOfPoints();
const finalCells = finalPolyData.getNumberOfCells();
const finalLines = finalPolyData.getLines().getNumberOfCells();
const finalPolys = finalPolyData.getPolys().getNumberOfCells();
const finalStrips = finalPolyData.getStrips().getNumberOfCells();

document.querySelector('.final-points').textContent = finalPoints;
document.querySelector('.final-cells').textContent = finalCells;
document.querySelector('.final-lines').textContent = finalLines;
document.querySelector('.final-polys').textContent = finalPolys;
document.querySelector('.final-strips').textContent = finalStrips;
Loading