mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-12-22 19:13:50 +01:00
create basic component
This commit is contained in:
parent
3f3408747c
commit
ae24974e31
18
.babelrc
18
.babelrc
@ -1,19 +1,25 @@
|
||||
{
|
||||
"env": {
|
||||
// transpile to common node & browser compatible js, keeping modules
|
||||
"module": {
|
||||
"presets": [
|
||||
["latest", {
|
||||
["env", {
|
||||
"targets": { "node": "6" },
|
||||
"modules": false
|
||||
}]
|
||||
}],
|
||||
"stage-0",
|
||||
"react"
|
||||
]
|
||||
},
|
||||
// transpile to common node & browser compatible js, using commonjs
|
||||
"main": {
|
||||
"presets": ["latest"]
|
||||
"presets": ["env", "react"]
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"babel-plugin-transform-object-rest-spread"
|
||||
"babel-plugin-transform-regenerator",
|
||||
"babel-plugin-transform-object-rest-spread",
|
||||
"babel-plugin-inline-import",
|
||||
"babel-plugin-transform-class-properties",
|
||||
"babel-plugin-transform-es2015-classes",
|
||||
"babel-plugin-syntax-dynamic-import"
|
||||
]
|
||||
}
|
||||
|
1165
package-lock.json
generated
1165
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@ -15,12 +15,25 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@doodle3d/clipper-js": "^1.0.7",
|
||||
"three": "^0.83.0"
|
||||
"proptypes": "^1.1.0",
|
||||
"react-jss": "^7.2.0",
|
||||
"three": "^0.83.0",
|
||||
"react": "^16.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.24.1",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.23.0",
|
||||
"babel-preset-latest": "^6.24.1"
|
||||
"babel-plugin-inline-import": "^2.0.6",
|
||||
"babel-preset-stage-0": "^6.24.1",
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-plugin-transform-es2015-classes": "^6.24.1",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-cli": "6.24.1",
|
||||
"babel-core": "6.24.1",
|
||||
"babel-loader": "7.0.0",
|
||||
"babel-plugin-add-module-exports": "0.2.1",
|
||||
"babel-preset-es2015": "6.24.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,29 +1,14 @@
|
||||
import React from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { defaultSettings, sliceGeometry } from 'doodle3d-slicer';
|
||||
import { Interface } from 'doodle3d-slicer';
|
||||
import fileURL from '!url-loader!./models/combingtest.json';
|
||||
import fileSaver from 'file-saver';
|
||||
|
||||
const settings = {
|
||||
...defaultSettings.base,
|
||||
...defaultSettings.material.pla,
|
||||
...defaultSettings.printer.ultimaker2go,
|
||||
...defaultSettings.quality.high
|
||||
};
|
||||
import { render } from 'react-dom';
|
||||
// import fileSaver from 'file-saver';
|
||||
|
||||
const jsonLoader = new THREE.JSONLoader();
|
||||
jsonLoader.load(fileURL, geometry => {
|
||||
geometry.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI / -2));
|
||||
geometry.applyMatrix(new THREE.Matrix4().setPosition(new THREE.Vector3(50, -0.0, 50)));
|
||||
|
||||
const onProgress = ({ progress: { done, total, action } }) => {
|
||||
const percentage = `${(done / total * 100).toFixed()}%`
|
||||
document.write(`<p>${action}, ${percentage}</p>`);
|
||||
};
|
||||
|
||||
const { filament, duration, gcode } = sliceGeometry(settings, geometry, null, true, onProgress);
|
||||
// console.log('filament: ', filament);
|
||||
// console.log('duration: ', duration);
|
||||
// document.body.innerHTML = gcode.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||
const file = new File([gcode], 'gcode.gcode', { type: 'text/plain' });
|
||||
fileSaver.saveAs(file);
|
||||
render(
|
||||
<Interface geometry={geometry} />,
|
||||
document.getElementById('app')
|
||||
);
|
||||
});
|
||||
|
148
simpleExample/package-lock.json
generated
148
simpleExample/package-lock.json
generated
@ -157,6 +157,11 @@
|
||||
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||
"dev": true
|
||||
},
|
||||
"asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||
},
|
||||
"asn1.js": {
|
||||
"version": "4.9.1",
|
||||
"resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz",
|
||||
@ -711,6 +716,15 @@
|
||||
"regenerator-transform": "0.9.11"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-runtime": {
|
||||
"version": "6.23.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz",
|
||||
"integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "6.23.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-transform-strict-mode": {
|
||||
"version": "6.24.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
|
||||
@ -1596,6 +1610,14 @@
|
||||
"integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=",
|
||||
"dev": true
|
||||
},
|
||||
"encoding": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
|
||||
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
|
||||
"requires": {
|
||||
"iconv-lite": "0.4.19"
|
||||
}
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.3.0.tgz",
|
||||
@ -1895,6 +1917,27 @@
|
||||
"websocket-driver": "0.6.5"
|
||||
}
|
||||
},
|
||||
"fbjs": {
|
||||
"version": "0.8.16",
|
||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
|
||||
"integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
|
||||
"requires": {
|
||||
"core-js": "1.2.7",
|
||||
"isomorphic-fetch": "2.2.1",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"promise": "7.3.1",
|
||||
"setimmediate": "1.0.5",
|
||||
"ua-parser-js": "0.7.17"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
|
||||
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
|
||||
}
|
||||
}
|
||||
},
|
||||
"file-saver": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz",
|
||||
@ -3120,6 +3163,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"html-webpack-template": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/html-webpack-template/-/html-webpack-template-6.0.2.tgz",
|
||||
"integrity": "sha512-ekYCkU5t41wOu4kgGWvojVrREHap1qvZ8cbuy8ogH7EmscY4B0ElOEGQFFKpvig4GhhlVCK4mWaIik3dgz92SQ=="
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
|
||||
@ -3230,12 +3278,26 @@
|
||||
"integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=",
|
||||
"dev": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.19",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
||||
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
|
||||
"integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
|
||||
"dev": true
|
||||
},
|
||||
"imports-loader": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.7.1.tgz",
|
||||
"integrity": "sha1-8gS180cCoywdt9SNidXoZ6BEElM=",
|
||||
"requires": {
|
||||
"loader-utils": "1.1.0",
|
||||
"source-map": "0.5.6"
|
||||
}
|
||||
},
|
||||
"indent-string": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
|
||||
@ -3438,6 +3500,11 @@
|
||||
"integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
|
||||
"dev": true
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
|
||||
},
|
||||
"is-utf8": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
|
||||
@ -3459,11 +3526,19 @@
|
||||
"isarray": "1.0.0"
|
||||
}
|
||||
},
|
||||
"isomorphic-fetch": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
|
||||
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
|
||||
"requires": {
|
||||
"node-fetch": "1.7.3",
|
||||
"whatwg-fetch": "2.0.3"
|
||||
}
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
|
||||
"dev": true
|
||||
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.9.0",
|
||||
@ -3598,7 +3673,6 @@
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
|
||||
"integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"js-tokens": "3.0.2"
|
||||
}
|
||||
@ -3828,6 +3902,15 @@
|
||||
"lower-case": "1.1.4"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
|
||||
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
|
||||
"requires": {
|
||||
"encoding": "0.1.12",
|
||||
"is-stream": "1.1.0"
|
||||
}
|
||||
},
|
||||
"node-forge": {
|
||||
"version": "0.6.33",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.33.tgz",
|
||||
@ -3912,8 +3995,7 @@
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object.omit": {
|
||||
"version": "2.0.1",
|
||||
@ -4226,6 +4308,24 @@
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
|
||||
"dev": true
|
||||
},
|
||||
"promise": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
||||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
||||
"requires": {
|
||||
"asap": "2.0.6"
|
||||
}
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.6.0",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
|
||||
"integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1"
|
||||
}
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.4.tgz",
|
||||
@ -4341,6 +4441,28 @@
|
||||
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
|
||||
"dev": true
|
||||
},
|
||||
"react": {
|
||||
"version": "16.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-16.1.0.tgz",
|
||||
"integrity": "sha512-hvKYlKqde2JNnNiEzORvSA0J1L7uSZ43l+J89ZNoP4EXxQrVNH0CFj8vorfPou3w+1ou1BNMBir2VVsuXtETRA==",
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.0"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "16.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.1.0.tgz",
|
||||
"integrity": "sha512-i9in5qW3H2PDinUPD9bnQK7tLAD8LhjYQ+fXi3nJOvVnxOO3ErHq6RNEnKY7pbjTPt155e74q7al8eBUuyLtew==",
|
||||
"requires": {
|
||||
"fbjs": "0.8.16",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.0"
|
||||
}
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
|
||||
@ -4696,8 +4818,7 @@
|
||||
"setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.0.3",
|
||||
@ -4770,8 +4891,7 @@
|
||||
"source-map": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
|
||||
"dev": true
|
||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.4.15",
|
||||
@ -4992,6 +5112,11 @@
|
||||
"mime-types": "2.1.15"
|
||||
}
|
||||
},
|
||||
"ua-parser-js": {
|
||||
"version": "0.7.17",
|
||||
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
|
||||
"integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "2.8.29",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
|
||||
@ -5296,6 +5421,11 @@
|
||||
"integrity": "sha1-domUmcGEtu91Q3fC27DNbLVdKec=",
|
||||
"dev": true
|
||||
},
|
||||
"whatwg-fetch": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
|
||||
"integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
|
||||
},
|
||||
"which-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
|
||||
|
@ -12,10 +12,15 @@
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.23.0",
|
||||
"file-saver": "^1.3.3",
|
||||
"html-webpack-template": "^6.0.2",
|
||||
"imports-loader": "^0.7.1",
|
||||
"react": "^16.1.0",
|
||||
"react-dom": "^16.1.0",
|
||||
"three": "^0.83.0",
|
||||
"url-loader": "^0.5.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-core": "^6.25.0",
|
||||
"babel-loader": "^7.1.1",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.23.0",
|
||||
|
@ -6,15 +6,17 @@ const babelLoader = {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: [
|
||||
['latest', {
|
||||
'modules': false,
|
||||
'loose': true
|
||||
}]
|
||||
require('babel-preset-env'),
|
||||
require('babel-preset-react')
|
||||
],
|
||||
plugins: [
|
||||
require('babel-plugin-transform-object-rest-spread'),
|
||||
require('babel-plugin-transform-class-properties'),
|
||||
require('babel-plugin-transform-runtime')
|
||||
],
|
||||
plugins: [require('babel-plugin-transform-object-rest-spread')],
|
||||
babelrc: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
entry: './index.js',
|
||||
@ -35,12 +37,13 @@ module.exports = {
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: babelLoader
|
||||
},
|
||||
{
|
||||
}, { // make THREE global available to three.js examples
|
||||
test: /three\/examples\/.+\.js/,
|
||||
use: 'imports-loader?THREE=three'
|
||||
}, {
|
||||
test: /\.yml$/,
|
||||
use: 'yml-loader'
|
||||
},
|
||||
{
|
||||
}, {
|
||||
test: /\.worker\.js$/,
|
||||
use: ['worker-loader', babelLoader]
|
||||
}
|
||||
@ -48,7 +51,10 @@ module.exports = {
|
||||
},
|
||||
plugins: [
|
||||
new HTMLWebpackPlugin({
|
||||
title: 'Doodle3D Slicer - Simple example'
|
||||
title: 'Doodle3D Slicer - Simple example',
|
||||
template: require('html-webpack-template'),
|
||||
inject: false,
|
||||
appMountId: 'app'
|
||||
}),
|
||||
],
|
||||
devtool: "source-map",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { sliceGeometry, sliceMesh } from './slicer.js';
|
||||
import Interface from './interface/index.js';
|
||||
import baseSettings from './settings/default.yml';
|
||||
import printerSettings from './settings/printer.yml';
|
||||
import materialSettings from './settings/material.yml';
|
||||
@ -14,5 +15,6 @@ const defaultSettings = {
|
||||
export {
|
||||
sliceGeometry,
|
||||
sliceMesh,
|
||||
Interface,
|
||||
defaultSettings
|
||||
};
|
||||
|
99
src/interface/index.js
Normal file
99
src/interface/index.js
Normal file
@ -0,0 +1,99 @@
|
||||
import React from 'react';
|
||||
import { placeOnGround, createScene } 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';
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
position: 'relative'
|
||||
},
|
||||
canvas: {
|
||||
position: 'absolute',
|
||||
},
|
||||
controlBar: {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0
|
||||
},
|
||||
sliceBar: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0
|
||||
}
|
||||
};
|
||||
|
||||
class Interface extends React.Component {
|
||||
static defaultProps = {
|
||||
width: 720,
|
||||
height: 480,
|
||||
printers: printerSettings,
|
||||
defaultPrinter: 'ultimaker2'
|
||||
};
|
||||
static propTypes = {
|
||||
geometry: (props, propName) => {
|
||||
if (!(props[propName].isGeometry || props[propName].isBufferGeometry)) {
|
||||
throw new Error('invalid prop, is not geometry');
|
||||
}
|
||||
},
|
||||
width: PropTypes.number.isRequired,
|
||||
height: PropTypes.number.isRequired,
|
||||
classes: PropTypes.objectOf(PropTypes.string),
|
||||
printers: PropTypes.object.isRequired,
|
||||
defaultPrinter: PropTypes.string.isRequired,
|
||||
};
|
||||
state = {
|
||||
controlMode: 'translate'
|
||||
};
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.state.editorControls) this.state.editorControls.dispose();
|
||||
if (this.state.control) this.state.control.dispose();
|
||||
}
|
||||
|
||||
componentWillUpdate(nextProps, nextState) {
|
||||
const { control } = this.state;
|
||||
if (control && nextState.controlMode !== this.state.controlMode) control.setMode(nextState.controlMode);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { width, height, classes } = this.props;
|
||||
return (
|
||||
<div style={{ width, height }} className={classes.container}>
|
||||
<canvas className={classes.canvas} ref="canvas" width={width} height={height} />
|
||||
<div className={classes.controlBar}>
|
||||
<button onClick={() => this.resetMesh()}>Reset</button>
|
||||
<button onClick={() => this.setState({ controlMode: 'translate' })}>Translate</button>
|
||||
<button onClick={() => this.setState({ controlMode: 'rotate' })}>Rotate</button>
|
||||
<button onClick={() => this.setState({ controlMode: 'scale' })}>Scale</button>
|
||||
</div>
|
||||
<div className={classes.sliceBar}>
|
||||
<button>Slice</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectSheet(styles)(Interface);
|
83
src/interface/utils.js
Normal file
83
src/interface/utils.js
Normal file
@ -0,0 +1,83 @@
|
||||
import * as THREE from 'three';
|
||||
import 'three/examples/js/controls/EditorControls';
|
||||
import 'three/examples/js/controls/TransformControls';
|
||||
|
||||
export function placeOnGround(mesh) {
|
||||
const boundingBox = new THREE.Box3();
|
||||
const vertices = mesh.geometry.vertices.map(vertex => vertex.clone().applyMatrix4(mesh.matrix));
|
||||
boundingBox.setFromPoints(vertices);
|
||||
|
||||
mesh.position.y -= boundingBox.min.y;
|
||||
mesh.updateMatrix();
|
||||
}
|
||||
|
||||
export function createScene(canvas, props, state) {
|
||||
let geometry;
|
||||
if (props.geometry.isGeometry) {
|
||||
geometry = props.geometry;
|
||||
} else if (props.geometry.isBufferGeometry) {
|
||||
geometry = new THREE.Geometry().fromBufferGeometry(props.geometry);
|
||||
}
|
||||
geometry.computeBoundingBox();
|
||||
const centerX = (geometry.boundingBox.max.x + geometry.boundingBox.min.x) / 2;
|
||||
const centerY = (geometry.boundingBox.max.y + geometry.boundingBox.min.y) / 2;
|
||||
const centerZ = (geometry.boundingBox.max.z + geometry.boundingBox.min.z) / 2;
|
||||
geometry.applyMatrix(new THREE.Matrix4().makeTranslation(-centerX, -centerY, -centerZ));
|
||||
|
||||
const { width, height, printers, defaultPrinter } = props;
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ canvas, alpha: true });
|
||||
renderer.setClearColor(0xffffff, 0);
|
||||
renderer.setSize(width, height);
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(50, width / height, 1, 10000);
|
||||
camera.position.set(0, 400, 300);
|
||||
camera.lookAt(new THREE.Vector3(0, 0, 0));
|
||||
|
||||
const directionalLight = new THREE.DirectionalLight(0xd5d5d5);
|
||||
directionalLight.position.set(1, 1, 1);
|
||||
scene.add(directionalLight);
|
||||
|
||||
const light = new THREE.AmbientLight(0x808080);
|
||||
scene.add(light);
|
||||
|
||||
const mesh = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: 0x2194ce }));
|
||||
placeOnGround(mesh);
|
||||
scene.add(mesh);
|
||||
|
||||
const editorControls = new THREE.EditorControls(camera, canvas);
|
||||
|
||||
const control = new THREE.TransformControls(camera, canvas);
|
||||
control.setMode(state.controlMode);
|
||||
control.setRotationSnap(THREE.Math.degToRad(45));
|
||||
control.addEventListener('mouseDown', () => editorControls.enabled = false);
|
||||
control.addEventListener('mouseUp', () => {
|
||||
editorControls.enabled = true;
|
||||
placeOnGround(mesh);
|
||||
});
|
||||
|
||||
control.attach(mesh);
|
||||
scene.add(control);
|
||||
|
||||
const render = () => {
|
||||
control.update();
|
||||
renderer.render(scene, camera);
|
||||
};
|
||||
|
||||
control.addEventListener('change', render);
|
||||
editorControls.addEventListener('change', render);
|
||||
|
||||
const box = new THREE.BoxHelper();
|
||||
box.update(new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1).applyMatrix(new THREE.Matrix4().makeTranslation(0, 0.5, 0))));
|
||||
box.material.color.setHex(0x72bcd4);
|
||||
scene.add(box);
|
||||
|
||||
const { dimensions } = printers[defaultPrinter];
|
||||
box.scale.set(dimensions.x, dimensions.y, dimensions.z);
|
||||
|
||||
render();
|
||||
|
||||
return { control, editorControls, scene, mesh, camera, renderer, render };
|
||||
}
|
Loading…
Reference in New Issue
Block a user