| 1115 | } |
| 1116 | |
| 1117 | std::vector<LineRun> runs_from_graph(const CenterLineGraphData& graph, double angle_tol_deg = 3., double line_dist_tol = 0.15) { |
| 1118 | std::vector<bool> visited(graph.edges.size(), false); |
| 1119 | std::vector<LineRun> runs; |
| 1120 | |
| 1121 | for (size_t seed_ei = 0; seed_ei < graph.edges.size(); ++seed_ei) { |
| 1122 | if (visited[seed_ei]) { |
| 1123 | continue; |
| 1124 | } |
| 1125 | |
| 1126 | const auto& seed_edge = graph.edges[seed_ei]; |
| 1127 | auto seed_a = graph.points_double[seed_edge.first]; |
| 1128 | auto seed_b = graph.points_double[seed_edge.second]; |
| 1129 | auto seed_dir = seed_b - seed_a; |
| 1130 | if (seed_dir.squared_length() < 1.e-18) { |
| 1131 | visited[seed_ei] = true; |
| 1132 | continue; |
| 1133 | } |
| 1134 | |
| 1135 | std::vector<size_t> queue = {seed_ei}; |
| 1136 | std::set<size_t> component_edges; |
| 1137 | |
| 1138 | while (!queue.empty()) { |
| 1139 | auto ei = queue.back(); |
| 1140 | queue.pop_back(); |
| 1141 | if (!component_edges.insert(ei).second) { |
| 1142 | continue; |
| 1143 | } |
| 1144 | |
| 1145 | const auto& edge = graph.edges[ei]; |
| 1146 | std::array<size_t, 2> vertices = {edge.first, edge.second}; |
| 1147 | for (auto v : vertices) { |
| 1148 | for (auto ej : graph.incident_edges[v]) { |
| 1149 | if (ej == ei || visited[ej] || component_edges.count(ej)) { |
| 1150 | continue; |
| 1151 | } |
| 1152 | const auto& candidate = graph.edges[ej]; |
| 1153 | auto test_a = graph.points_double[candidate.first]; |
| 1154 | auto test_b = graph.points_double[candidate.second]; |
| 1155 | if (edge_supports_same_line(seed_a, seed_b, test_a, test_b, angle_tol_deg, line_dist_tol)) { |
| 1156 | queue.push_back(ej); |
| 1157 | } |
| 1158 | } |
| 1159 | } |
| 1160 | } |
| 1161 | |
| 1162 | for (auto ei : component_edges) { |
| 1163 | visited[ei] = true; |
| 1164 | } |
| 1165 | |
| 1166 | std::set<size_t> component_vertices; |
| 1167 | auto ref = unit(seed_dir); |
| 1168 | DDir direction_sum{0., 0.}; |
| 1169 | double total_length = 0.; |
| 1170 | double weighted_width_sum = 0.; |
| 1171 | |
| 1172 | for (auto ei : component_edges) { |
| 1173 | const auto& edge = graph.edges[ei]; |
| 1174 | component_vertices.insert(edge.first); |
no test coverage detected