slicer can now fetch d3 files from cloud

This commit is contained in:
casperlamboo 2018-01-15 15:17:38 +01:00
parent 0d64b62f12
commit 457f110dd2
5 changed files with 209 additions and 93 deletions

View File

@ -1,17 +1,13 @@
import 'babel-polyfill' import 'babel-polyfill'
import React from 'react'; import React from 'react';
import { Interface } from 'doodle3d-slicer'; import { Interface } from 'doodle3d-slicer';
import doodleURL from '!url-loader!./models/Doodle_2.d3sketch';
import { render } from 'react-dom'; import { render } from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import injectTapEventPlugin from 'react-tap-event-plugin'; import injectTapEventPlugin from 'react-tap-event-plugin';
import jss from 'jss'; import jss from 'jss';
import preset from 'jss-preset-default'; import preset from 'jss-preset-default';
import normalize from 'normalize-jss'; import normalize from 'normalize-jss';
import JSONToSketchData from 'doodle3d-core/shape/JSONToSketchData'; import queryString from 'query-string';
import createSceneData from 'doodle3d-core/d3/createSceneData.js';
import { generateExportMesh } from 'doodle3d-core/utils/exportUtils.js';
import { Matrix4 } from 'three/src/math/Matrix4.js';
injectTapEventPlugin(); injectTapEventPlugin();
@ -26,17 +22,10 @@ jss.createStyleSheet({
} }
}).attach(); }).attach();
function init(mesh) { const { file } = queryString.parse(location.search);
render(( render((
<MuiThemeProvider> <MuiThemeProvider>
<Interface mesh={mesh} name="doodle"/> <Interface file={file} name="doodle"/>
</MuiThemeProvider> </MuiThemeProvider>
), document.getElementById('app')); ), document.getElementById('app'));
}
fetch(doodleURL)
.then(resonse => resonse.json())
.then(json => JSONToSketchData(json))
.then(file => createSceneData(file))
.then(sketch => generateExportMesh(sketch, { offsetSingleWalls: false, matrix: new Matrix4() }))
.then(init);

181
package-lock.json generated
View File

