Skip to content

Commit

Permalink
feat(vtkGCodeReader): add vtkGCodeReader
Browse files Browse the repository at this point in the history
Fixes #3149
  • Loading branch information
Adnane Belmadiaf committed Oct 20, 2024
1 parent 4691eea commit 643aefa
Show file tree
Hide file tree
Showing 7 changed files with 539 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions Documentation/content/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ This will allow you to see the some live code running in your browser. Just pick
[![HttpDataSetSeriesReader Example][HttpDataSetSeriesReaderWithIcon]](./HttpDataSetSeriesReader.html "Import a VTK dataset with time support.")
[![HttpSceneLoader Example][HttpSceneLoaderWithIcon]](./HttpSceneLoader.html "Import a VTK scene (data + representation)")
[![OfflineLocalView Example][OfflineLocalViewWithIcon]](./OfflineLocalView.html "Load a serialized scene (VTKSZ)")
[![G-Code Example][GCodeReaderWithIcon]](./GCodeReader.html "G-Code reader(gcode)")

</div>

Expand All @@ -203,6 +204,7 @@ This will allow you to see the some live code running in your browser. Just pick
[HttpDataSetSeriesReaderWithIcon]: ../docs/gallery/HttpDataSetSeriesReaderWithIcon.gif
[HttpSceneLoaderWithIcon]: ../docs/gallery/HttpSceneLoaderWithIcon.jpg
[OfflineLocalViewWithIcon]: ../docs/gallery/OfflineLocalViewWithIcon.jpg
[GCodeReaderWithIcon]: ../docs/gallery/GCodeReaderWithIcon.jpg

# Actors

Expand Down
13 changes: 13 additions & 0 deletions Sources/IO/Misc/GCodeReader/example/controller.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<table>
<tr>
<td colspan="2">
<h3 style="margin: 5px 0;">Options</h3>
</td>
</tr>
<tr>
<td class="label">Layers: </td>
<td>
<input type="range" class="layers" id="layers" min="0" max="0" value="0" step="1" style="width: 100%;" />
</td>
</tr>
</table>
137 changes: 137 additions & 0 deletions Sources/IO/Misc/GCodeReader/example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import '@kitware/vtk.js/favicon';

// Load the rendering pieces we want to use (for both WebGL and WebGPU)
import '@kitware/vtk.js/Rendering/Profiles/Geometry';

import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
import vtkGCodeReader from '@kitware/vtk.js/IO/Misc/GCodeReader';

import controlPanel from './controller.html';

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

let renderer = null;
let renderWindow = null;
let layersSelector = null;
let layersLabel = null;

const reader = vtkGCodeReader.newInstance();

// ----------------------------------------------------------------------------

function hslToRgb(h, s, l) {
let r;
let g;
let b;

if (s === 0) {
r = l;
g = l;
b = l;
} else {
const hue2rgb = (p, q, t) => {
let tMod = t;
if (tMod < 0) tMod += 1;
if (tMod > 1) tMod -= 1;
if (tMod < 1 / 6) return p + (q - p) * 6 * tMod;
if (tMod < 1 / 2) return q;
if (tMod < 2 / 3) return p + (q - p) * (2 / 3 - tMod) * 6;
return p;
};

const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}

return [r, g, b];
}

function refresh() {
if (renderer && renderWindow) {
renderer.resetCamera();
renderWindow.render();
}
}

function update() {
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance();
fullScreenRenderer.addController(controlPanel);
layersSelector = document.querySelector('.layers');
layersLabel = document.querySelector('.label');
renderer = fullScreenRenderer.getRenderer();
renderWindow = fullScreenRenderer.getRenderWindow();
const numLayers = reader.getNumberOfOutputPorts();

layersLabel.innerHTML = `Layers(${numLayers}):`;
layersSelector.max = numLayers.toString();
layersSelector.value = numLayers.toString();

const actors = [];

for (let idx = 1; idx < numLayers; idx++) {
const polyData = reader.getOutputData(idx);
if (polyData) {
const mapper = vtkMapper.newInstance();
mapper.setInputData(polyData);

const actor = vtkActor.newInstance();
actor.setMapper(mapper);

const hue = (idx / numLayers) * 0.8; // Use 0.8 instead of 1.0 to avoid red wrapping
actor.getProperty().setColor(...hslToRgb(hue, 1, 0.5));
actor.rotateX(-90);

actors.push(actor);
}
}

layersSelector.addEventListener('input', (event) => {
const visibleLayers = parseInt(event.target.value, 10);
actors.forEach((actor, index) => {
actor.setVisibility(index < visibleLayers);
});
renderWindow.render();
});

actors.forEach((actor) => renderer.addActor(actor));
refresh();
}

