Skip to content

Commit 2440cbf

Browse files
dakerfinetjul
authored andcommitted
feat(ClipPolyData): add vtkClipPolyData
1 parent 81a5336 commit 2440cbf

File tree

14 files changed

+1512
-6
lines changed

14 files changed

+1512
-6
lines changed
30.5 KB
Loading
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import vtkAbstractPointLocator, {
2+
IAbstractPointLocatorInitialValues,
3+
} from '../AbstractPointLocator';
4+
5+
/**
6+
* Initial values for vtkIncrementalPointLocator.
7+
*/
8+
export interface IIncrementalPointLocatorInitialValues
9+
extends IAbstractPointLocatorInitialValues {}
10+
11+
export interface vtkIncrementalPointLocator extends vtkAbstractPointLocator {}
12+
13+
/**
14+
* Method used to decorate a given object (publicAPI+model) with
15+
* vtkIncrementalPointLocator characteristics.
16+
*
17+
* @param publicAPI object on which methods will be bounds (public)
18+
* @param model object on which data structure will be bounds (protected)
19+
* @param {IIncrementalPointLocatorInitialValues} [initialValues] (default: {})
20+
*/
21+
export function extend(
22+
publicAPI: object,
23+
model: object,
24+
initialValues?: IIncrementalPointLocatorInitialValues
25+
): void;
26+
27+
/**
28+
* Method used to create a new instance of vtkIncrementalPointLocator.
29+
*
30+
* @param {IIncrementalPointLocatorInitialValues} [initialValues] for pre-setting some of its content
31+
*/
32+
export function newInstance(
33+
initialValues?: IIncrementalPointLocatorInitialValues
34+
): vtkIncrementalPointLocator;
35+
36+
/**
37+
* vtkIncrementalPointLocator is the abstract incremental insertion variant of
38+
* vtkAbstractPointLocator.
39+
*/
40+
export declare const vtkIncrementalPointLocator: {
41+
newInstance: typeof newInstance;
42+
extend: typeof extend;
43+
};
44+
45+
export default vtkIncrementalPointLocator;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import macro from 'vtk.js/Sources/macros';
2+
import vtkAbstractPointLocator from 'vtk.js/Sources/Common/DataModel/AbstractPointLocator';
3+
4+
function vtkIncrementalPointLocator(publicAPI, model) {
5+
// Set our className
6+
model.classHierarchy.push('vtkIncrementalPointLocator');
7+
}
8+
9+
// ----------------------------------------------------------------------------
10+
// Object factory
11+
// ----------------------------------------------------------------------------
12+
13+
function defaultValues(initialValues) {
14+
return {
15+
...initialValues,
16+
};
17+
}
18+
19+
// ----------------------------------------------------------------------------
20+
21+
export function extend(publicAPI, model, initialValues = {}) {
22+
vtkAbstractPointLocator.extend(
23+
publicAPI,
24+
model,
25+
defaultValues(initialValues)
26+
);
27+
28+
// Make this a VTK object
29+
macro.obj(publicAPI, model);
30+
31+
// Object specific methods
32+
vtkIncrementalPointLocator(publicAPI, model);
33+
}
34+
35+
// ----------------------------------------------------------------------------
36+
37+
export const newInstance = macro.newInstance(
38+
extend,
39+
'vtkIncrementalPointLocator'
40+
);
41+
42+
// ----------------------------------------------------------------------------
43+
44+
export default { newInstance, extend };

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { Bounds, Nullable, Vector3 } from '../../../types';
22
import vtkPoints from '../../Core/Points';
3-
import vtkAbstractPointLocator, {
4-
IAbstractPointLocatorInitialValues,
5-
} from '../AbstractPointLocator';
3+
import vtkIncrementalPointLocator, {
4+
IIncrementalPointLocatorInitialValues,
5+
} from '../IncrementalPointLocator';
66
import vtkPolyData from '../PolyData';
77

