updates for units (#1458)

* updates for units

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* scene units

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* start passing in units to tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* units tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add more images

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* hacky code for now

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* get settings context outside of react

* fmt

* pull through settings

* fix

* fmt

* move camera with units (#1461)

* temp patch tsc

* update kittycad.rs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* trait

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix compile

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update screenshots

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* execute on settings change

* Update src/clientSideScene/sceneInfra.ts

* try zoom

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* more shit image

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* new screenshots

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* udpates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* tests

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update cam

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* new

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates for units

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixles

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* ;scale

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fmt

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* tweak playwright draft segments test

* another test tweak

* last test tweak

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* update default plane snapshot scale

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* number tweaks for playwright flow checks

* up[date

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Jess Frazelle
2024-02-20 17:55:06 -08:00
committed by GitHub
parent e501a542ac
commit cbd26d29fa
77 changed files with 1425 additions and 1128 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 193 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 193 KiB

View File

@ -19,59 +19,59 @@ DATA;
); );
#4 = CARTESIAN_POINT('NONE', (0, 0, -0)); #4 = CARTESIAN_POINT('NONE', (0, 0, -0));
#5 = VERTEX_POINT('NONE', #4); #5 = VERTEX_POINT('NONE', #4);
#6 = CARTESIAN_POINT('NONE', (0, -0.0254, -0)); #6 = CARTESIAN_POINT('NONE', (0, -0.64516, -0));
#7 = VERTEX_POINT('NONE', #6); #7 = VERTEX_POINT('NONE', #6);
#8 = CARTESIAN_POINT('NONE', (0, -0.0254, 0.1016)); #8 = CARTESIAN_POINT('NONE', (0, -0.64516, 2.58064));
#9 = VERTEX_POINT('NONE', #8); #9 = VERTEX_POINT('NONE', #8);
#10 = CARTESIAN_POINT('NONE', (0, 0, 0.1016)); #10 = CARTESIAN_POINT('NONE', (0, 0, 2.58064));
#11 = VERTEX_POINT('NONE', #10); #11 = VERTEX_POINT('NONE', #10);
#12 = CARTESIAN_POINT('NONE', (0.07861346939195568, -0.0254, -0)); #12 = CARTESIAN_POINT('NONE', (1.996782122555674, -0.64516, -0));
#13 = VERTEX_POINT('NONE', #12); #13 = VERTEX_POINT('NONE', #12);
#14 = CARTESIAN_POINT('NONE', (0.07861346939195568, -0.0254, 0.1016)); #14 = CARTESIAN_POINT('NONE', (1.996782122555674, -0.64516, 2.58064));
#15 = VERTEX_POINT('NONE', #14); #15 = VERTEX_POINT('NONE', #14);
#16 = CARTESIAN_POINT('NONE', (0.1511633881344551, -0.07619999999999998, -0)); #16 = CARTESIAN_POINT('NONE', (3.839550058615159, -1.9354799999999992, -0));
#17 = VERTEX_POINT('NONE', #16); #17 = VERTEX_POINT('NONE', #16);
#18 = CARTESIAN_POINT('NONE', (0.1511633881344551, -0.07619999999999998, 0.1016)); #18 = CARTESIAN_POINT('NONE', (3.839550058615159, -1.9354799999999992, 2.58064));
#19 = VERTEX_POINT('NONE', #18); #19 = VERTEX_POINT('NONE', #18);
#20 = CARTESIAN_POINT('NONE', (0.2413, -0.0762, -0)); #20 = CARTESIAN_POINT('NONE', (6.12902, -1.93548, -0));
#21 = VERTEX_POINT('NONE', #20); #21 = VERTEX_POINT('NONE', #20);
#22 = CARTESIAN_POINT('NONE', (0.2413, -0.0762, 0.1016)); #22 = CARTESIAN_POINT('NONE', (6.12902, -1.93548, 2.58064));
#23 = VERTEX_POINT('NONE', #22); #23 = VERTEX_POINT('NONE', #22);
#24 = CARTESIAN_POINT('NONE', (0.2413, -0.0635, -0)); #24 = CARTESIAN_POINT('NONE', (6.12902, -1.6129, -0));
#25 = VERTEX_POINT('NONE', #24); #25 = VERTEX_POINT('NONE', #24);
#26 = CARTESIAN_POINT('NONE', (0.2413, -0.0635, 0.1016)); #26 = CARTESIAN_POINT('NONE', (6.12902, -1.6129, 2.58064));
#27 = VERTEX_POINT('NONE', #26); #27 = VERTEX_POINT('NONE', #26);
#28 = CARTESIAN_POINT('NONE', (0.1551676827532182, -0.0635, -0)); #28 = CARTESIAN_POINT('NONE', (3.9412591419317424, -1.6129, -0));
#29 = VERTEX_POINT('NONE', #28); #29 = VERTEX_POINT('NONE', #28);
#30 = CARTESIAN_POINT('NONE', (0.1551676827532182, -0.0635, 0.1016)); #30 = CARTESIAN_POINT('NONE', (3.9412591419317424, -1.6129, 2.58064));
#31 = VERTEX_POINT('NONE', #30); #31 = VERTEX_POINT('NONE', #30);
#32 = CARTESIAN_POINT('NONE', (0.06448028432509392, 0, -0)); #32 = CARTESIAN_POINT('NONE', (1.6377992218573856, 0, -0));
#33 = VERTEX_POINT('NONE', #32); #33 = VERTEX_POINT('NONE', #32);
#34 = CARTESIAN_POINT('NONE', (0.06448028432509392, 0, 0.1016)); #34 = CARTESIAN_POINT('NONE', (1.6377992218573856, 0, 2.58064));
#35 = VERTEX_POINT('NONE', #34); #35 = VERTEX_POINT('NONE', #34);
#36 = CARTESIAN_POINT('NONE', (0.14618599799650817, 0.03810000000000001, -0)); #36 = CARTESIAN_POINT('NONE', (3.7131243491113075, 0.9677400000000002, -0));
#37 = VERTEX_POINT('NONE', #36); #37 = VERTEX_POINT('NONE', #36);
#38 = CARTESIAN_POINT('NONE', (0.14618599799650817, 0.03810000000000001, 0.1016)); #38 = CARTESIAN_POINT('NONE', (3.7131243491113075, 0.9677400000000002, 2.58064));
#39 = VERTEX_POINT('NONE', #38); #39 = VERTEX_POINT('NONE', #38);
#40 = CARTESIAN_POINT('NONE', (0.2413, 0.0381, -0)); #40 = CARTESIAN_POINT('NONE', (6.12902, 0.9677399999999998, -0));
#41 = VERTEX_POINT('NONE', #40); #41 = VERTEX_POINT('NONE', #40);
#42 = CARTESIAN_POINT('NONE', (0.2413, 0.0381, 0.1016)); #42 = CARTESIAN_POINT('NONE', (6.12902, 0.9677399999999998, 2.58064));
#43 = VERTEX_POINT('NONE', #42); #43 = VERTEX_POINT('NONE', #42);
#44 = CARTESIAN_POINT('NONE', (0.2413, 0.0508, -0)); #44 = CARTESIAN_POINT('NONE', (6.12902, 1.29032, -0));
#45 = VERTEX_POINT('NONE', #44); #45 = VERTEX_POINT('NONE', #44);
#46 = CARTESIAN_POINT('NONE', (0.2413, 0.0508, 0.1016)); #46 = CARTESIAN_POINT('NONE', (6.12902, 1.29032, 2.58064));
#47 = VERTEX_POINT('NONE', #46); #47 = VERTEX_POINT('NONE', #46);
#48 = CARTESIAN_POINT('NONE', (0.14337047578094278, 0.0508, -0)); #48 = CARTESIAN_POINT('NONE', (3.6416100848359463, 1.29032, -0));
#49 = VERTEX_POINT('NONE', #48); #49 = VERTEX_POINT('NONE', #48);
#50 = CARTESIAN_POINT('NONE', (0.14337047578094278, 0.0508, 0.1016)); #50 = CARTESIAN_POINT('NONE', (3.6416100848359463, 1.29032, 2.58064));
#51 = VERTEX_POINT('NONE', #50); #51 = VERTEX_POINT('NONE', #50);
#52 = CARTESIAN_POINT('NONE', (0.08889999999999999, 0.0254, -0)); #52 = CARTESIAN_POINT('NONE', (2.2580599999999995, 0.64516, -0));
#53 = VERTEX_POINT('NONE', #52); #53 = VERTEX_POINT('NONE', #52);
#54 = CARTESIAN_POINT('NONE', (0.08889999999999999, 0.0254, 0.1016)); #54 = CARTESIAN_POINT('NONE', (2.2580599999999995, 0.64516, 2.58064));
#55 = VERTEX_POINT('NONE', #54); #55 = VERTEX_POINT('NONE', #54);
#56 = CARTESIAN_POINT('NONE', (0, 0.0254, -0)); #56 = CARTESIAN_POINT('NONE', (0, 0.64516, -0));
#57 = VERTEX_POINT('NONE', #56); #57 = VERTEX_POINT('NONE', #56);
#58 = CARTESIAN_POINT('NONE', (0, 0.0254, 0.1016)); #58 = CARTESIAN_POINT('NONE', (0, 0.64516, 2.58064));
#59 = VERTEX_POINT('NONE', #58); #59 = VERTEX_POINT('NONE', #58);
#60 = DIRECTION('NONE', (0, -1, 0)); #60 = DIRECTION('NONE', (0, -1, 0));
#61 = VECTOR('NONE', #60, 1); #61 = VECTOR('NONE', #60, 1);
@ -79,11 +79,11 @@ DATA;
#63 = LINE('NONE', #62, #61); #63 = LINE('NONE', #62, #61);
#64 = DIRECTION('NONE', (0, 0, 1)); #64 = DIRECTION('NONE', (0, 0, 1));
#65 = VECTOR('NONE', #64, 1); #65 = VECTOR('NONE', #64, 1);
#66 = CARTESIAN_POINT('NONE', (0, -0.0254, -0)); #66 = CARTESIAN_POINT('NONE', (0, -0.64516, -0));
#67 = LINE('NONE', #66, #65); #67 = LINE('NONE', #66, #65);
#68 = DIRECTION('NONE', (0, -1, 0)); #68 = DIRECTION('NONE', (0, -1, 0));
#69 = VECTOR('NONE', #68, 1); #69 = VECTOR('NONE', #68, 1);
#70 = CARTESIAN_POINT('NONE', (0, 0, 0.1016)); #70 = CARTESIAN_POINT('NONE', (0, 0, 2.58064));
#71 = LINE('NONE', #70, #69); #71 = LINE('NONE', #70, #69);
#72 = DIRECTION('NONE', (0, 0, 1)); #72 = DIRECTION('NONE', (0, 0, 1));
#73 = VECTOR('NONE', #72, 1); #73 = VECTOR('NONE', #72, 1);
@ -91,155 +91,155 @@ DATA;
#75 = LINE('NONE', #74, #73); #75 = LINE('NONE', #74, #73);
#76 = DIRECTION('NONE', (1, 0, 0)); #76 = DIRECTION('NONE', (1, 0, 0));
#77 = VECTOR('NONE', #76, 1); #77 = VECTOR('NONE', #76, 1);
#78 = CARTESIAN_POINT('NONE', (0, -0.0254, -0)); #78 = CARTESIAN_POINT('NONE', (0, -0.64516, -0));
#79 = LINE('NONE', #78, #77); #79 = LINE('NONE', #78, #77);
#80 = DIRECTION('NONE', (0, 0, 1)); #80 = DIRECTION('NONE', (0, 0, 1));
#81 = VECTOR('NONE', #80, 1); #81 = VECTOR('NONE', #80, 1);
#82 = CARTESIAN_POINT('NONE', (0.07861346939195568, -0.0254, -0)); #82 = CARTESIAN_POINT('NONE', (1.996782122555674, -0.64516, -0));
#83 = LINE('NONE', #82, #81); #83 = LINE('NONE', #82, #81);
#84 = DIRECTION('NONE', (1, 0, 0)); #84 = DIRECTION('NONE', (1, 0, 0));
#85 = VECTOR('NONE', #84, 1); #85 = VECTOR('NONE', #84, 1);
#86 = CARTESIAN_POINT('NONE', (0, -0.0254, 0.1016)); #86 = CARTESIAN_POINT('NONE', (0, -0.64516, 2.58064));
#87 = LINE('NONE', #86, #85); #87 = LINE('NONE', #86, #85);
#88 = DIRECTION('NONE', (0.8191520442889919, -0.5735764363510459, 0)); #88 = DIRECTION('NONE', (0.819152044288992, -0.5735764363510459, 0));
#89 = VECTOR('NONE', #88, 1); #89 = VECTOR('NONE', #88, 1);
#90 = CARTESIAN_POINT('NONE', (0.07861346939195568, -0.0254, -0)); #90 = CARTESIAN_POINT('NONE', (1.996782122555674, -0.64516, -0));
#91 = LINE('NONE', #90, #89); #91 = LINE('NONE', #90, #89);
#92 = DIRECTION('NONE', (0, 0, 1)); #92 = DIRECTION('NONE', (0, 0, 1));
#93 = VECTOR('NONE', #92, 1); #93 = VECTOR('NONE', #92, 1);
#94 = CARTESIAN_POINT('NONE', (0.1511633881344551, -0.07619999999999998, -0)); #94 = CARTESIAN_POINT('NONE', (3.839550058615159, -1.9354799999999992, -0));
#95 = LINE('NONE', #94, #93); #95 = LINE('NONE', #94, #93);
#96 = DIRECTION('NONE', (0.8191520442889919, -0.5735764363510459, 0)); #96 = DIRECTION('NONE', (0.819152044288992, -0.5735764363510459, 0));
#97 = VECTOR('NONE', #96, 1); #97 = VECTOR('NONE', #96, 1);
#98 = CARTESIAN_POINT('NONE', (0.07861346939195568, -0.0254, 0.1016)); #98 = CARTESIAN_POINT('NONE', (1.996782122555674, -0.64516, 2.58064));
#99 = LINE('NONE', #98, #97); #99 = LINE('NONE', #98, #97);
#100 = DIRECTION('NONE', (1, -0.0000000000000003079278779307945, 0)); #100 = DIRECTION('NONE', (1, -0.00000000000000038794063361359933, 0));
#101 = VECTOR('NONE', #100, 1); #101 = VECTOR('NONE', #100, 1);
#102 = CARTESIAN_POINT('NONE', (0.1511633881344551, -0.07619999999999998, -0)); #102 = CARTESIAN_POINT('NONE', (3.839550058615159, -1.9354799999999992, -0));
#103 = LINE('NONE', #102, #101); #103 = LINE('NONE', #102, #101);
#104 = DIRECTION('NONE', (0, 0, 1)); #104 = DIRECTION('NONE', (0, 0, 1));
#105 = VECTOR('NONE', #104, 1); #105 = VECTOR('NONE', #104, 1);
#106 = CARTESIAN_POINT('NONE', (0.2413, -0.0762, -0)); #106 = CARTESIAN_POINT('NONE', (6.12902, -1.93548, -0));
#107 = LINE('NONE', #106, #105); #107 = LINE('NONE', #106, #105);
#108 = DIRECTION('NONE', (1, -0.0000000000000003079278779307945, 0)); #108 = DIRECTION('NONE', (1, -0.00000000000000038794063361359933, 0));
#109 = VECTOR('NONE', #108, 1); #109 = VECTOR('NONE', #108, 1);
#110 = CARTESIAN_POINT('NONE', (0.1511633881344551, -0.07619999999999998, 0.1016)); #110 = CARTESIAN_POINT('NONE', (3.839550058615159, -1.9354799999999992, 2.58064));
#111 = LINE('NONE', #110, #109); #111 = LINE('NONE', #110, #109);
#112 = DIRECTION('NONE', (0, 1, 0)); #112 = DIRECTION('NONE', (0, 1, 0));
#113 = VECTOR('NONE', #112, 1); #113 = VECTOR('NONE', #112, 1);
#114 = CARTESIAN_POINT('NONE', (0.2413, -0.0762, -0)); #114 = CARTESIAN_POINT('NONE', (6.12902, -1.93548, -0));
#115 = LINE('NONE', #114, #113); #115 = LINE('NONE', #114, #113);
#116 = DIRECTION('NONE', (0, 0, 1)); #116 = DIRECTION('NONE', (0, 0, 1));
#117 = VECTOR('NONE', #116, 1); #117 = VECTOR('NONE', #116, 1);
#118 = CARTESIAN_POINT('NONE', (0.2413, -0.0635, -0)); #118 = CARTESIAN_POINT('NONE', (6.12902, -1.6129, -0));
#119 = LINE('NONE', #118, #117); #119 = LINE('NONE', #118, #117);
#120 = DIRECTION('NONE', (0, 1, 0)); #120 = DIRECTION('NONE', (0, 1, 0));
#121 = VECTOR('NONE', #120, 1); #121 = VECTOR('NONE', #120, 1);
#122 = CARTESIAN_POINT('NONE', (0.2413, -0.0762, 0.1016)); #122 = CARTESIAN_POINT('NONE', (6.12902, -1.93548, 2.58064));
#123 = LINE('NONE', #122, #121); #123 = LINE('NONE', #122, #121);
#124 = DIRECTION('NONE', (-1, 0, 0)); #124 = DIRECTION('NONE', (-1, 0, 0));
#125 = VECTOR('NONE', #124, 1); #125 = VECTOR('NONE', #124, 1);
#126 = CARTESIAN_POINT('NONE', (0.2413, -0.0635, -0)); #126 = CARTESIAN_POINT('NONE', (6.12902, -1.6129, -0));
#127 = LINE('NONE', #126, #125); #127 = LINE('NONE', #126, #125);
#128 = DIRECTION('NONE', (0, 0, 1)); #128 = DIRECTION('NONE', (0, 0, 1));
#129 = VECTOR('NONE', #128, 1); #129 = VECTOR('NONE', #128, 1);
#130 = CARTESIAN_POINT('NONE', (0.1551676827532182, -0.0635, -0)); #130 = CARTESIAN_POINT('NONE', (3.9412591419317424, -1.6129, -0));
#131 = LINE('NONE', #130, #129); #131 = LINE('NONE', #130, #129);
#132 = DIRECTION('NONE', (-1, 0, 0)); #132 = DIRECTION('NONE', (-1, 0, 0));
#133 = VECTOR('NONE', #132, 1); #133 = VECTOR('NONE', #132, 1);
#134 = CARTESIAN_POINT('NONE', (0.2413, -0.0635, 0.1016)); #134 = CARTESIAN_POINT('NONE', (6.12902, -1.6129, 2.58064));
#135 = LINE('NONE', #134, #133); #135 = LINE('NONE', #134, #133);
#136 = DIRECTION('NONE', (-0.8191520442889919, 0.573576436351046, 0)); #136 = DIRECTION('NONE', (-0.8191520442889919, 0.573576436351046, 0));
#137 = VECTOR('NONE', #136, 1); #137 = VECTOR('NONE', #136, 1);
#138 = CARTESIAN_POINT('NONE', (0.1551676827532182, -0.0635, -0)); #138 = CARTESIAN_POINT('NONE', (3.9412591419317424, -1.6129, -0));
#139 = LINE('NONE', #138, #137); #139 = LINE('NONE', #138, #137);
#140 = DIRECTION('NONE', (0, 0, 1)); #140 = DIRECTION('NONE', (0, 0, 1));
#141 = VECTOR('NONE', #140, 1); #141 = VECTOR('NONE', #140, 1);
#142 = CARTESIAN_POINT('NONE', (0.06448028432509392, 0, -0)); #142 = CARTESIAN_POINT('NONE', (1.6377992218573856, 0, -0));
#143 = LINE('NONE', #142, #141); #143 = LINE('NONE', #142, #141);
#144 = DIRECTION('NONE', (-0.8191520442889919, 0.573576436351046, 0)); #144 = DIRECTION('NONE', (-0.8191520442889919, 0.573576436351046, 0));
#145 = VECTOR('NONE', #144, 1); #145 = VECTOR('NONE', #144, 1);
#146 = CARTESIAN_POINT('NONE', (0.1551676827532182, -0.0635, 0.1016)); #146 = CARTESIAN_POINT('NONE', (3.9412591419317424, -1.6129, 2.58064));
#147 = LINE('NONE', #146, #145); #147 = LINE('NONE', #146, #145);
#148 = DIRECTION('NONE', (0.90630778703665, 0.4226182617406993, 0)); #148 = DIRECTION('NONE', (0.90630778703665, 0.4226182617406992, 0));
#149 = VECTOR('NONE', #148, 1); #149 = VECTOR('NONE', #148, 1);
#150 = CARTESIAN_POINT('NONE', (0.06448028432509392, 0, -0)); #150 = CARTESIAN_POINT('NONE', (1.6377992218573856, 0, -0));
#151 = LINE('NONE', #150, #149); #151 = LINE('NONE', #150, #149);
#152 = DIRECTION('NONE', (0, 0, 1)); #152 = DIRECTION('NONE', (0, 0, 1));
#153 = VECTOR('NONE', #152, 1); #153 = VECTOR('NONE', #152, 1);
#154 = CARTESIAN_POINT('NONE', (0.14618599799650817, 0.03810000000000001, -0)); #154 = CARTESIAN_POINT('NONE', (3.7131243491113075, 0.9677400000000002, -0));
#155 = LINE('NONE', #154, #153); #155 = LINE('NONE', #154, #153);
#156 = DIRECTION('NONE', (0.90630778703665, 0.4226182617406993, 0)); #156 = DIRECTION('NONE', (0.90630778703665, 0.4226182617406992, 0));
#157 = VECTOR('NONE', #156, 1); #157 = VECTOR('NONE', #156, 1);
#158 = CARTESIAN_POINT('NONE', (0.06448028432509392, 0, 0.1016)); #158 = CARTESIAN_POINT('NONE', (1.6377992218573856, 0, 2.58064));
#159 = LINE('NONE', #158, #157); #159 = LINE('NONE', #158, #157);
#160 = DIRECTION('NONE', (1, -0.00000000000000007295344279228718, 0)); #160 = DIRECTION('NONE', (1, -0.0000000000000001378647737807002, 0));
#161 = VECTOR('NONE', #160, 1); #161 = VECTOR('NONE', #160, 1);
#162 = CARTESIAN_POINT('NONE', (0.14618599799650817, 0.03810000000000001, -0)); #162 = CARTESIAN_POINT('NONE', (3.7131243491113075, 0.9677400000000002, -0));
#163 = LINE('NONE', #162, #161); #163 = LINE('NONE', #162, #161);
#164 = DIRECTION('NONE', (0, 0, 1)); #164 = DIRECTION('NONE', (0, 0, 1));
#165 = VECTOR('NONE', #164, 1); #165 = VECTOR('NONE', #164, 1);
#166 = CARTESIAN_POINT('NONE', (0.2413, 0.0381, -0)); #166 = CARTESIAN_POINT('NONE', (6.12902, 0.9677399999999998, -0));
#167 = LINE('NONE', #166, #165); #167 = LINE('NONE', #166, #165);
#168 = DIRECTION('NONE', (1, -0.00000000000000007295344279228718, 0)); #168 = DIRECTION('NONE', (1, -0.0000000000000001378647737807002, 0));
#169 = VECTOR('NONE', #168, 1); #169 = VECTOR('NONE', #168, 1);
#170 = CARTESIAN_POINT('NONE', (0.14618599799650817, 0.03810000000000001, 0.1016)); #170 = CARTESIAN_POINT('NONE', (3.7131243491113075, 0.9677400000000002, 2.58064));
#171 = LINE('NONE', #170, #169); #171 = LINE('NONE', #170, #169);
#172 = DIRECTION('NONE', (0, 1, 0)); #172 = DIRECTION('NONE', (0, 1, 0));
#173 = VECTOR('NONE', #172, 1); #173 = VECTOR('NONE', #172, 1);
#174 = CARTESIAN_POINT('NONE', (0.2413, 0.0381, -0)); #174 = CARTESIAN_POINT('NONE', (6.12902, 0.9677399999999998, -0));
#175 = LINE('NONE', #174, #173); #175 = LINE('NONE', #174, #173);
#176 = DIRECTION('NONE', (0, 0, 1)); #176 = DIRECTION('NONE', (0, 0, 1));
#177 = VECTOR('NONE', #176, 1); #177 = VECTOR('NONE', #176, 1);
#178 = CARTESIAN_POINT('NONE', (0.2413, 0.0508, -0)); #178 = CARTESIAN_POINT('NONE', (6.12902, 1.29032, -0));
#179 = LINE('NONE', #178, #177); #179 = LINE('NONE', #178, #177);
#180 = DIRECTION('NONE', (0, 1, 0)); #180 = DIRECTION('NONE', (0, 1, 0));
#181 = VECTOR('NONE', #180, 1); #181 = VECTOR('NONE', #180, 1);
#182 = CARTESIAN_POINT('NONE', (0.2413, 0.0381, 0.1016)); #182 = CARTESIAN_POINT('NONE', (6.12902, 0.9677399999999998, 2.58064));
#183 = LINE('NONE', #182, #181); #183 = LINE('NONE', #182, #181);
#184 = DIRECTION('NONE', (-1, 0, 0)); #184 = DIRECTION('NONE', (-1, 0, 0));
#185 = VECTOR('NONE', #184, 1); #185 = VECTOR('NONE', #184, 1);
#186 = CARTESIAN_POINT('NONE', (0.2413, 0.0508, -0)); #186 = CARTESIAN_POINT('NONE', (6.12902, 1.29032, -0));
#187 = LINE('NONE', #186, #185); #187 = LINE('NONE', #186, #185);
#188 = DIRECTION('NONE', (0, 0, 1)); #188 = DIRECTION('NONE', (0, 0, 1));
#189 = VECTOR('NONE', #188, 1); #189 = VECTOR('NONE', #188, 1);
#190 = CARTESIAN_POINT('NONE', (0.14337047578094278, 0.0508, -0)); #190 = CARTESIAN_POINT('NONE', (3.6416100848359463, 1.29032, -0));
#191 = LINE('NONE', #190, #189); #191 = LINE('NONE', #190, #189);
#192 = DIRECTION('NONE', (-1, 0, 0)); #192 = DIRECTION('NONE', (-1, 0, 0));
#193 = VECTOR('NONE', #192, 1); #193 = VECTOR('NONE', #192, 1);
#194 = CARTESIAN_POINT('NONE', (0.2413, 0.0508, 0.1016)); #194 = CARTESIAN_POINT('NONE', (6.12902, 1.29032, 2.58064));
#195 = LINE('NONE', #194, #193); #195 = LINE('NONE', #194, #193);
#196 = DIRECTION('NONE', (-0.90630778703665, -0.42261826174069944, 0)); #196 = DIRECTION('NONE', (-0.90630778703665, -0.4226182617406995, 0));
#197 = VECTOR('NONE', #196, 1); #197 = VECTOR('NONE', #196, 1);
#198 = CARTESIAN_POINT('NONE', (0.14337047578094278, 0.0508, -0)); #198 = CARTESIAN_POINT('NONE', (3.6416100848359463, 1.29032, -0));
#199 = LINE('NONE', #198, #197); #199 = LINE('NONE', #198, #197);
#200 = DIRECTION('NONE', (0, 0, 1)); #200 = DIRECTION('NONE', (0, 0, 1));
#201 = VECTOR('NONE', #200, 1); #201 = VECTOR('NONE', #200, 1);
#202 = CARTESIAN_POINT('NONE', (0.08889999999999999, 0.0254, -0)); #202 = CARTESIAN_POINT('NONE', (2.2580599999999995, 0.64516, -0));
#203 = LINE('NONE', #202, #201); #203 = LINE('NONE', #202, #201);
#204 = DIRECTION('NONE', (-0.90630778703665, -0.42261826174069944, 0)); #204 = DIRECTION('NONE', (-0.90630778703665, -0.4226182617406995, 0));
#205 = VECTOR('NONE', #204, 1); #205 = VECTOR('NONE', #204, 1);
#206 = CARTESIAN_POINT('NONE', (0.14337047578094278, 0.0508, 0.1016)); #206 = CARTESIAN_POINT('NONE', (3.6416100848359463, 1.29032, 2.58064));
#207 = LINE('NONE', #206, #205); #207 = LINE('NONE', #206, #205);
#208 = DIRECTION('NONE', (-1, 0, 0)); #208 = DIRECTION('NONE', (-1, 0, 0));
#209 = VECTOR('NONE', #208, 1); #209 = VECTOR('NONE', #208, 1);
#210 = CARTESIAN_POINT('NONE', (0.08889999999999999, 0.0254, -0)); #210 = CARTESIAN_POINT('NONE', (2.2580599999999995, 0.64516, -0));
#211 = LINE('NONE', #210, #209); #211 = LINE('NONE', #210, #209);
#212 = DIRECTION('NONE', (0, 0, 1)); #212 = DIRECTION('NONE', (0, 0, 1));
#213 = VECTOR('NONE', #212, 1); #213 = VECTOR('NONE', #212, 1);
#214 = CARTESIAN_POINT('NONE', (0, 0.0254, -0)); #214 = CARTESIAN_POINT('NONE', (0, 0.64516, -0));
#215 = LINE('NONE', #214, #213); #215 = LINE('NONE', #214, #213);
#216 = DIRECTION('NONE', (-1, 0, 0)); #216 = DIRECTION('NONE', (-1, 0, 0));
#217 = VECTOR('NONE', #216, 1); #217 = VECTOR('NONE', #216, 1);
#218 = CARTESIAN_POINT('NONE', (0.08889999999999999, 0.0254, 0.1016)); #218 = CARTESIAN_POINT('NONE', (2.2580599999999995, 0.64516, 2.58064));
#219 = LINE('NONE', #218, #217); #219 = LINE('NONE', #218, #217);
#220 = DIRECTION('NONE', (0, -1, 0)); #220 = DIRECTION('NONE', (0, -1, 0));
#221 = VECTOR('NONE', #220, 1); #221 = VECTOR('NONE', #220, 1);
#222 = CARTESIAN_POINT('NONE', (0, 0.0254, -0)); #222 = CARTESIAN_POINT('NONE', (0, 0.64516, -0));
#223 = LINE('NONE', #222, #221); #223 = LINE('NONE', #222, #221);
#224 = DIRECTION('NONE', (0, -1, 0)); #224 = DIRECTION('NONE', (0, -1, 0));
#225 = VECTOR('NONE', #224, 1); #225 = VECTOR('NONE', #224, 1);
#226 = CARTESIAN_POINT('NONE', (0, 0.0254, 0.1016)); #226 = CARTESIAN_POINT('NONE', (0, 0.64516, 2.58064));
#227 = LINE('NONE', #226, #225); #227 = LINE('NONE', #226, #225);
#228 = EDGE_CURVE('NONE', #5, #7, #63, .T.); #228 = EDGE_CURVE('NONE', #5, #7, #63, .T.);
#229 = EDGE_CURVE('NONE', #7, #9, #67, .T.); #229 = EDGE_CURVE('NONE', #7, #9, #67, .T.);
@ -383,59 +383,59 @@ DATA;
#367 = ORIENTED_EDGE('NONE', *, *, #267, .T.); #367 = ORIENTED_EDGE('NONE', *, *, #267, .T.);
#368 = ORIENTED_EDGE('NONE', *, *, #269, .T.); #368 = ORIENTED_EDGE('NONE', *, *, #269, .T.);
#369 = EDGE_LOOP('NONE', (#355, #356, #357, #358, #359, #360, #361, #362, #363, #364, #365, #366, #367, #368)); #369 = EDGE_LOOP('NONE', (#355, #356, #357, #358, #359, #360, #361, #362, #363, #364, #365, #366, #367, #368));
#370 = CARTESIAN_POINT('NONE', (0, -0.0127, 0.0508)); #370 = CARTESIAN_POINT('NONE', (0, -0.3225799999999985, 1.2903199999999995));
#371 = DIRECTION('NONE', (-1, -0, 0)); #371 = DIRECTION('NONE', (-1, -0, 0));
#372 = AXIS2_PLACEMENT_3D('NONE', #370, #371, $); #372 = AXIS2_PLACEMENT_3D('NONE', #370, #371, $);
#373 = PLANE('NONE', #372); #373 = PLANE('NONE', #372);
#374 = CARTESIAN_POINT('NONE', (0.039306734695977924, -0.025399999999999995, 0.0508)); #374 = CARTESIAN_POINT('NONE', (0.9983910612778368, -0.6451599999999998, 1.2903199999999997));
#375 = DIRECTION('NONE', (0, -1, 0)); #375 = DIRECTION('NONE', (0, -1, 0));
#376 = AXIS2_PLACEMENT_3D('NONE', #374, #375, $); #376 = AXIS2_PLACEMENT_3D('NONE', #374, #375, $);
#377 = PLANE('NONE', #376); #377 = PLANE('NONE', #376);
#378 = CARTESIAN_POINT('NONE', (0.11488842876320533, -0.05079999999999996, 0.05079999999999999)); #378 = CARTESIAN_POINT('NONE', (2.918166090585415, -1.2903199999999988, 1.2903199999999997));
#379 = DIRECTION('NONE', (-0.5735764363510459, -0.8191520442889919, 0)); #379 = DIRECTION('NONE', (-0.5735764363510459, -0.8191520442889919, 0));
#380 = AXIS2_PLACEMENT_3D('NONE', #378, #379, $); #380 = AXIS2_PLACEMENT_3D('NONE', #378, #379, $);
#381 = PLANE('NONE', #380); #381 = PLANE('NONE', #380);
#382 = CARTESIAN_POINT('NONE', (0.19623169406722757, -0.07619999999999999, 0.0508)); #382 = CARTESIAN_POINT('NONE', (4.984285029307579, -1.9354799999999992, 1.2903199999999997));
#383 = DIRECTION('NONE', (0, -1, 0)); #383 = DIRECTION('NONE', (0, -1, 0));
#384 = AXIS2_PLACEMENT_3D('NONE', #382, #383, $); #384 = AXIS2_PLACEMENT_3D('NONE', #382, #383, $);
#385 = PLANE('NONE', #384); #385 = PLANE('NONE', #384);
#386 = CARTESIAN_POINT('NONE', (0.2413, -0.06985, 0.0508)); #386 = CARTESIAN_POINT('NONE', (6.129019999999999, -1.7741899999999997, 1.2903199999999997));
#387 = DIRECTION('NONE', (1, -0, 0)); #387 = DIRECTION('NONE', (1, -0, 0));
#388 = AXIS2_PLACEMENT_3D('NONE', #386, #387, $); #388 = AXIS2_PLACEMENT_3D('NONE', #386, #387, $);
#389 = PLANE('NONE', #388); #389 = PLANE('NONE', #388);
#390 = CARTESIAN_POINT('NONE', (0.19823384137660915, -0.0635, 0.0508)); #390 = CARTESIAN_POINT('NONE', (5.035139570965871, -1.6128999999999998, 1.2903199999999997));
#391 = DIRECTION('NONE', (0, 1, -0)); #391 = DIRECTION('NONE', (0, 1, -0));
#392 = AXIS2_PLACEMENT_3D('NONE', #390, #391, $); #392 = AXIS2_PLACEMENT_3D('NONE', #390, #391, $);
#393 = PLANE('NONE', #392); #393 = PLANE('NONE', #392);
#394 = CARTESIAN_POINT('NONE', (0.10982398353915601, -0.03174999999999997, 0.0508)); #394 = CARTESIAN_POINT('NONE', (2.7895291818945633, -0.8064499999999998, 1.2903199999999995));
#395 = DIRECTION('NONE', (0.5735764363510459, 0.8191520442889917, -0)); #395 = DIRECTION('NONE', (0.5735764363510459, 0.8191520442889918, -0));
#396 = AXIS2_PLACEMENT_3D('NONE', #394, #395, $); #396 = AXIS2_PLACEMENT_3D('NONE', #394, #395, $);
#397 = PLANE('NONE', #396); #397 = PLANE('NONE', #396);
#398 = CARTESIAN_POINT('NONE', (0.105333141160801, 0.019049999999999987, 0.0508)); #398 = CARTESIAN_POINT('NONE', (2.6754617854843468, 0.4838700000000003, 1.2903199999999997));
#399 = DIRECTION('NONE', (0.4226182617406993, -0.90630778703665, 0)); #399 = DIRECTION('NONE', (0.4226182617406992, -0.90630778703665, 0));
#400 = AXIS2_PLACEMENT_3D('NONE', #398, #399, $); #400 = AXIS2_PLACEMENT_3D('NONE', #398, #399, $);
#401 = PLANE('NONE', #400); #401 = PLANE('NONE', #400);
#402 = CARTESIAN_POINT('NONE', (0.19374299899825406, 0.0381, 0.0508)); #402 = CARTESIAN_POINT('NONE', (4.921072174555653, 0.9677399999999998, 1.2903199999999995));
#403 = DIRECTION('NONE', (0, -1, 0)); #403 = DIRECTION('NONE', (0, -1, 0));
#404 = AXIS2_PLACEMENT_3D('NONE', #402, #403, $); #404 = AXIS2_PLACEMENT_3D('NONE', #402, #403, $);
#405 = PLANE('NONE', #404); #405 = PLANE('NONE', #404);
#406 = CARTESIAN_POINT('NONE', (0.2413, 0.044449999999999996, 0.0508)); #406 = CARTESIAN_POINT('NONE', (6.129019999999998, 1.1290299999999989, 1.2903199999999995));
#407 = DIRECTION('NONE', (1, -0, 0)); #407 = DIRECTION('NONE', (1, -0, 0));
#408 = AXIS2_PLACEMENT_3D('NONE', #406, #407, $); #408 = AXIS2_PLACEMENT_3D('NONE', #406, #407, $);
#409 = PLANE('NONE', #408); #409 = PLANE('NONE', #408);
#410 = CARTESIAN_POINT('NONE', (0.19233523789047138, 0.0508, 0.0508)); #410 = CARTESIAN_POINT('NONE', (4.8853150424179725, 1.2903199999999997, 1.2903199999999997));
#411 = DIRECTION('NONE', (0, 1, -0)); #411 = DIRECTION('NONE', (0, 1, -0));
#412 = AXIS2_PLACEMENT_3D('NONE', #410, #411, $); #412 = AXIS2_PLACEMENT_3D('NONE', #410, #411, $);
#413 = PLANE('NONE', #412); #413 = PLANE('NONE', #412);
#414 = CARTESIAN_POINT('NONE', (0.11613523789047137, 0.0381, 0.05079999999999999)); #414 = CARTESIAN_POINT('NONE', (2.9498350424179733, 0.9677399999999998, 1.2903199999999997));
#415 = DIRECTION('NONE', (-0.42261826174069966, 0.90630778703665, -0)); #415 = DIRECTION('NONE', (-0.42261826174069933, 0.9063077870366499, -0));
#416 = AXIS2_PLACEMENT_3D('NONE', #414, #415, $); #416 = AXIS2_PLACEMENT_3D('NONE', #414, #415, $);
#417 = PLANE('NONE', #416); #417 = PLANE('NONE', #416);
#418 = CARTESIAN_POINT('NONE', (0.044449999999999996, 0.0254, 0.0508)); #418 = CARTESIAN_POINT('NONE', (1.1290299999999998, 0.6451599999999998, 1.29032));
#419 = DIRECTION('NONE', (0, 1, -0)); #419 = DIRECTION('NONE', (0, 1, -0));
#420 = AXIS2_PLACEMENT_3D('NONE', #418, #419, $); #420 = AXIS2_PLACEMENT_3D('NONE', #418, #419, $);
#421 = PLANE('NONE', #420); #421 = PLANE('NONE', #420);
#422 = CARTESIAN_POINT('NONE', (0, 0.0127, 0.0508)); #422 = CARTESIAN_POINT('NONE', (0, 0.32257999999999987, 1.2903199999999995));
#423 = DIRECTION('NONE', (-1, -0, 0)); #423 = DIRECTION('NONE', (-1, -0, 0));
#424 = AXIS2_PLACEMENT_3D('NONE', #422, #423, $); #424 = AXIS2_PLACEMENT_3D('NONE', #422, #423, $);
#425 = PLANE('NONE', #424); #425 = PLANE('NONE', #424);
@ -443,7 +443,7 @@ DATA;
#427 = DIRECTION('NONE', (0, 0, 1)); #427 = DIRECTION('NONE', (0, 0, 1));
#428 = AXIS2_PLACEMENT_3D('NONE', #426, #427, $); #428 = AXIS2_PLACEMENT_3D('NONE', #426, #427, $);
#429 = PLANE('NONE', #428); #429 = PLANE('NONE', #428);
#430 = CARTESIAN_POINT('NONE', (0, 0, 0.1016)); #430 = CARTESIAN_POINT('NONE', (0, 0, 2.58064));
#431 = DIRECTION('NONE', (0, 0, 1)); #431 = DIRECTION('NONE', (0, 0, 1));
#432 = AXIS2_PLACEMENT_3D('NONE', #430, #431, $); #432 = AXIS2_PLACEMENT_3D('NONE', #430, #431, $);
#433 = PLANE('NONE', #432); #433 = PLANE('NONE', #432);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 221 KiB

View File

@ -1,478 +1,478 @@
solid unnamed solid unnamed
facet normal -1 0 0 facet normal -1 0 0
outer loop outer loop
vertex 0 -4 0 vertex 0 -101.600006 0
vertex 0 -0 0 vertex 0 -0 0
vertex 0 -4 -1 vertex 0 -101.600006 -25.400002
endloop endloop
endfacet endfacet
facet normal -1 0 0 facet normal -1 0 0
outer loop outer loop
vertex 0 -4 -1 vertex 0 -101.600006 -25.400002
vertex 0 -0 0 vertex 0 -0 0
vertex 0 -0 -1 vertex 0 -0 -25.400002
endloop endloop
endfacet endfacet
facet normal 0 0 -1 facet normal 0 0 -1
outer loop outer loop
vertex 0 -4 -1 vertex 0 -101.600006 -25.400002
vertex 0 -0 -1 vertex 0 -0 -25.400002
vertex 3.0950184 -4 -1 vertex 78.613464 -101.600006 -25.400002
endloop endloop
endfacet endfacet
facet normal 0 0 -1 facet normal 0 0 -1
outer loop outer loop
vertex 3.0950184 -4 -1 vertex 78.613464 -101.600006 -25.400002
vertex 0 -0 -1 vertex 0 -0 -25.400002
vertex 3.0950184 -0 -1 vertex 78.613464 -0 -25.400002
endloop endloop
endfacet endfacet
facet normal -0.57357645 0 -0.81915206 facet normal -0.5735764 0 -0.8191522
outer loop outer loop
vertex 3.0950184 -4 -1 vertex 78.613464 -101.600006 -25.400002
vertex 3.0950184 -0 -1 vertex 78.613464 -0 -25.400002
vertex 5.9513144 -4 -3 vertex 151.16339 -101.600006 -76.2
endloop endloop
endfacet endfacet
facet normal -0.57357645 0 -0.81915206 facet normal -0.5735764 0 -0.8191522
outer loop outer loop
vertex 5.9513144 -4 -3 vertex 151.16339 -101.600006 -76.2
vertex 3.0950184 -0 -1 vertex 78.613464 -0 -25.400002
vertex 5.9513144 -0 -3 vertex 151.16339 -0 -76.2
endloop endloop
endfacet endfacet
facet normal 0 0 -1 facet normal 0 0 -1
outer loop outer loop
vertex 5.9513144 -4 -3 vertex 151.16339 -101.600006 -76.2
vertex 5.9513144 -0 -3 vertex 151.16339 -0 -76.2
vertex 9.5 -4 -3 vertex 241.3 -101.600006 -76.2
endloop endloop
endfacet endfacet
facet normal 0 0 -1 facet normal 0 0 -1
outer loop outer loop
vertex 9.5 -4 -3 vertex 241.3 -101.600006 -76.2
vertex 5.9513144 -0 -3 vertex 151.16339 -0 -76.2
vertex 9.5 -0 -3 vertex 241.3 -0 -76.2
endloop endloop
endfacet endfacet
facet normal 1 0 0 facet normal 1 0 0
outer loop outer loop
vertex 9.5 -4 -3 vertex 241.3 -101.600006 -76.2
vertex 9.5 -0 -3 vertex 241.3 -0 -76.2
vertex 9.5 -4 -2.5 vertex 241.3 -101.600006 -63.5
endloop endloop
endfacet endfacet
facet normal 1 -0 0 facet normal 1 -0 0
outer loop outer loop
vertex 9.5 -4 -2.5 vertex 241.3 -101.600006 -63.5
vertex 9.5 -0 -3 vertex 241.3 -0 -76.2
vertex 9.5 -0 -2.5 vertex 241.3 -0 -63.5
endloop
endfacet
facet normal 0 -0 1
outer loop
vertex 241.3 -101.600006 -63.5
vertex 241.3 -0 -63.5
vertex 155.16768 -101.600006 -63.5
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 155.16768 -101.600006 -63.5
vertex 241.3 -0 -63.5
vertex 155.16768 -0 -63.5
endloop
endfacet
facet normal 0.5735765 0 0.81915194
outer loop
vertex 87.15214 -101.600006 -15.875
vertex 109.82398 -101.600006 -31.75
vertex 109.82398 -0 -31.75
endloop
endfacet
facet normal 0.57357645 0 0.819152
outer loop
vertex 109.82398 -101.600006 -31.75
vertex 155.16768 -101.600006 -63.5
vertex 155.16768 -0 -63.5
endloop
endfacet
facet normal 0.57357645 0 0.81915206
outer loop
vertex 87.15214 -0 -15.875
vertex 64.480286 -101.600006 0
vertex 87.15214 -101.600006 -15.875
endloop
endfacet
facet normal 0.5735765 0 0.81915194
outer loop
vertex 109.82398 -0 -31.75
vertex 87.15214 -0 -15.875
vertex 87.15214 -101.600006 -15.875
endloop
endfacet
facet normal 0.57357645 -0 0.819152
outer loop
vertex 109.82398 -101.600006 -31.75
vertex 155.16768 -0 -63.5
vertex 109.82398 -0 -31.75
endloop
endfacet
facet normal 0.57357645 -0 0.81915206
outer loop
vertex 64.480286 -101.600006 0
vertex 87.15214 -0 -15.875
vertex 64.480286 -0 0
endloop
endfacet
facet normal 0.4226182 0 -0.9063078
outer loop
vertex 84.906715 -101.600006 9.525
vertex 64.480286 -101.600006 0
vertex 64.480286 -0 0
endloop
endfacet
facet normal 0.42261833 0 -0.90630776
outer loop
vertex 105.33314 -101.600006 19.05
vertex 84.906715 -101.600006 9.525
vertex 84.906715 -0 9.525
endloop
endfacet
facet normal 0.4226182 0 -0.9063078
outer loop
vertex 84.906715 -0 9.525
vertex 84.906715 -101.600006 9.525
vertex 64.480286 -0 0
endloop
endfacet
facet normal 0.4226183 0 -0.9063078
outer loop
vertex 105.33314 -0 19.05
vertex 146.18599 -101.600006 38.1
vertex 105.33314 -101.600006 19.05
endloop
endfacet
facet normal 0.42261833 0 -0.90630776
outer loop
vertex 105.33314 -101.600006 19.05
vertex 84.906715 -0 9.525
vertex 105.33314 -0 19.05
endloop
endfacet
facet normal 0.4226183 0 -0.9063078
outer loop
vertex 146.18599 -101.600006 38.1
vertex 105.33314 -0 19.05
vertex 146.18599 -0 38.1
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 146.18599 -101.600006 38.1
vertex 146.18599 -0 38.1
vertex 241.3 -101.600006 38.1
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 241.3 -101.600006 38.1
vertex 146.18599 -0 38.1
vertex 241.3 -0 38.1
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 241.3 -101.600006 38.1
vertex 241.3 -0 38.1
vertex 241.3 -101.600006 50.800003
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 241.3 -101.600006 50.800003
vertex 241.3 -0 38.1
vertex 241.3 -0 50.800003
endloop endloop
endfacet endfacet
facet normal 0 -0 0.99999994 facet normal 0 -0 0.99999994
outer loop outer loop
vertex 9.5 -4 -2.5 vertex 241.3 -101.600006 50.800003
vertex 9.5 -0 -2.5 vertex 241.3 -0 50.800003
vertex 6.108964 -4 -2.5 vertex 143.37048 -101.600006 50.800003
endloop endloop
endfacet endfacet
facet normal 0 0 0.99999994 facet normal 0 0 0.99999994
outer loop outer loop
vertex 6.108964 -4 -2.5 vertex 143.37048 -101.600006 50.800003
vertex 9.5 -0 -2.5 vertex 241.3 -0 50.800003
vertex 6.108964 -0 -2.5 vertex 143.37048 -0 50.800003
endloop endloop
endfacet endfacet
facet normal 0.5735763 0 0.8191522 facet normal -0.42261827 0 0.9063078
outer loop outer loop
vertex 3.4311862 -4 -0.625 vertex 143.37048 -101.600006 50.800003
vertex 4.323779 -4 -1.25 vertex 143.37048 -0 50.800003
vertex 4.323779 -0 -1.25 vertex 88.9 -101.600006 25.400002
endloop endloop
endfacet endfacet
facet normal 0.57357645 0 0.819152 facet normal -0.42261827 0 0.9063078
outer loop outer loop
vertex 4.323779 -4 -1.25 vertex 88.9 -101.600006 25.400002
vertex 6.108964 -4 -2.5 vertex 143.37048 -0 50.800003
vertex 6.108964 -0 -2.5 vertex 88.9 -0 25.400002
endloop
endfacet
facet normal 0.57357645 0 0.819152
outer loop
vertex 3.4311862 -0 -0.625
vertex 2.5385938 -4 0
vertex 3.4311862 -4 -0.625
endloop
endfacet
facet normal 0.5735763 0 0.8191522
outer loop
vertex 4.323779 -0 -1.25
vertex 3.4311862 -0 -0.625
vertex 3.4311862 -4 -0.625
endloop
endfacet
facet normal 0.57357645 -0 0.819152
outer loop
vertex 4.323779 -4 -1.25
vertex 6.108964 -0 -2.5
vertex 4.323779 -0 -1.25
endloop
endfacet
facet normal 0.57357645 -0 0.819152
outer loop
vertex 2.5385938 -4 0
vertex 3.4311862 -0 -0.625
vertex 2.5385938 -0 0
endloop
endfacet
facet normal 0.42261824 0 -0.9063078
outer loop
vertex 3.342784 -4 0.375
vertex 2.5385938 -4 0
vertex 2.5385938 -0 0
endloop
endfacet
facet normal 0.42261824 0 -0.9063078
outer loop
vertex 4.146974 -4 0.75
vertex 3.342784 -4 0.375
vertex 3.342784 -0 0.375
endloop
endfacet
facet normal 0.42261824 0 -0.9063078
outer loop
vertex 3.342784 -0 0.375
vertex 3.342784 -4 0.375
vertex 2.5385938 -0 0
endloop
endfacet
facet normal 0.42261833 0 -0.90630776
outer loop
vertex 4.146974 -0 0.75
vertex 5.755354 -4 1.5
vertex 4.146974 -4 0.75
endloop
endfacet
facet normal 0.42261824 0 -0.9063078
outer loop
vertex 4.146974 -4 0.75
vertex 3.342784 -0 0.375
vertex 4.146974 -0 0.75
endloop
endfacet
facet normal 0.42261833 0 -0.90630776
outer loop
vertex 5.755354 -4 1.5
vertex 4.146974 -0 0.75
vertex 5.755354 -0 1.5
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 5.755354 -4 1.5
vertex 5.755354 -0 1.5
vertex 9.5 -4 1.5
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 9.5 -4 1.5
vertex 5.755354 -0 1.5
vertex 9.5 -0 1.5
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 9.5 -4 1.5
vertex 9.5 -0 1.5
vertex 9.5 -4 2
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 9.5 -4 2
vertex 9.5 -0 1.5
vertex 9.5 -0 2
endloop endloop
endfacet endfacet
facet normal 0 -0 1 facet normal 0 -0 1
outer loop outer loop
vertex 9.5 -4 2 vertex 88.9 -101.600006 25.400002
vertex 9.5 -0 2 vertex 88.9 -0 25.400002
vertex 5.644507 -4 2 vertex 0 -101.600006 25.400002
endloop endloop
endfacet endfacet
facet normal 0 0 1 facet normal 0 0 1
outer loop outer loop
vertex 5.644507 -4 2 vertex 0 -101.600006 25.400002
vertex 9.5 -0 2 vertex 88.9 -0 25.400002
vertex 5.644507 -0 2 vertex 0 -0 25.400002
endloop
endfacet
facet normal -0.42261824 0 0.90630776
outer loop
vertex 5.644507 -4 2
vertex 5.644507 -0 2
vertex 3.5 -4 1
endloop
endfacet
facet normal -0.42261824 0 0.90630776
outer loop
vertex 3.5 -4 1
vertex 5.644507 -0 2
vertex 3.5 -0 1
endloop
endfacet
facet normal 0 -0 1
outer loop
vertex 3.5 -4 1
vertex 3.5 -0 1
vertex 0 -4 1
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 0 -4 1
vertex 3.5 -0 1
vertex 0 -0 1
endloop endloop
endfacet endfacet
facet normal -1 0 0 facet normal -1 0 0
outer loop outer loop
vertex 0 -4 1 vertex 0 -101.600006 25.400002
vertex 0 -0 1 vertex 0 -0 25.400002
vertex 0 -4 0 vertex 0 -101.600006 0
endloop endloop
endfacet endfacet
facet normal -1 0 0 facet normal -1 0 0
outer loop outer loop
vertex 0 -4 0 vertex 0 -101.600006 0
vertex 0 -0 1 vertex 0 -0 25.400002
vertex 0 -0 0 vertex 0 -0 0
endloop endloop
endfacet endfacet
facet normal 0 1 -0 facet normal 0 1 -0
outer loop outer loop
vertex 3.342784 -0 0.375 vertex 84.906715 -0 9.525
vertex 2.5385938 -0 0 vertex 64.480286 -0 0
vertex 3.5 -0 1 vertex 88.9 -0 25.400002
endloop endloop
endfacet endfacet
facet normal 0 1 0 facet normal 0 1 0
outer loop outer loop
vertex 4.146974 -0 0.75 vertex 105.33314 -0 19.05
vertex 3.342784 -0 0.375 vertex 84.906715 -0 9.525
vertex 3.5 -0 1 vertex 88.9 -0 25.400002
endloop endloop
endfacet endfacet
facet normal 0 1 0 facet normal 0 1 0
outer loop outer loop
vertex 3.4311862 -0 -0.625 vertex 87.15214 -0 -15.875
vertex 4.323779 -0 -1.25 vertex 109.82398 -0 -31.75
vertex 3.0950184 -0 -1 vertex 78.613464 -0 -25.400002
endloop endloop
endfacet endfacet
facet normal 0 0.99999994 0 facet normal 0 1 0
outer loop outer loop
vertex 4.146974 -0 0.75 vertex 105.33314 -0 19.05
vertex 5.644507 -0 2 vertex 143.37048 -0 50.800003
vertex 5.755354 -0 1.5 vertex 146.18599 -0 38.1
endloop endloop
endfacet endfacet
facet normal -0 1 0 facet normal -0 1 0
outer loop outer loop
vertex 0 -0 1 vertex 0 -0 25.400002
vertex 3.5 -0 1 vertex 88.9 -0 25.400002
vertex 2.5385938 -0 0 vertex 64.480286 -0 0
endloop endloop
endfacet endfacet
facet normal 0 1 0 facet normal 0 1 0
outer loop outer loop
vertex 0 -0 1 vertex 0 -0 25.400002
vertex 2.5385938 -0 0 vertex 64.480286 -0 0
vertex 0 -0 0 vertex 0 -0 0
endloop endloop
endfacet endfacet
facet normal -0 1 0 facet normal -0 1 0
outer loop outer loop
vertex 5.644507 -0 2 vertex 143.37048 -0 50.800003
vertex 9.5 -0 2 vertex 241.3 -0 50.800003
vertex 5.755354 -0 1.5 vertex 146.18599 -0 38.1
endloop endloop
endfacet endfacet
facet normal 0 1 0 facet normal 0 1 0
outer loop outer loop
vertex 9.5 -0 2 vertex 241.3 -0 50.800003
vertex 9.5 -0 1.5 vertex 241.3 -0 38.1
vertex 5.755354 -0 1.5 vertex 146.18599 -0 38.1
endloop endloop
endfacet endfacet
facet normal 0 1 -0 facet normal 0 1 -0
outer loop outer loop
vertex 4.146974 -0 0.75 vertex 105.33314 -0 19.05
vertex 3.5 -0 1 vertex 88.9 -0 25.400002
vertex 5.644507 -0 2 vertex 143.37048 -0 50.800003
endloop endloop
endfacet endfacet
facet normal 0 0.99999994 0 facet normal 0 0.99999994 0
outer loop outer loop
vertex 2.5385938 -0 0 vertex 64.480286 -0 0
vertex 3.4311862 -0 -0.625 vertex 87.15214 -0 -15.875
vertex 3.0950184 -0 -1 vertex 78.613464 -0 -25.400002
endloop
endfacet
facet normal 0 0.99999994 0
outer loop
vertex 4.323779 -0 -1.25
vertex 5.9513144 -0 -3
vertex 3.0950184 -0 -1
endloop endloop
endfacet endfacet
facet normal 0 1 0 facet normal 0 1 0
outer loop outer loop
vertex 6.108964 -0 -2.5 vertex 109.82398 -0 -31.75
vertex 5.9513144 -0 -3 vertex 151.16339 -0 -76.2
vertex 4.323779 -0 -1.25 vertex 78.613464 -0 -25.400002
endloop
endfacet
facet normal 0 0.99999994 0
outer loop
vertex 9.5 -0 -2.5
vertex 9.5 -0 -3
vertex 6.108964 -0 -2.5
endloop endloop
endfacet endfacet
facet normal 0 1 0 facet normal 0 1 0
outer loop outer loop
vertex 6.108964 -0 -2.5 vertex 155.16768 -0 -63.5
vertex 9.5 -0 -3 vertex 151.16339 -0 -76.2
vertex 5.9513144 -0 -3 vertex 109.82398 -0 -31.75
endloop endloop
endfacet endfacet
facet normal 0 1 0 facet normal 0 1 0
outer loop outer loop
vertex 2.5385938 -0 0 vertex 241.3 -0 -63.5
vertex 3.0950184 -0 -1 vertex 241.3 -0 -76.2
vertex 0 -0 -1 vertex 155.16768 -0 -63.5
endloop endloop
endfacet endfacet
facet normal 0 1 0 facet normal 0 1 0
outer loop outer loop
vertex 0 -0 -1 vertex 155.16768 -0 -63.5
vertex 241.3 -0 -76.2
vertex 151.16339 -0 -76.2
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 64.480286 -0 0
vertex 78.613464 -0 -25.400002
vertex 0 -0 -25.400002
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 0 -0 -25.400002
vertex 0 -0 0 vertex 0 -0 0
vertex 2.5385938 -0 0 vertex 64.480286 -0 0
endloop endloop
endfacet endfacet
facet normal -0 -1 0 facet normal -0 -1 0
outer loop outer loop
vertex 3.342784 -4 0.375 vertex 84.906715 -101.600006 9.525
vertex 3.5 -4 1 vertex 88.9 -101.600006 25.400002
vertex 2.5385938 -4 0 vertex 64.480286 -101.600006 0
endloop endloop
endfacet endfacet
facet normal -0 -1 0 facet normal -0 -1 0
outer loop outer loop
vertex 4.146974 -4 0.75 vertex 105.33314 -101.600006 19.05
vertex 3.5 -4 1 vertex 88.9 -101.600006 25.400002
vertex 3.342784 -4 0.375 vertex 84.906715 -101.600006 9.525
endloop endloop
endfacet endfacet
facet normal 0 -1 -0 facet normal 0 -1 -0
outer loop outer loop
vertex 3.4311862 -4 -0.625 vertex 87.15214 -101.600006 -15.875
vertex 3.0950184 -4 -1 vertex 78.613464 -101.600006 -25.400002
vertex 4.323779 -4 -1.25 vertex 109.82398 -101.600006 -31.75
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 105.33314 -101.600006 19.05
vertex 146.18599 -101.600006 38.1
vertex 143.37048 -101.600006 50.800003
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 0 -101.600006 25.400002
vertex 64.480286 -101.600006 0
vertex 88.9 -101.600006 25.400002
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 0 -101.600006 25.400002
vertex 0 -101.600006 0
vertex 64.480286 -101.600006 0
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 143.37048 -101.600006 50.800003
vertex 146.18599 -101.600006 38.1
vertex 241.3 -101.600006 50.800003
endloop
endfacet
facet normal 0 -1 -0
outer loop
vertex 241.3 -101.600006 50.800003
vertex 146.18599 -101.600006 38.1
vertex 241.3 -101.600006 38.1
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 105.33314 -101.600006 19.05
vertex 143.37048 -101.600006 50.800003
vertex 88.9 -101.600006 25.400002
endloop endloop
endfacet endfacet
facet normal 0 -0.99999994 0 facet normal 0 -0.99999994 0
outer loop outer loop
vertex 4.146974 -4 0.75 vertex 64.480286 -101.600006 0
vertex 5.755354 -4 1.5 vertex 78.613464 -101.600006 -25.400002
vertex 5.644507 -4 2 vertex 87.15214 -101.600006 -15.875
endloop endloop
endfacet endfacet
facet normal 0 -1 0 facet normal -0 -1 -0
outer loop outer loop
vertex 0 -4 1 vertex 109.82398 -101.600006 -31.75
vertex 2.5385938 -4 0 vertex 78.613464 -101.600006 -25.400002
vertex 3.5 -4 1 vertex 151.16339 -101.600006 -76.2
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 0 -4 1
vertex 0 -4 0
vertex 2.5385938 -4 0
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 5.644507 -4 2
vertex 5.755354 -4 1.5
vertex 9.5 -4 2
endloop
endfacet
facet normal 0 -1 -0
outer loop
vertex 9.5 -4 2
vertex 5.755354 -4 1.5
vertex 9.5 -4 1.5
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 4.146974 -4 0.75
vertex 5.644507 -4 2
vertex 3.5 -4 1
endloop
endfacet
facet normal 0 -0.99999994 0
outer loop
vertex 2.5385938 -4 0
vertex 3.0950184 -4 -1
vertex 3.4311862 -4 -0.625
endloop
endfacet
facet normal -0 -0.99999994 -0
outer loop
vertex 4.323779 -4 -1.25
vertex 3.0950184 -4 -1
vertex 5.9513144 -4 -3
endloop endloop
endfacet endfacet
facet normal -0 -1 0 facet normal -0 -1 0
outer loop outer loop
vertex 6.108964 -4 -2.5 vertex 155.16768 -101.600006 -63.5
vertex 4.323779 -4 -1.25 vertex 109.82398 -101.600006 -31.75
vertex 5.9513144 -4 -3 vertex 151.16339 -101.600006 -76.2
endloop endloop
endfacet endfacet
facet normal -0 -0.99999994 -0 facet normal -0 -1 -0
outer loop outer loop
vertex 9.5 -4 -2.5 vertex 241.3 -101.600006 -63.5
vertex 6.108964 -4 -2.5 vertex 155.16768 -101.600006 -63.5
vertex 9.5 -4 -3 vertex 241.3 -101.600006 -76.2
endloop endloop
endfacet endfacet
facet normal 0 -1 -0 facet normal 0 -1 -0
outer loop outer loop
vertex 6.108964 -4 -2.5 vertex 155.16768 -101.600006 -63.5
vertex 5.9513144 -4 -3 vertex 151.16339 -101.600006 -76.2
vertex 9.5 -4 -3 vertex 241.3 -101.600006 -76.2
endloop endloop
endfacet endfacet
facet normal 0 -1 -0 facet normal 0 -1 -0
outer loop outer loop
vertex 2.5385938 -4 0 vertex 64.480286 -101.600006 0
vertex 0 -4 -1 vertex 0 -101.600006 -25.400002
vertex 3.0950184 -4 -1 vertex 78.613464 -101.600006 -25.400002
endloop endloop
endfacet endfacet
facet normal 0 -1 0 facet normal 0 -1 0
outer loop outer loop
vertex 0 -4 -1 vertex 0 -101.600006 -25.400002
vertex 2.5385938 -4 0 vertex 64.480286 -101.600006 0
vertex 0 -4 0 vertex 0 -101.600006 0
endloop endloop
endfacet endfacet
endsolid unnamed endsolid unnamed

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 221 KiB

View File

@ -72,7 +72,7 @@ test('Basic sketch', async ({ page }) => {
const startXPx = 600 const startXPx = 600
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
const startAt = '[23.89, -32.23]' const startAt = '[23.74, -32.03]'
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %)`) |> startProfileAt(${startAt}, %)`)
@ -82,7 +82,7 @@ test('Basic sketch', async ({ page }) => {
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10) await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
await page.waitForTimeout(100) await page.waitForTimeout(100)
const num = 24.11 const num = 23.97
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
@ -93,14 +93,14 @@ test('Basic sketch', async ({ page }) => {
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
|> line([${num}, 0], %) |> line([${num}, 0], %)
|> line([0, ${num + 0.01}], %)`) |> line([0, ${num}], %)`)
await page.mouse.click(startXPx, 500 - PUR * 20) await page.mouse.click(startXPx, 500 - PUR * 20)
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
|> line([${num}, 0], %) |> line([${num}, 0], %)
|> line([0, ${num + 0.01}], %) |> line([0, ${num}], %)
|> line([-48, 0], %)`) |> line([-47.71, 0], %)`)
// deselect line tool // deselect line tool
await page.getByRole('button', { name: 'Line' }).click() await page.getByRole('button', { name: 'Line' }).click()
@ -124,7 +124,7 @@ test('Basic sketch', async ({ page }) => {
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
|> line({ to: [${num}, 0], tag: 'seg01' }, %) |> line({ to: [${num}, 0], tag: 'seg01' }, %)
|> line([0, ${num + 0.01}], %) |> line([0, ${num}], %)
|> angledLine([180, segLen('seg01', %)], %)`) |> angledLine([180, segLen('seg01', %)], %)`)
}) })
@ -461,7 +461,7 @@ test('Selections work on fresh and edited sketch', async ({ page }) => {
const startXPx = 600 const startXPx = 600
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
const startAt = '[23.89, -32.23]' const startAt = '[23.74, -32.03]'
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %)`) |> startProfileAt(${startAt}, %)`)
@ -470,8 +470,8 @@ test('Selections work on fresh and edited sketch', async ({ page }) => {
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10) await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
const num = 24.11 const num = 23.97
const num2 = '48' const num2 = '47.71'
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
@ -482,13 +482,13 @@ test('Selections work on fresh and edited sketch', async ({ page }) => {
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
|> line([${num}, 0], %) |> line([${num}, 0], %)
|> line([0, ${num + 0.01}], %)`) |> line([0, ${num}], %)`)
await page.mouse.click(startXPx, 500 - PUR * 20) await page.mouse.click(startXPx, 500 - PUR * 20)
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
|> line([${num}, 0], %) |> line([${num}, 0], %)
|> line([0, ${num + 0.01}], %) |> line([0, ${num}], %)
|> line([-${num2}, 0], %)`) |> line([-${num2}, 0], %)`)
// deselect line tool // deselect line tool
@ -574,12 +574,13 @@ test('Selections work on fresh and edited sketch', async ({ page }) => {
await u.closeDebugPanel() await u.closeDebugPanel()
// select a line // select a line
await topHorzSegmentClick() // await topHorzSegmentClick()
await page.waitForTimeout(200) await page.getByText(startAt).click() // TODO remove this and reinstate // await topHorzSegmentClick()
await page.waitForTimeout(100)
// enter sketch again // enter sketch again
await page.getByRole('button', { name: 'Edit Sketch' }).click() await page.getByRole('button', { name: 'Edit Sketch' }).click()
await page.waitForTimeout(700) // wait for animation await page.waitForTimeout(300) // wait for animation
// hover again and check it works // hover again and check it works
await selectionSequence() await selectionSequence()
@ -715,7 +716,7 @@ test('Can add multiple sketches', async ({ page }) => {
const startXPx = 600 const startXPx = 600
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
const startAt = '[23.89, -32.23]' const startAt = '[23.74, -32.03]'
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %)`) |> startProfileAt(${startAt}, %)`)
@ -725,7 +726,7 @@ test('Can add multiple sketches', async ({ page }) => {
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10) await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
await page.waitForTimeout(100) await page.waitForTimeout(100)
const num = 24.11 const num = 23.97
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
@ -736,13 +737,13 @@ test('Can add multiple sketches', async ({ page }) => {
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
|> line([${num}, 0], %) |> line([${num}, 0], %)
|> line([0, ${num + 0.01}], %)`) |> line([0, ${num}], %)`)
await page.mouse.click(startXPx, 500 - PUR * 20) await page.mouse.click(startXPx, 500 - PUR * 20)
const finalCodeFirstSketch = `const part001 = startSketchOn('-XZ') const finalCodeFirstSketch = `const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)
|> line([${num}, 0], %) |> line([${num}, 0], %)
|> line([0, ${num + 0.01}], %) |> line([0, ${num}], %)
|> line([-48, 0], %)` |> line([-47.71, 0], %)`
await expect(page.locator('.cm-content')).toHaveText(finalCodeFirstSketch) await expect(page.locator('.cm-content')).toHaveText(finalCodeFirstSketch)
// exit the sketch // exit the sketch

View File

@ -369,13 +369,13 @@ test('extrude on each default plane should be stable', async ({
}) => { }) => {
const u = getUtils(page) const u = getUtils(page)
const makeCode = (plane = 'XY') => `const part001 = startSketchOn('${plane}') const makeCode = (plane = 'XY') => `const part001 = startSketchOn('${plane}')
|> startProfileAt([14.06, 8.88], %) |> startProfileAt([0.70, 0.44], %)
|> line([12.98, -0.15], %) |> line([0.66, -0.02], %)
|> line([5.56, 9.89], %) |> line([0.28, 0.50], %)
|> line([-11.28, 8.96], %) |> line([-0.56, 0.44], %)
|> line([-10.81, -7.57], %) |> line([-0.54, -0.38], %)
|> close(%) |> close(%)
|> extrude(20, %) |> extrude(1.00, %)
` `
await context.addInitScript(async (code) => { await context.addInitScript(async (code) => {
localStorage.setItem('persistCode', code) localStorage.setItem('persistCode', code)
@ -448,7 +448,7 @@ test('Draft segments should look right', async ({ page }) => {
const startXPx = 600 const startXPx = 600
await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10)
const startAt = '[23.89, -32.23]' const startAt = '[23.74, -32.03]'
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %)`) |> startProfileAt(${startAt}, %)`)
@ -463,7 +463,7 @@ test('Draft segments should look right', async ({ page }) => {
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10) await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 10)
await page.waitForTimeout(100) await page.waitForTimeout(100)
const num = 24.11 const num = 23.97
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const part001 = startSketchOn('-XZ') .toHaveText(`const part001 = startSketchOn('-XZ')
|> startProfileAt(${startAt}, %) |> startProfileAt(${startAt}, %)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -14,10 +14,8 @@ import {
Vector2, Vector2,
Group, Group,
PlaneGeometry, PlaneGeometry,
EdgesGeometry,
MeshBasicMaterial, MeshBasicMaterial,
Mesh, Mesh,
LineSegments,
DoubleSide, DoubleSide,
Intersection, Intersection,
Object3D, Object3D,
@ -34,7 +32,7 @@ import * as TWEEN from '@tweenjs/tween.js'
import { MouseGuard, cameraMouseDragGuards } from 'lib/cameraControls' import { MouseGuard, cameraMouseDragGuards } from 'lib/cameraControls'
import { SourceRange } from 'lang/wasm' import { SourceRange } from 'lang/wasm'
import { Axis } from 'lib/selections' import { Axis } from 'lib/selections'
import { createGridHelper } from './helpers' import { BaseUnit, SETTINGS_PERSIST_KEY } from 'machines/settingsMachine'
type SendType = ReturnType<typeof useModelingContext>['send'] type SendType = ReturnType<typeof useModelingContext>['send']
@ -308,8 +306,17 @@ class SceneInfra {
this.scene.background = null this.scene.background = null
// CAMERA // CAMERA
const camHeightDistanceRatio = 0.5
const baseUnit: BaseUnit =
JSON.parse(localStorage?.getItem(SETTINGS_PERSIST_KEY) || ('{}' as any))
.baseUnit || 'mm'
const baseRadius = 5.6
const length = baseUnitTomm(baseUnit) * baseRadius
const ang = Math.atan(camHeightDistanceRatio)
const x = Math.cos(ang) * length
const y = Math.sin(ang) * length
this.camera = this.createPerspectiveCamera() this.camera = this.createPerspectiveCamera()
this.camera.position.set(0, -128, 64) this.camera.position.set(0, -x, y)
if (DEBUG_SHOW_INTERSECTION_PLANE) if (DEBUG_SHOW_INTERSECTION_PLANE)
this.camera.layers.enable(INTERSECTION_PLANE_LAYER) this.camera.layers.enable(INTERSECTION_PLANE_LAYER)
@ -1107,6 +1114,23 @@ export function getSceneScale(
return 1 return 1
} }
function baseUnitTomm(baseUnit: BaseUnit) {
switch (baseUnit) {
case 'mm':
return 1
case 'cm':
return 10
case 'm':
return 1000
case 'in':
return 25.4
case 'ft':
return 304.8
case 'yd':
return 914.4
}
}
export function isQuaternionVertical(q: Quaternion) { export function isQuaternionVertical(q: Quaternion) {
const v = new Vector3(0, 0, 1).applyQuaternion(q) const v = new Vector3(0, 0, 1).applyQuaternion(q)
// no x or y components means it's vertical // no x or y components means it's vertical

View File

@ -30,6 +30,12 @@ type GlobalContext = {
settings: MachineContext<typeof settingsMachine> settings: MachineContext<typeof settingsMachine>
} }
// a little hacky for sure, open to changing it
// this implies that we should only even have one instance of this provider mounted at any one time
// but I think that's a safe assumption
let settingsStateRef: (typeof settingsMachine)['context'] | undefined
export const getSettingsState = () => settingsStateRef
export const GlobalStateContext = createContext({} as GlobalContext) export const GlobalStateContext = createContext({} as GlobalContext)
export const GlobalStateProvider = ({ export const GlobalStateProvider = ({
@ -71,6 +77,7 @@ export const GlobalStateProvider = ({
}, },
}, },
}) })
settingsStateRef = settingsState.context
useStateMachineCommands({ useStateMachineCommands({
machineId: 'settings', machineId: 'settings',

View File

@ -136,15 +136,21 @@ export const executor = async (
return _programMemory return _programMemory
} }
const getSettingsState = import('components/GlobalStateProvider').then(
(module) => module.getSettingsState
)
export const _executor = async ( export const _executor = async (
node: Program, node: Program,
programMemory: ProgramMemory = { root: {}, return: null }, programMemory: ProgramMemory = { root: {}, return: null },
engineCommandManager: EngineCommandManager engineCommandManager: EngineCommandManager
): Promise<ProgramMemory> => { ): Promise<ProgramMemory> => {
try { try {
const baseUnit = (await getSettingsState)()?.baseUnit || 'mm'
const memory: ProgramMemory = await execute_wasm( const memory: ProgramMemory = await execute_wasm(
JSON.stringify(node), JSON.stringify(node),
JSON.stringify(programMemory), JSON.stringify(programMemory),
baseUnit,
engineCommandManager, engineCommandManager,
fileSystemManager fileSystemManager
) )

View File

@ -3,6 +3,10 @@ import { Themes, getSystemTheme, setThemeClass } from '../lib/theme'
import { CameraSystem } from 'lib/cameraControls' import { CameraSystem } from 'lib/cameraControls'
import { Models } from '@kittycad/lib' import { Models } from '@kittycad/lib'
const kclManagerPromise = import('lang/KclSingleton').then(
(module) => module.kclManager
)
export const DEFAULT_PROJECT_NAME = 'project-$nnn' export const DEFAULT_PROJECT_NAME = 'project-$nnn'
export enum UnitSystem { export enum UnitSystem {
@ -29,7 +33,7 @@ export const settingsMachine = createMachine(
id: 'Settings', id: 'Settings',
predictableActionArguments: true, predictableActionArguments: true,
context: { context: {
baseUnit: 'in' as BaseUnit, baseUnit: 'mm' as BaseUnit,
cameraControls: 'KittyCAD' as CameraSystem, cameraControls: 'KittyCAD' as CameraSystem,
defaultDirectory: '', defaultDirectory: '',
defaultProjectName: DEFAULT_PROJECT_NAME, defaultProjectName: DEFAULT_PROJECT_NAME,
@ -37,7 +41,7 @@ export const settingsMachine = createMachine(
showDebugPanel: false, showDebugPanel: false,
textWrapping: 'On' as Toggle, textWrapping: 'On' as Toggle,
theme: Themes.System, theme: Themes.System,
unitSystem: UnitSystem.Imperial, unitSystem: UnitSystem.Metric,
}, },
initial: 'idle', initial: 'idle',
states: { states: {
@ -47,13 +51,13 @@ export const settingsMachine = createMachine(
'Set Base Unit': { 'Set Base Unit': {
actions: [ actions: [
assign({ assign({
baseUnit: (_, event) => { baseUnit: (_, event) => event.data.baseUnit,
console.log('event', event)
return event.data.baseUnit
},
}), }),
'persistSettings', 'persistSettings',
'toastSuccess', 'toastSuccess',
async () => {
;(await kclManagerPromise).executeAst()
},
], ],
target: 'idle', target: 'idle',
internal: true, internal: true,
@ -134,6 +138,9 @@ export const settingsMachine = createMachine(
}), }),
'persistSettings', 'persistSettings',
'toastSuccess', 'toastSuccess',
async () => {
;(await kclManagerPromise).executeAst()
},
], ],
target: 'idle', target: 'idle',
internal: true, internal: true,

View File

@ -1948,9 +1948,9 @@ dependencies = [
[[package]] [[package]]
name = "kittycad" name = "kittycad"
version = "0.2.53" version = "0.2.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a086e1a1bbddb3b38959c0f0ce6de6b3a3b7566e38e0b7d5fb101e91911beed4" checksum = "13958174d876353f429ea8230dc92fe86f164819cea2e51bbf22e01a4c2a496e"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",

View File

@ -58,7 +58,7 @@ members = [
] ]
[workspace.dependencies] [workspace.dependencies]
kittycad = { version = "0.2.53", default-features = false, features = ["js", "requests"] } kittycad = { version = "0.2.54", default-features = false, features = ["js", "requests"] }
kittycad-execution-plan = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" } kittycad-execution-plan = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }
kittycad-execution-plan-traits = "0.1.10" kittycad-execution-plan-traits = "0.1.10"
kittycad-modeling-session = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" } kittycad-modeling-session = { git = "https://github.com/KittyCAD/modeling-api", branch = "main" }

View File

@ -13,7 +13,7 @@ use tower_lsp::lsp_types::{Position as LspPosition, Range as LspRange};
use crate::{ use crate::{
ast::types::{BodyItem, FunctionExpression, KclNone, Value}, ast::types::{BodyItem, FunctionExpression, KclNone, Value},
engine::EngineConnection, engine::{EngineConnection, EngineManager},
errors::{KclError, KclErrorDetails}, errors::{KclError, KclErrorDetails},
fs::FileManager, fs::FileManager,
std::{FunctionKind, StdLib}, std::{FunctionKind, StdLib},
@ -950,27 +950,30 @@ pub struct ExecutorContext {
pub engine: EngineConnection, pub engine: EngineConnection,
pub fs: FileManager, pub fs: FileManager,
pub stdlib: Arc<StdLib>, pub stdlib: Arc<StdLib>,
pub units: kittycad::types::UnitLength,
} }
impl ExecutorContext { impl ExecutorContext {
/// Create a new default executor context. /// Create a new default executor context.
#[cfg(test)] #[cfg(test)]
pub async fn new() -> Result<Self> { pub async fn new(units: kittycad::types::UnitLength) -> Result<Self> {
Ok(Self { Ok(Self {
engine: EngineConnection::new().await?, engine: EngineConnection::new().await?,
fs: FileManager::new(), fs: FileManager::new(),
stdlib: Arc::new(StdLib::new()), stdlib: Arc::new(StdLib::new()),
units,
}) })
} }
/// Create a new default executor context. /// Create a new default executor context.
#[cfg(not(test))] #[cfg(not(test))]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub async fn new(ws: reqwest::Upgraded) -> Result<Self> { pub async fn new(ws: reqwest::Upgraded, units: kittycad::types::UnitLength) -> Result<Self> {
Ok(Self { Ok(Self {
engine: EngineConnection::new(ws).await?, engine: EngineConnection::new(ws).await?,
fs: FileManager::new(), fs: FileManager::new(),
stdlib: Arc::new(StdLib::new()), stdlib: Arc::new(StdLib::new()),
units,
}) })
} }
} }
@ -983,6 +986,17 @@ pub async fn execute(
options: BodyType, options: BodyType,
ctx: &ExecutorContext, ctx: &ExecutorContext,
) -> Result<ProgramMemory, KclError> { ) -> Result<ProgramMemory, KclError> {
// Before we even start executing the program, set the units.
ctx.engine
.send_modeling_cmd(
uuid::Uuid::new_v4(),
SourceRange::default(),
kittycad::types::ModelingCmd::SetSceneUnits {
unit: ctx.units.clone(),
},
)
.await?;
let mut pipe_info = PipeInfo::default(); let mut pipe_info = PipeInfo::default();
// Iterate over the body of the program. // Iterate over the body of the program.
@ -1269,7 +1283,7 @@ mod tests {
let parser = crate::parser::Parser::new(tokens); let parser = crate::parser::Parser::new(tokens);
let program = parser.ast()?; let program = parser.ast()?;
let mut mem: ProgramMemory = Default::default(); let mut mem: ProgramMemory = Default::default();
let ctx = ExecutorContext::new().await?; let ctx = ExecutorContext::new(kittycad::types::UnitLength::Mm).await?;
let memory = execute(program, &mut mem, BodyType::Root, &ctx).await?; let memory = execute(program, &mut mem, BodyType::Root, &ctx).await?;
Ok(memory) Ok(memory)

View File

@ -772,3 +772,24 @@ pub fn get_tangent_point_from_previous_arc(
tangential_angle.to_radians().sin() * 10.0 + last_arc_end[1], tangential_angle.to_radians().sin() * 10.0 + last_arc_end[1],
] ]
} }
fn unit_length_to_mm(base_unit: kittycad::types::UnitLength) -> f64 {
match base_unit {
kittycad::types::UnitLength::Mm => 1.0,
kittycad::types::UnitLength::Cm => 10.0,
kittycad::types::UnitLength::M => 1000.0,
kittycad::types::UnitLength::In => 25.4,
kittycad::types::UnitLength::Ft => 304.8,
kittycad::types::UnitLength::Yd => 914.4,
}
}
pub fn get_camera_zoom_magnitude_per_unit_length(unit: kittycad::types::UnitLength) -> (f64, f64) {
let base_radius = 5.6_f64;
let cam_height_distance_ratio = 0.5_f64;
let length = unit_length_to_mm(unit) * base_radius * 20.0;
let ang = cam_height_distance_ratio.atan();
let x = ang.cos() * length;
let y = ang.sin() * length;
(x, y)
}

View File

@ -1,327 +1,7 @@
//! Wasm bindings for `kcl`. //! Wasm bindings for `kcl`.
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use std::sync::{Arc, RwLock}; mod wasm;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use futures::stream::TryStreamExt; pub use wasm::*;
use gloo_utils::format::JsValueSerdeExt;
#[cfg(target_arch = "wasm32")]
use tower_lsp::{LspService, Server};
use wasm_bindgen::prelude::*;
// wasm_bindgen wrapper for execute
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub async fn execute_wasm(
program_str: &str,
memory_str: &str,
engine_manager: kcl_lib::engine::conn_wasm::EngineCommandManager,
fs_manager: kcl_lib::fs::wasm::FileSystemManager,
) -> Result<JsValue, String> {
// deserialize the ast from a stringified json
use kcl_lib::executor::ExecutorContext;
let program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
let mut mem: kcl_lib::executor::ProgramMemory = serde_json::from_str(memory_str).map_err(|e| e.to_string())?;
let engine = kcl_lib::engine::EngineConnection::new(engine_manager)
.await
.map_err(|e| format!("{:?}", e))?;
let fs = kcl_lib::fs::FileManager::new(fs_manager);
let ctx = ExecutorContext {
engine,
fs,
stdlib: std::sync::Arc::new(kcl_lib::std::StdLib::new()),
};
let memory = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &ctx)
.await
.map_err(String::from)?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead.
JsValue::from_serde(&memory).map_err(|e| e.to_string())
}
// wasm_bindgen wrapper for execute
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub async fn modify_ast_for_sketch_wasm(
manager: kcl_lib::engine::conn_wasm::EngineCommandManager,
program_str: &str,
sketch_name: &str,
plane_type: &str,
sketch_id: &str,
) -> Result<JsValue, String> {
// deserialize the ast from a stringified json
let mut program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
let plane: kcl_lib::executor::PlaneType = serde_json::from_str(plane_type).map_err(|e| e.to_string())?;
let mut engine = kcl_lib::engine::EngineConnection::new(manager)
.await
.map_err(|e| format!("{:?}", e))?;
let _ = kcl_lib::ast::modify::modify_ast_for_sketch(
&mut engine,
&mut program,
sketch_name,
plane,
uuid::Uuid::parse_str(sketch_id).map_err(|e| e.to_string())?,
)
.await
.map_err(String::from)?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead.
JsValue::from_serde(&program).map_err(|e| e.to_string())
}
#[wasm_bindgen]
pub fn deserialize_files(data: &[u8]) -> Result<JsValue, JsError> {
let ws_resp: kittycad::types::WebSocketResponse = bson::from_slice(data)?;
if let Some(success) = ws_resp.success {
if !success {
return Err(JsError::new(&format!("Server returned error: {:?}", ws_resp.errors)));
}
}
if let Some(kittycad::types::OkWebSocketResponseData::Export { files }) = ws_resp.resp {
return Ok(JsValue::from_serde(&files)?);
}
Err(JsError::new(&format!("Invalid response type, got: {:?}", ws_resp)))
}
// wasm_bindgen wrapper for lexer
// test for this function and by extension lexer are done in javascript land src/lang/tokeniser.test.ts
#[wasm_bindgen]
pub fn lexer_wasm(js: &str) -> Result<JsValue, JsError> {
let tokens = kcl_lib::token::lexer(js);
Ok(JsValue::from_serde(&tokens)?)
}
#[wasm_bindgen]
pub fn parse_wasm(js: &str) -> Result<JsValue, String> {
let tokens = kcl_lib::token::lexer(js);
let parser = kcl_lib::parser::Parser::new(tokens);
let program = parser.ast().map_err(String::from)?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead.
JsValue::from_serde(&program).map_err(|e| e.to_string())
}
// wasm_bindgen wrapper for recast
// test for this function and by extension the recaster are done in javascript land src/lang/recast.test.ts
#[wasm_bindgen]
pub fn recast_wasm(json_str: &str) -> Result<JsValue, JsError> {
// deserialize the ast from a stringified json
let program: kcl_lib::ast::types::Program = serde_json::from_str(json_str).map_err(JsError::from)?;
// Use the default options until we integrate into the UI the ability to change them.
let result = program.recast(&Default::default(), 0);
Ok(JsValue::from_serde(&result)?)
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub struct ServerConfig {
into_server: js_sys::AsyncIterator,
from_server: web_sys::WritableStream,
fs: kcl_lib::fs::wasm::FileSystemManager,
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
impl ServerConfig {
#[wasm_bindgen(constructor)]
pub fn new(
into_server: js_sys::AsyncIterator,
from_server: web_sys::WritableStream,
fs: kcl_lib::fs::wasm::FileSystemManager,
) -> Self {
Self {
into_server,
from_server,
fs,
}
}
}
/// Run the `kcl` lsp server.
//
// NOTE: we don't use web_sys::ReadableStream for input here because on the
// browser side we need to use a ReadableByteStreamController to construct it
// and so far only Chromium-based browsers support that functionality.
// NOTE: input needs to be an AsyncIterator<Uint8Array, never, void> specifically
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub async fn kcl_lsp_run(config: ServerConfig) -> Result<(), JsValue> {
let ServerConfig {
into_server,
from_server,
fs,
} = config;
let stdlib = kcl_lib::std::StdLib::new();
let stdlib_completions = kcl_lib::lsp::kcl::get_completions_from_stdlib(&stdlib).map_err(|e| e.to_string())?;
let stdlib_signatures = kcl_lib::lsp::kcl::get_signatures_from_stdlib(&stdlib).map_err(|e| e.to_string())?;
// We can unwrap here because we know the tokeniser is valid, since
// we have a test for it.
let token_types = kcl_lib::token::TokenType::all_semantic_token_types().unwrap();
let (service, socket) = LspService::new(|client| kcl_lib::lsp::kcl::Backend {
client,
fs: kcl_lib::fs::FileManager::new(fs),
stdlib_completions,
stdlib_signatures,
token_types,
token_map: Default::default(),
ast_map: Default::default(),
current_code_map: Default::default(),
diagnostics_map: Default::default(),
symbols_map: Default::default(),
semantic_tokens_map: Default::default(),
});
let input = wasm_bindgen_futures::stream::JsStream::from(into_server);
let input = input
.map_ok(|value| {
value
.dyn_into::<js_sys::Uint8Array>()
.expect("could not cast stream item to Uint8Array")
.to_vec()
})
.map_err(|_err| std::io::Error::from(std::io::ErrorKind::Other))
.into_async_read();
let output = wasm_bindgen::JsCast::unchecked_into::<wasm_streams::writable::sys::WritableStream>(from_server);
let output = wasm_streams::WritableStream::from_raw(output);
let output = output.try_into_async_write().map_err(|err| err.0)?;
Server::new(input, output, socket).serve(service).await;
Ok(())
}
/// Run the `copilot` lsp server.
//
// NOTE: we don't use web_sys::ReadableStream for input here because on the
// browser side we need to use a ReadableByteStreamController to construct it
// and so far only Chromium-based browsers support that functionality.
// NOTE: input needs to be an AsyncIterator<Uint8Array, never, void> specifically
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub async fn copilot_lsp_run(config: ServerConfig, token: String) -> Result<(), JsValue> {
let ServerConfig {
into_server,
from_server,
fs,
} = config;
let (service, socket) = LspService::build(|client| kcl_lib::lsp::copilot::Backend {
client,
fs: kcl_lib::fs::FileManager::new(fs),
current_code_map: Default::default(),
editor_info: Arc::new(RwLock::new(kcl_lib::lsp::copilot::types::CopilotEditorInfo::default())),
cache: kcl_lib::lsp::copilot::cache::CopilotCache::new(),
token,
})
.custom_method("setEditorInfo", kcl_lib::lsp::copilot::Backend::set_editor_info)
.custom_method(
"getCompletions",
kcl_lib::lsp::copilot::Backend::get_completions_cycling,
)
.custom_method("notifyAccepted", kcl_lib::lsp::copilot::Backend::accept_completions)
.custom_method("notifyRejected", kcl_lib::lsp::copilot::Backend::reject_completions)
.finish();
let input = wasm_bindgen_futures::stream::JsStream::from(into_server);
let input = input
.map_ok(|value| {
value
.dyn_into::<js_sys::Uint8Array>()
.expect("could not cast stream item to Uint8Array")
.to_vec()
})
.map_err(|_err| std::io::Error::from(std::io::ErrorKind::Other))
.into_async_read();
let output = wasm_bindgen::JsCast::unchecked_into::<wasm_streams::writable::sys::WritableStream>(from_server);
let output = wasm_streams::WritableStream::from_raw(output);
let output = output.try_into_async_write().map_err(|err| err.0)?;
Server::new(input, output, socket).serve(service).await;
Ok(())
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub fn is_points_ccw(points: &[f64]) -> i32 {
kcl_lib::std::utils::is_points_ccw_wasm(points)
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub struct TangentialArcInfoOutputWasm {
/// The geometric center of the arc x.
pub center_x: f64,
/// The geometric center of the arc y.
pub center_y: f64,
/// The midpoint of the arc x.
pub arc_mid_point_x: f64,
/// The midpoint of the arc y.
pub arc_mid_point_y: f64,
/// The radius of the arc.
pub radius: f64,
/// Start angle of the arc in radians.
pub start_angle: f64,
/// End angle of the arc in radians.
pub end_angle: f64,
/// Flag to determine if the arc is counter clockwise.
pub ccw: i32,
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub fn get_tangential_arc_to_info(
arc_start_point_x: f64,
arc_start_point_y: f64,
arc_end_point_x: f64,
arc_end_point_y: f64,
tan_previous_point_x: f64,
tan_previous_point_y: f64,
obtuse: bool,
) -> TangentialArcInfoOutputWasm {
let result = kcl_lib::std::utils::get_tangential_arc_to_info(kcl_lib::std::utils::TangentialArcInfoInput {
arc_start_point: [arc_start_point_x, arc_start_point_y],
arc_end_point: [arc_end_point_x, arc_end_point_y],
tan_previous_point: [tan_previous_point_x, tan_previous_point_y],
obtuse: obtuse,
});
TangentialArcInfoOutputWasm {
center_x: result.center[0],
center_y: result.center[1],
arc_mid_point_x: result.arc_mid_point[0],
arc_mid_point_y: result.arc_mid_point[1],
radius: result.radius,
start_angle: result.start_angle,
end_angle: result.end_angle,
ccw: result.ccw,
}
}
/// Create the default program memory.
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub fn program_memory_init() -> Result<JsValue, String> {
let memory = kcl_lib::executor::ProgramMemory::default();
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead.
JsValue::from_serde(&memory).map_err(|e| e.to_string())
}

320
src/wasm-lib/src/wasm.rs Normal file
View File

@ -0,0 +1,320 @@
//! Wasm bindings for `kcl`.
use std::{
str::FromStr,
sync::{Arc, RwLock},
};
use futures::stream::TryStreamExt;
use gloo_utils::format::JsValueSerdeExt;
use tower_lsp::{LspService, Server};
use wasm_bindgen::prelude::*;
// wasm_bindgen wrapper for execute
#[wasm_bindgen]
pub async fn execute_wasm(
program_str: &str,
memory_str: &str,
units: &str,
engine_manager: kcl_lib::engine::conn_wasm::EngineCommandManager,
fs_manager: kcl_lib::fs::wasm::FileSystemManager,
) -> Result<JsValue, String> {
// deserialize the ast from a stringified json
use kcl_lib::executor::ExecutorContext;
let program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
let mut mem: kcl_lib::executor::ProgramMemory = serde_json::from_str(memory_str).map_err(|e| e.to_string())?;
let units = kittycad::types::UnitLength::from_str(units).map_err(|e| e.to_string())?;
let engine = kcl_lib::engine::EngineConnection::new(engine_manager)
.await
.map_err(|e| format!("{:?}", e))?;
let fs = kcl_lib::fs::FileManager::new(fs_manager);
let ctx = ExecutorContext {
engine,
fs,
stdlib: std::sync::Arc::new(kcl_lib::std::StdLib::new()),
units,
};
let memory = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &ctx)
.await
.map_err(String::from)?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead.
JsValue::from_serde(&memory).map_err(|e| e.to_string())
}
// wasm_bindgen wrapper for execute
#[wasm_bindgen]
pub async fn modify_ast_for_sketch_wasm(
manager: kcl_lib::engine::conn_wasm::EngineCommandManager,
program_str: &str,
sketch_name: &str,
plane_type: &str,
sketch_id: &str,
) -> Result<JsValue, String> {
// deserialize the ast from a stringified json
let mut program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
let plane: kcl_lib::executor::PlaneType = serde_json::from_str(plane_type).map_err(|e| e.to_string())?;
let mut engine = kcl_lib::engine::EngineConnection::new(manager)
.await
.map_err(|e| format!("{:?}", e))?;
let _ = kcl_lib::ast::modify::modify_ast_for_sketch(
&mut engine,
&mut program,
sketch_name,
plane,
uuid::Uuid::parse_str(sketch_id).map_err(|e| e.to_string())?,
)
.await
.map_err(String::from)?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead.
JsValue::from_serde(&program).map_err(|e| e.to_string())
}
#[wasm_bindgen]
pub fn deserialize_files(data: &[u8]) -> Result<JsValue, JsError> {
let ws_resp: kittycad::types::WebSocketResponse = bson::from_slice(data)?;
if let Some(success) = ws_resp.success {
if !success {
return Err(JsError::new(&format!("Server returned error: {:?}", ws_resp.errors)));
}
}
if let Some(kittycad::types::OkWebSocketResponseData::Export { files }) = ws_resp.resp {
return Ok(JsValue::from_serde(&files)?);
}
Err(JsError::new(&format!("Invalid response type, got: {:?}", ws_resp)))
}
// wasm_bindgen wrapper for lexer
// test for this function and by extension lexer are done in javascript land src/lang/tokeniser.test.ts
#[wasm_bindgen]
pub fn lexer_wasm(js: &str) -> Result<JsValue, JsError> {
let tokens = kcl_lib::token::lexer(js);
Ok(JsValue::from_serde(&tokens)?)
}
#[wasm_bindgen]
pub fn parse_wasm(js: &str) -> Result<JsValue, String> {
let tokens = kcl_lib::token::lexer(js);
let parser = kcl_lib::parser::Parser::new(tokens);
let program = parser.ast().map_err(String::from)?;
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead.
JsValue::from_serde(&program).map_err(|e| e.to_string())
}
// wasm_bindgen wrapper for recast
// test for this function and by extension the recaster are done in javascript land src/lang/recast.test.ts
#[wasm_bindgen]
pub fn recast_wasm(json_str: &str) -> Result<JsValue, JsError> {
// deserialize the ast from a stringified json
let program: kcl_lib::ast::types::Program = serde_json::from_str(json_str).map_err(JsError::from)?;
// Use the default options until we integrate into the UI the ability to change them.
let result = program.recast(&Default::default(), 0);
Ok(JsValue::from_serde(&result)?)
}
#[wasm_bindgen]
pub struct ServerConfig {
into_server: js_sys::AsyncIterator,
from_server: web_sys::WritableStream,
fs: kcl_lib::fs::wasm::FileSystemManager,
}
#[wasm_bindgen]
impl ServerConfig {
#[wasm_bindgen(constructor)]
pub fn new(
into_server: js_sys::AsyncIterator,
from_server: web_sys::WritableStream,
fs: kcl_lib::fs::wasm::FileSystemManager,
) -> Self {
Self {
into_server,
from_server,
fs,
}
}
}
/// Run the `kcl` lsp server.
//
// NOTE: we don't use web_sys::ReadableStream for input here because on the
// browser side we need to use a ReadableByteStreamController to construct it
// and so far only Chromium-based browsers support that functionality.
// NOTE: input needs to be an AsyncIterator<Uint8Array, never, void> specifically
#[wasm_bindgen]
pub async fn kcl_lsp_run(config: ServerConfig) -> Result<(), JsValue> {
let ServerConfig {
into_server,
from_server,
fs,
} = config;
let stdlib = kcl_lib::std::StdLib::new();
let stdlib_completions = kcl_lib::lsp::kcl::get_completions_from_stdlib(&stdlib).map_err(|e| e.to_string())?;
let stdlib_signatures = kcl_lib::lsp::kcl::get_signatures_from_stdlib(&stdlib).map_err(|e| e.to_string())?;
// We can unwrap here because we know the tokeniser is valid, since
// we have a test for it.
let token_types = kcl_lib::token::TokenType::all_semantic_token_types().unwrap();
let (service, socket) = LspService::new(|client| kcl_lib::lsp::kcl::Backend {
client,
fs: kcl_lib::fs::FileManager::new(fs),
stdlib_completions,
stdlib_signatures,
token_types,
token_map: Default::default(),
ast_map: Default::default(),
current_code_map: Default::default(),
diagnostics_map: Default::default(),
symbols_map: Default::default(),
semantic_tokens_map: Default::default(),
});
let input = wasm_bindgen_futures::stream::JsStream::from(into_server);
let input = input
.map_ok(|value| {
value
.dyn_into::<js_sys::Uint8Array>()
.expect("could not cast stream item to Uint8Array")
.to_vec()
})
.map_err(|_err| std::io::Error::from(std::io::ErrorKind::Other))
.into_async_read();
let output = wasm_bindgen::JsCast::unchecked_into::<wasm_streams::writable::sys::WritableStream>(from_server);
let output = wasm_streams::WritableStream::from_raw(output);
let output = output.try_into_async_write().map_err(|err| err.0)?;
Server::new(input, output, socket).serve(service).await;
Ok(())
}
/// Run the `copilot` lsp server.
//
// NOTE: we don't use web_sys::ReadableStream for input here because on the
// browser side we need to use a ReadableByteStreamController to construct it
// and so far only Chromium-based browsers support that functionality.
// NOTE: input needs to be an AsyncIterator<Uint8Array, never, void> specifically
#[wasm_bindgen]
pub async fn copilot_lsp_run(config: ServerConfig, token: String) -> Result<(), JsValue> {
let ServerConfig {
into_server,
from_server,
fs,
} = config;
let (service, socket) = LspService::build(|client| kcl_lib::lsp::copilot::Backend {
client,
fs: kcl_lib::fs::FileManager::new(fs),
current_code_map: Default::default(),
editor_info: Arc::new(RwLock::new(kcl_lib::lsp::copilot::types::CopilotEditorInfo::default())),
cache: kcl_lib::lsp::copilot::cache::CopilotCache::new(),
token,
})
.custom_method("setEditorInfo", kcl_lib::lsp::copilot::Backend::set_editor_info)
.custom_method(
"getCompletions",
kcl_lib::lsp::copilot::Backend::get_completions_cycling,
)
.custom_method("notifyAccepted", kcl_lib::lsp::copilot::Backend::accept_completions)
.custom_method("notifyRejected", kcl_lib::lsp::copilot::Backend::reject_completions)
.finish();
let input = wasm_bindgen_futures::stream::JsStream::from(into_server);
let input = input
.map_ok(|value| {
value
.dyn_into::<js_sys::Uint8Array>()
.expect("could not cast stream item to Uint8Array")
.to_vec()
})
.map_err(|_err| std::io::Error::from(std::io::ErrorKind::Other))
.into_async_read();
let output = wasm_bindgen::JsCast::unchecked_into::<wasm_streams::writable::sys::WritableStream>(from_server);
let output = wasm_streams::WritableStream::from_raw(output);
let output = output.try_into_async_write().map_err(|err| err.0)?;
Server::new(input, output, socket).serve(service).await;
Ok(())
}
#[wasm_bindgen]
pub fn is_points_ccw(points: &[f64]) -> i32 {
kcl_lib::std::utils::is_points_ccw_wasm(points)
}
#[wasm_bindgen]
pub struct TangentialArcInfoOutputWasm {
/// The geometric center of the arc x.
pub center_x: f64,
/// The geometric center of the arc y.
pub center_y: f64,
/// The midpoint of the arc x.
pub arc_mid_point_x: f64,
/// The midpoint of the arc y.
pub arc_mid_point_y: f64,
/// The radius of the arc.
pub radius: f64,
/// Start angle of the arc in radians.
pub start_angle: f64,
/// End angle of the arc in radians.
pub end_angle: f64,
/// Flag to determine if the arc is counter clockwise.
pub ccw: i32,
}
#[wasm_bindgen]
pub fn get_tangential_arc_to_info(
arc_start_point_x: f64,
arc_start_point_y: f64,
arc_end_point_x: f64,
arc_end_point_y: f64,
tan_previous_point_x: f64,
tan_previous_point_y: f64,
obtuse: bool,
) -> TangentialArcInfoOutputWasm {
let result = kcl_lib::std::utils::get_tangential_arc_to_info(kcl_lib::std::utils::TangentialArcInfoInput {
arc_start_point: [arc_start_point_x, arc_start_point_y],
arc_end_point: [arc_end_point_x, arc_end_point_y],
tan_previous_point: [tan_previous_point_x, tan_previous_point_y],
obtuse: obtuse,
});
TangentialArcInfoOutputWasm {
center_x: result.center[0],
center_y: result.center[1],
arc_mid_point_x: result.arc_mid_point[0],
arc_mid_point_y: result.arc_mid_point[1],
radius: result.radius,
start_angle: result.start_angle,
end_angle: result.end_angle,
ccw: result.ccw,
}
}
/// Create the default program memory.
#[wasm_bindgen]
pub fn program_memory_init() -> Result<JsValue, String> {
let memory = kcl_lib::executor::ProgramMemory::default();
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
// gloo-serialize crate instead.
JsValue::from_serde(&memory).map_err(|e| e.to_string())
}

View File

@ -3,7 +3,7 @@ use kcl_lib::engine::EngineManager;
/// Executes a kcl program and takes a snapshot of the result. /// Executes a kcl program and takes a snapshot of the result.
/// This returns the bytes of the snapshot. /// This returns the bytes of the snapshot.
async fn execute_and_snapshot(code: &str) -> Result<image::DynamicImage> { async fn execute_and_snapshot(code: &str, units: kittycad::types::UnitLength) -> Result<image::DynamicImage> {
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),); let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
let http_client = reqwest::Client::builder() let http_client = reqwest::Client::builder()
.user_agent(user_agent) .user_agent(user_agent)
@ -38,9 +38,25 @@ async fn execute_and_snapshot(code: &str) -> Result<image::DynamicImage> {
let parser = kcl_lib::parser::Parser::new(tokens); let parser = kcl_lib::parser::Parser::new(tokens);
let program = parser.ast()?; let program = parser.ast()?;
let mut mem: kcl_lib::executor::ProgramMemory = Default::default(); let mut mem: kcl_lib::executor::ProgramMemory = Default::default();
let ctx = kcl_lib::executor::ExecutorContext::new(ws).await?; let ctx = kcl_lib::executor::ExecutorContext::new(ws, units.clone()).await?;
let _ = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &ctx).await?; let _ = kcl_lib::executor::execute(program, &mut mem, kcl_lib::executor::BodyType::Root, &ctx).await?;
let (x, y) = kcl_lib::std::utils::get_camera_zoom_magnitude_per_unit_length(units);
ctx.engine
.send_modeling_cmd(
uuid::Uuid::new_v4(),
kcl_lib::executor::SourceRange::default(),
kittycad::types::ModelingCmd::DefaultCameraLookAt {
center: kittycad::types::Point3D { x: 0.0, y: 0.0, z: 0.0 },
up: kittycad::types::Point3D { x: 0.0, y: 0.0, z: 1.0 },
vantage: kittycad::types::Point3D { x: 0.0, y: -x, z: y },
sequence: None,
},
)
.await?;
// Send a snapshot request to the engine. // Send a snapshot request to the engine.
let resp = ctx let resp = ctx
.engine .engine
@ -87,7 +103,9 @@ const part002 = startSketchOn(part001, "here")
|> extrude(5, %) |> extrude(5, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face.png", &result, 0.999);
} }
@ -115,7 +133,9 @@ const part002 = startSketchOn(part001, "start")
|> extrude(5, %) |> extrude(5, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face_start.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face_start.png", &result, 0.999);
} }
@ -143,7 +163,9 @@ const part002 = startSketchOn(part001, "END")
|> extrude(5, %) |> extrude(5, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face_end.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/sketch_on_face_end.png", &result, 0.999);
} }
@ -162,10 +184,11 @@ async fn serial_test_execute_with_function_sketch() {
} }
const fnBox = box(3, 6, 10) const fnBox = box(3, 6, 10)
"#;
show(fnBox)"#; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
let result = execute_and_snapshot(code).await.unwrap(); .unwrap();
twenty_twenty::assert_image("tests/executor/outputs/function_sketch.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/function_sketch.png", &result, 0.999);
} }
@ -183,9 +206,11 @@ async fn serial_test_execute_with_function_sketch_with_position() {
return myBox return myBox
} }
show(box([0,0], 3, 6, 10))"#; const thing = box([0,0], 3, 6, 10)"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image( twenty_twenty::assert_image(
"tests/executor/outputs/function_sketch_with_position.png", "tests/executor/outputs/function_sketch_with_position.png",
&result, &result,
@ -204,10 +229,11 @@ async fn serial_test_execute_with_angled_line() {
|> line([-13.02, 10.03], %) |> line([-13.02, 10.03], %)
|> close(%) |> close(%)
|> extrude(4, %) |> extrude(4, %)
"#;
show(part001)"#; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
let result = execute_and_snapshot(code).await.unwrap(); .unwrap();
twenty_twenty::assert_image("tests/executor/outputs/angled_line.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/angled_line.png", &result, 0.999);
} }
@ -231,10 +257,11 @@ const bracket = startSketchOn('XY')
|> line([0, -leg1 + thickness], %) |> line([0, -leg1 + thickness], %)
|> close(%) |> close(%)
|> extrude(width, %) |> extrude(width, %)
"#;
show(bracket)"#; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
let result = execute_and_snapshot(code).await.unwrap(); .unwrap();
twenty_twenty::assert_image("tests/executor/outputs/parametric.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/parametric.png", &result, 0.999);
} }
@ -266,10 +293,11 @@ const bracket = startSketchAt([0, 0])
|> line([0, -wallMountL], %) |> line([0, -wallMountL], %)
|> close(%) |> close(%)
|> extrude(width, %) |> extrude(width, %)
"#;
show(bracket)"#; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
let result = execute_and_snapshot(code).await.unwrap(); .unwrap();
twenty_twenty::assert_image("tests/executor/outputs/parametric_with_tan_arc.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/parametric_with_tan_arc.png", &result, 0.999);
} }
@ -284,7 +312,7 @@ async fn serial_test_execute_engine_error_return() {
|> extrude(4, %) |> extrude(4, %)
"#; "#;
let result = execute_and_snapshot(code).await; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm).await;
assert!(result.is_err()); assert!(result.is_err());
assert_eq!( assert_eq!(
result.err().unwrap().to_string(), result.err().unwrap().to_string(),
@ -297,7 +325,9 @@ async fn serial_test_execute_engine_error_return() {
async fn serial_test_execute_pipes_on_pipes() { async fn serial_test_execute_pipes_on_pipes() {
let code = include_str!("inputs/pipes_on_pipes.kcl"); let code = include_str!("inputs/pipes_on_pipes.kcl");
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/pipes_on_pipes.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/pipes_on_pipes.png", &result, 0.999);
} }
@ -305,7 +335,9 @@ async fn serial_test_execute_pipes_on_pipes() {
async fn serial_test_execute_cylinder() { async fn serial_test_execute_cylinder() {
let code = include_str!("inputs/cylinder.kcl"); let code = include_str!("inputs/cylinder.kcl");
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/cylinder.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/cylinder.png", &result, 0.999);
} }
@ -314,7 +346,9 @@ async fn serial_test_execute_cylinder() {
async fn serial_test_execute_kittycad_svg() { async fn serial_test_execute_kittycad_svg() {
let code = include_str!("inputs/kittycad_svg.kcl"); let code = include_str!("inputs/kittycad_svg.kcl");
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/kittycad_svg.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/kittycad_svg.png", &result, 0.999);
} }
@ -335,11 +369,11 @@ const b2 = cube([3,3], 4)
const pt1 = b1.value[0] const pt1 = b1.value[0]
const pt2 = b2.value[0] const pt2 = b2.value[0]
"#;
show(b1) let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
show(b2)"#; .await
.unwrap();
let result = execute_and_snapshot(code).await.unwrap();
twenty_twenty::assert_image( twenty_twenty::assert_image(
"tests/executor/outputs/member_expression_sketch_group.png", "tests/executor/outputs/member_expression_sketch_group.png",
&result, &result,
@ -358,10 +392,11 @@ const body = startSketchOn('XY')
|> arc({angle_end: 360, angle_start: 0, radius: radius}, %) |> arc({angle_end: 360, angle_start: 0, radius: radius}, %)
|> close(%) |> close(%)
|> extrude(height, %) |> extrude(height, %)
"#;
show(body)"#; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
let result = execute_and_snapshot(code).await.unwrap(); .unwrap();
twenty_twenty::assert_image("tests/executor/outputs/close_arc.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/close_arc.png", &result, 0.999);
} }
@ -387,7 +422,9 @@ box(10, 23, 8)
let thing = box(-12, -15, 10) let thing = box(-12, -15, 10)
box(-20, -5, 10)"#; box(-20, -5, 10)"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/negative_args.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/negative_args.png", &result, 0.999);
} }
@ -400,7 +437,9 @@ async fn serial_test_basic_tangential_arc() {
|> extrude(10, %) |> extrude(10, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/tangential_arc.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/tangential_arc.png", &result, 0.999);
} }
@ -413,7 +452,9 @@ async fn serial_test_basic_tangential_arc_with_point() {
|> extrude(10, %) |> extrude(10, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/tangential_arc_with_point.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/tangential_arc_with_point.png", &result, 0.999);
} }
@ -426,7 +467,9 @@ async fn serial_test_basic_tangential_arc_to() {
|> extrude(10, %) |> extrude(10, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/tangential_arc_to.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/tangential_arc_to.png", &result, 0.999);
} }
@ -453,7 +496,9 @@ box(30, 43, 18, '-xy')
let thing = box(-12, -15, 10, 'yz') let thing = box(-12, -15, 10, 'yz')
box(-20, -5, 10, 'xy')"#; box(-20, -5, 10, 'xy')"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image( twenty_twenty::assert_image(
"tests/executor/outputs/different_planes_same_drawing.png", "tests/executor/outputs/different_planes_same_drawing.png",
&result, &result,
@ -488,7 +533,6 @@ const bracket = startSketchOn('XY')
|> close(%) |> close(%)
|> extrude(width, %) |> extrude(width, %)
show(bracket)
const part001 = startSketchOn('XY') const part001 = startSketchOn('XY')
|> startProfileAt([-15.53, -10.28], %) |> startProfileAt([-15.53, -10.28], %)
|> line([10.49, -2.08], %) |> line([10.49, -2.08], %)
@ -516,7 +560,9 @@ const part004 = startSketchOn('YZ')
|> close(%) |> close(%)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/lots_of_planes.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/lots_of_planes.png", &result, 0.999);
} }
@ -540,11 +586,11 @@ const square = startSketchOn('XY')
|> hole(circle([2, 2], .5), %) |> hole(circle([2, 2], .5), %)
|> hole(circle([2, 8], .5), %) |> hole(circle([2, 8], .5), %)
|> extrude(2, %) |> extrude(2, %)
show(square)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/holes.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/holes.png", &result, 0.999);
} }
@ -560,9 +606,11 @@ async fn optional_params() {
return sg return sg
} }
show(circle([2, 2], 20)) const thing = circle([2, 2], 20)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/optional_params.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/optional_params.png", &result, 0.999);
} }
@ -608,10 +656,11 @@ const part = roundedRectangle([0, 0], 20, 20, 4)
|> hole(circle([-holeIndex, -holeIndex], holeRadius), %) |> hole(circle([-holeIndex, -holeIndex], holeRadius), %)
|> hole(circle([holeIndex, -holeIndex], holeRadius), %) |> hole(circle([holeIndex, -holeIndex], holeRadius), %)
|> extrude(2, %) |> extrude(2, %)
"#;
show(part)"#; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
let result = execute_and_snapshot(code).await.unwrap(); .unwrap();
twenty_twenty::assert_image("tests/executor/outputs/rounded_with_holes.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/rounded_with_holes.png", &result, 0.999);
} }
@ -631,7 +680,9 @@ async fn serial_test_top_level_expression() {
circle([0,0], 22) |> extrude(14, %)"#; circle([0,0], 22) |> extrude(14, %)"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/top_level_expression.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/top_level_expression.png", &result, 0.999);
} }
@ -653,7 +704,9 @@ const part = circle([0,0], 2)
|> patternLinear({axis: [0,0,1], repetitions: 12, distance: 2}, %) |> patternLinear({axis: [0,0,1], repetitions: 12, distance: 2}, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/patterns_linear_basic.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/patterns_linear_basic.png", &result, 0.999);
} }
@ -681,7 +734,9 @@ const part = startSketchOn('XY')
|> patternLinear({axis: [1, 0,1], repetitions: 3, distance: 6}, %) |> patternLinear({axis: [1, 0,1], repetitions: 3, distance: 6}, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/patterns_linear_basic_3d.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/patterns_linear_basic_3d.png", &result, 0.999);
} }
@ -703,7 +758,9 @@ const part = circle([0,0], 2)
|> patternLinear({axis: [0,0,1], repetitions: 12, distance: -2}, %) |> patternLinear({axis: [0,0,1], repetitions: 12, distance: -2}, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image( twenty_twenty::assert_image(
"tests/executor/outputs/patterns_linear_basic_negative_distance.png", "tests/executor/outputs/patterns_linear_basic_negative_distance.png",
&result, &result,
@ -729,7 +786,9 @@ const part = circle([0,0], 2)
|> patternLinear({axis: [0,0,-1], repetitions: 12, distance: 2}, %) |> patternLinear({axis: [0,0,-1], repetitions: 12, distance: 2}, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image( twenty_twenty::assert_image(
"tests/executor/outputs/patterns_linear_basic_negative_axis.png", "tests/executor/outputs/patterns_linear_basic_negative_axis.png",
&result, &result,
@ -764,7 +823,9 @@ const rectangle = startSketchOn('XY')
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/patterns_linear_basic_holes.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/patterns_linear_basic_holes.png", &result, 0.999);
} }
@ -786,7 +847,9 @@ const part = circle([0,0], 2)
|> patternCircular({axis: [0,0,1], center: [20, 20, 20], repetitions: 12, arcDegrees: 210, rotateDuplicates: true}, %) |> patternCircular({axis: [0,0,1], center: [20, 20, 20], repetitions: 12, arcDegrees: 210, rotateDuplicates: true}, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/patterns_circular_basic_2d.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/patterns_circular_basic_2d.png", &result, 0.999);
} }
@ -814,7 +877,9 @@ const part = startSketchOn('XY')
|> patternCircular({axis: [0,1,0], center: [-20, -20, -20], repetitions: 40, arcDegrees: 360, rotateDuplicates: false}, %) |> patternCircular({axis: [0,1,0], center: [-20, -20, -20], repetitions: 40, arcDegrees: 360, rotateDuplicates: false}, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/patterns_circular_basic_3d.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/patterns_circular_basic_3d.png", &result, 0.999);
} }
@ -842,7 +907,9 @@ const part = startSketchOn('XY')
|> patternCircular({axis: [1,1,-1], center: [10, 0, 10], repetitions: 10, arcDegrees: 360, rotateDuplicates: true}, %) |> patternCircular({axis: [1,1,-1], center: [10, 0, 10], repetitions: 10, arcDegrees: 360, rotateDuplicates: true}, %)
"#; "#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image( twenty_twenty::assert_image(
"tests/executor/outputs/patterns_circular_3d_tilted_axis.png", "tests/executor/outputs/patterns_circular_3d_tilted_axis.png",
&result, &result,
@ -854,7 +921,7 @@ const part = startSketchOn('XY')
async fn serial_test_import_file_doesnt_exist() { async fn serial_test_import_file_doesnt_exist() {
let code = r#"const model = import("thing.obj")"#; let code = r#"const model = import("thing.obj")"#;
let result = execute_and_snapshot(code).await; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm).await;
assert!(result.is_err()); assert!(result.is_err());
assert_eq!( assert_eq!(
result.err().unwrap().to_string(), result.err().unwrap().to_string(),
@ -866,7 +933,9 @@ async fn serial_test_import_file_doesnt_exist() {
async fn serial_test_import_obj_with_mtl() { async fn serial_test_import_obj_with_mtl() {
let code = r#"const model = import("tests/executor/inputs/cube.obj")"#; let code = r#"const model = import("tests/executor/inputs/cube.obj")"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/import_obj_with_mtl.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/import_obj_with_mtl.png", &result, 0.999);
} }
@ -874,7 +943,9 @@ async fn serial_test_import_obj_with_mtl() {
async fn serial_test_import_obj_with_mtl_units() { async fn serial_test_import_obj_with_mtl_units() {
let code = r#"const model = import("tests/executor/inputs/cube.obj", {type: "obj", units: "m"})"#; let code = r#"const model = import("tests/executor/inputs/cube.obj", {type: "obj", units: "m"})"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/import_obj_with_mtl_units.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/import_obj_with_mtl_units.png", &result, 0.999);
} }
@ -882,7 +953,9 @@ async fn serial_test_import_obj_with_mtl_units() {
async fn serial_test_import_gltf_with_bin() { async fn serial_test_import_gltf_with_bin() {
let code = r#"const model = import("tests/executor/inputs/cube.gltf")"#; let code = r#"const model = import("tests/executor/inputs/cube.gltf")"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/import_gltf_with_bin.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/import_gltf_with_bin.png", &result, 0.999);
} }
@ -890,7 +963,9 @@ async fn serial_test_import_gltf_with_bin() {
async fn serial_test_import_gltf_embedded() { async fn serial_test_import_gltf_embedded() {
let code = r#"const model = import("tests/executor/inputs/cube-embedded.gltf")"#; let code = r#"const model = import("tests/executor/inputs/cube-embedded.gltf")"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/import_gltf_embedded.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/import_gltf_embedded.png", &result, 0.999);
} }
@ -898,7 +973,9 @@ async fn serial_test_import_gltf_embedded() {
async fn serial_test_import_glb() { async fn serial_test_import_glb() {
let code = r#"const model = import("tests/executor/inputs/cube.glb")"#; let code = r#"const model = import("tests/executor/inputs/cube.glb")"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/import_glb.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/import_glb.png", &result, 0.999);
} }
@ -906,7 +983,9 @@ async fn serial_test_import_glb() {
async fn serial_test_import_glb_no_assign() { async fn serial_test_import_glb_no_assign() {
let code = r#"import("tests/executor/inputs/cube.glb")"#; let code = r#"import("tests/executor/inputs/cube.glb")"#;
let result = execute_and_snapshot(code).await.unwrap(); let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/import_glb_no_assign.png", &result, 0.999); twenty_twenty::assert_image("tests/executor/outputs/import_glb_no_assign.png", &result, 0.999);
} }
@ -914,10 +993,148 @@ async fn serial_test_import_glb_no_assign() {
async fn serial_test_import_ext_doesnt_match() { async fn serial_test_import_ext_doesnt_match() {
let code = r#"const model = import("tests/executor/inputs/cube.gltf", {type: "obj", units: "m"})"#; let code = r#"const model = import("tests/executor/inputs/cube.gltf", {type: "obj", units: "m"})"#;
let result = execute_and_snapshot(code).await; let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm).await;
assert!(result.is_err()); assert!(result.is_err());
assert_eq!( assert_eq!(
result.err().unwrap().to_string(), result.err().unwrap().to_string(),
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([14, 82])], message: "The given format does not match the file extension. Expected: `gltf`, Given: `obj`" }"# r#"semantic: KclErrorDetails { source_ranges: [SourceRange([14, 82])], message: "The given format does not match the file extension. Expected: `gltf`, Given: `obj`" }"#
); );
} }
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_cube_mm() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
|> close(%)
|> extrude(scale, %)
return sg
}
const myCube = cube([0,0], 10)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Mm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/cube_mm.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_cube_cm() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
|> close(%)
|> extrude(scale, %)
return sg
}
const myCube = cube([0,0], 10)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Cm)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/cube_cm.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_cube_m() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
|> close(%)
|> extrude(scale, %)
return sg
}
const myCube = cube([0,0], 10)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::M)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/cube_m.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_cube_in() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
|> close(%)
|> extrude(scale, %)
return sg
}
const myCube = cube([0,0], 10)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::In)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/cube_in.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_cube_ft() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
|> close(%)
|> extrude(scale, %)
return sg
}
const myCube = cube([0,0], 10)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Ft)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/cube_ft.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_cube_yd() {
let code = r#"fn cube = (pos, scale) => {
const sg = startSketchOn('XY')
|> startProfileAt(pos, %)
|> line([0, scale], %)
|> line([scale, 0], %)
|> line([0, -scale], %)
|> close(%)
|> extrude(scale, %)
return sg
}
const myCube = cube([0,0], 10)
"#;
let result = execute_and_snapshot(code, kittycad::types::UnitLength::Yd)
.await
.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/cube_yd.png", &result, 1.0);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 127 KiB

View File

@ -37,7 +37,7 @@ async fn setup(code: &str, name: &str) -> Result<(ExecutorContext, Program, uuid
let parser = kcl_lib::parser::Parser::new(tokens); let parser = kcl_lib::parser::Parser::new(tokens);
let program = parser.ast()?; let program = parser.ast()?;
let mut mem: kcl_lib::executor::ProgramMemory = Default::default(); let mut mem: kcl_lib::executor::ProgramMemory = Default::default();
let ctx = kcl_lib::executor::ExecutorContext::new(ws).await?; let ctx = kcl_lib::executor::ExecutorContext::new(ws, kittycad::types::UnitLength::Mm).await?;
let memory = kcl_lib::executor::execute(program.clone(), &mut mem, kcl_lib::executor::BodyType::Root, &ctx).await?; let memory = kcl_lib::executor::execute(program.clone(), &mut mem, kcl_lib::executor::BodyType::Root, &ctx).await?;
// We need to get the sketch ID. // We need to get the sketch ID.