// ----------------------------------------------------------------------------
// Use a file reader to load a local file
// ----------------------------------------------------------------------------

const myContainer = document.querySelector('body');
const fileContainer = document.createElement('div');
fileContainer.innerHTML =
'<div>Select a gcode file.<br/><input type="file" class="file"/></div>';
myContainer.appendChild(fileContainer);

const fileInput = fileContainer.querySelector('input');

function handleFile(event) {
event.preventDefault();
const dataTransfer = event.dataTransfer;
const files = event.target.files || dataTransfer.files;
myContainer.removeChild(fileContainer);
const fileReader = new FileReader();
fileReader.onload = function onLoad(e) {
reader.parse(fileReader.result);
update();
};
fileReader.readAsArrayBuffer(files[0]);
}

fileInput.addEventListener('change', handleFile);

// ----------------------------------------------------------------------------
// Use the reader to download a file
// ----------------------------------------------------------------------------
// reader.setUrl(`${__BASE_PATH__}/data/gcode/cube.gcode`, { binary: true }).then(update);
128 changes: 128 additions & 0 deletions Sources/IO/Misc/GCodeReader/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { vtkAlgorithm, vtkObject } from '../../../interfaces';
import HtmlDataAccessHelper from '../../Core/DataAccessHelper/HtmlDataAccessHelper';
import HttpDataAccessHelper from '../../Core/DataAccessHelper/HttpDataAccessHelper';
import JSZipDataAccessHelper from '../../Core/DataAccessHelper/JSZipDataAccessHelper';
import LiteHttpDataAccessHelper from '../../Core/DataAccessHelper/LiteHttpDataAccessHelper';

interface IGCodeReaderOptions {
binary?: boolean;
compression?: string;
progressCallback?: any;
}

/**
*
*/
export interface IGCodeReaderInitialValues {}

type vtkGCodeReaderBase = vtkObject &
Omit<
vtkAlgorithm,
| 'getInputData'
| 'setInputData'
| 'setInputConnection'
| 'getInputConnection'
| 'addInputConnection'
| 'addInputData'
>;

export interface vtkGCodeReader extends vtkGCodeReaderBase {
/**
*
*/
getBaseURL(): string;

/**
*
*/
getDataAccessHelper():
| HtmlDataAccessHelper
| HttpDataAccessHelper
| JSZipDataAccessHelper
| LiteHttpDataAccessHelper;

/**
* Get the url of the object to load.
*/
getUrl(): string;

/**
* Load the object data.
* @param {IGCodeReaderOptions} [options]
*/
loadData(options?: IGCodeReaderOptions): Promise<any>;

/**
* Parse data.
* @param {String | ArrayBuffer} content The content to parse.
*/
parse(content: string | ArrayBuffer): void;

/**
* Parse data as ArrayBuffer.
* @param {ArrayBuffer} content The content to parse.
*/
parseAsArrayBuffer(content: ArrayBuffer): void;

/**
* Parse data as text.
* @param {String} content The content to parse.
*/
parseAsText(content: string): void;

/**
*
* @param inData
* @param outData
*/
requestData(inData: any, outData: any): void;

/**
*
* @param dataAccessHelper
*/
setDataAccessHelper(
dataAccessHelper:
| HtmlDataAccessHelper
| HttpDataAccessHelper
| JSZipDataAccessHelper
| LiteHttpDataAccessHelper
): boolean;

/**
* Set the url of the object to load.
* @param {String} url the url of the object to load.
* @param {IGCodeReaderOptions} [option] The PLY reader options.
*/
setUrl(url: string, option?: IGCodeReaderOptions): Promise<string | any>;
}

/**
* Method used to decorate a given object (publicAPI+model) with vtkGCodeReader characteristics.
*
* @param publicAPI object on which methods will be bounds (public)
* @param model object on which data structure will be bounds (protected)
* @param {IGCodeReaderInitialValues} [initialValues] (default: {})
*/
export function extend(
publicAPI: object,
model: object,
initialValues?: IGCodeReaderInitialValues
): void;

/**
* Method used to create a new instance of vtkGCodeReader
* @param {IGCodeReaderInitialValues} [initialValues] for pre-setting some of its content
*/
export function newInstance(
initialValues?: IGCodeReaderInitialValues
): vtkGCodeReader;

/**
* vtkGCodeReader is a source object that reads a GCODE file.
*/
export declare const vtkGCodeReader: {
newInstance: typeof newInstance;
extend: typeof extend;
};
export default vtkGCodeReader;
Loading

0 comments on commit 643aefa

Please sign in to comment.