diff --git a/package-lock.json b/package-lock.json index 53b9fee..feca351 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1303,7 +1303,6 @@ "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", - "dev": true, "requires": { "core-js": "2.4.1", "regenerator-runtime": "0.10.5" @@ -1376,6 +1375,11 @@ "dev": true, "optional": true }, + "bowser": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.8.1.tgz", + "integrity": "sha512-NMPaR8ILtdLSWzxQtEs16XbxMcY8ohWGQ5V+TZSJS3fNUt/PBAGkF6YWO9B/4qWE23bK3o0moQKq8UyFEosYkA==" + }, "brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", @@ -1419,6 +1423,11 @@ "integrity": "sha1-7HIDlXQvHH7IlH/W3SYE53qPmP8=", "dev": true }, + "chain-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.0.tgz", + "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w=" + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -1432,6 +1441,11 @@ "supports-color": "2.0.0" } }, + "change-emitter": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz", + "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=" + }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", @@ -1477,8 +1491,7 @@ "core-js": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", - "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", - "dev": true + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" }, "core-util-is": { "version": "1.0.2", @@ -1497,6 +1510,14 @@ "object-assign": "4.1.1" } }, + "css-in-js-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz", + "integrity": "sha512-yuWmPMD9FLi50Xf3k8W8oO3WM1eVnxEGCldCLyfusQ+CgivFk0s23yst4ooW6tfxMuSa03S6uUEga9UhX6GRrA==", + "requires": { + "hyphenate-style-name": "1.0.2" + } + }, "css-vendor": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", @@ -1523,6 +1544,11 @@ "repeating": "2.0.1" } }, + "dom-helpers": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.2.1.tgz", + "integrity": "sha1-MgPgf+0he9H0JLAZc1WC/Deyglo=" + }, "electron-to-chromium": { "version": "1.3.27", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz", @@ -2646,6 +2672,11 @@ "os-tmpdir": "1.0.2" } }, + "hyphenate-style-name": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz", + "integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=" + }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", @@ -2667,6 +2698,15 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "inline-style-prefixer": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz", + "integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=", + "requires": { + "bowser": "1.8.1", + "css-in-js-utils": "2.0.0" + } + }, "invariant": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", @@ -2917,6 +2957,11 @@ "css-vendor": "0.3.8" } }, + "keycode": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.1.9.tgz", + "integrity": "sha1-lkojxU5IiUBbSGGlyfBIDUUUHfo=" + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -2943,6 +2988,16 @@ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", "dev": true }, + "lodash.merge": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", + "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=" + }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -2951,6 +3006,24 @@ "js-tokens": "3.0.2" } }, + "material-ui": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/material-ui/-/material-ui-0.19.4.tgz", + "integrity": "sha1-ypzcqKqLtZTfrF2zjsn/BFoyNYc=", + "requires": { + "babel-runtime": "6.23.0", + "inline-style-prefixer": "3.0.8", + "keycode": "2.1.9", + "lodash.merge": "4.6.0", + "lodash.throttle": "4.1.1", + "prop-types": "15.6.0", + "react-event-listener": "0.5.1", + "react-transition-group": "1.2.1", + "recompose": "0.26.0", + "simple-assign": "0.1.0", + "warning": "3.0.0" + } + }, "micromatch": { "version": "2.3.11", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", @@ -3240,6 +3313,33 @@ "prop-types": "15.6.0" } }, + "react-event-listener": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.5.1.tgz", + "integrity": "sha1-ujYHbke8N8Wmf/XM1Kn/DxViEEA=", + "requires": { + "babel-runtime": "6.26.0", + "fbjs": "0.8.16", + "prop-types": "15.6.0", + "warning": "3.0.0" + }, + "dependencies": { + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "2.4.1", + "regenerator-runtime": "0.11.0" + } + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" + } + } + }, "react-jss": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-7.2.0.tgz", @@ -3252,6 +3352,18 @@ "theming": "1.1.0" } }, + "react-transition-group": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.1.tgz", + "integrity": "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==", + "requires": { + "chain-function": "1.0.0", + "dom-helpers": "3.2.1", + "loose-envify": "1.3.1", + "prop-types": "15.6.0", + "warning": "3.0.0" + } + }, "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", @@ -3281,6 +3393,24 @@ "set-immediate-shim": "1.0.1" } }, + "recompose": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.26.0.tgz", + "integrity": "sha512-KwOu6ztO0mN5vy3+zDcc45lgnaUoaQse/a5yLVqtzTK13czSWnFGmXbQVmnoMgDkI5POd1EwIKSbjU1V7xdZog==", + "requires": { + "change-emitter": "0.1.6", + "fbjs": "0.8.16", + "hoist-non-react-statics": "2.3.1", + "symbol-observable": "1.0.4" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz", + "integrity": "sha1-ND24TGAYxlB3iJgkATWhQg7iLOA=" + } + } + }, "regenerate": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", @@ -3290,8 +3420,7 @@ "regenerator-runtime": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" }, "regenerator-transform": { "version": "0.10.1", @@ -3411,6 +3540,11 @@ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, + "simple-assign": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/simple-assign/-/simple-assign-0.1.0.tgz", + "integrity": "sha1-F/0wZqXz13OPUDIbsPFMooHMS6o=" + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -3457,6 +3591,11 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "symbol-observable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", + "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" + }, "theming": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/theming/-/theming-1.1.0.tgz", diff --git a/package.json b/package.json index 3481d29..b7adc5c 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,11 @@ }, "dependencies": { "@doodle3d/clipper-js": "^1.0.7", + "material-ui": "^0.19.4", "proptypes": "^1.1.0", + "react": "^16.1.0", "react-jss": "^7.2.0", - "three": "^0.83.0", - "react": "^16.1.0" + "three": "^0.83.0" }, "devDependencies": { "babel-plugin-inline-import": "^2.0.6", diff --git a/simpleExample/index.js b/simpleExample/index.js index d030f22..885f863 100644 --- a/simpleExample/index.js +++ b/simpleExample/index.js @@ -1,14 +1,11 @@ import React from 'react'; import * as THREE from 'three'; import { Interface } from 'doodle3d-slicer'; -import fileURL from '!url-loader!./models/combingtest.json'; +import fileURL from '!url-loader!./models/shape.json'; import { render } from 'react-dom'; // import fileSaver from 'file-saver'; const jsonLoader = new THREE.JSONLoader(); jsonLoader.load(fileURL, geometry => { - render( - , - document.getElementById('app') - ); + render(, document.getElementById('app')); }); diff --git a/src/interface/index.js b/src/interface/index.js index 56f8f79..b5e6042 100644 --- a/src/interface/index.js +++ b/src/interface/index.js @@ -1,11 +1,12 @@ import React from 'react'; -import { placeOnGround, createScene } from './utils.js'; +import { placeOnGround, createScene, createGcodeGeometry } from './utils.js'; import baseSettings from '../settings/default.yml'; import printerSettings from '../settings/printer.yml'; import materialSettings from '../settings/material.yml'; import qualitySettings from '../settings/quality.yml'; import PropTypes from 'proptypes'; import injectSheet from 'react-jss'; +import { sliceMesh } from '../slicer.js'; const styles = { container: { @@ -67,6 +68,26 @@ class Interface extends React.Component { } } + slice = async () => { + const { mesh, render, scene, control } = this.state; + const settings = { + ...baseSettings, + ...materialSettings.pla, + ...printerSettings[this.props.defaultPrinter] + }; + const { gcode } = await sliceMesh(settings, mesh, true, (process) => { + console.log('process: ', process); + }); + + control.dispose(); + scene.remove(control, mesh); + + const line = createGcodeGeometry(gcode); + scene.add(line); + + render(); + }; + componentWillUnmount() { if (this.state.editorControls) this.state.editorControls.dispose(); if (this.state.control) this.state.control.dispose(); @@ -83,13 +104,13 @@ class Interface extends React.Component {
- +
- +
); diff --git a/src/interface/utils.js b/src/interface/utils.js index 9c18fc3..1379ff5 100644 --- a/src/interface/utils.js +++ b/src/interface/utils.js @@ -2,6 +2,8 @@ import * as THREE from 'three'; import 'three/examples/js/controls/EditorControls'; import 'three/examples/js/controls/TransformControls'; +const MAX_SPEED = 100 * 60; + export function placeOnGround(mesh) { const boundingBox = new THREE.Box3(); const vertices = mesh.geometry.vertices.map(vertex => vertex.clone().applyMatrix4(mesh.matrix)); @@ -81,3 +83,37 @@ export function createScene(canvas, props, state) { return { control, editorControls, scene, mesh, camera, renderer, render }; } + +export function createGcodeGeometry(gcode) { + const geometry = new THREE.Geometry(); + + let lastPoint + for (let i = 0; i < gcode.length; i ++) { + const { G, F, X, Y, Z } = gcode[i]; + + if (X || Y || Z) { + const point = new THREE.Vector3(Y, Z, X); + + let color; + if (G === 0) { + color = new THREE.Color(0x00ff00); + } else if (G === 1) { + color = new THREE.Color().setHSL(F / MAX_SPEED, 0.5, 0.5); + } + + if (G === 1) { + if (lastPoint) geometry.vertices.push(lastPoint); + geometry.vertices.push(new THREE.Vector3(Y, Z, X)); + geometry.colors.push(color); + geometry.colors.push(color); + } + + lastPoint = point; + } + } + + const material = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors }); + const line = new THREE.LineSegments(geometry, material); + + return line; +} diff --git a/src/sliceActions/helpers/GCode.js b/src/sliceActions/helpers/GCode.js index 71f9a65..980d34f 100644 --- a/src/sliceActions/helpers/GCode.js +++ b/src/sliceActions/helpers/GCode.js @@ -1,20 +1,20 @@ import * as THREE from 'three'; import { PRECISION } from '../../constants.js'; -const MOVE = 'G'; -const M_COMMAND = 'M'; -const FAN_SPEED = 'S'; -const SPEED = 'F'; -const EXTRUDER = 'E'; -const POSITION_X = 'X'; -const POSITION_Y = 'Y'; -const POSITION_Z = 'Z'; +export const MOVE = 'G'; +export const M_COMMAND = 'M'; +export const FAN_SPEED = 'S'; +export const SPEED = 'F'; +export const EXTRUDER = 'E'; +export const POSITION_X = 'X'; +export const POSITION_Y = 'Y'; +export const POSITION_Z = 'Z'; export default class { constructor(nozzleToFilamentRatio) { this._nozzleToFilamentRatio = nozzleToFilamentRatio; - this._gcode = ''; + this._gcode = []; this._currentValues = {}; this._nozzlePosition = new THREE.Vector2(0, 0); this._extruder = 0.0; @@ -24,24 +24,7 @@ export default class { } _addGCode(command) { - let str = ''; - - let first = true; - for (const action in command) { - const value = command[action]; - const currentValue = this._currentValues[action]; - if (first) { - str = action + value; - - first = false; - } else if (currentValue !== value) { - str += ` ${action}${value}`; - - this._currentValues[action] = value; - } - } - - this._gcode += `${str}\n`; + this._gcode.push(command); } turnFanOn(fanSpeed) {