TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
137 / 138
99.3%
Branches:
283 / 461
61.4%
Functions:
12 / 12
100.0%

config/feature_lists.cpp
Line Branch Exec Source
1 #include "terraingen/config/build.h"
2 #include "terraingen/config/generate.h"
3 #include "terraingen/mesh/io/mesh_io.h"
4
5 #include <nlohmann/json.hpp>
6
7 #include <array>
8 #include <cstdio>
9 #include <fstream>
10 #include <map>
11 #include <numbers>
12 #include <stdexcept>
13 #include <string>
14
15 namespace terraingen {
16
17 namespace {
18
19 using Json = nlohmann::ordered_json;
20
21 /// `value` with the digits to read it back exactly.
22 493010 std::string Number(double value) {
23 493010 std::array<char, 32> buffer{};
24 986020 std::snprintf(buffer.data(), buffer.size(), "%.17g", value);
25
1/1
✓ Branch 1 taken 493010 times.
986020 return buffer.data();
26 }
27
28 /// @throws std::runtime_error if `path` cannot be opened.
29 72 std::ofstream OpenForWriting(const std::filesystem::path& path) {
30 72 std::ofstream file(path, std::ios::binary);
31
3/3
✓ Branch 1 taken 72 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 70 times.
72 if (!file) {
32
3/3
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
2 throw std::runtime_error("Cannot write " + path.string());
33 }
34 70 return file;
35 2 }
36
37 /// @throws std::runtime_error if writing to `file` failed.
38 70 void CheckWritten(const std::ofstream& file, const std::filesystem::path& path) {
39
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 68 times.
70 if (!file) {
40
3/3
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
2 throw std::runtime_error("Cannot write " + path.string());
41 }
42 68 }
43
44 36 void WriteCraterCsv(std::ostream& file, const CraterList& craters,
45 const std::vector<CraterAttributes>& attributes) {
46 36 const bool detailed = !attributes.empty();
47 file << "x,y,diameter,age_gyr,id,manual"
48
2/2
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 4 times.
36 << (detailed ? ",floor_depth,rim_height,depth_ratio,freshness,complex" : "") << '\n';
49
2/2
✓ Branch 1 taken 53032 times.
✓ Branch 2 taken 36 times.
53068 for (std::size_t n = 0; n < craters.Size(); ++n) {
50
1/1
✓ Branch 1 taken 53032 times.
53032 const Crater crater = craters.At(n);
51
1/1
✓ Branch 1 taken 53032 times.
106064 file << Number(crater.x) << ',' << Number(crater.y) << ',' << Number(crater.diameter) << ','
52
16/16
✓ Branch 1 taken 53032 times.
✓ Branch 4 taken 53032 times.
✓ Branch 7 taken 53032 times.
✓ Branch 10 taken 53032 times.
✓ Branch 13 taken 53032 times.
✓ Branch 16 taken 53032 times.
✓ Branch 19 taken 53032 times.
✓ Branch 22 taken 53032 times.
✓ Branch 25 taken 53032 times.
✓ Branch 28 taken 53032 times.
✓ Branch 31 taken 53032 times.
✓ Branch 34 taken 53032 times.
✓ Branch 37 taken 53032 times.
✓ Branch 39 taken 9 times.
✓ Branch 40 taken 53023 times.
✓ Branch 42 taken 53032 times.
53032 << Number(crater.ageGyr) << ',' << crater.id << ',' << (crater.manual ? 1 : 0);
53
2/2
✓ Branch 0 taken 31531 times.
✓ Branch 1 taken 21501 times.
53032 if (detailed) {
54 31531 const CraterAttributes& a = attributes[n];
55 31531 file << ',' << Number(a.floorDepth) << ',' << Number(a.rimHeight) << ','
56
13/13
✓ Branch 1 taken 31531 times.
✓ Branch 4 taken 31531 times.
✓ Branch 7 taken 31531 times.
✓ Branch 10 taken 31531 times.
✓ Branch 13 taken 31531 times.
✓ Branch 16 taken 31531 times.
✓ Branch 19 taken 31531 times.
✓ Branch 22 taken 31531 times.
✓ Branch 25 taken 31531 times.
✓ Branch 28 taken 31531 times.
✓ Branch 31 taken 31531 times.
✓ Branch 34 taken 31531 times.
✓ Branch 37 taken 31531 times.
63062 << Number(a.depthRatio) << ',' << Number(a.freshness) << ','
57
3/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 31529 times.
✓ Branch 3 taken 31531 times.
31531 << (a.complex ? 1 : 0);
58 }
59
1/1
✓ Branch 1 taken 53032 times.
53032 file << '\n';
60 }
61 36 }
62
63 4 Json CraterJson(const CraterList& craters, const std::vector<CraterAttributes>& attributes) {
64
1/1
✓ Branch 1 taken 4 times.
4 Json list = Json::array();
65
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 4 times.
38 for (std::size_t n = 0; n < craters.Size(); ++n) {
66
1/1
✓ Branch 1 taken 34 times.
34 const Crater crater = craters.At(n);
67 Json entry{{"x", crater.x},
68 {"y", crater.y},
69 {"diameter", crater.diameter},
70 {"age_gyr", crater.ageGyr},
71 {"id", crater.id},
72
2/4
✓ Branch 0 taken 204 times.
✓ Branch 1 taken 34 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
646 {"manual", crater.manual}};
73
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 2 times.
34 if (!attributes.empty()) {
74 32 const CraterAttributes& a = attributes[n];
75
1/1
✓ Branch 2 taken 32 times.
32 entry["floor_depth"] = a.floorDepth;
76
1/1
✓ Branch 2 taken 32 times.
32 entry["rim_height"] = a.rimHeight;
77
1/1
✓ Branch 2 taken 32 times.
32 entry["depth_ratio"] = a.depthRatio;
78
1/1
✓ Branch 2 taken 32 times.
32 entry["freshness"] = a.freshness;
79
1/1
✓ Branch 2 taken 32 times.
32 entry["complex"] = a.complex;
80 }
81
1/1
✓ Branch 2 taken 34 times.
34 list.push_back(std::move(entry));
82 34 }
83
2/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
20 return Json{{"craters", std::move(list)}};
84
30/80
✓ Branch 1 taken 34 times.
✓ Branch 5 taken 34 times.
✓ Branch 8 taken 34 times.
✓ Branch 12 taken 34 times.
✓ Branch 15 taken 34 times.
✓ Branch 19 taken 34 times.
✓ Branch 22 taken 34 times.
✓ Branch 26 taken 34 times.
✓ Branch 29 taken 34 times.
✓ Branch 33 taken 34 times.
✓ Branch 36 taken 34 times.
✓ Branch 40 taken 34 times.
✓ Branch 43 taken 34 times.
✓ Branch 45 taken 68 times.
✓ Branch 46 taken 34 times.
✓ Branch 47 taken 68 times.
✓ Branch 48 taken 34 times.
✓ Branch 49 taken 68 times.
✓ Branch 50 taken 34 times.
✓ Branch 51 taken 68 times.
✓ Branch 52 taken 34 times.
✓ Branch 53 taken 68 times.
✓ Branch 54 taken 34 times.
✓ Branch 55 taken 68 times.
✓ Branch 56 taken 34 times.
✓ Branch 59 taken 4 times.
✓ Branch 64 taken 4 times.
✓ Branch 67 taken 4 times.
✓ Branch 69 taken 8 times.
✓ Branch 70 taken 4 times.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
492 }
85
86 25 void WriteBoulderCsv(std::ostream& file, const std::vector<Boulder>& boulders) {
87 file << "x,y,ground,diameter,height,burial,yaw,lean,id,model,wear,parent,piece,rest,tilt,tilt_"
88 25 "azimuth\n";
89
2/2
✓ Branch 4 taken 14069 times.
✓ Branch 5 taken 25 times.
14094 for (const Boulder& boulder : boulders) {
90
1/1
✓ Branch 1 taken 14069 times.
28138 file << Number(boulder.x) << ',' << Number(boulder.y) << ','
91
3/3
✓ Branch 0 taken 14068 times.
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 14068 times.
28138 << (boulder.ground ? Number(*boulder.ground) : std::string()) << ','
92 14069 << Number(boulder.diameter) << ',' << Number(boulder.height) << ','
93 14069 << Number(boulder.burial) << ',' << Number(boulder.yaw) << ',' << Number(boulder.lean)
94
24/24
✓ Branch 1 taken 14069 times.
✓ Branch 4 taken 14069 times.
✓ Branch 7 taken 14069 times.
✓ Branch 10 taken 14069 times.
✓ Branch 13 taken 14069 times.
✓ Branch 17 taken 14069 times.
✓ Branch 20 taken 14069 times.
✓ Branch 23 taken 14069 times.
✓ Branch 26 taken 14069 times.
✓ Branch 29 taken 14069 times.
✓ Branch 32 taken 14069 times.
✓ Branch 35 taken 14069 times.
✓ Branch 38 taken 14069 times.
✓ Branch 41 taken 14069 times.
✓ Branch 44 taken 14069 times.
✓ Branch 47 taken 14069 times.
✓ Branch 50 taken 14069 times.
✓ Branch 53 taken 14069 times.
✓ Branch 56 taken 14069 times.
✓ Branch 59 taken 14069 times.
✓ Branch 62 taken 14069 times.
✓ Branch 65 taken 14069 times.
✓ Branch 68 taken 14069 times.
✓ Branch 71 taken 14069 times.
42207 << ',' << boulder.id << ',' << (boulder.model ? 1 : 0) << ',' << Number(boulder.wear)
95
11/11
✓ Branch 0 taken 271 times.
✓ Branch 1 taken 13798 times.
✓ Branch 3 taken 14069 times.
✓ Branch 6 taken 14069 times.
✓ Branch 9 taken 14069 times.
✓ Branch 12 taken 14069 times.
✓ Branch 15 taken 14069 times.
✓ Branch 18 taken 14069 times.
✓ Branch 21 taken 14069 times.
✓ Branch 24 taken 14069 times.
✓ Branch 27 taken 14069 times.
14069 << ',' << boulder.parent << ',' << boulder.piece << ','
96 14069 << static_cast<int>(boulder.rest) << ',' << Number(boulder.tilt) << ','
97
8/8
✓ Branch 1 taken 14069 times.
✓ Branch 4 taken 14069 times.
✓ Branch 7 taken 14069 times.
✓ Branch 10 taken 14069 times.
✓ Branch 13 taken 14069 times.
✓ Branch 16 taken 14069 times.
✓ Branch 19 taken 14069 times.
✓ Branch 22 taken 14069 times.
14069 << Number(boulder.tiltAzimuth) << '\n';
98 }
99 25 }
100
101 5 Json BoulderJson(const std::vector<Boulder>& boulders) {
102
1/1
✓ Branch 1 taken 5 times.
5 Json list = Json::array();
103
2/2
✓ Branch 4 taken 20846 times.
✓ Branch 5 taken 5 times.
20851 for (const Boulder& boulder : boulders) {
104
2/4
✓ Branch 0 taken 333536 times.
✓ Branch 1 taken 20846 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
1021454 list.push_back({{"x", boulder.x},
105 20846 {"y", boulder.y},
106
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 20001 times.
41692 {"ground", boulder.ground ? Json(*boulder.ground) : Json(nullptr)},
107 20846 {"diameter", boulder.diameter},
108 20846 {"height", boulder.height},
109 20846 {"burial", boulder.burial},
110 20846 {"yaw", boulder.yaw},
111 20846 {"lean", boulder.lean},
112 20846 {"id", boulder.id},
113 20846 {"model", boulder.model},
114 20846 {"wear", boulder.wear},
115 20846 {"parent", boulder.parent},
116 20846 {"piece", boulder.piece},
117 ✗ {"rest", static_cast<int>(boulder.rest)},
118 20846 {"tilt", boulder.tilt},
119 20846 {"tilt_azimuth", boulder.tiltAzimuth}});
120 }
121
2/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
25 return Json{{"boulders", std::move(list)}};
122
70/180
✓ Branch 1 taken 20846 times.
✓ Branch 5 taken 20846 times.
✓ Branch 8 taken 20846 times.
✓ Branch 12 taken 20846 times.
✓ Branch 15 taken 20846 times.
✓ Branch 20 taken 20846 times.
✓ Branch 23 taken 20846 times.
✓ Branch 27 taken 20846 times.
✓ Branch 30 taken 20846 times.
✓ Branch 34 taken 20846 times.
✓ Branch 37 taken 20846 times.
✓ Branch 41 taken 20846 times.
✓ Branch 44 taken 20846 times.
✓ Branch 48 taken 20846 times.
✓ Branch 51 taken 20846 times.
✓ Branch 55 taken 20846 times.
✓ Branch 58 taken 20846 times.
✓ Branch 62 taken 20846 times.
✓ Branch 65 taken 20846 times.
✓ Branch 69 taken 20846 times.
✓ Branch 72 taken 20846 times.
✓ Branch 76 taken 20846 times.
✓ Branch 79 taken 20846 times.
✓ Branch 83 taken 20846 times.
✓ Branch 86 taken 20846 times.
✓ Branch 90 taken 20846 times.
✓ Branch 93 taken 20846 times.
✓ Branch 97 taken 20846 times.
✓ Branch 100 taken 20846 times.
✓ Branch 104 taken 20846 times.
✓ Branch 107 taken 20846 times.
✓ Branch 111 taken 20846 times.
✓ Branch 114 taken 20846 times.
✓ Branch 116 taken 41692 times.
✓ Branch 117 taken 20846 times.
✓ Branch 118 taken 41692 times.
✓ Branch 119 taken 20846 times.
✓ Branch 120 taken 41692 times.
✓ Branch 121 taken 20846 times.
✓ Branch 122 taken 41692 times.
✓ Branch 123 taken 20846 times.
✓ Branch 124 taken 41692 times.
✓ Branch 125 taken 20846 times.
✓ Branch 126 taken 41692 times.
✓ Branch 127 taken 20846 times.
✓ Branch 128 taken 41692 times.
✓ Branch 129 taken 20846 times.
✓ Branch 130 taken 41692 times.
✓ Branch 131 taken 20846 times.
✓ Branch 132 taken 41692 times.
✓ Branch 133 taken 20846 times.
✓ Branch 134 taken 41692 times.
✓ Branch 135 taken 20846 times.
✓ Branch 136 taken 41692 times.
✓ Branch 137 taken 20846 times.
✓ Branch 138 taken 41692 times.
✓ Branch 139 taken 20846 times.
✓ Branch 140 taken 41692 times.
✓ Branch 141 taken 20846 times.
✓ Branch 142 taken 41692 times.
✓ Branch 143 taken 20846 times.
✓ Branch 144 taken 41692 times.
✓ Branch 145 taken 20846 times.
✓ Branch 146 taken 41692 times.
✓ Branch 147 taken 20846 times.
✓ Branch 150 taken 5 times.
✓ Branch 155 taken 5 times.
✓ Branch 158 taken 5 times.
✓ Branch 160 taken 10 times.
✓ Branch 161 taken 5 times.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 170 not taken.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 198 not taken.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 219 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 233 not taken.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 237 not taken.
✗ Branch 238 not taken.
✗ Branch 240 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 249 not taken.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✗ Branch 252 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✗ Branch 257 not taken.
✗ Branch 258 not taken.
✗ Branch 259 not taken.
✗ Branch 261 not taken.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✗ Branch 264 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 270 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✗ Branch 273 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 280 not taken.
✗ Branch 281 not taken.
✗ Branch 282 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 285 not taken.
✗ Branch 287 not taken.
✗ Branch 288 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
750476 }
123
124 473 BoulderPlacement PlacementOf(const BoulderModel& boulder, const Surface& surface,
125 const Vec2d& site) {
126
1/1
✓ Branch 1 taken 473 times.
946 return PlacementAtSite(boulder.placement, {boulder.boulder.x, boulder.boulder.y}, site,
127 946 surface);
128 }
129
130 /// Writes each shared shape once, with crease normals, and a node per boulder; or, not
131 /// `instanced`, each boulder's placed shape as its own mesh.
132 19 void WriteBoulderScene(const std::vector<BoulderModel>& boulders, const std::filesystem::path& path,
133 double creaseAngle, const Surface& surface, const Vec2d& site,
134 bool instanced) {
135 19 const double radians = creaseAngle * std::numbers::pi / 180.0;
136 19 std::vector<SceneMesh> meshes;
137 19 std::map<const BoulderShape*, std::size_t> indices;
138 19 std::vector<SceneNode> nodes;
139
2/2
✓ Branch 5 taken 473 times.
✓ Branch 6 taken 19 times.
492 for (const BoulderModel& boulder : boulders) {
140
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 409 times.
473 if (!instanced) {
141
1/1
✓ Branch 1 taken 64 times.
64 const BoulderPlacement placement = PlacementOf(boulder, surface, site);
142
1/1
✓ Branch 2 taken 64 times.
64 TriangleMesh placed = boulder.shape->mesh;
143
2/2
✓ Branch 5 taken 13997 times.
✓ Branch 6 taken 64 times.
14061 for (Vec3d& p : placed.positions) {
144
1/1
✓ Branch 1 taken 13997 times.
13997 p = placement.Apply(p);
145 }
146
1/1
✓ Branch 1 taken 64 times.
64 ShadedMesh shaded = WithCreases(placed, radians);
147
1/1
✓ Branch 2 taken 64 times.
64 nodes.push_back({meshes.size(), {1.0, 1.0, 1.0}, {}});
148 64 meshes.push_back(
149 64 {std::move(shaded.mesh), std::move(shaded.normals), boulder.shape->material});
150 64 continue;
151 64 }
152
1/1
✓ Branch 3 taken 409 times.
409 auto [found, added] = indices.emplace(boulder.shape.get(), meshes.size());
153
2/2
✓ Branch 0 taken 343 times.
✓ Branch 1 taken 66 times.
409 if (added) {
154
1/1
✓ Branch 2 taken 343 times.
343 ShadedMesh shaded = WithCreases(boulder.shape->mesh, radians);
155 343 meshes.push_back(
156 343 {std::move(shaded.mesh), std::move(shaded.normals), boulder.shape->material});
157 343 }
158
1/1
✓ Branch 1 taken 409 times.
409 const BoulderPlacement placement = PlacementOf(boulder, surface, site);
159
1/1
✓ Branch 2 taken 409 times.
409 nodes.push_back({found->second, placement.scale, placement.pose});
160 }
161
1/1
✓ Branch 1 taken 18 times.
19 WriteScene(path, meshes, nodes);
162
4/12
✓ Branch 5 taken 64 times.
✓ Branch 8 taken 64 times.
✓ Branch 15 taken 343 times.
✓ Branch 18 taken 343 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
428 }
163
164 } // namespace
165
166 42 void WriteCraterList(const CraterList& craters, const std::filesystem::path& path,
167 ListFormat format, const std::vector<CraterAttributes>& attributes) {
168
6/6
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 6 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 35 times.
✓ Branch 7 taken 1 time.
✓ Branch 8 taken 41 times.
42 if (!attributes.empty() && attributes.size() != craters.Size()) {
169
1/1
✓ Branch 2 taken 1 time.
1 throw std::invalid_argument("Crater attributes must be empty or one per crater");
170 }
171
1/1
✓ Branch 1 taken 40 times.
41 std::ofstream file = OpenForWriting(path);
172
2/3
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
40 switch (format) {
173 36 case ListFormat::Csv:
174
1/1
✓ Branch 1 taken 36 times.
36 WriteCraterCsv(file, craters, attributes);
175 36 break;
176 4 case ListFormat::Json:
177
4/4
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
✓ Branch 7 taken 4 times.
✓ Branch 10 taken 4 times.
4 file << CraterJson(craters, attributes).dump(2) << '\n';
178 4 break;
179 }
180
1/1
✓ Branch 1 taken 39 times.
40 CheckWritten(file, path);
181 40 }
182
183 31 void WriteBoulderList(const std::vector<Boulder>& boulders, const std::filesystem::path& path,
184 ListFormat format) {
185
1/1
✓ Branch 1 taken 30 times.
31 std::ofstream file = OpenForWriting(path);
186
2/3
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
30 switch (format) {
187 25 case ListFormat::Csv:
188
1/1
✓ Branch 1 taken 25 times.
25 WriteBoulderCsv(file, boulders);
189 25 break;
190 5 case ListFormat::Json:
191
4/4
✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
✓ Branch 7 taken 5 times.
✓ Branch 10 taken 5 times.
5 file << BoulderJson(boulders).dump(2) << '\n';
192 5 break;
193 }
194
1/1
✓ Branch 1 taken 29 times.
30 CheckWritten(file, path);
195 30 }
196
197 22 void WriteBoulderModels(const std::vector<BoulderModel>& boulders,
198 const std::filesystem::path& path, double creaseAngle,
199 const Surface& surface, const Vec2d& site, bool instanced) {
200
4/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 20 times.
22 if (!(creaseAngle >= 0.0 && creaseAngle <= 180.0)) {
201
1/1
✓ Branch 2 taken 2 times.
2 throw std::invalid_argument("Crease angle must be between 0 and 180 degrees");
202 }
203
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 19 times.
20 if (boulders.empty()) {
204
1/1
✓ Branch 2 taken 1 time.
1 throw std::invalid_argument("There are no boulder models to write");
205 }
206 19 WriteBoulderScene(boulders, path, creaseAngle, surface, site, instanced);
207 18 }
208
209 } // namespace terraingen
210