88
/**
99
*
1010
*/
1111
export interface IPointLocatorInitialValues
12-
extends IAbstractPointLocatorInitialValues {
12+
extends IIncrementalPointLocatorInitialValues {
1313
numberOfPointsPerBucket?: number;
1414
bucketSize?: number;
1515
}
@@ -24,7 +24,7 @@ interface IFindClosestPointResult {
2424
dist2: number;
2525
}
2626

27-
export interface vtkPointLocator extends vtkAbstractPointLocator {
27+
export interface vtkPointLocator extends vtkIncrementalPointLocator {
2828
/**
2929
* Find the closest inserted point to the given coordinates.
3030
*

Sources/Common/DataModel/Triangle/index.js

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,25 @@ function intersectWithTriangle(p1, q1, r1, p2, q2, r2, tolerance = 1e-6) {
234234
return { intersect: true, coplanar, pt1, pt2, surfaceId };
235235
}
236236

237+
const TRIANGLE_EDGES = [
238+
[0, 1],
239+
[1, 2],
240+
[2, 0],
241+
];
242+
243+
const TRIANGLE_CASE_MASK = [1, 2, 4];
244+
245+
const TRIANGLE_CASES = [
246+
[-1, -1, -1, -1, -1, -1, -1],
247+
[0, 2, 100, -1, -1, -1, -1],
248+
[1, 0, 101, -1, -1, -1, -1],
249+
[1, 2, 100, 1, 100, 101, -1],
250+
[2, 1, 102, -1, -1, -1, -1],
251+
[0, 1, 102, 102, 100, 0, -1],
252+
[0, 101, 2, 2, 101, 102, -1],
253+
[100, 101, 102, -1, -1, -1, -1],
254+
];
255+
237256
// ----------------------------------------------------------------------------
238257
// Static API
239258
// ----------------------------------------------------------------------------
@@ -711,6 +730,94 @@ function vtkTriangle(publicAPI, model) {
711730

712731
return true; // inside triangle
713732
};
733+
734+
publicAPI.clip = (
735+
value,
736+
cellScalars,
737+
locator,
738+
tris,
739+
inPd,
740+
outPd,
741+
inCd,
742+
cellId,
743+
outCd,
744+
insideOut
745+
) => {
746+
let index = 0;
747+
for (let i = 0; i < 3; i++) {
748+
const scalar = cellScalars.getComponent(i, 0);
749+
if ((insideOut && scalar <= value) || (!insideOut && scalar > value)) {
750+
index += TRIANGLE_CASE_MASK[i];
751+
}
752+
}
753+
754+
const triangleCase = TRIANGLE_CASES[index];
755+
const x = [0, 0, 0];
756+
const x1 = [0, 0, 0];
757+
const x2 = [0, 0, 0];
758+
759+
const pts = [0, 0, 0];
760+
761+
for (let edgeIdx = 0; triangleCase[edgeIdx] > -1; edgeIdx += 3) {
762+
pts[0] = 0;
763+
pts[1] = 0;
764+
pts[2] = 0;
765+
766+
for (let i = 0; i < 3; i++) {
767+
const edgeValue = triangleCase[edgeIdx + i];
768+
if (edgeValue >= 100) {
769+
const vertexId = edgeValue - 100;
770+
model.points.getPoint(vertexId, x);
771+
const { inserted, id } = locator.insertUniquePoint(x);
772+
pts[i] = id;
773+
if (inserted) {
774+
outPd.passData(inPd, model.pointsIds[vertexId], id);
775+
}
776+
} else {
777+
const vert = TRIANGLE_EDGES[edgeValue];
778+
let e1 = vert[0];
779+
let e2 = vert[1];
780+
let deltaScalar =
781+
cellScalars.getComponent(vert[1], 0) -
782+
cellScalars.getComponent(vert[0], 0);
783+
784+
if (deltaScalar <= 0) {
785+
e1 = vert[1];
786+
e2 = vert[0];
787+
deltaScalar = -deltaScalar;
788+
}
789+
790+
const t =
791+
deltaScalar === 0
792+
? 0
793+
: (value - cellScalars.getComponent(e1, 0)) / deltaScalar;
794+
795+
model.points.getPoint(e1, x1);
796+
model.points.getPoint(e2, x2);
797+
for (let j = 0; j < 3; j++) {
798+
x[j] = x1[j] + t * (x2[j] - x1[j]);
799+
}
800+
801+
const { inserted, id } = locator.insertUniquePoint(x);
802+
pts[i] = id;
803+
if (inserted) {
804+
outPd.interpolateData(
805+
inPd,
806+
model.pointsIds[e1],
807+
model.pointsIds[e2],
808+
id,
809+
t
810+
);
811+
}
812+
}
813+
}
814+
815+
if (!(pts[0] === pts[1] || pts[0] === pts[2] || pts[1] === pts[2])) {
816+
const newCellId = tris.insertNextCell(pts);
817+
outCd.passData(inCd, cellId, newCellId);
818+
}
819+
}
820+
};
714821
}
715822

716823
// ----------------------------------------------------------------------------

Sources/Common/DataModel/Triangle/test/testTriangle.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import test from 'tape';
22
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
3+
import vtkCellArray from 'vtk.js/Sources/Common/Core/CellArray';
4+
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
35
import vtkPoints from 'vtk.js/Sources/Common/Core/Points';
6+
import vtkDataSetAttributes from 'vtk.js/Sources/Common/DataModel/DataSetAttributes';
7+
import vtkMergePoints from 'vtk.js/Sources/Common/DataModel/MergePoints';
48
import vtkTriangle from 'vtk.js/Sources/Common/DataModel/Triangle';
59

610
test('Test vtkTriangle instance', (t) => {
@@ -211,3 +215,48 @@ test('Test vtkTriangle intersectWithTriangle coplanar', (t) => {
211215

212216
t.end();
213217
});
218+
219+
test('Test vtkTriangle clip', (t) => {
220+
const points = vtkPoints.newInstance();
221+
points.setData(Float32Array.from([-1, 0, 0, 1, 0, 0, 1, 1, 0]), 3);
222+
223+
const triangle = vtkTriangle.newInstance();
224+
triangle.initialize(points, [0, 1, 2]);
225+
226+
const cellScalars = vtkDataArray.newInstance({
227+
numberOfComponents: 1,
228+
values: new Float32Array([-1, 1, 1]),
229+
});
230+
231+
const locatorPoints = vtkPoints.newInstance();
232+
const locator = vtkMergePoints.newInstance();
233+
locator.initPointInsertion(locatorPoints, [-1, 1, 0, 1, 0, 0]);
234+
235+
const tris = vtkCellArray.newInstance();
236+
const inPd = vtkDataSetAttributes.newInstance();
237+
const outPd = vtkDataSetAttributes.newInstance();
238+
const inCd = vtkDataSetAttributes.newInstance();
239+
const outCd = vtkDataSetAttributes.newInstance();
240+
241+
triangle.clip(
242+
0,
243+
cellScalars,
244+
locator,
245+
tris,
246+
inPd,
247+
outPd,
248+
inCd,
249+
0,
250+
outCd,
251+
false
252+
);
253+
254+
t.equal(tris.getNumberOfCells(), 2, 'Should clip triangle into 2 triangles');
255+
t.equal(
256+
locatorPoints.getNumberOfPoints(),
257+
4,
258+
'Should create 4 unique kept points'
259+
);
260+
261+
t.end();
262+
});

Sources/Common/DataModel/TriangleStrip/index.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,55 @@ function vtkTriangleStrip(publicAPI, model) {
419419
cellId,
420420
outCd,
421421
insideOut
422-
) => notImplemented('clip')();
422+
) => {
423+
const numTris = model.points.getNumberOfPoints() - 2;
424+
const triScalarsValues = new Float32Array(3);
425+
const triScalars = cellScalars.newClone();
426+
triScalars.setNumberOfComponents(cellScalars.getNumberOfComponents());
427+
triScalars.setData(triScalarsValues, cellScalars.getNumberOfComponents());
428+
429+
const trianglePoints = model.triangle.getPoints();
430+
trianglePoints.setNumberOfPoints(3);
431+
const trianglePointIds = model.triangle.getPointsIds();
432+
const tmp = [0, 0, 0];
433+
434+
for (let i = 0; i < numTris; i++) {
435+
let id1 = i;
436+
let id2 = i + 1;
437+
let id3 = i + 2;
438+
439+
if (i % 2) {
440+
id1 = i + 2;
441+
id2 = i + 1;
442+
id3 = i;
443+
}
444+
445+
trianglePoints.setPoint(0, ...model.points.getPoint(id1, tmp));
446+
trianglePoints.setPoint(1, ...model.points.getPoint(id2, tmp));
447+
trianglePoints.setPoint(2, ...model.points.getPoint(id3, tmp));
448+
449+
trianglePointIds[0] = model.pointsIds[id1];
450+
trianglePointIds[1] = model.pointsIds[id2];
451+
trianglePointIds[2] = model.pointsIds[id3];
452+
453+
triScalarsValues[0] = cellScalars.getComponent(id1, 0);
454+
triScalarsValues[1] = cellScalars.getComponent(id2, 0);
455+
triScalarsValues[2] = cellScalars.getComponent(id3, 0);
456+
457+
model.triangle.clip(
458+
value,
459+
triScalars,
460+
locator,
461+
tris,
462+
inPd,
463+
outPd,
464+
inCd,
465+
cellId,
466+
outCd,
467+
insideOut
468+
);
469+
}
470+
};
423471
}
424472

425473
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)