@ -24,7 +24,7 @@
"integrity": "sha512-glELSijsD9b+/0d9iOdasBwqH3s+xPxD59tJ7aXkBx7klugygGOMXn7PB05AdhVyA1OYMj7GUCegaQa7nvLtmQ==" "integrity": "sha512-glELSijsD9b+/0d9iOdasBwqH3s+xPxD59tJ7aXkBx7klugygGOMXn7PB05AdhVyA1OYMj7GUCegaQa7nvLtmQ=="
}, },
"@doodle3d/doodle3d-core": { "@doodle3d/doodle3d-core": {
"version": "github:doodle3d/doodle3d-core#0c4e410a27ea2df8336a956e966ee16ad8ac04d7", "version": "github:doodle3d/doodle3d-core#36a73c233e569fca79d2059a50edb6bdb511aa58",
"dev": true, "dev": true,
"requires": { "requires": {
"@doodle3d/cal": "0.0.8", "@doodle3d/cal": "0.0.8",
@ -35,16 +35,18 @@
"@doodle3d/threejs-export-stl": "0.0.5", "@doodle3d/threejs-export-stl": "0.0.5",
"@doodle3d/touch-events": "0.0.7", "@doodle3d/touch-events": "0.0.7",
"babel-polyfill": "6.26.0", "babel-polyfill": "6.26.0",
"bezier-js": "2.2.3", "bezier-js": "2.2.5",
"blueimp-canvas-to-blob": "3.14.0", "blueimp-canvas-to-blob": "3.14.0",
"bowser": "1.8.1", "bowser": "1.8.1",
"fit-curve": "0.1.6", "fit-curve": "0.1.6",
"google-fonts-webpack-plugin": "0.4.4",
"imports-loader": "0.7.1", "imports-loader": "0.7.1",
"jss": "9.4.0", "jss": "9.5.1",
"keycode": "2.1.9", "keycode": "2.1.9",
"lodash": "4.17.4", "lodash": "4.17.4",
"memoizee": "0.3.10", "memoizee": "0.3.10",
"pouchdb": "6.4.0", "normalize-wheel": "1.0.1",
"pouchdb": "6.4.1",
"proptypes": "1.1.0", "proptypes": "1.1.0",
"raf": "3.4.0", "raf": "3.4.0",
"ramda": "0.21.0", "ramda": "0.21.0",
@ -66,9 +68,9 @@
}, },
"dependencies": { "dependencies": {
"jss": { "jss": {
"version": "9.4.0", "version": "9.5.1",
"resolved": "https://registry.npmjs.org/jss/-/jss-9.4.0.tgz", "resolved": "https://registry.npmjs.org/jss/-/jss-9.5.1.tgz",
"integrity": "sha512-ckJpElL5CimehboeLDQoHeY7mlxn0KPnPn2EZVbn6pomhfbTXiQJ6fAJXSp9rUM2hPtE0PG8Swzdy9vhB2v82w==", "integrity": "sha512-py//ogG1xeztpEDmosJtrkfUXibx3qiAr+1GQvfLHp7azpqkzTPLCnainDgH7Zn0q6S7rcM1eINrVT9n/r5f2w==",
"dev": true, "dev": true,
"requires": { "requires": {
"is-in-browser": "1.1.3", "is-in-browser": "1.1.3",
@ -1716,9 +1718,9 @@
} }
}, },
"bezier-js": { "bezier-js": {
"version": "2.2.3", "version": "2.2.5",
"resolved": "https://registry.npmjs.org/bezier-js/-/bezier-js-2.2.3.tgz", "resolved": "https://registry.npmjs.org/bezier-js/-/bezier-js-2.2.5.tgz",
"integrity": "sha1-xVdBFqSjVkpxU41z4LDVFdqN3sU=", "integrity": "sha512-HGh+GevPguxrAmnWF2/A+8c8FEatnKcE6WttpYWA5fn1CfpJz4reFbr11DuyFs2gwaIo9vF7aVXW2xg1iaqvyg==",
"dev": true "dev": true
}, },
"big.js": { "big.js": {
@ -1952,6 +1954,12 @@
"isarray": "1.0.0" "isarray": "1.0.0"
} }
}, },
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
"dev": true
},
"buffer-from": { "buffer-from": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.1.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.1.tgz",
@ -2456,6 +2464,11 @@
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"dev": true "dev": true
}, },
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
},
"deep-equal": { "deep-equal": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
@ -2729,9 +2742,9 @@
} }
}, },
"encoding-down": { "encoding-down": {
"version": "3.0.0", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-3.0.0.tgz", "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-3.0.1.tgz",
"integrity": "sha1-IGjLZ7E3G14frJtfF44FpVUr+l4=", "integrity": "sha512-uvx+39YNqiPLqhXAvOSGBVy/oYBh4p2ShwG9YFCipwgfOhnVIOxuOPE3R9dEGM44bn0VHIrC3ojXq6lNf2ulwg==",
"dev": true, "dev": true,
"requires": { "requires": {
"abstract-leveldown": "3.0.0", "abstract-leveldown": "3.0.0",
@ -2748,9 +2761,9 @@
} }
}, },
"end-of-stream": { "end-of-stream": {
"version": "1.4.0", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
"integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"once": "1.4.0" "once": "1.4.0"
@ -2836,9 +2849,9 @@
} }
}, },
"es6-error": { "es6-error": {
"version": "4.0.2", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.0.2.tgz", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
"integrity": "sha1-7sXHJurO9Rt/a3PCDbbhsTsGnJg=", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
"dev": true "dev": true
}, },
"es6-iterator": { "es6-iterator": {
@ -3173,6 +3186,15 @@
} }
} }
}, },
"fd-slicer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
"dev": true,
"requires": {
"pend": "1.2.0"
}
},
"file-saver": { "file-saver": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz", "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz",
@ -4081,14 +4103,6 @@
} }
} }
}, },
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"string-width": { "string-width": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
@ -4099,6 +4113,14 @@
"strip-ansi": "3.0.1" "strip-ansi": "3.0.1"
} }
}, },
"string_decoder": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"requires": {
"safe-buffer": "5.0.1"
}
},
"stringstream": { "stringstream": {
"version": "0.0.5", "version": "0.0.5",
"bundled": true, "bundled": true,
@ -4338,6 +4360,36 @@
"pinkie-promise": "2.0.1" "pinkie-promise": "2.0.1"
} }
}, },
"google-fonts-webpack-plugin": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/google-fonts-webpack-plugin/-/google-fonts-webpack-plugin-0.4.4.tgz",
"integrity": "sha512-+e2D9/DVBG9EDydRovzoqMZ658SsTBGbC0c65GyZqkwNvdj8vRSYQKXqbz7/yt7QaXsCPT1MpH45r3ivWOitcw==",
"dev": true,
"requires": {
"lodash": "4.17.4",
"node-fetch": "1.7.3",
"webpack-sources": "0.2.3",
"yauzl": "2.9.1"
},
"dependencies": {
"source-list-map": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.2.tgz",
"integrity": "sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE=",
"dev": true
},
"webpack-sources": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz",
"integrity": "sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=",
"dev": true,
"requires": {
"source-list-map": "1.1.2",
"source-map": "0.5.6"
}
}
}
},
"graceful-fs": { "graceful-fs": {
"version": "4.1.11", "version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
@ -5504,7 +5556,7 @@
"integrity": "sha512-I97zvGOZ6fJ9OFfYv+QmgBpDWbC+UaP5ERJ3oraTyk1v+ABAL4tazris5ym5qL2iLe+qNjXNM/iP8LQcoZMEWw==", "integrity": "sha512-I97zvGOZ6fJ9OFfYv+QmgBpDWbC+UaP5ERJ3oraTyk1v+ABAL4tazris5ym5qL2iLe+qNjXNM/iP8LQcoZMEWw==",
"dev": true, "dev": true,
"requires": { "requires": {
"encoding-down": "3.0.0", "encoding-down": "3.0.1",
"levelup": "2.0.1" "levelup": "2.0.1"
} }
}, },
@ -6198,6 +6250,12 @@
"white-space-x": "3.0.0" "white-space-x": "3.0.0"
} }
}, },
"normalize-wheel": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
"integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU=",
"dev": true
},
"npm-run-path": { "npm-run-path": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
@ -6534,6 +6592,12 @@
"sha.js": "2.4.9" "sha.js": "2.4.9"
} }
}, },
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
"dev": true
},
"pepjs": { "pepjs": {
"version": "0.4.3", "version": "0.4.3",
"resolved": "https://registry.npmjs.org/pepjs/-/pepjs-0.4.3.tgz", "resolved": "https://registry.npmjs.org/pepjs/-/pepjs-0.4.3.tgz",
@ -6596,9 +6660,9 @@
} }
}, },
"pouchdb": { "pouchdb": {
"version": "6.4.0", "version": "6.4.1",
"resolved": "https://registry.npmjs.org/pouchdb/-/pouchdb-6.4.0.tgz", "resolved": "https://registry.npmjs.org/pouchdb/-/pouchdb-6.4.1.tgz",
"integrity": "sha512-R9sm7USMctC1/itY9UdtA8iVOF04Ui+rsGnNdO9zLTpolzglWskSL/0B3RQ2OchGYLNgsaZS0UzQ7AQ1SHXobg==", "integrity": "sha512-7YrhsBXbQh/iPA8O5Nzixi9QigaQJjqbbCFr+D7Kc258oeXNW9a0t/tOME1Lh84TJiFRuN9982FGVnrBrUhLiA==",
"dev": true, "dev": true,
"requires": { "requires": {
"argsarray": "0.0.1", "argsarray": "0.0.1",
@ -6679,7 +6743,7 @@
"npmlog": "4.1.2", "npmlog": "4.1.2",
"os-homedir": "1.0.2", "os-homedir": "1.0.2",
"pump": "1.0.3", "pump": "1.0.3",
"rc": "1.2.2", "rc": "1.2.3",
"simple-get": "1.4.3", "simple-get": "1.4.3",
"tar-fs": "1.16.0", "tar-fs": "1.16.0",
"tunnel-agent": "0.6.0", "tunnel-agent": "0.6.0",
@ -6802,7 +6866,7 @@
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
"dev": true, "dev": true,
"requires": { "requires": {
"end-of-stream": "1.4.0", "end-of-stream": "1.4.1",
"once": "1.4.0" "once": "1.4.0"
} }
}, },
@ -6818,6 +6882,16 @@
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
"dev": true "dev": true
}, },
"query-string": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.0.1.tgz",
"integrity": "sha512-aM+MkQClojlNiKkO09tiN2Fv8jM/L7GWIjG2liWeKljlOdOPNWr+bW3KQ+w5V/uKprpezC7fAsAMsJtJ+2rLKA==",
"requires": {
"decode-uri-component": "0.2.0",
"object-assign": "4.1.1",
"strict-uri-encode": "1.1.0"
}
},
"querystring": { "querystring": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
@ -6944,9 +7018,9 @@
"dev": true "dev": true
}, },
"rc": { "rc": {
"version": "1.2.2", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.3.tgz",
"integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", "integrity": "sha1-UVdakA+N1oOBxxC0cSwhVMPiA1s=",
"dev": true, "dev": true,
"requires": { "requires": {
"deep-extend": "0.4.2", "deep-extend": "0.4.2",
@ -7210,7 +7284,7 @@
"dev": true, "dev": true,
"requires": { "requires": {
"deep-equal": "1.0.1", "deep-equal": "1.0.1",
"es6-error": "4.0.2", "es6-error": "4.1.1",
"hoist-non-react-statics": "2.3.1", "hoist-non-react-statics": "2.3.1",
"invariant": "2.2.2", "invariant": "2.2.2",
"is-promise": "2.1.0", "is-promise": "2.1.0",
@ -7873,14 +7947,10 @@
"xtend": "4.0.1" "xtend": "4.0.1"
} }
}, },
"string_decoder": { "strict-uri-encode": {
"version": "1.0.3", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
"integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
}, },
"string-width": { "string-width": {
"version": "2.1.1", "version": "2.1.1",
@ -7915,6 +7985,15 @@
} }
} }
}, },
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"stringstream": { "stringstream": {
"version": "0.0.5", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
@ -7991,7 +8070,7 @@
"dev": true, "dev": true,
"requires": { "requires": {
"bl": "1.2.1", "bl": "1.2.1",
"end-of-stream": "1.4.0", "end-of-stream": "1.4.1",
"readable-stream": "2.3.3", "readable-stream": "2.3.3",
"xtend": "4.0.1" "xtend": "4.0.1"
} }
@ -9036,6 +9115,16 @@
} }
} }
}, },
"yauzl": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz",
"integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=",
"dev": true,
"requires": {
"buffer-crc32": "0.2.13",
"fd-slicer": "1.0.1"
}
},
"yml-loader": { "yml-loader": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/yml-loader/-/yml-loader-2.1.0.tgz", "resolved": "https://registry.npmjs.org/yml-loader/-/yml-loader-2.1.0.tgz",

View File

@ -16,11 +16,13 @@
}, },
"dependencies": { "dependencies": {
"@doodle3d/clipper-js": "^1.0.7", "@doodle3d/clipper-js": "^1.0.7",
"@doodle3d/doodle3d-core": "github:doodle3d/doodle3d-core",
"babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-class-properties": "^6.24.1",
"file-saver": "^1.3.3", "file-saver": "^1.3.3",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"material-ui": "^0.19.4", "material-ui": "^0.19.4",
"proptypes": "^1.1.0", "proptypes": "^1.1.0",
"query-string": "^5.0.1",
"react": "^16.0.0", "react": "^16.0.0",
"react-dom": "^16.0.0", "react-dom": "^16.0.0",
"react-jss": "^7.2.0", "react-jss": "^7.2.0",
@ -28,7 +30,6 @@
"three": "^0.88.0" "three": "^0.88.0"
}, },
"devDependencies": { "devDependencies": {
"@doodle3d/doodle3d-core": "github:doodle3d/doodle3d-core",
"babel-cli": "6.24.1", "babel-cli": "6.24.1",
"babel-loader": "7.0.0", "babel-loader": "7.0.0",
"babel-plugin-transform-es2015-classes": "^6.24.1", "babel-plugin-transform-es2015-classes": "^6.24.1",

View File

@ -4,7 +4,7 @@ import { Quaternion } from 'three/src/math/Quaternion.js';
import { Vector3 } from 'three/src/math/Vector3.js'; import { Vector3 } from 'three/src/math/Vector3.js';
import { Mesh } from 'three/src/objects/Mesh.js'; import { Mesh } from 'three/src/objects/Mesh.js';
import PropTypes from 'proptypes'; import PropTypes from 'proptypes';
import { placeOnGround, createScene, fetchProgress, slice, TabTemplate } from './utils.js'; import { centerGeometry, placeOnGround, createScene, fetchProgress, slice, TabTemplate } from './utils.js';
import injectSheet from 'react-jss'; import injectSheet from 'react-jss';
import RaisedButton from 'material-ui/RaisedButton'; import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton'; import FlatButton from 'material-ui/FlatButton';
@ -21,6 +21,10 @@ import printerSettings from '../settings/printer.yml';
import materialSettings from '../settings/material.yml'; import materialSettings from '../settings/material.yml';
import qualitySettings from '../settings/quality.yml'; import qualitySettings from '../settings/quality.yml';
import ReactResizeDetector from 'react-resize-detector'; import ReactResizeDetector from 'react-resize-detector';
import JSONToSketchData from 'doodle3d-core/shape/JSONToSketchData';
import createSceneData from 'doodle3d-core/d3/createSceneData.js';
import { generateExportMesh } from 'doodle3d-core/utils/exportUtils.js';
import { Matrix4 } from 'three/src/math/Matrix4.js';
const MAX_FULLSCREEN_WIDTH = 720; const MAX_FULLSCREEN_WIDTH = 720;
@ -82,7 +86,10 @@ const styles = {
class Interface extends React.Component { class Interface extends React.Component {
static propTypes = { static propTypes = {
mesh: PropTypes.shape({ isMesh: PropTypes.oneOf([true]) }).isRequired, file: PropTypes.oneOfType([
PropTypes.shape({ isMesh: PropTypes.oneOf([true]) }),
PropTypes.string
]).isRequired,
classes: PropTypes.objectOf(PropTypes.string), classes: PropTypes.objectOf(PropTypes.string),
defaultSettings: PropTypes.object.isRequired, defaultSettings: PropTypes.object.isRequired,
printers: PropTypes.object.isRequired, printers: PropTypes.object.isRequired,
@ -110,9 +117,11 @@ class Interface extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
const { defaultPrinter, defaultQuality, defaultMaterial, printers, quality, material, defaultSettings } = props; const { defaultPrinter, defaultQuality, defaultMaterial, printers, quality, material, defaultSettings } = props;
this.state = { this.state = {
showFullScreen: false, showFullScreen: false,
isSlicing: false, isSlicing: false,
isLoading: true,
error: null, error: null,
printers: defaultPrinter, printers: defaultPrinter,
quality: defaultQuality, quality: defaultQuality,
@ -133,9 +142,35 @@ class Interface extends React.Component {
componentDidMount() { componentDidMount() {
const { canvas } = this.refs; const { canvas } = this.refs;
const scene = createScene(canvas, this.props, this.state); const scene = createScene(canvas, this.props, this.state);
this.setState({ ...scene });
this.setState({ scene });
const { file } = this.props;
if (!file) {
throw new Error('no file provided');
} if (typeof file === 'string') {
fetch(file)
.then(resonse => resonse.json())
.then(json => JSONToSketchData(json))
.then(file => createSceneData(file))
.then(sketch => generateExportMesh(sketch, { offsetSingleWalls: false, matrix: new Matrix4() }))
.then(mesh => this.updateMesh(mesh, scene));
} else if (file.isMesh) {
this.updateMesh(file, scene);
} else {
throw new Error('unknown file property');
}
}
updateMesh(mesh, scene) {
scene.mesh.geometry = mesh.geometry;
centerGeometry(scene.mesh);
placeOnGround(scene.mesh);
scene.render();
this.setState({ mesh, isLoading: false });
} }
componentWillUnmount() { componentWillUnmount() {
@ -146,8 +181,8 @@ class Interface extends React.Component {
} }
resetMesh = () => { resetMesh = () => {
if (isSlicing) return;
const { scene: { mesh, render }, isSlicing, isLoading } = this.state; const { scene: { mesh, render }, isSlicing, isLoading } = this.state;
if (isSlicing || isLoading) return;
if (mesh) { if (mesh) {
mesh.position.set(0, 0, 0); mesh.position.set(0, 0, 0);
mesh.scale.set(1, 1, 1); mesh.scale.set(1, 1, 1);
@ -161,8 +196,8 @@ class Interface extends React.Component {
scaleUp = () => this.scaleMesh(0.9); scaleUp = () => this.scaleMesh(0.9);
scaleDown = () => this.scaleMesh(1.0 / 0.9); scaleDown = () => this.scaleMesh(1.0 / 0.9);
scaleMesh = (factor) => { scaleMesh = (factor) => {
if (isSlicing) return;
const { scene: { mesh, render }, isSlicing, isLoading } = this.state; const { scene: { mesh, render }, isSlicing, isLoading } = this.state;
if (isSlicing || isLoading) return;
if (mesh) { if (mesh) {
mesh.scale.multiplyScalar(factor); mesh.scale.multiplyScalar(factor);
mesh.updateMatrix(); mesh.updateMatrix();
@ -175,8 +210,8 @@ class Interface extends React.Component {
rotateY = () => this.rotate(new Vector3(1, 0, 0), Math.PI / 2.0); rotateY = () => this.rotate(new Vector3(1, 0, 0), Math.PI / 2.0);
rotateZ = () => this.rotate(new Vector3(0, 1, 0), Math.PI / 2.0); rotateZ = () => this.rotate(new Vector3(0, 1, 0), Math.PI / 2.0);
rotate = (axis, angle) => { rotate = (axis, angle) => {
if (isSlicing) return;
const { scene: { mesh, render }, isSlicing, isLoading } = this.state; const { scene: { mesh, render }, isSlicing, isLoading } = this.state;
if (isSlicing || isLoading) return;
if (mesh) { if (mesh) {
mesh.rotateOnWorldAxis(axis, angle); mesh.rotateOnWorldAxis(axis, angle);
placeOnGround(mesh); placeOnGround(mesh);
@ -185,10 +220,10 @@ class Interface extends React.Component {
}; };
slice = async (target) => { slice = async (target) => {
const { isSlicing, isLoading, settings, printers, quality, scene: { material, mesh: { matrix } } } = this.state; const { isSlicing, isLoading, settings, printers, quality, mesh, scene: { material, mesh: { matrix } } } = this.state;
const { name, mesh } = this.props; const { name } = this.props;
if (isSlicing) return; if (isSlicing || isLoading) return;
this.closePopover(); this.closePopover();
@ -265,14 +300,15 @@ class Interface extends React.Component {
render() { render() {
const { classes, defaultPrinter, defaultQuality, defaultMaterial, onCancel } = this.props; const { classes, defaultPrinter, defaultQuality, defaultMaterial, onCancel } = this.props;
const { isSlicing, progress, settings, printers, quality, material, showFullScreen, error } = this.state; const { isSlicing, isLoading, progress, settings, printers, quality, material, showFullScreen, error } = this.state;
const disableUI = isSlicing || isLoading;
const style = { ...(showFullScreen ? {} : { maxWidth: 'inherit', width: '100%', height: '100%' }) }; const style = { ...(showFullScreen ? {} : { maxWidth: 'inherit', width: '100%', height: '100%' }) };
const settingsPanel = ( const settingsPanel = (
<div className={classes.settingsBar} style={style}> <div className={classes.settingsBar} style={style}>
<Settings <Settings
disabled={isSlicing} disabled={disableUI}
printers={printerSettings} printers={printerSettings}
defaultPrinter={defaultPrinter} defaultPrinter={defaultPrinter}
quality={qualitySettings} quality={qualitySettings}
@ -298,7 +334,7 @@ class Interface extends React.Component {
primary primary
className={`${classes.button}`} className={`${classes.button}`}
onTouchTap={this.openPopover} onTouchTap={this.openPopover}
disabled={isSlicing} disabled={disableUI}
/> />
<Popover <Popover
open={this.state.popover.open} open={this.state.popover.open}
@ -322,12 +358,12 @@ class Interface extends React.Component {
<ReactResizeDetector handleWidth handleHeight onResize={this.onResize3dView} /> <ReactResizeDetector handleWidth handleHeight onResize={this.onResize3dView} />
<canvas className={classes.canvas} ref="canvas" /> <canvas className={classes.canvas} ref="canvas" />
<div className={classes.controlBar}> <div className={classes.controlBar}>
<RaisedButton disabled={isSlicing} className={classes.controlButton} onTouchTap={this.resetMesh} label="reset" /> <RaisedButton disabled={disableUI} className={classes.controlButton} onTouchTap={this.resetMesh} label="reset" />
<RaisedButton disabled={isSlicing} className={classes.controlButton} onTouchTap={this.scaleUp} label="scale down" /> <RaisedButton disabled={disableUI} className={classes.controlButton} onTouchTap={this.scaleUp} label="scale down" />
<RaisedButton disabled={isSlicing} className={classes.controlButton} onTouchTap={this.scaleDown} label="scale up" /> <RaisedButton disabled={disableUI} className={classes.controlButton} onTouchTap={this.scaleDown} label="scale up" />
<RaisedButton disabled={isSlicing} className={classes.controlButton} onTouchTap={this.rotateX} label="rotate x" /> <RaisedButton disabled={disableUI} className={classes.controlButton} onTouchTap={this.rotateX} label="rotate x" />
<RaisedButton disabled={isSlicing} className={classes.controlButton} onTouchTap={this.rotateY} label="rotate y" /> <RaisedButton disabled={disableUI} className={classes.controlButton} onTouchTap={this.rotateY} label="rotate y" />
<RaisedButton disabled={isSlicing} className={classes.controlButton} onTouchTap={this.rotateZ} label="rotate z" /> <RaisedButton disabled={disableUI} className={classes.controlButton} onTouchTap={this.rotateZ} label="rotate z" />
</div> </div>
</div> </div>
); );

View File

@ -27,14 +27,16 @@ export function placeOnGround(mesh) {
mesh.updateMatrix(); mesh.updateMatrix();
} }
export function createScene(canvas, props, state) { export function centerGeometry(mesh) {
const { pixelRatio, mesh: { geometry } } = props;
const { settings } = state;
// center geometry // center geometry
geometry.computeBoundingBox(); mesh.geometry.computeBoundingBox();
const center = geometry.boundingBox.getCenter(); const center = mesh.geometry.boundingBox.getCenter();
geometry.applyMatrix(new Matrix4().makeTranslation(-center.x, -center.y, -center.z)); mesh.geometry.applyMatrix(new Matrix4().makeTranslation(-center.x, -center.y, -center.z));
}
export function createScene(canvas, props, state) {
const { pixelRatio } = props;
const { settings } = state;
const scene = new Scene(); const scene = new Scene();
@ -53,8 +55,7 @@ export function createScene(canvas, props, state) {
scene.add(light); scene.add(light);
const material = new MeshPhongMaterial({ color: 0x2194ce, side: DoubleSide, specular: 0xc5c5c5, shininess: 5 }); const material = new MeshPhongMaterial({ color: 0x2194ce, side: DoubleSide, specular: 0xc5c5c5, shininess: 5 });
const mesh = new Mesh(geometry, material); const mesh = new Mesh(new THREE.Geometry(), material);
placeOnGround(mesh);
scene.add(mesh); scene.add(mesh);
const box = new BoxHelper(new Mesh(new BoxGeometry(1, 1, 1).applyMatrix(new Matrix4().makeTranslation(0, 0.5, 0))), 0x72bcd4); const box = new BoxHelper(new Mesh(new BoxGeometry(1, 1, 1).applyMatrix(new Matrix4().makeTranslation(0, 0.5, 0))), 0x72bcd4);