UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

188 lines (153 loc) 7.59 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import { vec3 } from 'gl-matrix'; import macro from '../../macros.js'; import vtkTriangle from '../../Common/DataModel/Triangle.js'; import { FormatTypes } from './STLWriter/Constants.js'; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } var vtkErrorMacro = macro.vtkErrorMacro; // ---------------------------------------------------------------------------- // Global methods // ---------------------------------------------------------------------------- function writeFloatBinary(dataView, offset, float) { dataView.setFloat32(offset, float.toPrecision(6), true); return offset + 4; } function writeVectorBinary(dataView, offset, vector) { var off = writeFloatBinary(dataView, offset, vector[0]); off = writeFloatBinary(dataView, off, vector[1]); return writeFloatBinary(dataView, off, vector[2]); } // ---------------------------------------------------------------------------- // vtkSTLWriter methods // ---------------------------------------------------------------------------- var binaryWriter = function binaryWriter() { var offset = 0; var dataView = null; return { init: function init(polyData) { var polys = polyData.getPolys().getData(); var buffer = new ArrayBuffer(80 + 4 + 50 * polys.length / 4); // buffer for the full file; size = header (80) + num cells (4) + 50 bytes per poly dataView = new DataView(buffer); }, writeHeader: function writeHeader(polyData) { offset += 80; // Header is empty // TODO: could add date, version, package // First need to write the number of cells dataView.setUint32(offset, polyData.getNumberOfCells(), true); offset += 4; }, writeTriangle: function writeTriangle(v1, v2, v3, dn) { offset = writeVectorBinary(dataView, offset, dn); offset = writeVectorBinary(dataView, offset, v1); offset = writeVectorBinary(dataView, offset, v2); offset = writeVectorBinary(dataView, offset, v3); offset += 2; // unused 'attribute byte count' is a Uint16 }, writeFooter: function writeFooter(polyData) {}, getOutputData: function getOutputData() { return dataView; } }; }; var asciiWriter = function asciiWriter() { var file = ''; return { init: function init(polyData) {}, writeHeader: function writeHeader(polyData) { file += 'solid ascii\n'; }, writeTriangle: function writeTriangle(v1, v2, v3, dn) { file += " facet normal ".concat(dn[0].toPrecision(6), " ").concat(dn[1].toPrecision(6), " ").concat(dn[2].toPrecision(6), "\n"); file += ' outer loop\n'; file += " vertex ".concat(v1[0].toPrecision(6), " ").concat(v1[1].toPrecision(6), " ").concat(v1[2].toPrecision(6), "\n"); file += " vertex ".concat(v2[0].toPrecision(6), " ").concat(v2[1].toPrecision(6), " ").concat(v2[2].toPrecision(6), "\n"); file += " vertex ".concat(v3[0].toPrecision(6), " ").concat(v3[1].toPrecision(6), " ").concat(v3[2].toPrecision(6), "\n"); file += ' endloop\n'; file += ' endfacet\n'; }, writeFooter: function writeFooter(polyData) { file += 'endsolid\n'; }, getOutputData: function getOutputData() { return file; } }; }; function writeSTL(polyData) { var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : FormatTypes.BINARY; var transform = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var writer = null; if (format === FormatTypes.BINARY) { writer = binaryWriter(); } else if (format === FormatTypes.ASCII) { writer = asciiWriter(); } else { vtkErrorMacro('Invalid format type'); } writer.init(polyData); writer.writeHeader(polyData); var polys = polyData.getPolys().getData(); var points = polyData.getPoints().getData(); var strips = polyData.getStrips() ? polyData.getStrips().getData() : null; var n = []; var v1 = []; var v2 = []; var v3 = []; // Strips if (strips && strips.length > 0) { throw new Error('Unsupported strips'); } // Polys for (var i = 0; i < polys.length;) { var pointNumber = polys[i++]; if (pointNumber) { v1 = [points[polys[i] * 3], points[polys[i] * 3 + 1], points[polys[i++] * 3 + 2]]; v2 = [points[polys[i] * 3], points[polys[i] * 3 + 1], points[polys[i++] * 3 + 2]]; v3 = [points[polys[i] * 3], points[polys[i] * 3 + 1], points[polys[i++] * 3 + 2]]; if (transform) { vec3.transformMat4(v1, v1, transform); vec3.transformMat4(v2, v2, transform); vec3.transformMat4(v3, v3, transform); } vtkTriangle.computeNormal(v1, v2, v3, n); writer.writeTriangle(v1, v2, v3, n); } } writer.writeFooter(polyData); return writer.getOutputData(); } // ---------------------------------------------------------------------------- // Static API // ---------------------------------------------------------------------------- var STATIC = { writeSTL: writeSTL }; // ---------------------------------------------------------------------------- // vtkSTLWriter methods // ---------------------------------------------------------------------------- function vtkSTLWriter(publicAPI, model) { // Set our className model.classHierarchy.push('vtkSTLWriter'); publicAPI.requestData = function (inData, outData) { var input = inData[0]; if (!input || input.getClassName() !== 'vtkPolyData') { vtkErrorMacro('Invalid or missing input'); return; } outData[0] = writeSTL(input, model.format, model.transform); }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { format: FormatTypes.BINARY, transform: null }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Make this a VTK object macro.obj(publicAPI, model); // Also make it an algorithm with one input and one output macro.algo(publicAPI, model, 1, 1); macro.setGet(publicAPI, model, ['format', 'transform']); // Object specific methods vtkSTLWriter(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = macro.newInstance(extend, 'vtkSTLWriter'); // ---------------------------------------------------------------------------- var vtkSTLWriter$1 = _objectSpread({ newInstance: newInstance, extend: extend }, STATIC); export { STATIC, vtkSTLWriter$1 as default, extend, newInstance };