UNPKG

@edsilv/ami.js

Version:

<p align="center"> <img src="https://user-images.githubusercontent.com/214063/46479857-4cd66e80-c7f0-11e8-9585-5748409c9490.png" width="60%"> </p>

299 lines (259 loc) 8.77 kB
/* globals Stats, dat*/ import ControlsTrackball from 'base/controls/controls.trackball'; import HelpersStack from 'base/helpers/helpers.stack'; import LoadersVolume from 'base/loaders/loaders.volume'; import WidgetsAnnotation from 'base/widgets/widgets.annotation'; import WidgetsAngle from 'base/widgets/widgets.angle'; import WidgetsBiRuler from 'base/widgets/widgets.biruler'; import WidgetsCrossRuler from 'base/widgets/widgets.crossRuler'; import WidgetsEllipse from 'base/widgets/widgets.ellipse'; import WidgetsFreehand from 'base/widgets/widgets.freehand'; import WidgetsHandle from 'base/widgets/widgets.handle'; import WidgetsPolygon from 'base/widgets/widgets.polygon'; import WidgetsRectangle from 'base/widgets/widgets.rectangle'; import WidgetsRuler from 'base/widgets/widgets.ruler'; import WidgetsVoxelProbe from 'base/widgets/widgets.voxelProbe'; // standard global variables let controls; let renderer; let threeD; let stats; let scene; let camera; let offsets; let widgets = []; const widgetsAvailable = [ 'Handle', 'VoxelProbe', 'Ruler', 'BiRuler', 'CrossRuler', 'Angle', 'Rectangle', 'Ellipse', 'Polygon', 'Freehand', 'Annotation', ]; const guiObjects = { type: 'Handle', }; function render() { // render controls.update(); renderer.render(scene, camera); stats.update(); } function init() { // this function is executed on each animation frame function animate() { render(); // request new frame requestAnimationFrame(function() { animate(); }); } // renderer threeD = document.getElementById('r3d'); renderer = new THREE.WebGLRenderer({ antialias: true, }); renderer.setSize(threeD.offsetWidth, threeD.offsetHeight); renderer.setClearColor(0xffffff, 1); threeD.appendChild(renderer.domElement); // stats stats = new Stats(); threeD.appendChild(stats.domElement); // scene scene = new THREE.Scene(); // camera camera = new THREE.PerspectiveCamera(45, threeD.offsetWidth / threeD.offsetHeight, 1, 10000000); camera.position.x = 150; camera.position.y = 50; camera.position.z = 50; // controls controls = new ControlsTrackball(camera, threeD); controls.rotateSpeed = 1.4; controls.zoomSpeed = 1.2; controls.panSpeed = 0.8; controls.staticMoving = true; controls.dynamicDampingFactor = 0.3; camera.controls = controls; animate(); } window.onload = function() { // init threeJS... init(); const file = 'https://cdn.rawgit.com/FNNDSC/data/master/dicom/adi_brain/36749894'; const loader = new LoadersVolume(threeD); // Start off with a promise that always resolves loader.load(file).then(series => { const stack = series[0]._stack[0]; loader.free(); let stackHelper = new HelpersStack(stack); scene.add(stackHelper); threeD.addEventListener('mouseup', function() { // if something hovered, exit for (let widget of widgets) { if (widget.active) { widget.onEnd(); return; } } }); threeD.addEventListener('mousemove', function(evt) { // if something hovered, exit let cursor = 'default'; for (let widget of widgets) { widget.onMove(evt); if (widget.hovered) { cursor = 'pointer'; } } threeD.style.cursor = cursor; }); threeD.addEventListener('mousedown', function(evt) { // if something hovered, exit for (let widget of widgets) { if (widget.hovered) { widget.onStart(evt); return; } } threeD.style.cursor = 'default'; // mouse position let mouse = { x: ((evt.clientX - offsets.left) / threeD.offsetWidth) * 2 - 1, y: -((evt.clientY - offsets.top) / threeD.offsetHeight) * 2 + 1, }; // update the raycaster let raycaster = new THREE.Raycaster(); raycaster.setFromCamera(mouse, camera); let intersects = raycaster.intersectObject(stackHelper.slice.mesh); if (intersects.length <= 0) { return; } let widget = null; switch (guiObjects.type) { case 'VoxelProbe': widget = new WidgetsVoxelProbe(stackHelper.slice.mesh, controls, { stack: stack, worldPosition: intersects[0].point, }); break; case 'Ruler': widget = new WidgetsRuler(stackHelper.slice.mesh, controls, { lps2IJK: stack.lps2IJK, pixelSpacing: stack.frame[stackHelper.index].pixelSpacing, ultrasoundRegions: stack.frame[stackHelper.index].ultrasoundRegions, worldPosition: intersects[0].point, }); break; case 'CrossRuler': widget = new WidgetsCrossRuler(stackHelper.slice.mesh, controls, { lps2IJK: stack.lps2IJK, pixelSpacing: stack.frame[stackHelper.index].pixelSpacing, ultrasoundRegions: stack.frame[stackHelper.index].ultrasoundRegions, }); break; case 'BiRuler': widget = new WidgetsBiRuler(stackHelper.slice.mesh, controls, { lps2IJK: stack.lps2IJK, pixelSpacing: stack.frame[stackHelper.index].pixelSpacing, ultrasoundRegions: stack.frame[stackHelper.index].ultrasoundRegions, worldPosition: intersects[0].point, }); break; case 'Angle': widget = new WidgetsAngle(stackHelper.slice.mesh, controls, { worldPosition: intersects[0].point, }); break; case 'Rectangle': widget = new WidgetsRectangle(stackHelper.slice.mesh, controls, { frameIndex: stackHelper.index, stack: stack, worldPosition: intersects[0].point, }); break; case 'Ellipse': widget = new WidgetsEllipse(stackHelper.slice.mesh, controls, { frameIndex: stackHelper.index, stack: stack, worldPosition: intersects[0].point, }); break; case 'Polygon': widget = new WidgetsPolygon(stackHelper.slice.mesh, controls, { frameIndex: stackHelper.index, stack: stack, worldPosition: intersects[0].point, }); break; case 'Freehand': widget = new WidgetsFreehand(stackHelper.slice.mesh, controls, { frameIndex: stackHelper.index, stack: stack, worldPosition: intersects[0].point, }); break; case 'Annotation': widget = new WidgetsAnnotation(stackHelper.slice.mesh, controls, { worldPosition: intersects[0].point, }); break; case 'Handle': default: widget = new WidgetsHandle(stackHelper.slice.mesh, controls, { worldPosition: intersects[0].point, }); } widgets.push(widget); scene.add(widget); }); function onWindowResize() { camera.aspect = threeD.clientWidth / threeD.clientHeight; camera.updateProjectionMatrix(); renderer.setSize(threeD.clientWidth, threeD.clientHeight); // update offset const box = threeD.getBoundingClientRect(); const body = document.body; const docEl = document.documentElement; const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft; const clientTop = docEl.clientTop || body.clientTop || 0; const clientLeft = docEl.clientLeft || body.clientLeft || 0; const top = box.top + scrollTop - clientTop; const left = box.left + scrollLeft - clientLeft; offsets = { top: Math.round(top), left: Math.round(left), }; // repaint all widgets for (let widget of widgets) { widget.update(); } } window.addEventListener('resize', onWindowResize, false); onWindowResize(); // const centerLPS = stack.worldCenter(); camera.lookAt(centerLPS.x, centerLPS.y, centerLPS.z); controls.target.set(centerLPS.x, centerLPS.y, centerLPS.z); camera.updateProjectionMatrix(); const gui = new dat.GUI({ autoPlace: false, }); const widgetFolder = gui.addFolder('Widget'); widgetFolder.add(guiObjects, 'type', widgetsAvailable); widgetFolder.open(); const customContainer = document.getElementById('my-gui-container'); customContainer.appendChild(gui.domElement); // force first render render(); // notify puppeteer to take screenshot const puppetDiv = document.createElement('div'); puppetDiv.setAttribute('id', 'puppeteer'); document.body.appendChild(puppetDiv); }); };