Skip to content

Commit 69ef3be

Browse files
committed
feat(CleanPolyData): add vtkCleanPolyData
1 parent bea78f5 commit 69ef3be

File tree

13 files changed

+1061
-36
lines changed

13 files changed

+1061
-36
lines changed

Sources/Common/Core/CellArray/index.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ export interface vtkCellArray extends vtkDataArray {
4646
* @returns {Number} Idx of where the cell was inserted
4747
*/
4848
insertNextCell(cellPointIds: number[]): number;
49+
50+
/**
51+
* Get the maximum cell size.
52+
*/
53+
getMaxCellSize(): number;
4954
}
5055

5156
/**

Sources/Common/Core/CellArray/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@ function vtkCellArray(publicAPI, model) {
117117
}
118118
return cellId;
119119
};
120+
121+
publicAPI.getMaxCellSize = () => {
122+
const cellSizes = publicAPI.getCellSizes();
123+
if (cellSizes.length === 0) {
124+
return 0;
125+
}
126+
let len = cellSizes.length;
127+
let max = -Infinity;
128+
129+
while (len--) {
130+
max = cellSizes[len] > max ? cellSizes[len] : max;
131+
}
132+
return max;
133+
};
120134
}
121135

122136
// ----------------------------------------------------------------------------

Sources/Common/DataModel/BoundingBox/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,7 @@ export const STATIC = {
993993
getLengths,
994994
getMaxLength,
995995
getDiagonalLength,
996+
getDiagonalLength2,
996997
getMinPoint,
997998
getMaxPoint,
998999
getXRange,

Sources/Common/DataModel/DataSet/index.js

Lines changed: 83 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,10 @@
11
import macro from 'vtk.js/Sources/macros';
22
import vtk from 'vtk.js/Sources/vtk';
33
import vtkDataSetAttributes from 'vtk.js/Sources/Common/DataModel/DataSetAttributes';
4+
import vtkBoundingBox from 'vtk.js/Sources/Common/DataModel/BoundingBox';
5+
import vtkMath from 'vtk.js/Sources/Common/Core/Math';
46
import Constants from 'vtk.js/Sources/Common/DataModel/DataSet/Constants';
57

6-
// import vtkBoundingBox from '../BoundingBox';
7-
// import * as vtkMath from '../../Core/Math';
8-
//
9-
// function getBounds(dataset) {
10-
// if (dataset.bounds) {
11-
// return dataset.bounds;
12-
// }
13-
// if (dataset.type && dataset[dataset.type]) {
14-
// const ds = dataset[dataset.type];
15-
// if (ds.bounds) {
16-
// return ds.bounds;
17-
// }
18-
// if (ds.Points && ds.Points.bounds) {
19-
// return ds.Points.bounds;
20-
// }
21-
22-
// if (ds.Points && ds.Points.values) {
23-
// const array = ds.Points.values;
24-
// const bbox = [...vtkBoundingBox.INIT_BOUNDS];
25-
// const size = array.length;
26-
// const delta = ds.Points.numberOfComponents ? ds.Points.numberOfComponents : 3;
27-
// for (let idx = 0; idx < size; idx += delta) {
28-
// vtkBoundingBox.addPoint(bbox, array[idx * delta], array[(idx * delta) + 1], array[(idx * delta) + 2]);
29-
// }
30-
// ds.Points.bounds = bbox;
31-
// return ds.Points.bounds;
32-
// }
33-
// }
34-
// return vtkMath.createUninitializedBounds();
35-
// }
36-
378
// ----------------------------------------------------------------------------
389
// Global methods
3910
// ----------------------------------------------------------------------------
@@ -57,6 +28,87 @@ function vtkDataSet(publicAPI, model) {
5728
}
5829
});
5930

31+
//------------------------------------------------------------------------------
32+
// Compute the data bounding box from data points.
33+
publicAPI.computeBounds = () => {
34+
if (
35+
(model.modifiedTime &&
36+
model.computeTime &&
37+
model.modifiedTime > model.computeTime) ||
38+
!model.computeTime
39+
) {
40+
const points = publicAPI.getPoints();
41+
if (points?.getNumberOfPoints()) {
42+
// Compute bounds from points
43+
const bounds = vtkBoundingBox.INIT_BOUNDS.slice();
44+
const numberOfPoints = points.getNumberOfPoints();
45+
for (let i = 0; i < numberOfPoints; i++) {
46+
const pt = points.getPoint(i);
47+
vtkBoundingBox.addPoint(bounds, pt[0], pt[1], pt[2]);
48+
}
49+
model.bounds = bounds;
50+
} else {
51+
model.bounds = vtkMath.createUninitializedBounds();
52+
}
53+
// Update computeTime
54+
model.computeTime = Date.now();
55+
}
56+
};
57+
58+
/**
59+
* Returns the bounds as [xmin, xmax, ymin, ymax, zmin, zmax]
60+
*/
61+
publicAPI.getBounds = () => {
62+
if (model.bounds && model.bounds.length === 6) {
63+
return model.bounds;
64+
}
65+
// fallback: try to get bounds from pointData if available
66+
if (publicAPI.getPoints && publicAPI.getPoints()) {
67+
return publicAPI.getPoints().getBounds();
68+
}
69+
return vtkMath.createUninitializedBounds();
70+
};
71+
72+
/**
73+
* Returns the squared length of the diagonal of the bounding box
74+
*/
75+
publicAPI.getLength2 = () => {
76+
const bounds = publicAPI.getBounds();
77+
if (!bounds || bounds.length !== 6) return 0;
78+
return vtkBoundingBox.getDiagonalLength2(bounds);
79+
};
80+
81+
/**
82+
* Returns the length of the diagonal of the bounding box
83+
*/
84+
publicAPI.getLength = () => Math.sqrt(publicAPI.getLength2());
85+
86+
/**
87+
* Returns the center of the bounding box as [x, y, z]
88+
*/
89+
publicAPI.getCenter = () => {
90+
const bounds = publicAPI.getBounds();
91+
if (!bounds || bounds.length !== 6) return [0, 0, 0];
92+
return [
93+
(bounds[0] + bounds[1]) / 2,
94+
(bounds[2] + bounds[3]) / 2,
95+
(bounds[4] + bounds[5]) / 2,
96+
];
97+
};
98+
99+
/**
100+
* Get the bounding box of a cell with the given cellId
101+
* @param {Number} cellId - The id of the cell
102+
* @returns {Number[]} - The bounds as [xmin, xmax, ymin, ymax, zmin, zmax]
103+
*/
104+
publicAPI.getCellBounds = (cellId) => {
105+
const cell = publicAPI.getCell(cellId);
106+
if (cell) {
107+
return cell.getBounds();
108+
}
109+
return vtkMath.createUninitializedBounds();
110+
};
111+
60112
const superShallowCopy = publicAPI.shallowCopy;
61113
publicAPI.shallowCopy = (other, debug = false) => {
62114
superShallowCopy(other, debug);

Sources/Common/DataModel/DataSetAttributes/FieldData.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function vtkFieldData(publicAPI, model) {
3232
publicAPI.copyStructure = (other) => {
3333
publicAPI.initializeFields();
3434
model.copyFieldFlags = other.getCopyFieldFlags().map((x) => x); // Deep-copy
35-
model.arrays = other.arrays().map((x) => ({ array: x })); // Deep-copy
35+
model.arrays = other.getArrays().map((x) => ({ data: x })); // Deep-copy
3636
// TODO: Copy array information objects (once we support information objects)
3737
};
3838

Sources/Common/DataModel/PolyData/index.d.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,14 @@ export interface vtkPolyData extends vtkPointSet {
6666
getLines(): vtkCellArray;
6767

6868
/**
69-
*
69+
* Get the links between points and cells.
7070
*/
71-
getLinks(): any;
71+
getLinks(): any; // vtkCellLinks
72+
73+
/**
74+
* Get the maximum cell size.
75+
*/
76+
getMaxCellSize(): number;
7277

7378
/**
7479
* Determine the number of cells composing the polydata.
@@ -104,7 +109,7 @@ export interface vtkPolyData extends vtkPointSet {
104109
* Topological inquiry to get cells using point.
105110
* @param ptId
106111
*/
107-
getPointCells(ptId: any): void;
112+
getPointCells(ptId: number): void;
108113

109114
/**
110115
* Get the cell array defining polys.

Sources/Common/DataModel/PolyData/index.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,25 @@ import vtkCellLinks from 'vtk.js/Sources/Common/DataModel/CellLinks';
55
import vtkCellTypes from 'vtk.js/Sources/Common/DataModel/CellTypes';
66
import vtkLine from 'vtk.js/Sources/Common/DataModel/Line';
77
import vtkPointSet from 'vtk.js/Sources/Common/DataModel/PointSet';
8-
import vtkTriangle from 'vtk.js/Sources/Common/DataModel/Triangle';
8+
import vtkQuad from 'vtk.js/Sources/Common/DataModel/Quad';
9+
import vtkPolyLine from 'vtk.js/Sources/Common/DataModel//PolyLine';
10+
import vtkPolygon from 'vtk.js/Sources/Common/DataModel/Polygon';
911

12+
import vtkTriangle from 'vtk.js/Sources/Common/DataModel/Triangle';
13+
import vtkTriangleStrip from 'vtk.js/Sources/Common/DataModel/TriangleStrip';
1014
import { CellType } from 'vtk.js/Sources/Common/DataModel/CellTypes/Constants';
1115
import { POLYDATA_FIELDS } from 'vtk.js/Sources/Common/DataModel/PolyData/Constants';
1216

1317
const { vtkWarningMacro } = macro;
1418

1519
export const CELL_FACTORY = {
1620
[CellType.VTK_LINE]: vtkLine,
21+
[CellType.VTK_QUAD]: vtkQuad,
1722
[CellType.VTK_POLY_LINE]: vtkLine,
1823
[CellType.VTK_TRIANGLE]: vtkTriangle,
24+
[CellType.VTK_TRIANGLE_STRIP]: vtkTriangleStrip,
25+
[CellType.VTK_POLY_LINE]: vtkPolyLine,
26+
[CellType.VTK_POLYGON]: vtkPolygon,
1927
};
2028

2129
// ----------------------------------------------------------------------------
@@ -242,6 +250,28 @@ function vtkPolyData(publicAPI, model) {
242250
cell.initialize(publicAPI.getPoints(), cellInfo.cellPointIds);
243251
return cell;
244252
};
253+
254+
publicAPI.getMaxCellSize = () => {
255+
let maxCellSize = 0;
256+
257+
if (model.verts) {
258+
maxCellSize = Math.max(maxCellSize, model.verts.getMaxCellSize());
259+
}
260+
261+
if (model.lines) {
262+
maxCellSize = Math.max(maxCellSize, model.lines.getMaxCellSize());
263+
}
264+
265+
if (model.polys) {
266+
maxCellSize = Math.max(maxCellSize, model.polys.getMaxCellSize());
267+
}
268+
269+
if (model.strips) {
270+
maxCellSize = Math.max(maxCellSize, model.strips.getMaxCellSize());
271+
}
272+
273+
return maxCellSize;
274+
};
245275
}
246276

247277
// ----------------------------------------------------------------------------
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<table>
2+
<tr>
3+
<td colspan="5"><b>Initial<b></td>
4+
</tr>
5+
<tr>
6+
<td style="padding: 5px;">Points : <span class="initial-points">0</span></td>
7+
<td style="padding: 5px;">Cells : <span class="initial-cells">0</span></td>
8+
<td style="padding: 5px;">Lines : <span class="initial-lines">0</span></td>
9+
<td style="padding: 5px;">Polys : <span class="initial-polys">0</span></td>
10+
<td style="padding: 5px;">Strips : <span class="initial-strips">0</span></td>
11+
</tr>
12+
<tr>
13+
<td colspan="5"><b>Final<b></td>
14+
</tr>
15+
<tr>
16+
<td style="padding: 5px;">Points : <span class="final-points">0</span></td>
17+
<td style="padding: 5px;">Cells : <span class="final-cells">0</span></td>
18+
<td style="padding: 5px;">Lines : <span class="final-lines">0</span></td>
19+
<td style="padding: 5px;">Polys : <span class="final-polys">0</span></td>
20+
<td style="padding: 5px;">Strips : <span class="final-strips">0</span></td>
21+
</tr>
22+
</table>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import '@kitware/vtk.js/favicon';
2+
3+
// Load the rendering pieces we want to use (for both WebGL and WebGPU)
4+
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
5+
import '@kitware/vtk.js/IO/Core/DataAccessHelper/HttpDataAccessHelper';
6+
7+
import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
8+
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
9+
import vtkCleanPolyData from '@kitware/vtk.js/Filters/Core/CleanPolyData';
10+
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
11+
import vtkCubeSource from '@kitware/vtk.js/Filters/Sources/CubeSource';
12+
13+
import controlPanel from './controlPanel.html';
14+
15+
// ----------------------------------------------------------------------------
16+
// Standard rendering code setup
17+
// ----------------------------------------------------------------------------
18+
19+
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance();
20+
const renderer = fullScreenRenderer.getRenderer();
21+
const renderWindow = fullScreenRenderer.getRenderWindow();
22+
23+
// -----------------------------------------------------------
24+
// UI control handling
25+
// -----------------------------------------------------------
26+
27+
fullScreenRenderer.addController(controlPanel);
28+
29+
// ----------------------------------------------------------------------------
30+
// Example code
31+
// ----------------------------------------------------------------------------
32+
const cleanPolyData = vtkCleanPolyData.newInstance();
33+
34+
const actor = vtkActor.newInstance();
35+
const mapper = vtkMapper.newInstance();
36+
actor.setMapper(mapper);
37+
38+
const cubeSource = vtkCubeSource.newInstance();
39+
mapper.setInputConnection(cleanPolyData.getOutputPort());
40+
41+
cleanPolyData.setInputConnection(cubeSource.getOutputPort());
42+
43+
// Update the control panel with initial values
44+
const initialPoints = cubeSource.getOutputData().getNumberOfPoints();
45+
const initialCells = cubeSource.getOutputData().getNumberOfCells();
46+
const initialLines = cubeSource.getOutputData().getLines().getNumberOfCells();
47+
const initialPolys = cubeSource.getOutputData().getPolys().getNumberOfCells();
48+
const initialStrips = cubeSource.getOutputData().getStrips().getNumberOfCells();
49+
document.querySelector('.initial-points').textContent = initialPoints;
50+
document.querySelector('.initial-cells').textContent = initialCells;
51+
document.querySelector('.initial-lines').textContent = initialLines;
52+
document.querySelector('.initial-polys').textContent = initialPolys;
53+
document.querySelector('.initial-strips').textContent = initialStrips;
54+
55+
const finalPoints = cleanPolyData.getOutputData().getNumberOfPoints();
56+
const finalCells = cleanPolyData.getOutputData().getNumberOfCells();
57+
const finalLines = cleanPolyData.getOutputData().getLines().getNumberOfCells();
58+
const finalPolys = cleanPolyData.getOutputData().getPolys().getNumberOfCells();
59+
const finalStrips = cleanPolyData
60+
.getOutputData()
61+
.getStrips()
62+
.getNumberOfCells();
63+
document.querySelector('.final-points').textContent = finalPoints;
64+
document.querySelector('.final-cells').textContent = finalCells;
65+
document.querySelector('.final-lines').textContent = finalLines;
66+
document.querySelector('.final-polys').textContent = finalPolys;
67+
document.querySelector('.final-strips').textContent = finalStrips;
68+
69+
renderer.addActor(actor);
70+
renderer.resetCamera();
71+
renderWindow.render();

0 commit comments

Comments
 (0)