|
| 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 | + |
| 6 | +import vtkSphere from 'vtk.js/Sources/Common/DataModel/Sphere'; |
| 7 | +import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor'; |
| 8 | +import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper'; |
| 9 | +import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow'; |
| 10 | +import vtkSphereSource from '@kitware/vtk.js/Filters/Sources/SphereSource'; |
| 11 | + |
| 12 | +import GUI from 'lil-gui'; |
| 13 | + |
| 14 | +// ---------------------------------------------------------------------------- |
| 15 | +// Example code |
| 16 | +// ---------------------------------------------------------------------------- |
| 17 | + |
| 18 | +const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance(); |
| 19 | +const renderer = fullScreenRenderer.getRenderer(); |
| 20 | +const renderWindow = fullScreenRenderer.getRenderWindow(); |
| 21 | + |
| 22 | +function makeSphereActor( |
| 23 | + center, |
| 24 | + radius, |
| 25 | + color, |
| 26 | + wireframe = false, |
| 27 | + opacity = 1.0 |
| 28 | +) { |
| 29 | + const source = vtkSphereSource.newInstance({ |
| 30 | + center, |
| 31 | + radius, |
| 32 | + thetaResolution: 50, |
| 33 | + phiResolution: 50, |
| 34 | + }); |
| 35 | + const mapper = vtkMapper.newInstance(); |
| 36 | + mapper.setInputConnection(source.getOutputPort()); |
| 37 | + |
| 38 | + const actor = vtkActor.newInstance(); |
| 39 | + actor.setMapper(mapper); |
| 40 | + actor.getProperty().setColor(color[0], color[1], color[2]); |
| 41 | + actor.getProperty().setOpacity(opacity); |
| 42 | + if (wireframe) { |
| 43 | + actor.getProperty().setRepresentationToWireframe(); |
| 44 | + actor.getProperty().setLineWidth(2); |
| 45 | + } |
| 46 | + return actor; |
| 47 | +} |
| 48 | + |
| 49 | +// ---------------------------------------------------------------------------- |
| 50 | +// Scene 1: bounding sphere from points (left side) |
| 51 | +// ---------------------------------------------------------------------------- |
| 52 | +const points = [0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0]; |
| 53 | +const pointBoundingSphere = vtkSphere.computeBoundingSphere(points); |
| 54 | + |
| 55 | +for (let i = 0; i < points.length; i += 3) { |
| 56 | + const point = [points[i], points[i + 1], points[i + 2]]; |
| 57 | + renderer.addActor(makeSphereActor(point, 0.08, [0.1, 0.7, 1.0])); |
| 58 | +} |
| 59 | + |
| 60 | +renderer.addActor( |
| 61 | + makeSphereActor( |
| 62 | + [pointBoundingSphere[0], pointBoundingSphere[1], pointBoundingSphere[2]], |
| 63 | + pointBoundingSphere[3], |
| 64 | + [1.0, 0.2, 0.2], |
| 65 | + true |
| 66 | + ) |
| 67 | +); |
| 68 | + |
| 69 | +// ---------------------------------------------------------------------------- |
| 70 | +// Scene 2: bounding sphere from spheres (right side) |
| 71 | +// ---------------------------------------------------------------------------- |
| 72 | +const xOffset = 8.0; |
| 73 | +const spheres = [ |
| 74 | + [0.0 + xOffset, 0.0, 0.0, 1.0], |
| 75 | + [4.0 + xOffset, 0.0, 0.0, 1.0], |
| 76 | + [2.0 + xOffset, 0.0, 0.0, 0.5], |
| 77 | +]; |
| 78 | +const spheresBoundingSphere = |
| 79 | + vtkSphere.computeBoundingSphereFromSpheres(spheres); |
| 80 | + |
| 81 | +spheres.forEach((sphere) => { |
| 82 | + renderer.addActor( |
| 83 | + makeSphereActor( |
| 84 | + [sphere[0], sphere[1], sphere[2]], |
| 85 | + sphere[3], |
| 86 | + [0.2, 1.0, 0.5], |
| 87 | + false, |
| 88 | + 0.35 |
| 89 | + ) |
| 90 | + ); |
| 91 | +}); |
| 92 | + |
| 93 | +renderer.addActor( |
| 94 | + makeSphereActor( |
| 95 | + [ |
| 96 | + spheresBoundingSphere[0], |
| 97 | + spheresBoundingSphere[1], |
| 98 | + spheresBoundingSphere[2], |
| 99 | + ], |
| 100 | + spheresBoundingSphere[3], |
| 101 | + [1.0, 0.75, 0.2], |
| 102 | + true |
| 103 | + ) |
| 104 | +); |
| 105 | + |
| 106 | +renderer.setBackground(0.12, 0.14, 0.18); |
| 107 | +renderer.resetCamera(); |
| 108 | +renderWindow.render(); |
| 109 | + |
| 110 | +const sceneGuide = { |
| 111 | + scene1: `Input: cyan points represented as small spheres |
| 112 | +Result: red wireframe sphere |
| 113 | +API: vtkSphere.computeBoundingSphere(points)`, |
| 114 | + scene2: `Input: green spheres |
| 115 | +Result: orange wireframe sphere |
| 116 | +API: vtkSphere.computeBoundingSphereFromSpheres(spheres)`, |
| 117 | +}; |
| 118 | + |
| 119 | +const gui = new GUI({ title: 'Controls' }); |
| 120 | + |
| 121 | +function addReadOnlyTextArea(folder, object, key, label) { |
| 122 | + const controller = folder.add(object, key).name(label).listen().disable(); |
| 123 | + controller.domElement.style.display = 'block'; |
| 124 | + controller.domElement.style.minHeight = 'auto'; |
| 125 | + const nameEl = controller.domElement.querySelector('.name'); |
| 126 | + const widgetEl = controller.domElement.querySelector('.widget'); |
| 127 | + if (nameEl) { |
| 128 | + nameEl.style.width = '100%'; |
| 129 | + nameEl.style.paddingBottom = '4px'; |
| 130 | + } |
| 131 | + if (widgetEl) { |
| 132 | + widgetEl.style.width = '100%'; |
| 133 | + } |
| 134 | + const input = controller.domElement.querySelector('input'); |
| 135 | + if (input && input.parentElement) { |
| 136 | + const textArea = document.createElement('textarea'); |
| 137 | + textArea.value = String(object[key]); |
| 138 | + textArea.readOnly = true; |
| 139 | + textArea.rows = 5; |
| 140 | + textArea.style.width = '100%'; |
| 141 | + textArea.style.resize = 'none'; |
| 142 | + textArea.style.fontFamily = 'monospace'; |
| 143 | + textArea.style.fontSize = '11px'; |
| 144 | + input.parentElement.replaceChild(textArea, input); |
| 145 | + } |
| 146 | + return controller; |
| 147 | +} |
| 148 | + |
| 149 | +addReadOnlyTextArea(gui, sceneGuide, 'scene1', 'Left scene'); |
| 150 | +addReadOnlyTextArea(gui, sceneGuide, 'scene2', 'Right scene'); |
0 commit comments