1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import anywidget import traitlets from traitlets import List, Any from pathlib import Path import numpy as np import scipy.ndimage import ipywidgets as widgets from IPython.display import display grids = 2 boxs = 5 voxelarray = np.zeros((boxs * grids, boxs * grids, boxs * grids)) i = 1 for xi in range(0, 2): for yi in range(0, 2): for zi in range(0, 2): voxelarray[ xi * boxs : xi * boxs + boxs, yi * boxs : yi * boxs + boxs, zi * boxs : zi * boxs + boxs, ] = i i += 1 voxelarray = np.uint8(voxelarray * 255 / i) class HelloWidget(anywidget.AnyWidget): _esm = Path("widget.js") count = traitlets.Int(0).tag(sync=True) voxel_data = List(List(List(Any()))).tag(sync=True) # Initialize the widget first three_viewer = HelloWidget() # Then set the voxel data voxel_data_list = voxelarray.tolist() three_viewer.voxel_data = voxel_data_list # Create and display the slider sigma_slider = widgets.FloatSlider(value=0.1, min=0, max=4, step=0.01, description='Sigma:') def apply_gaussian_filter(sigma): voxelarrayX = scipy.ndimage.gaussian_filter(voxelarray, sigma=sigma) voxel_data_list = voxelarrayX.tolist() three_viewer.voxel_data = voxel_data_list print(f"Applied Gaussian filter with sigma: {sigma}") def on_slider_change(change): apply_gaussian_filter(change['new']) sigma_slider.observe(on_slider_change, names='value') # Display the widgets together w = widgets.VBox([sigma_slider, three_viewer]) display(w) page = w
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import * as THREE from "https://esm.sh/three"; import { OrbitControls } from "https://esm.sh/three/examples/jsm/controls/OrbitControls.js"; function render({ model, el }) { let container = document.createElement("div"); container.style.height = "500px"; container.style.width = "500px"; el.appendChild(container); const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, container.clientWidth / container.clientHeight, 0.1, 1000 ); camera.position.z = 15; const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(container.clientWidth, container.clientHeight); container.appendChild(renderer.domElement); const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.05; controls.screenSpacePanning = false; controls.minDistance = 5; controls.maxDistance = 50; function getColor(value) { const minColor = new THREE.Color("yellow"); const maxColor = new THREE.Color("red"); return minColor.lerp(maxColor, value / 255); } function drawVoxels(data) { const offsetX = data.length / 2; const offsetY = data[0].length / 2; const offsetZ = data[0][0].length / 2; const geometry = new THREE.BoxGeometry(); for (let x = 0; x < data.length; x++) { for (let y = 0; y < data[x].length; y++) { for (let z = 0; z < data[x][y].length; z++) { if (data[x][y][z] > 0) { const color = getColor(data[x][y][z]); const material = new THREE.MeshBasicMaterial({ color }); const cube = new THREE.Mesh(geometry, material); cube.position.set(x - offsetX, y - offsetY, z - offsetZ); scene.add(cube); } } } } } function clearScene() { scene.children.forEach((child) => { if (child instanceof THREE.Mesh) { child.geometry.dispose(); child.material.dispose(); scene.remove(child); } }); } function animate() { requestAnimationFrame(animate); // Add constant rotation scene.rotation.y += 0.01; // Adjust the speed as needed controls.update(); renderer.render(scene, camera); } // Initial draw setTimeout(() => { const data = model.get("voxel_data"); drawVoxels(data); }, 1000); // Adjust the timeout duration as needed model.on("change:voxel_data", () => { clearScene(); const newData = model.get("voxel_data"); drawVoxels(newData); }); animate(); } export default { render };