|
1 | 1 | #include "mapping.hpp" |
| 2 | +#include <unordered_map> |
| 3 | +#include <vector> |
| 4 | +#include <cmath> |
| 5 | +#include <tuple> |
| 6 | +#include <iomanip> |
| 7 | +#include <iostream> |
| 8 | + |
| 9 | +// Custom hash function for tuple |
| 10 | +struct TupleHash { |
| 11 | + std::size_t operator()(const std::tuple<int64_t, int64_t>& t) const { |
| 12 | + auto h1 = std::hash<int64_t>{}(std::get<0>(t)); |
| 13 | + auto h2 = std::hash<int64_t>{}(std::get<1>(t)); |
| 14 | + return h1 ^ (h2 << 1); // basic hash combination |
| 15 | + } |
| 16 | +}; |
| 17 | + |
| 18 | +constexpr double TOLERANCE = 1e-6; |
| 19 | + |
| 20 | +std::tuple<int64_t, int64_t> grid_key(double x, double y) { |
| 21 | + return { |
| 22 | + static_cast<int64_t>(std::floor(x / TOLERANCE)), |
| 23 | + static_cast<int64_t>(std::floor(y / TOLERANCE)) |
| 24 | + }; |
| 25 | +} |
| 26 | + |
| 27 | +bool is_same_point(double x1, double y1, double z1, |
| 28 | + double x2, double y2, double z2, |
| 29 | + double tol) { |
| 30 | + return std::abs(x1 - x2) < tol && |
| 31 | + std::abs(y1 - y2) < tol && |
| 32 | + std::abs(z1 - z2) < tol; |
| 33 | +} |
2 | 34 |
|
3 | 35 | std::vector<std::vector<int>> map_mesh_cropped( |
4 | 36 | Eigen::Ref<const compas::RowMatrixXd> v, |
@@ -217,56 +249,109 @@ std::tuple<compas::RowMatrixXd, std::vector<std::vector<int>>> eigen_to_clipper |
217 | 249 |
|
218 | 250 | solutions.push_back(solution); |
219 | 251 | } |
220 | | - //solutions = patterns_to_cut; |
221 | | - |
222 | | - // Count total points |
223 | | - size_t total_points = 0; |
224 | | - for (const auto &solution : solutions) |
225 | | - for (const auto &path : solution) |
226 | | - total_points += path.size(); |
227 | 252 |
|
228 | | - for (const auto &subject : patterns_to_keep) |
229 | | - for (const auto &path : subject) |
230 | | - total_points += path.size(); |
231 | | - |
232 | | - |
233 | | - // We'll count the total points and then initialize our output matrices |
234 | | - // These will be populated later |
| 253 | + std::vector<std::array<double, 3>> unique_points; |
| 254 | + std::unordered_map<std::tuple<int64_t, int64_t>, std::vector<int>, TupleHash> grid_map; |
235 | 255 | std::vector<std::vector<int>> faces; |
236 | | - faces.reserve(total_points); // This is an overestimation, but ensures capacity |
237 | 256 |
|
238 | | - size_t point_index = 0; // Reset point index |
239 | | - |
240 | | - compas::RowMatrixXd vertices(total_points, 3); |
| 257 | + auto find_or_add_point = [&](double x, double y) -> int { |
| 258 | + double z = 0.0; |
| 259 | + auto key = grid_key(x, y); |
| 260 | + auto& bucket = grid_map[key]; |
| 261 | + |
| 262 | + for (int idx : bucket) { |
| 263 | + const auto& pt = unique_points[idx]; |
| 264 | + if (is_same_point(pt[0], pt[1], pt[2], x, y, z, TOLERANCE)) |
| 265 | + return idx; |
| 266 | + } |
| 267 | + |
| 268 | + int new_index = static_cast<int>(unique_points.size()); |
| 269 | + unique_points.push_back({x, y, z}); |
| 270 | + bucket.push_back(new_index); |
| 271 | + return new_index; |
| 272 | + }; |
241 | 273 |
|
242 | | - for (const auto &solution : solutions){ |
| 274 | + for (const auto &solution : solutions) { |
243 | 275 | for (const auto& path : solution) { |
244 | 276 | std::vector<int> face; |
245 | 277 | for (const auto& point : path) { |
246 | | - vertices(point_index, 0) = point.x; |
247 | | - vertices(point_index, 1) = point.y; |
248 | | - vertices(point_index, 2) = 0; |
249 | | - face.push_back(point_index); |
250 | | - point_index++; |
| 278 | + int idx = find_or_add_point(point.x, point.y); |
| 279 | + face.push_back(idx); |
251 | 280 | } |
252 | 281 | faces.push_back(face); |
253 | 282 | } |
254 | 283 | } |
255 | | - |
256 | | - for (const auto &subject : patterns_to_keep){ |
| 284 | + |
| 285 | + for (const auto &subject : patterns_to_keep) { |
257 | 286 | for (const auto& path : subject) { |
258 | 287 | std::vector<int> face; |
259 | 288 | for (const auto& point : path) { |
260 | | - vertices(point_index, 0) = point.x; |
261 | | - vertices(point_index, 1) = point.y; |
262 | | - vertices(point_index, 2) = 0; // Set z-coordinate to 0 |
263 | | - face.push_back(point_index); |
264 | | - point_index++; |
| 289 | + int idx = find_or_add_point(point.x, point.y); |
| 290 | + face.push_back(idx); |
265 | 291 | } |
266 | 292 | faces.push_back(face); |
267 | 293 | } |
268 | 294 | } |
269 | 295 |
|
| 296 | + compas::RowMatrixXd vertices(unique_points.size(), 3); |
| 297 | + for (size_t i = 0; i < unique_points.size(); ++i) { |
| 298 | + vertices(i, 0) = unique_points[i][0]; |
| 299 | + vertices(i, 1) = unique_points[i][1]; |
| 300 | + vertices(i, 2) = 0.0; |
| 301 | + } |
| 302 | + |
| 303 | + |
| 304 | + |
| 305 | + // //solutions = patterns_to_cut; |
| 306 | + |
| 307 | + // // Count total points |
| 308 | + // size_t total_points = 0; |
| 309 | + // for (const auto &solution : solutions) |
| 310 | + // for (const auto &path : solution) |
| 311 | + // total_points += path.size(); |
| 312 | + |
| 313 | + // for (const auto &subject : patterns_to_keep) |
| 314 | + // for (const auto &path : subject) |
| 315 | + // total_points += path.size(); |
| 316 | + |
| 317 | + |
| 318 | + // // We'll count the total points and then initialize our output matrices |
| 319 | + // // These will be populated later |
| 320 | + // std::vector<std::vector<int>> faces; |
| 321 | + // faces.reserve(total_points); // This is an overestimation, but ensures capacity |
| 322 | + |
| 323 | + // size_t point_index = 0; // Reset point index |
| 324 | + |
| 325 | + // compas::RowMatrixXd vertices(total_points, 3); |
| 326 | + |
| 327 | + // for (const auto &solution : solutions){ |
| 328 | + // for (const auto& path : solution) { |
| 329 | + // std::vector<int> face; |
| 330 | + // for (const auto& point : path) { |
| 331 | + // vertices(point_index, 0) = point.x; |
| 332 | + // vertices(point_index, 1) = point.y; |
| 333 | + // vertices(point_index, 2) = 0; |
| 334 | + // face.push_back(point_index); |
| 335 | + // point_index++; |
| 336 | + // } |
| 337 | + // faces.push_back(face); |
| 338 | + // } |
| 339 | + // } |
| 340 | + |
| 341 | + // for (const auto &subject : patterns_to_keep){ |
| 342 | + // for (const auto& path : subject) { |
| 343 | + // std::vector<int> face; |
| 344 | + // for (const auto& point : path) { |
| 345 | + // vertices(point_index, 0) = point.x; |
| 346 | + // vertices(point_index, 1) = point.y; |
| 347 | + // vertices(point_index, 2) = 0; // Set z-coordinate to 0 |
| 348 | + // face.push_back(point_index); |
| 349 | + // point_index++; |
| 350 | + // } |
| 351 | + // faces.push_back(face); |
| 352 | + // } |
| 353 | + // } |
| 354 | + |
270 | 355 | return std::make_tuple(vertices, faces); |
271 | 356 |
|
272 | 357 | } |
|
0 commit comments