| 71 | using namespace WireVertexPeriodicIndexAttributeHelper; |
| 72 | |
| 73 | void WireVertexPeriodicIndexAttribute::compute(const WireNetwork& network) { |
| 74 | const Float EPS = 1e-6; |
| 75 | const size_t dim = network.get_dim(); |
| 76 | const size_t num_vertices = network.get_num_vertices(); |
| 77 | const MatrixFr& vertices = network.get_vertices(); |
| 78 | |
| 79 | const VectorF bbox_min = vertices.colwise().minCoeff(); |
| 80 | const VectorF bbox_max = vertices.colwise().maxCoeff(); |
| 81 | const VectorF bbox_size = bbox_max - bbox_min; |
| 82 | |
| 83 | HashGrid::Ptr grid = HashGrid::create(EPS, dim); |
| 84 | m_values.resize(num_vertices, 1); |
| 85 | for (size_t i=0; i<num_vertices; i++) { |
| 86 | const VectorF& v = vertices.row(i); |
| 87 | m_values(i, 0) = i; |
| 88 | grid->insert(i, v); |
| 89 | } |
| 90 | |
| 91 | FunctionList transforms = get_periodic_transforms(bbox_size); |
| 92 | for (auto trans: transforms) { |
| 93 | std::vector<bool> visited(num_vertices, false); |
| 94 | for (size_t i=0; i<num_vertices; i++) { |
| 95 | if (visited[i]) continue; |
| 96 | const VectorF& v = vertices.row(i); |
| 97 | |
| 98 | if ((v - bbox_min).cwiseAbs().minCoeff() < EPS) { |
| 99 | VectorF opposite = trans(v); |
| 100 | VectorI opposite_indices = grid->get_items_near_point(opposite); |
| 101 | VectorI current_indices = grid->get_items_near_point(v); |
| 102 | |
| 103 | if (opposite_indices.size() == 0) continue; |
| 104 | |
| 105 | std::vector<int> indices(opposite_indices.size() + |
| 106 | current_indices.size()); |
| 107 | std::copy(opposite_indices.data(), opposite_indices.data() + |
| 108 | opposite_indices.size(), indices.begin()); |
| 109 | std::copy(current_indices.data(), current_indices.data() + |
| 110 | current_indices.size(), indices.begin() + |
| 111 | opposite_indices.size()); |
| 112 | |
| 113 | auto get_value = [&](size_t i) { |
| 114 | return size_t(m_values(i,0)); |
| 115 | }; |
| 116 | |
| 117 | std::vector<size_t> periodic_indices(indices.size()); |
| 118 | std::transform(indices.begin(), indices.end(), |
| 119 | periodic_indices.begin(), get_value); |
| 120 | size_t label = *std::min_element( |
| 121 | periodic_indices.begin(), periodic_indices.end()); |
| 122 | |
| 123 | for (auto idx : indices) { |
| 124 | m_values(idx, 0) = label; |
| 125 | visited[idx] = true; |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | } |
nothing calls this directly
no test coverage detected