Skip to content

Commit 9236e51

Browse files
test: add a second test for adding clipping planes
This tests two things: - Many clipping planes (>6, which was a previous limit) - Rendering with no clipping planes, then adding clipping planes, then rendering again with them included. This used to be broken, because the shaders weren't notified that they need to be rebuilt when clipping planes are first introduced.
1 parent dc84f29 commit 9236e51

File tree

3 files changed

+129
-1
lines changed

3 files changed

+129
-1
lines changed

Examples/Geometry/_MeshClipPlane/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ const rotationMatrix = [
9494
const normal = [1, 0, 0];
9595
const origin = [0, 0, 0];
9696

97-
// let el = document.querySelector('.togglePlanesButton');
9897
document.querySelector('.addClippingPlane').addEventListener('click', (e) => {
9998
vtkMath.multiplyAccumulate([0, 0, 0], normal, -0.8, origin);
10099
addClippingPlaneToScene(
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import test from 'tape-catch';
2+
3+
import vtkOpenGLRenderWindow from 'vtk.js/Sources/Rendering/OpenGL/RenderWindow';
4+
import vtkRenderWindow from 'vtk.js/Sources/Rendering/Core/RenderWindow';
5+
import vtkRenderer from 'vtk.js/Sources/Rendering/Core/Renderer';
6+
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
7+
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
8+
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
9+
import vtkSphereSource from 'vtk.js/Sources/Filters/Sources/SphereSource';
10+
import vtkPlaneSource from 'vtk.js/Sources/Filters/Sources/PlaneSource';
11+
import vtkPlane from 'vtk.js/Sources/Common/DataModel/Plane';
12+
import testUtils from 'vtk.js/Sources/Testing/testUtils';
13+
import baseline from './testMoreClippingPlanes.png';
14+
15+
test('Test PolyDataMapper Clipping Planes 2', (t) => {
16+
const gc = testUtils.createGarbageCollector(t);
17+
// TODO switch back to onlyIfWebGL
18+
// Create some control UI
19+
const container = document.querySelector('body');
20+
const renderWindowContainer = document.createElement('div');
21+
container.appendChild(renderWindowContainer);
22+
23+
// Create what we will view
24+
const renderWindow = gc.registerResource(vtkRenderWindow.newInstance());
25+
const renderer = gc.registerResource(vtkRenderer.newInstance());
26+
renderWindow.addRenderer(renderer);
27+
renderer.setBackground(0.32, 0.34, 0.43);
28+
29+
// The rest is pretty much a static test version of the interactive example _MeshClipPlane
30+
31+
const sphereMapper = gc.registerResource(vtkMapper.newInstance());
32+
const sphereSource = gc.registerResource(
33+
vtkSphereSource.newInstance({
34+
radius: 1.0,
35+
phiResolution: 30,
36+
thetaResolution: 30,
37+
})
38+
);
39+
sphereMapper.setInputConnection(sphereSource.getOutputPort());
40+
const sphereActor = gc.registerResource(vtkActor.newInstance());
41+
sphereActor.setMapper(sphereMapper);
42+
sphereActor.getProperty().setColor(1, 0, 1);
43+
44+
// This function adds a clipping plane to the scene
45+
// The center of the plane will be `origin`
46+
// The normal direction of the plane is `normal`; it's okay if it's not a unit vector
47+
// `scale` is the size of the plane, i.e. the side length of the square that is created
48+
function addClippingPlaneToScene(origin, normal, scale) {
49+
vtkMath.normalize(normal);
50+
51+
const dir1 = [];
52+
const dir2 = [];
53+
vtkMath.perpendiculars(normal, dir1, dir2, 0);
54+
55+
const corner = [];
56+
vtkMath.multiplyAccumulate(origin, dir1, -0.5 * scale, corner);
57+
vtkMath.multiplyAccumulate(corner, dir2, -0.5 * scale, corner);
58+
59+
const point1 = [];
60+
const point2 = [];
61+
vtkMath.multiplyAccumulate(corner, dir1, scale, point1);
62+
vtkMath.multiplyAccumulate(corner, dir2, scale, point2);
63+
64+
const planeSource = gc.registerResource(
65+
vtkPlaneSource.newInstance({
66+
xResolution: 1,
67+
yResolution: 1,
68+
origin: corner,
69+
point1,
70+
point2,
71+
})
72+
);
73+
74+
const clipPlane = gc.registerResource(
75+
vtkPlane.newInstance({
76+
normal,
77+
origin,
78+
})
79+
);
80+
81+
const planeMapper = gc.registerResource(vtkMapper.newInstance());
82+
planeMapper.setInputConnection(planeSource.getOutputPort());
83+
const planeActor = gc.registerResource(vtkActor.newInstance());
84+
planeActor.setMapper(planeMapper);
85+
planeActor.getProperty().setOpacity(0.2);
86+
renderer.addActor(planeActor);
87+
88+
sphereMapper.addClippingPlane(clipPlane);
89+
}
90+
91+
renderer.addActor(sphereActor);
92+
93+
const numPlanes = 8;
94+
95+
const theta = (2 * Math.PI) / numPlanes;
96+
const rotationMatrix = [
97+
[Math.cos(theta), Math.sin(theta), 0],
98+
[-Math.sin(theta), Math.cos(theta), 0],
99+
[0, 0, 1],
100+
];
101+
const normal = [1, 0, 0];
102+
const origin = [0, 0, 0];
103+
104+
const glwindow = gc.registerResource(vtkOpenGLRenderWindow.newInstance());
105+
glwindow.setContainer(renderWindowContainer);
106+
renderWindow.addView(glwindow);
107+
glwindow.setSize(400, 400);
108+
109+
// Render once without any clipping planes present
110+
// Hopefully when we render again below, the shader will be
111+
// rebuilt because we added clipping planes.
112+
renderer.resetCamera();
113+
renderWindow.render();
114+
115+
for (let i = 0; i < 7; ++i) {
116+
vtkMath.multiplyAccumulate([0, 0, 0], normal, -0.8, origin);
117+
addClippingPlaneToScene(
118+
origin, // origin
119+
normal, // normal
120+
3 // scale
121+
);
122+
vtkMath.multiply3x3_vect3(rotationMatrix, normal, normal);
123+
}
124+
125+
glwindow.captureNextImage().then((image) => {
126+
testUtils.compareImages(image, [baseline], 'TestMoreClippingPlanes', t, 2);
127+
});
128+
renderWindow.render();
129+
});
23.5 KB
Loading

0 commit comments

Comments
 (0)