React-app - Building volume rendering web app with VTK.js,react & HTML Using datasets provided in vtk examples (head for surface rendering and chest for ray casting)

Related tags

React react-app
Overview

SBE306 Assignment 4 (VTK)

  • data : Directory containing Head and Ankle datasets

Description

A 3D medical viewer built with vtk-js

Team

Team Name : team-22-final

Team Members

Name Section BN
Mustafa Megahed gamil 2 31
Mahmoud Mohamed Mahmoud Ahmed 2 23
Ahmed Hossam Eldeen 1 6
Hamza Jamal ALshaikh 1 27

Table of content

1. Task Objectives
2. Description
3. Features in our web app
4. Issues
5. code snippet
6. Conclusion

Task Objectives

The main target of this project is: Loading vtk.js Example

● Surface rendering
● Ray casting rendering
● Interactive widgets
● Preset controlling
● Web GUI application

Description

Building volume rendering web app with VTK.js,react & HTML Using datasets provided in vtk examples (head for surface rendering and chest for ray casting)

Features in our web app

● making two button in a (div) to switch between two example,button for skull &button for a chest
● bulding Surface rendering with adjustable iso value with a slidder in skull Example
● Adding Ray casting rendering (with a fixed transfer function) & interactive widget to cut the volume in the three perpendicular planes in a chest Example

Issues

Issue Solution
faced some problems in running example such as loading data replace ${BASE_PATH} in reader function with https://kitware.github.io/vtk-js
faced problems in all imports replace vtk.js/Sources with @kitware/vtk.js
switching between the two examples was dificult making two files (one for head and other for chest) , creating a main App and donig two button in a retrun html and linking them with a function that we have import from two files

code snippet

first We make code snippet in main app we make two button one for chest and on for skull in return HTML

  <button style={{width:"150px"}} onClick={clickhead}>Skull</button>
  <button style={{width:"150px"}} onClick={clickchest}>Chest</button> 
    
      );

import two file (chest.js,head.js)

import head from './head';
import Chest from './chest';

making two click function one for chest and the other for head to caling the in the two buttons

const clickchest =()=>{
    chest()
  }
  const clickhead =()=>{
    head()
  }

