src/worker/SurfaceExtractor.js
import { DualContouring } from "../isosurface/dual-contouring/DualContouring";
import { SparseVoxelOctree } from "../octree/voxel/SparseVoxelOctree";
import { HermiteData } from "../volume/HermiteData";
import { ExtractionResponse } from "./messages/ExtractionResponse";
import { DataProcessor } from "./DataProcessor";
/**
* A surface extractor that generates a polygonal mesh from Hermite data.
*/
export class SurfaceExtractor extends DataProcessor {
/**
* Constructs a new surface extractor.
*/
constructor() {
super();
/**
* A container for the data that will be returned to the main thread.
*
* @type {ExtractionResponse}
*/
this.response = new ExtractionResponse();
/**
* A target container for decompressed data.
*
* @type {HermiteData}
* @private
*/
this.decompressionTarget = new HermiteData(false);
/**
* The result of the isosurface extraction process.
*
* @type {Isosurface}
* @private
*/
this.isosurface = null;
}
/**
* Prepares a response that can be send back to the main thread.
*
* Should be used together with {@link SurfaceExtractor#createTransferList}.
*
* @return {ExtractionResponse} A response.
*/
respond() {
const response = super.respond();
response.isosurface = (this.isosurface !== null) ? this.isosurface.serialise() : null;
return response;
}
/**
* Creates a list of transferable items.
*
* @param {Array} [transferList] - An optional target list. The transferable items will be added to this list.
* @return {Transferable[]} The transfer list.
*/
createTransferList(transferList = []) {
super.createTransferList(transferList);
return (this.isosurface !== null) ? this.isosurface.createTransferList(transferList) : transferList;
}
/**
* Extracts a surface from the given Hermite data.
*
* @param {ExtractionRequest} request - An extraction request.
*/
process(request) {
// Adopt the provided data.
const data = super.process(request).getData();
// Decompress the data and build an SVO.
const svo = new SparseVoxelOctree(data.decompress(this.decompressionTarget));
// Generate the isosurface.
this.isosurface = DualContouring.run(svo);
// Release the decompressed data.
this.decompressionTarget.clear();
return this;
}
}