@jscad/web 2.5.10 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +1 -1
- package/dist/jscad-web.min.js +959 -2030
- package/examples/CHANGELOG.md +30 -0
- package/examples/README.md +1 -5
- package/examples/package.json +1 -1
- package/examples/parameters/gear.js +1 -1
- package/locales/README.md +23 -0
- package/locales/de.json +1 -0
- package/locales/en.json +2 -1
- package/locales/fr.json +1 -0
- package/locales/hr.json +1 -0
- package/locales/ja.json +1 -0
- package/locales/zh.json +62 -0
- package/package.json +7 -7
- package/postInstall.js +0 -1
- package/src/index.js +2 -1
- package/src/sideEffects/i18n/index.js +2 -1
- package/src/sideEffects/worker/index.js +7 -8
- package/src/ui/flow/design.js +10 -305
- package/src/ui/flow/reducers.js +304 -0
- package/examples/old/benchmark-cag.jscad +0 -27
- package/examples/old/benchmark-csg.jscad +0 -29
- package/examples/old/benchmark.jscad +0 -25
- package/examples/old/bunch-cubes.jscad +0 -17
- package/examples/old/complex/example001.jscad +0 -31
- package/examples/old/complex/example002.jscad +0 -25
- package/examples/old/complex/example003.jscad +0 -25
- package/examples/old/complex/example004.jscad +0 -16
- package/examples/old/complex/example005.jscad +0 -27
- package/examples/old/complex/globe.js +0 -235
- package/examples/old/complex/iphone4-case.js +0 -213
- package/examples/old/complex/umbilical_torus.js +0 -43
- package/examples/old/complex/umbilical_torus.scad +0 -37
- package/examples/old/core/cncCutout.js +0 -16
- package/examples/old/core/connectors/servo.js +0 -185
- package/examples/old/core/extrusions/extrudeLinear.js +0 -24
- package/examples/old/core/extrusions/extrudeRectangular.js +0 -21
- package/examples/old/core/extrusions/extrudeRotate.js +0 -43
- package/examples/old/core/extrusions/slices/four2three-round.js +0 -62
- package/examples/old/core/extrusions/slices/four2three.js +0 -53
- package/examples/old/core/extrusions/slices/jar-barrel.js +0 -60
- package/examples/old/core/extrusions/slices/jar.js +0 -69
- package/examples/old/core/extrusions/slices/non-aff.js +0 -72
- package/examples/old/core/extrusions/slices/rose.js +0 -52
- package/examples/old/core/extrusions/slices/screw.js +0 -34
- package/examples/old/core/extrusions/slices/screwDouble.js +0 -34
- package/examples/old/core/extrusions/slices/slices.js +0 -43
- package/examples/old/core/extrusions/slices/spring.js +0 -41
- package/examples/old/core/extrusions/slices/three2four.js +0 -42
- package/examples/old/core/extrusions/slices/tor.js +0 -30
- package/examples/old/core/hulls/hullChain.js +0 -58
- package/examples/old/core/lookup.js +0 -19
- package/examples/old/core/platonics/main.jscad +0 -42
- package/examples/old/core/platonics/maths_geodesic.jscad +0 -192
- package/examples/old/core/platonics/origv07/dualdodeca_difference.stl +0 -1962
- package/examples/old/core/platonics/origv07/dualdodeca_intersection.stl +0 -1374
- package/examples/old/core/platonics/origv07/dualdodeca_union.stl +0 -1822
- package/examples/old/core/platonics/origv07/maths_geodesic.scad +0 -162
- package/examples/old/core/platonics/origv07/platonic.scad +0 -483
- package/examples/old/core/platonics/origv07/test_platonic.scad +0 -616
- package/examples/old/core/platonics/platonic.jscad +0 -528
- package/examples/old/core/text/textSimplex.js +0 -625
- package/examples/old/core/transforms/transformations.js +0 -29
- package/examples/old/echo.jscad +0 -7
- package/examples/old/formats/scad/example001.scad +0 -26
- package/examples/old/formats/scad/example002.scad +0 -23
- package/examples/old/formats/scad/example003.scad +0 -20
- package/examples/old/formats/scad/example004.scad +0 -11
- package/examples/old/formats/scad/example005.scad +0 -20
- package/examples/old/json_logo.json +0 -1
- package/examples/old/parameters/axis-coupler.js +0 -149
- package/examples/old/parameters/celtic-knot-ring.js +0 -300
- package/examples/old/parameters/grille.js +0 -257
- package/examples/old/parameters/lamp-shade.js +0 -369
- package/examples/old/parameters/name-plate.js +0 -46
- package/examples/old/parameters/s-hook.js +0 -131
- package/examples/old/parameters/stepper-motor.js +0 -127
- package/examples/old/various/logo.js +0 -32
- package/examples/old/voxel.json +0 -1
package/examples/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,36 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.4.2](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/examples@2.4.1...@jscad/examples@2.4.2) (2022-07-17)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @jscad/examples
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [2.4.1](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/examples@2.4.0...@jscad/examples@2.4.1) (2022-06-12)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* **examples:** create uniform segments for involute gear example ([#1093](https://github.com/jscad/OpenJSCAD.org/issues/1093)) ([0b234f3](https://github.com/jscad/OpenJSCAD.org/commit/0b234f3f8ff6b39a967900089e2d939295163b68))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# [2.4.0](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/examples@2.3.4...@jscad/examples@2.4.0) (2022-05-15)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
* **examples:** new Nuts and Bolts example ([#1081](https://github.com/jscad/OpenJSCAD.org/issues/1081)) ([cd78003](https://github.com/jscad/OpenJSCAD.org/commit/cd7800351e56f7cd75f0add07cf068df328b7839))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
6
36
|
## [2.3.4](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/examples@2.3.3...@jscad/examples@2.3.4) (2022-04-24)
|
|
7
37
|
|
|
8
38
|
**Note:** Version bump only for package @jscad/examples
|
package/examples/README.md
CHANGED
|
@@ -10,7 +10,7 @@ packages like @jscad/cli , @jscad/web, @jscad/desktop
|
|
|
10
10
|
[](https://github.com/jscad/OpenJSCAD.org/blob/master/LICENSE)
|
|
11
11
|
|
|
12
12
|
[](https://openjscad.nodebb.com/)
|
|
13
|
-
[](https://
|
|
13
|
+
[](https://lerna.js.org/)
|
|
14
14
|
[](https://standardjs.com)
|
|
15
15
|
|
|
16
16
|
[](https://opencollective.com/openjscad)
|
|
@@ -63,9 +63,5 @@ See for more details
|
|
|
63
63
|
(unless specified otherwise)
|
|
64
64
|
|
|
65
65
|
Some content released under different licence:
|
|
66
|
-
- thing_7-Zomboe.stl: CC-BY-NC-SA
|
|
67
66
|
- 3d_sculpture-VernonBussler.stl: CC-BY-SA
|
|
68
67
|
- frog-OwenCollins.stl: CC-BY-NC-SA
|
|
69
|
-
- organic_flower-Bogoboy23.stl: CC-BY
|
|
70
|
-
- treefrog-Jerrill.stl: CC-BY-NC-SA
|
|
71
|
-
- yoda-RichRap.stl: CC-BY-SA
|
package/examples/package.json
CHANGED
|
@@ -50,7 +50,7 @@ const createSingleToothPolygon = (maxAngle, baseRadius, angularToothWidthAtBase)
|
|
|
50
50
|
const points = [[0, 0]]
|
|
51
51
|
for (let i = 0; i <= toothCurveResolution; i++) {
|
|
52
52
|
// first side of the tooth:
|
|
53
|
-
const angle = maxAngle * i / toothCurveResolution
|
|
53
|
+
const angle = maxAngle * Math.pow(i / toothCurveResolution, 2 / 3)
|
|
54
54
|
const tanLength = angle * baseRadius
|
|
55
55
|
let radiantVector = vec2.fromAngleRadians(vec2.create(), angle)
|
|
56
56
|
let tangentVector = vec2.scale(vec2.create(), vec2.normal(vec2.create(), radiantVector), -tanLength)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Locales for JSCAD
|
|
2
|
+
|
|
3
|
+
These files specific the language phrases for JSCAD, where each language has a specific file.
|
|
4
|
+
The files are named after the ISO code for the language, i.e. 'zh' for chinese.
|
|
5
|
+
|
|
6
|
+
So, just copy en.json to create a new file (zh.json), and translate the phrases.
|
|
7
|
+
The file should have an extra entry for the new language as well, i.e. "chinese":"中文"
|
|
8
|
+
|
|
9
|
+
Oh! Don't forget that each language (file) needs a new entry, e.g. "chinese":"中国語" for Japanese.
|
|
10
|
+
Translations are easy using BING translator, etc.
|
|
11
|
+
|
|
12
|
+
Finally, the new language needs to be registered by changing the following files.
|
|
13
|
+
```
|
|
14
|
+
src/index.js
|
|
15
|
+
src/sideEffects/i18n/index.js
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Be sure to test the new language by running...
|
|
19
|
+
```
|
|
20
|
+
npm run dev
|
|
21
|
+
```
|
|
22
|
+
And opening the given URL.
|
|
23
|
+
|
package/locales/de.json
CHANGED
package/locales/en.json
CHANGED
package/locales/fr.json
CHANGED
package/locales/hr.json
CHANGED
package/locales/ja.json
CHANGED
package/locales/zh.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"language":"chinese",
|
|
3
|
+
|
|
4
|
+
"english":"英文",
|
|
5
|
+
"german":"德文",
|
|
6
|
+
"french":"法文",
|
|
7
|
+
"japanese":"日文",
|
|
8
|
+
"croatian":"克罗地亚语",
|
|
9
|
+
"chinese":"中文",
|
|
10
|
+
|
|
11
|
+
"Languages":"语言",
|
|
12
|
+
"Themes":"工场外观",
|
|
13
|
+
|
|
14
|
+
"Generation":"生成几何图形",
|
|
15
|
+
"enable geometry caching":"开启图形缓存(实验性)",
|
|
16
|
+
"timeout for generation":"超时停止生成时间(单位:毫秒)",
|
|
17
|
+
|
|
18
|
+
"Shortcuts":"快捷键",
|
|
19
|
+
|
|
20
|
+
"Command":"命令",
|
|
21
|
+
"Key Binding":"快捷键绑定",
|
|
22
|
+
"When":"起效条件",
|
|
23
|
+
"type and hit enter":"输入快捷键,按回车生效",
|
|
24
|
+
|
|
25
|
+
"not settable":"(只读)",
|
|
26
|
+
"see":"见",
|
|
27
|
+
|
|
28
|
+
"grid":"显示网格",
|
|
29
|
+
"axes":"显示坐标轴",
|
|
30
|
+
"auto rotate": "开启自动旋转",
|
|
31
|
+
"auto reload": "开启自动刷新",
|
|
32
|
+
"auto zoom": "开启自动缩放",
|
|
33
|
+
"export":"导出",
|
|
34
|
+
"load project":"载入项目",
|
|
35
|
+
|
|
36
|
+
"AMF (experimental)":"AMF(实验性)",
|
|
37
|
+
"DXF (ASCII)":"DXF (字符版)",
|
|
38
|
+
"json":"JSON",
|
|
39
|
+
"STL (Binary)":"STL (二进制版)",
|
|
40
|
+
"STL (ASCII)":"STL (字符版)",
|
|
41
|
+
|
|
42
|
+
"update":"更新",
|
|
43
|
+
"reset":"重置",
|
|
44
|
+
"instant update":"立即刷新",
|
|
45
|
+
|
|
46
|
+
"toPresetView":"重置视图",
|
|
47
|
+
"front":"前",
|
|
48
|
+
"back":"后",
|
|
49
|
+
"top":"上",
|
|
50
|
+
"bottom":"下",
|
|
51
|
+
"left":"左",
|
|
52
|
+
"right":"右",
|
|
53
|
+
|
|
54
|
+
"setProjectionType":"视图类型",
|
|
55
|
+
"perspective":"透视",
|
|
56
|
+
"orthographic":"正视",
|
|
57
|
+
|
|
58
|
+
"editorCommand":"编辑器命令",
|
|
59
|
+
"reevaluate":"编译",
|
|
60
|
+
|
|
61
|
+
"always":"永远"
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jscad/web",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Web Application for JSCAD",
|
|
5
5
|
"homepage": "https://openjscad.xyz/",
|
|
6
6
|
"repository": "https://github.com/jscad/OpenJSCAD.org",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@jscad/array-utils": "2.1.4",
|
|
39
|
-
"@jscad/core": "2.6.
|
|
40
|
-
"@jscad/examples": "2.4.
|
|
41
|
-
"@jscad/io": "2.
|
|
42
|
-
"@jscad/modeling": "2.
|
|
43
|
-
"@jscad/regl-renderer": "2.6.
|
|
39
|
+
"@jscad/core": "2.6.3",
|
|
40
|
+
"@jscad/examples": "2.4.2",
|
|
41
|
+
"@jscad/io": "2.4.2",
|
|
42
|
+
"@jscad/modeling": "2.10.0",
|
|
43
|
+
"@jscad/regl-renderer": "2.6.3",
|
|
44
44
|
"@most/create": "2.0.1",
|
|
45
45
|
"brace": "0.11.1",
|
|
46
46
|
"codemirror": "5.65.2",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"url": "https://opencollective.com/openjscad",
|
|
68
68
|
"logo": "https://opencollective.com/openjscad/logo.txt"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "13572067545460affd53b64b3ab834a39af8c7e5"
|
|
71
71
|
}
|
package/postInstall.js
CHANGED
|
@@ -29,7 +29,6 @@ const processExamplesInDirectory = (dir, examples) => {
|
|
|
29
29
|
files.forEach((fileName) => {
|
|
30
30
|
const filePath = path.join(dir, fileName)
|
|
31
31
|
if (fs.lstatSync(filePath).isDirectory()) {
|
|
32
|
-
if (fileName === 'old') return
|
|
33
32
|
processExamplesInDirectory(filePath, examples)
|
|
34
33
|
} else if (filePath.endsWith('.js')) {
|
|
35
34
|
processExamplesFile(filePath, examples)
|
package/src/index.js
CHANGED
|
@@ -55,7 +55,8 @@ const makeJscad = async (targetElement, options) => {
|
|
|
55
55
|
fr: require('../locales/fr.json'),
|
|
56
56
|
de: require('../locales/de.json'),
|
|
57
57
|
ja: require('../locales/ja.json'),
|
|
58
|
-
hr: require('../locales/hr.json')
|
|
58
|
+
hr: require('../locales/hr.json'),
|
|
59
|
+
zh: require('../locales/zh.json')
|
|
59
60
|
},
|
|
60
61
|
logging
|
|
61
62
|
})
|
|
@@ -5,25 +5,24 @@ const callBackToStream = require('../../most-utils/callbackToObservable')
|
|
|
5
5
|
const makeWorkerEffect = (workerPath) => {
|
|
6
6
|
const workerEventsCb = callBackToStream()
|
|
7
7
|
|
|
8
|
-
let _worker = WebWorkify(workerPath)
|
|
8
|
+
let _worker = WebWorkify(workerPath, {})
|
|
9
9
|
_worker.onerror = (error) => workerEventsCb.callback({ error })
|
|
10
10
|
_worker.onmessage = (message) => workerEventsCb.callback(message)
|
|
11
11
|
|
|
12
12
|
const workerSink = (outToWorker$) => {
|
|
13
13
|
// cancel whatever is going on in the worker by terminating it
|
|
14
14
|
outToWorker$.filter(({ cmd }) => cmd === 'cancel')
|
|
15
|
-
.forEach((_) => _worker.terminate())
|
|
16
|
-
|
|
17
|
-
// send other messages to the worker
|
|
18
|
-
outToWorker$
|
|
19
|
-
.filter(({ cmd }) => cmd !== 'cancel')
|
|
20
15
|
.forEach((task) => {
|
|
21
|
-
// FIXME: sub optimal ! worker recreation is SLOW and should not be systematic
|
|
22
16
|
_worker.terminate()
|
|
23
17
|
_worker = WebWorkify(workerPath)
|
|
24
18
|
_worker.onerror = (error) => workerEventsCb.callback({ error })
|
|
25
19
|
_worker.onmessage = (message) => workerEventsCb.callback(message)
|
|
26
|
-
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
// send other messages to the worker
|
|
23
|
+
outToWorker$
|
|
24
|
+
.filter(({ cmd }) => cmd !== 'cancel')
|
|
25
|
+
.forEach((task) => {
|
|
27
26
|
_worker.postMessage(task)
|
|
28
27
|
})
|
|
29
28
|
}
|
package/src/ui/flow/design.js
CHANGED
|
@@ -1,309 +1,14 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
1
|
const most = require('most')
|
|
3
2
|
|
|
4
3
|
const { delayFromObservable, holdUntil, withLatestFrom } = require('../../most-utils')
|
|
5
4
|
|
|
6
|
-
const {
|
|
7
|
-
const { getDesignEntryPoint, getDesignName } = require('@jscad/core').loading.requireDesignUtilsFs
|
|
8
|
-
const { makeFakeFs } = require('@jscad/core').loading
|
|
5
|
+
const { getParameterValuesFromUIControls } = require('@jscad/core').parameters
|
|
9
6
|
|
|
10
|
-
const { keep } = require('../../utils/object')
|
|
11
7
|
const { fetchUriParams, getAllUriParams } = require('../../utils/urlUtils')
|
|
12
|
-
const { availableExportFormatsFromSolids, exportFilePathFromFormatAndDesign } = require('../../core/io/exportUtils')
|
|
13
|
-
const packageMetadata = require('../../../package.json')
|
|
14
8
|
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
// what fields should we check to determine if two designs are the same
|
|
18
|
-
const designEqualityFields = [
|
|
19
|
-
'parameterDefinitions',
|
|
20
|
-
'parameterValues',
|
|
21
|
-
'mainPath',
|
|
22
|
-
'filesAndFolders',
|
|
23
|
-
'vtreeMode' // also trigger a recompute when vtree mode is enabled/ disabled
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
// what fields we want to de/serialize
|
|
27
|
-
const serializableFields = [
|
|
28
|
-
'name',
|
|
29
|
-
'mainPath',
|
|
30
|
-
'origin',
|
|
31
|
-
'parameterValues',
|
|
32
|
-
'vtreeMode',
|
|
33
|
-
'autoReload',
|
|
34
|
-
'instantUpdate',
|
|
35
|
-
'solidsTimeOut'
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
const reducers = {
|
|
39
|
-
/** initialise the design's state
|
|
40
|
-
* @returns {Object} the default state for designs
|
|
41
|
-
*/
|
|
42
|
-
initialize: (state) => {
|
|
43
|
-
const design = {
|
|
44
|
-
// metadata
|
|
45
|
-
name: '',
|
|
46
|
-
path: '',
|
|
47
|
-
mainPath: '',
|
|
48
|
-
origin: undefined, // where the design came from : http, local etc
|
|
49
|
-
filesAndFolders: [], // file tree, of sorts
|
|
50
|
-
// code
|
|
51
|
-
instantUpdate: false,
|
|
52
|
-
autoReload: false,
|
|
53
|
-
// parameters
|
|
54
|
-
parameterDefinitions: [],
|
|
55
|
-
parameterValues: {},
|
|
56
|
-
parameterDefaults: {},
|
|
57
|
-
// solids
|
|
58
|
-
solidsTimeOut: 80000,
|
|
59
|
-
solids: [],
|
|
60
|
-
// geometry caching
|
|
61
|
-
vtreeMode: false,
|
|
62
|
-
lookup: {},
|
|
63
|
-
lookupCounts: {},
|
|
64
|
-
debug: {
|
|
65
|
-
startTime: 0,
|
|
66
|
-
endTime: 0,
|
|
67
|
-
totalTime: 0
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return { design }
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
/** reset the content of the design
|
|
74
|
-
* @param {Object} state
|
|
75
|
-
* @param {String} payload
|
|
76
|
-
* @returns {Object} the updated state
|
|
77
|
-
*/
|
|
78
|
-
resetDesign: (state, origin) => {
|
|
79
|
-
// we reset only the given fields: mostly all except design specific things
|
|
80
|
-
const fieldsToReset = [
|
|
81
|
-
'name', 'path', 'mainPath', 'origin', 'filesAndFolders',
|
|
82
|
-
'parameterDefinitions', 'parameterValues', 'parameterDefaults',
|
|
83
|
-
'lookup', 'lookupCounts', 'debug', 'solids'
|
|
84
|
-
]
|
|
85
|
-
const design = Object.assign({},
|
|
86
|
-
state.design, keep(fieldsToReset, reducers.initialize().design)
|
|
87
|
-
)
|
|
88
|
-
// ugh
|
|
89
|
-
design.origin = origin
|
|
90
|
-
return { design }
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
/** set the content of the design usually after a reset
|
|
94
|
-
* bulk of the data is set here
|
|
95
|
-
* @param {Object} state
|
|
96
|
-
* @param {String} payload
|
|
97
|
-
* @returns {Object} the updated state
|
|
98
|
-
*/
|
|
99
|
-
setDesignContent: (state, payload) => {
|
|
100
|
-
// all our available data (specific to web)
|
|
101
|
-
const { filesAndFolders } = payload
|
|
102
|
-
const fakeFs = makeFakeFs(filesAndFolders)
|
|
103
|
-
const rootPath = filesAndFolders[0].fullPath
|
|
104
|
-
const mainPath = getDesignEntryPoint(fakeFs, rootPath)
|
|
105
|
-
const designName = getDesignName(fakeFs, rootPath)
|
|
106
|
-
const designPath = path.dirname(rootPath)
|
|
107
|
-
|
|
108
|
-
let design = state.design
|
|
109
|
-
// to track computation time
|
|
110
|
-
const debug = Object.assign({ }, state.design.debug, { startTime: new Date() })
|
|
111
|
-
|
|
112
|
-
design = Object.assign({}, design, {
|
|
113
|
-
name: designName,
|
|
114
|
-
path: designPath,
|
|
115
|
-
mainPath,
|
|
116
|
-
filesAndFolders,
|
|
117
|
-
debug
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
const appTitle = `jscad v ${packageMetadata.version}: ${state.design.name}`
|
|
121
|
-
|
|
122
|
-
// FIXME: this is the same as clear errors ?
|
|
123
|
-
const status = Object.assign({}, state.status, { busy: true, error: undefined })
|
|
124
|
-
return {
|
|
125
|
-
design,
|
|
126
|
-
appTitle,
|
|
127
|
-
status
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
/** set the solids (2d/ 3D /csg/cag data), and the geometry cache if applicable
|
|
132
|
-
* @param {} state
|
|
133
|
-
* @param {} {solids
|
|
134
|
-
* @param {} lookup
|
|
135
|
-
* @param {} lookupCounts}
|
|
136
|
-
* @returns {Object} the updated state
|
|
137
|
-
*/
|
|
138
|
-
setDesignSolids: (state, { solids, lookup, lookupCounts }) => {
|
|
139
|
-
solids = solids || []
|
|
140
|
-
lookup = lookup || {}
|
|
141
|
-
lookupCounts = lookupCounts || {}
|
|
142
|
-
|
|
143
|
-
// should debug be part of status ?
|
|
144
|
-
const endTime = new Date()
|
|
145
|
-
const totalTime = endTime - state.design.debug.startTime
|
|
146
|
-
const debug = Object.assign({ }, state.design.debug, {
|
|
147
|
-
endTime,
|
|
148
|
-
totalTime
|
|
149
|
-
})
|
|
150
|
-
console.warn('total time for design regeneration', totalTime, new Date().getSeconds())
|
|
151
|
-
|
|
152
|
-
const design = Object.assign({}, state.design, {
|
|
153
|
-
solids,
|
|
154
|
-
lookup,
|
|
155
|
-
lookupCounts,
|
|
156
|
-
debug
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
// TODO: move this to IO ??
|
|
160
|
-
const { exportFormat, availableExportFormats } = availableExportFormatsFromSolids(solids)
|
|
161
|
-
const exportInfos = exportFilePathFromFormatAndDesign(design, exportFormat)
|
|
162
|
-
const io = {
|
|
163
|
-
exportFormat,
|
|
164
|
-
exportFilePath: exportInfos.exportFilePath, // default export file path
|
|
165
|
-
availableExportFormats
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const status = Object.assign({}, state.status, { busy: false })
|
|
169
|
-
|
|
170
|
-
return {
|
|
171
|
-
design,
|
|
172
|
-
status,
|
|
173
|
-
io
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
setDesignParameterDefinitions: (state, data) => {
|
|
178
|
-
const parameterDefaults = data.parameterDefaults || state.design.parameterDefaults
|
|
179
|
-
const parameterDefinitions = data.parameterDefinitions || state.design.parameterDefinitions
|
|
180
|
-
const design = Object.assign({}, state.design, {
|
|
181
|
-
parameterDefaults,
|
|
182
|
-
parameterDefinitions,
|
|
183
|
-
parametersOrigin: data.origin
|
|
184
|
-
})
|
|
185
|
-
return { design }
|
|
186
|
-
},
|
|
187
|
-
|
|
188
|
-
/** set the parameters of this design
|
|
189
|
-
* @param {Object} state
|
|
190
|
-
* @param {} {parameterDefaults
|
|
191
|
-
* @param {} parameterValues
|
|
192
|
-
* @param {} parameterDefinitions}
|
|
193
|
-
* @returns {Object} the updated state
|
|
194
|
-
*/
|
|
195
|
-
setDesignParameterValues: (state, data) => {
|
|
196
|
-
let parameterValues = data.parameterValues
|
|
197
|
-
// one of many ways of filtering out data from instantUpdates
|
|
198
|
-
if (data.origin === 'instantUpdate' && !state.design.instantUpdate) {
|
|
199
|
-
parameterValues = state.design.parameterValues
|
|
200
|
-
}
|
|
201
|
-
parameterValues = parameterValues ? applyParameterDefinitions(parameterValues, state.design.parameterDefinitions) : parameterValues
|
|
202
|
-
parameterValues = Object.assign({}, state.design.parameterValues, parameterValues)
|
|
203
|
-
|
|
204
|
-
let design = Object.assign({}, state.design, {
|
|
205
|
-
parameterValues,
|
|
206
|
-
parametersOrigin: data.origin
|
|
207
|
-
})
|
|
208
|
-
// to track computation time
|
|
209
|
-
const debug = Object.assign({ }, state.design.debug, { startTime: new Date() })
|
|
210
|
-
design = Object.assign({}, design, { debug })
|
|
211
|
-
|
|
212
|
-
const status = Object.assign({}, state.status, { busy: true, error: undefined })
|
|
213
|
-
|
|
214
|
-
return {
|
|
215
|
-
design,
|
|
216
|
-
status
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
|
|
220
|
-
setSettings: (state, { data }) => {
|
|
221
|
-
const {
|
|
222
|
-
vtreeMode,
|
|
223
|
-
autoReload,
|
|
224
|
-
instantUpdate,
|
|
225
|
-
solidsTimeOut
|
|
226
|
-
} = data
|
|
227
|
-
// FIXME : clunky but needed to make sure we have no invalid settings
|
|
228
|
-
if (vtreeMode === undefined) {
|
|
229
|
-
return { design: state.design }
|
|
230
|
-
}
|
|
231
|
-
const design = Object.assign({}, state.design, { vtreeMode, autoReload, instantUpdate, solidsTimeOut })
|
|
232
|
-
return {
|
|
233
|
-
design
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
|
|
237
|
-
requestGeometryRecompute: ({ design }, _) => keep(['mainPath', 'parameterValues', 'filesAndFolders', 'vtreeMode', 'lookup', 'lookupCounts'], design),
|
|
238
|
-
|
|
239
|
-
timeoutGeometryRecompute: ({ status }, _) => {
|
|
240
|
-
if (status.isBusy) { // still computing... we can kill it
|
|
241
|
-
return Object.assign({}, status, {
|
|
242
|
-
busy: false,
|
|
243
|
-
error: new Error('Failed to generate design within an acceptable time, bailing out')
|
|
244
|
-
})
|
|
245
|
-
}
|
|
246
|
-
// no problem, just act as a no-op
|
|
247
|
-
return { status }
|
|
248
|
-
},
|
|
249
|
-
|
|
250
|
-
requestWriteCachedGeometry: ({ design }, cache) => {
|
|
251
|
-
const data = {}
|
|
252
|
-
Object.keys(cache).forEach((key) => {
|
|
253
|
-
data[key] = cache[key]
|
|
254
|
-
})
|
|
255
|
-
// we want to save the geometry cache under '.solidsCache'
|
|
256
|
-
return { path: '.solidsCache', options: { isRawData: true }, origin: design.origin }
|
|
257
|
-
},
|
|
258
|
-
|
|
259
|
-
// what do we want to save , return an object containing only that data?
|
|
260
|
-
requestSaveSettings: ({ design }) => keep(serializableFields, design),
|
|
261
|
-
|
|
262
|
-
// helpers
|
|
263
|
-
isDesignValid: (state) => (state.design && state.design.name && state.design.path !== ''),
|
|
264
|
-
|
|
265
|
-
// determine if a design has remained the same : does NOT include solids, as they are a result of all the other parameters
|
|
266
|
-
isDesignTheSame: (previousState, state) => {
|
|
267
|
-
if (!previousState.design) {
|
|
268
|
-
return false
|
|
269
|
-
}
|
|
270
|
-
const current = JSON.stringify(keep(designEqualityFields, state.design))
|
|
271
|
-
const previous = JSON.stringify(keep(designEqualityFields, previousState.design))
|
|
272
|
-
return previous === current
|
|
273
|
-
},
|
|
274
|
-
|
|
275
|
-
// same as above but with added fields for settings
|
|
276
|
-
isDesignTheSameForSerialization: (previousState, state) => {
|
|
277
|
-
if (!previousState.design) {
|
|
278
|
-
return false
|
|
279
|
-
}
|
|
280
|
-
// do a JSON compare of the previous & current fields to save if needed
|
|
281
|
-
const current = JSON.stringify(keep(serializableFields, state.design))
|
|
282
|
-
const previous = JSON.stringify(keep(serializableFields, previousState.design))
|
|
283
|
-
return previous === current
|
|
284
|
-
},
|
|
9
|
+
const reducers = require('./reducers')
|
|
285
10
|
|
|
286
|
-
|
|
287
|
-
toggleAutoReload: (state, autoReload) => {
|
|
288
|
-
const design = Object.assign({}, state.design, { autoReload })
|
|
289
|
-
return { design }
|
|
290
|
-
},
|
|
291
|
-
|
|
292
|
-
toggleInstantUpdate: (state, instantUpdate) => {
|
|
293
|
-
const design = Object.assign({}, state.design, { instantUpdate })
|
|
294
|
-
return { design }
|
|
295
|
-
},
|
|
296
|
-
|
|
297
|
-
toggleVtreeMode: (state, vtreeMode) => {
|
|
298
|
-
const design = Object.assign({}, state.design, { vtreeMode })
|
|
299
|
-
return { design }
|
|
300
|
-
},
|
|
301
|
-
|
|
302
|
-
setSolidsTimeout: (state, solidsTimeOut) => {
|
|
303
|
-
const design = Object.assign({}, state.design, { solidsTimeOut })
|
|
304
|
-
return { design }
|
|
305
|
-
}
|
|
306
|
-
} // end of reducers
|
|
11
|
+
const jsonCompare = (first, second) => JSON.stringify(first) === JSON.stringify(second)
|
|
307
12
|
|
|
308
13
|
const actions = ({ sources }) => {
|
|
309
14
|
const initialize$ = most.just({})
|
|
@@ -315,11 +20,11 @@ const actions = ({ sources }) => {
|
|
|
315
20
|
const requestLoadSettings$ = initialize$
|
|
316
21
|
.map((_) => ({ sink: 'store', key: 'design', type: 'read' }))
|
|
317
22
|
|
|
318
|
-
// starts
|
|
23
|
+
// starts emitting to storage only AFTER initial settings have been loaded
|
|
319
24
|
const requestSaveSettings$ = sources.state
|
|
320
25
|
.filter(reducers.isDesignValid)
|
|
321
26
|
.skipRepeatsWith(reducers.isDesignTheSameForSerialization)
|
|
322
|
-
// wait until we
|
|
27
|
+
// wait until we actually have design data
|
|
323
28
|
.thru(holdUntil(sources.store.filter((reply) => reply.key === 'design' && reply.type === 'read')))
|
|
324
29
|
.map(reducers.requestSaveSettings)
|
|
325
30
|
.map((data) => Object.assign({}, { data }, { sink: 'store', key: 'design', type: 'write' }))
|
|
@@ -446,7 +151,7 @@ const actions = ({ sources }) => {
|
|
|
446
151
|
const resetDesign$ = most.mergeArray([
|
|
447
152
|
requestLoadDesignContent$.map(({ sink }) => sink)
|
|
448
153
|
])
|
|
449
|
-
// .thru(holdUntil(setDesignSettings$))// only after FIXME : this does not seem to work
|
|
154
|
+
// .thru(holdUntil(setDesignSettings$)) // only after FIXME : this does not seem to work
|
|
450
155
|
.thru(withLatestFrom(reducers.resetDesign, sources.state))
|
|
451
156
|
.map((data) => ({ type: 'resetDesign', state: data, sink: 'state' }))
|
|
452
157
|
.multicast()
|
|
@@ -491,7 +196,7 @@ const actions = ({ sources }) => {
|
|
|
491
196
|
|
|
492
197
|
// we also re-use the timeout to send a signal to the worker to terminate the current geometry generation
|
|
493
198
|
const cancelGeometryRecompute$ = timeoutGeometryRecompute$
|
|
494
|
-
.filter(({ state }) => state.status.error !== undefined)// if there was no error
|
|
199
|
+
.filter(({ state }) => state.status.error !== undefined) // if there was no error, the timeout is irrelevant
|
|
495
200
|
.map((_) => Object.assign({}, { sink: 'geometryWorker', cmd: 'cancel' }))
|
|
496
201
|
.multicast()
|
|
497
202
|
|
|
@@ -539,13 +244,13 @@ const actions = ({ sources }) => {
|
|
|
539
244
|
.multicast()
|
|
540
245
|
.debounce(10)
|
|
541
246
|
|
|
542
|
-
// parameter values etc
|
|
247
|
+
// parameter values etc retrieved from local storage
|
|
543
248
|
const parametersFromStore$ = sources.store
|
|
544
249
|
.filter((reply) => reply.key === 'design' && reply.type === 'read' && reply.data.parameterValues !== undefined)
|
|
545
250
|
.map(({ data }) => ({ parameterValues: data.parameterValues, origin: 'store' }))
|
|
546
251
|
.multicast()
|
|
547
252
|
|
|
548
|
-
// parameter values
|
|
253
|
+
// parameter values retrieved from titleBar
|
|
549
254
|
const parametersFromTitleBar$ = sources.titleBar
|
|
550
255
|
.map((uri) => getAllUriParams(uri))
|
|
551
256
|
.filter((params) => Object.keys(params).length > 0)
|
|
@@ -573,7 +278,7 @@ const actions = ({ sources }) => {
|
|
|
573
278
|
.thru(withLatestFrom(reducers.setDesignParameterValues, sources.state))
|
|
574
279
|
.map((data) => ({ type: 'setDesignParameterValues', state: data, sink: 'state' }))
|
|
575
280
|
.multicast()
|
|
576
|
-
.delay(10) // needed
|
|
281
|
+
.delay(10) // needed, why?
|
|
577
282
|
|
|
578
283
|
// errors retrieved from worker
|
|
579
284
|
const errorsFromWorker$ = sources.solidWorker
|