using zindex in to overlap the black widget in the return html in main app

  return (
    <div style={{
      zIndex:"2", 
      position: "relative"
  }}>

in chest file

we using margin to translate the container of transfer function

widgetContainer.style.marginLeft='1050px';

get transfer function from PiecewiseGaussianWidget example in vtk.js datasets and put it in the ImageCroppingWidget example and linking them


  //----------------transfer function-----------------------///
//////////////////////////////////////////////////////////////////////////////////
const rootContainer = document.querySelector(
  '.vtk-js-example-piecewise-gaussian-widget2'
);
const containerStyle = rootContainer ? { height: '100%' } : null;
const urlToLoad = rootContainer
  ? rootContainer.dataset.url ||
    'https://kitware.github.io/vtk-js/data/volume/LIDC2.vti'
  : `https://kitware.github.io/vtk-js/data/volume/LIDC2.vti`;




// ----------------------------------------------------------------------------
// Example code
// ----------------------------------------------------------------------------

const body = rootContainer || document.querySelector('body');

// Create Widget container
const widgetContainer = document.createElement('div');
widgetContainer.style.position = 'absolute';
widgetContainer.style.top = 'calc(10px + 1em)';
widgetContainer.style.left = '5px';
widgetContainer.style.background = 'rgba(255, 255, 255, 0.3)';
widgetContainer.style.marginLeft='1050px';
body.appendChild(widgetContainer);

// Create Label for preset
const labelContainer = document.createElement('div');
labelContainer.style.position = 'absolute';
labelContainer.style.top = '5px';
labelContainer.style.left = '5px';
labelContainer.style.width = '100%';
labelContainer.style.color = 'white';
labelContainer.style.textAlign = 'center';
labelContainer.style.userSelect = 'none';
labelContainer.style.cursor = 'pointer';
labelContainer.style.marginTop='100px';
body.appendChild(labelContainer);

let presetIndex = 1;
const globalDataRange = [0, 255];
const lookupTable = vtkColorTransferFunction.newInstance();

function changePreset(delta = 1) {
  presetIndex =
    (presetIndex + delta + vtkColorMaps.rgbPresetNames.length) %
    vtkColorMaps.rgbPresetNames.length;
  lookupTable.applyColorMap(
    vtkColorMaps.getPresetByName(vtkColorMaps.rgbPresetNames[presetIndex])
  );
  lookupTable.setMappingRange(...globalDataRange);
  lookupTable.updateRange();
  labelContainer.innerHTML = vtkColorMaps.rgbPresetNames[presetIndex];
}

let intervalID = null;
function stopInterval() {
  if (intervalID !== null) {
    clearInterval(intervalID);
    intervalID = null;
  }
}

labelContainer.addEventListener('click', (event) => {
  if (event.pageX < 200) {
    stopInterval();
    changePreset(-1);
  } else {
    stopInterval();
    changePreset(1);
  }
});

// ----------------------------------------------------------------------------
// Example code
// ----------------------------------------------------------------------------

const widget2 = vtkPiecewiseGaussianWidget.newInstance({
  numberOfBins: 256,
  size: [400, 150],
});
widget2.updateStyle({
  backgroundColor: 'rgba(255, 255, 255, 0.6)',
  histogramColor: 'rgba(100, 100, 100, 0.5)',
  strokeColor: 'rgb(0, 0, 0)',
  activeColor: 'rgb(255, 255, 255)',
  handleColor: 'rgb(50, 150, 50)',
  buttonDisableFillColor: 'rgba(255, 255, 255, 0.5)',
  buttonDisableStrokeColor: 'rgba(0, 0, 0, 0.5)',
  buttonStrokeColor: 'rgba(0, 0, 0, 1)',
  buttonFillColor: 'rgba(255, 255, 255, 1)',
  strokeWidth: 2,
  activeStrokeWidth: 3,
  buttonStrokeWidth: 1.5,
  handleWidth: 3,
  iconSize: 20, // Can be 0 if you want to remove buttons (dblClick for (+) / rightClick for (-))
  padding: 10,
  
});

fullScreenRenderer.setResizeCallback(({ width, height }) => {
  widget2.setSize(Math.min(450, width - 10), 150);
});

const piecewiseFunction = vtkPiecewiseFunction.newInstance();

// const actor = vtkVolume.newInstance();
// const mapper = vtkVolumeMapper.newInstance({ sampleDistance: 1.1 });
// const reader = vtkHttpDataSetReader.newInstance({ fetchGzip: true });

reader.setUrl(urlToLoad).then(() => {
  reader.loadData().then(() => {
    const imageData = reader.getOutputData();
    const dataArray = imageData.getPointData().getScalars();
    const dataRange = dataArray.getRange();
    globalDataRange[0] = dataRange[0];
    globalDataRange[1] = dataRange[1];

    // Update Lookup table
    changePreset();

    // Automatic switch to next preset every 5s
    if (!rootContainer) {
      intervalID = setInterval(changePreset, 5000);
    }

    widget2.setDataArray(dataArray.getData());
    widget2.applyOpacity(piecewiseFunction);

    widget2.setColorTransferFunction(lookupTable);
    lookupTable.onModified(() => {
      widget2.render();
      renderWindow.render();
    });

    renderer.addVolume(actor);
    renderer.resetCamera();
    renderer.getActiveCamera().elevation(70);
    renderWindow.render();
  });
});

actor.setMapper(mapper);
mapper.setInputConnection(reader.getOutputPort());

actor.getProperty().setRGBTransferFunction(0, lookupTable);
actor.getProperty().setScalarOpacity(0, piecewiseFunction);
actor.getProperty().setInterpolationTypeToFastLinear();

// ----------------------------------------------------------------------------
// Default setting Piecewise function widget
// ----------------------------------------------------------------------------

widget2.addGaussian(0.425, 0.5, 0.2, 0.3, 0.2);
widget2.addGaussian(0.75, 1, 0.3, 0, 0);

widget2.setContainer(widgetContainer);
widget2.bindMouseListeners();

widget2.onAnimation((start) => {
  if (start) {
    renderWindow.getInteractor().requestAnimation(widget2);
  } else {
    renderWindow.getInteractor().cancelAnimation(widget2);
  }
});

widget2.onOpacityChange(() => {
  widget2.applyOpacity(piecewiseFunction);
  if (!renderWindow.getInteractor().isAnimating()) {
    renderWindow.render();
  }
});

Conclusion

develop web app and this video illusrate it

Video GIf

ezgif.com-gif-maker_2.mp4
You might also like...

This hook allows you to isolate and manage the state within the component, reducing rendering operations and keeping the source code concise.

React Hook Component State This hook allows you to isolate and manage the state within the component, reducing rendering operations and keeping the so

May 15, 2022

⚛️ Hooks for building fast and extendable tables and datagrids for React

⚛️ Hooks for building fast and extendable tables and datagrids for React

Hooks for building lightweight, fast and extendable datagrids for React Enjoy this library? Try them all! React Query, React Form, React Charts Visit

Jan 3, 2023

Accessible, unstyled, open-sourced, and fully functional react component library for building design systems

DORAI UI Accessible, unstyled, open-sourced and fully functional react component library for building design systems Documentation site coming soon St

Dec 30, 2022

Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js.

Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js.

Onsen UI - Cross-Platform Hybrid App and PWA Framework Onsen UI is an open source framework that makes it easy to create native-feeling Progressive We

Jan 8, 2023

A collection of composable React components for building interactive data visualizations

A collection of composable React components for building interactive data visualizations

an ecosystem of composable React components for building interactive data visualizations. Victory Contents Getting Started Victory Native API Document

Jan 3, 2023

The best JavaScript Data Table for building Enterprise Applications. Supports React / Angular / Vue / Plain JavaScript.

The best JavaScript Data Table for building Enterprise Applications. Supports React / Angular / Vue / Plain JavaScript.

Module SonarCloud Status ag-grid-community ag-grid-enterprise AG Grid AG Grid is a fully-featured and highly customizable JavaScript data grid. It del

Dec 30, 2022

The repository helps you learn React by building Netflix :star:

The repository helps you learn React by building Netflix :star:

Learn React by Building Netflix. Click ⭐ if you like the project. Pull Request are highly appreciated ❤️ You can check the advance folder for more Rea

Dec 22, 2022

Light-weight react-like maximum-optimistic library for building user interfaces.

wili Wili is a 2kb Light-weight react-like maximum-optimistic library for building user interfaces. Usage Welcome componenet: class Welcome extends Wi

Feb 16, 2022

IngredientRecipeFinder - Web app built with react using Edamam API to find any recipe for an ingredient search with nutrition filters (high protein, low carb,etc)

Ingredient Recipe Finder Web app This web app built with the use of Edamam API allows you to find any type of recipe for a specific ingredient you are

Jan 4, 2022
Owner
Mustafa Megahed
Student at SBME Department in Faculty Of Engineering Cairo Unversity
Mustafa Megahed
Recipe providing mobile app, User selects ingredients in pantry and is then provided recipes for those ingredients. App contains a signup/login, meal planner and grocery list pages.

Recipog Student Information Name Connor de Bruyn Username Destiro Assignment SWEN325 A2 Description “Recipog” is a recipe providing app that allows th

Connor de Bruyn 1 Dec 26, 2021
Very simple app to decode your Vaccination Proof QR Code (such as the one provided by government of Quebec) - Compatible with SHC (Smart Health Card standard)

shc-covid19-decoder Visit simple hosted version on your phone (does NOT transmit any data, all remains in your browser) https://fproulx.github.io/shc-

François Proulx 148 Sep 23, 2022
Examples of Solidity++ contracts

soliditypp-examples Examples of Solidity++ 0.8.0 / 0.8.1. This is a preview version. DO NOT use it in production environment. Getting Started npm inst

Vite Labs 8 Sep 18, 2022
Finished code and notes from EFA bonus class on building a React project without create-react-app

React From Scratch Completed Code This is the completed code for the EFA bonus class on building a React project from scratch. Included are also markd

Conor Broaders 3 Oct 11, 2021
A frontend Framework for building B2B applications running in the browser on top of REST/GraphQL APIs, using ES6, React and Material Design

react-admin A frontend Framework for building data-driven applications running in the browser on top of REST/GraphQL APIs, using ES6, React and Materi

marmelab 21.2k Dec 30, 2022
React components for efficiently rendering large lists and tabular data

React components for efficiently rendering large lists and tabular data. Check out the demo for some examples. Sponsors The following wonderful compan

Brian Vaughn 24.5k Jan 7, 2023
React components for efficiently rendering large lists and tabular data

react-window React components for efficiently rendering large lists and tabular data React window works by only rendering part of a large data set (ju

Brian Vaughn 13.5k Jan 4, 2023
A simple project showing the usage of useState, useEffect and conditional rendering in React

Getting Started with Tour-sample React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can ru

Amaechi johnkingsley 1 Jul 30, 2022
Boilerplate to get started building React-based interfaces for Crestron using CH5

Getting Started with Crestron UI This project was bootstrapped with Create React App. Example component communicating with the Crestron-CH5 library: i

Mukund Salia 3 Apr 25, 2022
This is a challenge intiated by ModelSis. It consists in building a basic fullstack web app

modelsis-react-fullstack ?? Description This is a challenge intiated by ModelSis. It consists in building a basic fullstack web app. The current repos

Régis 1 Jan 21, 2022