Skip to content

Commit 36a57d1

Browse files
author
pv
committed
FIX remove duplicate vertices
1 parent 5f8f4a7 commit 36a57d1

File tree

2 files changed

+116
-33
lines changed

2 files changed

+116
-33
lines changed

src/compas_libigl/mapping.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import numpy as np
2-
from compas.utilities import print_profile
32

43
from compas_libigl import _mapping
54

65

7-
@print_profile
86
def map_mesh(target_mesh, pattern_mesh, clip_boundaries=True):
97
"""
108
Map a 2D pattern mesh onto a 3D target.

src/mapping.cpp

Lines changed: 116 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,36 @@
11
#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+
}
234

335
std::vector<std::vector<int>> map_mesh_cropped(
436
Eigen::Ref<const compas::RowMatrixXd> v,
@@ -217,56 +249,109 @@ std::tuple<compas::RowMatrixXd, std::vector<std::vector<int>>> eigen_to_clipper
217249

218250
solutions.push_back(solution);
219251
}
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();
227252

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;
235255
std::vector<std::vector<int>> faces;
236-
faces.reserve(total_points); // This is an overestimation, but ensures capacity
237256

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+
};
241273

242-
for (const auto &solution : solutions){
274+
for (const auto &solution : solutions) {
243275
for (const auto& path : solution) {
244276
std::vector<int> face;
245277
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);
251280
}
252281
faces.push_back(face);
253282
}
254283
}
255-
256-
for (const auto &subject : patterns_to_keep){
284+
285+
for (const auto &subject : patterns_to_keep) {
257286
for (const auto& path : subject) {
258287
std::vector<int> face;
259288
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);
265291
}
266292
faces.push_back(face);
267293
}
268294
}
269295

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+
270355
return std::make_tuple(vertices, faces);
271356

272357
}

0 commit comments

Comments
 (0)