diff --git a/.gitignore b/.gitignore
index 555f981..6e08204 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
/public/build/
/.vscode
/.idea
+/src/solver/node_modules/
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 3ffd6ff..e85d18a 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -2,32 +2,58 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -62,6 +88,7 @@
+
@@ -71,15 +98,21 @@
+
-
-
-
+
+
+
+
+
+
+
+
@@ -110,6 +143,10 @@
+
+
+
+
@@ -117,11 +154,21 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -130,26 +177,30 @@
-
+
-
+
-
-
+
+
+
+
+
+
-
+
-
+
-
+
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index e5d4bae..6000ff3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -212,6 +212,14 @@
"picomatch": "^2.0.4"
}
},
+ "as-bind": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/as-bind/-/as-bind-0.7.1.tgz",
+ "integrity": "sha512-x/tfZZcyObwvAohhVYaKqLSvroMHqop3l9gkUO5JM0bBEdhI3BWXjkG3DZIuWj0YFzhQ8OiWG3FCvQQq/5yB3A==",
+ "requires": {
+ "visitor-as": "^0.5.0"
+ }
+ },
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -246,8 +254,7 @@
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
- "dev": true
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
},
"builtin-modules": {
"version": "3.2.0",
@@ -545,6 +552,11 @@
"resolved": "https://registry.npmjs.org/local-access/-/local-access-1.1.0.tgz",
"integrity": "sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw=="
},
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
+ },
"magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
@@ -820,7 +832,6 @@
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
- "dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -829,8 +840,7 @@
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
@@ -927,6 +937,11 @@
"resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz",
"integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g=="
},
+ "ts-mixer": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz",
+ "integrity": "sha512-Zo9HgPCtNouDgJ+LGtrzVOjSg8+7WGQktIKLwAfaNrlOK1mWGlz1ejsAF/YqUEqAGjUTeB5fEg8gH9Aui6w9xA=="
+ },
"tslib": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz",
@@ -938,6 +953,15 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.0-dev.20210525.tgz",
"integrity": "sha512-hpPEilDaUKKUgh7UmsjDzf3+8dSVICYRHxrXLFOhhKe5gHktNYVFGYdRhUApIPbWhAbwJxIssM3X89QW/+y/+A=="
},
+ "visitor-as": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/visitor-as/-/visitor-as-0.5.0.tgz",
+ "integrity": "sha512-U2P13pa7BAnfj6IEbP4feS1Rci6NT4GlDcwpqkk90u7LGalc5jH9aMuWnxTC8RJJ92iZzDQ8Lea5/OnLDsgzlw==",
+ "requires": {
+ "lodash.clonedeep": "^4.5.0",
+ "ts-mixer": "^5.1.0"
+ }
+ },
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
diff --git a/package.json b/package.json
index 93d9969..b28b47e 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,9 @@
"tslib": "^2.0.0"
},
"dependencies": {
+ "as-bind": "^0.7.1",
"sirv-cli": "^1.0.0",
+ "source-map-support": "^0.5.19",
"three": "^0.128.0",
"typescript": "^4.4.0-dev.20210525"
}
diff --git a/public/global.css b/public/global.css
index 76424a8..c06a6d8 100644
--- a/public/global.css
+++ b/public/global.css
@@ -63,3 +63,10 @@ button:not(:disabled):active {
button:focus {
border-color: #666;
}
+
+::-webkit-scrollbar {
+ background-color: transparent;
+}
+::-webkit-scrollbar-thumb {
+ background-color: rgba(0,0,0,0.25);
+}
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index 5da7ed3..d982c8d 100644
--- a/public/index.html
+++ b/public/index.html
@@ -6,11 +6,11 @@
Svelte app
-
-
-
+
+
+
-
+
diff --git a/public/resources/bevel-cube/000000.mtl b/public/resources/bevel-cube/000000.mtl
deleted file mode 100644
index 5882e03..0000000
--- a/public/resources/bevel-cube/000000.mtl
+++ /dev/null
@@ -1,12 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500.000001
-Ka 1.000000 1.000000 1.000000
-Kd 0.800000 0.800000 0.800000
-Ks 0.800000 0.800000 0.800000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2
diff --git a/public/resources/bevel-cube/000001.mtl b/public/resources/bevel-cube/000001.mtl
deleted file mode 100644
index f231bdf..0000000
--- a/public/resources/bevel-cube/000001.mtl
+++ /dev/null
@@ -1,10 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500
-Ka 0.8 0.8 0.8
-Kd 0.8 0.8 0.8
-Ks 0.8 0.8 0.8
-d 1
-illum 2
diff --git a/public/resources/bevel-cube/000001.obj b/public/resources/bevel-cube/000001.obj
deleted file mode 100644
index 05a67fe..0000000
--- a/public/resources/bevel-cube/000001.obj
+++ /dev/null
@@ -1,287 +0,0 @@
-# Blender v2.82 (sub 7) OBJ File: ''
-# www.blender.org
-mtllib 000001.mtl
-o Cube_Cube.001
-v -0.447727 0.391799 0.476834
-v -0.391799 0.391799 0.500000
-v -0.391799 0.447727 0.476834
-v -0.449707 0.449707 0.449707
-v -0.391799 0.476834 0.447727
-v -0.391799 0.500000 0.391799
-v -0.447727 0.476834 0.391799
-v -0.476834 0.391799 0.447727
-v -0.476834 0.447727 0.391799
-v -0.500000 0.391799 0.391799
-v -0.447727 0.476834 -0.391799
-v -0.391799 0.500000 -0.391799
-v -0.391799 0.476834 -0.447727
-v -0.449707 0.449707 -0.449707
-v -0.391799 0.447727 -0.476834
-v -0.391799 0.391799 -0.500000
-v -0.447727 0.391799 -0.476834
-v -0.476834 0.447727 -0.391799
-v -0.476834 0.391799 -0.447727
-v -0.500000 0.391799 -0.391799
-v 0.447727 0.476834 0.391799
-v 0.391799 0.500000 0.391799
-v 0.391799 0.476834 0.447727
-v 0.449707 0.449707 0.449707
-v 0.391799 0.447727 0.476834
-v 0.391799 0.391799 0.500000
-v 0.447727 0.391799 0.476834
-v 0.476834 0.447727 0.391799
-v 0.476834 0.391799 0.447727
-v 0.500000 0.391799 0.391799
-v 0.391799 0.476834 -0.447727
-v 0.391799 0.500000 -0.391799
-v 0.447727 0.476834 -0.391799
-v 0.449707 0.449707 -0.449707
-v 0.476834 0.447727 -0.391799
-v 0.500000 0.391799 -0.391799
-v 0.476834 0.391799 -0.447727
-v 0.391799 0.447727 -0.476834
-v 0.447727 0.391799 -0.476834
-v 0.391799 0.391799 -0.500000
-v -0.447727 -0.504219 0.476834
-v -0.391799 -0.504219 0.500000
-v -0.476834 -0.504219 0.447727
-v -0.500000 -0.504219 0.391799
-v -0.391799 -0.504219 -0.500000
-v -0.447727 -0.504219 -0.476834
-v -0.476834 -0.504219 -0.447727
-v -0.500000 -0.504219 -0.391799
-v 0.391799 -0.504219 0.500000
-v 0.447727 -0.504219 0.476834
-v 0.476834 -0.504219 0.447727
-v 0.500000 -0.504219 0.391799
-v 0.500000 -0.504219 -0.391799
-v 0.476834 -0.504219 -0.447727
-v 0.447727 -0.504219 -0.476834
-v 0.391799 -0.504219 -0.500000
-vt 0.632277 0.527050
-vt 0.632277 0.722950
-vt 0.617723 0.722950
-vt 0.617723 0.527050
-vt 0.652050 0.736932
-vt 0.847950 0.736932
-vt 0.847950 0.744209
-vt 0.652050 0.744209
-vt 0.847950 0.513068
-vt 0.652050 0.513068
-vt 0.652050 0.505791
-vt 0.847950 0.505791
-vt 0.652050 0.527050
-vt 0.847950 0.527050
-vt 0.847950 0.722950
-vt 0.652050 0.722950
-vt 0.861932 0.722950
-vt 0.861932 0.527050
-vt 0.869209 0.527050
-vt 0.869208 0.722950
-vt 0.597950 0.986932
-vt 0.597950 0.981140
-vt 0.606140 0.981140
-vt 0.606140 0.991171
-vt 0.847950 0.731140
-vt 0.856140 0.731140
-vt 0.856140 0.741171
-vt 0.597950 0.994209
-vt 0.606140 0.989969
-vt 0.606140 1.000000
-vt 0.597950 1.000000
-vt 0.862828 0.512172
-vt 0.847950 0.500000
-vt 0.856140 0.500000
-vt 0.856140 0.510031
-vt 0.864969 0.518860
-vt 0.875000 0.518860
-vt 0.875000 0.527050
-vt 0.643860 0.722950
-vt 0.643860 0.731140
-vt 0.623797 0.731140
-vt 0.652050 0.750000
-vt 0.643860 0.750000
-vt 0.643860 0.739969
-vt 0.626203 0.731140
-vt 0.606140 0.731140
-vt 0.606140 0.722950
-vt 0.652050 0.518860
-vt 0.643860 0.518860
-vt 0.643860 0.508829
-vt 0.606140 0.527050
-vt 0.606140 0.518860
-vt 0.626203 0.518860
-vt 0.643860 0.510031
-vt 0.643860 0.500000
-vt 0.652050 0.500000
-vt 0.612828 0.986625
-vt 0.856140 0.739969
-vt 0.866171 0.731140
-vt 0.861625 0.512172
-vt 0.597950 0.257277
-vt 0.597950 0.242723
-vt 0.606140 0.248797
-vt 0.637172 0.737828
-vt 0.597950 0.757277
-vt 0.597950 0.742723
-vt 0.606140 0.748798
-vt 0.637172 0.513375
-vt 0.623797 0.518860
-vt 0.597950 0.507277
-vt 0.597950 0.492723
-vt 0.606140 0.498798
-vt 0.597950 0.222950
-vt 0.597950 0.027050
-vt 0.606140 0.027050
-vt 0.606140 0.222950
-vt 0.597950 0.472950
-vt 0.597950 0.277050
-vt 0.606140 0.277050
-vt 0.606140 0.472950
-vt 0.597950 0.722950
-vt 0.597950 0.527050
-vt 0.597950 0.972950
-vt 0.597950 0.777050
-vt 0.606140 0.777050
-vt 0.606140 0.972950
-vt 0.643860 0.500000
-vt 0.652050 0.500000
-vt 0.597950 0.757277
-vt 0.597950 0.742723
-vt 0.597950 0.994209
-vt 0.597950 0.986932
-vt 0.597950 1.000000
-vt 0.597950 0.222950
-vt 0.597950 0.027050
-vt 0.597950 0.722950
-vt 0.597950 0.527050
-vt 0.847950 0.500000
-vt 0.856140 0.500000
-vt 0.652050 0.750000
-vt 0.643860 0.750000
-vt 0.597950 0.981140
-vt 0.606140 0.527050
-vt 0.606140 0.518860
-vt 0.597950 0.257277
-vt 0.597950 0.242723
-vt 0.875000 0.518860
-vt 0.875000 0.527050
-vt 0.597950 0.507277
-vt 0.597950 0.492723
-vt 0.597950 0.472950
-vt 0.597950 0.277050
-vt 0.606140 0.731140
-vt 0.606140 0.722950
-vt 0.597950 0.972950
-vt 0.597950 0.777050
-vn 0.5505 0.8168 -0.1727
-vn 0.5518 0.8162 0.1716
-vn 0.8162 0.5518 0.1714
-vn 0.8162 0.5518 -0.1716
-vn 0.1714 0.8162 0.5518
-vn -0.1715 0.8171 0.5503
-vn -0.1714 0.5518 0.8162
-vn 0.1716 0.5518 0.8162
-vn -0.1714 0.8162 -0.5518
-vn 0.1716 0.8162 -0.5518
-vn 0.1714 0.5518 -0.8162
-vn -0.1716 0.5518 -0.8162
-vn 0.1955 0.9610 -0.1955
-vn -0.1955 0.9610 -0.1955
-vn -0.1955 0.9610 0.1955
-vn 0.1939 0.9617 0.1939
-vn -0.5518 0.8162 0.1714
-vn -0.5518 0.8162 -0.1716
-vn -0.8162 0.5518 -0.1714
-vn -0.8162 0.5518 0.1716
-vn -0.5518 0.1714 0.8162
-vn -0.1955 0.1955 0.9610
-vn -0.5795 0.5795 0.5730
-vn -0.8171 0.1716 0.5503
-vn -0.9610 0.1955 0.1955
-vn -0.5774 0.5774 -0.5774
-vn -0.1955 0.1955 -0.9610
-vn -0.5518 0.1714 -0.8162
-vn -0.8162 0.1714 -0.5518
-vn -0.9610 0.1955 -0.1955
-vn 0.5774 0.5774 0.5774
-vn 0.1955 0.1955 0.9610
-vn 0.5518 0.1714 0.8162
-vn 0.8162 0.1714 0.5518
-vn 0.9610 0.1955 0.1955
-vn 0.5739 0.5791 -0.5791
-vn 0.9610 0.1955 -0.1955
-vn 0.8156 0.1713 -0.5527
-vn 0.5518 0.1714 -0.8162
-vn 0.1955 0.1955 -0.9610
-vn 0.5556 0.0000 -0.8315
-vn 0.1951 0.0000 -0.9808
-vn 0.5556 0.0000 0.8315
-vn 0.8315 0.0000 0.5556
-vn -0.8315 0.0000 0.5556
-vn -0.5556 0.0000 0.8315
-vn -0.9808 0.0000 0.1951
-vn -0.9808 0.0000 -0.1951
-vn 0.9808 0.0000 0.1951
-vn 0.9808 0.0000 -0.1951
-vn -0.1951 0.0000 -0.9808
-vn -0.5556 0.0000 -0.8315
-vn 0.1951 0.0000 0.9808
-vn -0.1951 0.0000 0.9808
-vn 0.8315 0.0000 -0.5556
-vn -0.8315 0.0000 -0.5556
-usemtl None
-s 1
-f 33/1/1 21/2/2 28/3/3 35/4/4
-f 23/5/5 5/6/6 3/7/7 25/8/8
-f 13/9/9 31/10/10 38/11/11 15/12/12
-f 32/13/13 12/14/14 6/15/15 22/16/16
-f 7/17/17 11/18/18 18/19/19 9/20/20
-f 1/21/21 2/22/22 3/23/7 4/24/23
-f 5/6/6 6/25/15 7/26/17 4/27/23
-f 8/28/24 4/29/23 9/30/20 10/31/25
-f 11/18/18 12/14/14 13/9/9 14/32/26
-f 15/12/12 16/33/27 17/34/28 14/35/26
-f 18/19/19 14/36/26 19/37/29 20/38/30
-f 21/2/2 22/39/16 23/40/5 24/41/31
-f 25/8/8 26/42/32 27/43/33 24/44/31
-f 28/3/3 24/45/31 29/46/34 30/47/35
-f 31/10/10 32/48/13 33/49/1 34/50/36
-f 35/4/4 36/51/37 37/52/38 34/53/36
-f 38/11/11 34/54/36 39/55/39 40/56/40
-f 8/28/24 1/21/21 4/57/23
-f 3/7/7 5/6/6 4/58/23
-f 7/17/17 9/20/20 4/59/23
-f 18/19/19 11/18/18 14/60/26
-f 13/9/9 15/12/12 14/32/26
-f 17/61/28 19/62/29 14/63/26
-f 28/3/3 21/2/2 24/45/31
-f 23/5/5 25/8/8 24/64/31
-f 27/65/33 29/66/34 24/67/31
-f 38/11/11 31/10/10 34/68/36
-f 33/1/1 35/4/4 34/69/36
-f 37/70/38 39/71/39 34/72/36
-f 6/15/15 12/14/14 11/18/18 7/17/17
-f 20/73/30 10/74/25 9/75/20 18/76/19
-f 12/14/14 32/13/13 31/10/10 13/9/9
-f 40/77/40 16/78/27 15/79/12 38/80/11
-f 32/13/13 22/16/16 21/2/2 33/1/1
-f 30/81/35 36/82/37 35/4/4 28/3/3
-f 22/16/16 6/15/15 5/6/6 23/5/5
-f 2/83/22 26/84/32 25/85/8 3/86/7
-f 40/56/40 39/55/39 55/87/41 56/88/42
-f 29/66/34 27/65/33 50/89/43 51/90/44
-f 1/21/21 8/28/24 43/91/45 41/92/46
-f 8/28/24 10/31/25 44/93/47 43/91/45
-f 10/74/25 20/73/30 48/94/48 44/95/47
-f 36/82/37 30/81/35 52/96/49 53/97/50
-f 17/34/28 16/33/27 45/98/51 46/99/52
-f 27/43/33 26/42/32 49/100/53 50/101/43
-f 2/22/22 1/21/21 41/92/46 42/102/54
-f 37/52/38 36/51/37 53/103/50 54/104/55
-f 19/62/29 17/61/28 46/105/52 47/106/56
-f 20/38/30 19/37/29 47/107/56 48/108/48
-f 39/71/39 37/70/38 54/109/55 55/110/41
-f 16/78/27 40/77/40 56/111/42 45/112/51
-f 30/47/35 29/46/34 51/113/44 52/114/49
-f 26/84/32 2/83/22 42/115/54 49/116/53
diff --git a/public/resources/bevel-cube/x.mtl b/public/resources/bevel-cube/x.mtl
deleted file mode 100644
index 5882e03..0000000
--- a/public/resources/bevel-cube/x.mtl
+++ /dev/null
@@ -1,12 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500.000001
-Ka 1.000000 1.000000 1.000000
-Kd 0.800000 0.800000 0.800000
-Ks 0.800000 0.800000 0.800000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2
diff --git a/public/resources/bevel-cube/xy.mtl b/public/resources/bevel-cube/xy.mtl
deleted file mode 100644
index 5882e03..0000000
--- a/public/resources/bevel-cube/xy.mtl
+++ /dev/null
@@ -1,12 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500.000001
-Ka 1.000000 1.000000 1.000000
-Kd 0.800000 0.800000 0.800000
-Ks 0.800000 0.800000 0.800000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2
diff --git a/public/resources/bevel-cube/xy.obj b/public/resources/bevel-cube/xy.obj
deleted file mode 100644
index 5fb17c4..0000000
--- a/public/resources/bevel-cube/xy.obj
+++ /dev/null
@@ -1,299 +0,0 @@
-# Blender v2.82 (sub 7) OBJ File: ''
-# www.blender.org
-mtllib xy.mtl
-o Cube_Cube.001
-v 0.499961 0.500000 -0.499961
-v 0.499961 -0.500000 -0.499961
-v 0.499961 0.500000 0.399961
-v 0.499961 0.399961 0.500000
-v 0.499961 0.492385 0.438244
-v 0.499961 0.470699 0.470699
-v 0.499961 0.438244 0.492385
-v 0.499961 -0.399961 0.500000
-v 0.499961 -0.500000 0.399961
-v 0.499961 -0.438244 0.492385
-v 0.499961 -0.470699 0.470699
-v 0.499961 -0.492385 0.438244
-v -0.500000 0.399961 -0.499961
-v -0.399961 0.500000 -0.499961
-v -0.492385 0.438244 -0.499961
-v -0.470699 0.470699 -0.499961
-v -0.438244 0.492385 -0.499961
-v -0.399961 -0.500000 -0.499961
-v -0.500000 -0.399961 -0.499961
-v -0.438244 -0.492385 -0.499961
-v -0.470699 -0.470699 -0.499961
-v -0.492385 -0.438244 -0.499961
-v -0.500000 0.399961 0.399961
-v -0.399961 0.399961 0.500000
-v -0.399961 0.500000 0.399961
-v -0.492385 0.399961 0.438244
-v -0.470699 0.399961 0.470699
-v -0.492385 0.438244 0.399961
-v -0.483194 0.439203 0.439203
-v -0.465612 0.437212 0.465612
-v -0.457718 0.457718 0.457718
-v -0.399961 0.438244 0.492385
-v -0.399961 0.470699 0.470699
-v -0.438244 0.399961 0.492385
-v -0.439203 0.439203 0.483194
-v -0.437212 0.465612 0.465612
-v -0.438244 0.492385 0.399961
-v -0.470699 0.470699 0.399961
-v -0.399961 0.492385 0.438244
-v -0.439203 0.483194 0.439203
-v -0.465612 0.465612 0.437212
-v -0.399961 -0.399961 0.500000
-v -0.500000 -0.399961 0.399961
-v -0.399961 -0.500000 0.399961
-v -0.438244 -0.399961 0.492385
-v -0.470699 -0.399961 0.470699
-v -0.399961 -0.438244 0.492385
-v -0.439203 -0.439203 0.483194
-v -0.465612 -0.437212 0.465612
-v -0.457718 -0.457718 0.457718
-v -0.492385 -0.438244 0.399961
-v -0.470699 -0.470699 0.399961
-v -0.492385 -0.399961 0.438244
-v -0.483194 -0.439203 0.439203
-v -0.465612 -0.465612 0.437212
-v -0.399961 -0.492385 0.438244
-v -0.399961 -0.470699 0.470699
-v -0.438244 -0.492385 0.399961
-v -0.439203 -0.483194 0.439203
-v -0.437212 -0.465612 0.465612
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.150010 0.525010
-vt 0.349990 0.525010
-vt 0.349990 0.724990
-vt 0.150010 0.724990
-vt 0.400010 0.775010
-vt 0.599990 0.775010
-vt 0.599990 0.974990
-vt 0.400010 0.974990
-vt 0.400010 0.025010
-vt 0.599990 0.025010
-vt 0.599990 0.224990
-vt 0.400010 0.224990
-vt 0.599990 0.765439
-vt 0.609801 0.765199
-vt 0.609561 0.775010
-vt 0.599990 0.750000
-vt 0.609303 0.750000
-vt 0.625000 0.765697
-vt 0.625000 0.775010
-vt 0.614430 0.750000
-vt 0.359561 0.724990
-vt 0.359801 0.734801
-vt 0.349990 0.734561
-vt 0.375000 0.724990
-vt 0.375000 0.734303
-vt 0.359303 0.750000
-vt 0.349990 0.750000
-vt 0.375000 0.739430
-vt 0.599990 0.724990
-vt 0.609561 0.724990
-vt 0.609801 0.734801
-vt 0.599990 0.734561
-vt 0.625000 0.724990
-vt 0.625000 0.734303
-vt 0.609303 0.750000
-vt 0.599990 0.750000
-vt 0.625000 0.739430
-vt 0.150010 0.734561
-vt 0.140199 0.734801
-vt 0.140439 0.724990
-vt 0.150010 0.750000
-vt 0.140697 0.750000
-vt 0.125000 0.734303
-vt 0.125000 0.724990
-vt 0.135570 0.750000
-vt 0.390439 0.775010
-vt 0.390199 0.765199
-vt 0.400010 0.765439
-vt 0.375000 0.775010
-vt 0.375000 0.765697
-vt 0.390697 0.750000
-vt 0.400010 0.750000
-vt 0.375000 0.760570
-vt 0.400010 0.234561
-vt 0.390199 0.234801
-vt 0.390439 0.224990
-vt 0.400010 0.250000
-vt 0.390697 0.250000
-vt 0.375000 0.234303
-vt 0.375000 0.224990
-vt 0.385570 0.250000
-vt 0.599990 0.234561
-vt 0.599990 0.250000
-vt 0.125000 0.525010
-vt 0.140439 0.525010
-vt 0.599990 0.525010
-vt 0.609561 0.525010
-vt 0.625000 0.525010
-vt 0.625000 0.974990
-vt 0.609561 0.974990
-vt 0.390439 0.025010
-vt 0.375000 0.025010
-vt 0.375000 0.974990
-vt 0.390439 0.974990
-vt 0.400010 0.724990
-vt 0.400010 0.734561
-vt 0.400010 0.750000
-vt 0.375000 0.525010
-vt 0.359561 0.525010
-vt 0.400010 0.525010
-vn 0.0000 0.0000 -1.0000
-vn 1.0000 -0.0000 0.0000
-vn 0.0000 -0.0980 0.9952
-vn 0.0000 0.0980 0.9952
-vn -0.1004 0.1004 0.9899
-vn -0.1004 -0.1004 0.9899
-vn -0.9899 -0.1004 0.1004
-vn -0.9899 0.1004 0.1004
-vn -0.9952 0.0980 0.0000
-vn -0.9952 -0.0980 -0.0000
-vn -0.0980 -0.9952 -0.0000
-vn 0.0000 -1.0000 -0.0000
-vn 0.0000 -0.9952 0.0980
-vn -0.1004 -0.9899 0.1004
-vn -0.9201 0.0981 0.3792
-vn -0.8545 0.3673 0.3673
-vn -0.9201 0.3792 0.0981
-vn -0.7041 0.0919 0.7041
-vn -0.6663 0.3347 0.6663
-vn -0.6663 0.6663 0.3347
-vn -0.7041 0.7041 0.0919
-vn -0.5774 0.5774 0.5773
-vn -0.0981 0.3792 0.9201
-vn -0.3673 0.3673 0.8545
-vn -0.3792 0.0981 0.9201
-vn -0.0919 0.7041 0.7041
-vn -0.3347 0.6663 0.6663
-vn -0.1004 0.9899 0.1004
-vn -0.3792 0.9201 0.0981
-vn -0.3673 0.8545 0.3673
-vn -0.0981 0.9201 0.3792
-vn -0.3792 -0.0981 0.9201
-vn -0.3673 -0.3673 0.8545
-vn -0.0981 -0.3792 0.9201
-vn -0.7041 -0.0919 0.7041
-vn -0.6663 -0.3347 0.6663
-vn -0.3347 -0.6663 0.6663
-vn -0.0919 -0.7041 0.7041
-vn -0.5774 -0.5774 0.5773
-vn -0.9201 -0.3792 0.0981
-vn -0.8545 -0.3673 0.3673
-vn -0.9201 -0.0981 0.3792
-vn -0.7041 -0.7041 0.0919
-vn -0.6663 -0.6663 0.3347
-vn -0.0981 -0.9201 0.3792
-vn -0.3673 -0.8545 0.3673
-vn -0.3792 -0.9201 0.0981
-vn 0.0000 -0.9239 0.3827
-vn 0.0000 -0.7071 0.7071
-vn 0.0000 -0.3827 0.9239
-vn -0.0980 0.9952 0.0000
-vn -0.3827 0.9239 0.0000
-vn -0.7071 0.7071 0.0000
-vn -0.9239 0.3827 0.0000
-vn -0.3827 -0.9239 0.0000
-vn -0.7071 -0.7071 0.0000
-vn -0.9239 -0.3827 -0.0000
-vn 0.0000 0.9952 0.0980
-vn 0.0000 0.9239 0.3827
-vn 0.0000 0.7071 0.7071
-vn 0.0000 0.3827 0.9239
-vn 0.0000 1.0000 0.0000
-usemtl None
-s off
-f 2/1/1 18/2/1 14/3/1
-f 14/3/1 13/4/1 16/5/1
-f 13/4/1 15/6/1 16/5/1
-f 17/7/1 14/3/1 16/5/1
-f 22/8/1 19/9/1 21/10/1
-f 19/9/1 18/2/1 21/10/1
-f 18/2/1 20/11/1 21/10/1
-f 1/12/1 2/1/1 14/3/1
-f 13/4/1 14/3/1 19/9/1
-f 14/3/1 18/2/1 19/9/1
-f 3/13/2 5/14/2 6/15/2
-f 9/16/2 8/17/2 11/18/2
-f 3/13/2 2/1/2 1/12/2
-f 3/13/2 9/16/2 2/1/2
-f 9/16/2 4/19/2 8/17/2
-f 4/19/2 3/13/2 6/15/2
-f 7/20/2 4/19/2 6/15/2
-f 12/21/2 9/16/2 11/18/2
-f 4/19/2 9/16/2 3/13/2
-f 10/22/2 11/18/2 8/17/2
-s 1
-f 8/23/3 4/24/4 24/25/5 42/26/6
-f 43/27/7 23/28/8 13/29/9 19/30/10
-f 18/31/11 2/32/12 9/33/13 44/34/14
-f 23/28/8 26/35/15 29/36/16 28/37/17
-f 26/35/15 27/38/18 30/39/19 29/36/16
-f 28/37/17 29/36/16 41/40/20 38/41/21
-f 29/36/16 30/39/19 31/42/22 41/40/20
-f 24/25/5 32/43/23 35/44/24 34/45/25
-f 32/43/23 33/46/26 36/47/27 35/44/24
-f 34/45/25 35/44/24 30/48/19 27/49/18
-f 35/44/24 36/47/27 31/50/22 30/48/19
-f 25/51/28 37/52/29 40/53/30 39/54/31
-f 37/52/29 38/55/21 41/56/20 40/53/30
-f 39/54/31 40/53/30 36/57/27 33/58/26
-f 40/53/30 41/56/20 31/59/22 36/57/27
-f 42/26/6 45/60/32 48/61/33 47/62/34
-f 45/60/32 46/63/35 49/64/36 48/61/33
-f 47/62/34 48/61/33 60/65/37 57/66/38
-f 48/61/33 49/64/36 50/67/39 60/65/37
-f 43/27/7 51/68/40 54/69/41 53/70/42
-f 51/68/40 52/71/43 55/72/44 54/69/41
-f 53/70/42 54/69/41 49/73/36 46/74/35
-f 54/69/41 55/72/44 50/75/39 49/73/36
-f 44/34/14 56/76/45 59/77/46 58/78/47
-f 56/76/45 57/79/38 60/80/37 59/77/46
-f 58/78/47 59/77/46 55/81/44 52/82/43
-f 59/77/46 60/80/37 50/83/39 55/81/44
-f 44/34/14 9/33/13 12/84/48 56/76/45
-f 56/76/45 12/84/48 11/85/49 57/79/38
-f 57/66/38 11/86/49 10/87/50 47/62/34
-f 47/62/34 10/87/50 8/23/3 42/26/6
-f 25/51/28 14/88/51 17/89/52 37/52/29
-f 37/52/29 17/89/52 16/90/53 38/55/21
-f 38/41/21 16/91/53 15/92/54 28/37/17
-f 28/37/17 15/92/54 13/29/9 23/28/8
-f 18/31/11 44/34/14 58/78/47 20/93/55
-f 20/93/55 58/78/47 52/82/43 21/94/56
-f 21/95/56 52/71/43 51/68/40 22/96/57
-f 22/96/57 51/68/40 43/27/7 19/30/10
-f 3/97/58 25/51/28 39/54/31 5/98/59
-f 5/98/59 39/54/31 33/58/26 6/99/60
-f 6/100/60 33/46/26 32/43/23 7/101/61
-f 7/101/61 32/43/23 24/25/5 4/24/4
-f 42/26/6 24/25/5 34/45/25 45/60/32
-f 45/60/32 34/45/25 27/49/18 46/63/35
-f 46/74/35 27/38/18 26/35/15 53/70/42
-f 53/70/42 26/35/15 23/28/8 43/27/7
-f 1/102/62 14/88/51 25/51/28 3/97/58
diff --git a/public/resources/bevel-cube/xymx.mtl b/public/resources/bevel-cube/xymx.mtl
deleted file mode 100644
index 5882e03..0000000
--- a/public/resources/bevel-cube/xymx.mtl
+++ /dev/null
@@ -1,12 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500.000001
-Ka 1.000000 1.000000 1.000000
-Kd 0.800000 0.800000 0.800000
-Ks 0.800000 0.800000 0.800000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2
diff --git a/public/resources/bevel-cube/xymx.obj b/public/resources/bevel-cube/xymx.obj
deleted file mode 100644
index e06deca..0000000
--- a/public/resources/bevel-cube/xymx.obj
+++ /dev/null
@@ -1,131 +0,0 @@
-# Blender v2.82 (sub 7) OBJ File: ''
-# www.blender.org
-mtllib xymx.mtl
-o Cube_Cube.001
-v 0.499961 0.500000 -0.499961
-v 0.499961 -0.500000 -0.499961
-v 0.499961 0.500000 0.399961
-v 0.499961 0.399961 0.500000
-v 0.499961 0.492385 0.438244
-v 0.499961 0.470699 0.470699
-v 0.499961 0.438244 0.492385
-v 0.499961 -0.399961 0.500000
-v 0.499961 -0.500000 0.399961
-v 0.499961 -0.438244 0.492385
-v 0.499961 -0.470699 0.470699
-v 0.499961 -0.492385 0.438244
-v -0.499961 0.500000 -0.499961
-v -0.499961 -0.500000 -0.499961
-v -0.499961 0.399961 0.500000
-v -0.499961 0.500000 0.399961
-v -0.499961 0.438244 0.492385
-v -0.499961 0.470699 0.470699
-v -0.499961 0.492385 0.438244
-v -0.499961 -0.399961 0.500000
-v -0.499961 -0.500000 0.399961
-v -0.499961 -0.438244 0.492385
-v -0.499961 -0.492385 0.438244
-v -0.499961 -0.470699 0.470699
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.150010 0.525010
-vt 0.349990 0.525010
-vt 0.349990 0.724990
-vt 0.150010 0.724990
-vt 0.400010 0.025010
-vt 0.599990 0.025010
-vt 0.599990 0.224990
-vt 0.400010 0.224990
-vt 0.599990 0.234561
-vt 0.400010 0.234561
-vt 0.599990 0.250000
-vt 0.400010 0.250000
-vt 0.125000 0.724990
-vt 0.125000 0.525010
-vt 0.140439 0.525010
-vt 0.140439 0.724990
-vt 0.400010 0.724990
-vt 0.599990 0.724990
-vt 0.599990 0.734561
-vt 0.400010 0.734561
-vt 0.599990 0.750000
-vt 0.400010 0.750000
-vt 0.375000 0.525010
-vt 0.375000 0.724990
-vt 0.359561 0.724990
-vt 0.359561 0.525010
-vt 0.400010 0.525010
-vt 0.599990 0.525010
-vn 0.0000 0.0000 -1.0000
-vn 1.0000 -0.0000 0.0000
-vn -1.0000 0.0000 0.0000
-vn 0.0000 -0.0980 0.9952
-vn 0.0000 0.0980 0.9952
-vn 0.0000 -1.0000 -0.0000
-vn 0.0000 -0.9952 0.0980
-vn 0.0000 -0.9239 0.3827
-vn 0.0000 -0.7071 0.7071
-vn 0.0000 -0.3827 0.9239
-vn 0.0000 0.9952 0.0980
-vn 0.0000 0.9239 0.3827
-vn 0.0000 0.7071 0.7071
-vn 0.0000 0.3827 0.9239
-vn 0.0000 1.0000 0.0000
-usemtl None
-s off
-f 2/1/1 14/2/1 13/3/1
-f 1/4/1 2/1/1 13/3/1
-f 3/5/2 5/6/2 6/7/2
-f 9/8/2 8/9/2 11/10/2
-f 3/5/2 2/1/2 1/4/2
-f 3/5/2 9/8/2 2/1/2
-f 9/8/2 4/11/2 8/9/2
-f 4/11/2 3/5/2 6/7/2
-f 7/12/2 4/11/2 6/7/2
-f 12/13/2 9/8/2 11/10/2
-f 4/11/2 9/8/2 3/5/2
-f 10/14/2 11/10/2 8/9/2
-f 16/15/3 13/3/3 14/2/3
-f 16/15/3 14/2/3 21/16/3
-f 21/16/3 20/17/3 16/15/3
-f 20/17/3 15/18/3 16/15/3
-f 21/16/3 23/19/3 24/20/3
-f 19/21/3 16/15/3 18/22/3
-f 20/17/3 21/16/3 24/20/3
-f 15/18/3 17/23/3 18/22/3
-f 16/15/3 15/18/3 18/22/3
-f 24/20/3 22/24/3 20/17/3
-s 1
-f 8/25/4 4/26/5 15/27/5 20/28/4
-f 14/29/6 2/30/6 9/31/7 21/32/7
-f 21/32/7 9/31/7 12/33/8 23/34/8
-f 23/34/8 12/33/8 11/35/9 24/36/9
-f 24/37/9 11/38/9 10/39/10 22/40/10
-f 22/40/10 10/39/10 8/25/4 20/28/4
-f 3/41/11 16/42/11 19/43/12 5/44/12
-f 5/44/12 19/43/12 18/45/13 6/46/13
-f 6/47/13 18/48/13 17/49/14 7/50/14
-f 7/50/14 17/49/14 15/27/5 4/26/5
-f 1/51/15 13/52/15 16/42/11 3/41/11
diff --git a/public/resources/bevel-cube/xymxmy.mtl b/public/resources/bevel-cube/xymxmy.mtl
deleted file mode 100644
index 5882e03..0000000
--- a/public/resources/bevel-cube/xymxmy.mtl
+++ /dev/null
@@ -1,12 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500.000001
-Ka 1.000000 1.000000 1.000000
-Kd 0.800000 0.800000 0.800000
-Ks 0.800000 0.800000 0.800000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2
diff --git a/public/resources/bevel-cube/xyz.mtl b/public/resources/bevel-cube/xyz.mtl
deleted file mode 100644
index 5882e03..0000000
--- a/public/resources/bevel-cube/xyz.mtl
+++ /dev/null
@@ -1,12 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500.000001
-Ka 1.000000 1.000000 1.000000
-Kd 0.800000 0.800000 0.800000
-Ks 0.800000 0.800000 0.800000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2
diff --git a/public/resources/bevel-cube/xyz.obj b/public/resources/bevel-cube/xyz.obj
deleted file mode 100644
index ecc356b..0000000
--- a/public/resources/bevel-cube/xyz.obj
+++ /dev/null
@@ -1,197 +0,0 @@
-# Blender v2.82 (sub 7) OBJ File: ''
-# www.blender.org
-mtllib xyz.mtl
-o Cube_Cube.001
-v 0.499961 0.500000 -0.499961
-v 0.499961 -0.500000 -0.499961
-v 0.499961 0.499961 0.500000
-v 0.499961 -0.399961 0.500000
-v 0.499961 -0.500000 0.399961
-v 0.499961 -0.438244 0.492385
-v 0.499961 -0.470699 0.470699
-v 0.499961 -0.492385 0.438244
-v -0.500000 0.499961 -0.499961
-v -0.399961 -0.500000 -0.499961
-v -0.500000 -0.399961 -0.499961
-v -0.438244 -0.492385 -0.499961
-v -0.470699 -0.470699 -0.499961
-v -0.492385 -0.438244 -0.499961
-v -0.500000 0.499961 0.399961
-v -0.399961 0.499961 0.500000
-v -0.492385 0.499961 0.438244
-v -0.470699 0.499961 0.470699
-v -0.438244 0.499961 0.492385
-v -0.399961 -0.399961 0.500000
-v -0.500000 -0.399961 0.399961
-v -0.399961 -0.500000 0.399961
-v -0.438244 -0.399961 0.492385
-v -0.470699 -0.399961 0.470699
-v -0.399961 -0.438244 0.492385
-v -0.439203 -0.439203 0.483194
-v -0.465612 -0.437212 0.465612
-v -0.457718 -0.457718 0.457718
-v -0.492385 -0.438244 0.399961
-v -0.470699 -0.470699 0.399961
-v -0.492385 -0.399961 0.438244
-v -0.483194 -0.439203 0.439203
-v -0.465612 -0.465612 0.437212
-v -0.399961 -0.492385 0.438244
-v -0.399961 -0.470699 0.470699
-v -0.438244 -0.492385 0.399961
-v -0.439203 -0.483194 0.439203
-v -0.437212 -0.465612 0.465612
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.150010 0.525010
-vt 0.349990 0.525010
-vt 0.349990 0.724990
-vt 0.150010 0.724990
-vt 0.400010 0.775010
-vt 0.599990 0.775010
-vt 0.599990 0.974990
-vt 0.400010 0.974990
-vt 0.400010 0.025010
-vt 0.599990 0.025010
-vt 0.599990 0.224990
-vt 0.400010 0.224990
-vt 0.150010 0.734561
-vt 0.140199 0.734801
-vt 0.140439 0.724990
-vt 0.150010 0.750000
-vt 0.140697 0.750000
-vt 0.125000 0.734303
-vt 0.125000 0.724990
-vt 0.135570 0.750000
-vt 0.390439 0.775010
-vt 0.390199 0.765199
-vt 0.400010 0.765439
-vt 0.375000 0.775010
-vt 0.375000 0.765697
-vt 0.390697 0.750000
-vt 0.400010 0.750000
-vt 0.375000 0.760570
-vt 0.400010 0.234561
-vt 0.390199 0.234801
-vt 0.390439 0.224990
-vt 0.400010 0.250000
-vt 0.390697 0.250000
-vt 0.375000 0.234303
-vt 0.375000 0.224990
-vt 0.385570 0.250000
-vt 0.599990 0.234561
-vt 0.599990 0.250000
-vt 0.125000 0.525010
-vt 0.140439 0.525010
-vt 0.390439 0.025010
-vt 0.375000 0.025010
-vt 0.375000 0.974990
-vt 0.390439 0.974990
-vt 0.349990 0.734561
-vt 0.349990 0.750000
-vt 0.599990 0.750000
-vt 0.599990 0.765439
-vn -0.0000 -0.0000 -1.0000
-vn 0.0000 1.0000 0.0000
-vn 1.0000 0.0000 0.0000
-vn 0.0000 -0.0980 0.9952
-vn 0.0000 -0.0000 1.0000
-vn -0.0980 -0.0000 0.9952
-vn -0.1004 -0.1004 0.9899
-vn -0.9899 -0.1004 0.1004
-vn -0.9952 0.0000 0.0980
-vn -1.0000 0.0000 0.0000
-vn -0.9952 -0.0980 -0.0000
-vn -0.0980 -0.9952 -0.0000
-vn 0.0000 -1.0000 -0.0000
-vn 0.0000 -0.9952 0.0980
-vn -0.1004 -0.9899 0.1004
-vn -0.3792 -0.0981 0.9201
-vn -0.3673 -0.3673 0.8545
-vn -0.0981 -0.3792 0.9201
-vn -0.7041 -0.0919 0.7041
-vn -0.6663 -0.3347 0.6663
-vn -0.3347 -0.6663 0.6663
-vn -0.0919 -0.7041 0.7041
-vn -0.5774 -0.5774 0.5773
-vn -0.9201 -0.3792 0.0981
-vn -0.8545 -0.3673 0.3673
-vn -0.9201 -0.0981 0.3792
-vn -0.7041 -0.7041 0.0919
-vn -0.6663 -0.6663 0.3347
-vn -0.0981 -0.9201 0.3792
-vn -0.3673 -0.8545 0.3673
-vn -0.3792 -0.9201 0.0981
-vn 0.0000 -0.9239 0.3827
-vn 0.0000 -0.7071 0.7071
-vn 0.0000 -0.3827 0.9239
-vn -0.3827 -0.9239 0.0000
-vn -0.7071 -0.7071 0.0000
-vn -0.9239 -0.3827 -0.0000
-vn -0.3827 -0.0000 0.9239
-vn -0.7071 0.0000 0.7071
-vn -0.9239 0.0000 0.3827
-usemtl None
-s off
-f 14/1/1 11/2/1 13/3/1
-f 11/2/1 10/4/1 13/3/1
-f 10/4/1 12/5/1 13/3/1
-f 16/6/2 3/7/2 1/8/2
-f 16/6/2 15/9/2 18/10/2
-f 19/11/2 16/6/2 18/10/2
-f 1/8/1 2/12/1 10/4/1
-f 5/13/3 2/12/3 1/8/3
-f 15/9/2 16/6/2 1/8/2
-f 11/2/1 9/14/1 1/8/1
-f 15/9/2 17/15/2 18/10/2
-f 3/7/3 5/13/3 1/8/3
-f 15/9/2 1/8/2 9/14/2
-f 11/2/1 1/8/1 10/4/1
-f 5/13/3 4/16/3 7/17/3
-f 5/13/3 3/7/3 4/16/3
-f 8/18/3 5/13/3 7/17/3
-f 6/19/3 7/17/3 4/16/3
-s 1
-f 4/20/4 3/21/5 16/22/6 20/23/7
-f 21/24/8 15/25/9 9/26/10 11/27/11
-f 10/28/12 2/29/13 5/30/14 22/31/15
-f 20/23/7 23/32/16 26/33/17 25/34/18
-f 23/32/16 24/35/19 27/36/20 26/33/17
-f 25/34/18 26/33/17 38/37/21 35/38/22
-f 26/33/17 27/36/20 28/39/23 38/37/21
-f 21/24/8 29/40/24 32/41/25 31/42/26
-f 29/40/24 30/43/27 33/44/28 32/41/25
-f 31/42/26 32/41/25 27/45/20 24/46/19
-f 32/41/25 33/44/28 28/47/23 27/45/20
-f 22/31/15 34/48/29 37/49/30 36/50/31
-f 34/48/29 35/51/22 38/52/21 37/49/30
-f 36/50/31 37/49/30 33/53/28 30/54/27
-f 37/49/30 38/52/21 28/55/23 33/53/28
-f 22/31/15 5/30/14 8/56/32 34/48/29
-f 34/48/29 8/56/32 7/57/33 35/51/22
-f 35/38/22 7/58/33 6/59/34 25/34/18
-f 25/34/18 6/59/34 4/20/4 20/23/7
-f 10/28/12 22/31/15 36/50/31 12/60/35
-f 12/60/35 36/50/31 30/54/27 13/61/36
-f 13/62/36 30/43/27 29/40/24 14/63/37
-f 14/63/37 29/40/24 21/24/8 11/27/11
-f 20/23/7 16/22/6 19/64/38 23/32/16
-f 23/32/16 19/64/38 18/65/39 24/35/19
-f 24/46/19 18/66/39 17/67/40 31/42/26
-f 31/42/26 17/67/40 15/25/9 21/24/8
diff --git a/public/resources/bevel-cube/xyzmx.mtl b/public/resources/bevel-cube/xyzmx.mtl
deleted file mode 100644
index 5882e03..0000000
--- a/public/resources/bevel-cube/xyzmx.mtl
+++ /dev/null
@@ -1,12 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500.000001
-Ka 1.000000 1.000000 1.000000
-Kd 0.800000 0.800000 0.800000
-Ks 0.800000 0.800000 0.800000
-Ke 0.000000 0.000000 0.000000
-Ni 1.450000
-d 1.000000
-illum 2
diff --git a/public/resources/bevel-cube/xyzmx.obj b/public/resources/bevel-cube/xyzmx.obj
deleted file mode 100644
index c4fc922..0000000
--- a/public/resources/bevel-cube/xyzmx.obj
+++ /dev/null
@@ -1,88 +0,0 @@
-# Blender v2.82 (sub 7) OBJ File: ''
-# www.blender.org
-mtllib xyzmx.mtl
-o Cube_Cube.001
-v -0.499961 0.500000 -0.499961
-v -0.499961 -0.500000 -0.499961
-v 0.499961 -0.500000 -0.499961
-v -0.499961 0.499961 0.500000
-v -0.499961 -0.500000 0.399961
-v -0.499961 -0.399961 0.500000
-v -0.499960 -0.492385 0.438244
-v -0.499960 -0.470699 0.470699
-v -0.499960 -0.438244 0.492385
-v 0.499961 0.499961 0.500000
-v 0.499961 -0.399961 0.500000
-v 0.499961 -0.500000 0.399961
-v 0.499961 -0.438244 0.492385
-v 0.499961 -0.470699 0.470699
-v 0.499961 -0.492385 0.438244
-v 0.499961 0.500000 -0.499961
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.000000 0.000000
-vt 0.400010 0.775010
-vt 0.599990 0.775010
-vt 0.599990 0.974990
-vt 0.400010 0.974990
-vt 0.400010 0.025010
-vt 0.599990 0.025010
-vt 0.599990 0.224990
-vt 0.400010 0.224990
-vt 0.390439 0.224990
-vt 0.390439 0.025010
-vt 0.375000 0.224990
-vt 0.375000 0.025010
-vt 0.375000 0.974990
-vt 0.375000 0.775010
-vt 0.390439 0.775010
-vt 0.390439 0.974990
-vn -1.0000 0.0000 0.0000
-vn 0.0000 -0.0000 -1.0000
-vn -0.0000 1.0000 0.0000
-vn 1.0000 0.0000 -0.0000
-vn 0.0000 -0.0980 0.9952
-vn 0.0000 0.0000 1.0000
-vn 0.0000 -0.9952 0.0980
-vn 0.0000 -1.0000 -0.0000
-vn 0.0000 -0.9239 0.3827
-vn 0.0000 -0.7071 0.7071
-vn 0.0000 -0.3827 0.9239
-usemtl None
-s off
-f 9/1/1 6/2/1 8/3/1
-f 6/2/1 5/4/1 8/3/1
-f 5/4/1 7/5/1 8/3/1
-f 1/6/1 2/7/1 5/4/1
-f 3/8/2 2/7/2 1/6/2
-f 6/2/1 4/9/1 1/6/1
-f 10/10/3 1/6/3 4/9/3
-f 6/2/1 1/6/1 5/4/1
-f 16/11/3 1/6/3 10/10/3
-f 10/10/4 11/12/4 16/11/4
-f 11/12/4 13/13/4 14/14/4
-f 16/11/2 3/8/2 1/6/2
-f 12/15/4 11/12/4 14/14/4
-f 15/16/4 12/15/4 14/14/4
-f 12/15/4 3/8/4 16/11/4
-f 11/12/4 12/15/4 16/11/4
-s 1
-f 11/17/5 10/18/6 4/19/6 6/20/5
-f 5/21/7 2/22/8 3/23/8 12/24/7
-f 5/21/7 12/24/7 15/25/9 7/26/9
-f 7/26/9 15/25/9 14/27/10 8/28/10
-f 8/29/10 14/30/10 13/31/11 9/32/11
-f 9/32/11 13/31/11 11/17/5 6/20/5
diff --git a/public/resources/bevel_cube.mtl b/public/resources/bevel_cube.mtl
deleted file mode 100644
index f231bdf..0000000
--- a/public/resources/bevel_cube.mtl
+++ /dev/null
@@ -1,10 +0,0 @@
-# Blender MTL File: 'None'
-# Material Count: 1
-
-newmtl None
-Ns 500
-Ka 0.8 0.8 0.8
-Kd 0.8 0.8 0.8
-Ks 0.8 0.8 0.8
-d 1
-illum 2
diff --git a/public/resources/bevel_cube.obj b/public/resources/bevel_cube.obj
deleted file mode 100644
index e9bb051..0000000
--- a/public/resources/bevel_cube.obj
+++ /dev/null
@@ -1,557 +0,0 @@
-# Blender v2.82 (sub 7) OBJ File: ''
-# www.blender.org
-mtllib bevel_cube.mtl
-o Cube_Cube.002
-v 0.798071 -0.798071 1.000000
-v 0.798071 0.798071 1.000000
-v 1.000000 0.798071 0.798071
-v 0.798071 1.000000 0.798071
-v 1.000000 -0.798071 0.798071
-v 0.798071 -1.000000 0.798071
-v 1.000000 -0.798071 -0.798071
-v 1.000000 0.798071 -0.798071
-v 0.798071 0.798071 -1.000000
-v 0.798071 1.000000 -0.798071
-v 0.798071 -0.798071 -1.000000
-v 0.798071 -1.000000 -0.798071
-v -0.798071 -0.798071 -1.000000
-v -0.798071 0.798071 -1.000000
-v -1.000000 0.798071 -0.798071
-v -0.798071 1.000000 -0.798071
-v -0.798071 1.000000 0.798071
-v -1.000000 0.798071 0.798071
-v -0.798071 0.798071 1.000000
-v -0.798071 -0.798071 1.000000
-v -1.000000 -0.798071 -0.798071
-v -1.000000 -0.798071 0.798071
-v -0.798071 -1.000000 0.798071
-v -0.798071 -1.000000 -0.798071
-v -0.892152 -0.961030 0.798071
-v -0.798071 -1.000000 0.798071
-v -0.798071 -0.961030 0.892152
-v -0.898181 -0.910004 0.898181
-v -0.798071 -0.892152 0.961030
-v -0.798071 -0.798071 1.000000
-v -0.892152 -0.798071 0.961030
-v -0.898181 -0.898181 0.910004
-v -0.961030 -0.892152 0.798071
-v -0.910004 -0.898181 0.898181
-v -0.961030 -0.798071 0.892152
-v -1.000000 -0.798071 0.798071
-v -0.892152 0.798071 0.961030
-v -0.798071 0.798071 1.000000
-v -0.798071 0.892152 0.961030
-v -0.898181 0.898181 0.910004
-v -0.798071 0.961030 0.892152
-v -0.798071 1.000000 0.798071
-v -0.892152 0.961030 0.798071
-v -0.898181 0.910004 0.898181
-v -0.961030 0.798071 0.892152
-v -0.910004 0.898181 0.898181
-v -0.961030 0.892152 0.798071
-v -1.000000 0.798071 0.798071
-v -0.798071 -0.961030 -0.892152
-v -0.798071 -1.000000 -0.798071
-v -0.892152 -0.961030 -0.798071
-v -0.898181 -0.910004 -0.898181
-v -0.961030 -0.892152 -0.798071
-v -1.000000 -0.798071 -0.798071
-v -0.961030 -0.798071 -0.892152
-v -0.910004 -0.898181 -0.898181
-v -0.798071 -0.892152 -0.961030
-v -0.898181 -0.898181 -0.910004
-v -0.892152 -0.798071 -0.961030
-v -0.798071 -0.798071 -1.000000
-v -0.892152 0.961030 -0.798071
-v -0.798071 1.000000 -0.798071
-v -0.798071 0.961030 -0.892152
-v -0.898181 0.910004 -0.898181
-v -0.798071 0.892152 -0.961030
-v -0.798071 0.798071 -1.000000
-v -0.892152 0.798071 -0.961030
-v -0.898181 0.898181 -0.910004
-v -0.961030 0.892152 -0.798071
-v -0.910004 0.898181 -0.898181
-v -0.961030 0.798071 -0.892152
-v -1.000000 0.798071 -0.798071
-v 0.798071 -0.961030 0.892152
-v 0.798071 -1.000000 0.798071
-v 0.892152 -0.961030 0.798071
-v 0.898181 -0.910004 0.898181
-v 0.961030 -0.892152 0.798071
-v 1.000000 -0.798071 0.798071
-v 0.961030 -0.798071 0.892152
-v 0.910004 -0.898181 0.898181
-v 0.798071 -0.892152 0.961030
-v 0.898181 -0.898181 0.910004
-v 0.892152 -0.798071 0.961030
-v 0.798071 -0.798071 1.000000
-v 0.892152 0.961030 0.798071
-v 0.798071 1.000000 0.798071
-v 0.798071 0.961030 0.892152
-v 0.898181 0.910004 0.898181
-v 0.798071 0.892152 0.961030
-v 0.798071 0.798071 1.000000
-v 0.892152 0.798071 0.961030
-v 0.898181 0.898181 0.910004
-v 0.961030 0.892152 0.798071
-v 0.910004 0.898181 0.898181
-v 0.961030 0.798071 0.892152
-v 1.000000 0.798071 0.798071
-v 0.892152 -0.961030 -0.798071
-v 0.798071 -1.000000 -0.798071
-v 0.798071 -0.961030 -0.892152
-v 0.898181 -0.910004 -0.898181
-v 0.798071 -0.892152 -0.961030
-v 0.798071 -0.798071 -1.000000
-v 0.892152 -0.798071 -0.961030
-v 0.898181 -0.898181 -0.910004
-v 0.961030 -0.892152 -0.798071
-v 0.910004 -0.898181 -0.898181
-v 0.961030 -0.798071 -0.892152
-v 1.000000 -0.798071 -0.798071
-v 0.798071 0.961030 -0.892152
-v 0.798071 1.000000 -0.798071
-v 0.892152 0.961030 -0.798071
-v 0.898181 0.910004 -0.898181
-v 0.961030 0.892152 -0.798071
-v 1.000000 0.798071 -0.798071
-v 0.961030 0.798071 -0.892152
-v 0.910004 0.898181 -0.898181
-v 0.798071 0.892152 -0.961030
-v 0.898181 0.898181 -0.910004
-v 0.892152 0.798071 -0.961030
-v 0.798071 0.798071 -1.000000
-vt 0.400241 0.025241
-vt 0.599759 0.025241
-vt 0.599759 0.224759
-vt 0.400241 0.224759
-vt 0.150241 0.525241
-vt 0.349759 0.525241
-vt 0.349759 0.724759
-vt 0.150241 0.724759
-vt 0.650241 0.736519
-vt 0.849759 0.736519
-vt 0.849759 0.745129
-vt 0.650241 0.745129
-vt 0.400241 0.775241
-vt 0.599759 0.775241
-vt 0.599759 0.974759
-vt 0.400241 0.974759
-vt 0.362273 0.737273
-vt 0.363750 0.737273
-vt 0.362273 0.738750
-vt 0.599759 0.758610
-vt 0.400241 0.758610
-vt 0.400241 0.741390
-vt 0.599759 0.741390
-vt 0.400241 0.986519
-vt 0.599759 0.986519
-vt 0.599759 0.995129
-vt 0.400241 0.995129
-vt 0.150241 0.736519
-vt 0.349759 0.736519
-vt 0.349759 0.745129
-vt 0.150241 0.745129
-vt 0.138481 0.724759
-vt 0.150241 0.724759
-vt 0.137727 0.737273
-vt 0.150241 0.750000
-vt 0.143352 0.750000
-vt 0.143352 0.741563
-vt 0.599759 0.981648
-vt 0.606648 0.981648
-vt 0.606648 0.990085
-vt 0.349759 0.731648
-vt 0.356648 0.731648
-vt 0.356648 0.740085
-vt 0.383610 0.724759
-vt 0.393352 0.724759
-vt 0.393352 0.731648
-vt 0.376478 0.731648
-vt 0.356648 0.741563
-vt 0.356648 0.750000
-vt 0.349759 0.750000
-vt 0.650241 0.750000
-vt 0.643352 0.750000
-vt 0.643352 0.741563
-vt 0.366390 0.525241
-vt 0.356648 0.525241
-vt 0.356648 0.518352
-vt 0.373522 0.518352
-vt 0.137727 0.738750
-vt 0.393352 0.991563
-vt 0.393352 0.990085
-vt 0.366390 0.724759
-vt 0.373522 0.731648
-vt 0.393352 0.751478
-vt 0.393352 0.748522
-vt 0.150241 0.525241
-vt 0.138481 0.525241
-vt 0.400241 0.974759
-vt 0.599759 0.974759
-vt 0.349759 0.525241
-vt 0.150241 0.513481
-vt 0.349759 0.513481
-vt 0.349759 0.724759
-vt 0.599759 0.775241
-vt 0.400241 0.775241
-vt 0.393352 0.974759
-vt 0.393352 0.775241
-vt 0.606648 0.775241
-vt 0.606648 0.974759
-vt 0.633610 0.525241
-vt 0.633610 0.724759
-vt 0.616390 0.724759
-vt 0.616390 0.525241
-vt 0.150241 0.504871
-vt 0.349759 0.504871
-vt 0.612273 0.987273
-vt 0.613750 0.987273
-vt 0.612273 0.988751
-vt 0.862273 0.512727
-vt 0.862273 0.511250
-vt 0.863750 0.512727
-vt 0.599759 0.258610
-vt 0.400241 0.258610
-vt 0.400241 0.241390
-vt 0.599759 0.241390
-vt 0.849759 0.513481
-vt 0.650241 0.513481
-vt 0.650241 0.504871
-vt 0.849759 0.504871
-vt 0.383610 0.525241
-vt 0.362273 0.512727
-vt 0.362273 0.511250
-vt 0.363750 0.512727
-vt 0.599759 0.508610
-vt 0.400241 0.508610
-vt 0.400241 0.491390
-vt 0.599759 0.491390
-vt 0.136250 0.737273
-vt 0.137727 0.512727
-vt 0.136250 0.512727
-vt 0.137727 0.511250
-vt 0.637727 0.512727
-vt 0.636250 0.512727
-vt 0.637727 0.511250
-vt 0.637727 0.737273
-vt 0.637727 0.738750
-vt 0.636250 0.737273
-vt 0.861519 0.724759
-vt 0.861519 0.525241
-vt 0.870129 0.525241
-vt 0.870129 0.724759
-vt 0.129871 0.724759
-vt 0.133437 0.731648
-vt 0.125000 0.731648
-vt 0.125000 0.724759
-vt 0.849759 0.731648
-vt 0.856648 0.731648
-vt 0.856648 0.740085
-vt 0.606648 0.991563
-vt 0.606648 1.000000
-vt 0.599759 1.000000
-vt 0.129871 0.525241
-vt 0.125000 0.525241
-vt 0.125000 0.518352
-vt 0.133437 0.518352
-vt 0.143352 0.508437
-vt 0.143352 0.500000
-vt 0.150241 0.500000
-vt 0.849759 0.525241
-vt 0.849759 0.500000
-vt 0.856648 0.500000
-vt 0.856648 0.508437
-vt 0.866563 0.518352
-vt 0.875000 0.518352
-vt 0.875000 0.525241
-vt 0.643352 0.724759
-vt 0.643352 0.731648
-vt 0.626478 0.731648
-vt 0.623522 0.731648
-vt 0.606648 0.731648
-vt 0.606648 0.724759
-vt 0.349759 0.500000
-vt 0.356648 0.500000
-vt 0.356648 0.508437
-vt 0.376478 0.518352
-vt 0.393352 0.518352
-vt 0.393352 0.525241
-vt 0.650241 0.518352
-vt 0.643352 0.518352
-vt 0.643352 0.509915
-vt 0.606648 0.525241
-vt 0.606648 0.518352
-vt 0.623522 0.518352
-vt 0.643352 0.508437
-vt 0.643352 0.500000
-vt 0.650241 0.500000
-vt 0.856648 0.741563
-vt 0.866563 0.731648
-vt 0.865085 0.731648
-vt 0.393352 0.251478
-vt 0.393352 0.248522
-vt 0.606648 0.248522
-vt 0.606648 0.251478
-vt 0.606648 0.748522
-vt 0.606648 0.751478
-vt 0.393352 0.501478
-vt 0.393352 0.498522
-vt 0.626478 0.518352
-vt 0.606648 0.498522
-vt 0.606648 0.501478
-vt 0.400241 0.025241
-vt 0.400241 0.224759
-vt 0.393352 0.224759
-vt 0.393352 0.025241
-vt 0.599759 0.025241
-vt 0.400241 0.018352
-vt 0.599759 0.018352
-vt 0.849759 0.724759
-vt 0.599759 0.224759
-vt 0.606648 0.025241
-vt 0.606648 0.224759
-vt 0.599759 0.275241
-vt 0.400241 0.275241
-vt 0.400241 0.474759
-vt 0.393352 0.474759
-vt 0.393352 0.275241
-vt 0.650241 0.525241
-vt 0.599759 0.474759
-vt 0.606648 0.275241
-vt 0.606648 0.474759
-vt 0.599759 0.525241
-vt 0.400241 0.525241
-vt 0.400241 0.724759
-vt 0.650241 0.724759
-vt 0.599759 0.724759
-vt 0.650241 0.525241
-vt 0.849759 0.525241
-vt 0.849759 0.724759
-vt 0.650241 0.724759
-vt 0.400241 0.275241
-vt 0.599759 0.275241
-vt 0.599759 0.474759
-vt 0.400241 0.474759
-vt 0.400241 0.525241
-vt 0.599759 0.525241
-vt 0.599759 0.724759
-vt 0.400241 0.724759
-vn -1.0000 0.0000 0.0000
-vn 0.0000 -1.0000 0.0000
-vn 0.0000 0.7071 0.7071
-vn 0.0000 0.0000 1.0000
-vn 0.5774 -0.5774 0.5774
-vn 0.7071 0.0000 0.7071
-vn -0.7071 0.0000 0.7071
-vn 0.0000 -0.7071 0.7071
-vn -0.3793 -0.8439 0.3793
-vn -0.3793 -0.3793 0.8439
-vn -0.3793 0.3793 0.8439
-vn 0.3793 -0.8439 0.3793
-vn 0.8439 -0.3793 0.3793
-vn 0.3793 -0.3793 0.8439
-vn 0.3793 0.3793 0.8439
-vn 0.3793 -0.8439 -0.3793
-vn -0.3029 -0.6739 0.6739
-vn -0.6739 -0.3029 0.6739
-vn 0.3029 -0.6739 0.6739
-vn 0.6739 -0.6739 0.3029
-vn 0.6739 -0.3029 0.6739
-vn -0.3827 -0.9239 0.0000
-vn -0.3827 0.0000 0.9239
-vn 0.0000 -0.9239 -0.3827
-vn 0.3827 -0.9239 0.0000
-vn 0.3827 0.0000 0.9239
-vn 0.0000 -0.9239 0.3827
-vn 0.0000 -0.3827 0.9239
-vn 0.0000 0.3827 0.9239
-vn 0.5396 0.8233 -0.1761
-vn 0.5396 0.8233 0.1761
-vn 0.8233 0.5396 0.1761
-vn 0.8233 0.5396 -0.1761
-vn 0.1533 -0.6988 -0.6988
-vn -0.2338 -0.7625 -0.6033
-vn -0.1763 -0.5538 -0.8137
-vn 0.1787 -0.5368 -0.8246
-vn -0.5319 0.5319 0.6589
-vn -0.4969 0.7115 0.4969
-vn -0.7115 0.4969 0.4969
-vn -0.4957 0.7132 -0.4957
-vn -0.4957 0.4957 -0.7132
-vn -0.7207 0.4902 -0.4902
-vn -0.5368 0.1787 -0.8246
-vn -0.5538 -0.1763 -0.8137
-vn -0.8137 -0.1763 -0.5538
-vn -0.8137 0.1763 -0.5538
-vn -0.1761 0.8233 -0.5396
-vn 0.1761 0.8233 -0.5396
-vn 0.1761 0.5396 -0.8233
-vn -0.1761 0.5396 -0.8233
-vn 0.7071 -0.7071 0.0000
-vn 0.7008 -0.7008 -0.1330
-vn 0.8233 -0.5396 -0.1761
-vn 0.8315 -0.5556 0.0000
-vn 0.5228 -0.6733 -0.5228
-vn 0.4957 -0.4957 -0.7132
-vn 0.7132 -0.4957 -0.4957
-vn 0.8233 0.1761 -0.5396
-vn 0.8233 -0.1761 -0.5396
-vn 0.5396 -0.1761 -0.8233
-vn 0.5396 0.1761 -0.8233
-vn -0.6331 -0.6331 0.4454
-vn -0.5774 -0.5774 0.5774
-vn -0.7130 -0.5549 0.4286
-vn -0.4969 -0.7115 -0.4969
-vn -0.7115 -0.4969 -0.4969
-vn -0.4969 -0.4969 -0.7115
-vn 0.4957 0.7132 -0.4957
-vn 0.7132 0.4957 -0.4957
-vn 0.4957 0.4957 -0.7132
-vn 0.4957 0.7132 0.4957
-vn 0.5228 0.5228 0.6733
-vn 0.7132 0.4957 0.4957
-vn -0.5538 0.8137 0.1763
-vn -0.5368 0.8246 -0.1787
-vn -0.8137 0.5538 -0.1763
-vn -0.8137 0.5538 0.1763
-vn -0.8138 -0.5538 0.1763
-vn -0.9010 -0.1934 0.3884
-vn -0.9284 -0.2628 0.2628
-vn -0.2342 0.8380 0.4928
-vn -0.2628 0.9284 0.2628
-vn -0.8380 0.2342 0.4928
-vn -0.9284 0.2628 0.2628
-vn -0.3793 -0.8439 -0.3793
-vn -0.6033 -0.7625 -0.2338
-vn -0.8138 -0.5538 -0.1763
-vn -0.9284 -0.2628 -0.2628
-vn -0.2628 -0.2628 -0.9284
-vn -0.2588 0.9306 -0.2588
-vn -0.2588 0.2588 -0.9306
-vn -0.9284 0.2628 -0.2628
-vn 0.2588 0.9306 0.2588
-vn 0.2353 0.8501 0.4711
-vn 0.8501 0.2353 0.4711
-vn 0.9306 0.2588 0.2588
-vn 0.2588 -0.2588 -0.9306
-vn 0.9306 -0.2588 -0.2588
-vn 0.2588 0.9306 -0.2588
-vn 0.9306 0.2588 -0.2588
-vn 0.2588 0.2588 -0.9306
-vn -0.6988 -0.6988 0.1533
-vn -0.6739 0.3029 0.6739
-vn -0.3029 0.6739 0.6739
-vn 0.3029 0.6739 0.6739
-vn 0.6739 0.3029 0.6739
-vn 0.9239 -0.3827 0.0000
-vn 0.9239 0.0000 0.3827
-vn 0.0000 1.0000 0.0000
-vn 0.0000 0.0000 -1.0000
-vn 1.0000 0.0000 0.0000
-usemtl None
-s 1
-f 36/1/1 48/2/1 72/3/1 54/4/1
-s off
-f 50/5/2 98/6/2 74/7/2 26/8/2
-f 87/9/3 41/10/3 39/11/3 89/12/3
-f 84/13/4 90/14/4 38/15/4 30/16/4
-f 76/17/5 80/18/5 82/19/5
-f 91/20/6 83/21/6 79/22/6 95/23/6
-f 31/24/7 37/25/7 45/26/7 35/27/7
-f 27/28/8 73/29/8 81/30/8 29/31/8
-f 25/32/9 23/33/9 27/28/9 28/34/9
-f 29/31/10 20/35/10 31/36/10 32/37/10
-f 37/25/11 19/38/11 39/39/11 40/40/11
-f 73/29/12 6/41/12 75/42/12 76/43/12
-f 77/44/13 5/45/13 79/46/13 80/47/13
-f 81/30/14 82/48/14 83/49/14 1/50/14
-f 89/12/15 2/51/15 91/52/15 92/53/15
-f 97/54/16 12/55/16 99/56/16 100/57/16
-f 27/28/17 29/31/17 32/58/17 28/34/17
-f 31/24/18 35/27/18 34/59/18 32/60/18
-f 81/30/19 73/29/19 76/17/19 82/19/19
-f 75/61/20 77/44/20 80/47/20 76/62/20
-f 79/22/21 83/21/21 82/63/21 80/64/21
-f 24/65/22 23/33/22 25/32/22 51/66/22
-f 20/67/23 19/68/23 37/25/23 31/24/23
-f 12/69/24 24/65/24 49/70/24 99/71/24
-f 6/72/25 12/69/25 97/54/25 75/61/25
-f 2/73/26 1/74/26 83/21/26 91/20/26
-f 23/33/27 6/72/27 73/29/27 27/28/27
-f 1/74/28 20/67/28 29/75/28 81/76/28
-f 19/68/29 2/73/29 89/77/29 39/78/29
-s 2
-f 111/79/30 85/80/31 93/81/32 113/82/33
-f 99/71/34 49/70/35 57/83/36 101/84/37
-f 40/85/38 44/86/39 46/87/40
-f 64/88/41 68/89/42 70/90/43
-f 67/91/44 59/92/45 55/93/46 71/94/47
-f 63/95/48 109/96/49 117/97/50 65/98/51
-f 75/61/52 97/54/53 105/99/54 77/44/55
-f 100/100/56 104/101/57 106/102/58
-f 115/103/59 107/104/60 103/105/61 119/106/62
-f 28/34/63 32/58/64 34/107/65
-f 52/108/66 56/109/67 58/110/68
-f 112/111/69 116/112/70 118/113/71
-f 88/114/72 92/115/73 94/116/74
-f 43/117/75 61/118/76 69/119/77 47/120/78
-f 33/121/79 34/122/65 35/123/80 22/124/81
-f 41/10/82 17/125/83 43/126/75 44/127/39
-f 45/26/84 46/128/40 47/129/78 18/130/85
-f 49/70/35 24/65/86 51/66/87 52/108/66
-f 53/131/88 21/132/89 55/133/46 56/134/67
-f 57/83/36 58/135/68 59/136/45 13/137/90
-f 61/118/76 16/138/91 63/95/48 64/88/41
-f 65/98/51 14/139/92 67/140/44 68/141/42
-f 69/119/77 70/142/43 71/143/47 15/144/93
-f 85/80/31 4/145/94 87/146/95 88/147/72
-f 93/81/32 94/148/74 95/149/96 3/150/97
-f 101/84/37 11/151/98 103/152/61 104/153/57
-f 105/99/54 106/154/58 107/155/60 7/156/99
-f 109/96/49 10/157/100 111/158/30 112/159/69
-f 113/82/33 8/160/101 115/161/59 116/162/70
-f 117/97/50 118/163/71 119/164/62 9/165/102
-f 33/121/79 25/32/103 28/34/63 34/107/65
-f 45/26/84 37/25/104 40/85/38 46/87/40
-f 39/11/105 41/10/82 44/127/39 40/166/38
-f 43/117/75 47/120/78 46/167/40 44/168/39
-f 57/83/36 49/70/35 52/108/66 58/110/68
-f 51/66/87 53/131/88 56/109/67 52/108/66
-f 55/93/46 59/92/45 58/169/68 56/170/67
-f 69/119/77 61/118/76 64/88/41 70/90/43
-f 63/95/48 65/98/51 68/89/42 64/88/41
-f 67/91/44 71/94/47 70/171/43 68/172/42
-f 93/81/32 85/80/31 88/147/72 94/148/74
-f 87/9/95 89/12/106 92/115/73 88/114/72
-f 91/20/107 95/23/96 94/173/74 92/174/73
-f 105/99/54 97/54/53 100/57/56 106/154/58
-f 99/71/34 101/84/37 104/101/57 100/100/56
-f 103/105/61 107/104/60 106/175/58 104/176/57
-f 117/97/50 109/96/49 112/111/69 118/113/71
-f 111/79/30 113/82/33 116/162/70 112/177/69
-f 115/103/59 119/106/62 118/178/71 116/179/70
-f 22/180/81 21/181/89 53/182/88 33/183/79
-f 18/184/85 22/180/81 35/185/80 45/186/84
-f 17/187/83 16/138/91 61/118/76 43/117/75
-f 15/188/93 18/184/85 47/189/78 69/190/77
-f 14/191/92 13/192/90 59/92/45 67/91/44
-f 21/181/89 15/188/93 71/94/47 55/93/46
-f 13/192/90 11/193/98 101/194/37 57/195/36
-f 16/138/91 10/196/100 109/96/49 63/95/48
-f 9/197/102 14/191/92 65/198/51 117/199/50
-f 8/200/101 7/201/99 107/104/60 115/103/59
-f 11/193/98 9/197/102 119/106/62 103/105/61
-f 7/201/99 5/202/108 77/44/55 105/99/54
-f 10/196/100 4/203/94 85/80/31 111/79/30
-f 3/204/97 8/200/101 113/82/33 93/81/32
-f 5/202/109 3/204/97 95/23/96 79/22/109
-f 4/203/94 17/187/83 41/10/82 87/9/95
-f 51/66/87 25/32/103 33/121/79 53/131/88
-s 6
-f 110/205/110 62/206/110 42/207/110 86/208/110
-s 7
-f 60/209/111 66/210/111 120/211/111 102/212/111
-s 10
-f 108/213/112 114/214/112 96/215/112 78/216/112
diff --git a/public/resources/bevel-cube/none.obj b/public/resources/c000000.obj
similarity index 99%
rename from public/resources/bevel-cube/none.obj
rename to public/resources/c000000.obj
index 3ce257c..25d35a9 100644
--- a/public/resources/bevel-cube/none.obj
+++ b/public/resources/c000000.obj
@@ -1,6 +1,5 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
-mtllib 000000.mtl
o Cube_Cube.001
v 0.399961 0.500000 -0.399961
v 0.500000 0.399961 -0.399961
@@ -522,7 +521,6 @@ vn -0.6663 -0.6663 0.3347
vn -0.0981 -0.9201 0.3792
vn -0.3673 -0.8545 0.3673
vn -0.3792 -0.9201 0.0981
-usemtl None
s 1
f 58/1/1 41/2/2 116/3/3 134/4/4
f 96/5/5 79/6/6 3/7/7 22/8/8
diff --git a/public/resources/bevel-cube/x.obj b/public/resources/c000001.obj
similarity index 54%
rename from public/resources/bevel-cube/x.obj
rename to public/resources/c000001.obj
index 88243b6..575e7bc 100644
--- a/public/resources/bevel-cube/x.obj
+++ b/public/resources/c000001.obj
@@ -1,103 +1,103 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
-mtllib x.mtl
-o Cube_Cube.001
-v 0.499961 0.500000 -0.399961
+mtllib c000001.mtl
+o Cube_Cube.002
+v -0.399961 0.399961 0.500000
+v -0.399961 -0.399961 0.500000
+v 0.499961 -0.399961 0.500000
+v 0.499961 0.399961 0.500000
v 0.499961 0.399961 -0.500000
-v 0.499961 0.492385 -0.438244
-v 0.499961 0.438244 -0.492385
-v 0.499961 0.470699 -0.470699
-v 0.499961 -0.500000 -0.399961
v 0.499961 -0.399961 -0.500000
+v -0.399961 -0.399961 -0.500000
+v -0.399961 0.399961 -0.500000
+v -0.500000 0.399961 -0.399961
+v -0.500000 -0.399961 -0.399961
+v -0.500000 -0.399961 0.399961
+v -0.500000 0.399961 0.399961
+v 0.499961 0.500000 -0.399961
+v -0.399961 0.500000 -0.399961
+v -0.399961 0.500000 0.399961
+v 0.499961 0.500000 0.399961
+v -0.399961 -0.500000 -0.399961
+v -0.438244 -0.492385 -0.399961
+v -0.439203 -0.483194 -0.439203
+v -0.399961 -0.492385 -0.438244
+v -0.470699 -0.470699 -0.399961
+v -0.465612 -0.465612 -0.437212
+v -0.437212 -0.465612 -0.465612
+v -0.399961 -0.470699 -0.470699
+v -0.457718 -0.457718 -0.457718
+v -0.492385 -0.399961 -0.438244
+v -0.483194 -0.439203 -0.439203
+v -0.492385 -0.438244 -0.399961
+v -0.470699 -0.399961 -0.470699
+v -0.465612 -0.437212 -0.465612
+v -0.399961 -0.438244 -0.492385
+v -0.439203 -0.439203 -0.483194
+v -0.438244 -0.399961 -0.492385
+v -0.492385 0.438244 -0.399961
+v -0.483194 0.439203 -0.439203
+v -0.492385 0.399961 -0.438244
+v -0.470699 0.470699 -0.399961
+v -0.465612 0.465612 -0.437212
+v -0.465612 0.437212 -0.465612
+v -0.470699 0.399961 -0.470699
+v -0.457718 0.457718 -0.457718
+v -0.399961 0.492385 -0.438244
+v -0.439203 0.483194 -0.439203
+v -0.438244 0.492385 -0.399961
+v -0.399961 0.470699 -0.470699
+v -0.437212 0.465612 -0.465612
+v -0.438244 0.399961 -0.492385
+v -0.439203 0.439203 -0.483194
+v -0.399961 0.438244 -0.492385
+v -0.492385 -0.438244 0.399961
+v -0.483194 -0.439203 0.439203
+v -0.492385 -0.399961 0.438244
+v -0.470699 -0.470699 0.399961
+v -0.465612 -0.465612 0.437212
+v -0.465612 -0.437212 0.465612
+v -0.470699 -0.399961 0.470699
+v -0.457718 -0.457718 0.457718
+v -0.399961 -0.500000 0.399961
+v -0.399961 -0.492385 0.438244
+v -0.439203 -0.483194 0.439203
+v -0.438244 -0.492385 0.399961
+v -0.399961 -0.470699 0.470699
+v -0.437212 -0.465612 0.465612
+v -0.438244 -0.399961 0.492385
+v -0.439203 -0.439203 0.483194
+v -0.399961 -0.438244 0.492385
+v -0.399961 0.438244 0.492385
+v -0.439203 0.439203 0.483194
+v -0.438244 0.399961 0.492385
+v -0.399961 0.470699 0.470699
+v -0.437212 0.465612 0.465612
+v -0.465612 0.437212 0.465612
+v -0.470699 0.399961 0.470699
+v -0.457718 0.457718 0.457718
+v -0.438244 0.492385 0.399961
+v -0.439203 0.483194 0.439203
+v -0.399961 0.492385 0.438244
+v -0.470699 0.470699 0.399961
+v -0.465612 0.465612 0.437212
+v -0.492385 0.399961 0.438244
+v -0.483194 0.439203 0.439203
+v -0.492385 0.438244 0.399961
+v 0.499961 -0.500000 -0.399961
v 0.499961 -0.492385 -0.438244
v 0.499961 -0.470699 -0.470699
v 0.499961 -0.438244 -0.492385
-v 0.499961 0.500000 0.399961
-v 0.499961 0.399961 0.500000
-v 0.499961 0.492385 0.438244
-v 0.499961 0.470699 0.470699
-v 0.499961 0.438244 0.492385
-v 0.499961 -0.399961 0.500000
-v 0.499961 -0.500000 0.399961
+v 0.499961 0.438244 -0.492385
+v 0.499961 0.470699 -0.470699
+v 0.499961 0.492385 -0.438244
v 0.499961 -0.438244 0.492385
v 0.499961 -0.470699 0.470699
+v 0.499961 -0.500000 0.399961
v 0.499961 -0.492385 0.438244
-v -0.500000 0.399961 -0.399961
-v -0.399961 0.500000 -0.399961
-v -0.399961 0.399961 -0.500000
-v -0.492385 0.438244 -0.399961
-v -0.470699 0.470699 -0.399961
-v -0.492385 0.399961 -0.438244
-v -0.483194 0.439203 -0.439203
-v -0.465612 0.465612 -0.437212
-v -0.457718 0.457718 -0.457718
-v -0.399961 0.492385 -0.438244
-v -0.399961 0.470699 -0.470699
-v -0.438244 0.492385 -0.399961
-v -0.439203 0.483194 -0.439203
-v -0.437212 0.465612 -0.465612
-v -0.438244 0.399961 -0.492385
-v -0.470699 0.399961 -0.470699
-v -0.399961 0.438244 -0.492385
-v -0.439203 0.439203 -0.483194
-v -0.465612 0.437212 -0.465612
-v -0.399961 -0.399961 -0.500000
-v -0.399961 -0.500000 -0.399961
-v -0.500000 -0.399961 -0.399961
-v -0.399961 -0.438244 -0.492385
-v -0.399961 -0.470699 -0.470699
-v -0.438244 -0.399961 -0.492385
-v -0.439203 -0.439203 -0.483194
-v -0.437212 -0.465612 -0.465612
-v -0.457718 -0.457718 -0.457718
-v -0.438244 -0.492385 -0.399961
-v -0.470699 -0.470699 -0.399961
-v -0.399961 -0.492385 -0.438244
-v -0.439203 -0.483194 -0.439203
-v -0.465612 -0.465612 -0.437212
-v -0.492385 -0.399961 -0.438244
-v -0.470699 -0.399961 -0.470699
-v -0.492385 -0.438244 -0.399961
-v -0.483194 -0.439203 -0.439203
-v -0.465612 -0.437212 -0.465612
-v -0.500000 0.399961 0.399961
-v -0.399961 0.399961 0.500000
-v -0.399961 0.500000 0.399961
-v -0.492385 0.399961 0.438244
-v -0.470699 0.399961 0.470699
-v -0.492385 0.438244 0.399961
-v -0.483194 0.439203 0.439203
-v -0.465612 0.437212 0.465612
-v -0.457718 0.457718 0.457718
-v -0.399961 0.438244 0.492385
-v -0.399961 0.470699 0.470699
-v -0.438244 0.399961 0.492385
-v -0.439203 0.439203 0.483194
-v -0.437212 0.465612 0.465612
-v -0.438244 0.492385 0.399961
-v -0.470699 0.470699 0.399961
-v -0.399961 0.492385 0.438244
-v -0.439203 0.483194 0.439203
-v -0.465612 0.465612 0.437212
-v -0.399961 -0.399961 0.500000
-v -0.500000 -0.399961 0.399961
-v -0.399961 -0.500000 0.399961
-v -0.438244 -0.399961 0.492385
-v -0.470699 -0.399961 0.470699
-v -0.399961 -0.438244 0.492385
-v -0.439203 -0.439203 0.483194
-v -0.465612 -0.437212 0.465612
-v -0.457718 -0.457718 0.457718
-v -0.492385 -0.438244 0.399961
-v -0.470699 -0.470699 0.399961
-v -0.492385 -0.399961 0.438244
-v -0.483194 -0.439203 0.439203
-v -0.465612 -0.465612 0.437212
-v -0.399961 -0.492385 0.438244
-v -0.399961 -0.470699 0.470699
-v -0.438244 -0.492385 0.399961
-v -0.439203 -0.483194 0.439203
-v -0.437212 -0.465612 0.465612
+v 0.499961 0.438244 0.492385
+v 0.499961 0.470699 0.470699
+v 0.499961 0.492385 0.438244
vt 0.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 0.000000
@@ -126,147 +126,164 @@ vt 0.650010 0.525010
vt 0.849990 0.525010
vt 0.849990 0.724990
vt 0.650010 0.724990
-vt 0.400010 0.775010
-vt 0.599990 0.775010
-vt 0.599990 0.974990
-vt 0.400010 0.974990
+vt 0.400010 0.275010
+vt 0.599990 0.275010
+vt 0.599990 0.474990
+vt 0.400010 0.474990
vt 0.400010 0.025010
vt 0.599990 0.025010
vt 0.599990 0.224990
vt 0.400010 0.224990
-vt 0.609561 0.974990
-vt 0.609801 0.984801
-vt 0.599990 0.984561
-vt 0.625000 0.974990
-vt 0.625000 0.984303
-vt 0.609303 1.000000
-vt 0.599990 1.000000
-vt 0.625000 0.989430
-vt 0.599990 0.525010
-vt 0.599990 0.515439
-vt 0.609801 0.515199
-vt 0.609561 0.525010
-vt 0.599990 0.500000
-vt 0.609303 0.500000
-vt 0.625000 0.515697
-vt 0.625000 0.525010
-vt 0.614430 0.500000
-vt 0.849990 0.515439
-vt 0.859801 0.515199
-vt 0.859561 0.525010
-vt 0.849990 0.500000
-vt 0.859303 0.500000
-vt 0.875000 0.515697
-vt 0.875000 0.525010
-vt 0.864430 0.500000
-vt 0.640439 0.525010
-vt 0.640199 0.515199
-vt 0.650010 0.515439
-vt 0.625000 0.525010
-vt 0.625000 0.515697
-vt 0.640697 0.500000
-vt 0.650010 0.500000
-vt 0.625000 0.510570
-vt 0.390439 0.025010
-vt 0.390199 0.015199
-vt 0.400010 0.015439
-vt 0.375000 0.025010
-vt 0.375000 0.015697
-vt 0.390697 0.000000
-vt 0.400010 0.000000
-vt 0.375000 0.010570
-vt 0.400010 0.984561
-vt 0.390199 0.984801
-vt 0.390439 0.974990
-vt 0.400010 1.000000
-vt 0.390697 1.000000
-vt 0.375000 0.984303
-vt 0.375000 0.974990
-vt 0.385570 1.000000
-vt 0.599990 0.765439
-vt 0.609801 0.765199
-vt 0.609561 0.775010
-vt 0.599990 0.750000
-vt 0.609303 0.750000
-vt 0.625000 0.765697
-vt 0.625000 0.775010
-vt 0.614430 0.750000
-vt 0.359561 0.724990
-vt 0.359801 0.734801
-vt 0.349990 0.734561
-vt 0.375000 0.724990
-vt 0.375000 0.734303
-vt 0.359303 0.750000
-vt 0.349990 0.750000
-vt 0.375000 0.739430
-vt 0.599990 0.724990
-vt 0.609561 0.724990
-vt 0.609801 0.734801
-vt 0.599990 0.734561
-vt 0.625000 0.724990
-vt 0.625000 0.734303
-vt 0.609303 0.750000
-vt 0.599990 0.750000
-vt 0.625000 0.739430
-vt 0.150010 0.734561
-vt 0.140199 0.734801
-vt 0.140439 0.724990
-vt 0.150010 0.750000
-vt 0.140697 0.750000
-vt 0.125000 0.734303
-vt 0.125000 0.724990
-vt 0.135570 0.750000
-vt 0.390439 0.775010
-vt 0.390199 0.765199
-vt 0.400010 0.765439
-vt 0.375000 0.775010
-vt 0.375000 0.765697
-vt 0.390697 0.750000
-vt 0.400010 0.750000
-vt 0.375000 0.760570
-vt 0.400010 0.234561
-vt 0.390199 0.234801
-vt 0.390439 0.224990
-vt 0.400010 0.250000
-vt 0.390697 0.250000
-vt 0.375000 0.234303
-vt 0.375000 0.224990
-vt 0.385570 0.250000
-vt 0.599990 0.234561
+vt 0.400010 0.525010
+vt 0.390439 0.525010
+vt 0.390199 0.515199
+vt 0.400010 0.515439
+vt 0.375000 0.525010
+vt 0.375000 0.515697
+vt 0.390697 0.500000
+vt 0.400010 0.500000
+vt 0.375000 0.510570
+vt 0.599990 0.265439
+vt 0.609801 0.265199
+vt 0.609561 0.275010
vt 0.599990 0.250000
-vt 0.125000 0.525010
-vt 0.140439 0.525010
+vt 0.609303 0.250000
+vt 0.625000 0.265697
+vt 0.625000 0.275010
+vt 0.614430 0.250000
+vt 0.859561 0.724990
+vt 0.859801 0.734801
+vt 0.849990 0.734561
+vt 0.875000 0.724990
+vt 0.875000 0.734303
+vt 0.859303 0.750000
+vt 0.849990 0.750000
+vt 0.875000 0.739430
+vt 0.390439 0.275010
+vt 0.390199 0.265199
+vt 0.400010 0.265439
+vt 0.375000 0.275010
+vt 0.375000 0.265697
+vt 0.390697 0.250000
+vt 0.400010 0.250000
+vt 0.375000 0.260570
vt 0.599990 0.015439
+vt 0.609801 0.015199
+vt 0.609561 0.025010
vt 0.599990 0.000000
-vt 0.625000 0.724990
+vt 0.609303 0.000000
+vt 0.625000 0.015697
+vt 0.625000 0.025010
+vt 0.614430 0.000000
+vt 0.650010 0.734561
+vt 0.640199 0.734801
vt 0.640439 0.724990
+vt 0.650010 0.750000
+vt 0.640697 0.750000
+vt 0.625000 0.734303
+vt 0.625000 0.724990
+vt 0.635570 0.750000
+vt 0.609561 0.474990
+vt 0.609801 0.484801
+vt 0.599990 0.484561
+vt 0.625000 0.474990
+vt 0.625000 0.484303
+vt 0.609303 0.500000
+vt 0.599990 0.500000
+vt 0.625000 0.489430
vt 0.400010 0.724990
vt 0.400010 0.734561
+vt 0.390199 0.734801
+vt 0.390439 0.724990
vt 0.400010 0.750000
-vt 0.375000 0.525010
+vt 0.390697 0.750000
+vt 0.375000 0.734303
+vt 0.375000 0.724990
+vt 0.385570 0.750000
+vt 0.349990 0.515439
+vt 0.359801 0.515199
vt 0.359561 0.525010
-vt 0.400010 0.525010
-vt 0.400010 0.515439
+vt 0.349990 0.500000
+vt 0.359303 0.500000
+vt 0.375000 0.515697
+vt 0.375000 0.525010
+vt 0.364430 0.500000
+vt 0.140439 0.525010
+vt 0.140199 0.515199
+vt 0.150010 0.515439
+vt 0.125000 0.525010
+vt 0.125000 0.515697
+vt 0.140697 0.500000
+vt 0.150010 0.500000
+vt 0.125000 0.510570
+vt 0.609561 0.224990
+vt 0.609801 0.234801
+vt 0.599990 0.234561
+vt 0.625000 0.224990
+vt 0.625000 0.234303
+vt 0.609303 0.250000
+vt 0.599990 0.250000
+vt 0.625000 0.239430
+vt 0.400010 0.484561
+vt 0.390199 0.484801
+vt 0.390439 0.474990
vt 0.400010 0.500000
-vt 0.875000 0.724990
-vt 0.859561 0.724990
+vt 0.390697 0.500000
+vt 0.375000 0.484303
+vt 0.375000 0.474990
+vt 0.385570 0.500000
+vt 0.400010 0.234561
+vt 0.400010 0.250000
+vt 0.125000 0.724990
+vt 0.140439 0.724990
+vt 0.400010 0.015439
+vt 0.400010 0.000000
+vt 0.625000 0.525010
+vt 0.640439 0.525010
+vt 0.599990 0.724990
+vt 0.599990 0.734561
+vt 0.599990 0.750000
+vt 0.375000 0.724990
+vt 0.359561 0.724990
+vt 0.599990 0.525010
+vt 0.599990 0.515439
+vt 0.599990 0.500000
+vt 0.875000 0.525010
+vt 0.859561 0.525010
vn 1.0000 0.0000 0.0000
-vn 0.0000 -0.0980 0.9952
-vn 0.0000 0.0980 0.9952
vn -0.1004 0.1004 0.9899
vn -0.1004 -0.1004 0.9899
-vn -0.1004 -0.1004 -0.9899
-vn -0.1004 0.1004 -0.9899
+vn 0.0000 -0.0980 0.9952
+vn -0.0000 0.0980 0.9952
vn 0.0000 0.0980 -0.9952
vn 0.0000 -0.0980 -0.9952
-vn -0.9899 -0.1004 0.1004
-vn -0.9899 0.1004 0.1004
+vn -0.1004 -0.1004 -0.9899
+vn -0.1004 0.1004 -0.9899
vn -0.9899 0.1004 -0.1004
vn -0.9899 -0.1004 -0.1004
+vn -0.9899 -0.1004 0.1004
+vn -0.9899 0.1004 0.1004
+vn 0.0000 0.9952 -0.0980
+vn -0.1004 0.9899 -0.1004
+vn -0.1004 0.9899 0.1004
+vn 0.0000 0.9952 0.0980
vn -0.1004 -0.9899 -0.1004
-vn 0.0000 -0.9952 -0.0980
-vn 0.0000 -0.9952 0.0980
-vn -0.1004 -0.9899 0.1004
+vn -0.3792 -0.9201 -0.0981
+vn -0.3673 -0.8545 -0.3673
+vn -0.0981 -0.9201 -0.3792
+vn -0.7041 -0.7041 -0.0919
+vn -0.6663 -0.6663 -0.3347
+vn -0.3347 -0.6663 -0.6663
+vn -0.0919 -0.7041 -0.7041
+vn -0.5774 -0.5774 -0.5773
+vn -0.9201 -0.0981 -0.3792
+vn -0.8545 -0.3673 -0.3673
+vn -0.9201 -0.3792 -0.0981
+vn -0.7041 -0.0919 -0.7041
+vn -0.6663 -0.3347 -0.6663
+vn -0.0981 -0.3792 -0.9201
+vn -0.3673 -0.3673 -0.8545
+vn -0.3792 -0.0981 -0.9201
vn -0.9201 0.3792 -0.0981
vn -0.8545 0.3673 -0.3673
vn -0.9201 0.0981 -0.3792
@@ -275,7 +292,6 @@ vn -0.6663 0.6663 -0.3347
vn -0.6663 0.3347 -0.6663
vn -0.7041 0.0919 -0.7041
vn -0.5774 0.5774 -0.5773
-vn -0.1004 0.9899 -0.1004
vn -0.0981 0.9201 -0.3792
vn -0.3673 0.8545 -0.3673
vn -0.3792 0.9201 -0.0981
@@ -284,172 +300,156 @@ vn -0.3347 0.6663 -0.6663
vn -0.3792 0.0981 -0.9201
vn -0.3673 0.3673 -0.8545
vn -0.0981 0.3792 -0.9201
-vn -0.0981 -0.3792 -0.9201
-vn -0.3673 -0.3673 -0.8545
-vn -0.3792 -0.0981 -0.9201
-vn -0.0919 -0.7041 -0.7041
-vn -0.3347 -0.6663 -0.6663
-vn -0.6663 -0.3347 -0.6663
-vn -0.7041 -0.0919 -0.7041
-vn -0.5773 -0.5774 -0.5774
-vn -0.3792 -0.9201 -0.0981
-vn -0.3673 -0.8545 -0.3673
-vn -0.0981 -0.9201 -0.3792
-vn -0.7041 -0.7041 -0.0919
-vn -0.6663 -0.6663 -0.3347
-vn -0.9201 -0.0981 -0.3792
-vn -0.8545 -0.3673 -0.3673
-vn -0.9201 -0.3792 -0.0981
-vn -0.9201 0.0981 0.3792
-vn -0.8545 0.3673 0.3673
-vn -0.9201 0.3792 0.0981
-vn -0.7041 0.0919 0.7041
-vn -0.6663 0.3347 0.6663
-vn -0.6663 0.6663 0.3347
-vn -0.7041 0.7041 0.0919
-vn -0.5774 0.5774 0.5773
-vn -0.0981 0.3792 0.9201
-vn -0.3673 0.3673 0.8545
-vn -0.3792 0.0981 0.9201
-vn -0.0919 0.7041 0.7041
-vn -0.3347 0.6663 0.6663
-vn -0.1004 0.9899 0.1004
-vn -0.3792 0.9201 0.0981
-vn -0.3673 0.8545 0.3673
-vn -0.0981 0.9201 0.3792
-vn -0.3792 -0.0981 0.9201
-vn -0.3673 -0.3673 0.8545
-vn -0.0981 -0.3792 0.9201
-vn -0.7041 -0.0919 0.7041
-vn -0.6663 -0.3347 0.6663
-vn -0.3347 -0.6663 0.6663
-vn -0.0919 -0.7041 0.7041
-vn -0.5774 -0.5774 0.5773
vn -0.9201 -0.3792 0.0981
vn -0.8545 -0.3673 0.3673
vn -0.9201 -0.0981 0.3792
vn -0.7041 -0.7041 0.0919
vn -0.6663 -0.6663 0.3347
+vn -0.6663 -0.3347 0.6663
+vn -0.7041 -0.0919 0.7041
+vn -0.5774 -0.5774 0.5773
+vn -0.1004 -0.9899 0.1004
vn -0.0981 -0.9201 0.3792
vn -0.3673 -0.8545 0.3673
vn -0.3792 -0.9201 0.0981
-vn 0.0000 -0.9239 0.3827
-vn 0.0000 -0.7071 0.7071
-vn 0.0000 -0.3827 0.9239
-vn 0.0000 -0.9239 -0.3827
-vn 0.0000 -0.7071 -0.7071
-vn 0.0000 -0.3827 -0.9239
-vn 0.0000 0.9952 0.0980
+vn -0.0919 -0.7041 0.7041
+vn -0.3347 -0.6663 0.6663
+vn -0.3792 -0.0981 0.9201
+vn -0.3673 -0.3673 0.8545
+vn -0.0981 -0.3792 0.9201
+vn -0.0981 0.3792 0.9201
+vn -0.3673 0.3673 0.8545
+vn -0.3792 0.0981 0.9201
+vn -0.0919 0.7041 0.7041
+vn -0.3347 0.6663 0.6663
+vn -0.6663 0.3347 0.6663
+vn -0.7041 0.0919 0.7041
+vn -0.5774 0.5774 0.5773
+vn -0.3792 0.9201 0.0981
+vn -0.3673 0.8545 0.3673
+vn -0.0981 0.9201 0.3792
+vn -0.7041 0.7041 0.0919
+vn -0.6663 0.6663 0.3347
+vn -0.9201 0.0981 0.3792
+vn -0.8545 0.3673 0.3673
+vn -0.9201 0.3792 0.0981
vn 0.0000 0.9239 0.3827
vn 0.0000 0.7071 0.7071
vn 0.0000 0.3827 0.9239
-vn 0.0000 0.9952 -0.0980
vn 0.0000 0.9239 -0.3827
vn 0.0000 0.7071 -0.7071
vn 0.0000 0.3827 -0.9239
-usemtl None
+vn -0.0000 -0.9952 0.0980
+vn -0.0000 -0.9239 0.3827
+vn -0.0000 -0.7071 0.7071
+vn -0.0000 -0.3827 0.9239
+vn -0.0000 -0.9952 -0.0980
+vn -0.0000 -0.9239 -0.3827
+vn -0.0000 -0.7071 -0.7071
+vn -0.0000 -0.3827 -0.9239
+usemtl Default_OBJ
s off
-f 4/1/1 5/2/1 2/3/1
-f 11/4/1 13/5/1 14/6/1
-f 7/7/1 1/8/1 6/9/1
-f 10/10/1 7/7/1 9/11/1
-f 17/12/1 16/13/1 19/14/1
-f 7/7/1 6/9/1 9/11/1
-f 1/8/1 7/7/1 2/3/1
-f 1/8/1 2/3/1 5/2/1
-f 11/4/1 6/9/1 1/8/1
-f 11/4/1 17/12/1 6/9/1
-f 6/9/1 8/15/1 9/11/1
-f 17/12/1 12/16/1 16/13/1
-f 12/16/1 11/4/1 14/6/1
-f 15/17/1 12/16/1 14/6/1
-f 20/18/1 17/12/1 19/14/1
-f 12/16/1 17/12/1 11/4/1
-f 18/19/1 19/14/1 16/13/1
-f 3/20/1 1/8/1 5/2/1
+f 93/1/1 92/2/1 91/3/1
+f 4/4/1 16/5/1 95/6/1
+f 6/7/1 83/8/1 85/9/1
+f 13/10/1 5/11/1 88/12/1
+f 3/13/1 16/5/1 4/4/1
+f 16/5/1 96/14/1 95/6/1
+f 3/13/1 90/15/1 91/3/1
+f 5/11/1 13/10/1 92/2/1
+f 16/5/1 3/13/1 13/10/1
+f 83/8/1 5/11/1 92/2/1
+f 5/11/1 87/16/1 88/12/1
+f 95/6/1 94/17/1 4/4/1
+f 92/2/1 3/13/1 91/3/1
+f 5/11/1 83/8/1 6/7/1
+f 3/13/1 92/2/1 13/10/1
+f 85/9/1 86/18/1 6/7/1
+f 89/19/1 13/10/1 88/12/1
+f 83/8/1 84/20/1 85/9/1
s 1
-f 16/21/2 12/22/3 60/23/4 78/24/5
-f 40/25/6 23/26/7 2/27/8 7/28/9
-f 79/29/10 59/30/11 21/31/12 42/32/13
-f 41/33/14 6/34/15 17/35/16 80/36/17
-f 21/31/12 24/37/18 27/38/19 26/39/20
-f 24/37/18 25/40/21 28/41/22 27/38/19
-f 26/39/20 27/38/19 39/42/23 36/43/24
-f 27/38/19 28/41/22 29/44/25 39/42/23
-f 22/45/26 30/46/27 33/47/28 32/48/29
-f 30/46/27 31/49/30 34/50/31 33/47/28
-f 32/48/29 33/47/28 28/51/22 25/52/21
-f 33/47/28 34/50/31 29/53/25 28/51/22
-f 23/26/7 35/54/32 38/55/33 37/56/34
-f 35/54/32 36/57/24 39/58/23 38/55/33
-f 37/56/34 38/55/33 34/59/31 31/60/30
-f 38/55/33 39/58/23 29/61/25 34/59/31
-f 40/25/6 43/62/35 46/63/36 45/64/37
-f 43/62/35 44/65/38 47/66/39 46/63/36
-f 45/64/37 46/63/36 58/67/40 55/68/41
-f 46/63/36 47/66/39 48/69/42 58/67/40
-f 41/33/14 49/70/43 52/71/44 51/72/45
-f 49/70/43 50/73/46 53/74/47 52/71/44
-f 51/72/45 52/71/44 47/75/39 44/76/38
-f 52/71/44 53/74/47 48/77/42 47/75/39
-f 42/32/13 54/78/48 57/79/49 56/80/50
-f 54/78/48 55/81/41 58/82/40 57/79/49
-f 56/80/50 57/79/49 53/83/47 50/84/46
-f 57/79/49 58/82/40 48/85/42 53/83/47
-f 59/30/11 62/86/51 65/87/52 64/88/53
-f 62/86/51 63/89/54 66/90/55 65/87/52
-f 64/88/53 65/87/52 77/91/56 74/92/57
-f 65/87/52 66/90/55 67/93/58 77/91/56
-f 60/23/4 68/94/59 71/95/60 70/96/61
-f 68/94/59 69/97/62 72/98/63 71/95/60
-f 70/96/61 71/95/60 66/99/55 63/100/54
-f 71/95/60 72/98/63 67/101/58 66/99/55
-f 61/102/64 73/103/65 76/104/66 75/105/67
-f 73/103/65 74/106/57 77/107/56 76/104/66
-f 75/105/67 76/104/66 72/108/63 69/109/62
-f 76/104/66 77/107/56 67/110/58 72/108/63
-f 78/24/5 81/111/68 84/112/69 83/113/70
-f 81/111/68 82/114/71 85/115/72 84/112/69
-f 83/113/70 84/112/69 96/116/73 93/117/74
-f 84/112/69 85/115/72 86/118/75 96/116/73
-f 79/29/10 87/119/76 90/120/77 89/121/78
-f 87/119/76 88/122/79 91/123/80 90/120/77
-f 89/121/78 90/120/77 85/124/72 82/125/71
-f 90/120/77 91/123/80 86/126/75 85/124/72
-f 80/36/17 92/127/81 95/128/82 94/129/83
-f 92/127/81 93/130/74 96/131/73 95/128/82
-f 94/129/83 95/128/82 91/132/80 88/133/79
-f 95/128/82 96/131/73 86/134/75 91/132/80
-f 80/36/17 17/35/16 20/135/84 92/127/81
-f 92/127/81 20/135/84 19/136/85 93/130/74
-f 93/117/74 19/137/85 18/138/86 83/113/70
-f 83/113/70 18/138/86 16/21/2 78/24/5
-f 6/34/15 41/33/14 51/72/45 8/139/87
-f 8/139/87 51/72/45 44/76/38 9/140/88
-f 9/141/88 44/65/38 43/62/35 10/142/89
-f 10/142/89 43/62/35 40/25/6 7/28/9
-f 61/102/64 22/45/26 32/48/29 73/103/65
-f 73/103/65 32/48/29 25/52/21 74/106/57
-f 74/92/57 25/40/21 24/37/18 64/88/53
-f 64/88/53 24/37/18 21/31/12 59/30/11
-f 41/33/14 80/36/17 94/129/83 49/70/43
-f 49/70/43 94/129/83 88/133/79 50/73/46
-f 50/84/46 88/122/79 87/119/76 56/80/50
-f 56/80/50 87/119/76 79/29/10 42/32/13
-f 11/143/90 61/102/64 75/105/67 13/144/91
-f 13/144/91 75/105/67 69/109/62 14/145/92
-f 14/146/92 69/97/62 68/94/59 15/147/93
-f 15/147/93 68/94/59 60/23/4 12/22/3
-f 78/24/5 60/23/4 70/96/61 81/111/68
-f 81/111/68 70/96/61 63/100/54 82/114/71
-f 82/125/71 63/89/54 62/86/51 89/121/78
-f 89/121/78 62/86/51 59/30/11 79/29/10
-f 22/45/26 1/148/94 3/149/95 30/46/27
-f 30/46/27 3/149/95 5/150/96 31/49/30
-f 31/60/30 5/151/96 4/152/97 37/56/34
-f 37/56/34 4/152/97 2/27/8 23/26/7
-f 23/26/7 40/25/6 45/64/37 35/54/32
-f 35/54/32 45/64/37 55/68/41 36/57/24
-f 36/43/24 55/81/41 54/78/48 26/39/20
-f 26/39/20 54/78/48 42/32/13 21/31/12
-f 1/148/94 22/45/26 61/102/64 11/143/90
+f 1/21/2 2/22/3 3/23/4 4/24/5
+f 5/25/6 6/26/7 7/27/8 8/28/9
+f 9/29/10 10/30/11 11/31/12 12/32/13
+f 13/33/14 14/34/15 15/35/16 16/36/17
+f 17/37/18 18/38/19 19/39/20 20/40/21
+f 18/38/19 21/41/22 22/42/23 19/39/20
+f 20/40/21 19/39/20 23/43/24 24/44/25
+f 19/39/20 22/42/23 25/45/26 23/43/24
+f 10/30/11 26/46/27 27/47/28 28/48/29
+f 26/46/27 29/49/30 30/50/31 27/47/28
+f 28/48/29 27/47/28 22/51/23 21/52/22
+f 27/47/28 30/50/31 25/53/26 22/51/23
+f 7/27/8 31/54/32 32/55/33 33/56/34
+f 31/54/32 24/57/25 23/58/24 32/55/33
+f 33/56/34 32/55/33 30/59/31 29/60/30
+f 32/55/33 23/58/24 25/61/26 30/59/31
+f 9/29/10 34/62/35 35/63/36 36/64/37
+f 34/62/35 37/65/38 38/66/39 35/63/36
+f 36/64/37 35/63/36 39/67/40 40/68/41
+f 35/63/36 38/66/39 41/69/42 39/67/40
+f 14/34/15 42/70/43 43/71/44 44/72/45
+f 42/70/43 45/73/46 46/74/47 43/71/44
+f 44/72/45 43/71/44 38/75/39 37/76/38
+f 43/71/44 46/74/47 41/77/42 38/75/39
+f 8/28/9 47/78/48 48/79/49 49/80/50
+f 47/78/48 40/81/41 39/82/40 48/79/49
+f 49/80/50 48/79/49 46/83/47 45/84/46
+f 48/79/49 39/82/40 41/85/42 46/83/47
+f 11/31/12 50/86/51 51/87/52 52/88/53
+f 50/86/51 53/89/54 54/90/55 51/87/52
+f 52/88/53 51/87/52 55/91/56 56/92/57
+f 51/87/52 54/90/55 57/93/58 55/91/56
+f 58/94/59 59/95/60 60/96/61 61/97/62
+f 59/95/60 62/98/63 63/99/64 60/96/61
+f 61/97/62 60/96/61 54/100/55 53/101/54
+f 60/96/61 63/99/64 57/102/58 54/100/55
+f 2/22/3 64/103/65 65/104/66 66/105/67
+f 64/103/65 56/106/57 55/107/56 65/104/66
+f 66/105/67 65/104/66 63/108/64 62/109/63
+f 65/104/66 55/107/56 57/110/58 63/108/64
+f 1/21/2 67/111/68 68/112/69 69/113/70
+f 67/111/68 70/114/71 71/115/72 68/112/69
+f 69/113/70 68/112/69 72/116/73 73/117/74
+f 68/112/69 71/115/72 74/118/75 72/116/73
+f 15/35/16 75/119/76 76/120/77 77/121/78
+f 75/119/76 78/122/79 79/123/80 76/120/77
+f 77/121/78 76/120/77 71/124/72 70/125/71
+f 76/120/77 79/123/80 74/126/75 71/124/72
+f 12/32/13 80/127/81 81/128/82 82/129/83
+f 80/127/81 73/130/74 72/131/73 81/128/82
+f 82/129/83 81/128/82 79/132/80 78/133/79
+f 81/128/82 72/131/73 74/134/75 79/132/80
+f 16/36/17 15/35/16 77/121/78 96/135/84
+f 96/135/84 77/121/78 70/125/71 95/136/85
+f 95/137/85 70/114/71 67/111/68 94/138/86
+f 94/138/86 67/111/68 1/21/2 4/24/5
+f 15/35/16 14/34/15 44/72/45 75/119/76
+f 75/119/76 44/72/45 37/76/38 78/122/79
+f 78/133/79 37/65/38 34/62/35 82/129/83
+f 82/129/83 34/62/35 9/29/10 12/32/13
+f 17/37/18 58/94/59 61/97/62 18/38/19
+f 18/38/19 61/97/62 53/101/54 21/41/22
+f 21/52/22 53/89/54 50/86/51 28/48/29
+f 28/48/29 50/86/51 11/31/12 10/30/11
+f 14/34/15 13/33/14 89/139/87 42/70/43
+f 42/70/43 89/139/87 88/140/88 45/73/46
+f 45/84/46 88/141/88 87/142/89 49/80/50
+f 49/80/50 87/142/89 5/25/6 8/28/9
+f 58/94/59 92/143/90 93/144/91 59/95/60
+f 59/95/60 93/144/91 91/145/92 62/98/63
+f 62/109/63 91/146/92 90/147/93 66/105/67
+f 66/105/67 90/147/93 3/23/4 2/22/3
+f 2/22/3 1/21/2 69/113/70 64/103/65
+f 64/103/65 69/113/70 73/117/74 56/106/57
+f 56/92/57 73/130/74 80/127/81 52/88/53
+f 52/88/53 80/127/81 12/32/13 11/31/12
+f 10/30/11 9/29/10 36/64/37 26/46/27
+f 26/46/27 36/64/37 40/68/41 29/49/30
+f 29/60/30 40/81/41 47/78/48 33/56/34
+f 33/56/34 47/78/48 8/28/9 7/27/8
+f 83/148/94 17/37/18 20/40/21 84/149/95
+f 84/149/95 20/40/21 24/44/25 85/150/96
+f 85/151/96 24/57/25 31/54/32 86/152/97
+f 86/152/97 31/54/32 7/27/8 6/26/7
+f 17/37/18 83/148/94 92/143/90 58/94/59
diff --git a/public/resources/c000011.obj b/public/resources/c000011.obj
new file mode 100644
index 0000000..934ab85
--- /dev/null
+++ b/public/resources/c000011.obj
@@ -0,0 +1,301 @@
+# Blender v2.82 (sub 7) OBJ File: ''
+# www.blender.org
+mtllib c000011.mtl
+o Cube_Cube.003
+v 0.495579 0.504344 -0.499961
+v 0.495579 0.504344 0.399961
+v 0.504305 -0.495618 0.399961
+v 0.503432 -0.395583 0.500000
+v 0.504049 -0.466318 0.470699
+v 0.503766 -0.433864 0.492385
+v 0.504239 -0.488003 0.438244
+v 0.496118 0.442590 0.492385
+v 0.496452 0.404309 0.500000
+v 0.495834 0.475044 0.470699
+v 0.495645 0.496729 0.438244
+v 0.504305 -0.495618 -0.499961
+v -0.395583 -0.503471 -0.499961
+v -0.433931 -0.496191 -0.499961
+v -0.466574 -0.474789 -0.499961
+v -0.404309 0.496491 -0.499961
+v -0.503471 0.395583 -0.499961
+v -0.474789 0.466574 -0.499961
+v -0.496491 -0.404309 -0.499961
+v -0.488542 -0.442524 -0.499961
+v -0.442524 0.488542 -0.499961
+v -0.496190 0.433931 -0.499961
+v -0.496491 -0.404309 0.399961
+v -0.503471 0.395583 0.399961
+v -0.403436 0.396456 0.500000
+v -0.396456 -0.403436 0.500000
+v -0.404309 0.496491 0.399961
+v -0.434737 -0.403770 0.492385
+v -0.435354 -0.443019 0.483194
+v -0.396122 -0.441717 0.492385
+v -0.467191 -0.404053 0.470699
+v -0.461779 -0.441258 0.465612
+v -0.433132 -0.469410 0.465612
+v -0.395838 -0.474171 0.470699
+v -0.453706 -0.461695 0.457718
+v -0.488542 -0.442524 0.399961
+v -0.479343 -0.443403 0.439203
+v -0.488876 -0.404242 0.438244
+v -0.466574 -0.474789 0.399961
+v -0.461531 -0.469657 0.437212
+v -0.395583 -0.503471 0.399961
+v -0.395649 -0.495856 0.438244
+v -0.434970 -0.487008 0.439203
+v -0.433931 -0.496191 0.399961
+v -0.495856 0.395649 0.438244
+v -0.487008 0.434970 0.439203
+v -0.496191 0.433931 0.399961
+v -0.474171 0.395838 0.470699
+v -0.469410 0.433132 0.465612
+v -0.469657 0.461531 0.437212
+v -0.474789 0.466574 0.399961
+v -0.461695 0.453706 0.457718
+v -0.403770 0.434737 0.492385
+v -0.443019 0.435354 0.483194
+v -0.441718 0.396122 0.492385
+v -0.404053 0.467191 0.470699
+v -0.441258 0.461779 0.465612
+v -0.442524 0.488542 0.399961
+v -0.443403 0.479343 0.439203
+v -0.404243 0.488876 0.438244
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.150010 0.525010
+vt 0.349990 0.525010
+vt 0.349990 0.724990
+vt 0.150010 0.724990
+vt 0.400010 0.775010
+vt 0.599990 0.775010
+vt 0.599990 0.974990
+vt 0.400010 0.974990
+vt 0.400010 0.025010
+vt 0.599990 0.025010
+vt 0.599990 0.224990
+vt 0.400010 0.224990
+vt 0.599990 0.765439
+vt 0.609801 0.765199
+vt 0.609561 0.775010
+vt 0.599990 0.750000
+vt 0.609303 0.750000
+vt 0.625000 0.765697
+vt 0.625000 0.775010
+vt 0.614430 0.750000
+vt 0.359561 0.724990
+vt 0.359801 0.734801
+vt 0.349990 0.734561
+vt 0.375000 0.724990
+vt 0.375000 0.734303
+vt 0.359303 0.750000
+vt 0.349990 0.750000
+vt 0.375000 0.739430
+vt 0.599990 0.724990
+vt 0.609561 0.724990
+vt 0.609801 0.734801
+vt 0.599990 0.734561
+vt 0.625000 0.724990
+vt 0.625000 0.734303
+vt 0.609303 0.750000
+vt 0.599990 0.750000
+vt 0.625000 0.739430
+vt 0.150010 0.734561
+vt 0.140199 0.734801
+vt 0.140439 0.724990
+vt 0.150010 0.750000
+vt 0.140697 0.750000
+vt 0.125000 0.734303
+vt 0.125000 0.724990
+vt 0.135570 0.750000
+vt 0.390439 0.775010
+vt 0.390199 0.765199
+vt 0.400010 0.765439
+vt 0.375000 0.775010
+vt 0.375000 0.765697
+vt 0.390697 0.750000
+vt 0.400010 0.750000
+vt 0.375000 0.760570
+vt 0.400010 0.234561
+vt 0.390199 0.234801
+vt 0.390439 0.224990
+vt 0.400010 0.250000
+vt 0.390697 0.250000
+vt 0.375000 0.234303
+vt 0.375000 0.224990
+vt 0.385570 0.250000
+vt 0.599990 0.234561
+vt 0.599990 0.250000
+vt 0.125000 0.525010
+vt 0.140439 0.525010
+vt 0.599990 0.525010
+vt 0.609561 0.525010
+vt 0.625000 0.525010
+vt 0.625000 0.974990
+vt 0.609561 0.974990
+vt 0.390439 0.025010
+vt 0.375000 0.025010
+vt 0.375000 0.974990
+vt 0.390439 0.974990
+vt 0.400010 0.724990
+vt 0.400010 0.734561
+vt 0.400010 0.750000
+vt 0.375000 0.525010
+vt 0.359561 0.525010
+vt 0.400010 0.525010
+vn 1.0000 0.0087 -0.0000
+vn 1.0000 0.0088 -0.0000
+vn 1.0000 0.0087 -0.0001
+vn 0.0000 0.0000 -1.0000
+vn -0.9960 0.0893 -0.0000
+vn -0.9943 -0.1067 0.0000
+vn -0.9890 -0.1090 0.1004
+vn -0.9907 0.0917 0.1004
+vn -0.1013 0.0995 0.9899
+vn -0.0995 -0.1013 0.9899
+vn 0.0009 -0.0980 0.9952
+vn -0.0009 0.0980 0.9952
+vn -0.0087 0.9951 0.0980
+vn -0.0087 1.0000 -0.0000
+vn -0.1067 0.9943 -0.0000
+vn -0.1090 0.9890 0.1004
+vn -0.3783 -0.1014 0.9201
+vn -0.3641 -0.3705 0.8545
+vn -0.0948 -0.3801 0.9201
+vn -0.7033 -0.0981 0.7041
+vn -0.6634 -0.3405 0.6663
+vn -0.3289 -0.6692 0.6663
+vn -0.0858 -0.7049 0.7041
+vn -0.5723 -0.5824 0.5773
+vn -0.9167 -0.3872 0.0981
+vn -0.8512 -0.3748 0.3674
+vn -0.9192 -0.1062 0.3792
+vn -0.6979 -0.7102 0.0919
+vn -0.6605 -0.6721 0.3347
+vn -0.0917 -0.9907 0.1004
+vn -0.0901 -0.9209 0.3792
+vn -0.3599 -0.8576 0.3674
+vn -0.3712 -0.9234 0.0982
+vn -0.9209 0.0901 0.3792
+vn -0.8576 0.3599 0.3674
+vn -0.9234 0.3712 0.0982
+vn -0.7049 0.0858 0.7041
+vn -0.6692 0.3289 0.6663
+vn -0.6721 0.6605 0.3347
+vn -0.7102 0.6979 0.0919
+vn -0.5824 0.5723 0.5773
+vn -0.1014 0.3783 0.9201
+vn -0.3705 0.3641 0.8545
+vn -0.3801 0.0948 0.9201
+vn -0.0981 0.7033 0.7041
+vn -0.3405 0.6634 0.6663
+vn -0.3872 0.9167 0.0981
+vn -0.3748 0.8512 0.3674
+vn -0.1062 0.9192 0.3792
+vn -0.3907 0.9205 -0.0000
+vn -0.7132 0.7009 -0.0000
+vn -0.9272 0.3746 -0.0000
+vn 0.0087 -0.9951 0.0980
+vn 0.0081 -0.9238 0.3827
+vn 0.0062 -0.7071 0.7071
+vn 0.0033 -0.3827 0.9239
+vn -0.0081 0.9238 0.3827
+vn -0.0062 0.7071 0.7071
+vn -0.0033 0.3827 0.9239
+vn -0.0893 -0.9960 0.0000
+vn -0.3746 -0.9272 0.0000
+vn -0.7009 -0.7132 0.0000
+vn -0.9205 -0.3907 0.0000
+vn 0.0087 -1.0000 0.0000
+usemtl Default_OBJ.003
+s off
+f 1/1/1 2/2/1 3/3/1
+f 3/3/1 4/4/1 5/5/1
+f 4/4/1 6/6/1 5/5/1
+f 7/7/2 3/3/2 5/5/2
+f 8/8/3 9/9/3 10/10/3
+f 9/9/1 2/2/1 10/10/1
+f 2/2/1 11/11/1 10/10/1
+f 12/12/1 1/1/1 3/3/1
+f 4/4/1 3/3/1 9/9/1
+f 3/3/1 2/2/1 9/9/1
+f 13/13/4 14/14/4 15/15/4
+f 16/16/4 17/17/4 18/18/4
+f 13/13/4 1/1/4 12/12/4
+f 13/13/4 16/16/4 1/1/4
+f 16/16/4 19/19/4 17/17/4
+f 19/19/4 13/13/4 15/15/4
+f 20/20/4 19/19/4 15/15/4
+f 21/21/4 16/16/4 18/18/4
+f 19/19/4 16/16/4 13/13/4
+f 22/22/4 18/18/4 17/17/4
+s 1
+f 17/23/5 19/24/6 23/25/7 24/26/8
+f 25/27/9 26/28/10 4/29/11 9/30/12
+f 2/31/13 1/32/14 16/33/15 27/34/16
+f 26/28/10 28/35/17 29/36/18 30/37/19
+f 28/35/17 31/38/20 32/39/21 29/36/18
+f 30/37/19 29/36/18 33/40/22 34/41/23
+f 29/36/18 32/39/21 35/42/24 33/40/22
+f 23/25/7 36/43/25 37/44/26 38/45/27
+f 36/43/25 39/46/28 40/47/29 37/44/26
+f 38/45/27 37/44/26 32/48/21 31/49/20
+f 37/44/26 40/47/29 35/50/24 32/48/21
+f 41/51/30 42/52/31 43/53/32 44/54/33
+f 42/52/31 34/55/23 33/56/22 43/53/32
+f 44/54/33 43/53/32 40/57/29 39/58/28
+f 43/53/32 33/56/22 35/59/24 40/57/29
+f 24/26/8 45/60/34 46/61/35 47/62/36
+f 45/60/34 48/63/37 49/64/38 46/61/35
+f 47/62/36 46/61/35 50/65/39 51/66/40
+f 46/61/35 49/64/38 52/67/41 50/65/39
+f 25/27/9 53/68/42 54/69/43 55/70/44
+f 53/68/42 56/71/45 57/72/46 54/69/43
+f 55/70/44 54/69/43 49/73/38 48/74/37
+f 54/69/43 57/72/46 52/75/41 49/73/38
+f 27/34/16 58/76/47 59/77/48 60/78/49
+f 58/76/47 51/79/40 50/80/39 59/77/48
+f 60/78/49 59/77/48 57/81/46 56/82/45
+f 59/77/48 50/80/39 52/83/41 57/81/46
+f 27/34/16 16/33/15 21/84/50 58/76/47
+f 58/76/47 21/84/50 18/85/51 51/79/40
+f 51/66/40 18/86/51 22/87/52 47/62/36
+f 47/62/36 22/87/52 17/23/5 24/26/8
+f 41/51/30 3/88/53 7/89/54 42/52/31
+f 42/52/31 7/89/54 5/90/55 34/55/23
+f 34/41/23 5/91/55 6/92/56 30/37/19
+f 30/37/19 6/92/56 4/29/11 26/28/10
+f 2/31/13 27/34/16 60/78/49 11/93/57
+f 11/93/57 60/78/49 56/82/45 10/94/58
+f 10/95/58 56/71/45 53/68/42 8/96/59
+f 8/96/59 53/68/42 25/27/9 9/30/12
+f 13/97/60 41/51/30 44/54/33 14/98/61
+f 14/98/61 44/54/33 39/58/28 15/99/62
+f 15/100/62 39/46/28 36/43/25 20/101/63
+f 20/101/63 36/43/25 23/25/7 19/24/6
+f 24/26/8 23/25/7 38/45/27 45/60/34
+f 45/60/34 38/45/27 31/49/20 48/63/37
+f 48/74/37 31/38/20 28/35/17 55/70/44
+f 55/70/44 28/35/17 26/28/10 25/27/9
+f 12/102/64 3/88/53 41/51/30 13/97/60
diff --git a/public/resources/c000111.obj b/public/resources/c000111.obj
new file mode 100644
index 0000000..7c227e0
--- /dev/null
+++ b/public/resources/c000111.obj
@@ -0,0 +1,214 @@
+# Blender v2.82 (sub 7) OBJ File: ''
+# www.blender.org
+mtllib c000111.mtl
+o Cube_Cube.004
+v 0.499961 -0.500000 0.399961
+v 0.499961 -0.399961 0.500000
+v 0.499961 -0.470699 0.470699
+v 0.499961 -0.438244 0.492385
+v 0.499961 -0.492385 0.438244
+v 0.499961 0.499961 0.500000
+v -0.399962 -0.500000 -0.499961
+v -0.438245 -0.492385 -0.499961
+v -0.470700 -0.470699 -0.499961
+v -0.500000 -0.399961 -0.499961
+v -0.492385 -0.438244 -0.499961
+v -0.500000 0.499961 -0.499961
+v -0.500000 -0.399961 0.399961
+v -0.500000 0.499962 0.399961
+v -0.399961 0.499962 0.500000
+v -0.399961 -0.399961 0.500000
+v -0.438244 -0.399961 0.492385
+v -0.439203 -0.439203 0.483194
+v -0.399962 -0.438243 0.492385
+v -0.470699 -0.399961 0.470699
+v -0.465612 -0.437211 0.465612
+v -0.437212 -0.465612 0.465612
+v -0.399961 -0.470699 0.470699
+v -0.457718 -0.457718 0.457718
+v -0.492385 -0.438244 0.399961
+v -0.483194 -0.439203 0.439203
+v -0.492385 -0.399960 0.438244
+v -0.470699 -0.470699 0.399961
+v -0.465612 -0.465612 0.437212
+v -0.399961 -0.500000 0.399961
+v -0.399961 -0.492384 0.438244
+v -0.439203 -0.483194 0.439203
+v -0.438244 -0.492385 0.399961
+v 0.499961 0.500000 -0.499961
+v 0.499961 -0.500000 -0.499961
+v -0.492384 0.499961 0.438244
+v -0.470699 0.499961 0.470699
+v -0.438244 0.499962 0.492385
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.150010 0.525010
+vt 0.349990 0.724990
+vt 0.150010 0.724990
+vt 0.599990 0.775010
+vt 0.400010 0.974990
+vt 0.400010 0.775010
+vt 0.599990 0.765439
+vt 0.609561 0.775010
+vt 0.599990 0.750000
+vt 0.609801 0.765199
+vt 0.625000 0.775010
+vt 0.614430 0.750000
+vt 0.625000 0.765697
+vt 0.359561 0.724990
+vt 0.349990 0.734561
+vt 0.375000 0.724990
+vt 0.359801 0.734801
+vt 0.349990 0.750000
+vt 0.375000 0.739430
+vt 0.359303 0.750000
+vt 0.609561 0.724990
+vt 0.599990 0.734561
+vt 0.599990 0.724990
+vt 0.625000 0.724990
+vt 0.609801 0.734801
+vt 0.599990 0.750000
+vt 0.625000 0.739430
+vt 0.609303 0.750000
+vt 0.000000 0.000000
+vt 0.400010 0.525010
+vt 0.599990 0.525010
+vt 0.609561 0.525010
+vt 0.609561 0.974990
+vt 0.400010 0.724990
+vt 0.400010 0.734561
+vt 0.400010 0.750000
+vt 0.375000 0.525010
+vt 0.359561 0.525010
+vt 0.349990 0.525010
+vt 0.150010 0.734561
+vt 0.150010 0.750000
+vt 0.400010 0.750000
+vt 0.400010 0.765439
+vt 0.599990 0.974990
+vt 0.609303 0.750000
+vt 0.375000 0.734303
+vt 0.625000 0.734303
+vt 0.625000 0.525010
+vt 0.625000 0.974990
+vn 0.8575 -0.5120 0.0504
+vn 0.8321 -0.0544 0.5520
+vn 0.8321 -0.3922 0.3922
+vn 0.2425 -0.3713 0.8963
+vn 0.3162 -0.8765 0.3630
+vn 0.6933 0.5095 0.5096
+vn -0.0588 -0.5971 -0.8000
+vn -0.3423 -0.8263 -0.4472
+vn -0.5657 -0.5657 -0.6000
+vn -0.5971 -0.0588 -0.8000
+vn -0.8264 -0.3423 -0.4472
+vn -0.5774 0.5773 -0.5774
+vn -0.9905 -0.0970 0.0970
+vn -0.7244 0.6857 0.0714
+vn -0.0970 -0.0970 0.9905
+vn -0.0714 0.6857 0.7244
+vn -0.3783 -0.0972 0.9206
+vn -0.0972 -0.3783 0.9206
+vn -0.7041 -0.0919 0.7041
+vn -0.3703 -0.3703 0.8519
+vn -0.0919 -0.7041 0.7041
+vn -0.5774 -0.5773 0.5774
+vn -0.3266 -0.6683 0.6683
+vn -0.9206 -0.3783 0.0972
+vn -0.9206 -0.0972 0.3783
+vn -0.7041 -0.7041 0.0919
+vn -0.8519 -0.3703 0.3703
+vn -0.6683 -0.3266 0.6683
+vn -0.0972 -0.9206 0.3783
+vn -0.3783 -0.9206 0.0972
+vn -0.0970 -0.9905 0.0970
+vn -0.3703 -0.8519 0.3703
+vn -0.6683 -0.6683 0.3266
+vn 0.5773 0.5774 -0.5773
+vn 0.5000 -0.7071 -0.5000
+vn -0.6894 0.6657 0.2856
+vn -0.5277 0.6657 0.5276
+vn -0.2856 0.6657 0.6894
+usemtl Default_OBJ.005
+s 1
+f 1/1/1 2/2/2 3/3/3
+f 2/2/2 4/4/4 3/3/3
+f 5/5/5 1/1/1 3/3/3
+f 2/2/2 1/1/1 6/6/6
+f 7/7/7 8/8/8 9/9/9
+f 10/10/10 7/7/7 9/9/9
+f 11/11/11 10/10/10 9/9/9
+f 12/12/12 13/13/13 14/14/14
+f 16/15/15 6/16/6 15/17/16
+f 17/18/17 19/19/18 16/15/15
+f 20/20/19 18/21/20 17/18/17
+f 18/21/20 23/22/21 19/19/18
+f 18/21/20 24/23/22 22/24/23
+f 25/25/24 27/26/25 13/13/13
+f 28/27/26 26/28/27 25/25/24
+f 26/28/27 20/29/19 27/26/25
+f 26/28/27 24/30/22 21/31/28
+f 31/32/29 33/33/30 30/34/31
+f 23/35/21 32/36/32 31/32/29
+f 32/36/32 28/37/26 33/33/30
+f 32/36/32 24/38/22 29/39/33
+f 10/10/10 12/12/12 34/40/34
+f 34/40/34 1/1/1 35/41/35
+f 34/40/34 14/14/14 15/17/16
+f 1/42/1 31/32/29 30/34/31
+f 5/43/5 23/35/21 31/32/29
+f 23/22/21 4/44/4 19/19/18
+f 4/44/4 16/15/15 19/19/18
+f 7/45/7 33/33/30 8/46/8
+f 33/33/30 9/47/9 8/46/8
+f 9/48/9 25/25/24 11/49/11
+f 25/25/24 10/50/10 11/49/11
+f 13/13/13 36/51/36 14/14/14
+f 27/26/25 37/52/37 36/51/36
+f 37/53/37 17/18/17 38/54/38
+f 17/18/17 15/17/16 38/54/38
+f 35/41/35 30/34/31 7/45/7
+f 12/12/12 10/50/10 13/13/13
+f 16/15/15 2/55/2 6/16/6
+f 17/18/17 18/21/20 19/19/18
+f 20/20/19 21/56/28 18/21/20
+f 18/21/20 22/24/23 23/22/21
+f 18/21/20 21/56/28 24/23/22
+f 25/25/24 26/28/27 27/26/25
+f 28/27/26 29/57/33 26/28/27
+f 26/28/27 21/31/28 20/29/19
+f 26/28/27 29/57/33 24/30/22
+f 31/32/29 32/36/32 33/33/30
+f 23/35/21 22/58/23 32/36/32
+f 32/36/32 29/39/33 28/37/26
+f 32/36/32 22/58/23 24/38/22
+f 35/41/35 7/7/7 34/40/34
+f 7/7/7 10/10/10 34/40/34
+f 34/40/34 6/16/6 1/1/1
+f 12/12/12 14/14/14 34/40/34
+f 14/14/14 36/51/36 38/54/38
+f 36/51/36 37/52/37 38/54/38
+f 38/54/38 15/17/16 14/14/14
+f 15/17/16 6/16/6 34/40/34
+f 1/42/1 5/43/5 31/32/29
+f 5/43/5 3/59/3 23/35/21
+f 23/22/21 3/60/3 4/44/4
+f 4/44/4 2/55/2 16/15/15
+f 7/45/7 30/34/31 33/33/30
+f 33/33/30 28/37/26 9/47/9
+f 9/48/9 28/27/26 25/25/24
+f 25/25/24 13/13/13 10/50/10
+f 13/13/13 27/26/25 36/51/36
+f 27/26/25 20/29/19 37/52/37
+f 37/53/37 20/20/19 17/18/17
+f 17/18/17 16/15/15 15/17/16
+f 35/41/35 1/42/1 30/34/31
diff --git a/public/resources/c001001.obj b/public/resources/c001001.obj
new file mode 100644
index 0000000..c4bcb41
--- /dev/null
+++ b/public/resources/c001001.obj
@@ -0,0 +1,213 @@
+# Blender v2.82 (sub 7) OBJ File: ''
+# www.blender.org
+mtllib c001001.mtl
+o Cube_Cube.010
+v -0.499961 0.500000 -0.399961
+v -0.499961 0.399961 0.500000
+v -0.499961 0.500000 0.399961
+v -0.499961 0.470699 0.470699
+v -0.499961 0.492385 0.438244
+v -0.499961 0.492385 -0.438244
+v -0.499961 0.470699 -0.470699
+v -0.499961 0.438244 -0.492385
+v -0.499961 0.399961 -0.500000
+v -0.499961 -0.399961 -0.500000
+v -0.499961 -0.438244 -0.492385
+v -0.499961 -0.470699 -0.470699
+v -0.499961 0.438244 0.492385
+v -0.499961 -0.399961 0.500000
+v -0.499961 -0.500000 0.399961
+v -0.499961 -0.470699 0.470699
+v 0.499961 0.500000 0.399961
+v 0.499961 0.399961 -0.500000
+v 0.499961 0.500000 -0.399961
+v -0.499961 -0.438244 0.492385
+v -0.499961 -0.500000 -0.399961
+v -0.499961 -0.492385 0.438244
+v -0.499961 -0.492385 -0.438244
+v 0.499961 0.470699 -0.470699
+v 0.499961 0.492385 -0.438244
+v 0.499961 0.492385 0.438244
+v 0.499961 0.470699 0.470699
+v 0.499961 0.438244 0.492385
+v 0.499961 0.399961 0.500000
+v 0.499961 -0.399961 0.500000
+v 0.499961 -0.438244 0.492385
+v 0.499961 -0.470699 0.470699
+v 0.499961 0.438244 -0.492385
+v 0.499961 -0.399961 -0.500000
+v 0.499961 -0.500000 -0.399961
+v 0.499961 -0.470699 -0.470699
+v 0.499961 -0.438244 -0.492385
+v 0.499961 -0.500000 0.399961
+v 0.499961 -0.492385 -0.438244
+v 0.499961 -0.492385 0.438244
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.150010 0.525010
+vt 0.349990 0.525010
+vt 0.349990 0.724990
+vt 0.150010 0.724990
+vt 0.650010 0.525010
+vt 0.849990 0.525010
+vt 0.849990 0.724990
+vt 0.650010 0.724990
+vt 0.400010 0.025010
+vt 0.599990 0.025010
+vt 0.599990 0.224990
+vt 0.400010 0.224990
+vt 0.599990 0.234561
+vt 0.400010 0.234561
+vt 0.599990 0.250000
+vt 0.400010 0.250000
+vt 0.125000 0.724990
+vt 0.125000 0.525010
+vt 0.140439 0.525010
+vt 0.140439 0.724990
+vt 0.400010 0.015439
+vt 0.599990 0.015439
+vt 0.400010 0.000000
+vt 0.599990 0.000000
+vt 0.625000 0.724990
+vt 0.625000 0.525010
+vt 0.640439 0.525010
+vt 0.640439 0.724990
+vt 0.400010 0.724990
+vt 0.599990 0.724990
+vt 0.599990 0.734561
+vt 0.400010 0.734561
+vt 0.599990 0.750000
+vt 0.400010 0.750000
+vt 0.375000 0.525010
+vt 0.375000 0.724990
+vt 0.359561 0.724990
+vt 0.359561 0.525010
+vt 0.599990 0.525010
+vt 0.400010 0.525010
+vt 0.400010 0.515439
+vt 0.599990 0.515439
+vt 0.400010 0.500000
+vt 0.599990 0.500000
+vt 0.875000 0.525010
+vt 0.875000 0.724990
+vt 0.859561 0.724990
+vt 0.859561 0.525010
+vn -1.0000 0.0000 -0.0000
+vn 1.0000 -0.0000 0.0000
+vn -0.0000 -0.9952 -0.0980
+vn -0.0000 -0.9952 0.0980
+vn 0.0000 0.9952 -0.0980
+vn 0.0000 0.9952 0.0980
+vn 0.0000 0.0980 -0.9952
+vn 0.0000 -0.0980 -0.9952
+vn 0.0000 -0.3827 -0.9239
+vn 0.0000 -0.7071 -0.7071
+vn -0.0000 -0.9239 -0.3827
+vn 0.0000 0.3827 -0.9239
+vn 0.0000 0.7071 -0.7071
+vn 0.0000 0.9239 -0.3827
+vn -0.0000 -0.0980 0.9952
+vn -0.0000 -0.3827 0.9239
+vn -0.0000 -0.7071 0.7071
+vn -0.0000 -0.9239 0.3827
+vn -0.0000 0.0980 0.9952
+vn -0.0000 0.3827 0.9239
+vn -0.0000 0.7071 0.7071
+vn 0.0000 0.9239 0.3827
+usemtl Default_OBJ.006
+s off
+f 1/1/1 2/2/1 3/3/1
+f 4/4/1 5/5/1 3/3/1
+f 1/1/1 6/6/1 7/7/1
+f 8/8/1 9/9/1 7/7/1
+f 10/10/1 11/11/1 12/12/1
+f 2/2/1 13/13/1 4/4/1
+f 14/14/1 15/15/1 16/16/1
+f 15/15/1 14/14/1 9/9/1
+f 2/2/1 1/1/1 14/14/1
+f 10/10/1 15/15/1 9/9/1
+f 17/17/2 18/18/2 19/19/2
+f 3/3/1 2/2/1 4/4/1
+f 9/9/1 1/1/1 7/7/1
+f 1/1/1 9/9/1 14/14/1
+f 20/20/1 14/14/1 16/16/1
+f 21/21/1 10/10/1 12/12/1
+f 15/15/1 22/22/1 16/16/1
+f 15/15/1 10/10/1 21/21/1
+f 12/12/1 23/23/1 21/21/1
+f 24/24/2 25/25/2 19/19/2
+f 17/17/2 26/26/2 27/27/2
+f 28/28/2 29/29/2 27/27/2
+f 30/30/2 31/31/2 32/32/2
+f 18/18/2 33/33/2 24/24/2
+f 34/34/2 35/35/2 36/36/2
+f 35/35/2 34/34/2 29/29/2
+f 18/18/2 17/17/2 34/34/2
+f 30/30/2 35/35/2 29/29/2
+f 19/19/2 18/18/2 24/24/2
+f 29/29/2 17/17/2 27/27/2
+f 17/17/2 29/29/2 34/34/2
+f 37/37/2 34/34/2 36/36/2
+f 38/38/2 30/30/2 32/32/2
+f 35/35/2 39/39/2 36/36/2
+f 35/35/2 30/30/2 38/38/2
+f 32/32/2 40/40/2 38/38/2
+s 1
+f 35/41/3 38/42/4 15/43/4 21/44/3
+f 1/45/5 3/46/6 17/47/6 19/48/5
+f 9/49/7 18/50/7 34/51/8 10/52/8
+f 10/52/8 34/51/8 37/53/9 11/54/9
+f 11/54/9 37/53/9 36/55/10 12/56/10
+f 12/57/10 36/58/10 39/59/11 23/60/11
+f 23/60/11 39/59/11 35/41/3 21/44/3
+f 18/50/7 9/49/7 8/61/12 33/62/12
+f 33/62/12 8/61/12 7/63/13 24/64/13
+f 24/65/13 7/66/13 6/67/14 25/68/14
+f 25/68/14 6/67/14 1/45/5 19/48/5
+f 30/69/15 14/70/15 20/71/16 31/72/16
+f 31/72/16 20/71/16 16/73/17 32/74/17
+f 32/75/17 16/76/17 22/77/18 40/78/18
+f 40/78/18 22/77/18 15/43/4 38/42/4
+f 2/79/19 29/80/19 28/81/20 13/82/20
+f 13/82/20 28/81/20 27/83/21 4/84/21
+f 4/85/21 27/86/21 26/87/22 5/88/22
+f 5/88/22 26/87/22 17/47/6 3/46/6
+f 29/80/19 2/79/19 14/70/15 30/69/15
diff --git a/public/resources/c001011.obj b/public/resources/c001011.obj
new file mode 100644
index 0000000..8a3bbc8
--- /dev/null
+++ b/public/resources/c001011.obj
@@ -0,0 +1,131 @@
+# Blender v2.82 (sub 7) OBJ File: ''
+# www.blender.org
+mtllib c001011.mtl
+o Cube_Cube.011
+v -0.499961 -0.500000 -0.499961
+v -0.499961 -0.500000 0.499961
+v -0.499961 0.500000 0.499961
+v -0.499961 0.500000 -0.499961
+v 0.399961 0.500000 -0.499961
+v 0.438244 0.492385 -0.499961
+v 0.470699 0.470699 -0.499961
+v 0.399961 -0.500000 -0.499961
+v 0.500000 -0.399961 -0.499961
+v 0.470699 -0.470699 -0.499961
+v 0.500000 0.399961 -0.499961
+v 0.492385 0.438244 -0.499961
+v 0.438244 -0.492385 -0.499961
+v 0.492385 -0.438244 -0.499961
+v 0.399961 0.500000 0.499961
+v 0.399961 -0.500000 0.499961
+v 0.500000 -0.399961 0.499961
+v 0.500000 0.399961 0.499961
+v 0.438244 -0.492385 0.499961
+v 0.470699 -0.470699 0.499961
+v 0.438244 0.492385 0.499961
+v 0.470699 0.470699 0.499961
+v 0.492385 0.438244 0.499961
+v 0.492385 -0.438244 0.499961
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.150010 0.525010
+vt 0.349990 0.525010
+vt 0.349990 0.724990
+vt 0.150010 0.724990
+vt 0.400010 0.025010
+vt 0.599990 0.025010
+vt 0.599990 0.224990
+vt 0.400010 0.224990
+vt 0.599990 0.234561
+vt 0.400010 0.234561
+vt 0.599990 0.250000
+vt 0.400010 0.250000
+vt 0.125000 0.724990
+vt 0.125000 0.525010
+vt 0.140439 0.525010
+vt 0.140439 0.724990
+vt 0.400010 0.724990
+vt 0.599990 0.724990
+vt 0.599990 0.734561
+vt 0.400010 0.734561
+vt 0.599990 0.750000
+vt 0.400010 0.750000
+vt 0.375000 0.525010
+vt 0.375000 0.724990
+vt 0.359561 0.724990
+vt 0.359561 0.525010
+vt 0.400010 0.525010
+vt 0.599990 0.525010
+vn -1.0000 0.0000 0.0000
+vn 0.0000 0.0000 -1.0000
+vn 0.0000 0.0000 1.0000
+vn 0.9952 -0.0980 0.0000
+vn 0.9952 0.0980 0.0000
+vn 0.0000 -1.0000 0.0000
+vn 0.0980 -0.9952 0.0000
+vn 0.3827 -0.9239 0.0000
+vn 0.7071 -0.7071 0.0000
+vn 0.9239 -0.3827 0.0000
+vn 0.0980 0.9952 0.0000
+vn 0.3827 0.9239 0.0000
+vn 0.7071 0.7071 0.0000
+vn 0.9239 0.3827 0.0000
+vn 0.0000 1.0000 0.0000
+usemtl Default_OBJ.007
+s off
+f 1/1/1 2/2/1 3/3/1
+f 4/4/1 1/1/1 3/3/1
+f 5/5/2 6/6/2 7/7/2
+f 8/8/2 9/9/2 10/10/2
+f 5/5/2 1/1/2 4/4/2
+f 5/5/2 8/8/2 1/1/2
+f 8/8/2 11/11/2 9/9/2
+f 11/11/2 5/5/2 7/7/2
+f 12/12/2 11/11/2 7/7/2
+f 13/13/2 8/8/2 10/10/2
+f 11/11/2 8/8/2 5/5/2
+f 14/14/2 10/10/2 9/9/2
+f 15/15/3 3/3/3 2/2/3
+f 15/15/3 2/2/3 16/16/3
+f 16/16/3 17/17/3 15/15/3
+f 17/17/3 18/18/3 15/15/3
+f 16/16/3 19/19/3 20/20/3
+f 21/21/3 15/15/3 22/22/3
+f 17/17/3 16/16/3 20/20/3
+f 18/18/3 23/23/3 22/22/3
+f 15/15/3 18/18/3 22/22/3
+f 20/20/3 24/24/3 17/17/3
+s 1
+f 9/25/4 11/26/5 18/27/5 17/28/4
+f 2/29/6 1/30/6 8/31/7 16/32/7
+f 16/32/7 8/31/7 13/33/8 19/34/8
+f 19/34/8 13/33/8 10/35/9 20/36/9
+f 20/37/9 10/38/9 14/39/10 24/40/10
+f 24/40/10 14/39/10 9/25/4 17/28/4
+f 5/41/11 15/42/11 21/43/12 6/44/12
+f 6/44/12 21/43/12 22/45/13 7/46/13
+f 7/47/13 22/48/13 23/49/14 12/50/14
+f 12/50/14 23/49/14 18/27/5 11/26/5
+f 4/51/15 3/52/15 15/42/11 5/41/11
diff --git a/public/resources/c001111.obj b/public/resources/c001111.obj
new file mode 100644
index 0000000..9292a27
--- /dev/null
+++ b/public/resources/c001111.obj
@@ -0,0 +1,92 @@
+# Blender v2.82 (sub 7) OBJ File: ''
+# www.blender.org
+mtllib c001111.mtl
+o Cube_Cube.011
+v 0.505169 -0.500000 -0.494698
+v -0.494698 -0.500000 -0.505169
+v 0.495745 -0.500000 0.405174
+v 0.494698 -0.399961 0.505208
+v 0.495005 -0.470699 0.475909
+v 0.494698 0.499961 0.505208
+v 0.495344 -0.492385 0.443455
+v 0.494777 -0.438244 0.497593
+v -0.504122 -0.500000 0.394704
+v -0.505169 -0.399961 0.494737
+v -0.505169 0.499961 0.494737
+v -0.504523 -0.492385 0.432985
+v -0.504863 -0.470699 0.465438
+v 0.505169 0.500000 -0.494698
+v -0.494698 0.500000 -0.505169
+v -0.505090 -0.438244 0.487123
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.000000 0.000000
+vt 0.150010 0.525010
+vt 0.349990 0.525010
+vt 0.349990 0.724990
+vt 0.150010 0.724990
+vt 0.400010 0.025010
+vt 0.599990 0.025010
+vt 0.599990 0.224990
+vt 0.400010 0.224990
+vt 0.599990 0.234561
+vt 0.400010 0.234561
+vt 0.599990 0.250000
+vt 0.400010 0.250000
+vt 0.125000 0.724990
+vt 0.125000 0.525010
+vt 0.140439 0.525010
+vt 0.140439 0.724990
+vn 0.9280 -0.3696 0.0461
+vn 0.8262 -0.0544 0.5607
+vn 0.8279 -0.3922 0.4009
+vn 0.8122 0.4082 0.4168
+vn 0.4436 -0.8264 0.3469
+vn 0.4385 -0.3423 0.8310
+vn 0.5834 -0.5774 -0.5713
+vn 0.5834 0.5774 -0.5713
+vn -0.8990 -0.0438 0.4357
+vn -0.9013 0.3015 -0.3110
+vn -0.8948 -0.4451 0.0344
+vn -0.3997 -0.4082 -0.8207
+vn -0.4508 -0.8263 0.3376
+vn -0.8361 -0.3922 0.3835
+vn -0.4125 0.8165 0.4040
+vn -0.4558 -0.3423 0.8216
+usemtl Default_OBJ.007
+s 1
+f 3/1/1 4/2/2 5/3/3
+f 3/1/1 6/4/4 4/2/2
+f 7/5/5 3/1/1 5/3/3
+f 8/6/6 5/3/3 4/2/2
+f 1/7/7 14/8/8 3/1/1
+f 10/9/9 15/10/10 9/11/11
+f 14/8/8 2/12/12 15/10/10
+f 9/11/11 12/13/13 13/14/14
+f 11/15/15 14/8/8 15/10/10
+f 10/9/9 9/11/11 13/14/14
+f 11/15/15 6/4/4 14/8/8
+f 14/8/8 1/7/7 2/12/12
+f 13/14/14 16/16/16 10/9/9
+f 4/17/2 6/18/4 11/19/15 10/20/9
+f 2/21/12 1/22/7 3/23/1 9/24/11
+f 9/24/11 3/23/1 7/25/5 12/26/13
+f 12/26/13 7/25/5 5/27/3 13/28/14
+f 13/29/14 5/30/3 8/31/6 16/32/16
+f 16/32/16 8/31/6 4/17/2 10/20/9
+f 14/8/8 6/4/4 3/1/1
+f 15/10/10 2/12/12 9/11/11
+f 11/15/15 15/10/10 10/9/9
diff --git a/public/resources/bevel-cube/xymxmy.obj b/public/resources/c011011.obj
similarity index 97%
rename from public/resources/bevel-cube/xymxmy.obj
rename to public/resources/c011011.obj
index 615195c..2145024 100644
--- a/public/resources/bevel-cube/xymxmy.obj
+++ b/public/resources/c011011.obj
@@ -1,6 +1,5 @@
# Blender v2.82 (sub 7) OBJ File: ''
# www.blender.org
-mtllib xymxmy.mtl
o Cube_Cube.001
v 0.499961 0.500000 -0.499961
v 0.499961 -0.500000 -0.499961
@@ -32,7 +31,6 @@ vn -1.0000 0.0000 0.0000
vn 0.0000 -0.0000 1.0000
vn 0.0000 -1.0000 -0.0000
vn 0.0000 1.0000 0.0000
-usemtl None
s off
f 2/1/1 6/2/1 5/3/1
f 1/4/1 2/1/1 5/3/1
diff --git a/public/solver/SomaSolver.js b/public/solver/SomaSolver.js
index c69072b..0d22f29 100644
--- a/public/solver/SomaSolver.js
+++ b/public/solver/SomaSolver.js
@@ -21,6 +21,7 @@ export default class SomaSolver {
this.solutions = [];
const combosWithRots = polycubes.slice(1).map(polycube => polycube.getUniqueRotations().map((rot) => rot.getAllPositionsInCube(this.dim)).flat());
const combos = [polycubes[0].getAllPositionsInCube(this.dim), ...combosWithRots];
+ console.log(combos.flat().length);
this.backtrackSolve(this.solutionCube, combos, new SomaSolution(this.dim));
this.solutions = SomaSolution.filterUnique(this.solutions);
}
@@ -46,3 +47,92 @@ export default class SomaSolver {
}
}
}
+
+class SomaSolution {
+ constructor(dim) {
+ if (dim < 0 || dim % 1 !== 0) {
+ throw new Error("Dimension must be a whole positive integer!");
+ }
+ this.dim = dim;
+ this.solutionSpaces = [];
+ }
+ static filterUnique(solutions) {
+ if (solutions.length === 0) {
+ return [];
+ }
+ const uniqueSolns = [solutions[0]];
+ for (const solution of solutions) {
+ let foundMatch = false;
+ for (const rotation of solution.getUniqueRotations()) {
+ let end = uniqueSolns.length;
+ for (let i = 0; i < end; i++) {
+ if (rotation.matches(uniqueSolns[i])) {
+ foundMatch = true;
+ }
+ }
+ }
+ if (!foundMatch) {
+ uniqueSolns.push(solution);
+ }
+ }
+ return uniqueSolns;
+ }
+ getUniqueRotations() {
+ if (this.solutionSpaces.length === 0) {
+ return [];
+ }
+ const result = [];
+ const allRots = this.solutionSpaces.map(space => space.getAllRotations());
+ for (let i = 0; i < allRots[0].length; i++) {
+ const solnRot = new SomaSolution(this.dim);
+ allRots.forEach(rotGroup => solnRot.addSpace(rotGroup[i]));
+ result.push(solnRot);
+ }
+ return result;
+ }
+ matches(solution) {
+ for (let i = 0; i < this.solutionSpaces.length; i++) {
+ if (!this.solutionSpaces[i].matches(solution.solutionSpaces[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ addSpace(space) {
+ this.solutionSpaces.push(space);
+ }
+ print() {
+ let accum = "";
+ console.log("---");
+ for (let x = 0; x < this.dim; x++) {
+ for (let y = 0; y < this.dim; y++) {
+ for (let z = 0; z < this.dim; z++) {
+ for (const space of this.solutionSpaces) {
+ if (space.at(x, y, z)) {
+ accum += space.getId();
+ }
+ }
+ }
+ console.log(accum);
+ accum = "";
+ }
+ if (x !== this.dim - 1) {
+ console.log("-");
+ }
+ }
+ console.log("---");
+ }
+ at(x, y, z) {
+ for (const space of this.solutionSpaces) {
+ if (space.at(x, y, z)) {
+ return space.getId();
+ }
+ }
+ return 0;
+ }
+ clone() {
+ const clone = new SomaSolution(this.dim);
+ clone.solutionSpaces = this.solutionSpaces.slice();
+ return clone;
+ }
+}
diff --git a/public/solver/as-bind.esm.js b/public/solver/as-bind.esm.js
new file mode 100644
index 0000000..89727ba
--- /dev/null
+++ b/public/solver/as-bind.esm.js
@@ -0,0 +1 @@
+var t="0.7.0";const e="undefined"!=typeof BigUint64Array,r=Symbol(),n=new TextDecoder("utf-16le");function s(t,e){const r=new Uint32Array(t)[e+-4>>>2]>>>1,s=new Uint16Array(t,e,r);return r<=32?String.fromCharCode.apply(String,s):n.decode(s)}function i(t){const e={};function r(t,e){return t?s(t.buffer,e):""}const n=t.env=t.env||{};return n.abort=n.abort||function(t,s,i,o){const a=e.memory||n.memory;throw Error(`abort: ${r(a,t)} at ${r(a,s)}:${i}:${o}`)},n.trace=n.trace||function(t,s,...i){const o=e.memory||n.memory;console.log(`trace: ${r(o,t)}${s?" ":""}${i.slice(0,s).join(", ")}`)},n.seed=n.seed||Date.now,t.Math=t.Math||Math,t.Date=t.Date||Date,e}const o=function(){throw Error("Operation requires compiling with --exportRuntime")};function a(t,r){const n=r.exports,i=n.memory,a=n.table,c=n.__new||o,u=n.__pin||o,y=n.__unpin||o,l=n.__collect||o,p=n.__rtti_base,d=p?function(t){return t[p>>>2]}:o;function b(t){const e=function(t){const e=new Uint32Array(i.buffer);if((t>>>=0)>=d(e))throw Error(`invalid id: ${t}`);return e[(p+4>>>2)+2*t]}(t);if(!(7&e))throw Error(`not an array: ${t}, flags=${e}`);return e}function h(t){const e=new Uint32Array(i.buffer);if((t>>>=0)>=d(e))throw Error(`invalid id: ${t}`);return e[(p+4>>>2)+2*t+1]}function m(t){return 31-Math.clz32(t>>>6&31)}function g(t,e,r){const n=i.buffer;if(r)switch(t){case 2:return new Float32Array(n);case 3:return new Float64Array(n)}else switch(t){case 0:return new(e?Int8Array:Uint8Array)(n);case 1:return new(e?Int16Array:Uint16Array)(n);case 2:return new(e?Int32Array:Uint32Array)(n);case 3:return new(e?BigInt64Array:BigUint64Array)(n)}throw Error(`unsupported align: ${t}`)}function A(t){const e=new Uint32Array(i.buffer),r=b(e[t+-8>>>2]),n=m(r);let s=4&r?t:e[t+4>>>2];const o=2&r?e[t+12>>>2]:e[s+-4>>>2]>>>n;return g(n,2048&r,4096&r).subarray(s>>>=n,s+o)}function w(t,e,r){return new t(_(t,e,r))}function _(t,e,r){const n=i.buffer,s=new Uint32Array(n),o=s[r+4>>>2];return new t(n,o,s[o+-4>>>2]>>>e)}function T(e,r,n){t[`__get${r}`]=w.bind(null,e,n),t[`__get${r}View`]=_.bind(null,e,n)}return t.__new=c,t.__pin=u,t.__unpin=y,t.__collect=l,t.__newString=function(t){if(null==t)return 0;const e=t.length,r=c(e<<1,1),n=new Uint16Array(i.buffer);for(var s=0,o=r>>>1;s>>2])throw Error(`not a string: ${t}`);return s(e,t)},t.__newArray=function(t,e){const r=b(t),n=m(r),s=e.length,o=c(s<>>2]=o,l[e+4>>>2]=o,l[e+8>>>2]=s<>>2]=s),a=e}const l=g(n,2048&r,4096&r);if(16384&r)for(let t=0;t>>n)+t]=r}else l.set(e,o>>>n);return a},t.__getArrayView=A,t.__getArray=function(t){const e=A(t),r=e.length,n=new Array(r);for(let t=0;t>>2];return e.slice(t,t+r)},[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array].forEach((t=>{T(t,t.name,31-Math.clz32(t.BYTES_PER_ELEMENT))})),e&&[BigUint64Array,BigInt64Array].forEach((t=>{T(t,t.name.slice(3),3)})),t.__instanceof=function(t,e){const r=new Uint32Array(i.buffer);let n=r[t+-8>>>2];if(n<=d(r))do{if(n==e)return!0;n=h(n)}while(n);return!1},t.memory=t.memory||i,t.table=t.table||a,f(n,t)}function c(t){return"undefined"!=typeof Response&&t instanceof Response}function u(t){return t instanceof WebAssembly.Module}async function y(t,e={}){if(c(t=await t))return l(t,e);const r=u(t)?t:await WebAssembly.compile(t),n=i(e),s=await WebAssembly.instantiate(r,e);return{module:r,instance:s,exports:a(n,s)}}async function l(t,e={}){if(!WebAssembly.instantiateStreaming)return y(c(t=await t)?t.arrayBuffer():t,e);const r=i(e),n=await WebAssembly.instantiateStreaming(t,e),s=a(r,n.instance);return{...n,exports:s}}function f(t,e={}){const n=t.__argumentsLength?e=>{t.__argumentsLength.value=e}:t.__setArgumentsLength||t.__setargc||(()=>{});for(let s in t){if(!Object.prototype.hasOwnProperty.call(t,s))continue;const i=t[s];let o=s.split("."),a=e;for(;o.length>1;){let t=o.shift();Object.prototype.hasOwnProperty.call(a,t)||(a[t]={}),a=a[t]}let c=o[0],u=c.indexOf("#");if(u>=0){const e=c.substring(0,u),o=a[e];if(void 0===o||!o.prototype){const t=function(...e){return t.wrap(t.prototype.constructor(0,...e))};t.prototype={valueOf(){return this[r]}},t.wrap=function(e){return Object.create(t.prototype,{[r]:{value:e,writable:!1}})},o&&Object.getOwnPropertyNames(o).forEach((e=>Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e)))),a[e]=t}if(c=c.substring(u+1),a=a[e].prototype,/^(get|set):/.test(c)){if(!Object.prototype.hasOwnProperty.call(a,c=c.substring(4))){let e=t[s.replace("set:","get:")],n=t[s.replace("get:","set:")];Object.defineProperty(a,c,{get(){return e(this[r])},set(t){n(this[r],t)},enumerable:!0})}}else"constructor"===c?(a[c]=(...t)=>(n(t.length),i(...t))).original=i:(a[c]=function(...t){return n(t.length),i(this[r],...t)}).original=i}else/^(get|set):/.test(c)?Object.prototype.hasOwnProperty.call(a,c=c.substring(4))||Object.defineProperty(a,c,{get:t[s.replace("set:","get:")],set:t[s.replace("get:","set:")],enumerable:!0}):"function"==typeof i&&i!==n?(a[c]=(...t)=>(n(t.length),i(...t))).original=i:a[c]=i}return e}var p={instantiate:y,instantiateSync:function(t,e={}){const r=u(t)?t:new WebAssembly.Module(t),n=i(e),s=new WebAssembly.Instance(r,e);return{module:r,instance:s,exports:a(n,s)}},instantiateStreaming:l,demangle:f};function d(t,e,r){return e}function b(t,e,r){return t.exports.__getArrayBuffer(e)}function h(t,e,r){return t.exports[`__get${function(t){return t.startsWith("~lib/typedarray/")?((t=t.slice("~lib/typedarray/".length)).startsWith("Big")&&(t=t.slice(3)),t):t}(r)}View`](e)}function m(t,e,r){return t.exports.__newArray(t.getTypeId(r),e)}function g(t){if(!t.startsWith("~lib/array/Array"))throw Error(`${JSON.stringify(t)} is not an array type`);return t.slice("~lib/array/Array<".length,-1)}const A=new Map([["void",{ascToJs:d,jsToAsc:d}],[/^(i|u|f)(8|16|32|64)|[ui]size|bool|externref$/,{ascToJs:d,jsToAsc:d}],["~lib/string/String",{ascToJs:function(t,e,r){return t.exports.__getString(e)},jsToAsc:function(t,e,r){return t.exports.__newString(e)}}],["~lib/typedarray/Int8Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Int16Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Int32Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint8Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint16Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint32Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Int64Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint64Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint8ClampedArray",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Float32Array",{ascToJs:b,jsToAsc:m}],["~lib/typedarray/Float64Array",{ascToJs:b,jsToAsc:m}],["~lib/arraybuffer/ArrayBuffer",{ascToJs:b,jsToAsc:function(t,e,r){const n=t.exports.__new(e.byteLength,t.getTypeId(r));return new Uint8Array(t.exports.memory.buffer,n,e.byteLength).set(new Uint8Array(e)),n}}],[/^~lib\/array\/Array<.+>$/,{ascToJs:function(t,e,r){const n=g(r),s=_(n);return t.exports.__getArray(e).map((e=>s.ascToJs(t,e,n)))},jsToAsc:function(t,e,r){const n=g(r),s=_(n),i=e.map((e=>s.jsToAsc(t,e,n)));return t.exports.__newArray(t.getTypeId(r),i)}}]]),w=new Set;function _(t){for(const[e,r]of A)if("string"!=typeof e){if(e.test(t))return r}else if(e===t)return r;return w.has(t)||(console.warn(`No converter for ${JSON.stringify(t)}, using pass-through`),w.add(t)),{ascToJs:d,jsToAsc:d}}function T(t){var e;return null===(e=_(t))||void 0===e?void 0:e.ascToJs}function j(t){var e;return null===(e=_(t))||void 0===e?void 0:e.jsToAsc}function O(t,e,r){const n=r.parameters.map(T),s=j(r.returnType);return function(...i){if(i.length!=n.length)throw Error(`Expected ${n.length} arguments, got ${i.length}`);const o=i.map(((e,s)=>n[s](t,e,r.parameters[s]))),a=e(...o);return s(t,a,r.returnType)}}function U(t,e,r){const n=r.parameters.map(j),s=T(r.returnType);return(...i)=>{if(i.length!=n.length)throw Error(`Expected ${n.length} arguments, got ${i.length}`);const o=i.map(((e,s)=>n[s](t,e,r.parameters[s]))),a=e(...o);return s(t,a,r.returnType)}}function x(t,{depth:e=Number.POSITIVE_INFINITY}={}){return e<=0||!t||"object"!=typeof t?t:Object.fromEntries(Object.entries(t).map((([t,r])=>[t,x(r,{depth:e-1})])))}function E(t){const e=WebAssembly.Module.customSections(t,"as-bind_bindings"),r=new TextDecoder("utf8").decode(new Uint8Array(e[0]));try{return JSON.parse(r)}catch(t){throw Error(`Couldn’t decode type descriptor: ${t.message}`)}}class S{constructor(){this.unboundExports={},this.exports={},this.importObject={}}getTypeId(t){if(t in this.typeDescriptor.typeIds)return this.typeDescriptor.typeIds[t].id;throw Error(`Unknown type ${JSON.stringify(t)}`)}getTypeSize(t){if(t in this.typeDescriptor.typeIds)return this.typeDescriptor.typeIds[t].byteSize;throw Error(`Unknown type ${JSON.stringify(t)}`)}_validate(){if(!WebAssembly.Module.exports(this.module).find((t=>"__new"===t.name)))throw Error("The AssemblyScript wasm module was not built with --exportRuntime, which is required.");if(1!==WebAssembly.Module.customSections(this.module,"as-bind_bindings").length)throw new Error("The AssemblyScript wasm module was not built with the as-bind transform.")}async _instantiate(t,e){this.module=await async function(t){if(t=await Promise.resolve(t),"undefined"!=typeof Response&&t instanceof Response){if(WebAssembly.compileStreaming)return WebAssembly.compileStreaming(t);t=await t.arrayBuffer()}return WebAssembly.compile(t)}(t),this._validate(),this.typeDescriptor=E(this.module),this._instantiateBindImportFunctions(e),this.loadedModule=await async function(t,e){return p.instantiate(t,e)}(this.module,this.importObject),this._instantiateBindUnboundExports()}_instantiateSync(t,e){this.module=new WebAssembly.Module(t),this._validate(),this.typeDescriptor=E(this.module),this._instantiateBindImportFunctions(e),this.loadedModule=function(t,e){return p.instantiateSync(t,e)}(this.module,this.importObject),this._instantiateBindUnboundExports()}_instantiateBindImportFunctions(t){this.importObject=x(t,{depth:2});for(const[e,r]of Object.entries(this.typeDescriptor.importedFunctions))for(const[n,s]of Object.entries(r))this.importObject[e][`__asbind_unbound_${n}`]=t[e][n],this.importObject[e][n]=O(this,t[e][n],s)}_instantiateBindUnboundExports(){const t=this.loadedModule.exports;this.exports=x(t,{depth:1});for(const[e,r]of Object.entries(this.typeDescriptor.exportedFunctions))this.exports[e]=U(this,t[e],r)}}async function I(t,e){let r=new S;return await r._instantiate(t,e),r}function $(t,e){let r=new S;return r._instantiateSync(t,e),r}export{A as converters,I as instantiate,$ as instantiateSync,t as version};
diff --git a/public/solver/main.js b/public/solver/main.js
index b0bfe64..444b8ca 100644
--- a/public/solver/main.js
+++ b/public/solver/main.js
@@ -1,8 +1,340 @@
-import SomaSolver from "./SomaSolver.js";
-import VoxelSpace from "./VoxelSpace.js";
+var t="0.7.0";const e="undefined"!=typeof BigUint64Array,r=Symbol(),n=new TextDecoder("utf-16le");function s(t,e){const r=new Uint32Array(t)[e+-4>>>2]>>>1,s=new Uint16Array(t,e,r);return r<=32?String.fromCharCode.apply(String,s):n.decode(s)}function i(t){const e={};function r(t,e){return t?s(t.buffer,e):""}const n=t.env=t.env||{};return n.abort=n.abort||function(t,s,i,o){const a=e.memory||n.memory;throw Error(`abort: ${r(a,t)} at ${r(a,s)}:${i}:${o}`)},n.trace=n.trace||function(t,s,...i){const o=e.memory||n.memory;console.log(`trace: ${r(o,t)}${s?" ":""}${i.slice(0,s).join(", ")}`)},n.seed=n.seed||Date.now,t.Math=t.Math||Math,t.Date=t.Date||Date,e}const o=function(){throw Error("Operation requires compiling with --exportRuntime")};function a(t,r){const n=r.exports,i=n.memory,a=n.table,c=n.__new||o,u=n.__pin||o,y=n.__unpin||o,l=n.__collect||o,p=n.__rtti_base,d=p?function(t){return t[p>>>2]}:o;function b(t){const e=function(t){const e=new Uint32Array(i.buffer);if((t>>>=0)>=d(e))throw Error(`invalid id: ${t}`);return e[(p+4>>>2)+2*t]}(t);if(!(7&e))throw Error(`not an array: ${t}, flags=${e}`);return e}function h(t){const e=new Uint32Array(i.buffer);if((t>>>=0)>=d(e))throw Error(`invalid id: ${t}`);return e[(p+4>>>2)+2*t+1]}function m(t){return 31-Math.clz32(t>>>6&31)}function g(t,e,r){const n=i.buffer;if(r)switch(t){case 2:return new Float32Array(n);case 3:return new Float64Array(n)}else switch(t){case 0:return new(e?Int8Array:Uint8Array)(n);case 1:return new(e?Int16Array:Uint16Array)(n);case 2:return new(e?Int32Array:Uint32Array)(n);case 3:return new(e?BigInt64Array:BigUint64Array)(n)}throw Error(`unsupported align: ${t}`)}function A(t){const e=new Uint32Array(i.buffer),r=b(e[t+-8>>>2]),n=m(r);let s=4&r?t:e[t+4>>>2];const o=2&r?e[t+12>>>2]:e[s+-4>>>2]>>>n;return g(n,2048&r,4096&r).subarray(s>>>=n,s+o)}function w(t,e,r){return new t(_(t,e,r))}function _(t,e,r){const n=i.buffer,s=new Uint32Array(n),o=s[r+4>>>2];return new t(n,o,s[o+-4>>>2]>>>e)}function T(e,r,n){t[`__get${r}`]=w.bind(null,e,n),t[`__get${r}View`]=_.bind(null,e,n)}return t.__new=c,t.__pin=u,t.__unpin=y,t.__collect=l,t.__newString=function(t){if(null==t)return 0;const e=t.length,r=c(e<<1,1),n=new Uint16Array(i.buffer);for(var s=0,o=r>>>1;s>>2])throw Error(`not a string: ${t}`);return s(e,t)},t.__newArray=function(t,e){const r=b(t),n=m(r),s=e.length,o=c(s<>>2]=o,l[e+4>>>2]=o,l[e+8>>>2]=s<>>2]=s),a=e}const l=g(n,2048&r,4096&r);if(16384&r)for(let t=0;t>>n)+t]=r}else l.set(e,o>>>n);return a},t.__getArrayView=A,t.__getArray=function(t){const e=A(t),r=e.length,n=new Array(r);for(let t=0;t>>2];return e.slice(t,t+r)},[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array].forEach((t=>{T(t,t.name,31-Math.clz32(t.BYTES_PER_ELEMENT))})),e&&[BigUint64Array,BigInt64Array].forEach((t=>{T(t,t.name.slice(3),3)})),t.__instanceof=function(t,e){const r=new Uint32Array(i.buffer);let n=r[t+-8>>>2];if(n<=d(r))do{if(n==e)return!0;n=h(n)}while(n);return!1},t.memory=t.memory||i,t.table=t.table||a,f(n,t)}function c(t){return"undefined"!=typeof Response&&t instanceof Response}function u(t){return t instanceof WebAssembly.Module}async function y(t,e={}){if(c(t=await t))return l(t,e);const r=u(t)?t:await WebAssembly.compile(t),n=i(e),s=await WebAssembly.instantiate(r,e);return{module:r,instance:s,exports:a(n,s)}}async function l(t,e={}){if(!WebAssembly.instantiateStreaming)return y(c(t=await t)?t.arrayBuffer():t,e);const r=i(e),n=await WebAssembly.instantiateStreaming(t,e),s=a(r,n.instance);return{...n,exports:s}}function f(t,e={}){const n=t.__argumentsLength?e=>{t.__argumentsLength.value=e}:t.__setArgumentsLength||t.__setargc||(()=>{});for(let s in t){if(!Object.prototype.hasOwnProperty.call(t,s))continue;const i=t[s];let o=s.split("."),a=e;for(;o.length>1;){let t=o.shift();Object.prototype.hasOwnProperty.call(a,t)||(a[t]={}),a=a[t]}let c=o[0],u=c.indexOf("#");if(u>=0){const e=c.substring(0,u),o=a[e];if(void 0===o||!o.prototype){const t=function(...e){return t.wrap(t.prototype.constructor(0,...e))};t.prototype={valueOf(){return this[r]}},t.wrap=function(e){return Object.create(t.prototype,{[r]:{value:e,writable:!1}})},o&&Object.getOwnPropertyNames(o).forEach((e=>Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(o,e)))),a[e]=t}if(c=c.substring(u+1),a=a[e].prototype,/^(get|set):/.test(c)){if(!Object.prototype.hasOwnProperty.call(a,c=c.substring(4))){let e=t[s.replace("set:","get:")],n=t[s.replace("get:","set:")];Object.defineProperty(a,c,{get(){return e(this[r])},set(t){n(this[r],t)},enumerable:!0})}}else"constructor"===c?(a[c]=(...t)=>(n(t.length),i(...t))).original=i:(a[c]=function(...t){return n(t.length),i(this[r],...t)}).original=i}else/^(get|set):/.test(c)?Object.prototype.hasOwnProperty.call(a,c=c.substring(4))||Object.defineProperty(a,c,{get:t[s.replace("set:","get:")],set:t[s.replace("get:","set:")],enumerable:!0}):"function"==typeof i&&i!==n?(a[c]=(...t)=>(n(t.length),i(...t))).original=i:a[c]=i}return e}var p={instantiate:y,instantiateSync:function(t,e={}){const r=u(t)?t:new WebAssembly.Module(t),n=i(e),s=new WebAssembly.Instance(r,e);return{module:r,instance:s,exports:a(n,s)}},instantiateStreaming:l,demangle:f};function d(t,e,r){return e}function b(t,e,r){return t.exports.__getArrayBuffer(e)}function h(t,e,r){return t.exports[`__get${function(t){return t.startsWith("~lib/typedarray/")?((t=t.slice("~lib/typedarray/".length)).startsWith("Big")&&(t=t.slice(3)),t):t}(r)}View`](e)}function m(t,e,r){return t.exports.__newArray(t.getTypeId(r),e)}function g(t){if(!t.startsWith("~lib/array/Array"))throw Error(`${JSON.stringify(t)} is not an array type`);return t.slice("~lib/array/Array<".length,-1)}const A=new Map([["void",{ascToJs:d,jsToAsc:d}],[/^(i|u|f)(8|16|32|64)|[ui]size|bool|externref$/,{ascToJs:d,jsToAsc:d}],["~lib/string/String",{ascToJs:function(t,e,r){return t.exports.__getString(e)},jsToAsc:function(t,e,r){return t.exports.__newString(e)}}],["~lib/typedarray/Int8Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Int16Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Int32Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint8Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint16Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint32Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Int64Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint64Array",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Uint8ClampedArray",{ascToJs:h,jsToAsc:m}],["~lib/typedarray/Float32Array",{ascToJs:b,jsToAsc:m}],["~lib/typedarray/Float64Array",{ascToJs:b,jsToAsc:m}],["~lib/arraybuffer/ArrayBuffer",{ascToJs:b,jsToAsc:function(t,e,r){const n=t.exports.__new(e.byteLength,t.getTypeId(r));return new Uint8Array(t.exports.memory.buffer,n,e.byteLength).set(new Uint8Array(e)),n}}],[/^~lib\/array\/Array<.+>$/,{ascToJs:function(t,e,r){const n=g(r),s=_(n);return t.exports.__getArray(e).map((e=>s.ascToJs(t,e,n)))},jsToAsc:function(t,e,r){const n=g(r),s=_(n),i=e.map((e=>s.jsToAsc(t,e,n)));return t.exports.__newArray(t.getTypeId(r),i)}}]]),w=new Set;function _(t){for(const[e,r]of A)if("string"!=typeof e){if(e.test(t))return r}else if(e===t)return r;return w.has(t)||(console.warn(`No converter for ${JSON.stringify(t)}, using pass-through`),w.add(t)),{ascToJs:d,jsToAsc:d}}function T(t){var e;return null===(e=_(t))||void 0===e?void 0:e.ascToJs}function j(t){var e;return null===(e=_(t))||void 0===e?void 0:e.jsToAsc}function O(t,e,r){const n=r.parameters.map(T),s=j(r.returnType);return function(...i){if(i.length!=n.length)throw Error(`Expected ${n.length} arguments, got ${i.length}`);const o=i.map(((e,s)=>n[s](t,e,r.parameters[s]))),a=e(...o);return s(t,a,r.returnType)}}function U(t,e,r){const n=r.parameters.map(j),s=T(r.returnType);return(...i)=>{if(i.length!=n.length)throw Error(`Expected ${n.length} arguments, got ${i.length}`);const o=i.map(((e,s)=>n[s](t,e,r.parameters[s]))),a=e(...o);return s(t,a,r.returnType)}}function x(t,{depth:e=Number.POSITIVE_INFINITY}={}){return e<=0||!t||"object"!=typeof t?t:Object.fromEntries(Object.entries(t).map((([t,r])=>[t,x(r,{depth:e-1})])))}function E(t){const e=WebAssembly.Module.customSections(t,"as-bind_bindings"),r=new TextDecoder("utf8").decode(new Uint8Array(e[0]));try{return JSON.parse(r)}catch(t){throw Error(`Couldn’t decode type descriptor: ${t.message}`)}}class S{constructor(){this.unboundExports={},this.exports={},this.importObject={}}getTypeId(t){if(t in this.typeDescriptor.typeIds)return this.typeDescriptor.typeIds[t].id;throw Error(`Unknown type ${JSON.stringify(t)}`)}getTypeSize(t){if(t in this.typeDescriptor.typeIds)return this.typeDescriptor.typeIds[t].byteSize;throw Error(`Unknown type ${JSON.stringify(t)}`)}_validate(){if(!WebAssembly.Module.exports(this.module).find((t=>"__new"===t.name)))throw Error("The AssemblyScript wasm module was not built with --exportRuntime, which is required.");if(1!==WebAssembly.Module.customSections(this.module,"as-bind_bindings").length)throw new Error("The AssemblyScript wasm module was not built with the as-bind transform.")}async _instantiate(t,e){this.module=await async function(t){if(t=await Promise.resolve(t),"undefined"!=typeof Response&&t instanceof Response){if(WebAssembly.compileStreaming)return WebAssembly.compileStreaming(t);t=await t.arrayBuffer()}return WebAssembly.compile(t)}(t),this._validate(),this.typeDescriptor=E(this.module),this._instantiateBindImportFunctions(e),this.loadedModule=await async function(t,e){return p.instantiate(t,e)}(this.module,this.importObject),this._instantiateBindUnboundExports()}_instantiateSync(t,e){this.module=new WebAssembly.Module(t),this._validate(),this.typeDescriptor=E(this.module),this._instantiateBindImportFunctions(e),this.loadedModule=function(t,e){return p.instantiateSync(t,e)}(this.module,this.importObject),this._instantiateBindUnboundExports()}_instantiateBindImportFunctions(t){this.importObject=x(t,{depth:2});for(const[e,r]of Object.entries(this.typeDescriptor.importedFunctions))for(const[n,s]of Object.entries(r))this.importObject[e][`__asbind_unbound_${n}`]=t[e][n],this.importObject[e][n]=O(this,t[e][n],s)}_instantiateBindUnboundExports(){const t=this.loadedModule.exports;this.exports=x(t,{depth:1});for(const[e,r]of Object.entries(this.typeDescriptor.exportedFunctions))this.exports[e]=U(this,t[e],r)}}async function I(t,e){let r=new S;return await r._instantiate(t,e),r}function $(t,e){let r=new S;return r._instantiateSync(t,e),r};
+const instantiate = I;
+
+let solveFn;
+async function load() {
+ const file = fetch("../solver/main.wasm");
+ const instance = await instantiate(file);
+ solveFn = instance.exports.solve;
+}
+load();
+
self.addEventListener('message', (event) => {
const { polycubes, dims } = event.data;
- const solver = new SomaSolver(event.data.dims);
- solver.solve(polycubes.map((cubeRep, i) => new VoxelSpace(i, [dims, dims, dims], cubeRep, true)));
- self.postMessage(solver.getSolutions());
+ const solutions = solveFn(polycubes, dims);
+ self.postMessage(solutions.map(soln => soln.toString()));
});
+
+class SomaSolver {
+ constructor(dimension) {
+ this.solutions = [];
+ this.iterations = 0;
+ if (dimension % 1 !== 0 || dimension < 0) {
+ throw new Error("The argument 'dimension' must be a positive whole number");
+ }
+ this.dim = dimension;
+ this.solutionCube = new VoxelSpace(0, [dimension, dimension, dimension], Array(dimension ** 3).fill(0));
+ }
+ async solve(polycubes) {
+ if (polycubes.length === 0) {
+ throw new Error("You must pass at least one polycube to solve the puzzle.");
+ }
+ let cumulativeSize = polycubes.reduce((prev, curr) => prev + curr.size(), 0);
+ if (cumulativeSize !== this.dim ** 3) {
+ throw new Error(`The polycubes passed do not add up to exactly enough units to form a cube of dimension ${this.dim}! Got: ${cumulativeSize}, need: ${this.dim ** 3}`);
+ }
+ this.solutions = [];
+ const combosWithRots = polycubes.slice(1).map(polycube => polycube.getUniqueRotations().map((rot) => rot.getAllPositionsInCube(this.dim)).flat());
+ const combos = [polycubes[0].getAllPositionsInCube(this.dim), ...combosWithRots];
+ console.log(combos.flat().length);
+ this.backtrackSolve(this.solutionCube, combos, new SomaSolution(this.dim));
+ this.solutions = SomaSolution.filterUnique(this.solutions);
+ }
+ getSolutions() {
+ return this.solutions.slice();
+ }
+ backtrackSolve(workingSolution, polycubes, currentSoln) {
+ const nextCubeGroup = polycubes[0];
+ for (let i = 0; i < nextCubeGroup.length; i++) {
+ const fusionAttempt = workingSolution.plus(nextCubeGroup[i]);
+ if (fusionAttempt) {
+ const nextSoln = currentSoln.clone();
+ nextSoln.addSpace(nextCubeGroup[i]);
+ if (polycubes.length === 1) {
+ this.solutions.push(nextSoln);
+ currentSoln = new SomaSolution(this.dim);
+ return;
+ }
+ else {
+ this.backtrackSolve(fusionAttempt, polycubes.slice(1), nextSoln);
+ }
+ }
+ }
+ }
+}
+
+class VoxelSpace {
+ constructor(id, dims, space, cullEmpty) {
+ if (!space) {
+ space = 0n;
+ }
+ else if (Array.isArray(space)) {
+ if (space.length !== dims[0] * dims[1] * dims[2]) {
+ throw new Error("Vals don't fit in given dimensions.");
+ }
+ space = VoxelSpace.boolArrayToBigInt(space);
+ }
+ this.id = id;
+ this.length = dims[0] * dims[1] * dims[2];
+ this.dims = dims;
+ this.space = space;
+ if (cullEmpty) {
+ this.cullEmptySpace();
+ }
+ }
+ static boolArrayToBigInt(boolArray) {
+ let result = 0n;
+ for (let i = 0; i < boolArray.length; i++) {
+ if (boolArray[i]) {
+ result |= BigInt(1 << i);
+ }
+ }
+ return result;
+ }
+ binaryRep() {
+ return this.space.toString(2);
+ }
+ getExtrema() {
+ const extrema = {
+ xMax: -Infinity,
+ xMin: Infinity,
+ yMax: -Infinity,
+ yMin: Infinity,
+ zMax: -Infinity,
+ zMin: Infinity,
+ };
+ this.forEachCell((val, x, y, z) => {
+ if (val) {
+ extrema.xMax = Math.max(extrema.xMax, x);
+ extrema.xMin = Math.min(extrema.xMin, x);
+ extrema.yMax = Math.max(extrema.yMax, y);
+ extrema.yMin = Math.min(extrema.yMin, y);
+ extrema.zMax = Math.max(extrema.zMax, z);
+ extrema.zMin = Math.min(extrema.zMin, z);
+ }
+ });
+ return extrema;
+ }
+ cullEmptySpace() {
+ const extrema = this.getExtrema();
+ let index = 0n;
+ let newSpace = 0n;
+ for (let x = extrema.xMin; x <= extrema.xMax; x++) {
+ for (let y = extrema.yMin; y <= extrema.yMax; y++) {
+ for (let z = extrema.zMin; z <= extrema.zMax; z++) {
+ if (this.at(x, y, z)) {
+ newSpace |= 1n << index;
+ }
+ index++;
+ }
+ }
+ }
+ this.dims[0] = extrema.xMax - extrema.xMin + 1;
+ this.dims[1] = extrema.yMax - extrema.yMin + 1;
+ this.dims[2] = extrema.zMax - extrema.zMin + 1;
+ this.space = newSpace;
+ }
+ forEachCell(cb) {
+ loopStart: for (let x = 0; x < this.dims[0]; x++) {
+ for (let y = 0; y < this.dims[1]; y++) {
+ for (let z = 0; z < this.dims[2]; z++) {
+ if (cb(this.at(x, y, z), x, y, z) === 0) {
+ break loopStart;
+ }
+ }
+ }
+ }
+ }
+ getId() {
+ return this.id;
+ }
+ print() {
+ let accum = "";
+ console.log("---");
+ for (let i = 0; i < this.dims[0]; i++) {
+ for (let j = 0; j < this.dims[1]; j++) {
+ for (let k = 0; k < this.dims[2]; k++) {
+ accum += this.at(i, j, k) ? '#' : 'O';
+ }
+ console.log(accum);
+ accum = "";
+ }
+ if (i !== this.dims[0] - 1) {
+ console.log("-");
+ }
+ }
+ console.log("---");
+ }
+ getUniqueRotations() {
+ const rotations = [];
+ const refSpace = this.clone();
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getAxisSpins('x'));
+ refSpace.rot90('y');
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getAxisSpins('x'));
+ refSpace.rot90('y');
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getAxisSpins('x'));
+ refSpace.rot90('y');
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getAxisSpins('x'));
+ refSpace.rot90('z');
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getAxisSpins('x'));
+ refSpace.rot90('z');
+ refSpace.rot90('z');
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getAxisSpins('x'));
+ return rotations;
+ }
+ getAllRotations() {
+ const rotations = [];
+ const refSpace = this.clone();
+ rotations.push(...refSpace.getAxisSpins('x'));
+ refSpace.rot90('y');
+ rotations.push(...refSpace.getAxisSpins('x'));
+ refSpace.rot90('y');
+ rotations.push(...refSpace.getAxisSpins('x'));
+ refSpace.rot90('y');
+ rotations.push(...refSpace.getAxisSpins('x'));
+ refSpace.rot90('z');
+ rotations.push(...refSpace.getAxisSpins('x'));
+ refSpace.rot90('z');
+ refSpace.rot90('z');
+ rotations.push(...refSpace.getAxisSpins('x'));
+ return rotations;
+ }
+ static pushNewUniqueSpaces(existingSpaces, newSpaces) {
+ for (const newSpace of newSpaces) {
+ let matchFound = false;
+ for (const existingSpace of existingSpaces) {
+ if (newSpace.matches(existingSpace)) {
+ matchFound = true;
+ break;
+ }
+ }
+ if (!matchFound) {
+ existingSpaces.push(newSpace);
+ }
+ }
+ }
+ getAllPositionsInCube(cubeDim) {
+ if ((cubeDim > 0) && (cubeDim % 1 === 0)) {
+ const cubePositions = [];
+ for (let x = 0; x < cubeDim - this.dims[0] + 1; x++) {
+ for (let y = 0; y < cubeDim - this.dims[1] + 1; y++) {
+ for (let z = 0; z < cubeDim - this.dims[2] + 1; z++) {
+ const cubePos = new VoxelSpace(this.id, [cubeDim, cubeDim, cubeDim]);
+ this.forEachCell((val, rotX, rotY, rotZ) => {
+ cubePos.set(x + rotX, y + rotY, z + rotZ, val);
+ });
+ cubePositions.push(cubePos);
+ }
+ }
+ }
+ return cubePositions;
+ }
+ else {
+ throw new Error("cubeDim must be a positive integer.");
+ }
+ }
+ matches(space) {
+ const otherDims = space.getDims();
+ for (let i = 0; i < this.dims.length; i++) {
+ if (otherDims[i] !== this.dims[i]) {
+ return false;
+ }
+ }
+ return this.space === space.getRaw();
+ }
+ clone() {
+ return new VoxelSpace(this.id, this.getDims(), this.getRaw());
+ }
+ getAxisSpins(axis) {
+ const rotations = [this.clone()];
+ for (let i = 0; i < 3; i++) {
+ rotations.push(rotations[i].rotated90(axis));
+ }
+ return rotations;
+ }
+ getDims() {
+ return this.dims.slice();
+ }
+ getRaw() {
+ return this.space;
+ }
+ // [1, 0, 0] [x] [ x]
+ // [0, 0, -1] * [y] = [-z]
+ // [0, 1, 0] [z] [ y]
+ newIndexRotX(x, y, z) {
+ return this.dims[2] * this.dims[1] * x + this.dims[1] * (this.dims[2] - 1 - z) + y;
+ }
+ // [ 0, 0, 1] [x] [ z]
+ // [ 0, 1, 0] * [y] = [ y]
+ // [-1, 0, 0] [z] [-x]
+ newIndexRotY(x, y, z) {
+ return this.dims[1] * this.dims[0] * z + this.dims[0] * y + (this.dims[0] - 1 - x);
+ }
+ // [0, -1, 0] [x] [-y]
+ // [1, 0, 0] * [y] = [ x]
+ // [0, 0, 1] [z] [ z]
+ newIndexRotZ(x, y, z) {
+ return this.dims[0] * this.dims[2] * (this.dims[1] - 1 - y) + this.dims[2] * x + z;
+ }
+ at(x, y, z) {
+ const mask = 1n << BigInt(this.dims[1] * this.dims[2] * x + this.dims[2] * y + z);
+ return (this.space & mask) !== 0n;
+ }
+ toggle(x, y, z) {
+ const mask = BigInt(1 << this.dims[1] * this.dims[2] * x + this.dims[2] * y + z);
+ this.space ^= mask;
+ }
+ set(x, y, z, val) {
+ const mask = BigInt(1 << this.dims[1] * this.dims[2] * x + this.dims[2] * y + z);
+ if (val) {
+ this.space |= mask;
+ }
+ else {
+ this.space &= ~mask;
+ }
+ }
+ rotated90(dim) {
+ let newSpace = 0n;
+ let newDims;
+ let rotIndex;
+ if (dim === 'x') {
+ newDims = [this.dims[0], this.dims[2], this.dims[1]];
+ rotIndex = this.newIndexRotX.bind(this);
+ }
+ else if (dim === 'y') {
+ newDims = [this.dims[2], this.dims[1], this.dims[0]];
+ rotIndex = this.newIndexRotY.bind(this);
+ }
+ else {
+ newDims = [this.dims[1], this.dims[0], this.dims[2]];
+ rotIndex = this.newIndexRotZ.bind(this);
+ }
+ this.forEachCell((val, i, j, k) => {
+ if (val) {
+ newSpace |= BigInt(1 << rotIndex(i, j, k));
+ }
+ });
+ return new VoxelSpace(this.id, newDims, newSpace);
+ }
+ rot90(dim) {
+ const rot = this.rotated90(dim);
+ this.space = rot.getRaw();
+ this.dims = rot.getDims();
+ }
+ plus(space) {
+ const otherSpace = space.getRaw();
+ if ((this.space | otherSpace) === (this.space ^ otherSpace)) {
+ return new VoxelSpace(this.id, this.dims, otherSpace | this.space);
+ }
+ return null;
+ }
+ size() {
+ let size = 0;
+ this.forEachCell((val) => {
+ if (val) {
+ size++;
+ }
+ });
+ return size;
+ }
+}
diff --git a/public/solver/main.wasm b/public/solver/main.wasm
new file mode 100644
index 0000000..e6fe6c3
Binary files /dev/null and b/public/solver/main.wasm differ
diff --git a/src/OBJLoader.js b/src/OBJLoader.js
deleted file mode 100644
index 768a1ff..0000000
--- a/src/OBJLoader.js
+++ /dev/null
@@ -1,911 +0,0 @@
-import {
- BufferGeometry,
- FileLoader,
- Float32BufferAttribute,
- Group,
- LineBasicMaterial,
- LineSegments,
- Loader,
- Material,
- Mesh,
- MeshPhongMaterial,
- Points,
- PointsMaterial,
- Vector3
-} from 'three';
-
-// o object_name | g group_name
-const _object_pattern = /^[og]\s*(.+)?/;
-// mtllib file_reference
-const _material_library_pattern = /^mtllib /;
-// usemtl material_name
-const _material_use_pattern = /^usemtl /;
-// usemap map_name
-const _map_use_pattern = /^usemap /;
-
-const _vA = new Vector3();
-const _vB = new Vector3();
-const _vC = new Vector3();
-
-const _ab = new Vector3();
-const _cb = new Vector3();
-
-function ParserState() {
-
- const state = {
- objects: [],
- object: {},
-
- vertices: [],
- normals: [],
- colors: [],
- uvs: [],
-
- materials: {},
- materialLibraries: [],
-
- startObject: function ( name, fromDeclaration ) {
-
- // If the current object (initial from reset) is not from a g/o declaration in the parsed
- // file. We need to use it for the first parsed g/o to keep things in sync.
- if ( this.object && this.object.fromDeclaration === false ) {
-
- this.object.name = name;
- this.object.fromDeclaration = ( fromDeclaration !== false );
- return;
-
- }
-
- const previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
-
- if ( this.object && typeof this.object._finalize === 'function' ) {
-
- this.object._finalize( true );
-
- }
-
- this.object = {
- name: name || '',
- fromDeclaration: ( fromDeclaration !== false ),
-
- geometry: {
- vertices: [],
- normals: [],
- colors: [],
- uvs: [],
- hasUVIndices: false
- },
- materials: [],
- smooth: true,
-
- startMaterial: function ( name, libraries ) {
-
- const previous = this._finalize( false );
-
- // New usemtl declaration overwrites an inherited material, except if faces were declared
- // after the material, then it must be preserved for proper MultiMaterial continuation.
- if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
-
- this.materials.splice( previous.index, 1 );
-
- }
-
- const material = {
- index: this.materials.length,
- name: name || '',
- mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),
- smooth: ( previous !== undefined ? previous.smooth : this.smooth ),
- groupStart: ( previous !== undefined ? previous.groupEnd : 0 ),
- groupEnd: - 1,
- groupCount: - 1,
- inherited: false,
-
- clone: function ( index ) {
-
- const cloned = {
- index: ( typeof index === 'number' ? index : this.index ),
- name: this.name,
- mtllib: this.mtllib,
- smooth: this.smooth,
- groupStart: 0,
- groupEnd: - 1,
- groupCount: - 1,
- inherited: false
- };
- cloned.clone = this.clone.bind( cloned );
- return cloned;
-
- }
- };
-
- this.materials.push( material );
-
- return material;
-
- },
-
- currentMaterial: function () {
-
- if ( this.materials.length > 0 ) {
-
- return this.materials[ this.materials.length - 1 ];
-
- }
-
- return undefined;
-
- },
-
- _finalize: function ( end ) {
-
- const lastMultiMaterial = this.currentMaterial();
- if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {
-
- lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
- lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
- lastMultiMaterial.inherited = false;
-
- }
-
- // Ignore objects tail materials if no face declarations followed them before a new o/g started.
- if ( end && this.materials.length > 1 ) {
-
- for ( let mi = this.materials.length - 1; mi >= 0; mi -- ) {
-
- if ( this.materials[ mi ].groupCount <= 0 ) {
-
- this.materials.splice( mi, 1 );
-
- }
-
- }
-
- }
-
- // Guarantee at least one empty material, this makes the creation later more straight forward.
- if ( end && this.materials.length === 0 ) {
-
- this.materials.push( {
- name: '',
- smooth: this.smooth
- } );
-
- }
-
- return lastMultiMaterial;
-
- }
- };
-
- // Inherit previous objects material.
- // Spec tells us that a declared material must be set to all objects until a new material is declared.
- // If a usemtl declaration is encountered while this new object is being parsed, it will
- // overwrite the inherited material. Exception being that there was already face declarations
- // to the inherited material, then it will be preserved for proper MultiMaterial continuation.
-
- if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) {
-
- const declared = previousMaterial.clone( 0 );
- declared.inherited = true;
- this.object.materials.push( declared );
-
- }
-
- this.objects.push( this.object );
-
- },
-
- finalize: function () {
-
- if ( this.object && typeof this.object._finalize === 'function' ) {
-
- this.object._finalize( true );
-
- }
-
- },
-
- parseVertexIndex: function ( value, len ) {
-
- const index = parseInt( value, 10 );
- return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
-
- },
-
- parseNormalIndex: function ( value, len ) {
-
- const index = parseInt( value, 10 );
- return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
-
- },
-
- parseUVIndex: function ( value, len ) {
-
- const index = parseInt( value, 10 );
- return ( index >= 0 ? index - 1 : index + len / 2 ) * 2;
-
- },
-
- addVertex: function ( a, b, c ) {
-
- const src = this.vertices;
- const dst = this.object.geometry.vertices;
-
- dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
- dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
- dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
-
- },
-
- addVertexPoint: function ( a ) {
-
- const src = this.vertices;
- const dst = this.object.geometry.vertices;
-
- dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
-
- },
-
- addVertexLine: function ( a ) {
-
- const src = this.vertices;
- const dst = this.object.geometry.vertices;
-
- dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
-
- },
-
- addNormal: function ( a, b, c ) {
-
- const src = this.normals;
- const dst = this.object.geometry.normals;
-
- dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
- dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
- dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
-
- },
-
- addFaceNormal: function ( a, b, c ) {
-
- const src = this.vertices;
- const dst = this.object.geometry.normals;
-
- _vA.fromArray( src, a );
- _vB.fromArray( src, b );
- _vC.fromArray( src, c );
-
- _cb.subVectors( _vC, _vB );
- _ab.subVectors( _vA, _vB );
- _cb.cross( _ab );
-
- _cb.normalize();
-
- dst.push( _cb.x, _cb.y, _cb.z );
- dst.push( _cb.x, _cb.y, _cb.z );
- dst.push( _cb.x, _cb.y, _cb.z );
-
- },
-
- addColor: function ( a, b, c ) {
-
- const src = this.colors;
- const dst = this.object.geometry.colors;
-
- if ( src[ a ] !== undefined ) dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
- if ( src[ b ] !== undefined ) dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
- if ( src[ c ] !== undefined ) dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
-
- },
-
- addUV: function ( a, b, c ) {
-
- const src = this.uvs;
- const dst = this.object.geometry.uvs;
-
- dst.push( src[ a + 0 ], src[ a + 1 ] );
- dst.push( src[ b + 0 ], src[ b + 1 ] );
- dst.push( src[ c + 0 ], src[ c + 1 ] );
-
- },
-
- addDefaultUV: function () {
-
- const dst = this.object.geometry.uvs;
-
- dst.push( 0, 0 );
- dst.push( 0, 0 );
- dst.push( 0, 0 );
-
- },
-
- addUVLine: function ( a ) {
-
- const src = this.uvs;
- const dst = this.object.geometry.uvs;
-
- dst.push( src[ a + 0 ], src[ a + 1 ] );
-
- },
-
- addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) {
-
- const vLen = this.vertices.length;
-
- let ia = this.parseVertexIndex( a, vLen );
- let ib = this.parseVertexIndex( b, vLen );
- let ic = this.parseVertexIndex( c, vLen );
-
- this.addVertex( ia, ib, ic );
- this.addColor( ia, ib, ic );
-
- // normals
-
- if ( na !== undefined && na !== '' ) {
-
- const nLen = this.normals.length;
-
- ia = this.parseNormalIndex( na, nLen );
- ib = this.parseNormalIndex( nb, nLen );
- ic = this.parseNormalIndex( nc, nLen );
-
- this.addNormal( ia, ib, ic );
-
- } else {
-
- this.addFaceNormal( ia, ib, ic );
-
- }
-
- // uvs
-
- if ( ua !== undefined && ua !== '' ) {
-
- const uvLen = this.uvs.length;
-
- ia = this.parseUVIndex( ua, uvLen );
- ib = this.parseUVIndex( ub, uvLen );
- ic = this.parseUVIndex( uc, uvLen );
-
- this.addUV( ia, ib, ic );
-
- this.object.geometry.hasUVIndices = true;
-
- } else {
-
- // add placeholder values (for inconsistent face definitions)
-
- this.addDefaultUV();
-
- }
-
- },
-
- addPointGeometry: function ( vertices ) {
-
- this.object.geometry.type = 'Points';
-
- const vLen = this.vertices.length;
-
- for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {
-
- const index = this.parseVertexIndex( vertices[ vi ], vLen );
-
- this.addVertexPoint( index );
- this.addColor( index );
-
- }
-
- },
-
- addLineGeometry: function ( vertices, uvs ) {
-
- this.object.geometry.type = 'Line';
-
- const vLen = this.vertices.length;
- const uvLen = this.uvs.length;
-
- for ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {
-
- this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );
-
- }
-
- for ( let uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {
-
- this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );
-
- }
-
- }
-
- };
-
- state.startObject( '', false );
-
- return state;
-
-}
-
-//
-
-class OBJLoader extends Loader {
-
- constructor( manager ) {
-
- super( manager );
-
- this.materials = null;
-
- }
-
- load( url, onLoad, onProgress, onError ) {
-
- const scope = this;
-
- const loader = new FileLoader( this.manager );
- loader.setPath( this.path );
- loader.setRequestHeader( this.requestHeader );
- loader.setWithCredentials( this.withCredentials );
- loader.load( url, function ( text ) {
-
- try {
-
- onLoad( scope.parse( text ) );
-
- } catch ( e ) {
-
- if ( onError ) {
-
- onError( e );
-
- } else {
-
- console.error( e );
-
- }
-
- scope.manager.itemError( url );
-
- }
-
- }, onProgress, onError );
-
- }
-
- setMaterials( materials ) {
-
- this.materials = materials;
-
- return this;
-
- }
-
- parse( text ) {
-
- const state = new ParserState();
-
- if ( text.indexOf( '\r\n' ) !== - 1 ) {
-
- // This is faster than String.split with regex that splits on both
- text = text.replace( /\r\n/g, '\n' );
-
- }
-
- if ( text.indexOf( '\\\n' ) !== - 1 ) {
-
- // join lines separated by a line continuation character (\)
- text = text.replace( /\\\n/g, '' );
-
- }
-
- const lines = text.split( '\n' );
- let line = '', lineFirstChar = '';
- let lineLength = 0;
- let result = [];
-
- // Faster to just trim left side of the line. Use if available.
- const trimLeft = ( typeof ''.trimLeft === 'function' );
-
- for ( let i = 0, l = lines.length; i < l; i ++ ) {
-
- line = lines[ i ];
-
- line = trimLeft ? line.trimLeft() : line.trim();
-
- lineLength = line.length;
-
- if ( lineLength === 0 ) continue;
-
- lineFirstChar = line.charAt( 0 );
-
- // @todo invoke passed in handler if any
- if ( lineFirstChar === '#' ) continue;
-
- if ( lineFirstChar === 'v' ) {
-
- const data = line.split( /\s+/ );
-
- switch ( data[ 0 ] ) {
-
- case 'v':
- state.vertices.push(
- parseFloat( data[ 1 ] ),
- parseFloat( data[ 2 ] ),
- parseFloat( data[ 3 ] )
- );
- if ( data.length >= 7 ) {
-
- state.colors.push(
- parseFloat( data[ 4 ] ),
- parseFloat( data[ 5 ] ),
- parseFloat( data[ 6 ] )
-
- );
-
- } else {
-
- // if no colors are defined, add placeholders so color and vertex indices match
-
- state.colors.push( undefined, undefined, undefined );
-
- }
-
- break;
- case 'vn':
- state.normals.push(
- parseFloat( data[ 1 ] ),
- parseFloat( data[ 2 ] ),
- parseFloat( data[ 3 ] )
- );
- break;
- case 'vt':
- state.uvs.push(
- parseFloat( data[ 1 ] ),
- parseFloat( data[ 2 ] )
- );
- break;
-
- }
-
- } else if ( lineFirstChar === 'f' ) {
-
- const lineData = line.substr( 1 ).trim();
- const vertexData = lineData.split( /\s+/ );
- const faceVertices = [];
-
- // Parse the face vertex data into an easy to work with format
-
- for ( let j = 0, jl = vertexData.length; j < jl; j ++ ) {
-
- const vertex = vertexData[ j ];
-
- if ( vertex.length > 0 ) {
-
- const vertexParts = vertex.split( '/' );
- faceVertices.push( vertexParts );
-
- }
-
- }
-
- // Draw an edge between the first vertex and all subsequent vertices to form an n-gon
-
- const v1 = faceVertices[ 0 ];
-
- for ( let j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {
-
- const v2 = faceVertices[ j ];
- const v3 = faceVertices[ j + 1 ];
-
- state.addFace(
- v1[ 0 ], v2[ 0 ], v3[ 0 ],
- v1[ 1 ], v2[ 1 ], v3[ 1 ],
- v1[ 2 ], v2[ 2 ], v3[ 2 ]
- );
-
- }
-
- } else if ( lineFirstChar === 'l' ) {
-
- const lineParts = line.substring( 1 ).trim().split( ' ' );
- let lineVertices = [];
- const lineUVs = [];
-
- if ( line.indexOf( '/' ) === - 1 ) {
-
- lineVertices = lineParts;
-
- } else {
-
- for ( let li = 0, llen = lineParts.length; li < llen; li ++ ) {
-
- const parts = lineParts[ li ].split( '/' );
-
- if ( parts[ 0 ] !== '' ) lineVertices.push( parts[ 0 ] );
- if ( parts[ 1 ] !== '' ) lineUVs.push( parts[ 1 ] );
-
- }
-
- }
-
- state.addLineGeometry( lineVertices, lineUVs );
-
- } else if ( lineFirstChar === 'p' ) {
-
- const lineData = line.substr( 1 ).trim();
- const pointData = lineData.split( ' ' );
-
- state.addPointGeometry( pointData );
-
- } else if ( ( result = _object_pattern.exec( line ) ) !== null ) {
-
- // o object_name
- // or
- // g group_name
-
- // WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
- // let name = result[ 0 ].substr( 1 ).trim();
- const name = ( ' ' + result[ 0 ].substr( 1 ).trim() ).substr( 1 );
-
- state.startObject( name );
-
- } else if ( _material_use_pattern.test( line ) ) {
-
- // material
-
- state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );
-
- } else if ( _material_library_pattern.test( line ) ) {
-
- // mtl file
-
- state.materialLibraries.push( line.substring( 7 ).trim() );
-
- } else if ( _map_use_pattern.test( line ) ) {
-
- // the line is parsed but ignored since the loader assumes textures are defined MTL files
- // (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method)
-
- console.warn( 'THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.' );
-
- } else if ( lineFirstChar === 's' ) {
-
- result = line.split( ' ' );
-
- // smooth shading
-
- // @todo Handle files that have varying smooth values for a set of faces inside one geometry,
- // but does not define a usemtl for each face set.
- // This should be detected and a dummy material created (later MultiMaterial and geometry groups).
- // This requires some care to not create extra material on each smooth value for "normal" obj files.
- // where explicit usemtl defines geometry groups.
- // Example asset: examples/models/obj/cerberus/Cerberus.obj
-
- /*
- * http://paulbourke.net/dataformats/obj/
- * or
- * http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf
- *
- * From chapter "Grouping" Syntax explanation "s group_number":
- * "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.
- * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form
- * surfaces, smoothing groups are either turned on or off; there is no difference between values greater
- * than 0."
- */
- if ( result.length > 1 ) {
-
- const value = result[ 1 ].trim().toLowerCase();
- state.object.smooth = ( value !== '0' && value !== 'off' );
-
- } else {
-
- // ZBrush can produce "s" lines #11707
- state.object.smooth = true;
-
- }
-
- const material = state.object.currentMaterial();
- if ( material ) material.smooth = state.object.smooth;
-
- } else {
-
- // Handle null terminated files without exception
- if ( line === '\0' ) continue;
-
- console.warn( 'THREE.OBJLoader: Unexpected line: "' + line + '"' );
-
- }
-
- }
-
- state.finalize();
-
- const container = new Group();
- container.materialLibraries = [].concat( state.materialLibraries );
-
- const hasPrimitives = ! ( state.objects.length === 1 && state.objects[ 0 ].geometry.vertices.length === 0 );
-
- if ( hasPrimitives === true ) {
-
- for ( let i = 0, l = state.objects.length; i < l; i ++ ) {
-
- const object = state.objects[ i ];
- const geometry = object.geometry;
- const materials = object.materials;
- const isLine = ( geometry.type === 'Line' );
- const isPoints = ( geometry.type === 'Points' );
- let hasVertexColors = false;
-
- // Skip o/g line declarations that did not follow with any faces
- if ( geometry.vertices.length === 0 ) continue;
-
- const buffergeometry = new BufferGeometry();
-
- buffergeometry.setAttribute( 'position', new Float32BufferAttribute( geometry.vertices, 3 ) );
-
- if ( geometry.normals.length > 0 ) {
-
- buffergeometry.setAttribute( 'normal', new Float32BufferAttribute( geometry.normals, 3 ) );
-
- }
-
- if ( geometry.colors.length > 0 ) {
-
- hasVertexColors = true;
- buffergeometry.setAttribute( 'color', new Float32BufferAttribute( geometry.colors, 3 ) );
-
- }
-
- if ( geometry.hasUVIndices === true ) {
-
- buffergeometry.setAttribute( 'uv', new Float32BufferAttribute( geometry.uvs, 2 ) );
-
- }
-
- // Create materials
-
- const createdMaterials = [];
-
- for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
-
- const sourceMaterial = materials[ mi ];
- const materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors;
- let material = state.materials[ materialHash ];
-
- if ( this.materials !== null ) {
-
- material = this.materials.create( sourceMaterial.name );
-
- // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
- if ( isLine && material && ! ( material instanceof LineBasicMaterial ) ) {
-
- const materialLine = new LineBasicMaterial();
- Material.prototype.copy.call( materialLine, material );
- materialLine.color.copy( material.color );
- material = materialLine;
-
- } else if ( isPoints && material && ! ( material instanceof PointsMaterial ) ) {
-
- const materialPoints = new PointsMaterial( { size: 10, sizeAttenuation: false } );
- Material.prototype.copy.call( materialPoints, material );
- materialPoints.color.copy( material.color );
- materialPoints.map = material.map;
- material = materialPoints;
-
- }
-
- }
-
- if ( material === undefined ) {
-
- if ( isLine ) {
-
- material = new LineBasicMaterial();
-
- } else if ( isPoints ) {
-
- material = new PointsMaterial( { size: 1, sizeAttenuation: false } );
-
- } else {
-
- material = new MeshPhongMaterial();
-
- }
-
- material.name = sourceMaterial.name;
- material.flatShading = sourceMaterial.smooth ? false : true;
- material.vertexColors = hasVertexColors;
-
- state.materials[ materialHash ] = material;
-
- }
-
- createdMaterials.push( material );
-
- }
-
- // Create mesh
-
- let mesh;
-
- if ( createdMaterials.length > 1 ) {
-
- for ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
-
- const sourceMaterial = materials[ mi ];
- buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );
-
- }
-
- if ( isLine ) {
-
- mesh = new LineSegments( buffergeometry, createdMaterials );
-
- } else if ( isPoints ) {
-
- mesh = new Points( buffergeometry, createdMaterials );
-
- } else {
-
- mesh = new Mesh( buffergeometry, createdMaterials );
-
- }
-
- } else {
-
- if ( isLine ) {
-
- mesh = new LineSegments( buffergeometry, createdMaterials[ 0 ] );
-
- } else if ( isPoints ) {
-
- mesh = new Points( buffergeometry, createdMaterials[ 0 ] );
-
- } else {
-
- mesh = new Mesh( buffergeometry, createdMaterials[ 0 ] );
-
- }
-
- }
-
- mesh.name = object.name;
-
- container.add( mesh );
-
- }
-
- } else {
-
- // if there is only the default parser state object with no geometry data, interpret data as point cloud
-
- if ( state.vertices.length > 0 ) {
-
- const material = new PointsMaterial( { size: 1, sizeAttenuation: false } );
-
- const buffergeometry = new BufferGeometry();
-
- buffergeometry.setAttribute( 'position', new Float32BufferAttribute( state.vertices, 3 ) );
-
- if ( state.colors.length > 0 && state.colors[ 0 ] !== undefined ) {
-
- buffergeometry.setAttribute( 'color', new Float32BufferAttribute( state.colors, 3 ) );
- material.vertexColors = true;
-
- }
-
- const points = new Points( buffergeometry, material );
- container.add( points );
-
- }
-
- }
-
- return container;
-
- }
-
-}
-
-export { OBJLoader };
diff --git a/src/PolycubeScene.ts b/src/PolycubeScene.ts
deleted file mode 100644
index dc279ea..0000000
--- a/src/PolycubeScene.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import * as THREE from 'three';
-import { OBJLoader } from './OBJLoader.js';
-import VoxelSpace from './solver/VoxelSpace';
-import type SomaSolution from "./solver/SomaSolution";
-import RotationControl from "./RotationControl";
-
-export default class PolycubeScene {
- private renderer: THREE.WebGLRenderer;
- private camera: THREE.Camera;
- private mainScene: THREE.Scene;
- private polycubeMeshes: THREE.Mesh[] = [];
- private controls: RotationControl;
- private light: THREE.Light;
- private lastDims: number = 0;
- private lastColor: string = "#FF0000";
- private lastPolycube: bigint = 0n;
- private cubeMaterial: THREE.MeshPhongMaterial;
- private materials: Record = {};
- private cubeGeometry: THREE.BufferGeometry;
- private cubeScene: THREE.Scene;
-
- constructor(el: HTMLCanvasElement, onReady: () => any, onError: (err: Error) => any) {
- this.init(el).then(onReady).catch(onError);
- }
-
- private async init(el: HTMLCanvasElement) {
- this.renderer = new THREE.WebGLRenderer({canvas: el});
- this.setupCamera(el.clientWidth / el.clientHeight);
- this.setupLight();
- try {
- await this.createCubeGeometry();
- } catch (err) {
- throw new Error(err);
- }
- this.createCubeMaterial("red");
- this.mainScene = new THREE.Scene();
- this.cubeScene = new THREE.Scene();
- this.mainScene.add(this.cubeScene, this.camera);
- this.camera.add(this.light);
- this.cubeScene.rotateX(Math.PI/4);
- this.cubeScene.rotateY(Math.PI/4);
- this.controls = new RotationControl(this.cubeScene, this.camera, el);
- requestAnimationFrame((timestamp) => this.render(timestamp));
- }
-
- private setupCamera(aspect: number) {
- const fov = 60;
- const near = 0.1;
- const far = 15;
- this.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
- this.camera.position.z = 6;
- this.camera.lookAt(0, 0, 0);
- }
-
- private setPolycube(polycube: bigint, dims: number, color: string) {
- if (dims !== this.lastDims) {
- this.updateCubesFromDims(dims);
- }
-
- if (polycube !== this.lastPolycube) {
- let i = 0;
- const voxelSpace = new VoxelSpace(0, [dims, dims, dims], polycube, true);
- const newDims = voxelSpace.getDims();
- this.polycubeMeshes.forEach(mesh => {
- mesh.position.set(1000, 1000, 1000);
- mesh.material = this.cubeMaterial;
- });
- voxelSpace.forEachCell((val: boolean, x: number, y: number, z: number) => {
- if (val) {
- this.polycubeMeshes[i].position.set(
- -((newDims[2] - 1)/2) + z,
- ((newDims[0] - 1)/2) - x,
- -((newDims[1] - 1)/2) + y,
- );
- }
- i++;
- });
- this.lastPolycube = polycube;
- }
-
- if (color !== this.lastColor) {
- this.cubeMaterial.color.set(color);
- this.lastColor = color;
- }
- }
-
- private updateCubesFromDims(newDims: number) {
- const requiredCubes = newDims**3;
- if (this.polycubeMeshes.length < requiredCubes) {
- for (let i = this.polycubeMeshes.length; i < requiredCubes; i++) {
- const newCube = new THREE.Mesh(this.cubeGeometry, this.cubeMaterial);
- this.cubeScene.add(newCube);
- this.polycubeMeshes.push(newCube);
- }
- }
- if (newDims < this.lastDims || this.lastDims === 0) {
- this.polycubeMeshes.forEach(mesh => mesh.position.set(1000, 1000, 1000));
- }
- this.lastDims = newDims;
- }
-
- private setSolution(solution: SomaSolution, colorMap: Record) {
- const dims = solution.getDims();
- if (dims[0] !== this.lastDims) {
- this.updateCubesFromDims(dims[0]);
- }
-
- let i = 0;
- this.polycubeMeshes.forEach(mesh => mesh.position.set(1000, 1000, 1000));
- Object.keys(colorMap).forEach(key => {
- if (!this.materials[key]) {
- this.materials[key] = this.newCubeMaterial(colorMap[key]);
- }
- })
- solution.forEachCell((val: number, x: number, y: number, z: number) => {
- this.polycubeMeshes[i].position.set(
- -((dims[2] - 1)/2) + z,
- ((dims[0] - 1)/2) - x,
- -((dims[1] - 1)/2) + y,
- );
- this.polycubeMeshes[i].material = this.materials[val];
- i++;
- });
- }
-
- private setupLight() {
- const color = 0xFFFFFF;
- const intensity = 1;
- this.light = new THREE.DirectionalLight(color, intensity);
- this.light.position.set(-1, 2, 4);
- }
-
- private render(time: number) {
- this.renderer.render(this.mainScene, this.camera);
- requestAnimationFrame((time: number) => this.render(time));
- }
-
- private async createCubeGeometry(): Promise {
- const onLoaded = (obj: THREE.Mesh, resolve: () => any) => {
- this.cubeGeometry = (obj.children[0] as THREE.Mesh).geometry;
- this.cubeGeometry.computeVertexNormals();
- this.cubeGeometry.computeBoundingSphere();
- this.cubeGeometry.scale(1/this.cubeGeometry.boundingSphere.radius, 1/this.cubeGeometry.boundingSphere.radius, 1/this.cubeGeometry.boundingSphere.radius);
- resolve();
- };
- const load = (resolve: () => any, reject: (err: string) => any) => {
- const loader = new OBJLoader();
- loader.load(
- '../resources/bevel_cube.obj',
- obj => onLoaded(obj, resolve),
- () => {},
- (err) => reject(`Error loading OBJ file: ${err}`),
- );
- };
- return new Promise(load);
- }
-
- private newCubeMaterial(color: string) {
- return new THREE.MeshPhongMaterial({color});
- }
-
- private createCubeMaterial(color: string) {
- this.cubeMaterial = this.newCubeMaterial(color);
- }
-}
diff --git a/src/Sidebar.svelte b/src/Sidebar.svelte
deleted file mode 100644
index 4dca502..0000000
--- a/src/Sidebar.svelte
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
Somaesque
-
Settings
-
-
-
Cube Dimension: {$somaDimension}
-
-
-
+
-
-
-
-
Cubes: {numCubes}
-
-
-
+
-
-
-
- {solving ? 'Solving...' : 'Solve'}
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/SolutionInteractor.svelte b/src/SolutionInteractor.svelte
deleted file mode 100644
index 7f022ab..0000000
--- a/src/SolutionInteractor.svelte
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/SolutionList.svelte b/src/SolutionList.svelte
deleted file mode 100644
index 00f6994..0000000
--- a/src/SolutionList.svelte
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-Solutions: {$solutions.length}
-
- {#each $solutions as soln, i}
- selectSolution(i)}>
- Solution #{i + 1}
-
- {/each}
-
-
-
\ No newline at end of file
diff --git a/src/solver/SomaSolution.ts b/src/SomaSolution.ts
similarity index 95%
rename from src/solver/SomaSolution.ts
rename to src/SomaSolution.ts
index 71f38aa..a6f02dd 100644
--- a/src/solver/SomaSolution.ts
+++ b/src/SomaSolution.ts
@@ -18,7 +18,7 @@ export default class SomaSolution {
const uniqueSolns = [solutions[0]];
for (const solution of solutions) {
let foundMatch = false;
- for (const rotation of solution.getUniqueRotations()) {
+ for (const rotation of solution.getRotations()) {
let end = uniqueSolns.length;
for (let i = 0; i < end; i++) {
if (rotation.matches(uniqueSolns[i])) {
@@ -33,7 +33,7 @@ export default class SomaSolution {
return uniqueSolns;
}
- getUniqueRotations(): SomaSolution[] {
+ getRotations(): SomaSolution[] {
if (this.solutionSpaces.length === 0) {
return [];
}
@@ -110,4 +110,8 @@ export default class SomaSolution {
}
}
}
+
+ getPieces() {
+ return this.solutionSpaces.slice();
+ }
}
\ No newline at end of file
diff --git a/src/solver/SomaSolver.ts b/src/SomaSolver.ts
similarity index 100%
rename from src/solver/SomaSolver.ts
rename to src/SomaSolver.ts
diff --git a/src/solver/VoxelSpace.ts b/src/VoxelSpace.ts
similarity index 92%
rename from src/solver/VoxelSpace.ts
rename to src/VoxelSpace.ts
index 8f78c9e..9519d3d 100644
--- a/src/solver/VoxelSpace.ts
+++ b/src/VoxelSpace.ts
@@ -1,5 +1,14 @@
export type DimensionDef = [number, number, number];
+const enum NeighbourDirection {
+ POSX,
+ POSY,
+ POSZ,
+ NEGX,
+ NEGY,
+ NEGZ,
+}
+
export default class VoxelSpace {
private dims: DimensionDef;
private length: number;
@@ -299,4 +308,27 @@ export default class VoxelSpace {
});
return size;
}
+
+ getDirectNeighbourProfile(x: number, y: number, z: number): number {
+ let result = 0;
+ if (x < this.dims[0] - 1 && this.at(x + 1, y, z)) {
+ result += 1;
+ }
+ if (y < this.dims[1] - 1 && this.at(x, y + 1, z)) {
+ result += 2;
+ }
+ if (z < this.dims[2] - 1 && this.at(x, y, z + 1)) {
+ result += 4;
+ }
+ if (x > 0 && this.at(x - 1, y, z)) {
+ result += 8;
+ }
+ if (y > 0 && this.at(x, y - 1, z)) {
+ result += 16;
+ }
+ if (z > 0 && this.at(x, y, z - 1)) {
+ result += 32;
+ }
+ return result;
+ }
}
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
index d6cacbb..39e64dd 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,4 +1,4 @@
-import App from './App.svelte';
+import App from './ui/App.svelte';
const app = new App({
target: document.body,
diff --git a/src/solver/asconfig.json b/src/solver/asconfig.json
new file mode 100644
index 0000000..af6a46f
--- /dev/null
+++ b/src/solver/asconfig.json
@@ -0,0 +1,20 @@
+{
+ "targets": {
+ "debug": {
+ "binaryFile": "build/untouched.wasm",
+ "textFile": "build/untouched.wat",
+ "sourceMap": true,
+ "debug": true
+ },
+ "release": {
+ "binaryFile": "../../public/solver/main.wasm",
+ "textFile": "../../public/solver/main.wat",
+ "sourceMap": false,
+ "optimizeLevel": 3,
+ "shrinkLevel": 1,
+ "converge": true,
+ "noAssert": true
+ }
+ },
+ "options": {}
+}
\ No newline at end of file
diff --git a/src/solver/assembly/SomaSolution.ts b/src/solver/assembly/SomaSolution.ts
new file mode 100644
index 0000000..422ce95
--- /dev/null
+++ b/src/solver/assembly/SomaSolution.ts
@@ -0,0 +1,89 @@
+import VoxelSpace from "./VoxelSpace";
+
+export default class SomaSolution {
+ private solutionSpaces: VoxelSpace[];
+ private dim: i32;
+ constructor(dim: i32) {
+ if (dim < 0 || dim % 1 !== 0) {
+ throw new Error("Dimension must be a whole positive integer!");
+ }
+ this.dim = dim;
+ this.solutionSpaces = [];
+ }
+
+ static filterUnique(solutions: SomaSolution[]): SomaSolution[] {
+ const uniqueSolns = new Array();
+ if (solutions.length == 0) {
+ return uniqueSolns;
+ }
+ uniqueSolns.push(solutions[0]);
+ for (let iSoln = 0; iSoln < solutions.length; iSoln++) {
+ const rots = solutions[iSoln].getRotations();
+ let foundMatch = false;
+ for (let iRot = 0; iRot < rots.length; iRot++) {
+ let end = uniqueSolns.length;
+ for (let i = 0; i < end; i++) {
+ if (rots[iRot].matches(uniqueSolns[i])) {
+ foundMatch = true;
+ }
+ }
+ }
+ if (!foundMatch) {
+ uniqueSolns.push(solutions[iSoln]);
+ }
+ }
+ return uniqueSolns;
+ }
+
+ getRotations(): SomaSolution[] {
+ const result: SomaSolution[] = new Array();
+ if (this.solutionSpaces.length == 0) {
+ return result;
+ }
+ const allRots: VoxelSpace[][] = this.solutionSpaces.map(space => space.getAllRotations());
+ for (let i = 0; i < allRots[0].length; i++) {
+ const solnRot = new SomaSolution(this.dim);
+ for (let j = 0; j < allRots.length; j++) {
+ solnRot.addSpace(allRots[j][i]);
+ }
+ result.push(solnRot);
+ }
+ return result;
+ }
+
+ matches(solution: SomaSolution): boolean {
+ for (let i = 0; i < this.solutionSpaces.length; i++) {
+ if (!this.solutionSpaces[i].matches(solution.solutionSpaces[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ addSpace(space: VoxelSpace): void {
+ this.solutionSpaces.push(space);
+ }
+
+ at(x: i32, y: i32, z: i32): i32 {
+ for (let i = 0; i < this.solutionSpaces.length; i++) {
+ if (this.solutionSpaces[i].at(x, y, z)) {
+ return this.solutionSpaces[i].getId();
+ }
+ }
+ return 0;
+ }
+
+ clone(): SomaSolution {
+ const clone = new SomaSolution(this.dim);
+ clone.solutionSpaces = this.solutionSpaces.slice(0, this.solutionSpaces.length);
+ return clone;
+ }
+
+ getDims(): i32[] {
+ return [this.dim, this.dim, this.dim];
+ }
+
+ getPieces(): VoxelSpace[] {
+ return this.solutionSpaces;
+ }
+}
\ No newline at end of file
diff --git a/src/solver/assembly/SomaSolver.ts b/src/solver/assembly/SomaSolver.ts
new file mode 100644
index 0000000..a123ef0
--- /dev/null
+++ b/src/solver/assembly/SomaSolver.ts
@@ -0,0 +1,58 @@
+import VoxelSpace from "./VoxelSpace";
+import SomaSolution from "./SomaSolution";
+
+export default class SomaSolver {
+ private solutionCube: VoxelSpace;
+ private dim: i32;
+ private solutions: SomaSolution[] = new Array();
+ private iterations: i32 = 0;
+ constructor(dimension: i32) {
+ if (dimension % 1 !== 0 || dimension < 0) {
+ throw new Error("The argument 'dimension' must be a positive whole number");
+ }
+ this.dim = dimension;
+ this.solutionCube = new VoxelSpace(0, dimension, dimension, dimension, 0);
+ }
+
+ solve(polycubes: VoxelSpace[]): void {
+ if (polycubes.length === 0) {
+ throw new Error("You must pass at least one polycube to solve the puzzle.");
+ }
+ let cumulativeSize = polycubes.reduce((prev, curr) => prev + curr.size(), 0);
+ if (cumulativeSize !== this.dim**3) {
+ throw new Error(`The polycubes passed do not add up to exactly enough units to form a cube of dimension ${this.dim}! Got: ${cumulativeSize}, need: ${this.dim**3}`);
+ }
+ this.solutions.splice(0, this.solutions.length);
+ const combosWithRots: VoxelSpace[][] = new Array>();
+ for (let i = 1; i < polycubes.length; i++) {
+ combosWithRots.push(polycubes[i].getAllPermutationsInCubeOfSize(this.dim));
+ }
+ let combos: VoxelSpace[][] = new Array>();
+ combos.push(polycubes[0].getAllPositionsInCube(this.dim));
+ combos = combos.concat(combosWithRots);
+ this.backtrackSolve(this.solutionCube, combos, new SomaSolution(this.dim));
+ this.solutions = SomaSolution.filterUnique(this.solutions);
+ }
+
+ getSolutions(): SomaSolution[] {
+ return this.solutions.slice(0, this.solutions.length);
+ }
+
+ private backtrackSolve(workingSolution: VoxelSpace, polycubes: VoxelSpace[][], currentSoln: SomaSolution, depth: i32 = 0): void {
+ const nextCubeGroup = polycubes[0];
+ for (let i = 0; i < nextCubeGroup.length; i++) {
+ const fusionAttempt = workingSolution.plus(nextCubeGroup[i]);
+ if (fusionAttempt) {
+ const nextSoln = currentSoln.clone();
+ nextSoln.addSpace(nextCubeGroup[i]);
+ if (polycubes.length == 1) {
+ this.solutions.push(nextSoln);
+ currentSoln = new SomaSolution(this.dim);
+ return;
+ } else {
+ this.backtrackSolve(fusionAttempt, polycubes.slice(1), nextSoln, depth + 1);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/solver/assembly/VoxelSpace.ts b/src/solver/assembly/VoxelSpace.ts
new file mode 100644
index 0000000..1c26a80
--- /dev/null
+++ b/src/solver/assembly/VoxelSpace.ts
@@ -0,0 +1,327 @@
+class Extrema {
+ constructor(
+ public xMax: i32,
+ public xMin: i32,
+ public yMax: i32,
+ public yMin: i32,
+ public zMax: i32,
+ public zMin: i32,
+ ) {}
+}
+
+export default class VoxelSpace {
+ private length: i32;
+ private space: i64;
+ private id: i32;
+ private dimx: i32;
+ private dimy: i32;
+ private dimz: i32;
+
+ constructor(id: i32, dimx: i32, dimy: i32, dimz: i32, space: i64 = 0, cullEmpty: boolean = false) {
+ if (!space) {
+ space = 0;
+ }
+ this.id = id;
+ this.length = dimx * dimy * dimz;
+ this.dimx = dimx;
+ this.dimy = dimy;
+ this.dimz = dimz;
+ this.space = space;
+ if (cullEmpty) {
+ this.cullEmptySpace();
+ }
+ }
+
+ getExtrema(): Extrema {
+ const extrema = new Extrema(
+ 0,
+ i32.MAX_VALUE,
+ 0,
+ i32.MAX_VALUE,
+ 0,
+ i32.MAX_VALUE,
+ );
+ for (let x = 0; x < this.dimx; x++) {
+ for (let y = 0; y < this.dimy; y++) {
+ for (let z = 0; z < this.dimz; z++) {
+ const val = this.at(x, y, z);
+ if (val) {
+ extrema.xMax = Math.max(extrema.xMax, x) as i32;
+ extrema.xMin = Math.min(extrema.xMin, x) as i32;
+ extrema.yMax = Math.max(extrema.yMax, y) as i32;
+ extrema.yMin = Math.min(extrema.yMin, y) as i32;
+ extrema.zMax = Math.max(extrema.zMax, z) as i32;
+ extrema.zMin = Math.min(extrema.zMin, z) as i32;
+ }
+ }
+ }
+ }
+ return extrema;
+ }
+
+ private cullEmptySpace(): void {
+ const extrema = this.getExtrema();
+ let index = 0;
+ let newSpace = 0;
+ for (let x = extrema.xMin; x <= extrema.xMax; x++) {
+ for (let y = extrema.yMin; y <= extrema.yMax; y++) {
+ for (let z = extrema.zMin; z <= extrema.zMax; z++) {
+ if (this.at(x, y, z)) {
+ newSpace |= 1 << index;
+ }
+ index++;
+ }
+ }
+ }
+ this.dimx = extrema.xMax - extrema.xMin + 1;
+ this.dimy = extrema.yMax - extrema.yMin + 1;
+ this.dimz = extrema.zMax - extrema.zMin + 1;
+ this.space = newSpace;
+ }
+
+ getId(): i32 {
+ return this.id;
+ }
+
+ getUniqueRotations(): VoxelSpace[] {
+ const rotations: VoxelSpace[] = new Array();
+ const refSpace = this.clone();
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getXAxisSpins());
+ refSpace.rot90Y();
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getXAxisSpins());
+ refSpace.rot90Y();
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getXAxisSpins());
+ refSpace.rot90Y();
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getXAxisSpins());
+ refSpace.rot90Z();
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getXAxisSpins());
+ refSpace.rot90Z();
+ refSpace.rot90Z();
+ VoxelSpace.pushNewUniqueSpaces(rotations, refSpace.getXAxisSpins());
+ return rotations;
+ }
+
+ getAllRotations(): VoxelSpace[] {
+ let rotations: VoxelSpace[] = new Array();
+ const refSpace = this.clone();
+ rotations = rotations.concat(refSpace.getXAxisSpins());
+ refSpace.rot90Y();
+ rotations = rotations.concat(refSpace.getXAxisSpins());
+ refSpace.rot90Y();
+ rotations = rotations.concat(refSpace.getXAxisSpins());
+ refSpace.rot90Y();
+ rotations = rotations.concat(refSpace.getXAxisSpins());
+ refSpace.rot90Z();
+ rotations = rotations.concat(refSpace.getXAxisSpins());
+ refSpace.rot90Z();
+ refSpace.rot90Z();
+ rotations = rotations.concat(refSpace.getXAxisSpins());
+ return rotations;
+ }
+
+ protected static pushNewUniqueSpaces(existingSpaces: VoxelSpace[], newSpaces: VoxelSpace[]): void {
+ for (let iNew = 0; iNew < newSpaces.length; iNew++) {
+ let matchFound = false;
+ for (let iExisting = 0; iExisting < existingSpaces.length; iExisting++) {
+ if (newSpaces[iNew].matches(existingSpaces[iExisting])) {
+ matchFound = true;
+ break;
+ }
+ }
+ if (!matchFound) {
+ existingSpaces.push(newSpaces[iNew]);
+ }
+ }
+ }
+
+ getAllPositionsInCube(cubeDim: i32): VoxelSpace[] {
+ if ((cubeDim > 0) && (cubeDim % 1 == 0)) {
+ const cubePositions: VoxelSpace[] = [];
+ for (let x = 0; x < cubeDim - this.dimx + 1; x++) {
+ for (let y = 0; y < cubeDim - this.dimy + 1; y++) {
+ for (let z = 0; z < cubeDim - this.dimz + 1; z++) {
+ const cubePos = new VoxelSpace(this.id, cubeDim, cubeDim, cubeDim);
+ for (let rotX = 0; rotX < this.dimx; rotX++) {
+ for (let rotY = 0; rotY < this.dimy; rotY++) {
+ for (let rotZ = 0; rotZ < this.dimz; rotZ++) {
+ cubePos.set(x + rotX, y + rotY, z + rotZ, this.at(rotX, rotY, rotZ));
+ }
+ }
+ }
+ cubePositions.push(cubePos);
+ }
+ }
+ }
+ return cubePositions;
+ } else {
+ throw new Error("cubeDim must be a positive integer.");
+ }
+ }
+
+ matches(space: VoxelSpace): boolean {
+ if (space.dimx !== this.dimx) {
+ return false;
+ }
+ if (space.dimy !== this.dimy) {
+ return false;
+ }
+ if (space.dimz !== this.dimz) {
+ return false;
+ }
+ return this.space == space.getRaw();
+ }
+
+ clone(): VoxelSpace {
+ return new VoxelSpace(this.id, this.dimx, this.dimy, this.dimz, this.getRaw());
+ }
+
+ private getXAxisSpins(): VoxelSpace[] {
+ const rotations: Array = new Array();
+ rotations.push(this.clone());
+ for (let i = 0; i < 3; i++) {
+ rotations.push(rotations[i].rotated90X());
+ }
+ return rotations;
+ }
+
+ getRaw(): i64 {
+ return this.space;
+ }
+
+ // [1, 0, 0] [x] [ x]
+ // [0, 0, -1] * [y] = [-z]
+ // [0, 1, 0] [z] [ y]
+ private newIndexRotX(x: i32, y: i32, z: i32): i32 {
+ return this.dimz * this.dimy * x + this.dimy * (this.dimz - 1 - z) + y;
+ }
+
+ // [ 0, 0, 1] [x] [ z]
+ // [ 0, 1, 0] * [y] = [ y]
+ // [-1, 0, 0] [z] [-x]
+ private newIndexRotY(x: i32, y: i32, z: i32): i32 {
+ return this.dimy * this.dimx * z + this.dimx * y + (this.dimx - 1 - x);
+ }
+
+ // [0, -1, 0] [x] [-y]
+ // [1, 0, 0] * [y] = [ x]
+ // [0, 0, 1] [z] [ z]
+ private newIndexRotZ(x: i32, y: i32, z: i32): i32 {
+ return this.dimx * this.dimz * (this.dimy - 1 - y) + this.dimz * x + z;
+ }
+
+ at(x: i32, y: i32, z: i32): boolean {
+ const mask = 1 << (this.dimy * this.dimz * x + this.dimz * y + z);
+ return (this.space & mask) !== 0;
+ }
+
+ toggle(x: i32, y: i32, z: i32): void {
+ const mask = 1 << this.dimy * this.dimz * x + this.dimz * y + z;
+ this.space ^= mask;
+ }
+
+ set(x: i32, y: i32, z: i32, val: boolean): void {
+ const mask = 1 << this.dimy * this.dimz * x + this.dimz * y + z;
+ if (val) {
+ this.space |= mask;
+ } else {
+ this.space &= ~mask;
+ }
+ }
+
+ rotated90X(): VoxelSpace {
+ let newSpace = 0;
+ for (let x = 0; x < this.dimx; x++) {
+ for (let y = 0; y < this.dimy; y++) {
+ for (let z = 0; z < this.dimz; z++) {
+ if (this.at(x, y, z)) {
+ newSpace |= 1 << this.newIndexRotX(x, y, z);
+ }
+ }
+ }
+ }
+ return new VoxelSpace(this.id, this.dimx, this.dimz, this.dimy, newSpace);
+ }
+
+ rotated90Y(): VoxelSpace {
+ let newSpace = 0;
+ for (let x = 0; x < this.dimx; x++) {
+ for (let y = 0; y < this.dimy; y++) {
+ for (let z = 0; z < this.dimz; z++) {
+ if (this.at(x, y, z)) {
+ newSpace |= 1 << this.newIndexRotY(x, y, z);
+ }
+ }
+ }
+ }
+ return new VoxelSpace(this.id, this.dimz, this.dimy, this.dimx, newSpace);
+ }
+
+ rotated90Z(): VoxelSpace {
+ let newSpace = 0;
+ for (let x = 0; x < this.dimx; x++) {
+ for (let y = 0; y < this.dimy; y++) {
+ for (let z = 0; z < this.dimz; z++) {
+ if (this.at(x, y, z)) {
+ newSpace |= 1 << this.newIndexRotZ(x, y, z);
+ }
+ }
+ }
+ }
+ return new VoxelSpace(this.id, this.dimy, this.dimx, this.dimz, newSpace);
+ }
+
+ rot90X(): void {
+ const rot = this.rotated90X();
+ this.space = rot.getRaw();
+ this.dimx = rot.dimx;
+ this.dimy = rot.dimy;
+ this.dimz = rot.dimz;
+ }
+
+ rot90Y(): void {
+ const rot = this.rotated90Y();
+ this.space = rot.getRaw();
+ this.dimx = rot.dimx;
+ this.dimy = rot.dimy;
+ this.dimz = rot.dimz;
+ }
+
+ rot90Z(): void {
+ const rot = this.rotated90Z();
+ this.space = rot.getRaw();
+ this.dimx = rot.dimx;
+ this.dimy = rot.dimy;
+ this.dimz = rot.dimz;
+ }
+
+ plus(space: VoxelSpace): VoxelSpace | null {
+ const otherSpace = space.getRaw();
+ if ((this.space | otherSpace) == (this.space ^ otherSpace)) {
+ return new VoxelSpace(this.id, this.dimx, this.dimy, this.dimz, otherSpace | this.space);
+ }
+ return null;
+ }
+
+ size(): i32 {
+ let size = 0;
+ for (let x = 0; x < this.dimx; x++) {
+ for (let y = 0; y < this.dimy; y++) {
+ for (let z = 0; z < this.dimz; z++) {
+ if (this.at(x, y, z)) {
+ size++;
+ }
+ }
+ }
+ }
+ return size;
+ }
+
+ getAllPermutationsInCubeOfSize(dim: i32): VoxelSpace[] {
+ const rotations = this.getUniqueRotations();
+ let result = new Array();
+ for (let i = 0; i < rotations.length; i++) {
+ result = result.concat(rotations[i].getAllPositionsInCube(dim));
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/solver/assembly/index.ts b/src/solver/assembly/index.ts
new file mode 100644
index 0000000..941163b
--- /dev/null
+++ b/src/solver/assembly/index.ts
@@ -0,0 +1,22 @@
+import SomaSolver from "./SomaSolver";
+import VoxelSpace from "./VoxelSpace";
+
+
+export function solve(polycubes: Array, dim: i32): Int64Array[] {
+ const solver = new SomaSolver(dim);
+ const voxelSpaces = new Array();
+ for (let i = 0; i < polycubes.length; i++) {
+ voxelSpaces.push(new VoxelSpace(i, dim, dim, dim, polycubes[i], true));
+ }
+ solver.solve(voxelSpaces);
+ const solutions = solver.getSolutions();
+ let output: Int64Array[] = new Array();
+ for (let i = 0; i < solutions.length; i++) {
+ const pieces = solutions[i].getPieces();
+ output.push(new Int64Array(pieces.length));
+ for (let j = 0; j < pieces.length; j++) {
+ output[i][j] = pieces[j].getRaw();
+ }
+ }
+ return output;
+}
\ No newline at end of file
diff --git a/src/solver/assembly/tsconfig.json b/src/solver/assembly/tsconfig.json
new file mode 100644
index 0000000..e28fcf2
--- /dev/null
+++ b/src/solver/assembly/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "extends": "assemblyscript/std/assembly.json",
+ "include": [
+ "./**/*.ts"
+ ]
+}
\ No newline at end of file
diff --git a/src/solver/index.js b/src/solver/index.js
new file mode 100644
index 0000000..0c1fe49
--- /dev/null
+++ b/src/solver/index.js
@@ -0,0 +1,13 @@
+const AsBind = require("as-bind/dist/as-bind.cjs.js");
+const fs = require("fs");
+const wasm = fs.readFileSync("./build/untouched.wasm");
+const asyncTask = async () => {
+ const asBindInstance = await AsBind.instantiate(wasm);
+
+ // You can now use your wasm / as-bind instance!
+ const response = asBindInstance.exports.solve(
+ [16875584n, 16810176n, 65688n, 77952n, 12296n, 2109456n, 4184n], 3
+ );
+ console.log(response); // AsBind: Hello World!
+};
+asyncTask();
\ No newline at end of file
diff --git a/src/solver/main.ts b/src/solver/main.ts
deleted file mode 100644
index d7f0d73..0000000
--- a/src/solver/main.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import SomaSolver from "./SomaSolver";
-import VoxelSpace from "./VoxelSpace";
-
-type SolveStartMessageData = {polycubes: bigint[], dims: number};
-
-self.addEventListener('message', (event) => {
- const {polycubes, dims} = event.data as SolveStartMessageData;
- const solver = new SomaSolver(event.data.dims);
- solver.solve(polycubes.map((cubeRep, i) => new VoxelSpace(i, [dims, dims, dims], cubeRep)));
- (self as unknown as Worker).postMessage(solver.getSolutions());
-});
-
diff --git a/src/solver/package-lock.json b/src/solver/package-lock.json
new file mode 100644
index 0000000..ed766a4
--- /dev/null
+++ b/src/solver/package-lock.json
@@ -0,0 +1,60 @@
+{
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "@assemblyscript/loader": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.19.1.tgz",
+ "integrity": "sha512-3vpqYxOY7o8SNj2riGNF3wSZsqWippWTs7YwyTPPyxvjbrT1ZJnMMoGm4HSpbZ0QmKphzsaM4trR+BtxLFynDA=="
+ },
+ "as-bind": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/as-bind/-/as-bind-0.7.1.tgz",
+ "integrity": "sha512-x/tfZZcyObwvAohhVYaKqLSvroMHqop3l9gkUO5JM0bBEdhI3BWXjkG3DZIuWj0YFzhQ8OiWG3FCvQQq/5yB3A==",
+ "requires": {
+ "visitor-as": "^0.5.0"
+ }
+ },
+ "assemblyscript": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.1.tgz",
+ "integrity": "sha512-unWcmJsw5H0H2GrTf25GlDJCaNzAveeFYPH5XhP54m540+26KJIurTEHN+xf/EI3MdK7IhThpGCE+pNqiNuLmA==",
+ "dev": true,
+ "requires": {
+ "binaryen": "101.0.0-nightly.20210527",
+ "long": "^4.0.0"
+ }
+ },
+ "binaryen": {
+ "version": "101.0.0-nightly.20210527",
+ "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210527.tgz",
+ "integrity": "sha512-dbKentJwA6H0LfI+pRuzNNzAooJwYFNrg1L8rRw8j6rlfkU815ytNLO+uDzGNcltYehUa5ERZFJHPIdqX12n0w==",
+ "dev": true
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
+ },
+ "long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
+ "dev": true
+ },
+ "ts-mixer": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz",
+ "integrity": "sha512-Zo9HgPCtNouDgJ+LGtrzVOjSg8+7WGQktIKLwAfaNrlOK1mWGlz1ejsAF/YqUEqAGjUTeB5fEg8gH9Aui6w9xA=="
+ },
+ "visitor-as": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/visitor-as/-/visitor-as-0.5.0.tgz",
+ "integrity": "sha512-U2P13pa7BAnfj6IEbP4feS1Rci6NT4GlDcwpqkk90u7LGalc5jH9aMuWnxTC8RJJ92iZzDQ8Lea5/OnLDsgzlw==",
+ "requires": {
+ "lodash.clonedeep": "^4.5.0",
+ "ts-mixer": "^5.1.0"
+ }
+ }
+ }
+}
diff --git a/src/solver/package.json b/src/solver/package.json
new file mode 100644
index 0000000..3d8fcfc
--- /dev/null
+++ b/src/solver/package.json
@@ -0,0 +1,15 @@
+{
+ "scripts": {
+ "asbuild:untouched": "asc assembly/index.ts --target debug",
+ "asbuild:optimized": "asc assembly/index.ts --target release",
+ "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized",
+ "test": "node tests"
+ },
+ "dependencies": {
+ "@assemblyscript/loader": "^0.19.1",
+ "as-bind": "^0.7.1"
+ },
+ "devDependencies": {
+ "assemblyscript": "^0.19.1"
+ }
+}
diff --git a/src/store.ts b/src/store.ts
index d26ec26..b45981e 100644
--- a/src/store.ts
+++ b/src/store.ts
@@ -1,6 +1,6 @@
import { derived, writable } from 'svelte/store';
import { get } from 'svelte/store';
-import type SomaSolution from "./solver/SomaSolution";
+import type SomaSolution from "./SomaSolution";
type PolycubeInput = {
color: string,
@@ -23,7 +23,7 @@ export const isMaxPolycubes = derived(
([$polycubes, $somaDimension]: [PolycubeInput[], number]) => $polycubes.length >= $somaDimension ** 3);
export const isMinPolycubes = derived(store.polycubes, ($polycubes: PolycubeInput[]) => $polycubes.length <= 1);
export const solutions = writable([] as SomaSolution[]);
-export const activeSolution = writable(0);
+export const activeSolution = writable(null);
export const showingSolution = writable(false);
export const somaDimension = {
@@ -43,6 +43,12 @@ export const somaDimension = {
return dims - 1;
});
}
+ },
+ set(dims: number) {
+ if (dims <= MAX_DIMS && dims >= MIN_DIMS) {
+ polycubes.reset(dims);
+ store.somaDimension.set(dims);
+ }
}
};
@@ -107,5 +113,5 @@ function colorFromIndex(index: number) {
let hue = spacing * (index % 6) + offset;
const saturation = 100;
const lightness = 1 / (2 + darknessCycle) * 100;
- return `hsl(${hue},${saturation}%,${lightness}%)`;
+ return `hsl(${hue},${saturation}%,${Math.round(lightness)}%)`;
}
\ No newline at end of file
diff --git a/src/App.svelte b/src/ui/App.svelte
similarity index 93%
rename from src/App.svelte
rename to src/ui/App.svelte
index 1852a6e..4887671 100644
--- a/src/App.svelte
+++ b/src/ui/App.svelte
@@ -1,6 +1,6 @@
diff --git a/src/CubeInput.svelte b/src/ui/CubeInput.svelte
similarity index 90%
rename from src/CubeInput.svelte
rename to src/ui/CubeInput.svelte
index 5f9e004..10a63e4 100644
--- a/src/CubeInput.svelte
+++ b/src/ui/CubeInput.svelte
@@ -1,11 +1,11 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/ui/Sidebar.svelte b/src/ui/Sidebar.svelte
new file mode 100644
index 0000000..64e70a1
--- /dev/null
+++ b/src/ui/Sidebar.svelte
@@ -0,0 +1,196 @@
+
+
+
+
Somaesque
+
+
Solutions: {$solutions.length}
+
+
+
+
\ No newline at end of file
diff --git a/src/ui/Solution2D.svelte b/src/ui/Solution2D.svelte
new file mode 100644
index 0000000..812c4c3
--- /dev/null
+++ b/src/ui/Solution2D.svelte
@@ -0,0 +1,91 @@
+
+
+{#if $activeSolution !== null}
+ showingSolution.set(true)}
+ >
+
Solution #{$activeSolution + 1}
+
+ {#each {length: dimension} as _, x}
+
+ {#each {length: dimension} as _, y}
+
+ {#each {length: dimension} as _, z}
+
+ {/each}
+
+ {/each}
+
+ {/each}
+
+
+{/if}
+
+
\ No newline at end of file
diff --git a/src/ui/SolutionList.svelte b/src/ui/SolutionList.svelte
new file mode 100644
index 0000000..b7d138f
--- /dev/null
+++ b/src/ui/SolutionList.svelte
@@ -0,0 +1,44 @@
+
+
+
+ {#if $solutions.length === 0}
+ No solutions yet...
+ {/if}
+ {#each $solutions as soln, i}
+ selectSolution(i)}>
+ Solution #{i + 1}
+
+ {/each}
+
+
+
\ No newline at end of file
diff --git a/src/Polycube3D.svelte b/src/ui/SolutionViewer.svelte
similarity index 50%
rename from src/Polycube3D.svelte
rename to src/ui/SolutionViewer.svelte
index 35848c6..c18b546 100644
--- a/src/Polycube3D.svelte
+++ b/src/ui/SolutionViewer.svelte
@@ -1,7 +1,8 @@
-
+
\ No newline at end of file
diff --git a/src/ui/threedee/GeometryManager.ts b/src/ui/threedee/GeometryManager.ts
new file mode 100644
index 0000000..cd7ae83
--- /dev/null
+++ b/src/ui/threedee/GeometryManager.ts
@@ -0,0 +1,144 @@
+import type * as THREE from "three";
+import {OBJLoader} from "three/examples/jsm/loaders/OBJLoader";
+
+export enum SomaesqueGeometry {
+ c000000 = 'c000000',
+ c000001 = 'c000001',
+ c000011 = 'c000011',
+ c000111 = 'c000111',
+ c001001 = 'c001001',
+ c001011 = 'c001011',
+ c001111 = 'c001111',
+ c011011 = 'c011011',
+}
+
+const MESH_ROT_MAP = [
+ "000000", // 000000
+ "000001", // 000001
+ "000001z", // 000010
+ "000011", // 000011
+ "000001b", // 000100
+ "000011x", // 000101
+ "000011b", // 000110
+ "000111", // 000111
+ "000001yy", // 001000
+ "001001", // 001001
+ "000011yy", // 001010
+ "001011", // 001011
+ "000011zx", // 001100
+ "001011x", // 001101
+ "000111y", // 001110
+ "001111", // 001111
+ "000001ba", // 010000
+ "000011xx", // 010001
+ "001001ya", // 010010
+ "001011zb", // 010011
+ "000011yx", // 010100
+ "000111x", // 010101
+ "001011zb", // 010110
+ "001111zb", // 010111
+ "000011zz", // 011000
+ "001011xx", // 011001
+ "001011z", // 011010
+ "011011", // 011011
+ "000111yx", // 011100
+ "001111x", // 011101
+ "001111yx", // 011110
+ "011011", // 011111
+ "000001y", // 100000
+ "000011a", // 100001
+ "000011b", // 100010
+ "000111b", // 100011
+ "001001b", // 100100
+ "001011yc", // 100101 //---
+ "001011b", // 100110
+ "001111b", // 100111
+ "000011ccx",// 101000
+ "001011a", // 101001
+ "000111bb", // 101010
+ "001111a", // 101011
+ "001011yz", // 101100 //---
+ "011011x", // 101101 //---
+ "001111y", // 101110 //---
+ "011011", // 101111
+ "000011xz", // 110000 //---
+ "000111ba", // 110001 //---
+ "001011ba", // 110010 //---
+ "001111ba", // 110011
+ "001011bx", // 110100
+ "001111bx", // 110101
+ "011011b", // 110110
+ "011011", // 110111
+ "000111bba",// 111000
+ "001111xx", // 111001
+ "001111ya", // 111010
+ "011011", // 111011
+ "001111yz", // 111100
+ "011011", // 111101
+ "011011", // 111110
+ "011011", // 111111
+];
+
+const ROT_CODE_MAP = {
+ x(mesh: THREE.Object3D) { mesh.rotateX(Math.PI/2); },
+ y(mesh: THREE.Object3D) { mesh.rotateY(Math.PI/2); },
+ z(mesh: THREE.Object3D) { mesh.rotateZ(Math.PI/2); },
+ a(mesh: THREE.Object3D) { mesh.rotateX(-Math.PI/2); },
+ b(mesh: THREE.Object3D) { mesh.rotateY(-Math.PI/2); },
+ c(mesh: THREE.Object3D) { mesh.rotateZ(-Math.PI/2); },
+} as const;
+
+type GeomRecord = Record;
+
+export default class GeometryManager {
+ private readonly root: string = "";
+ private geometryRecord: GeomRecord = {} as GeomRecord;
+ constructor(root: string, onReadyCb: (error?: string) => any) {
+ this.root = root;
+ Promise.allSettled(Object.keys(SomaesqueGeometry).map(geomId =>
+ this.loadCubeGeometry(geomId as SomaesqueGeometry),
+ )).then(() => onReadyCb()).catch((err) => onReadyCb(err));
+ }
+
+ private async loadCubeGeometry(id: SomaesqueGeometry): Promise {
+ const onLoaded = (obj: THREE.Group, resolve: (geom: THREE.BufferGeometry) => any) => {
+ const geom = (obj.children[0] as THREE.Mesh).geometry;
+ this.geometryRecord[id] = geom;
+ resolve(geom);
+ };
+ const load = (resolve: (geom: THREE.BufferGeometry) => any, reject: (err: string) => any) => {
+ const loader = new OBJLoader();
+ loader.load(
+ `${this.root}${id}.obj`,
+ obj => onLoaded(obj, resolve),
+ () => {},
+ (err) => reject(`Error loading OBJ file: ${err}`),
+ );
+ };
+ return new Promise(load);
+ }
+
+ retrieve(geometry: SomaesqueGeometry) {
+ let requestedGeom = this.geometryRecord[geometry];
+ if (requestedGeom) {
+ return requestedGeom;
+ } else {
+ throw new Error(`Geometry with id: ${geometry} does not exist!`);
+ }
+ }
+
+ retrieveCubeGeometry(neighbourProfile: number) {
+ return this.geometryRecord.c000000;
+ // let requestedGeom = this.geometryRecord[`c${MESH_ROT_MAP[neighbourProfile].substr(0, 6)}`];
+ // const rotations = MESH_ROT_MAP[neighbourProfile].substr(6);
+ // if (!requestedGeom) {
+ // throw new Error(`No similar cube found for the neighbour profile: ${neighbourProfile}`)
+ // } else if (rotations) {
+ // requestedGeom = requestedGeom.clone();
+ // for (let i = 0; i < rotations.length; i++) {
+ // ROT_CODE_MAP[rotations[i]](requestedGeom);
+ // }
+ // }
+ // return requestedGeom;
+ }
+}
\ No newline at end of file
diff --git a/src/ui/threedee/PolycubeMesh.ts b/src/ui/threedee/PolycubeMesh.ts
new file mode 100644
index 0000000..d466d7b
--- /dev/null
+++ b/src/ui/threedee/PolycubeMesh.ts
@@ -0,0 +1,91 @@
+import * as THREE from "three";
+import type VoxelSpace from "../../VoxelSpace";
+import type GeometryManager from "./GeometryManager";
+
+export default class PolycubeMesh {
+ private static geometryManager: GeometryManager;
+ private group: THREE.Group;
+ private meshes: THREE.Mesh[] = [];
+ private currentPolycube: bigint = 0n;
+ private material: THREE.MeshPhongMaterial;
+ private numActiveCubes: number = 0;
+ private flyDirection: THREE.Vector3 = new THREE.Vector3();
+
+ constructor(polycube: VoxelSpace, color: string) {
+ this.material = new THREE.MeshPhongMaterial({color: 'red', shininess: 100, reflectivity: 100});
+ this.group = new THREE.Group();
+ this.swapColor(color);
+ this.swapPolycube(polycube);
+ }
+
+ static setManager(manager: GeometryManager) {
+ PolycubeMesh.geometryManager = manager;
+ }
+
+ swapColor(color: string) {
+ this.material.color.set(color);
+ }
+
+ swapPolycube(polycube: VoxelSpace) {
+ if (polycube.getRaw() === this.currentPolycube) {
+ return;
+ }
+ this.numActiveCubes = polycube.size();
+ this.meshes = [];
+ this.group.clear();
+ this.group.position.set(0, 0, 0);
+ polycube.forEachCell((val: boolean, x: number, y: number, z: number) => {
+ if (val) {
+ this.addCube(polycube, x, y, z);
+ }
+ });
+ this.currentPolycube = polycube.getRaw();
+ this.flyDirection = this.middlePosOfGroup().normalize();
+ }
+
+ private addCube(refPolycube: VoxelSpace, x: number, y: number, z: number) {
+ const dims = refPolycube.getDims();
+ const neighbourProfile = refPolycube.getDirectNeighbourProfile(x, y, z);
+ const mesh = new THREE.Mesh(
+ PolycubeMesh.geometryManager.retrieveCubeGeometry(neighbourProfile),
+ this.material
+ );
+ mesh.position.set(
+ -((dims[0] - 1)/2) + x,
+ -((dims[1] - 1)/2) + y,
+ -((dims[2] - 1)/2) + z,
+ );
+ this.meshes.push(mesh);
+ this.group.add(mesh);
+ }
+
+ center() {
+ const mid = this.middlePosOfGroup();
+ this.group.children.forEach(child => child.position.sub(mid));
+ }
+
+ private middlePosOfGroup() {
+ return this.group.children.reduce(
+ (prev, child) => prev.add(child.position),
+ new THREE.Vector3()
+ ).divideScalar(this.group.children.length);
+ }
+
+ flyBy(factor: number) {
+ const movementVector = this.flyDirection.clone().multiplyScalar(factor);
+ const targetPos = this.group.position.clone().add(movementVector);
+ const willMoveBehindStartingPosition = targetPos.clone().sub(this.flyDirection).dot(this.flyDirection) < -1;
+ if (!willMoveBehindStartingPosition) {
+ const distanceFromOrigin = targetPos.distanceTo(new THREE.Vector3());
+ if (distanceFromOrigin >= 0 && distanceFromOrigin < 3) {
+ this.group.position.add(movementVector);
+ }
+ } else {
+ this.group.position.set(0, 0, 0);
+ }
+ }
+
+ asObj3D(): THREE.Object3D {
+ return this.group;
+ }
+}
diff --git a/src/ui/threedee/PolycubeScene.ts b/src/ui/threedee/PolycubeScene.ts
new file mode 100644
index 0000000..00d99ba
--- /dev/null
+++ b/src/ui/threedee/PolycubeScene.ts
@@ -0,0 +1,87 @@
+import * as THREE from 'three';
+import type SomaSolution from "../../SomaSolution";
+import RotationControl from "./RotationControl";
+import PolycubeMesh from "./PolycubeMesh";
+import VoxelSpace, {DimensionDef} from "../../VoxelSpace";
+import GeometryManager from "./GeometryManager";
+
+export default class PolycubeScene {
+ private renderer: THREE.WebGLRenderer;
+ private camera: THREE.Camera;
+ private mainScene: THREE.Scene;
+ private polycubeMeshes: PolycubeMesh[] = [];
+ private controls: RotationControl;
+ private light: THREE.Light;
+ private cubeScene: THREE.Scene;
+ private geomManager: GeometryManager;
+
+ constructor(el: HTMLCanvasElement, onReady: () => any, onError: (err: Error) => any) {
+ this.init(el).then(onReady).catch(onError);
+ }
+
+ private async init(el: HTMLCanvasElement) {
+ this.renderer = new THREE.WebGLRenderer({canvas: el, antialias: true});
+ this.setupCamera(el.clientWidth / el.clientHeight);
+ this.setupLight();
+ this.mainScene = new THREE.Scene();
+ this.cubeScene = new THREE.Scene();
+ this.mainScene.add(this.cubeScene, this.camera, this.light);
+ this.cubeScene.rotateX(Math.PI/4);
+ this.cubeScene.rotateY(Math.PI/4);
+ this.controls = new RotationControl(this.cubeScene, this.polycubeMeshes, this.camera, el);
+ this.geomManager = await new GeometryManager('../resources/', () => {
+ requestAnimationFrame((timestamp) => this.render(timestamp));
+ });
+ PolycubeMesh.setManager(this.geomManager);
+ }
+
+ private setupCamera(aspect: number) {
+ const fov = 60;
+ const near = 0.1;
+ const far = 15;
+ this.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+ this.camera.position.z = 6;
+ this.camera.lookAt(0, 0, 0);
+ }
+
+ private showPolycube(polycube: bigint, dims: number, color: string) {
+ this.controls.disableFly();
+ const voxelSpace = new VoxelSpace(0, [dims, dims, dims], polycube, true);
+ this.clearScene();
+ this.addPolycube(voxelSpace, color);
+ this.polycubeMeshes[0].center();
+ }
+
+ private showSolution(solution: SomaSolution, colorMap: Record) {
+ this.controls.enableFly();
+ this.clearScene();
+ const pieces = solution.getPieces();
+ for (let i = 0; i < pieces.length; i++) {
+ this.addPolycube(pieces[i], colorMap[i]);
+ }
+ }
+
+ private clearScene() {
+ this.polycubeMeshes.splice(0, this.polycubeMeshes.length);
+ this.cubeScene.clear();
+ }
+
+ private addPolycube(voxelSpace: VoxelSpace, color: string) {
+ const newMesh = new PolycubeMesh(voxelSpace, color);
+ this.polycubeMeshes.push(newMesh);
+ this.cubeScene.add(newMesh.asObj3D());
+ }
+
+ private setupLight() {
+ const color = 0xFFFFFF;
+ const intensity = 1;
+ this.light = new THREE.DirectionalLight(color, intensity);
+ this.light.position.set(4, 6, 24);
+ this.light.lookAt(0,0,0);
+ }
+
+ private render(time: number) {
+ this.renderer.render(this.mainScene, this.camera);
+ requestAnimationFrame((time: number) => this.render(time));
+ }
+}
diff --git a/src/RotationControl.ts b/src/ui/threedee/RotationControl.ts
similarity index 53%
rename from src/RotationControl.ts
rename to src/ui/threedee/RotationControl.ts
index b2d9343..fc45967 100644
--- a/src/RotationControl.ts
+++ b/src/ui/threedee/RotationControl.ts
@@ -1,18 +1,26 @@
import type * as THREE from 'three';
+interface Fliable {
+ flyBy(factor: number);
+}
+
export default class RotationControls {
private static ROTATION_FACTOR = 1/200;
private object: THREE.Object3D;
private element: HTMLCanvasElement;
- private respondToMovement: boolean = false;
+ private dragging: boolean = false;
+ private flyingEnabled = true;
private lastX: number = 0;
private lastY: number = 0;
private yAxis: THREE.Vector3;
private xAxis: THREE.Vector3;
private start: THREE.Euler;
+ private fliables: Fliable[];
+ private hovered: boolean = false;
- constructor(object: THREE.Object3D, camera: THREE.Camera, element: HTMLCanvasElement) {
+ constructor(object: THREE.Object3D, fliables: Fliable[], camera: THREE.Camera, element: HTMLCanvasElement) {
this.object = object;
+ this.fliables = fliables;
this.element = element;
this.yAxis = object.worldToLocal(camera.up);
this.xAxis = object.position.sub(camera.position);
@@ -20,26 +28,50 @@ export default class RotationControls {
this.xAxis = this.xAxis.clone().cross(this.yAxis.clone());
this.start = this.object.rotation.clone();
+ this.element.addEventListener('mouseover', () => this.hovered = true);
+ this.element.addEventListener('mouseout', () => this.hovered = false);
+ this.element.addEventListener('wheel', (ev) => this.handleScroll(ev));
this.element.addEventListener('mousedown', (event) => {
if (event.button === 1) {
this.object.setRotationFromEuler(this.start);
}
- if (!this.respondToMovement) {
+ if (!this.dragging) {
this.lastX = event.x;
this.lastY = event.y;
- this.respondToMovement = true;
+ this.dragging = true;
}
});
window.addEventListener('mousemove', (ev) => this.handleMove(ev));
- window.addEventListener('mouseup', () => this.respondToMovement = false);
+ window.addEventListener('mouseup', () => this.dragging = false);
}
private handleMove(event: MouseEvent) {
- if (this.respondToMovement) {
+ if (this.dragging) {
const xDiff = event.movementX * RotationControls.ROTATION_FACTOR;
const yDiff = event.movementY * RotationControls.ROTATION_FACTOR;
this.object.rotateOnAxis(this.yAxis, xDiff);
this.object.rotateOnWorldAxis(this.xAxis, yDiff);
}
}
+
+ private handleScroll(event: WheelEvent) {
+ if (this.flyingEnabled && this.hovered) {
+ for (const fliable of this.fliables) {
+ const direction = event.deltaY / Math.abs(event.deltaY);
+ fliable.flyBy(direction / 10);
+ }
+ }
+ }
+
+ enableFly() {
+ this.flyingEnabled = true;
+ }
+
+ disableFly() {
+ this.flyingEnabled = false;
+ }
+
+ private static isMesh(object: THREE.Object3D): object is THREE.Mesh {
+ return (object as THREE.Mesh).isMesh;
+ }
}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 24ad1b3..383e4af 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,8 +2,8 @@
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"lib": ["dom", "ESNext"],
- "target": "ESNext",
+ "target": "ESNext"
},
"include": ["./src/**/*"],
- "exclude": ["./node_modules/*", "./__sapper__/*", "./public/*"]
+ "exclude": ["./node_modules/*", "./__sapper__/*", "./public/*", "./src/solver/**/*"]
}
\ No newline at end of file