# ICR PolySeg-WASM: a WASM module that implements PolySeg for the Web

## Introduction
The ICR PolySeg-WASM is an extended WASM wrapper for the [PerkLab/PolySeg](https://github.com/PerkLab/PolySeg) library, including C++ code repurposed from [Slicer](https://github.com/Slicer/Slicer) and [SlicerRT](https://github.com/SlicerRt/SlicerRT).

### Supported conversions
* Planar contour to closed surface &rarr; `convertContourRoiToSurface`.
* Planar contour to labelmap &rarr; `convertContourRoiToLabelmap`.
* Surface to labelmap &rarr; `convertSurfaceToLabelmap`.
* Labelmap to closed surface (using flying edges) &rarr; `convertLabelmapToSurface`.
* Contour to Ribbon  &rarr; `convertContourRoiToRibbon`.
* Ribbon to Labelmap  &rarr; `convertRibbonToLabelmap`.


### Issues and feature requests
This project is under active development. Please report issues [here](https://bitbucket.org/icrimaginginformatics/polyseg-wasm/issues).

## Installation
```bash
$ npm install @icr/polyseg-wasm
or
$ yarn add @icr/polyseg-wasm
```

## Usage
* Use the provided [index.js](./src/index.js) script to load the wasm module
    ```js
    import ICRPolySeg from '@icr/polyseg-wasm';
    const icrPolySeg = await ICRPolySeg();
    // Initialize the module and optionally pass a callback for progress updates
    await icrPolySeg.initialize(/*{ updateProgress: updateProgressThrottled }*/);
    // Use the initialized 'instance' to invoke a conversion method
    const instance = icrPolySeg.instance;
    ```

* Or, manually import the launcher and wasm to load the module
    ```js
    import launcher from '@icr/polyseg-wasm/js';
    import wasm from '@icr/polyseg-wasm/wasm';
    // Initialize the module according to your project configuration
    ...
    ```

### Usage example for planar contour to closed surface conversion
```js
import ICRPolySeg from '@icr/polyseg-wasm';

// Initialize the module and optionally pass a callback for progress updates
const icrPolySeg = await ICRPolySeg();
await icrPolySeg.initialize(/*{ updateProgress: updateProgressThrottled }*/);

// Assuming that an ROI consists of C contours with each contour having an array of points (xyz coordinate tuples)
// Extract and join the ponints from all contours
let flatPointsArray = [];
let numPointsArray = [];
for (let c = 0; c < roi.contours.length; c++) {
    const points = roi.contours[c].points;
    numPointsArray.push(points.length);
    for (let p = 0; p < points.length; p++) {
        const point = points[p];
        flatPointsArray.push(point.x, point.y, point.z);
    }
}
// Use Float32 typed array
flatPointsArray = new Float32Array(flatPointsArray)
numPointsArray = new Float32Array(numPointsArray)

// Run the conversion using the initialized 'instance'
const result = icrPolySeg.instance.convertContourRoiToSurface(flatPointsArray, numPointsArray);

// Create a VTK mesh from the result
const polydata = vtkPolyData.newInstance();
polydata.getPoints().setData(result.points, 3);
polydata.getPolys().setData(result.polys);

```

## Examples
To run and view the examples:
```bash
$ $ git clone https://bitbucket.org/icrimaginginformatics/polyseg-wasm.git
$ cd polyseg-wasm/examples
$ yarn install
$ yarn run start
```

## Development
* Clone polyseg-wasm
    ```bash
    $ git clone https://bitbucket.org/icrimaginginformatics/polyseg-wasm.git
    ```
* Pull `kitware/vtk-wasm` Docker image
    ```bash
    $ docker pull kitware/vtk-wasm:v9.2.6-2743-gdcc0ce36db-20230312
    ```

* Run `build.sh`:
    ```bash
    $ cd polyseg-wasm
    $ ./build.sh
    ```
* If you have trouble running `build.sh`, please execute this command `chmod +x build.sh` and `chmod +x build_wasm.sh` to allow the shell scripts to excute in your machine.
