Skip to content

Commit dc84f29

Browse files
feat: add example demonstrating issue #2134
run with `npm run example _MeshClipPlane`
1 parent e242cfc commit dc84f29

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<button type="button" class="addClippingPlane">add clipping plane</button>
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import 'vtk.js/Sources/favicon';
2+
3+
// Load the rendering pieces we want to use (for both WebGL and WebGPU)
4+
import 'vtk.js/Sources/Rendering/Profiles/All';
5+
6+
import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
7+
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
8+
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
9+
import * as vtkMath from 'vtk.js/Sources/Common/Core/Math';
10+
import vtkRenderWindow from 'vtk.js/Sources/Rendering/Core/RenderWindow';
11+
import vtkSphereSource from 'vtk.js/Sources/Filters/Sources/SphereSource';
12+
import vtkPlaneSource from 'vtk.js/Sources/Filters/Sources/PlaneSource';
13+
import vtkPlane from 'vtk.js/Sources/Common/DataModel/Plane';
14+
import controlPanel from './controlPanel.html';
15+
16+
// ----------------------------------------------------------------------------
17+
// Standard rendering code setup
18+
// ----------------------------------------------------------------------------
19+
20+
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
21+
background: [0.33, 0.4, 0.4],
22+
});
23+
fullScreenRenderer.addController(controlPanel);
24+
const renderer = fullScreenRenderer.getRenderer();
25+
const renderWindow = fullScreenRenderer.getRenderWindow();
26+
27+
const sphereMapper = vtkMapper.newInstance();
28+
const sphereSource = vtkSphereSource.newInstance({
29+
radius: 1.0,
30+
phiResolution: 30,
31+
thetaResolution: 30,
32+
});
33+
sphereMapper.setInputConnection(sphereSource.getOutputPort());
34+
const sphereActor = vtkActor.newInstance();
35+
sphereActor.setMapper(sphereMapper);
36+
sphereActor.getProperty().setColor(1, 0, 1);
37+
38+
// Add a clipping plane to the scene
39+
// The center of the plane will be `origin`
40+
// The normal direction of the plane is `normal`; it's okay if it's not a unit vector
41+
// `scale` is the size of the plane, i.e. the side length of the square that is created
42+
function addClippingPlaneToScene(origin, normal, scale) {
43+
vtkMath.normalize(normal);
44+
45+
const dir1 = [];
46+
const dir2 = [];
47+
vtkMath.perpendiculars(normal, dir1, dir2, 0);
48+
49+
const corner = [];
50+
vtkMath.multiplyAccumulate(origin, dir1, -0.5 * scale, corner);
51+
vtkMath.multiplyAccumulate(corner, dir2, -0.5 * scale, corner);
52+
53+
const point1 = [];
54+
const point2 = [];
55+
vtkMath.multiplyAccumulate(corner, dir1, scale, point1);
56+
vtkMath.multiplyAccumulate(corner, dir2, scale, point2);
57+
58+
const planeSource = vtkPlaneSource.newInstance({
59+
xResolution: 1,
60+
yResolution: 1,
61+
origin: corner,
62+
point1,
63+
point2,
64+
});
65+
66+
const clipPlane = vtkPlane.newInstance({
67+
normal,
68+
origin,
69+
});
70+
71+
const planeMapper = vtkMapper.newInstance();
72+
planeMapper.setInputConnection(planeSource.getOutputPort());
73+
const planeActor = vtkActor.newInstance();
74+
planeActor.setMapper(planeMapper);
75+
planeActor.getProperty().setOpacity(0.2);
76+
renderer.addActor(planeActor);
77+
78+
sphereMapper.addClippingPlane(clipPlane);
79+
}
80+
81+
renderer.addActor(sphereActor);
82+
83+
renderer.resetCamera();
84+
renderWindow.render();
85+
86+
const numPlanes = 8;
87+
88+
const theta = (2 * Math.PI) / numPlanes;
89+
const rotationMatrix = [
90+
[Math.cos(theta), Math.sin(theta), 0],
91+
[-Math.sin(theta), Math.cos(theta), 0],
92+
[0, 0, 1],
93+
];
94+
const normal = [1, 0, 0];
95+
const origin = [0, 0, 0];
96+
97+
// let el = document.querySelector('.togglePlanesButton');
98+
document.querySelector('.addClippingPlane').addEventListener('click', (e) => {
99+
vtkMath.multiplyAccumulate([0, 0, 0], normal, -0.8, origin);
100+
addClippingPlaneToScene(
101+
origin, // origin
102+
normal, // normal
103+
3 // scale
104+
);
105+
vtkMath.multiply3x3_vect3(rotationMatrix, normal, normal);
106+
renderWindow.render();
107+
});
108+
109+
// -----------------------------------------------------------
110+
// Make some variables global so that you can inspect and
111+
// modify objects in your browser's developer console:
112+
// -----------------------------------------------------------
113+
114+
global.renderer = renderer;
115+
global.renderWindow = renderWindow;
116+
global.vtkMapper = vtkMapper;
117+
global.vtkRenderWindow = vtkRenderWindow;

0 commit comments

Comments
 (0)