From 7687a388648c4c88a9806cd9a69e8b76535530af Mon Sep 17 00:00:00 2001 From: Kristian Krsnik Date: Wed, 19 Jul 2023 02:26:23 +0200 Subject: [PATCH] initial commit --- .gitignore | 8 + README.md | 34 ++ Test/teapot_v1.hxa | Bin 0 -> 21867 bytes Test/teapot_v1_print.txt | 1102 +++++++++++++++++++++++++++++++++++++ Test/teapot_v3.hxa | Bin 0 -> 21871 bytes Test/teapot_v3_print.txt | 1103 ++++++++++++++++++++++++++++++++++++++ build.zig | 25 + src/HxA.zig | 493 +++++++++++++++++ src/test.zig | 117 ++++ src/types.zig | 218 ++++++++ 10 files changed, 3100 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 Test/teapot_v1.hxa create mode 100644 Test/teapot_v1_print.txt create mode 100644 Test/teapot_v3.hxa create mode 100644 Test/teapot_v3_print.txt create mode 100644 build.zig create mode 100644 src/HxA.zig create mode 100644 src/test.zig create mode 100644 src/types.zig diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ddcb7dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +Test/teapot_v1_test.hxa +Test/teapot_v3_test.hxa +Test/teapot_v1_print_test.txt +Test/teapot_v3_print_test.txt +Test/teapot_converted_v1_v3.hxa + +zig-cache/* +zig-out/* diff --git a/README.md b/README.md new file mode 100644 index 0000000..d08b649 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# zig-HxA + +This is a parser for the [HxA](https://github.com/quelsolaar/HxA) file format (by the wonderful [Eskil Steenberg](http://www.quelsolaar.com/) in the zig programming language. + +This is an alpha project and certain aspects of this implementation could not be testet. Feel free to open an issue or pull request if something catches your eye! Known correct HxA files are also welcome as a test tool! + +## The Standard +The actual standard can be found in `types.hxa`. The struct represented there is the actual HxA format. + +## Usage +```zig +const std = @import("std"); +const hxa = @import("HxA.zig"); + +const allocator = std.heap.page_allocator; + +const file1 = &try std.fs.cwd().openFile("Test/teapot_v1.hxa", .{ .read = true }); +const file2 = &try std.fs.cwd().createFile("Test/teapot_v1_test.hxa", .{ .read = true }); +const stdout = &std.io.getStdOut().writer(); + +// Load HxA file +const teapot_v1 = try hxa.load(allocator, file1); +// Free when done +defer hxa.free(allocator, teapot_v1); + +// Print HxA in human readable format to stdout +try hxa.print(teapot_v1, stdout, .data); + +// Save HxA to file +try hxa.save(teapot_v1, file2); +``` + +## Tests +Run all tests with `zig build test`. Since I am unsure if the parser handles all cases correctly, tests are more of a tool to communicate breaking code change than to validate absolute feature correctness. diff --git a/Test/teapot_v1.hxa b/Test/teapot_v1.hxa new file mode 100644 index 0000000000000000000000000000000000000000..954ab5a1012cee96592adde842c6e88f8783aab7 GIT binary patch literal 21867 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 b61V|dQGP@o#B*$a{=nR3{sf%+761Jo9F4Mr literal 0 HcmV?d00001 diff --git a/Test/teapot_v1_print.txt b/Test/teapot_v1_print.txt new file mode 100644 index 0000000..ea29df1 --- /dev/null +++ b/Test/teapot_v1_print.txt @@ -0,0 +1,1102 @@ +HxA version: 1 +Node lenght: 1 +-Node id: 0 + -Node type: geometry + -Node meta length: 38 + -Meta u64 "Texture resolution" [1]: { 1024 } + -Meta u64 "Separate hard edges" [1]: { 18446744071654704384 } + -Meta u64 "Aspect" [1]: { 0 } + -Meta u64 "Use normal" [1]: { 18446744071654704385 } + -Meta u64 "Overlap Identical parts" [1]: { 18446744071654704384 } + -Meta u64 "Overlap mirrored parts" [1]: { 18446744071654704384 } + -Meta u64 "Enable Experimental unwrapping" [1]: { 18446744071654704384 } + -Meta u64 "Supress validation errors" [1]: { 18446744071654704384 } + -Meta u64 "Quads" [1]: { 18446744071654704385 } + -Meta u64 "Vertex Weld" [1]: { 18446744071654704385 } + -Meta u64 "Flat Soft surface" [1]: { 18446744071654704385 } + -Meta u64 "Cones" [1]: { 18446744071654704385 } + -Meta u64 "Cone Ratio" [1]: { 0 } + -Meta u64 "Strips" [1]: { 18446744071654704385 } + -Meta u64 "Patches" [1]: { 18446744071654704385 } + -Meta u64 "Planes" [1]: { 18446744071654704385 } + -Meta u64 "Flatness" [1]: { 18446744072635809792 } + -Meta u64 "Merge" [1]: { 18446744071654704385 } + -Meta u64 "Merge limit" [1]: { 0 } + -Meta u64 "Pre-Smooth" [1]: { 18446744071654704385 } + -Meta u64 "Soft unfold" [1]: { 18446744071654704384 } + -Meta u64 "Tubes" [1]: { 18446744071654704385 } + -Meta u64 "Junctions" [1]: { 18446744071654704385 } + -Meta u64 "Extra ordenary point" [1]: { 18446744071654704384 } + -Meta u64 "Angle based flatening" [1]: { 18446744071654704385 } + -Meta u64 "Smooth" [1]: { 18446744071654704385 } + -Meta u64 "Repair Smooth" [1]: { 18446744071654704385 } + -Meta u64 "Repair" [1]: { 18446744071654704384 } + -Meta u64 "Squares" [1]: { 18446744071654704385 } + -Meta u64 "Relax" [1]: { 18446744071654704384 } + -Meta u64 "Relaxation iterations" [1]: { 50 } + -Meta u64 "Expand" [1]: { 0 } + -Meta u64 "Cut" [1]: { 18446744071654704385 } + -Meta u64 "Stretch" [1]: { 18446744071654704385 } + -Meta u64 "Match" [1]: { 18446744071654704385 } + -Meta u64 "Rasterization resolution" [1]: { 64 } + -Meta u64 "Packing iterations" [1]: { 4 } + -Meta u64 "Validate" [1]: { 18446744071654704385 } + -Geometry vertex length: 530 + -Vertex Layer length: 1 + Layer name: vertex + Layer components: 3 + Layer type: f64 + { 4.062660, 2.834570, -0.110804 } + { 4.007140, 3.044430, -0.110804 } + { 4.071550, 3.114380, -0.110804 } + { 4.202570, 3.044430, -0.110804 } + { 4.346920, 2.834570, -0.110804 } + { 3.754250, 2.834570, 1.451170 } + { 3.703030, 3.044430, 1.429380 } + { 3.762440, 3.114380, 1.454660 } + { 3.883310, 3.044430, 1.506090 } + { 4.016470, 2.834570, 1.562740 } + { 2.908590, 2.834570, 2.714680 } + { 2.869170, 3.044430, 2.675270 } + { 2.914900, 3.114380, 2.720990 } + { 3.007920, 3.044430, 2.814020 } + { 3.110410, 2.834570, 2.916500 } + { 1.645080, 2.834570, 3.560340 } + { 1.623290, 3.044430, 3.509120 } + { 1.648570, 3.114380, 3.568530 } + { 1.699990, 3.044430, 3.689400 } + { 1.756650, 2.834570, 3.822560 } + { 0.083103, 2.834570, 3.868760 } + { 0.083103, 3.044430, 3.813240 } + { 0.083103, 3.114380, 3.877640 } + { 0.083103, 3.044430, 4.008660 } + { 0.083103, 2.834570, 4.153010 } + { -1.586800, 2.834570, 3.560340 } + { -1.502620, 3.044430, 3.509120 } + { -1.495850, 3.114380, 3.568530 } + { -1.535470, 3.044430, 3.689400 } + { -1.590440, 2.834570, 3.822560 } + { -2.838320, 2.834570, 2.714680 } + { -2.743440, 3.044430, 2.675270 } + { -2.760680, 3.114380, 2.720990 } + { -2.843220, 3.044430, 2.814020 } + { -2.944210, 2.834570, 2.916500 } + { -3.624020, 2.834570, 1.451170 } + { -3.552000, 3.044430, 1.429380 } + { -3.600730, 3.114380, 1.454660 } + { -3.717670, 3.044430, 1.506090 } + { -3.850270, 2.834570, 1.562740 } + { -3.896460, 2.834570, -0.110804 } + { -3.840940, 3.044430, -0.110804 } + { -3.905340, 3.114380, -0.110804 } + { -4.036360, 3.044430, -0.110804 } + { -4.180710, 2.834570, -0.110804 } + { -3.588040, 2.834570, -1.672780 } + { -3.536830, 3.044430, -1.650990 } + { -3.596240, 3.114380, -1.676270 } + { -3.717110, 3.044430, -1.727690 } + { -3.850270, 2.834570, -1.784350 } + { -2.742380, 2.834570, -2.936290 } + { -2.702970, 3.044430, -2.896870 } + { -2.748690, 3.114380, -2.942600 } + { -2.841720, 3.044430, -3.035620 } + { -2.944210, 2.834570, -3.138110 } + { -1.478870, 2.834570, -3.781950 } + { -1.457080, 3.044430, -3.730730 } + { -1.482360, 3.114380, -3.790140 } + { -1.533790, 3.044430, -3.911010 } + { -1.590440, 2.834570, -4.044170 } + { 0.083103, 2.834570, -4.090360 } + { 0.083103, 3.044430, -4.034840 } + { 0.083103, 3.114380, -4.099250 } + { 0.083103, 3.044430, -4.230270 } + { 0.083103, 2.834570, -4.374620 } + { 1.645080, 2.834570, -3.781950 } + { 1.623290, 3.044430, -3.730730 } + { 1.648570, 3.114380, -3.790140 } + { 1.699990, 3.044430, -3.911010 } + { 1.756650, 2.834570, -4.044170 } + { 2.908590, 2.834570, -2.936290 } + { 2.869170, 3.044430, -2.896870 } + { 2.914900, 3.114380, -2.942600 } + { 3.007920, 3.044430, -3.035620 } + { 3.110410, 2.834570, -3.138110 } + { 3.754250, 2.834570, -1.672780 } + { 3.703030, 3.044430, -1.650990 } + { 3.762440, 3.114380, -1.676270 } + { 3.883310, 3.044430, -1.727690 } + { 4.016470, 2.834570, -1.784350 } + { 4.868790, 1.718650, -0.110804 } + { 5.324040, 0.622714, -0.110804 } + { 5.646050, -0.433246, -0.110804 } + { 5.768190, -1.429250, -0.110804 } + { 4.497900, 1.718650, 1.767580 } + { 4.917870, 0.622714, 1.946260 } + { 5.214920, -0.433246, 2.072650 } + { 5.327590, -1.429250, 2.120590 } + { 3.480940, 1.718650, 3.287030 } + { 3.804170, 0.622714, 3.610260 } + { 4.032790, -0.433246, 3.838890 } + { 4.119510, -1.429250, 3.925610 } + { 1.961480, 1.718650, 4.303990 } + { 2.140170, 0.622714, 4.723960 } + { 2.266560, -0.433246, 5.021010 } + { 2.314500, -1.429250, 5.133690 } + { 0.083103, 1.718650, 4.674880 } + { 0.083103, 0.622714, 5.130130 } + { 0.083103, -0.433246, 5.452140 } + { 0.083103, -1.429250, 5.574280 } + { -1.795280, 1.718650, 4.303990 } + { -1.973970, 0.622714, 4.723960 } + { -2.100350, -0.433246, 5.021010 } + { -2.148290, -1.429250, 5.133690 } + { -3.314740, 1.718650, 3.287030 } + { -3.637960, 0.622714, 3.610260 } + { -3.866590, -0.433246, 3.838890 } + { -3.953310, -1.429250, 3.925610 } + { -4.331690, 1.718650, 1.767580 } + { -4.751660, 0.622714, 1.946260 } + { -5.048710, -0.433246, 2.072650 } + { -5.161390, -1.429250, 2.120590 } + { -4.702580, 1.718650, -0.110804 } + { -5.157840, 0.622714, -0.110804 } + { -5.479840, -0.433246, -0.110804 } + { -5.601980, -1.429250, -0.110804 } + { -4.331690, 1.718650, -1.989190 } + { -4.751660, 0.622714, -2.167870 } + { -5.048710, -0.433246, -2.294260 } + { -5.161390, -1.429250, -2.342200 } + { -3.314740, 1.718650, -3.508640 } + { -3.637960, 0.622714, -3.831870 } + { -3.866590, -0.433246, -4.060490 } + { -3.953310, -1.429250, -4.147210 } + { -1.795280, 1.718650, -4.525600 } + { -1.973970, 0.622714, -4.945570 } + { -2.100350, -0.433246, -5.242620 } + { -2.148290, -1.429250, -5.355290 } + { 0.083103, 1.718650, -4.896490 } + { 0.083103, 0.622714, -5.351740 } + { 0.083103, -0.433246, -5.673750 } + { 0.083103, -1.429250, -5.795890 } + { 1.961480, 1.718650, -4.525600 } + { 2.140170, 0.622714, -4.945570 } + { 2.266560, -0.433246, -5.242620 } + { 2.314500, -1.429250, -5.355290 } + { 3.480940, 1.718650, -3.508640 } + { 3.804170, 0.622714, -3.831870 } + { 4.032790, -0.433246, -4.060490 } + { 4.119510, -1.429250, -4.147210 } + { 4.497900, 1.718650, -1.989190 } + { 4.917870, 0.622714, -2.167870 } + { 5.214920, -0.433246, -2.294260 } + { 5.327590, -1.429250, -2.342200 } + { 5.546110, -2.272020, -0.110804 } + { 5.057550, -2.894930, -0.110804 } + { 4.568990, -3.317980, -0.110804 } + { 4.346920, -3.561150, -0.110804 } + { 5.122730, -2.272020, 2.033430 } + { 4.672030, -2.894930, 1.841670 } + { 4.221330, -3.317980, 1.649910 } + { 4.016470, -3.561150, 1.562740 } + { 3.961840, -2.272020, 3.767930 } + { 3.614960, -2.894930, 3.421060 } + { 3.268080, -3.317980, 3.074180 } + { 3.110410, -3.561150, 2.916500 } + { 2.227330, -2.272020, 4.928820 } + { 2.035570, -2.894930, 4.478130 } + { 1.843810, -3.317980, 4.027430 } + { 1.756650, -3.561150, 3.822560 } + { 0.083103, -2.272020, 5.352210 } + { 0.083103, -2.894930, 4.863650 } + { 0.083103, -3.317980, 4.375080 } + { 0.083103, -3.561150, 4.153010 } + { -2.061130, -2.272020, 4.928820 } + { -1.869370, -2.894930, 4.478130 } + { -1.677610, -3.317980, 4.027430 } + { -1.590440, -3.561150, 3.822560 } + { -3.795640, -2.272020, 3.767930 } + { -3.448760, -2.894930, 3.421060 } + { -3.101880, -3.317980, 3.074180 } + { -2.944210, -3.561150, 2.916500 } + { -4.956530, -2.272020, 2.033430 } + { -4.505830, -2.894930, 1.841670 } + { -4.055130, -3.317980, 1.649910 } + { -3.850270, -3.561150, 1.562740 } + { -5.379910, -2.272020, -0.110804 } + { -4.891350, -2.894930, -0.110804 } + { -4.402790, -3.317980, -0.110804 } + { -4.180710, -3.561150, -0.110804 } + { -4.956530, -2.272020, -2.255040 } + { -4.505830, -2.894930, -2.063270 } + { -4.055130, -3.317980, -1.871510 } + { -3.850270, -3.561150, -1.784350 } + { -3.795640, -2.272020, -3.989540 } + { -3.448760, -2.894930, -3.642660 } + { -3.101880, -3.317980, -3.295780 } + { -2.944210, -3.561150, -3.138110 } + { -2.061130, -2.272020, -5.150430 } + { -1.869370, -2.894930, -4.699730 } + { -1.677610, -3.317980, -4.249030 } + { -1.590440, -3.561150, -4.044170 } + { 0.083103, -2.272020, -5.573820 } + { 0.083103, -2.894930, -5.085250 } + { 0.083103, -3.317980, -4.596690 } + { 0.083103, -3.561150, -4.374620 } + { 2.227330, -2.272020, -5.150430 } + { 2.035570, -2.894930, -4.699730 } + { 1.843810, -3.317980, -4.249030 } + { 1.756650, -3.561150, -4.044170 } + { 3.961840, -2.272020, -3.989540 } + { 3.614960, -2.894930, -3.642660 } + { 3.268080, -3.317980, -3.295780 } + { 3.110410, -3.561150, -3.138110 } + { 5.122730, -2.272020, -2.255040 } + { 4.672030, -2.894930, -2.063270 } + { 4.221330, -3.317980, -1.871510 } + { 4.016470, -3.561150, -1.784350 } + { 4.250310, -3.717720, -0.110804 } + { 3.733990, -3.854290, -0.110804 } + { 2.458180, -3.950890, -0.110804 } + { 0.083103, -3.987540, -0.110804 } + { 3.927360, -3.717720, 1.524830 } + { 3.451050, -3.854290, 1.322170 } + { 2.274110, -3.950890, 0.821414 } + { 3.041820, -3.717720, 2.847920 } + { 2.675230, -3.854290, 2.481330 } + { 1.769410, -3.950890, 1.575500 } + { 1.718730, -3.717720, 3.733450 } + { 1.516080, -3.854290, 3.257140 } + { 1.015320, -3.950890, 2.080210 } + { 0.083103, -3.717720, 4.056410 } + { 0.083103, -3.854290, 3.540090 } + { 0.083103, -3.950890, 2.264270 } + { -1.552530, -3.717720, 3.733450 } + { -1.349870, -3.854290, 3.257140 } + { -0.849115, -3.950890, 2.080210 } + { -2.875620, -3.717720, 2.847920 } + { -2.509030, -3.854290, 2.481330 } + { -1.603200, -3.950890, 1.575500 } + { -3.761150, -3.717720, 1.524830 } + { -3.284840, -3.854290, 1.322170 } + { -2.107910, -3.950890, 0.821414 } + { -4.084110, -3.717720, -0.110804 } + { -3.567790, -3.854290, -0.110804 } + { -2.291980, -3.950890, -0.110804 } + { -3.761150, -3.717720, -1.746430 } + { -3.284840, -3.854290, -1.543780 } + { -2.107910, -3.950890, -1.043020 } + { -2.875620, -3.717720, -3.069520 } + { -2.509030, -3.854290, -2.702940 } + { -1.603200, -3.950890, -1.797110 } + { -1.552530, -3.717720, -3.955060 } + { -1.349870, -3.854290, -3.478750 } + { -0.849115, -3.950890, -2.301810 } + { 0.083103, -3.717720, -4.278020 } + { 0.083103, -3.854290, -3.761690 } + { 0.083103, -3.950890, -2.485880 } + { 1.718730, -3.717720, -3.955060 } + { 1.516080, -3.854290, -3.478750 } + { 1.015320, -3.950890, -2.301810 } + { 3.041820, -3.717720, -3.069520 } + { 2.675230, -3.854290, -2.702940 } + { 1.769410, -3.950890, -1.797110 } + { 3.927360, -3.717720, -1.746430 } + { 3.451050, -3.854290, -1.543780 } + { 2.274110, -3.950890, -1.043020 } + { -4.464970, 1.768610, -0.110804 } + { -5.792970, 1.758620, -0.110804 } + { -6.774530, 1.688670, -0.110804 } + { -7.383010, 1.498790, -0.110804 } + { -7.591760, 1.129040, -0.110804 } + { -4.420550, 1.868550, 0.368876 } + { -5.832520, 1.856990, 0.368876 } + { -6.868910, 1.776110, 0.368876 } + { -7.507240, 1.556570, 0.368876 } + { -7.725010, 1.129040, 0.368876 } + { -4.322840, 2.088400, 0.528769 } + { -5.919550, 2.073410, 0.528769 } + { -7.076550, 1.968480, 0.528769 } + { -7.780530, 1.683670, 0.528769 } + { -8.018140, 1.129040, 0.528769 } + { -4.225130, 2.308250, 0.368876 } + { -6.006570, 2.289830, 0.368876 } + { -7.284190, 2.160850, 0.368876 } + { -8.053810, 1.810770, 0.368876 } + { -8.311280, 1.129040, 0.368876 } + { -4.180710, 2.408190, -0.110804 } + { -6.046130, 2.388200, -0.110804 } + { -7.378570, 2.248290, -0.110804 } + { -8.178040, 1.868550, -0.110804 } + { -8.444530, 1.129040, -0.110804 } + { -4.225130, 2.308250, -0.590483 } + { -6.006570, 2.289830, -0.590483 } + { -7.284190, 2.160850, -0.590483 } + { -8.053810, 1.810770, -0.590483 } + { -8.311280, 1.129040, -0.590483 } + { -4.322840, 2.088400, -0.750376 } + { -5.919550, 2.073410, -0.750376 } + { -7.076550, 1.968480, -0.750376 } + { -7.780530, 1.683670, -0.750376 } + { -8.018140, 1.129040, -0.750376 } + { -4.420550, 1.868550, -0.590483 } + { -5.832520, 1.856990, -0.590483 } + { -6.868910, 1.776110, -0.590483 } + { -7.507240, 1.556570, -0.590483 } + { -7.725010, 1.129040, -0.590483 } + { -7.480730, 0.549430, -0.110804 } + { -7.129850, -0.150103, -0.110804 } + { -6.512480, -0.849634, -0.110804 } + { -5.601980, -1.429250, -0.110804 } + { -7.601830, 0.493477, 0.368876 } + { -7.215900, -0.235462, 0.368876 } + { -6.542670, -0.955033, 0.368876 } + { -5.557570, -1.562490, 0.368876 } + { -7.868240, 0.370383, 0.528769 } + { -7.405220, -0.423253, 0.528769 } + { -6.609090, -1.186910, 0.528769 } + { -5.459860, -1.855630, 0.528769 } + { -8.134660, 0.247288, 0.368876 } + { -7.594540, -0.611044, 0.368876 } + { -6.675500, -1.418780, 0.368876 } + { -5.362140, -2.148770, 0.368876 } + { -8.255760, 0.191336, -0.110804 } + { -7.680590, -0.696404, -0.110804 } + { -6.705690, -1.524180, -0.110804 } + { -5.317730, -2.282010, -0.110804 } + { -8.134660, 0.247288, -0.590483 } + { -7.594540, -0.611044, -0.590483 } + { -6.675500, -1.418780, -0.590483 } + { -5.362140, -2.148770, -0.590483 } + { -7.868240, 0.370383, -0.750376 } + { -7.405220, -0.423253, -0.750376 } + { -6.609090, -1.186910, -0.750376 } + { -5.459860, -1.855630, -0.750376 } + { -7.601830, 0.493477, -0.590483 } + { -7.215900, -0.235462, -0.590483 } + { -6.542670, -0.955033, -0.590483 } + { -5.557570, -1.562490, -0.590483 } + { 4.915430, 0.063088, -0.110804 } + { 6.278960, 0.376212, -0.110804 } + { 6.869670, 1.129040, -0.110804 } + { 7.193900, 2.041760, -0.110804 } + { 7.757970, 2.834570, -0.110804 } + { 4.915430, -0.303333, 0.944490 } + { 6.383050, 0.104519, 0.842059 } + { 7.002920, 0.970814, 0.616710 } + { 7.356290, 1.984510, 0.391361 } + { 8.024460, 2.834570, 0.288929 } + { 4.915430, -1.109460, 1.296260 } + { 6.612070, -0.493206, 1.159680 } + { 7.296050, 0.622714, 0.859214 } + { 7.713550, 1.858550, 0.558749 } + { 8.610730, 2.834570, 0.422173 } + { 4.915430, -1.915590, 0.944490 } + { 6.841080, -1.090930, 0.842059 } + { 7.589190, 0.274614, 0.616710 } + { 8.070810, 1.732600, 0.391361 } + { 9.197000, 2.834570, 0.288929 } + { 4.915430, -2.282010, -0.110804 } + { 6.945180, -1.362620, -0.110804 } + { 7.722440, 0.116386, -0.110804 } + { 8.233210, 1.675340, -0.110804 } + { 9.463490, 2.834570, -0.110804 } + { 4.915430, -1.915590, -1.166100 } + { 6.841080, -1.090930, -1.063670 } + { 7.589190, 0.274614, -0.838317 } + { 8.070810, 1.732600, -0.612968 } + { 9.197000, 2.834570, -0.510536 } + { 4.915430, -1.109460, -1.517860 } + { 6.612070, -0.493206, -1.381290 } + { 7.296050, 0.622714, -1.080820 } + { 7.713550, 1.858550, -0.780356 } + { 8.610730, 2.834570, -0.643780 } + { 4.915430, -0.303333, -1.166100 } + { 6.383050, 0.104519, -1.063670 } + { 7.002920, 0.970814, -0.838317 } + { 7.356290, 1.984510, -0.612968 } + { 8.024460, 2.834570, -0.510536 } + { 7.962270, 2.954490, -0.110804 } + { 8.113290, 2.994460, -0.110804 } + { 8.157700, 2.954490, -0.110804 } + { 8.042220, 2.834570, -0.110804 } + { 8.247670, 2.960340, 0.263946 } + { 8.381160, 3.003830, 0.208983 } + { 8.385150, 2.962680, 0.154019 } + { 8.219880, 2.834570, 0.129036 } + { 8.875550, 2.973220, 0.388862 } + { 8.970490, 3.024440, 0.315578 } + { 8.885550, 2.980720, 0.242294 } + { 8.610730, 2.834570, 0.208983 } + { 9.503430, 2.986110, 0.263946 } + { 9.559820, 3.045050, 0.208983 } + { 9.385940, 2.998750, 0.154019 } + { 9.001580, 2.834570, 0.129036 } + { 9.788830, 2.991960, -0.110804 } + { 9.827690, 3.054420, -0.110804 } + { 9.613390, 3.006950, -0.110804 } + { 9.179240, 2.834570, -0.110804 } + { 9.503430, 2.986110, -0.485553 } + { 9.559820, 3.045050, -0.430590 } + { 9.385940, 2.998750, -0.375626 } + { 9.001580, 2.834570, -0.350643 } + { 8.875550, 2.973220, -0.610469 } + { 8.970490, 3.024440, -0.537185 } + { 8.885550, 2.980720, -0.463901 } + { 8.610730, 2.834570, -0.430590 } + { 8.247670, 2.960340, -0.485553 } + { 8.381160, 3.003830, -0.430590 } + { 8.385150, 2.962680, -0.375626 } + { 8.219880, 2.834570, -0.350643 } + { 0.083103, 4.966470, -0.110804 } + { 1.051340, 4.826570, -0.110804 } + { 1.006930, 4.486800, -0.110804 } + { 0.642728, 4.067080, -0.110804 } + { 0.651611, 3.687330, -0.110804 } + { 0.976642, 4.826570, 0.270243 } + { 0.935632, 4.486800, 0.252698 } + { 0.599470, 4.067080, 0.109187 } + { 0.607552, 3.687330, 0.112336 } + { 0.771453, 4.826570, 0.577547 } + { 0.739819, 4.486800, 0.545913 } + { 0.480736, 4.067080, 0.286830 } + { 0.486744, 3.687330, 0.292838 } + { 0.464149, 4.826570, 0.782736 } + { 0.446604, 4.486800, 0.741726 } + { 0.303093, 4.067080, 0.405564 } + { 0.306242, 3.687330, 0.413646 } + { 0.083103, 4.826570, 0.857438 } + { 0.083103, 4.486800, 0.813023 } + { 0.083103, 4.067080, 0.448822 } + { 0.083103, 3.687330, 0.457705 } + { -0.297944, 4.826570, 0.782736 } + { -0.280399, 4.486800, 0.741726 } + { -0.136888, 4.067080, 0.405564 } + { -0.140037, 3.687330, 0.413646 } + { -0.605248, 4.826570, 0.577547 } + { -0.573614, 4.486800, 0.545913 } + { -0.314531, 4.067080, 0.286830 } + { -0.320539, 3.687330, 0.292838 } + { -0.810437, 4.826570, 0.270243 } + { -0.769427, 4.486800, 0.252698 } + { -0.433265, 4.067080, 0.109187 } + { -0.441347, 3.687330, 0.112336 } + { -0.885139, 4.826570, -0.110804 } + { -0.840724, 4.486800, -0.110804 } + { -0.476523, 4.067080, -0.110804 } + { -0.485406, 3.687330, -0.110804 } + { -0.810437, 4.826570, -0.491850 } + { -0.769427, 4.486800, -0.474305 } + { -0.433265, 4.067080, -0.330794 } + { -0.441347, 3.687330, -0.333943 } + { -0.605248, 4.826570, -0.799154 } + { -0.573614, 4.486800, -0.767520 } + { -0.314531, 4.067080, -0.508437 } + { -0.320539, 3.687330, -0.514445 } + { -0.297944, 4.826570, -1.004340 } + { -0.280399, 4.486800, -0.963333 } + { -0.136888, 4.067080, -0.627171 } + { -0.140037, 3.687330, -0.635253 } + { 0.083103, 4.826570, -1.079040 } + { 0.083103, 4.486800, -1.034630 } + { 0.083103, 4.067080, -0.670429 } + { 0.083103, 3.687330, -0.679312 } + { 0.464149, 4.826570, -1.004340 } + { 0.446604, 4.486800, -0.963333 } + { 0.303093, 4.067080, -0.627171 } + { 0.306242, 3.687330, -0.635253 } + { 0.771453, 4.826570, -0.799154 } + { 0.739819, 4.486800, -0.767520 } + { 0.480736, 4.067080, -0.508437 } + { 0.486744, 3.687330, -0.514445 } + { 0.976642, 4.826570, -0.491850 } + { 0.935632, 4.486800, -0.474305 } + { 0.599470, 4.067080, -0.330794 } + { 0.607552, 3.687330, -0.333943 } + { 1.380010, 3.434170, -0.110804 } + { 2.428200, 3.260950, -0.110804 } + { 3.369790, 3.087730, -0.110804 } + { 3.778410, 2.834570, -0.110804 } + { 1.279500, 3.434170, 0.398234 } + { 2.246460, 3.260950, 0.809647 } + { 3.115070, 3.087730, 1.179220 } + { 3.492020, 2.834570, 1.339600 } + { 1.003910, 3.434170, 0.810003 } + { 1.748120, 3.260950, 1.554220 } + { 2.416650, 3.087730, 2.222750 } + { 2.706770, 2.834570, 2.512860 } + { 0.592140, 3.434170, 1.085600 } + { 1.003550, 3.260950, 2.052550 } + { 1.373130, 3.087730, 2.921170 } + { 1.533510, 2.834570, 3.298120 } + { 0.083103, 3.434170, 1.186110 } + { 0.083103, 3.260950, 2.234290 } + { 0.083103, 3.087730, 3.175890 } + { 0.083103, 2.834570, 3.584500 } + { -0.425935, 3.434170, 1.085600 } + { -0.837348, 3.260950, 2.052550 } + { -1.206920, 3.087730, 2.921170 } + { -1.367300, 2.834570, 3.298120 } + { -0.837704, 3.434170, 0.810003 } + { -1.581920, 3.260950, 1.554220 } + { -2.250450, 3.087730, 2.222750 } + { -2.540560, 2.834570, 2.512860 } + { -1.113300, 3.434170, 0.398234 } + { -2.080250, 3.260950, 0.809647 } + { -2.948870, 3.087730, 1.179220 } + { -3.325820, 2.834570, 1.339600 } + { -1.213810, 3.434170, -0.110804 } + { -2.262000, 3.260950, -0.110804 } + { -3.203590, 3.087730, -0.110804 } + { -3.612200, 2.834570, -0.110804 } + { -1.113300, 3.434170, -0.619841 } + { -2.080250, 3.260950, -1.031250 } + { -2.948870, 3.087730, -1.400830 } + { -3.325820, 2.834570, -1.561210 } + { -0.837704, 3.434170, -1.031610 } + { -1.581920, 3.260950, -1.775820 } + { -2.250450, 3.087730, -2.444350 } + { -2.540560, 2.834570, -2.734470 } + { -0.425935, 3.434170, -1.307200 } + { -0.837348, 3.260950, -2.274160 } + { -1.206920, 3.087730, -3.142770 } + { -1.367300, 2.834570, -3.519720 } + { 0.083103, 3.434170, -1.407710 } + { 0.083103, 3.260950, -2.455900 } + { 0.083103, 3.087730, -3.397490 } + { 0.083103, 2.834570, -3.806110 } + { 0.592140, 3.434170, -1.307200 } + { 1.003550, 3.260950, -2.274160 } + { 1.373130, 3.087730, -3.142770 } + { 1.533510, 2.834570, -3.519720 } + { 1.003910, 3.434170, -1.031610 } + { 1.748120, 3.260950, -1.775820 } + { 2.416650, 3.087730, -2.444350 } + { 2.706770, 2.834570, -2.734470 } + { 1.279500, 3.434170, -0.619841 } + { 2.246460, 3.260950, -1.031250 } + { 3.115070, 3.087730, -1.400830 } + { 3.492020, 2.834570, -1.561210 } + -Geometry edge length: 2026 + -Corner Layer length: 1 + Layer name: reference + Layer components: 1 + Layer type: i32 + { 6, 5, 0, -2 } + { 7, 6, 1, -3 } + { 8, 7, 2, -4 } + { 9, 8, 3, -5 } + { 11, 10, 5, -7 } + { 12, 11, 6, -8 } + { 13, 12, 7, -9 } + { 14, 13, 8, -10 } + { 16, 15, 10, -12 } + { 17, 16, 11, -13 } + { 18, 17, 12, -14 } + { 19, 18, 13, -15 } + { 21, 20, 15, -17 } + { 22, 21, 16, -18 } + { 23, 22, 17, -19 } + { 24, 23, 18, -20 } + { 26, 25, 20, -22 } + { 27, 26, 21, -23 } + { 28, 27, 22, -24 } + { 29, 28, 23, -25 } + { 33, 32, 27, -29 } + { 34, 33, 28, -30 } + { 36, 35, 30, -32 } + { 37, 36, 31, -33 } + { 38, 37, 32, -34 } + { 39, 38, 33, -35 } + { 41, 40, 35, -37 } + { 42, 41, 36, -38 } + { 43, 42, 37, -39 } + { 44, 43, 38, -40 } + { 46, 45, 40, -42 } + { 47, 46, 41, -43 } + { 48, 47, 42, -44 } + { 49, 48, 43, -45 } + { 51, 50, 45, -47 } + { 52, 51, 46, -48 } + { 53, 52, 47, -49 } + { 54, 53, 48, -50 } + { 56, 55, 50, -52 } + { 57, 56, 51, -53 } + { 58, 57, 52, -54 } + { 59, 58, 53, -55 } + { 61, 60, 55, -57 } + { 62, 61, 56, -58 } + { 63, 62, 57, -59 } + { 64, 63, 58, -60 } + { 66, 65, 60, -62 } + { 67, 66, 61, -63 } + { 68, 67, 62, -64 } + { 69, 68, 63, -65 } + { 71, 70, 65, -67 } + { 72, 71, 66, -68 } + { 73, 72, 67, -69 } + { 74, 73, 68, -70 } + { 76, 75, 70, -72 } + { 77, 76, 71, -73 } + { 78, 77, 72, -74 } + { 79, 78, 73, -75 } + { 1, 0, 75, -77 } + { 2, 1, 76, -78 } + { 3, 2, 77, -79 } + { 4, 3, 78, -80 } + { 84, 9, 4, -81 } + { 85, 84, 80, -82 } + { 86, 85, 81, -83 } + { 87, 86, 82, -84 } + { 88, 14, 9, -85 } + { 89, 88, 84, -86 } + { 90, 89, 85, -87 } + { 91, 90, 86, -88 } + { 92, 19, 14, -89 } + { 93, 92, 88, -90 } + { 94, 93, 89, -91 } + { 95, 94, 90, -92 } + { 96, 24, 19, -93 } + { 97, 96, 92, -94 } + { 98, 97, 93, -95 } + { 99, 98, 94, -96 } + { 100, 29, 24, -97 } + { 101, 100, 96, -98 } + { 102, 101, 97, -99 } + { 103, 102, 98, -100 } + { 104, 34, 29, -101 } + { 105, 104, 100, -102 } + { 106, 105, 101, -103 } + { 107, 106, 102, -104 } + { 108, 39, 34, -105 } + { 109, 108, 104, -106 } + { 110, 109, 105, -107 } + { 111, 110, 106, -108 } + { 112, 44, 39, -109 } + { 113, 112, 108, -110 } + { 114, 113, 109, -111 } + { 115, 114, 110, -112 } + { 116, 49, 44, -113 } + { 117, 116, 112, -114 } + { 118, 117, 113, -115 } + { 119, 118, 114, -116 } + { 120, 54, 49, -117 } + { 121, 120, 116, -118 } + { 122, 121, 117, -119 } + { 123, 122, 118, -120 } + { 124, 59, 54, -121 } + { 125, 124, 120, -122 } + { 126, 125, 121, -123 } + { 127, 126, 122, -124 } + { 128, 64, 59, -125 } + { 129, 128, 124, -126 } + { 130, 129, 125, -127 } + { 131, 130, 126, -128 } + { 132, 69, 64, -129 } + { 133, 132, 128, -130 } + { 134, 133, 129, -131 } + { 135, 134, 130, -132 } + { 136, 74, 69, -133 } + { 137, 136, 132, -134 } + { 138, 137, 133, -135 } + { 139, 138, 134, -136 } + { 140, 79, 74, -137 } + { 141, 140, 136, -138 } + { 142, 141, 137, -139 } + { 143, 142, 138, -140 } + { 80, 4, 79, -141 } + { 81, 80, 140, -142 } + { 82, 81, 141, -143 } + { 83, 82, 142, -144 } + { 148, 87, 83, -145 } + { 149, 148, 144, -146 } + { 150, 149, 145, -147 } + { 151, 150, 146, -148 } + { 152, 91, 87, -149 } + { 153, 152, 148, -150 } + { 154, 153, 149, -151 } + { 155, 154, 150, -152 } + { 156, 95, 91, -153 } + { 157, 156, 152, -154 } + { 158, 157, 153, -155 } + { 159, 158, 154, -156 } + { 160, 99, 95, -157 } + { 161, 160, 156, -158 } + { 162, 161, 157, -159 } + { 163, 162, 158, -160 } + { 164, 103, 99, -161 } + { 165, 164, 160, -162 } + { 166, 165, 161, -163 } + { 167, 166, 162, -164 } + { 168, 107, 103, -165 } + { 169, 168, 164, -166 } + { 170, 169, 165, -167 } + { 171, 170, 166, -168 } + { 172, 111, 107, -169 } + { 173, 172, 168, -170 } + { 174, 173, 169, -171 } + { 175, 174, 170, -172 } + { 176, 115, 111, -173 } + { 177, 176, 172, -174 } + { 178, 177, 173, -175 } + { 179, 178, 174, -176 } + { 180, 119, 115, -177 } + { 181, 180, 176, -178 } + { 182, 181, 177, -179 } + { 183, 182, 178, -180 } + { 184, 123, 119, -181 } + { 185, 184, 180, -182 } + { 186, 185, 181, -183 } + { 187, 186, 182, -184 } + { 188, 127, 123, -185 } + { 189, 188, 184, -186 } + { 190, 189, 185, -187 } + { 191, 190, 186, -188 } + { 192, 131, 127, -189 } + { 193, 192, 188, -190 } + { 194, 193, 189, -191 } + { 195, 194, 190, -192 } + { 196, 135, 131, -193 } + { 197, 196, 192, -194 } + { 198, 197, 193, -195 } + { 199, 198, 194, -196 } + { 200, 139, 135, -197 } + { 201, 200, 196, -198 } + { 202, 201, 197, -199 } + { 203, 202, 198, -200 } + { 204, 143, 139, -201 } + { 205, 204, 200, -202 } + { 206, 205, 201, -203 } + { 207, 206, 202, -204 } + { 144, 83, 143, -205 } + { 145, 144, 204, -206 } + { 146, 145, 205, -207 } + { 147, 146, 206, -208 } + { 212, 151, 147, -209 } + { 213, 212, 208, -210 } + { 214, 213, 209, -211 } + { 211, 214, -211 } + { 215, 155, 151, -213 } + { 216, 215, 212, -214 } + { 217, 216, 213, -215 } + { 211, 217, -215 } + { 218, 159, 155, -216 } + { 219, 218, 215, -217 } + { 220, 219, 216, -218 } + { 211, 220, -218 } + { 221, 163, 159, -219 } + { 222, 221, 218, -220 } + { 223, 222, 219, -221 } + { 211, 223, -221 } + { 224, 167, 163, -222 } + { 225, 224, 221, -223 } + { 226, 225, 222, -224 } + { 211, 226, -224 } + { 227, 171, 167, -225 } + { 228, 227, 224, -226 } + { 229, 228, 225, -227 } + { 211, 229, -227 } + { 230, 175, 171, -228 } + { 231, 230, 227, -229 } + { 232, 231, 228, -230 } + { 211, 232, -230 } + { 233, 179, 175, -231 } + { 234, 233, 230, -232 } + { 235, 234, 231, -233 } + { 211, 235, -233 } + { 236, 183, 179, -234 } + { 237, 236, 233, -235 } + { 238, 237, 234, -236 } + { 211, 238, -236 } + { 239, 187, 183, -237 } + { 240, 239, 236, -238 } + { 241, 240, 237, -239 } + { 211, 241, -239 } + { 242, 191, 187, -240 } + { 243, 242, 239, -241 } + { 244, 243, 240, -242 } + { 211, 244, -242 } + { 245, 195, 191, -243 } + { 246, 245, 242, -244 } + { 247, 246, 243, -245 } + { 211, 247, -245 } + { 248, 199, 195, -246 } + { 249, 248, 245, -247 } + { 250, 249, 246, -248 } + { 211, 250, -248 } + { 251, 203, 199, -249 } + { 252, 251, 248, -250 } + { 253, 252, 249, -251 } + { 211, 253, -251 } + { 254, 207, 203, -252 } + { 255, 254, 251, -253 } + { 256, 255, 252, -254 } + { 211, 256, -254 } + { 208, 147, 207, -255 } + { 209, 208, 254, -256 } + { 210, 209, 255, -257 } + { 211, 210, -257 } + { 263, 262, 257, -259 } + { 264, 263, 258, -260 } + { 265, 264, 259, -261 } + { 266, 265, 260, -262 } + { 268, 267, 262, -264 } + { 271, 270, 265, -267 } + { 273, 272, 267, -269 } + { 276, 275, 270, -272 } + { 278, 277, 272, -274 } + { 279, 278, 273, -275 } + { 280, 279, 274, -276 } + { 281, 280, 275, -277 } + { 283, 282, 277, -279 } + { 284, 283, 278, -280 } + { 285, 284, 279, -281 } + { 286, 285, 280, -282 } + { 288, 287, 282, -284 } + { 291, 290, 285, -287 } + { 293, 292, 287, -289 } + { 296, 295, 290, -292 } + { 258, 257, 292, -294 } + { 259, 258, 293, -295 } + { 260, 259, 294, -296 } + { 261, 260, 295, -297 } + { 301, 266, 261, -298 } + { 302, 301, 297, -299 } + { 303, 302, 298, -300 } + { 304, 303, 299, -301 } + { 305, 271, 266, -302 } + { 306, 305, 301, -303 } + { 309, 276, 271, -306 } + { 310, 309, 305, -307 } + { 313, 281, 276, -310 } + { 314, 313, 309, -311 } + { 315, 314, 310, -312 } + { 316, 315, 311, -313 } + { 317, 286, 281, -314 } + { 318, 317, 313, -315 } + { 319, 318, 314, -316 } + { 320, 319, 315, -317 } + { 321, 291, 286, -318 } + { 322, 321, 317, -319 } + { 325, 296, 291, -322 } + { 326, 325, 321, -323 } + { 297, 261, 296, -326 } + { 298, 297, 325, -327 } + { 299, 298, 326, -328 } + { 300, 299, 327, -329 } + { 335, 334, 329, -331 } + { 337, 336, 331, -333 } + { 338, 337, 332, -334 } + { 340, 339, 334, -336 } + { 345, 344, 339, -341 } + { 350, 349, 344, -346 } + { 351, 350, 345, -347 } + { 352, 351, 346, -348 } + { 355, 354, 349, -351 } + { 356, 355, 350, -352 } + { 357, 356, 351, -353 } + { 360, 359, 354, -356 } + { 362, 361, 356, -358 } + { 365, 364, 359, -361 } + { 330, 329, 364, -366 } + { 332, 331, 366, -368 } + { 333, 332, 367, -369 } + { 375, 374, 370, -372 } + { 383, 382, -379 } + { 378, 379, -384 } + { 387, 386, -383 } + { 382, 383, -388 } + { 391, 390, -387 } + { 386, 387, -392 } + { 395, 394, -391 } + { 390, 391, -396 } + { 399, 398, -395 } + { 394, 395, -400 } + { 371, 370, 398, -400 } + { 401, 402, -407 } + { 407, 406, 402, -404 } + { 408, 407, 403, -405 } + { 409, 408, 404, -406 } + { 401, 406, -411 } + { 411, 410, 406, -408 } + { 412, 411, 407, -409 } + { 413, 412, 408, -410 } + { 401, 410, -415 } + { 415, 414, 410, -412 } + { 416, 415, 411, -413 } + { 417, 416, 412, -414 } + { 401, 414, -419 } + { 419, 418, 414, -416 } + { 420, 419, 415, -417 } + { 421, 420, 416, -418 } + { 401, 418, -423 } + { 423, 422, 418, -420 } + { 424, 423, 419, -421 } + { 425, 424, 420, -422 } + { 401, 422, -427 } + { 427, 426, 422, -424 } + { 428, 427, 423, -425 } + { 429, 428, 424, -426 } + { 401, 426, -431 } + { 431, 430, 426, -428 } + { 432, 431, 427, -429 } + { 433, 432, 428, -430 } + { 401, 430, -435 } + { 435, 434, 430, -432 } + { 436, 435, 431, -433 } + { 437, 436, 432, -434 } + { 401, 434, -439 } + { 439, 438, 434, -436 } + { 440, 439, 435, -437 } + { 441, 440, 436, -438 } + { 401, 438, -443 } + { 443, 442, 438, -440 } + { 444, 443, 439, -441 } + { 445, 444, 440, -442 } + { 401, 442, -447 } + { 447, 446, 442, -444 } + { 448, 447, 443, -445 } + { 449, 448, 444, -446 } + { 401, 446, -451 } + { 451, 450, 446, -448 } + { 452, 451, 447, -449 } + { 453, 452, 448, -450 } + { 401, 450, -455 } + { 455, 454, 450, -452 } + { 456, 455, 451, -453 } + { 457, 456, 452, -454 } + { 401, 454, -459 } + { 459, 458, 454, -456 } + { 460, 459, 455, -457 } + { 461, 460, 456, -458 } + { 401, 458, -463 } + { 463, 462, 458, -460 } + { 464, 463, 459, -461 } + { 465, 464, 460, -462 } + { 401, 462, -403 } + { 403, 402, 462, -464 } + { 404, 403, 463, -465 } + { 405, 404, 464, -466 } + { 470, 409, 405, -467 } + { 471, 470, 466, -468 } + { 472, 471, 467, -469 } + { 473, 472, 468, -470 } + { 474, 413, 409, -471 } + { 475, 474, 470, -472 } + { 476, 475, 471, -473 } + { 477, 476, 472, -474 } + { 478, 417, 413, -475 } + { 479, 478, 474, -476 } + { 480, 479, 475, -477 } + { 481, 480, 476, -478 } + { 482, 421, 417, -479 } + { 483, 482, 478, -480 } + { 484, 483, 479, -481 } + { 485, 484, 480, -482 } + { 486, 425, 421, -483 } + { 487, 486, 482, -484 } + { 488, 487, 483, -485 } + { 489, 488, 484, -486 } + { 490, 429, 425, -487 } + { 491, 490, 486, -488 } + { 492, 491, 487, -489 } + { 493, 492, 488, -490 } + { 494, 433, 429, -491 } + { 495, 494, 490, -492 } + { 496, 495, 491, -493 } + { 497, 496, 492, -494 } + { 498, 437, 433, -495 } + { 499, 498, 494, -496 } + { 500, 499, 495, -497 } + { 501, 500, 496, -498 } + { 502, 441, 437, -499 } + { 503, 502, 498, -500 } + { 504, 503, 499, -501 } + { 505, 504, 500, -502 } + { 506, 445, 441, -503 } + { 507, 506, 502, -504 } + { 508, 507, 503, -505 } + { 509, 508, 504, -506 } + { 510, 449, 445, -507 } + { 511, 510, 506, -508 } + { 512, 511, 507, -509 } + { 513, 512, 508, -510 } + { 514, 453, 449, -511 } + { 515, 514, 510, -512 } + { 516, 515, 511, -513 } + { 517, 516, 512, -514 } + { 518, 457, 453, -515 } + { 519, 518, 514, -516 } + { 520, 519, 515, -517 } + { 521, 520, 516, -518 } + { 522, 461, 457, -519 } + { 523, 522, 518, -520 } + { 524, 523, 519, -521 } + { 525, 524, 520, -522 } + { 526, 465, 461, -523 } + { 527, 526, 522, -524 } + { 528, 527, 523, -525 } + { 529, 528, 524, -526 } + { 466, 405, 465, -527 } + { 467, 466, 526, -528 } + { 468, 467, 527, -529 } + { 469, 468, 528, -530 } + { 289, 288, 283, -285 } + { 293, 288, 289, -295 } + { 289, 290, 295, -295 } + { 285, 290, 289, -285 } + { 269, 270, 275, -275 } + { 265, 270, 269, -265 } + { 269, 268, 263, -265 } + { 273, 268, 269, -275 } + { 322, 323, 327, -327 } + { 319, 323, 322, -319 } + { 324, 328, 327, -324 } + { 320, 324, 323, -320 } + { 304, 308, 307, -304 } + { 308, 312, 311, -308 } + { 307, 306, 302, -304 } + { 310, 306, 307, -312 } + { 331, 330, 365, -367 } + { 335, 330, 331, -337 } + { 341, 340, 335, -337 } + { 345, 340, 341, -347 } + { 361, 360, 355, -357 } + { 365, 360, 361, -367 } + { 358, 363, 362, -358 } + { 367, 362, 363, -369 } + { 361, 362, 367, -367 } + { 353, 352, 347, -349 } + { 357, 352, 353, -359 } + { 343, 342, 337, -339 } + { 347, 342, 343, -349 } + { 342, 341, 336, -338 } + { 346, 341, 342, -348 } + { 397, 369, 333, -369 } + { 370, 369, 397, -399 } + { 397, 393, 394, -399 } + { 363, 393, 397, -369 } + { 389, 393, 363, -359 } + { 394, 393, 389, -391 } + { 389, 385, 386, -391 } + { 353, 385, 389, -359 } + { 385, 381, 382, -387 } + { 348, 381, 385, -354 } + { 381, 377, 378, -383 } + { 343, 377, 381, -349 } + { 377, 373, 374, -379 } + { 338, 373, 377, -344 } + { 369, 373, 338, -334 } + { 374, 373, 369, -371 } + { 372, 376, 375, -372 } + { 400, 372, 371, -400 } + { 396, 400, 399, -396 } + { 391, 392, 396, -396 } + { 387, 388, 392, -392 } + { 383, 384, 388, -388 } + { 379, 380, 384, -384 } + { 374, 375, 379, -379 } + { 376, 380, 379, -376 } + { 32, 31, 26, -28 } + { 30, 25, 26, -32 } + -Geometry face length: 517 + -Face Layer length: 0 diff --git a/Test/teapot_v3.hxa b/Test/teapot_v3.hxa new file mode 100644 index 0000000000000000000000000000000000000000..756683233862b6011efd439f5596033f13f13e63 GIT binary patch literal 21871 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 h^K#&$0da19O}C6L2)GxM%Ud{{xYLvV{Nu literal 0 HcmV?d00001 diff --git a/Test/teapot_v3_print.txt b/Test/teapot_v3_print.txt new file mode 100644 index 0000000..8818e41 --- /dev/null +++ b/Test/teapot_v3_print.txt @@ -0,0 +1,1103 @@ +HxA version: 3 +Node lenght: 1 +-Node id: 0 + -Node type: geometry + -Node meta length: 38 + -Meta u64 "Texture resolution" [1]: { 1024 } + -Meta u64 "Separate hard edges" [1]: { 18446744071654704384 } + -Meta u64 "Aspect" [1]: { 0 } + -Meta u64 "Use normal" [1]: { 18446744071654704385 } + -Meta u64 "Overlap Identical parts" [1]: { 18446744071654704384 } + -Meta u64 "Overlap mirrored parts" [1]: { 18446744071654704384 } + -Meta u64 "Enable Experimental unwrapping" [1]: { 18446744071654704384 } + -Meta u64 "Supress validation errors" [1]: { 18446744071654704384 } + -Meta u64 "Quads" [1]: { 18446744071654704385 } + -Meta u64 "Vertex Weld" [1]: { 18446744071654704385 } + -Meta u64 "Flat Soft surface" [1]: { 18446744071654704385 } + -Meta u64 "Cones" [1]: { 18446744071654704385 } + -Meta u64 "Cone Ratio" [1]: { 0 } + -Meta u64 "Strips" [1]: { 18446744071654704385 } + -Meta u64 "Patches" [1]: { 18446744071654704385 } + -Meta u64 "Planes" [1]: { 18446744071654704385 } + -Meta u64 "Flatness" [1]: { 18446744072635809792 } + -Meta u64 "Merge" [1]: { 18446744071654704385 } + -Meta u64 "Merge limit" [1]: { 0 } + -Meta u64 "Pre-Smooth" [1]: { 18446744071654704385 } + -Meta u64 "Soft unfold" [1]: { 18446744071654704384 } + -Meta u64 "Tubes" [1]: { 18446744071654704385 } + -Meta u64 "Junctions" [1]: { 18446744071654704385 } + -Meta u64 "Extra ordenary point" [1]: { 18446744071654704384 } + -Meta u64 "Angle based flatening" [1]: { 18446744071654704385 } + -Meta u64 "Smooth" [1]: { 18446744071654704385 } + -Meta u64 "Repair Smooth" [1]: { 18446744071654704385 } + -Meta u64 "Repair" [1]: { 18446744071654704384 } + -Meta u64 "Squares" [1]: { 18446744071654704385 } + -Meta u64 "Relax" [1]: { 18446744071654704384 } + -Meta u64 "Relaxation iterations" [1]: { 50 } + -Meta u64 "Expand" [1]: { 0 } + -Meta u64 "Cut" [1]: { 18446744071654704385 } + -Meta u64 "Stretch" [1]: { 18446744071654704385 } + -Meta u64 "Match" [1]: { 18446744071654704385 } + -Meta u64 "Rasterization resolution" [1]: { 64 } + -Meta u64 "Packing iterations" [1]: { 4 } + -Meta u64 "Validate" [1]: { 18446744071654704385 } + -Geometry vertex length: 530 + -Vertex Layer length: 1 + Layer name: vertex + Layer components: 3 + Layer type: f64 + { 4.062660, 2.834570, -0.110804 } + { 4.007140, 3.044430, -0.110804 } + { 4.071550, 3.114380, -0.110804 } + { 4.202570, 3.044430, -0.110804 } + { 4.346920, 2.834570, -0.110804 } + { 3.754250, 2.834570, 1.451170 } + { 3.703030, 3.044430, 1.429380 } + { 3.762440, 3.114380, 1.454660 } + { 3.883310, 3.044430, 1.506090 } + { 4.016470, 2.834570, 1.562740 } + { 2.908590, 2.834570, 2.714680 } + { 2.869170, 3.044430, 2.675270 } + { 2.914900, 3.114380, 2.720990 } + { 3.007920, 3.044430, 2.814020 } + { 3.110410, 2.834570, 2.916500 } + { 1.645080, 2.834570, 3.560340 } + { 1.623290, 3.044430, 3.509120 } + { 1.648570, 3.114380, 3.568530 } + { 1.699990, 3.044430, 3.689400 } + { 1.756650, 2.834570, 3.822560 } + { 0.083103, 2.834570, 3.868760 } + { 0.083103, 3.044430, 3.813240 } + { 0.083103, 3.114380, 3.877640 } + { 0.083103, 3.044430, 4.008660 } + { 0.083103, 2.834570, 4.153010 } + { -1.586800, 2.834570, 3.560340 } + { -1.502620, 3.044430, 3.509120 } + { -1.495850, 3.114380, 3.568530 } + { -1.535470, 3.044430, 3.689400 } + { -1.590440, 2.834570, 3.822560 } + { -2.838320, 2.834570, 2.714680 } + { -2.743440, 3.044430, 2.675270 } + { -2.760680, 3.114380, 2.720990 } + { -2.843220, 3.044430, 2.814020 } + { -2.944210, 2.834570, 2.916500 } + { -3.624020, 2.834570, 1.451170 } + { -3.552000, 3.044430, 1.429380 } + { -3.600730, 3.114380, 1.454660 } + { -3.717670, 3.044430, 1.506090 } + { -3.850270, 2.834570, 1.562740 } + { -3.896460, 2.834570, -0.110804 } + { -3.840940, 3.044430, -0.110804 } + { -3.905340, 3.114380, -0.110804 } + { -4.036360, 3.044430, -0.110804 } + { -4.180710, 2.834570, -0.110804 } + { -3.588040, 2.834570, -1.672780 } + { -3.536830, 3.044430, -1.650990 } + { -3.596240, 3.114380, -1.676270 } + { -3.717110, 3.044430, -1.727690 } + { -3.850270, 2.834570, -1.784350 } + { -2.742380, 2.834570, -2.936290 } + { -2.702970, 3.044430, -2.896870 } + { -2.748690, 3.114380, -2.942600 } + { -2.841720, 3.044430, -3.035620 } + { -2.944210, 2.834570, -3.138110 } + { -1.478870, 2.834570, -3.781950 } + { -1.457080, 3.044430, -3.730730 } + { -1.482360, 3.114380, -3.790140 } + { -1.533790, 3.044430, -3.911010 } + { -1.590440, 2.834570, -4.044170 } + { 0.083103, 2.834570, -4.090360 } + { 0.083103, 3.044430, -4.034840 } + { 0.083103, 3.114380, -4.099250 } + { 0.083103, 3.044430, -4.230270 } + { 0.083103, 2.834570, -4.374620 } + { 1.645080, 2.834570, -3.781950 } + { 1.623290, 3.044430, -3.730730 } + { 1.648570, 3.114380, -3.790140 } + { 1.699990, 3.044430, -3.911010 } + { 1.756650, 2.834570, -4.044170 } + { 2.908590, 2.834570, -2.936290 } + { 2.869170, 3.044430, -2.896870 } + { 2.914900, 3.114380, -2.942600 } + { 3.007920, 3.044430, -3.035620 } + { 3.110410, 2.834570, -3.138110 } + { 3.754250, 2.834570, -1.672780 } + { 3.703030, 3.044430, -1.650990 } + { 3.762440, 3.114380, -1.676270 } + { 3.883310, 3.044430, -1.727690 } + { 4.016470, 2.834570, -1.784350 } + { 4.868790, 1.718650, -0.110804 } + { 5.324040, 0.622714, -0.110804 } + { 5.646050, -0.433246, -0.110804 } + { 5.768190, -1.429250, -0.110804 } + { 4.497900, 1.718650, 1.767580 } + { 4.917870, 0.622714, 1.946260 } + { 5.214920, -0.433246, 2.072650 } + { 5.327590, -1.429250, 2.120590 } + { 3.480940, 1.718650, 3.287030 } + { 3.804170, 0.622714, 3.610260 } + { 4.032790, -0.433246, 3.838890 } + { 4.119510, -1.429250, 3.925610 } + { 1.961480, 1.718650, 4.303990 } + { 2.140170, 0.622714, 4.723960 } + { 2.266560, -0.433246, 5.021010 } + { 2.314500, -1.429250, 5.133690 } + { 0.083103, 1.718650, 4.674880 } + { 0.083103, 0.622714, 5.130130 } + { 0.083103, -0.433246, 5.452140 } + { 0.083103, -1.429250, 5.574280 } + { -1.795280, 1.718650, 4.303990 } + { -1.973970, 0.622714, 4.723960 } + { -2.100350, -0.433246, 5.021010 } + { -2.148290, -1.429250, 5.133690 } + { -3.314740, 1.718650, 3.287030 } + { -3.637960, 0.622714, 3.610260 } + { -3.866590, -0.433246, 3.838890 } + { -3.953310, -1.429250, 3.925610 } + { -4.331690, 1.718650, 1.767580 } + { -4.751660, 0.622714, 1.946260 } + { -5.048710, -0.433246, 2.072650 } + { -5.161390, -1.429250, 2.120590 } + { -4.702580, 1.718650, -0.110804 } + { -5.157840, 0.622714, -0.110804 } + { -5.479840, -0.433246, -0.110804 } + { -5.601980, -1.429250, -0.110804 } + { -4.331690, 1.718650, -1.989190 } + { -4.751660, 0.622714, -2.167870 } + { -5.048710, -0.433246, -2.294260 } + { -5.161390, -1.429250, -2.342200 } + { -3.314740, 1.718650, -3.508640 } + { -3.637960, 0.622714, -3.831870 } + { -3.866590, -0.433246, -4.060490 } + { -3.953310, -1.429250, -4.147210 } + { -1.795280, 1.718650, -4.525600 } + { -1.973970, 0.622714, -4.945570 } + { -2.100350, -0.433246, -5.242620 } + { -2.148290, -1.429250, -5.355290 } + { 0.083103, 1.718650, -4.896490 } + { 0.083103, 0.622714, -5.351740 } + { 0.083103, -0.433246, -5.673750 } + { 0.083103, -1.429250, -5.795890 } + { 1.961480, 1.718650, -4.525600 } + { 2.140170, 0.622714, -4.945570 } + { 2.266560, -0.433246, -5.242620 } + { 2.314500, -1.429250, -5.355290 } + { 3.480940, 1.718650, -3.508640 } + { 3.804170, 0.622714, -3.831870 } + { 4.032790, -0.433246, -4.060490 } + { 4.119510, -1.429250, -4.147210 } + { 4.497900, 1.718650, -1.989190 } + { 4.917870, 0.622714, -2.167870 } + { 5.214920, -0.433246, -2.294260 } + { 5.327590, -1.429250, -2.342200 } + { 5.546110, -2.272020, -0.110804 } + { 5.057550, -2.894930, -0.110804 } + { 4.568990, -3.317980, -0.110804 } + { 4.346920, -3.561150, -0.110804 } + { 5.122730, -2.272020, 2.033430 } + { 4.672030, -2.894930, 1.841670 } + { 4.221330, -3.317980, 1.649910 } + { 4.016470, -3.561150, 1.562740 } + { 3.961840, -2.272020, 3.767930 } + { 3.614960, -2.894930, 3.421060 } + { 3.268080, -3.317980, 3.074180 } + { 3.110410, -3.561150, 2.916500 } + { 2.227330, -2.272020, 4.928820 } + { 2.035570, -2.894930, 4.478130 } + { 1.843810, -3.317980, 4.027430 } + { 1.756650, -3.561150, 3.822560 } + { 0.083103, -2.272020, 5.352210 } + { 0.083103, -2.894930, 4.863650 } + { 0.083103, -3.317980, 4.375080 } + { 0.083103, -3.561150, 4.153010 } + { -2.061130, -2.272020, 4.928820 } + { -1.869370, -2.894930, 4.478130 } + { -1.677610, -3.317980, 4.027430 } + { -1.590440, -3.561150, 3.822560 } + { -3.795640, -2.272020, 3.767930 } + { -3.448760, -2.894930, 3.421060 } + { -3.101880, -3.317980, 3.074180 } + { -2.944210, -3.561150, 2.916500 } + { -4.956530, -2.272020, 2.033430 } + { -4.505830, -2.894930, 1.841670 } + { -4.055130, -3.317980, 1.649910 } + { -3.850270, -3.561150, 1.562740 } + { -5.379910, -2.272020, -0.110804 } + { -4.891350, -2.894930, -0.110804 } + { -4.402790, -3.317980, -0.110804 } + { -4.180710, -3.561150, -0.110804 } + { -4.956530, -2.272020, -2.255040 } + { -4.505830, -2.894930, -2.063270 } + { -4.055130, -3.317980, -1.871510 } + { -3.850270, -3.561150, -1.784350 } + { -3.795640, -2.272020, -3.989540 } + { -3.448760, -2.894930, -3.642660 } + { -3.101880, -3.317980, -3.295780 } + { -2.944210, -3.561150, -3.138110 } + { -2.061130, -2.272020, -5.150430 } + { -1.869370, -2.894930, -4.699730 } + { -1.677610, -3.317980, -4.249030 } + { -1.590440, -3.561150, -4.044170 } + { 0.083103, -2.272020, -5.573820 } + { 0.083103, -2.894930, -5.085250 } + { 0.083103, -3.317980, -4.596690 } + { 0.083103, -3.561150, -4.374620 } + { 2.227330, -2.272020, -5.150430 } + { 2.035570, -2.894930, -4.699730 } + { 1.843810, -3.317980, -4.249030 } + { 1.756650, -3.561150, -4.044170 } + { 3.961840, -2.272020, -3.989540 } + { 3.614960, -2.894930, -3.642660 } + { 3.268080, -3.317980, -3.295780 } + { 3.110410, -3.561150, -3.138110 } + { 5.122730, -2.272020, -2.255040 } + { 4.672030, -2.894930, -2.063270 } + { 4.221330, -3.317980, -1.871510 } + { 4.016470, -3.561150, -1.784350 } + { 4.250310, -3.717720, -0.110804 } + { 3.733990, -3.854290, -0.110804 } + { 2.458180, -3.950890, -0.110804 } + { 0.083103, -3.987540, -0.110804 } + { 3.927360, -3.717720, 1.524830 } + { 3.451050, -3.854290, 1.322170 } + { 2.274110, -3.950890, 0.821414 } + { 3.041820, -3.717720, 2.847920 } + { 2.675230, -3.854290, 2.481330 } + { 1.769410, -3.950890, 1.575500 } + { 1.718730, -3.717720, 3.733450 } + { 1.516080, -3.854290, 3.257140 } + { 1.015320, -3.950890, 2.080210 } + { 0.083103, -3.717720, 4.056410 } + { 0.083103, -3.854290, 3.540090 } + { 0.083103, -3.950890, 2.264270 } + { -1.552530, -3.717720, 3.733450 } + { -1.349870, -3.854290, 3.257140 } + { -0.849115, -3.950890, 2.080210 } + { -2.875620, -3.717720, 2.847920 } + { -2.509030, -3.854290, 2.481330 } + { -1.603200, -3.950890, 1.575500 } + { -3.761150, -3.717720, 1.524830 } + { -3.284840, -3.854290, 1.322170 } + { -2.107910, -3.950890, 0.821414 } + { -4.084110, -3.717720, -0.110804 } + { -3.567790, -3.854290, -0.110804 } + { -2.291980, -3.950890, -0.110804 } + { -3.761150, -3.717720, -1.746430 } + { -3.284840, -3.854290, -1.543780 } + { -2.107910, -3.950890, -1.043020 } + { -2.875620, -3.717720, -3.069520 } + { -2.509030, -3.854290, -2.702940 } + { -1.603200, -3.950890, -1.797110 } + { -1.552530, -3.717720, -3.955060 } + { -1.349870, -3.854290, -3.478750 } + { -0.849115, -3.950890, -2.301810 } + { 0.083103, -3.717720, -4.278020 } + { 0.083103, -3.854290, -3.761690 } + { 0.083103, -3.950890, -2.485880 } + { 1.718730, -3.717720, -3.955060 } + { 1.516080, -3.854290, -3.478750 } + { 1.015320, -3.950890, -2.301810 } + { 3.041820, -3.717720, -3.069520 } + { 2.675230, -3.854290, -2.702940 } + { 1.769410, -3.950890, -1.797110 } + { 3.927360, -3.717720, -1.746430 } + { 3.451050, -3.854290, -1.543780 } + { 2.274110, -3.950890, -1.043020 } + { -4.464970, 1.768610, -0.110804 } + { -5.792970, 1.758620, -0.110804 } + { -6.774530, 1.688670, -0.110804 } + { -7.383010, 1.498790, -0.110804 } + { -7.591760, 1.129040, -0.110804 } + { -4.420550, 1.868550, 0.368876 } + { -5.832520, 1.856990, 0.368876 } + { -6.868910, 1.776110, 0.368876 } + { -7.507240, 1.556570, 0.368876 } + { -7.725010, 1.129040, 0.368876 } + { -4.322840, 2.088400, 0.528769 } + { -5.919550, 2.073410, 0.528769 } + { -7.076550, 1.968480, 0.528769 } + { -7.780530, 1.683670, 0.528769 } + { -8.018140, 1.129040, 0.528769 } + { -4.225130, 2.308250, 0.368876 } + { -6.006570, 2.289830, 0.368876 } + { -7.284190, 2.160850, 0.368876 } + { -8.053810, 1.810770, 0.368876 } + { -8.311280, 1.129040, 0.368876 } + { -4.180710, 2.408190, -0.110804 } + { -6.046130, 2.388200, -0.110804 } + { -7.378570, 2.248290, -0.110804 } + { -8.178040, 1.868550, -0.110804 } + { -8.444530, 1.129040, -0.110804 } + { -4.225130, 2.308250, -0.590483 } + { -6.006570, 2.289830, -0.590483 } + { -7.284190, 2.160850, -0.590483 } + { -8.053810, 1.810770, -0.590483 } + { -8.311280, 1.129040, -0.590483 } + { -4.322840, 2.088400, -0.750376 } + { -5.919550, 2.073410, -0.750376 } + { -7.076550, 1.968480, -0.750376 } + { -7.780530, 1.683670, -0.750376 } + { -8.018140, 1.129040, -0.750376 } + { -4.420550, 1.868550, -0.590483 } + { -5.832520, 1.856990, -0.590483 } + { -6.868910, 1.776110, -0.590483 } + { -7.507240, 1.556570, -0.590483 } + { -7.725010, 1.129040, -0.590483 } + { -7.480730, 0.549430, -0.110804 } + { -7.129850, -0.150103, -0.110804 } + { -6.512480, -0.849634, -0.110804 } + { -5.601980, -1.429250, -0.110804 } + { -7.601830, 0.493477, 0.368876 } + { -7.215900, -0.235462, 0.368876 } + { -6.542670, -0.955033, 0.368876 } + { -5.557570, -1.562490, 0.368876 } + { -7.868240, 0.370383, 0.528769 } + { -7.405220, -0.423253, 0.528769 } + { -6.609090, -1.186910, 0.528769 } + { -5.459860, -1.855630, 0.528769 } + { -8.134660, 0.247288, 0.368876 } + { -7.594540, -0.611044, 0.368876 } + { -6.675500, -1.418780, 0.368876 } + { -5.362140, -2.148770, 0.368876 } + { -8.255760, 0.191336, -0.110804 } + { -7.680590, -0.696404, -0.110804 } + { -6.705690, -1.524180, -0.110804 } + { -5.317730, -2.282010, -0.110804 } + { -8.134660, 0.247288, -0.590483 } + { -7.594540, -0.611044, -0.590483 } + { -6.675500, -1.418780, -0.590483 } + { -5.362140, -2.148770, -0.590483 } + { -7.868240, 0.370383, -0.750376 } + { -7.405220, -0.423253, -0.750376 } + { -6.609090, -1.186910, -0.750376 } + { -5.459860, -1.855630, -0.750376 } + { -7.601830, 0.493477, -0.590483 } + { -7.215900, -0.235462, -0.590483 } + { -6.542670, -0.955033, -0.590483 } + { -5.557570, -1.562490, -0.590483 } + { 4.915430, 0.063088, -0.110804 } + { 6.278960, 0.376212, -0.110804 } + { 6.869670, 1.129040, -0.110804 } + { 7.193900, 2.041760, -0.110804 } + { 7.757970, 2.834570, -0.110804 } + { 4.915430, -0.303333, 0.944490 } + { 6.383050, 0.104519, 0.842059 } + { 7.002920, 0.970814, 0.616710 } + { 7.356290, 1.984510, 0.391361 } + { 8.024460, 2.834570, 0.288929 } + { 4.915430, -1.109460, 1.296260 } + { 6.612070, -0.493206, 1.159680 } + { 7.296050, 0.622714, 0.859214 } + { 7.713550, 1.858550, 0.558749 } + { 8.610730, 2.834570, 0.422173 } + { 4.915430, -1.915590, 0.944490 } + { 6.841080, -1.090930, 0.842059 } + { 7.589190, 0.274614, 0.616710 } + { 8.070810, 1.732600, 0.391361 } + { 9.197000, 2.834570, 0.288929 } + { 4.915430, -2.282010, -0.110804 } + { 6.945180, -1.362620, -0.110804 } + { 7.722440, 0.116386, -0.110804 } + { 8.233210, 1.675340, -0.110804 } + { 9.463490, 2.834570, -0.110804 } + { 4.915430, -1.915590, -1.166100 } + { 6.841080, -1.090930, -1.063670 } + { 7.589190, 0.274614, -0.838317 } + { 8.070810, 1.732600, -0.612968 } + { 9.197000, 2.834570, -0.510536 } + { 4.915430, -1.109460, -1.517860 } + { 6.612070, -0.493206, -1.381290 } + { 7.296050, 0.622714, -1.080820 } + { 7.713550, 1.858550, -0.780356 } + { 8.610730, 2.834570, -0.643780 } + { 4.915430, -0.303333, -1.166100 } + { 6.383050, 0.104519, -1.063670 } + { 7.002920, 0.970814, -0.838317 } + { 7.356290, 1.984510, -0.612968 } + { 8.024460, 2.834570, -0.510536 } + { 7.962270, 2.954490, -0.110804 } + { 8.113290, 2.994460, -0.110804 } + { 8.157700, 2.954490, -0.110804 } + { 8.042220, 2.834570, -0.110804 } + { 8.247670, 2.960340, 0.263946 } + { 8.381160, 3.003830, 0.208983 } + { 8.385150, 2.962680, 0.154019 } + { 8.219880, 2.834570, 0.129036 } + { 8.875550, 2.973220, 0.388862 } + { 8.970490, 3.024440, 0.315578 } + { 8.885550, 2.980720, 0.242294 } + { 8.610730, 2.834570, 0.208983 } + { 9.503430, 2.986110, 0.263946 } + { 9.559820, 3.045050, 0.208983 } + { 9.385940, 2.998750, 0.154019 } + { 9.001580, 2.834570, 0.129036 } + { 9.788830, 2.991960, -0.110804 } + { 9.827690, 3.054420, -0.110804 } + { 9.613390, 3.006950, -0.110804 } + { 9.179240, 2.834570, -0.110804 } + { 9.503430, 2.986110, -0.485553 } + { 9.559820, 3.045050, -0.430590 } + { 9.385940, 2.998750, -0.375626 } + { 9.001580, 2.834570, -0.350643 } + { 8.875550, 2.973220, -0.610469 } + { 8.970490, 3.024440, -0.537185 } + { 8.885550, 2.980720, -0.463901 } + { 8.610730, 2.834570, -0.430590 } + { 8.247670, 2.960340, -0.485553 } + { 8.381160, 3.003830, -0.430590 } + { 8.385150, 2.962680, -0.375626 } + { 8.219880, 2.834570, -0.350643 } + { 0.083103, 4.966470, -0.110804 } + { 1.051340, 4.826570, -0.110804 } + { 1.006930, 4.486800, -0.110804 } + { 0.642728, 4.067080, -0.110804 } + { 0.651611, 3.687330, -0.110804 } + { 0.976642, 4.826570, 0.270243 } + { 0.935632, 4.486800, 0.252698 } + { 0.599470, 4.067080, 0.109187 } + { 0.607552, 3.687330, 0.112336 } + { 0.771453, 4.826570, 0.577547 } + { 0.739819, 4.486800, 0.545913 } + { 0.480736, 4.067080, 0.286830 } + { 0.486744, 3.687330, 0.292838 } + { 0.464149, 4.826570, 0.782736 } + { 0.446604, 4.486800, 0.741726 } + { 0.303093, 4.067080, 0.405564 } + { 0.306242, 3.687330, 0.413646 } + { 0.083103, 4.826570, 0.857438 } + { 0.083103, 4.486800, 0.813023 } + { 0.083103, 4.067080, 0.448822 } + { 0.083103, 3.687330, 0.457705 } + { -0.297944, 4.826570, 0.782736 } + { -0.280399, 4.486800, 0.741726 } + { -0.136888, 4.067080, 0.405564 } + { -0.140037, 3.687330, 0.413646 } + { -0.605248, 4.826570, 0.577547 } + { -0.573614, 4.486800, 0.545913 } + { -0.314531, 4.067080, 0.286830 } + { -0.320539, 3.687330, 0.292838 } + { -0.810437, 4.826570, 0.270243 } + { -0.769427, 4.486800, 0.252698 } + { -0.433265, 4.067080, 0.109187 } + { -0.441347, 3.687330, 0.112336 } + { -0.885139, 4.826570, -0.110804 } + { -0.840724, 4.486800, -0.110804 } + { -0.476523, 4.067080, -0.110804 } + { -0.485406, 3.687330, -0.110804 } + { -0.810437, 4.826570, -0.491850 } + { -0.769427, 4.486800, -0.474305 } + { -0.433265, 4.067080, -0.330794 } + { -0.441347, 3.687330, -0.333943 } + { -0.605248, 4.826570, -0.799154 } + { -0.573614, 4.486800, -0.767520 } + { -0.314531, 4.067080, -0.508437 } + { -0.320539, 3.687330, -0.514445 } + { -0.297944, 4.826570, -1.004340 } + { -0.280399, 4.486800, -0.963333 } + { -0.136888, 4.067080, -0.627171 } + { -0.140037, 3.687330, -0.635253 } + { 0.083103, 4.826570, -1.079040 } + { 0.083103, 4.486800, -1.034630 } + { 0.083103, 4.067080, -0.670429 } + { 0.083103, 3.687330, -0.679312 } + { 0.464149, 4.826570, -1.004340 } + { 0.446604, 4.486800, -0.963333 } + { 0.303093, 4.067080, -0.627171 } + { 0.306242, 3.687330, -0.635253 } + { 0.771453, 4.826570, -0.799154 } + { 0.739819, 4.486800, -0.767520 } + { 0.480736, 4.067080, -0.508437 } + { 0.486744, 3.687330, -0.514445 } + { 0.976642, 4.826570, -0.491850 } + { 0.935632, 4.486800, -0.474305 } + { 0.599470, 4.067080, -0.330794 } + { 0.607552, 3.687330, -0.333943 } + { 1.380010, 3.434170, -0.110804 } + { 2.428200, 3.260950, -0.110804 } + { 3.369790, 3.087730, -0.110804 } + { 3.778410, 2.834570, -0.110804 } + { 1.279500, 3.434170, 0.398234 } + { 2.246460, 3.260950, 0.809647 } + { 3.115070, 3.087730, 1.179220 } + { 3.492020, 2.834570, 1.339600 } + { 1.003910, 3.434170, 0.810003 } + { 1.748120, 3.260950, 1.554220 } + { 2.416650, 3.087730, 2.222750 } + { 2.706770, 2.834570, 2.512860 } + { 0.592140, 3.434170, 1.085600 } + { 1.003550, 3.260950, 2.052550 } + { 1.373130, 3.087730, 2.921170 } + { 1.533510, 2.834570, 3.298120 } + { 0.083103, 3.434170, 1.186110 } + { 0.083103, 3.260950, 2.234290 } + { 0.083103, 3.087730, 3.175890 } + { 0.083103, 2.834570, 3.584500 } + { -0.425935, 3.434170, 1.085600 } + { -0.837348, 3.260950, 2.052550 } + { -1.206920, 3.087730, 2.921170 } + { -1.367300, 2.834570, 3.298120 } + { -0.837704, 3.434170, 0.810003 } + { -1.581920, 3.260950, 1.554220 } + { -2.250450, 3.087730, 2.222750 } + { -2.540560, 2.834570, 2.512860 } + { -1.113300, 3.434170, 0.398234 } + { -2.080250, 3.260950, 0.809647 } + { -2.948870, 3.087730, 1.179220 } + { -3.325820, 2.834570, 1.339600 } + { -1.213810, 3.434170, -0.110804 } + { -2.262000, 3.260950, -0.110804 } + { -3.203590, 3.087730, -0.110804 } + { -3.612200, 2.834570, -0.110804 } + { -1.113300, 3.434170, -0.619841 } + { -2.080250, 3.260950, -1.031250 } + { -2.948870, 3.087730, -1.400830 } + { -3.325820, 2.834570, -1.561210 } + { -0.837704, 3.434170, -1.031610 } + { -1.581920, 3.260950, -1.775820 } + { -2.250450, 3.087730, -2.444350 } + { -2.540560, 2.834570, -2.734470 } + { -0.425935, 3.434170, -1.307200 } + { -0.837348, 3.260950, -2.274160 } + { -1.206920, 3.087730, -3.142770 } + { -1.367300, 2.834570, -3.519720 } + { 0.083103, 3.434170, -1.407710 } + { 0.083103, 3.260950, -2.455900 } + { 0.083103, 3.087730, -3.397490 } + { 0.083103, 2.834570, -3.806110 } + { 0.592140, 3.434170, -1.307200 } + { 1.003550, 3.260950, -2.274160 } + { 1.373130, 3.087730, -3.142770 } + { 1.533510, 2.834570, -3.519720 } + { 1.003910, 3.434170, -1.031610 } + { 1.748120, 3.260950, -1.775820 } + { 2.416650, 3.087730, -2.444350 } + { 2.706770, 2.834570, -2.734470 } + { 1.279500, 3.434170, -0.619841 } + { 2.246460, 3.260950, -1.031250 } + { 3.115070, 3.087730, -1.400830 } + { 3.492020, 2.834570, -1.561210 } + -Geometry edge length: 2026 + -Corner Layer length: 1 + Layer name: reference + Layer components: 1 + Layer type: i32 + { 6, 5, 0, -2 } + { 7, 6, 1, -3 } + { 8, 7, 2, -4 } + { 9, 8, 3, -5 } + { 11, 10, 5, -7 } + { 12, 11, 6, -8 } + { 13, 12, 7, -9 } + { 14, 13, 8, -10 } + { 16, 15, 10, -12 } + { 17, 16, 11, -13 } + { 18, 17, 12, -14 } + { 19, 18, 13, -15 } + { 21, 20, 15, -17 } + { 22, 21, 16, -18 } + { 23, 22, 17, -19 } + { 24, 23, 18, -20 } + { 26, 25, 20, -22 } + { 27, 26, 21, -23 } + { 28, 27, 22, -24 } + { 29, 28, 23, -25 } + { 33, 32, 27, -29 } + { 34, 33, 28, -30 } + { 36, 35, 30, -32 } + { 37, 36, 31, -33 } + { 38, 37, 32, -34 } + { 39, 38, 33, -35 } + { 41, 40, 35, -37 } + { 42, 41, 36, -38 } + { 43, 42, 37, -39 } + { 44, 43, 38, -40 } + { 46, 45, 40, -42 } + { 47, 46, 41, -43 } + { 48, 47, 42, -44 } + { 49, 48, 43, -45 } + { 51, 50, 45, -47 } + { 52, 51, 46, -48 } + { 53, 52, 47, -49 } + { 54, 53, 48, -50 } + { 56, 55, 50, -52 } + { 57, 56, 51, -53 } + { 58, 57, 52, -54 } + { 59, 58, 53, -55 } + { 61, 60, 55, -57 } + { 62, 61, 56, -58 } + { 63, 62, 57, -59 } + { 64, 63, 58, -60 } + { 66, 65, 60, -62 } + { 67, 66, 61, -63 } + { 68, 67, 62, -64 } + { 69, 68, 63, -65 } + { 71, 70, 65, -67 } + { 72, 71, 66, -68 } + { 73, 72, 67, -69 } + { 74, 73, 68, -70 } + { 76, 75, 70, -72 } + { 77, 76, 71, -73 } + { 78, 77, 72, -74 } + { 79, 78, 73, -75 } + { 1, 0, 75, -77 } + { 2, 1, 76, -78 } + { 3, 2, 77, -79 } + { 4, 3, 78, -80 } + { 84, 9, 4, -81 } + { 85, 84, 80, -82 } + { 86, 85, 81, -83 } + { 87, 86, 82, -84 } + { 88, 14, 9, -85 } + { 89, 88, 84, -86 } + { 90, 89, 85, -87 } + { 91, 90, 86, -88 } + { 92, 19, 14, -89 } + { 93, 92, 88, -90 } + { 94, 93, 89, -91 } + { 95, 94, 90, -92 } + { 96, 24, 19, -93 } + { 97, 96, 92, -94 } + { 98, 97, 93, -95 } + { 99, 98, 94, -96 } + { 100, 29, 24, -97 } + { 101, 100, 96, -98 } + { 102, 101, 97, -99 } + { 103, 102, 98, -100 } + { 104, 34, 29, -101 } + { 105, 104, 100, -102 } + { 106, 105, 101, -103 } + { 107, 106, 102, -104 } + { 108, 39, 34, -105 } + { 109, 108, 104, -106 } + { 110, 109, 105, -107 } + { 111, 110, 106, -108 } + { 112, 44, 39, -109 } + { 113, 112, 108, -110 } + { 114, 113, 109, -111 } + { 115, 114, 110, -112 } + { 116, 49, 44, -113 } + { 117, 116, 112, -114 } + { 118, 117, 113, -115 } + { 119, 118, 114, -116 } + { 120, 54, 49, -117 } + { 121, 120, 116, -118 } + { 122, 121, 117, -119 } + { 123, 122, 118, -120 } + { 124, 59, 54, -121 } + { 125, 124, 120, -122 } + { 126, 125, 121, -123 } + { 127, 126, 122, -124 } + { 128, 64, 59, -125 } + { 129, 128, 124, -126 } + { 130, 129, 125, -127 } + { 131, 130, 126, -128 } + { 132, 69, 64, -129 } + { 133, 132, 128, -130 } + { 134, 133, 129, -131 } + { 135, 134, 130, -132 } + { 136, 74, 69, -133 } + { 137, 136, 132, -134 } + { 138, 137, 133, -135 } + { 139, 138, 134, -136 } + { 140, 79, 74, -137 } + { 141, 140, 136, -138 } + { 142, 141, 137, -139 } + { 143, 142, 138, -140 } + { 80, 4, 79, -141 } + { 81, 80, 140, -142 } + { 82, 81, 141, -143 } + { 83, 82, 142, -144 } + { 148, 87, 83, -145 } + { 149, 148, 144, -146 } + { 150, 149, 145, -147 } + { 151, 150, 146, -148 } + { 152, 91, 87, -149 } + { 153, 152, 148, -150 } + { 154, 153, 149, -151 } + { 155, 154, 150, -152 } + { 156, 95, 91, -153 } + { 157, 156, 152, -154 } + { 158, 157, 153, -155 } + { 159, 158, 154, -156 } + { 160, 99, 95, -157 } + { 161, 160, 156, -158 } + { 162, 161, 157, -159 } + { 163, 162, 158, -160 } + { 164, 103, 99, -161 } + { 165, 164, 160, -162 } + { 166, 165, 161, -163 } + { 167, 166, 162, -164 } + { 168, 107, 103, -165 } + { 169, 168, 164, -166 } + { 170, 169, 165, -167 } + { 171, 170, 166, -168 } + { 172, 111, 107, -169 } + { 173, 172, 168, -170 } + { 174, 173, 169, -171 } + { 175, 174, 170, -172 } + { 176, 115, 111, -173 } + { 177, 176, 172, -174 } + { 178, 177, 173, -175 } + { 179, 178, 174, -176 } + { 180, 119, 115, -177 } + { 181, 180, 176, -178 } + { 182, 181, 177, -179 } + { 183, 182, 178, -180 } + { 184, 123, 119, -181 } + { 185, 184, 180, -182 } + { 186, 185, 181, -183 } + { 187, 186, 182, -184 } + { 188, 127, 123, -185 } + { 189, 188, 184, -186 } + { 190, 189, 185, -187 } + { 191, 190, 186, -188 } + { 192, 131, 127, -189 } + { 193, 192, 188, -190 } + { 194, 193, 189, -191 } + { 195, 194, 190, -192 } + { 196, 135, 131, -193 } + { 197, 196, 192, -194 } + { 198, 197, 193, -195 } + { 199, 198, 194, -196 } + { 200, 139, 135, -197 } + { 201, 200, 196, -198 } + { 202, 201, 197, -199 } + { 203, 202, 198, -200 } + { 204, 143, 139, -201 } + { 205, 204, 200, -202 } + { 206, 205, 201, -203 } + { 207, 206, 202, -204 } + { 144, 83, 143, -205 } + { 145, 144, 204, -206 } + { 146, 145, 205, -207 } + { 147, 146, 206, -208 } + { 212, 151, 147, -209 } + { 213, 212, 208, -210 } + { 214, 213, 209, -211 } + { 211, 214, -211 } + { 215, 155, 151, -213 } + { 216, 215, 212, -214 } + { 217, 216, 213, -215 } + { 211, 217, -215 } + { 218, 159, 155, -216 } + { 219, 218, 215, -217 } + { 220, 219, 216, -218 } + { 211, 220, -218 } + { 221, 163, 159, -219 } + { 222, 221, 218, -220 } + { 223, 222, 219, -221 } + { 211, 223, -221 } + { 224, 167, 163, -222 } + { 225, 224, 221, -223 } + { 226, 225, 222, -224 } + { 211, 226, -224 } + { 227, 171, 167, -225 } + { 228, 227, 224, -226 } + { 229, 228, 225, -227 } + { 211, 229, -227 } + { 230, 175, 171, -228 } + { 231, 230, 227, -229 } + { 232, 231, 228, -230 } + { 211, 232, -230 } + { 233, 179, 175, -231 } + { 234, 233, 230, -232 } + { 235, 234, 231, -233 } + { 211, 235, -233 } + { 236, 183, 179, -234 } + { 237, 236, 233, -235 } + { 238, 237, 234, -236 } + { 211, 238, -236 } + { 239, 187, 183, -237 } + { 240, 239, 236, -238 } + { 241, 240, 237, -239 } + { 211, 241, -239 } + { 242, 191, 187, -240 } + { 243, 242, 239, -241 } + { 244, 243, 240, -242 } + { 211, 244, -242 } + { 245, 195, 191, -243 } + { 246, 245, 242, -244 } + { 247, 246, 243, -245 } + { 211, 247, -245 } + { 248, 199, 195, -246 } + { 249, 248, 245, -247 } + { 250, 249, 246, -248 } + { 211, 250, -248 } + { 251, 203, 199, -249 } + { 252, 251, 248, -250 } + { 253, 252, 249, -251 } + { 211, 253, -251 } + { 254, 207, 203, -252 } + { 255, 254, 251, -253 } + { 256, 255, 252, -254 } + { 211, 256, -254 } + { 208, 147, 207, -255 } + { 209, 208, 254, -256 } + { 210, 209, 255, -257 } + { 211, 210, -257 } + { 263, 262, 257, -259 } + { 264, 263, 258, -260 } + { 265, 264, 259, -261 } + { 266, 265, 260, -262 } + { 268, 267, 262, -264 } + { 271, 270, 265, -267 } + { 273, 272, 267, -269 } + { 276, 275, 270, -272 } + { 278, 277, 272, -274 } + { 279, 278, 273, -275 } + { 280, 279, 274, -276 } + { 281, 280, 275, -277 } + { 283, 282, 277, -279 } + { 284, 283, 278, -280 } + { 285, 284, 279, -281 } + { 286, 285, 280, -282 } + { 288, 287, 282, -284 } + { 291, 290, 285, -287 } + { 293, 292, 287, -289 } + { 296, 295, 290, -292 } + { 258, 257, 292, -294 } + { 259, 258, 293, -295 } + { 260, 259, 294, -296 } + { 261, 260, 295, -297 } + { 301, 266, 261, -298 } + { 302, 301, 297, -299 } + { 303, 302, 298, -300 } + { 304, 303, 299, -301 } + { 305, 271, 266, -302 } + { 306, 305, 301, -303 } + { 309, 276, 271, -306 } + { 310, 309, 305, -307 } + { 313, 281, 276, -310 } + { 314, 313, 309, -311 } + { 315, 314, 310, -312 } + { 316, 315, 311, -313 } + { 317, 286, 281, -314 } + { 318, 317, 313, -315 } + { 319, 318, 314, -316 } + { 320, 319, 315, -317 } + { 321, 291, 286, -318 } + { 322, 321, 317, -319 } + { 325, 296, 291, -322 } + { 326, 325, 321, -323 } + { 297, 261, 296, -326 } + { 298, 297, 325, -327 } + { 299, 298, 326, -328 } + { 300, 299, 327, -329 } + { 335, 334, 329, -331 } + { 337, 336, 331, -333 } + { 338, 337, 332, -334 } + { 340, 339, 334, -336 } + { 345, 344, 339, -341 } + { 350, 349, 344, -346 } + { 351, 350, 345, -347 } + { 352, 351, 346, -348 } + { 355, 354, 349, -351 } + { 356, 355, 350, -352 } + { 357, 356, 351, -353 } + { 360, 359, 354, -356 } + { 362, 361, 356, -358 } + { 365, 364, 359, -361 } + { 330, 329, 364, -366 } + { 332, 331, 366, -368 } + { 333, 332, 367, -369 } + { 375, 374, 370, -372 } + { 383, 382, -379 } + { 378, 379, -384 } + { 387, 386, -383 } + { 382, 383, -388 } + { 391, 390, -387 } + { 386, 387, -392 } + { 395, 394, -391 } + { 390, 391, -396 } + { 399, 398, -395 } + { 394, 395, -400 } + { 371, 370, 398, -400 } + { 401, 402, -407 } + { 407, 406, 402, -404 } + { 408, 407, 403, -405 } + { 409, 408, 404, -406 } + { 401, 406, -411 } + { 411, 410, 406, -408 } + { 412, 411, 407, -409 } + { 413, 412, 408, -410 } + { 401, 410, -415 } + { 415, 414, 410, -412 } + { 416, 415, 411, -413 } + { 417, 416, 412, -414 } + { 401, 414, -419 } + { 419, 418, 414, -416 } + { 420, 419, 415, -417 } + { 421, 420, 416, -418 } + { 401, 418, -423 } + { 423, 422, 418, -420 } + { 424, 423, 419, -421 } + { 425, 424, 420, -422 } + { 401, 422, -427 } + { 427, 426, 422, -424 } + { 428, 427, 423, -425 } + { 429, 428, 424, -426 } + { 401, 426, -431 } + { 431, 430, 426, -428 } + { 432, 431, 427, -429 } + { 433, 432, 428, -430 } + { 401, 430, -435 } + { 435, 434, 430, -432 } + { 436, 435, 431, -433 } + { 437, 436, 432, -434 } + { 401, 434, -439 } + { 439, 438, 434, -436 } + { 440, 439, 435, -437 } + { 441, 440, 436, -438 } + { 401, 438, -443 } + { 443, 442, 438, -440 } + { 444, 443, 439, -441 } + { 445, 444, 440, -442 } + { 401, 442, -447 } + { 447, 446, 442, -444 } + { 448, 447, 443, -445 } + { 449, 448, 444, -446 } + { 401, 446, -451 } + { 451, 450, 446, -448 } + { 452, 451, 447, -449 } + { 453, 452, 448, -450 } + { 401, 450, -455 } + { 455, 454, 450, -452 } + { 456, 455, 451, -453 } + { 457, 456, 452, -454 } + { 401, 454, -459 } + { 459, 458, 454, -456 } + { 460, 459, 455, -457 } + { 461, 460, 456, -458 } + { 401, 458, -463 } + { 463, 462, 458, -460 } + { 464, 463, 459, -461 } + { 465, 464, 460, -462 } + { 401, 462, -403 } + { 403, 402, 462, -464 } + { 404, 403, 463, -465 } + { 405, 404, 464, -466 } + { 470, 409, 405, -467 } + { 471, 470, 466, -468 } + { 472, 471, 467, -469 } + { 473, 472, 468, -470 } + { 474, 413, 409, -471 } + { 475, 474, 470, -472 } + { 476, 475, 471, -473 } + { 477, 476, 472, -474 } + { 478, 417, 413, -475 } + { 479, 478, 474, -476 } + { 480, 479, 475, -477 } + { 481, 480, 476, -478 } + { 482, 421, 417, -479 } + { 483, 482, 478, -480 } + { 484, 483, 479, -481 } + { 485, 484, 480, -482 } + { 486, 425, 421, -483 } + { 487, 486, 482, -484 } + { 488, 487, 483, -485 } + { 489, 488, 484, -486 } + { 490, 429, 425, -487 } + { 491, 490, 486, -488 } + { 492, 491, 487, -489 } + { 493, 492, 488, -490 } + { 494, 433, 429, -491 } + { 495, 494, 490, -492 } + { 496, 495, 491, -493 } + { 497, 496, 492, -494 } + { 498, 437, 433, -495 } + { 499, 498, 494, -496 } + { 500, 499, 495, -497 } + { 501, 500, 496, -498 } + { 502, 441, 437, -499 } + { 503, 502, 498, -500 } + { 504, 503, 499, -501 } + { 505, 504, 500, -502 } + { 506, 445, 441, -503 } + { 507, 506, 502, -504 } + { 508, 507, 503, -505 } + { 509, 508, 504, -506 } + { 510, 449, 445, -507 } + { 511, 510, 506, -508 } + { 512, 511, 507, -509 } + { 513, 512, 508, -510 } + { 514, 453, 449, -511 } + { 515, 514, 510, -512 } + { 516, 515, 511, -513 } + { 517, 516, 512, -514 } + { 518, 457, 453, -515 } + { 519, 518, 514, -516 } + { 520, 519, 515, -517 } + { 521, 520, 516, -518 } + { 522, 461, 457, -519 } + { 523, 522, 518, -520 } + { 524, 523, 519, -521 } + { 525, 524, 520, -522 } + { 526, 465, 461, -523 } + { 527, 526, 522, -524 } + { 528, 527, 523, -525 } + { 529, 528, 524, -526 } + { 466, 405, 465, -527 } + { 467, 466, 526, -528 } + { 468, 467, 527, -529 } + { 469, 468, 528, -530 } + { 289, 288, 283, -285 } + { 293, 288, 289, -295 } + { 289, 290, 295, -295 } + { 285, 290, 289, -285 } + { 269, 270, 275, -275 } + { 265, 270, 269, -265 } + { 269, 268, 263, -265 } + { 273, 268, 269, -275 } + { 322, 323, 327, -327 } + { 319, 323, 322, -319 } + { 324, 328, 327, -324 } + { 320, 324, 323, -320 } + { 304, 308, 307, -304 } + { 308, 312, 311, -308 } + { 307, 306, 302, -304 } + { 310, 306, 307, -312 } + { 331, 330, 365, -367 } + { 335, 330, 331, -337 } + { 341, 340, 335, -337 } + { 345, 340, 341, -347 } + { 361, 360, 355, -357 } + { 365, 360, 361, -367 } + { 358, 363, 362, -358 } + { 367, 362, 363, -369 } + { 361, 362, 367, -367 } + { 353, 352, 347, -349 } + { 357, 352, 353, -359 } + { 343, 342, 337, -339 } + { 347, 342, 343, -349 } + { 342, 341, 336, -338 } + { 346, 341, 342, -348 } + { 397, 369, 333, -369 } + { 370, 369, 397, -399 } + { 397, 393, 394, -399 } + { 363, 393, 397, -369 } + { 389, 393, 363, -359 } + { 394, 393, 389, -391 } + { 389, 385, 386, -391 } + { 353, 385, 389, -359 } + { 385, 381, 382, -387 } + { 348, 381, 385, -354 } + { 381, 377, 378, -383 } + { 343, 377, 381, -349 } + { 377, 373, 374, -379 } + { 338, 373, 377, -344 } + { 369, 373, 338, -334 } + { 374, 373, 369, -371 } + { 372, 376, 375, -372 } + { 400, 372, 371, -400 } + { 396, 400, 399, -396 } + { 391, 392, 396, -396 } + { 387, 388, 392, -392 } + { 383, 384, 388, -388 } + { 379, 380, 384, -384 } + { 374, 375, 379, -379 } + { 376, 380, 379, -376 } + { 32, 31, 26, -28 } + { 30, 25, 26, -32 } + -Edge Layer length: 0 + -Geometry face length: 517 + -Face Layer length: 0 diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..7b90d1f --- /dev/null +++ b/build.zig @@ -0,0 +1,25 @@ +const std = @import("std"); + +pub fn build(b: *std.build.Builder) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + + // Standard release options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. + const mode = b.standardReleaseOptions(); + + const exe = b.addExecutable("hxa", "src/test.zig"); + exe.setTarget(target); + exe.setBuildMode(mode); + exe.install(); + + const exe_tests = b.addTest("src/test.zig"); + exe_tests.setTarget(target); + exe_tests.setBuildMode(mode); + + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&exe_tests.step); +} diff --git a/src/HxA.zig b/src/HxA.zig new file mode 100644 index 0000000..1957f5f --- /dev/null +++ b/src/HxA.zig @@ -0,0 +1,493 @@ +const std = @import("std"); +const Types = @import("types.zig"); + +pub const MAGIC_NUMBER = Types.MAGIC_NUMBER; +pub const VERSION = Types.VERSION; + +const NodeType = Types.NodeType; +const ImageType = Types.ImageType; +const MetaType = Types.MetaType; +const Meta = Types.Meta; +const LayerType = Types.LayerType; +const Layer = Types.Layer; +const LayerStack = Types.LayerStack; +const Node = Types.Node; +const File = Types.File; + +pub const Conventions = Types.Conventions {}; + +const Error = error { + UnexpectedEOF, + NoHxaFile, + NodeTypeNotRecognized, + MetaTypeNotRecognized, + LayerTypeNotRecognized, + UnexpectedPointerType, + InvalidComponents, +} || std.mem.Allocator.Error || std.fs.File.OpenError || std.os.ReadError || std.os.WriteError; + + +// TODO: The function relies on that alloc cannot fail (If it does an errdefer will trie to free unallocated memory) +// Read a HxA file and close it afterwards +pub fn load(allocator: std.mem.Allocator, file: *std.fs.File) Error!*File { + + // close file when done + defer file.close(); + + // temporary variables are used to make the free function work on error and avoid dirty memory + var len: u32 = undefined; + var version: u32 = undefined; + + // check magic number + var magic_number: @TypeOf(MAGIC_NUMBER) = undefined; + try loadData(file, &magic_number); + + if (magic_number != MAGIC_NUMBER) { + return Error.NoHxaFile; + } + + // allocate hxa object + const hxa = try allocator.create(File); + errdefer { + // std.debug.print("Error while reading file {s} at location {X}", .{ file., BYTES_READ }); + free(allocator, hxa); + } + + // get version + hxa.version = 0; hxa.len = 0; + + try loadData(file, &version); + hxa.version = version; + + // get node_count + try loadData(file, &len); + hxa.len = len; + + // allocate nodes + hxa.nodes = try allocator.alloc(Node, hxa.len); + + for (hxa.nodes) |*node| { + node.len = 0; + + try loadData(file, &node.type); + if (@enumToInt(node.type) >= @typeInfo(NodeType).Enum.fields.len) { + return Error.NodeTypeNotRecognized; + } + + // set zero defaults (needed for free to avoid dirty memory) + switch (node.type) { + .geometry => { + node.content.geometry.vertex_len = 0; + node.content.geometry.edge_corner_len = 0; + node.content.geometry.face_len = 0; + node.content.geometry.vertex_stack.len = 0; + node.content.geometry.edge_stack.len = 0; + node.content.geometry.face_stack.len = 0; + }, + .image => { + node.content.image.type = .cube; + node.content.image.resolution = [_]u32 {1, 1, 1}; + node.content.image.image_stack.len = 0; + }, + else => {}, + } + + // get number of nodes + try loadData(file, &len); + node.len = len; + + node.meta = try allocator.alloc(Meta, node.len); + try loadMeta(allocator, file, &node.meta); + + switch (node.type) { + .geometry => { + try loadData(file, &node.content.geometry.vertex_len); + try loadStack(allocator, file, &node.content.geometry.vertex_stack, node.content.geometry.vertex_len); + try loadData(file, &node.content.geometry.edge_corner_len); + try loadStack(allocator, file, &node.content.geometry.corner_stack, node.content.geometry.edge_corner_len); + if (hxa.version > 2) + try loadStack(allocator, file, &node.content.geometry.edge_stack, node.content.geometry.edge_corner_len); + try loadData(file, &node.content.geometry.face_len); + try loadStack(allocator, file, &node.content.geometry.face_stack, node.content.geometry.face_len); + }, + .image => { + try loadData(file, &node.content.image.type); + var dimensions = @enumToInt(node.content.image.type); + if (node.content.image.type == .cube) + dimensions = 2; + try loadData(file, node.content.image.resolution[0..dimensions]); + + var size: u32 = node.content.image.resolution[0] * node.content.image.resolution[1] * node.content.image.resolution[2]; + if (node.content.image.type == .cube) + size *= 6; + try loadStack(allocator, file, &node.content.image.image_stack, size); + }, + else => {}, + } + } + + return hxa; +} + +fn loadData(file: *std.fs.File, buffer: anytype) Error!void { + + // represent passed value as slice of bytes + var bytes: []u8 = undefined; + + const info = @typeInfo(@TypeOf(buffer)).Pointer; + switch (info.size) { + .Slice => bytes = @ptrCast([*]u8, buffer)[0 .. @sizeOf(info.child) * buffer.len], + .One => bytes = @ptrCast([*]u8, buffer)[0 .. @sizeOf(info.child)], + else => { + return Error.UnexpectedPointerType; + }, + } + + // read file bytes into buffer + const read = try file.read(bytes); + + // if file read less than bytes than buffer - return error + if (read != bytes.len) { + return Error.UnexpectedEOF; + } +} + +fn loadName(allocator: std.mem.Allocator, file: *std.fs.File, name: *[]u8) !void { + var len: u8 = undefined; + try loadData(file, &len); + + name.* = try allocator.alloc(u8, len); + try loadData(file, name.*); +} + +fn loadMeta(allocator: std.mem.Allocator, file: *std.fs.File, meta: *[]Meta) Error!void { + for (meta.*) |*data| { + data.len = 0; + var len: u32 = undefined; + + try loadName(allocator, file, &data.name); + try loadData(file, &data.type); + if (@enumToInt(data.type) >= @typeInfo(MetaType).Enum.fields.len) + return Error.MetaTypeNotRecognized; + + try loadData(file, &len); + data.len = len; + + switch (data.type) { + .u64 => { + data.values.u64 = try allocator.alloc(u64, data.len); + try loadData(file, data.values.u64); + }, + .f64 => { + data.values.f64 = try allocator.alloc(f64, data.len); + try loadData(file, data.values.f64); + }, + .node => { + data.values.node = try allocator.alloc(Node, data.len); + try loadData(file, data.values.node); + }, + .text => { + data.values.text = try allocator.alloc(u8, data.len); + try loadData(file, data.values.text); + }, + .binary => { + data.values.binary = try allocator.alloc(u8, data.len); + try loadData(file, data.values.binary); + }, + .meta => { + data.values.meta = try allocator.alloc(Meta, data.len); + try loadMeta(allocator, file, &data.values.meta); + }, + } + } +} + +fn loadStack(allocator: std.mem.Allocator, file: *std.fs.File, stack: *LayerStack, layer_len: u32) Error!void { + const type_sizes = [_]u32 { @sizeOf(u8), @sizeOf(u32), @sizeOf(f32), @sizeOf(f64) }; + stack.len = 0; + var len: u32 = undefined; + + try loadData(file, &len); + stack.len = len; + + stack.layers = try allocator.alloc(Layer, stack.len); + + for (stack.layers) |*layer| { + layer.components = 0; + + try loadName(allocator, file, &layer.name); + try loadData(file, &layer.components); + if (layer.components == 0) + return Error.InvalidComponents; + try loadData(file, &layer.type); + + if (@enumToInt(layer.type) >= @typeInfo(LayerType).Enum.fields.len) { + return Error.LayerTypeNotRecognized; + } + + layer.data = try allocator.alloc(u8, type_sizes[@enumToInt(layer.type)] * layer.components * layer_len); + + try loadData(file, layer.data); + } +} + +// Frees a HxA object +pub fn free(allocator: std.mem.Allocator, hxa: *File) void { + + for (hxa.nodes) |*node| + freeNode(allocator, node, hxa.version); + allocator.free(hxa.nodes); + + allocator.destroy(hxa); +} + +fn freeNode(allocator: std.mem.Allocator, node: *Node, version: u32) void { + for (node.meta) |*data| { + freeMeta(allocator, data); + } + + allocator.free(node.meta); + + switch (node.type) { + .geometry => { + freeStack(allocator, &node.content.geometry.corner_stack); + freeStack(allocator, &node.content.geometry.vertex_stack); + freeStack(allocator, &node.content.geometry.face_stack); + if (version > 2) + freeStack(allocator, &node.content.geometry.edge_stack); + }, + .image => { + freeStack(allocator, &node.content.image.image_stack); + }, + else => {}, + } +} + +fn freeMeta(allocator: std.mem.Allocator, meta: *Meta) void { + allocator.free(meta.name); + + switch (meta.type) { + .u64 => allocator.free(meta.values.u64), + .f64 => allocator.free(meta.values.f64), + .node => allocator.free(meta.values.node), + .text => allocator.free(meta.values.text), + .binary => allocator.free(meta.values.binary), + .meta => { + for (meta.values.meta) |*data| + freeMeta(allocator, data); + allocator.free(meta.values.meta); + }, + } +} + +fn freeStack(allocator: std.mem.Allocator, stack: *LayerStack) void { + for (stack.layers) |*layer| { + allocator.free(layer.name); + allocator.free(layer.data); + } + + allocator.free(stack.layers); +} + +// Save a HxA object to the file and close it afterwards +pub fn save(hxa: *File, file: *std.fs.File) !void { + + defer file.close(); + + _ = try file.write(std.mem.asBytes(&MAGIC_NUMBER)); + _ = try file.write(std.mem.asBytes(&hxa.version)); + _ = try file.write(std.mem.asBytes(&hxa.len)); + for (hxa.nodes) |*node| { + _ = try file.write(std.mem.asBytes(&node.type)); + _ = try file.write(std.mem.asBytes(&node.len)); + + for (node.meta) |*data| + try saveMeta(file, data); + + switch (node.type) { + .geometry => { + _ = try file.write(std.mem.asBytes(&node.content.geometry.vertex_len)); + try saveStack(file, &node.content.geometry.vertex_stack); + _ = try file.write(std.mem.asBytes(&node.content.geometry.edge_corner_len)); + try saveStack(file, &node.content.geometry.corner_stack); + if (hxa.version > 2) + try saveStack(file, &node.content.geometry.edge_stack); + _ = try file.write(std.mem.asBytes(&node.content.geometry.face_len)); + try saveStack(file, &node.content.geometry.face_stack); + }, + .image => { + _ = try file.write(std.mem.asBytes(&node.content.image.type)); + var dimension: u32 = @enumToInt(node.content.image.type); + if (node.content.image.type == .cube) + dimension = 2; + _ = try file.write(std.mem.sliceAsBytes(node.content.image.resolution[0..dimension])); + try saveStack(file, &node.content.image.image_stack); + }, + else => {}, + } + } +} + +fn saveMeta(file: *std.fs.File, meta: *Meta) Error!void { + _ = try file.write(std.mem.asBytes(&@intCast(u8, meta.name.len))); + _ = try file.write(meta.name); + _ = try file.write(std.mem.asBytes(&meta.type)); + _ = try file.write(std.mem.asBytes(&meta.len)); + + switch (meta.type) { + .u64 => { _ = try file.write(std.mem.sliceAsBytes(meta.values.u64)); }, + .f64 => { _ = try file.write(std.mem.sliceAsBytes(meta.values.f64)); }, + .node => { _ = try file.write(std.mem.sliceAsBytes(meta.values.node)); }, + .text => { _ = try file.write(std.mem.sliceAsBytes(meta.values.text)); }, + .binary => { _ = try file.write(std.mem.sliceAsBytes(meta.values.binary)); }, + .meta => { + for (meta.values.meta) |*data| + try saveMeta(file, data); + }, + } +} + +fn saveStack(file: *std.fs.File, stack: *LayerStack) !void { + _ = try file.write(std.mem.asBytes(&stack.len)); + + for (stack.layers) |*layer| { + _ = try file.write(std.mem.asBytes(&@intCast(u8, layer.name.len))); + _ = try file.write(layer.name); + _ = try file.write(std.mem.asBytes(&layer.components)); + _ = try file.write(std.mem.asBytes(&layer.type)); + _ = try file.write(layer.data); + } +} + +// Outline does not print layer data +const PrintOptions = enum { outline, data }; + +// Print a HxA file in human readable format to the writer object +pub fn print(hxa: *File, writer: *std.fs.File.Writer, option: PrintOptions) !void { + + try writer.print("HxA version: {}\n", .{ hxa.version }); + try writer.print("Node lenght: {}\n", .{ hxa.len }); + for (hxa.nodes) |*node, i| { + try writer.print("-Node id: {}\n", .{ i }); + try writer.print("\t-Node type: {s}\n", .{ @tagName(node.type) }); + try writer.print("\t-Node meta length: {}\n", .{ node.len }); + + try printMeta(writer, &node.meta, 2, option); + + switch (node.type) { + .geometry => { + try writer.print("\t-Geometry vertex length: {}\n", .{ node.content.geometry.vertex_len }); + try printStack(writer, &node.content.geometry.vertex_stack, "Vertex", option); + try writer.print("\t-Geometry edge length: {}\n", .{ node.content.geometry.edge_corner_len }); + try printStack(writer, &node.content.geometry.corner_stack, "Corner", option); + if (hxa.version > 2) + try printStack(writer, &node.content.geometry.edge_stack, "Edge", option); + try writer.print("\t-Geometry face length: {}\n", .{ node.content.geometry.face_len }); + try printStack(writer, &node.content.geometry.face_stack, "Face", option); + }, + .image => { + try writer.print("\t-Pixel type: {s}\n", .{ @tagName(node.content.image.type) }); + switch (node.content.image.type) { + .cube => try writer.print("\t-Pixel resolution: {} x {} x 6", .{ node.content.image.resolution[0], node.content.image.resolution[1] }), + .@"1d" => try writer.print("\t-Pixel resolution: {}\n", .{ node.content.image.resolution[0] }), + .@"2d" => try writer.print("\t-Pixel resolution: {} x {}\n", .{ node.content.image.resolution[0], node.content.image.resolution[1] }), + .@"3d" => try writer.print("\t-Pixel resolution: {} x {} x {}\n", .{ node.content.image.resolution[0], node.content.image.resolution[1], node.content.image.resolution[2] }), + } + }, + else => {}, + } + } +} + +fn printMeta(writer: *std.fs.File.Writer, meta: *[]Meta, tab_len: usize, option: PrintOptions) Error!void { + const tabs = [_]u8 {'\t'} ** 16; + + for (meta.*) |*data| { + try writer.print("{s}-Meta {s} \"{s}\" [{}]:", .{ tabs[0..tab_len % tabs.len], @tagName(data.type), data.name, data.len }); + + // print data + if (option == .data) { + switch(data.type) { + .u64 => try writer.print(" {any}", .{ data.values.u64[0..@minimum(tabs.len, data.values.u64.len)] }), + .f64 => try writer.print(" {any}", .{ data.values.f64[0..@minimum(tabs.len, data.values.f64.len)] }), + .node => try writer.print("{any}", .{ data.values.node[0..@minimum(tabs.len, data.values.text.len)] }), + .text => try writer.print(" {s}", .{ data.values.text[0..@minimum(tabs.len, data.values.binary.len)] }), + .binary => try writer.print(" {}", .{ std.fmt.fmtSliceHexUpper(data.values.binary) }), + .meta => try printMeta(writer, &data.values.meta, tab_len + 1, option), + } + } + + if (data.type != .meta) { + if (data.len > tabs.len and data.type != .text) { + try writer.print(" ...\n", .{}); + } else { + try writer.print("\n", .{}); + } + } + } + +} + +fn printStack(writer: *std.fs.File.Writer, stack: *LayerStack, name: []const u8, option: PrintOptions) !void { + try writer.print("\t-{s} Layer length: {}\n", .{ name, stack.layers.len }); + + for (stack.layers) |*layer| { + try writer.print("\t\tLayer name: {s}\n", .{ layer.name }); + try writer.print("\t\tLayer components: {}\n", .{ layer.components }); + try writer.print("\t\tLayer type: {s}\n", .{ @tagName(layer.type) }); + + if (option == .data) { + switch (layer.type) { + .u8 => { + var i: usize = 0; + while (i < layer.data.len) : (i += layer.components ) + try writer.print("\t\t\t{d} \n", .{ layer.data[i..i + layer.components] }); + }, + .i32 => { + if (std.mem.eql(u8, layer.name, "reference" ) and layer.components == 1) { + const data = @ptrCast([*]align(1) i32, layer.data)[0 .. layer.data.len / @sizeOf(i32)]; + var i: usize = 0; + for (data) |d, j| { + if (d < 0) { + try writer.print("\t\t\t{d}\n", .{ data[i..j+1] }); + i = j+1; + } + } + } else { + var i: usize = 0; + const data = @ptrCast([*]align(1) i32, layer.data)[0 .. layer.data.len / @sizeOf(i32)]; + while (i < data.len) : (i += layer.components ) + try writer.print("\t\t\t{d} \n", .{ data[i..i + layer.components] }); + } + }, + .f32 => { + var i: usize = 0; + const data = @ptrCast([*]align(1) f32, layer.data)[0 .. layer.data.len / @sizeOf(f32)]; + while (i < data.len) : (i += layer.components ) + try writer.print("\t\t\t{d:.6} \n", .{ data[i..i + layer.components] }); + }, + .f64 => { + var i: usize = 0; + const data = @ptrCast([*]align(1) f64, layer.data)[0 .. layer.data.len / @sizeOf(f64)]; + while (i < data.len) : (i += layer.components ) + try writer.print("\t\t\t{d:.6} \n", .{ data[i..i + layer.components] }); + }, + } + } + } +} + +// Upgrade old files to newer version +// Silent if hxa.version is newer than version +// Please upgrade right after loading, before working on the file +pub fn upgradeVersion(allocator: std.mem.Allocator, hxa: *File, version: u32) !void { + if (hxa.version < version) { + if (version > 2) { + hxa.version = version; + for (hxa.nodes) |*node| { + if (node.type == .geometry) + node.content.geometry.edge_stack.layers = try allocator.alloc(Layer, 0); + } + } + } +} diff --git a/src/test.zig b/src/test.zig new file mode 100644 index 0000000..05d3bbe --- /dev/null +++ b/src/test.zig @@ -0,0 +1,117 @@ +const std = @import("std"); +const hxa = @import("HxA.zig"); + +const allocator = std.testing.allocator; + +test "Load and free HxA file v1" { + // Load and free + const teapot_v1 = try hxa.load(allocator, &try std.fs.cwd().openFile("Test/teapot_v1.hxa", .{ .read = true })); + defer hxa.free(allocator, teapot_v1); +} + +test "Load and free HxA file v3" { + // Load and free + const teapot_v3 = try hxa.load(allocator, &try std.fs.cwd().openFile("Test/teapot_v3.hxa", .{ .read = true })); + defer hxa.free(allocator, teapot_v3); +} + +test "Load, save v1" { + // Load and Save + const teapot_v1 = try hxa.load(allocator, &try std.fs.cwd().openFile("Test/teapot_v1.hxa", .{ .read = true })); + defer hxa.free(allocator, teapot_v1); + try hxa.save(teapot_v1, &try std.fs.cwd().createFile("Test/teapot_v1_test.hxa", .{ .read = true })); + + // Read and compare + try checkFileEql("Test/teapot_v1.hxa", "Test/teapot_v1_test.hxa"); +} + +test "Load, save v3" { + // Load and Save + const teapot_v3 = try hxa.load(allocator, &try std.fs.cwd().openFile("Test/teapot_v3.hxa", .{ .read = true })); + defer hxa.free(allocator, teapot_v3); + try hxa.save(teapot_v3, &try std.fs.cwd().createFile("Test/teapot_v3_test.hxa", .{ .read = true })); + + // Read and compare + try checkFileEql("Test/teapot_v3.hxa", "Test/teapot_v3_test.hxa"); +} + +test "Load and convert HxA file v1 to v3" { + // Load and free + const teapot = try hxa.load(allocator, &try std.fs.cwd().openFile("Test/teapot_v1.hxa", .{ .read = true })); + defer hxa.free(allocator, teapot); + + try hxa.upgradeVersion(allocator, teapot, 3); + try hxa.save(teapot, &try std.fs.cwd().createFile("Test/teapot_converted_v1_v3.hxa", .{ .read = true })); + + try checkFileEql("Test/teapot_v3.hxa", "Test/teapot_converted_v1_v3.hxa"); +} + +test "Load and print HxA file v1" { + const file = try std.fs.cwd().createFile("Test/teapot_v1_print_test.txt", .{}); + defer file.close(); + + const writer = &file.writer(); + + // Load and free + const teapot_v1 = try hxa.load(allocator, &try std.fs.cwd().openFile("Test/teapot_v1.hxa", .{ .read = true })); + defer hxa.free(allocator, teapot_v1); + + try hxa.print(teapot_v1, writer, .data); + + try checkFileEql("Test/teapot_v1_print.txt", "Test/teapot_v1_print_test.txt"); +} + +test "Load and print HxA file v3" { + const file = try std.fs.cwd().createFile("Test/teapot_v3_print_test.txt", .{}); + defer file.close(); + + const writer = &file.writer(); + + // Load and free + const teapot_v3 = try hxa.load(allocator, &try std.fs.cwd().openFile("Test/teapot_v3.hxa", .{ .read = true })); + defer hxa.free(allocator, teapot_v3); + + try hxa.print(teapot_v3, writer, .data); + + try checkFileEql("Test/teapot_v3_print.txt", "Test/teapot_v3_print_test.txt"); +} + +fn checkFileEql(filepath1: []const u8, filepath2: []const u8) !void { + + // Read and compare + const file1 = &try std.fs.cwd().openFile(filepath1, .{ .read = true }); + defer file1.close(); + const file2 = &try std.fs.cwd().openFile(filepath2, .{ .read = true }); + defer file2.close(); + + const file1_stat = try file1.stat(); + const file2_stat = try file2.stat(); + + if (file1_stat.size != file2_stat.size) { + std.debug.print("Files are of different sizes.\n\t{s}: {}\n{s}: {}\n", .{ filepath1, file1_stat.size, filepath2, file2_stat.size }); + try std.testing.expect(false); + } + + const contents1 = try allocator.alloc(u8, file1_stat.size); + defer allocator.free(contents1); + + const contents2 = try allocator.alloc(u8, file2_stat.size); + defer allocator.free(contents2); + + _ = try file1.read(contents1); + _ = try file2.read(contents2); + + var i: usize = 0; + var diffs: usize = 0; + while (i < contents1.len) : (i += 1) { + if (contents1[i] != contents2[i]) { + if (diffs == 0) + std.debug.print("Differences were detected.\n\tFirst Diff at: {X}\n", .{ i }); + diffs += 1; + } + } + if (diffs != 0) { + std.debug.print("\tTotal Differences: {}\n", .{ i }); + try std.testing.expect(false); + } +} diff --git a/src/types.zig b/src/types.zig new file mode 100644 index 0000000..488ee2d --- /dev/null +++ b/src/types.zig @@ -0,0 +1,218 @@ +// +// HxA is a interchangeable graphics asset format. Written by Eskil Steenberg. @quelsolaar / eskil 'at' obsession 'dot' se / www.quelsolaar.com +// + +// +// TODO: Structure +// +// HxA is designed to be extremely simple to parse, and is therefore based around conventions. +// It has a few basic structures, and depending on how they are used they mean different things. +// This means that you can implement a tool that loads the entire file, modifies the parts it cares about and leaves the rest intact. +// It is also possible to write a tool that makes all data in the file editable without the need to understand its use. +// It is also possible for anyone to use the format to store axillary data. +// Anyone who wants to store data not covered by a convention can submit a convention to extend the format. +// There should never be a convention for storing the same data in two differed ways. + +// The data is story in a number of nodes that are stored in an array. +// Each node stores an array of meta data. +// Meta data can describe anything you want, and a lot of conventions will use meta data to store additional information, for things like transforms, lights, shaders and animation. +// Data for Vertices, Corners, Faces, and Pixels are stored in named layer stacks. Each stack consists of a number of named layers. All layers in the stack have the same number of elements. +// Each layer describes one property of the primitive. Each layer can have multiple channels and each layer can store data of a different type. + +// HxA stores 3 kinds of nodes +// -Pixel data. +// -Polygon geometry data. +// -Meta data only. + +// Pixel Nodes stores pixels in a layer stack. A layer may store things like Albedo, Roughness, Reflectance, Light maps, Masks, Normal maps, and Displacements. +// Layers use the channels of the layers to store things like color. + +// Geometry data is stored in 3 separate layer stacks for: vertex data, corner data and face data. +// The vertex data stores things like veritices, blend shapes, weight maps, and vertex colors. +// The first layer in a vertex stack has to be a 3 channel layer named "position" describing the base position of the vertices. +// The corner stack describes data per corner or edge of the polygons. It can be used for things like UV, normals, and adjacency. +// The first layer in a corner stack has to be a 1 channel integer layer named "index" describing the vertices used to form polygons. +// The last value in each polygon has a negative - 1 index to indicate the end of the polygon. + +// Example: +// A quad and a tri with the vertex index: +// [0, 1, 2, 3] [1, 4, 2] +// are stored as: +// [0, 1, 2, -4, 1, 4, -3] + +// The face stack stores values per face. the length of the face stack has to match the number of negative values in the index layer in the corner stack. +// The face stack can be used to store things like material index. + +// +// Storage +// +// All data is stored in little endian byte order with no padding. The layout mirrors the struct defined below with a few exceptions. +// All names are stored as u8 indicating the lenght of the name followed by that many characters. Termination is not stored in the file. +// Text strings stored in meta data are stored the same way as names, but inseatd of u8 for size a u32 is used. + +pub const MAGIC_NUMBER = @ptrCast(*const u32, "HxA").*; +pub const VERSION: u32 = 3; +pub const NAME_MAX_LENGHT: u8 = 255; + +// +// HxA stores 3 types of nodes +// +pub const NodeType = enum(u8) { + meta, // Node only containing meta data + geometry, // Node containing a geometry mesh and meta data + image, // Node containing a 1D, 2D, 3D, or Cube image and meta data +}; + +// +// Pixel data is arranged in the followign configurations +// +pub const ImageType = enum(u8) { + cube, // 6-sided cube in the order: +x, -x, +y, -y, +z, -z + @"1d", // One dimensional pixel data + @"2d", // Two dimensional pixel data + @"3d", // Three dimensional pixel data +}; + +pub const MetaType = enum(u8) { + u64, + f64, + node, + text, + binary, + meta, +}; + +pub const Meta = struct { + name: []u8, // Name of meta data value + type: MetaType, // Type of values - stored in the file as a u8 + len: u32, // How many values are stored / The length of the stored text string (excluding termination) + values: extern union { + u64: []u64, + f64: []f64, + node: []Node, // A reference to another Node + text: []u8, + binary: []u8, + meta: []Meta, + }, +}; + +// +// HxA stores layer data in the following types +// +pub const LayerType = enum(u8) { + u8, + i32, + f32, + f64, +}; + +// +// Layers are arrays of data used to store geometry and pixel data +// +pub const Layer = struct { + name: []u8, // Name of the layer. List of predefined names for common usages like uv, reference, blendshapes, weights... + components: u8, // 2 for uv, 3 for xyz or rgb, 4 for rgba. From 1 - 255 is legal TODO: 0 check + type: LayerType, // stored in the file as a u8 + data: []u8, +}; + +pub const LayerStack = struct { + len: u32, // Number of layers in a stack + layers: []Layer, // An array of layers +}; + +// +// A file consists of an array of nodes. All nodes have meta data. Geometry nodes have geometry. Image nodes have pixel data +// +pub const Node = struct { + type: NodeType, // stored as u8 in file + len: u32, // how many meta data key/values are stored in the node + meta: []Meta, // array of key/values + content: extern union { // extern because zig includes extra fields for safety checking and that messes with later code (search: switch (node.type)) + geometry: Geometry, + image: Image, + + const Geometry = struct { + vertex_len: u32, // Number of vertices + vertex_stack: LayerStack, // Stack of vertex arrays. The first layer is always the vertex positions + edge_corner_len: u32, // Number of corners + corner_stack: LayerStack, // Stack of corner arrays: The first layer is allways a reference array (see below) TODO: see below + edge_stack: LayerStack, // Stack of edge arrays // Version > 2 + face_len: u32, // Number of polygons + face_stack: LayerStack, // Stack of per polygon data. + }; + const Image = struct { + type: ImageType = .cube, // type of image + resolution: [3]u32, // resolytion i X, Y and Z dimention; + image_stack: LayerStack, // the number of values in the stack is equal to the number of pixels depending on resolution + }; + }, +}; + +pub const File = struct { + // The file begins with a file identifier. The first 4 bytes spell "HxA". See definition of MAGIC_NUMBER. Since the magic number is always the same we do not store it in this structure, even if it is always present in files. + // magic_number: u32 + version: u32, // VERSION + len: u32, // number of nodes in the file + nodes: []Node, // array of nodes +}; + +// +// Conventions +// +// Much of HxA's use is based on conventions. HxA lets users store arbitrary data in its structure that can be parsed but who's semantic meaning does not need to be understood. +// A few conventions are hard, and some are soft. +// Hard conventions HAVE to be followed by users in order to produce a valid file. Hard conventions simplify parsing because the parser can make some assumtions. +// Soft conventions are basically recommendations of how to store sommon data. +pub const Conventions = struct { + Hard: Hard = Hard {}, + Soft: Soft = Soft {}, + + const Hard = struct { + base_vertex_layer_name: []const u8 = "vertex", + base_vertex_layer_id: u32 = 0, + base_vertex_layer_components: u32 = 3, + base_corner_layer_name: []const u8 = "reference", + base_corner_layer_id: u32 = 0, + base_corner_layer_components: u32 = 1, + base_corner_layer_type: type = i32, + edge_neighbour_layer_name: []const u8 = "neighbour", + edge_neighbour_layer_type: type = i32, + }; + + const Soft = struct { + Geometry: Geometry = Geometry {}, + Image: Image = Image {}, + Tags: Tags = Tags {}, + + const Geometry = struct { + sequence0: []const u8 = "sequence", + uv0: []const u8 = "uv", + normals: []const u8 = "normal", + binormal: []const u8 = "binormal", + tangent: []const u8 = "tangent", + color: []const u8 = "color", + creases: []const u8 = "creases", + selection: []const u8 = "select", + skin_weight: []const u8 = "skin_weight", + skin_reference: []const u8 = "skin_reference", + blendshape: []const u8 = "blendshape", + add_blendshape: []const u8 = "addblendshape", + material_id: []const u8 = "material", + group_id: []const u8 = "group", + }; + + const Image = struct { + albedo: []const u8 = "albedo", + light: []const u8 = "light", + displacement: []const u8 = "displacement", + distortion: []const u8 = "distortion", + ambient_occlusion: []const u8 = "ambient_occlusion", + }; + + const Tags = struct { + name: []const u8 = "name", + transform: []const u8 = "transform", + }; + }; +};