import _ from 'lodash'; import React from 'react'; import * as THREE from 'three'; import PropTypes from 'proptypes'; import { placeOnGround, createScene, createGcodeGeometry } from './utils.js'; import injectSheet from 'react-jss'; import { sliceGeometry } from '../slicer.js'; import RaisedButton from 'material-ui/RaisedButton'; import Slider from 'material-ui/Slider'; import { grey100, grey300 } from 'material-ui/styles/colors'; import Settings from './Settings.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 ReactResizeDetector from 'react-resize-detector'; const styles = { container: { position: 'relative', display: 'flex', height: '100%', backgroundColor: grey100, overflow: 'hidden' }, controlBar: { position: 'absolute', bottom: '10px', left: '10px' }, d3View: { flexGrow: 1 }, canvas: { position: 'absolute' }, sliceBar: { width: '240px', padding: '10px', overflowY: 'auto', backgroundColor: 'white', borderLeft: `1px solid ${grey300}` }, overlay: { position: 'absolute', backgroundColor: 'rgba(0, 0, 0, 0.5)', color: 'white', top: 0, right: 0, bottom: 0, left: 0, padding: '20px' }, sliceActions: { listStyleType: 'none', paddingLeft: 0 }, button: { margin: '5px 0' }, controlButton: { marginRight: '2px' } }; class Interface extends React.Component { constructor(props) { super(props); const { defaultPrinter, defaultQuality, defaultMaterial, printers, quality, material, defaultSettings } = props; this.state = { controlMode: 'translate', isSlicing: false, sliced: false, printers: defaultPrinter, quality: defaultQuality, material: defaultMaterial, settings: _.merge( {}, defaultSettings, printers[defaultPrinter], quality[defaultQuality], material[defaultMaterial] ) }; } componentDidMount() { const { canvas } = this.refs; const scene = createScene(canvas, this.props, this.state); this.setState(scene); } resetMesh = () => { const { mesh, render } = this.state; if (mesh) { mesh.position.set(0, 0, 0); mesh.scale.set(1, 1, 1); mesh.rotation.set(0, 0, 0); mesh.updateMatrix(); placeOnGround(mesh); render(); } }; reset = () => { const { control, mesh, render, gcode, scene } = this.state; control.enabled = true; control.setSize(1); control.visible = true; mesh.visible = true; scene.remove(gcode.linePreview); gcode.linePreview.geometry.dispose(); this.setState({ sliced: false, gcode: null }); render(); }; slice = async () => { const { mesh, render, scene, control, settings } = this.state; const { dimensions } = settings; const centerX = dimensions.x / 2; const centerY = dimensions.y / 2; const geometry = mesh.geometry.clone(); mesh.updateMatrix(); this.setState({ isSlicing: true, progress: { actions: [], percentage: 0 } }); const matrix = new THREE.Matrix4().makeTranslation(centerY, 0, centerX).multiply(mesh.matrix); const gcode = await sliceGeometry(settings, geometry, matrix, false, true, ({ progress }) => { this.setState({ progress: { actions: [...this.state.progress.actions, progress.action], percentage: progress.done / progress.total } }); }); this.setState({ isSlicing: false }); // TODO // can't disable control ui still interacts with mouse input control.enabled = false; // hack to disable control control.setSize(0); control.visible = false; mesh.visible = false; gcode.linePreview.position.x = -centerY; gcode.linePreview.position.z = -centerX; scene.add(gcode.linePreview); this.setState({ sliced: true, gcode }); render(); }; onChangeSettings = (settings) => { this.setState(settings); }; updateDrawRange = (event, value) => { const { gcode, render } = this.state; gcode.linePreview.geometry.setDrawRange(0, value); render(); }; componentWillUnmount() { if (this.state.editorControls) this.state.editorControls.dispose(); if (this.state.control) this.state.control.dispose(); } componentWillUpdate(nextProps, nextState) { const { control, box, render, setSize } = this.state; if (control && nextState.controlMode !== this.state.controlMode) control.setMode(nextState.controlMode); if (box && nextState.settings.dimensions !== this.state.settings.dimensions) { const { dimensions } = nextState.settings; box.scale.set(dimensions.y, dimensions.z, dimensions.x); render(); } } onResize = (width, height) => { window.requestAnimationFrame(() => { const { setSize } = this.state; const { pixelRatio } = this.props; setSize(width, height, pixelRatio); }); }; render() { const { classes, onCompleteActions, defaultPrinter, defaultQuality, defaultMaterial } = this.props; const { sliced, isSlicing, progress, gcode, controlMode, settings, printers, quality, material } = this.state; return (
Slicing: {progress.percentage.toLocaleString(navigator.language, { style: 'percent' })}