1 #ifndef RAM_PATH_PLANNING_DONGHONG_DING_IMP_HPP 2 #define RAM_PATH_PLANNING_DONGHONG_DING_IMP_HPP 8 template<
class ActionSpec>
11 "ram/path_planning/generate_trajectory/donghong_ding"),
21 template<
class ActionSpec>
23 const int current_progrress_value,
24 const int next_progress_value,
27 const double deposited_material_width,
28 const double contours_filtering_tolerance,
29 const std::array<double, 3> normal_vector,
30 const double polygon_division_tolerance,
31 const bool closest_to_bisector,
39 int progress_value = current_progrress_value;
42 return "Polydata is not initialized";
44 if (poly_data->GetNumberOfPoints() == 0)
45 return "Polydata is empty";
53 if (normal_vector[0] == 0 && normal_vector[1] == 0 && normal_vector[2] == 0)
66 return "Failed to remove duplicate points";
69 return "Failed to merge colinear edges";
72 return "Contours intersects";
74 std::vector<int> level;
75 std::vector<int> father;
78 return "Failed to organize polygon contours in layer";
81 vtkSmartPointer<vtkPoints> split_points = vtkSmartPointer<vtkPoints>::New();
82 for (
unsigned i(0); i < layer.size(); ++i)
85 while (j < layer[i].size())
91 std::getline(std::cin, s);
97 vtkIdType n_cells = layer[i][j]->GetNumberOfCells();
98 if (n_cells == 1 && vtkPolygon::IsConvex(layer[i][j]->GetPoints()))
102 return "Error dividing the polygons";
105 v = 0.5 * (i + 1) / layer.size();
106 progress_value = (int)(current_progrress_value + v * (next_progress_value - current_progrress_value));
110 return "GoalHandle is not active";
116 std::getline(std::cin, s);
121 std::vector<std::future<bool> > futures;
122 for (
auto polygons : layer)
123 for (
auto poly_data : polygons)
126 bool global_return =
true;
127 for (
auto &t : futures)
128 global_return &= t.get();
130 return "Failed to generate trajectory in one of the convex polygons";
133 vtkIdType n_lines = split_points->GetNumberOfPoints() / 2;
134 int current_line = 0;
135 unsigned polygon_id = layer.size() - 1;
136 for (
int line_id(n_lines - 1); line_id >= 0; --line_id)
142 std::getline(std::cin, s);
143 ROS_INFO_STREAM(
"Enter was pressed: Merging polygons. Line " << line_id);
148 v = 0.5 + 0.5 * (current_line) / (n_lines);
149 progress_value = (int)(current_progrress_value + v * (next_progress_value - current_progrress_value));
151 return "GoalHandle is not active";
153 if (layer[polygon_id].size() == 1)
156 return "Failed to merge convex polygons";
159 for (
auto polygons : layer)
160 for (
auto poly_data : polygons)
163 return "Failed to remove duplicate points";
165 return "Failed to merge colinear edges";
172 std::getline(std::cin, s);
177 template<
class ActionSpec>
179 const int current_progrress_value,
180 const int next_progress_value,
181 const std::string yaml_file,
183 const double deposited_material_width,
184 const double contours_filtering_tolerance,
185 const double polygon_division_tolerance,
186 const bool closest_to_bisector,
190 const Polygon poly_data = Polygon::New();
191 std::vector<unsigned> layer_count;
194 return "Could not parse the YAML file";
196 std::array<double, 3> normal_vector = {0, 0, 1};
199 deposited_material_width,
200 contours_filtering_tolerance, normal_vector,
201 polygon_division_tolerance,
202 closest_to_bisector, use_gui);
205 template<
class ActionSpec>
211 vtkIdType n_cells = poly_data->GetNumberOfCells();
213 for (vtkIdType i(0); i < n_cells; ++i)
216 vtkIdType n_points = poly_data->GetCell(i)->GetNumberOfPoints();
217 for (vtkIdType j(0); j < n_points; ++j)
224 poly_data->GetCell(i)->GetPoints()->GetPoint((n_points - 1), p0);
226 poly_data->GetCell(i)->GetPoints()->GetPoint((j - 1), p0);
228 poly_data->GetCell(i)->GetPoints()->GetPoint(j, p1);
229 poly_data->GetCell(i)->GetPoints()->GetPoint((j + 1) % n_points, p2);
234 vtkMath::Subtract(p0, p1, v1);
235 vtkMath::Subtract(p2, p1, v2);
251 template<
class ActionSpec>
253 const vtkIdType notch_cell_id,
254 const vtkIdType notch_pos,
255 const vtkIdType vertex_cell_id,
256 const vtkIdType vertex_pos)
258 vtkIdType n_points_cell;
259 double notch_prev[3];
261 double notch_next[3];
262 n_points_cell = poly_data->GetCell(notch_cell_id)->GetNumberOfPoints();
265 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint((n_points_cell - 1), notch_prev);
267 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint((notch_pos - 1), notch_prev);
268 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint(notch_pos, notch);
269 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint((notch_pos + 1) % n_points_cell, notch_next);
271 double vertex_prev[3];
273 double vertex_next[3];
274 n_points_cell = poly_data->GetCell(vertex_cell_id)->GetNumberOfPoints();
277 poly_data->GetCell(vertex_cell_id)->GetPoints()->GetPoint((n_points_cell - 1), vertex_prev);
279 poly_data->GetCell(vertex_cell_id)->GetPoints()->GetPoint((vertex_pos - 1), vertex_prev);
280 poly_data->GetCell(vertex_cell_id)->GetPoints()->GetPoint(vertex_pos, vertex);
281 poly_data->GetCell(vertex_cell_id)->GetPoints()->GetPoint((vertex_pos + 1) % n_points_cell, vertex_next);
287 vtkMath::Subtract(vertex, notch, v_2);
288 vtkMath::Subtract(notch_prev, notch, v_1);
292 vtkMath::Subtract(notch_next, notch, v_1);
296 vtkMath::Subtract(notch, vertex, v_2);
297 vtkMath::Subtract(vertex_prev, vertex, v_1);
301 vtkMath::Subtract(vertex_next, vertex, v_1);
307 template<
class ActionSpec>
312 vtkIdType n_cells = poly_data->GetNumberOfCells();
313 for (vtkIdType cell_id(0); cell_id < n_cells; ++cell_id)
315 vtkIdType n_edges = poly_data->GetCell(cell_id)->GetNumberOfEdges();
316 for (vtkIdType edge_id(0); edge_id < n_edges; ++edge_id)
320 poly_data->GetCell(cell_id)->GetEdge(edge_id)->GetPoints()->GetPoint(0, e_p1);
321 poly_data->GetCell(cell_id)->GetEdge(edge_id)->GetPoints()->GetPoint(1, e_p2);
324 int intersection = 0;
326 intersection = vtkLine::Intersection3D(point_1, point_2, e_p1, e_p2, u, v);
334 template<
class ActionSpec>
336 const vtkIdType notch_cell_id,
337 const vtkIdType notch_pos,
338 vtkIdType &vertex_cell_id,
339 vtkIdType &vertex_pos,
340 const double notch_angle)
342 double ref_angle = notch_angle * (-1);
343 vtkIdType n_cells = poly_data->GetNumberOfCells();
344 bool is_vertex =
false;
350 double notch_next[3];
351 vtkIdType n_points_cell = poly_data->GetCell(notch_cell_id)->GetNumberOfPoints();
352 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint(notch_pos, notch);
353 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint((notch_pos + 1) % n_points_cell, notch_next);
354 vtkMath::Subtract(notch, notch_next, v_ref);
357 bool is_notch =
false;
358 float vertex_d = FLT_MAX;
359 for (vtkIdType cell_id(0); cell_id < n_cells; ++cell_id)
361 vtkIdType n_points = poly_data->GetCell(cell_id)->GetNumberOfPoints();
362 for (vtkIdType point_id(0); point_id < n_points; ++point_id)
368 poly_data->GetCell(cell_id)->GetPoints()->GetPoint((n_points - 1), p0);
370 poly_data->GetCell(cell_id)->GetPoints()->GetPoint((point_id - 1), p0);
371 poly_data->GetCell(cell_id)->GetPoints()->GetPoint(point_id, p);
372 poly_data->GetCell(cell_id)->GetPoints()->GetPoint((point_id + 1) % n_points, p2);
375 vtkMath::Subtract(p, notch, vector);
378 if (!(angle >= 0 && angle <= ref_angle))
387 vtkMath::Subtract(p0, p, p1_p0);
388 vtkMath::Subtract(p2, p, p2_p0);
398 if (!((point_angle > 0 && !is_notch) || point_angle < 0))
405 point_d =
sqrt(vtkMath::Distance2BetweenPoints(notch, p)) * std::abs(
sin(angle - ref_angle / 2));
407 point_d =
sqrt(vtkMath::Distance2BetweenPoints(notch, p));
409 if (point_d < vertex_d)
414 vertex_pos = point_id;
415 vertex_cell_id = cell_id;
424 template<
class ActionSpec>
426 const vtkIdType notch_cell_id,
427 const vtkIdType notch_pos,
428 vtkIdType &vertex_cell_id,
429 vtkIdType &vertex_pos,
432 double notch_prev[3];
434 double notch_next[3];
436 vtkIdType n_points_cell = poly_data->GetCell(notch_cell_id)->GetNumberOfPoints();
439 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint((n_points_cell - 1), notch_prev);
441 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint((notch_pos - 1), notch_prev);
442 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint(notch_pos, notch);
443 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint((notch_pos + 1) % n_points_cell, notch_next);
446 double v1[3] = {notch[0] - notch_prev[0], notch[1] - notch_prev[1], notch[2] - notch_prev[2]};
448 double v2[3] = {notch[0] - notch_next[0], notch[1] - notch_next[1], notch[2] - notch_next[2]};
449 vtkMath::Normalize(v1);
450 vtkMath::Normalize(v2);
451 double bisector[3] = {v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]};
452 vtkMath::Normalize(bisector);
454 poly_data->GetPoints()->GetBounds(bounds);
455 double bound_min[3] = {bounds[0], bounds[2], bounds[4]};
456 double bound_max[3] = {bounds[1], bounds[3], bounds[5]};
459 double d_max =
sqrt(vtkMath::Distance2BetweenPoints(bound_min, bound_max));
462 double bisector_p[3];
463 for (
unsigned i(0); i < 3; ++i)
464 bisector_p[i] = notch[i] + d_max * bisector[i];
467 double vertex_coordinate = DBL_MAX;
468 bool find_intersection =
false;
469 vtkIdType n_cells = poly_data->GetNumberOfCells();
471 for (vtkIdType cell_id(0); cell_id < n_cells; ++cell_id)
473 vtkIdType n_edges = poly_data->GetCell(cell_id)->GetNumberOfEdges();
474 for (vtkIdType edge_id(0); edge_id < n_edges; ++edge_id)
478 poly_data->GetCell(cell_id)->GetEdge(edge_id)->GetPoints()->GetPoint(0, e_p1);
479 poly_data->GetCell(cell_id)->GetEdge(edge_id)->GetPoints()->GetPoint(1, e_p2);
482 int intersection = 0;
483 intersection = vtkLine::Intersection3D(notch, bisector_p, e_p1, e_p2, u, v);
484 if (u < vertex_coordinate && intersection == 2 && std::abs(u) > this->
calculation_tol_ 488 find_intersection =
true;
489 vertex_coordinate = u;
490 vertex_cell_id = cell_id;
491 vertex_pos = edge_id;
496 if (find_intersection ==
false)
502 for (
unsigned i = 0; i < 3; i++)
503 vertex[i] = notch[i] + vertex_coordinate * d_max * bisector[i];
508 template<
class ActionSpec>
510 const int polygon_position,
511 const vtkSmartPointer<vtkPoints> split_points)
516 vtkSmartPointer<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New();
517 poly_data->DeepCopy(polygon_source[polygon_position]);
518 vtkIdType n_cells = poly_data->GetNumberOfCells();
524 if (n_cells == 1 && vtkPolygon::IsConvex(poly_data->GetPoints()))
530 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
531 points = poly_data->GetPoints();
533 vtkIdType notch_cell_id;
536 if (!
findNotch(poly_data, notch_cell_id, notch_id, angle))
539 poly_data->GetCell(notch_cell_id)->GetPoints()->GetPoint(notch_id, notch);
541 vtkIdType vertex_cell_id;
542 vtkIdType vertex_pos;
543 vtkIdType vertex_edge_id;
547 bool is_vertex(
findVertex(poly_data, notch_cell_id, notch_id, vertex_cell_id, vertex_pos, angle));
550 is_vertex =
verifyAngles(poly_data, notch_cell_id, notch_id, vertex_cell_id, vertex_pos);
552 if (is_vertex ==
false)
558 poly_data->GetCell(vertex_cell_id)->GetPoints()->GetPoint(vertex_pos, vertex);
567 vtkSmartPointer<vtkCellArray> polygon_array_a = vtkSmartPointer<vtkCellArray>::New();
568 vtkSmartPointer<vtkPoints> points_a = vtkSmartPointer<vtkPoints>::New();
570 vtkSmartPointer<vtkCellArray> polygon_array_b = vtkSmartPointer<vtkCellArray>::New();
571 vtkSmartPointer<vtkPoints> points_b = vtkSmartPointer<vtkPoints>::New();
573 vtkSmartPointer<vtkPoints> point_list = vtkSmartPointer<vtkPoints>::New();
574 vtkSmartPointer<vtkPolygon> polygon_a = vtkSmartPointer<vtkPolygon>::New();
575 vtkSmartPointer<vtkPolygon> polygon_b = vtkSmartPointer<vtkPolygon>::New();
583 point_list = poly_data->GetCell(0)->GetPoints();
584 vtkIdType last_point_a;
585 vtkIdType first_point_b;
586 if (notch_cell_id == 0 && vertex_cell_id == 0)
588 if (is_vertex ==
true)
590 split_points->InsertNextPoint(notch);
591 split_points->InsertNextPoint(vertex);
592 last_point_a = vertex_pos;
593 first_point_b = vertex_pos;
597 split_points->InsertNextPoint(vertex);
598 split_points->InsertNextPoint(notch);
599 last_point_a = vertex_edge_id;
600 first_point_b = (vertex_edge_id + 1) % point_list->GetNumberOfPoints();
602 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
603 polygon_a->GetPoints()->InsertNextPoint(vertex);
604 points_a->InsertNextPoint(vertex);
606 polygon_b->GetPointIds()->InsertNextId(points_b->GetNumberOfPoints());
607 polygon_b->GetPoints()->InsertNextPoint(vertex);
608 points_b->InsertNextPoint(vertex);
610 vtkIdType n_points = point_list->GetNumberOfPoints();
611 for (vtkIdType i(0); i < n_points; ++i)
613 int id = (i + notch_id) % n_points;
614 point_list->GetPoint(
id, p);
615 if (first_point_b > notch_id)
617 if (
id >= notch_id &&
id <= last_point_a)
619 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
620 polygon_a->GetPoints()->InsertNextPoint(p);
621 points_a->InsertNextPoint(p);
623 if (
id >= first_point_b ||
id < notch_id)
625 polygon_b->GetPointIds()->InsertNextId(points_b->GetNumberOfPoints());
626 polygon_b->GetPoints()->InsertNextPoint(p);
627 points_b->InsertNextPoint(p);
630 else if (first_point_b < notch_id)
632 if (
id >= notch_id || (last_point_a < notch_id &&
id <= last_point_a))
634 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
635 polygon_a->GetPoints()->InsertNextPoint(p);
636 points_a->InsertNextPoint(p);
639 if (
id >= first_point_b &&
id < notch_id)
641 polygon_b->GetPointIds()->InsertNextId(points_b->GetNumberOfPoints());
642 polygon_b->GetPoints()->InsertNextPoint(p);
643 points_b->InsertNextPoint(p);
647 point_list->GetPoint(notch_id, p);
648 polygon_b->GetPointIds()->InsertNextId(points_b->GetNumberOfPoints());
649 polygon_b->GetPoints()->InsertNextPoint(p);
650 points_b->InsertNextPoint(p);
652 polygon_array_a->InsertNextCell(polygon_a);
653 polygon_array_b->InsertNextCell(polygon_b);
655 vtkSmartPointer<vtkPolygon> external_contour_a = vtkSmartPointer<vtkPolygon>::New();
656 external_contour_a->DeepCopy(polygon_a);
657 for (vtkIdType i = 1; i < n_cells; i++)
659 polygon_a = vtkSmartPointer<vtkPolygon>::New();
660 polygon_b = vtkSmartPointer<vtkPolygon>::New();
661 point_list = poly_data->GetCell(i)->GetPoints();
662 point_list->GetPoint(0, p);
666 external_contour_a->GetPoints()->GetBounds(bounds);
668 int in_polygon_a = external_contour_a->PointInPolygon(
669 p, external_contour_a->GetPoints()->GetNumberOfPoints(),
670 static_cast<double*
>(external_contour_a->GetPoints()->GetData()->GetVoidPointer(0)),
673 if (in_polygon_a == 1)
675 for (vtkIdType j = 0; j < point_list->GetNumberOfPoints(); ++j)
677 point_list->GetPoint(j, p);
678 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
679 polygon_a->GetPoints()->InsertNextPoint(p);
680 points_a->InsertNextPoint(p);
682 polygon_array_a->InsertNextCell(polygon_a);
684 if (in_polygon_a == 0)
686 for (vtkIdType j = 0; j < point_list->GetNumberOfPoints(); ++j)
688 point_list->GetPoint(j, p);
689 polygon_b->GetPointIds()->InsertNextId(points_b->GetNumberOfPoints());
690 polygon_b->GetPoints()->InsertNextPoint(p);
691 points_b->InsertNextPoint(p);
693 polygon_array_b->InsertNextCell(polygon_b);
699 if (notch_cell_id != vertex_cell_id)
701 vtkIdType first_point_vertex_contour;
702 if (notch_cell_id != 0 && vertex_cell_id != 0)
705 polygon_a = vtkSmartPointer<vtkPolygon>::New();
706 point_list = poly_data->GetCell(0)->GetPoints();
707 for (vtkIdType j = 0; j < point_list->GetNumberOfPoints(); ++j)
709 point_list->GetPoint(j, p);
710 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
711 points_a->InsertNextPoint(p);
713 polygon_array_a->InsertNextCell(polygon_a);
714 polygon_a = vtkSmartPointer<vtkPolygon>::New();
717 point_list = poly_data->GetCell(notch_cell_id)->GetPoints();
718 n_points = point_list->GetNumberOfPoints();
721 for (vtkIdType i = 0; i <= n_points; i++)
723 vtkIdType pos = (i + notch_id) % n_points;
724 point_list->GetPoint(pos, p);
728 double next_point[3];
729 point_list->GetPoint((i + 1 + notch_id) % n_points, next_point);
730 vtkMath::Subtract(next_point, p, delta);
731 vtkMath::Normalize(delta);
732 vtkMath::MultiplyScalar(delta, 1e-7);
733 vtkMath::Add(p, delta, p);
735 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
736 polygon_a->GetPoints()->InsertNextPoint(p);
737 points_a->InsertNextPoint(p);
740 point_list = poly_data->GetCell(vertex_cell_id)->GetPoints();
741 n_points = point_list->GetNumberOfPoints();
742 if (is_vertex ==
true)
743 first_point_vertex_contour = vertex_pos;
746 first_point_vertex_contour = (vertex_edge_id + 1) % n_points;
747 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
748 points_a->InsertNextPoint(vertex);
751 for (vtkIdType i = 0; i < n_points; i++)
753 vtkIdType pos = (i + first_point_vertex_contour) % n_points;
754 point_list->GetPoint(pos, p);
755 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
756 points_a->InsertNextPoint(p);
758 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
759 vtkMath::Add(vertex, delta, vertex);
760 points_a->InsertNextPoint(vertex);
762 polygon_array_a->InsertNextCell(polygon_a);
764 for (vtkIdType i = 1; i < n_cells; i++)
766 if (i != vertex_cell_id && i != notch_cell_id)
768 polygon_a = vtkSmartPointer<vtkPolygon>::New();
769 point_list = poly_data->GetCell(i)->GetPoints();
770 for (vtkIdType j = 0; j < point_list->GetNumberOfPoints(); ++j)
772 point_list->GetPoint(j, p);
773 polygon_a->GetPointIds()->InsertNextId(points_a->GetNumberOfPoints());
774 points_a->InsertNextPoint(p);
776 polygon_array_a->InsertNextCell(polygon_a);
781 vtkSmartPointer<vtkPolyData> poly_data_a = vtkSmartPointer<vtkPolyData>::New();
782 poly_data_a->SetPolys(polygon_array_a);
783 poly_data_a->SetPoints(points_a);
784 polygon_source.erase(polygon_source.begin() + polygon_position);
785 polygon_source.push_back(poly_data_a);
787 if (polygon_array_b->GetNumberOfCells() > 0)
789 vtkSmartPointer<vtkPolyData> poly_data_b = vtkSmartPointer<vtkPolyData>::New();
790 poly_data_b->SetPolys(polygon_array_b);
791 poly_data_b->SetPoints(points_b);
792 polygon_source.push_back(poly_data_b);
797 template<
class ActionSpec>
800 vtkIdType &opposite_point_id)
802 if (poly_data->GetNumberOfCells() != 1)
804 ROS_ERROR_STREAM(
"identifyZigzagDirection: multiple or zero cells in the polydata");
808 vtkIdType n_points = poly_data->GetCell(0)->GetNumberOfPoints();
809 double min_global_h = DBL_MAX;
811 for (vtkIdType edge_id(0); edge_id < n_points; ++edge_id)
815 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(0, e_p1);
816 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(1, e_p2);
818 double max_local_h = 0;
819 vtkIdType local_opposite_point = 0;
820 for (vtkIdType point_id(0); point_id < n_points; ++point_id)
822 if (point_id != edge_id && point_id != (edge_id + 1) % n_points)
825 poly_data->GetCell(0)->GetPoints()->GetPoint(point_id, point);
826 double h =
sqrt(vtkLine::DistanceToLine(point, e_p1, e_p2));
828 double delta_h = h - max_local_h;
832 local_opposite_point = point_id;
837 poly_data->GetCell(0)->GetPoints()->GetPoint(local_opposite_point, max_point);
839 if (vtkMath::Distance2BetweenPoints(point, e_p2) < vtkMath::Distance2BetweenPoints(max_point, e_p2))
840 local_opposite_point = point_id;
844 if (max_local_h < min_global_h)
846 min_global_h = max_local_h;
848 opposite_point_id = local_opposite_point;
854 template<
class ActionSpec>
856 const vtkIdType edge_id,
857 const vtkIdType opposite_point_id,
858 const vtkSmartPointer<vtkPoints> left_chain,
859 const vtkSmartPointer<vtkPoints> right_chain)
861 vtkIdType n_points = poly_data->GetCell(0)->GetNumberOfPoints();
865 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(0, e_p1);
866 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(1, e_p2);
869 poly_data->GetCell(0)->GetPoints()->GetPoint(opposite_point_id, p);
870 vtkIdType last_point_id = opposite_point_id;
871 vtkIdType first_point_id = (edge_id + 1) % n_points;
873 poly_data->GetCell(0)->GetPoints()->GetPoint(last_point_id, p);
874 right_chain->InsertNextPoint(p);
876 for (vtkIdType i(0); i < n_points; ++i)
878 int id = (i + first_point_id) % n_points;
880 poly_data->GetCell(0)->GetPoints()->GetPoint(
id, p);
882 if (last_point_id > first_point_id)
884 if (
id >= first_point_id &&
id <= last_point_id)
885 left_chain->InsertNextPoint(p);
887 right_chain->InsertNextPoint(p);
891 if (id < first_point_id && id > last_point_id)
892 right_chain->InsertNextPoint(p);
894 left_chain->InsertNextPoint(p);
899 template<
class ActionSpec>
901 const vtkIdType edge_id,
902 const vtkIdType opposite_point_id,
903 const vtkSmartPointer<vtkPoints> left_chain,
904 const vtkSmartPointer<vtkPoints> right_chain)
906 if (poly_data->GetNumberOfCells() != 1)
908 ROS_ERROR_STREAM(
"offsetLeftChain: multiple or zero cells in the polydata");
911 vtkIdType n_points = poly_data->GetCell(0)->GetNumberOfPoints();
914 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(0, e_p1);
915 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(1, e_p2);
917 vtkIdType first_point_id = (edge_id + 1) % n_points;
920 double angle_first_point = M_PI / 2;
921 vtkSmartPointer<vtkPoints> new_points = vtkSmartPointer<vtkPoints>::New();
922 for (vtkIdType i(0); i < left_chain->GetNumberOfPoints(); ++i)
924 vtkIdType
id = (first_point_id + i) % n_points;
936 poly_data->GetCell(0)->GetPoints()->GetPoint((n_points - 1), p0);
938 poly_data->GetCell(0)->GetPoints()->GetPoint((
id - 1), p0);
939 poly_data->GetCell(0)->GetPoints()->GetPoint(
id, p1);
940 poly_data->GetCell(0)->GetPoints()->GetPoint((
id + 1) % n_points, p2);
942 vtkMath::Subtract(p0, p1, v1);
943 vtkMath::Subtract(p2, p1, v2);
944 vtkMath::Normalize(v1);
945 vtkMath::Normalize(v2);
946 angle = vtkMath::AngleBetweenVectors(v1, v2);
949 angle_first_point = angle;
950 for (
int k = 0; k < 3; ++k)
952 if (
sqrt(vtkMath::Distance2BetweenPoints(p1, new_point)) >
sqrt(vtkMath::Distance2BetweenPoints(p1, p0)))
954 ROS_ERROR_STREAM(
"offsetLeftChain: error modifying the first point in the left chain");
958 else if (i == (left_chain->GetNumberOfPoints() - 1))
960 for (
int k = 0; k < 3; ++k)
962 if (
sqrt(vtkMath::Distance2BetweenPoints(p1, new_point)) >
sqrt(vtkMath::Distance2BetweenPoints(p1, p2)))
964 ROS_ERROR_STREAM(
"offsetLeftChain: error modifying the last point in the left chain");
970 vtkMath::Add(v1, v2, bisector);
971 vtkMath::Normalize(bisector);
972 for (
int k = 0; k < 3; ++k)
975 new_points->InsertNextPoint(new_point);
979 for (vtkIdType i(0); i < left_chain->GetNumberOfPoints(); ++i)
983 left_chain->GetPoint(i, p_i);
984 new_points->GetPoint(i, new_p_i);
986 for (vtkIdType j(0); j < left_chain->GetNumberOfPoints(); ++j)
990 left_chain->GetPoint(i, p_j);
991 new_points->GetPoint(i, new_p_j);
995 int intersection = vtkLine::Intersection3D(p_i, new_p_i, p_j, new_p_j, u, v);
997 if (intersection == 2)
1006 for (vtkIdType i(0); i < left_chain->GetNumberOfPoints(); ++i)
1008 vtkIdType
id = (first_point_id + i) % n_points;
1009 double new_point[3];
1010 new_points->GetPoint(i, new_point);
1011 poly_data->GetPoints()->SetPoint(poly_data->GetCell(0)->GetPointId(
id), new_point);
1012 poly_data->Modified();
1020 right_chain->GetPoint(0, p0);
1021 poly_data->GetCell(0)->GetPoints()->GetPoint(opposite_point_id, p1);
1022 poly_data->GetCell(0)->GetPoints()->GetPoint((opposite_point_id + 1) % n_points, p2);
1024 if (vtkMath::Distance2BetweenPoints(p0, p1) >= vtkMath::Distance2BetweenPoints(p1, p2))
1026 ROS_ERROR_STREAM(
"offsetLeftChain: Error modifying the point between the zigzag path and the right chain");
1030 vtkMath::Subtract(p1, p0, v);
1031 for (
int k = 0; k < 3; ++k)
1033 right_chain->SetPoint(0, p0);
1036 for (vtkIdType i(left_chain->GetNumberOfPoints() - 1); i >= 0; --i)
1038 vtkIdType
id = (first_point_id + i) % n_points;
1040 poly_data->GetCell(0)->GetPoints()->GetPoint(
id, p);
1041 left_chain->InsertNextPoint(p);
1045 left_chain->GetPoint((left_chain->GetNumberOfPoints() - 1), p0);
1046 left_chain->GetPoint((left_chain->GetNumberOfPoints() - 2), p1);
1047 vtkMath::Subtract(p1, p0, v);
1048 vtkMath::Normalize(v);
1051 ROS_ERROR_STREAM(
"offsetLeftChain: Error modifying the point between the left chain and the zigzag path");
1054 for (
int k = 0; k < 3; ++k)
1056 left_chain->SetPoint((left_chain->GetNumberOfPoints() - 1), p0);
1061 template<
class ActionSpec>
1063 const vtkIdType edge_id,
1064 const vtkIdType opposite_point_id,
1065 const vtkSmartPointer<vtkPoints> zigzag_points,
1066 const double deposited_material_width)
1068 if (poly_data->GetNumberOfCells() != 1)
1070 ROS_ERROR_STREAM(
"zigzagGeneration: multiple or zero cells in the polydata");
1073 vtkIdType n_edges = poly_data->GetCell(0)->GetNumberOfEdges();
1078 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(0, e_p1);
1079 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(1, e_p2);
1080 poly_data->GetPoints()->GetPoint(opposite_point_id, last_p);
1081 poly_data->GetPoints()->GetPoint((opposite_point_id + 1) % n_edges, next_p);
1082 double zigzag_dir[3];
1084 vtkMath::Subtract(e_p1, e_p2, zigzag_dir);
1085 vtkMath::Normalize(zigzag_dir);
1088 vtkMath::Subtract(last_p, e_p2, u);
1090 vtkMath::ProjectVector(u, zigzag_dir, proj_u);
1092 vtkMath::Subtract(u, proj_u, step_dir);
1093 double h = vtkMath::Norm(step_dir);
1094 vtkMath::Normalize(step_dir);
1096 double l = deposited_material_width;
1097 zigzag_points->InsertNextPoint(e_p2);
1098 zigzag_points->InsertNextPoint(e_p1);
1103 vtkSmartPointer<vtkPoints> intersection_points = vtkSmartPointer<vtkPoints>::New();
1104 for (vtkIdType edge_id(0); edge_id < n_edges; ++edge_id)
1108 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(0, p1);
1109 poly_data->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(1, p2);
1111 for (
unsigned k(0); k < 3; ++k)
1112 p0[k] = e_p2[k] + l * step_dir[k];
1115 int intersection = vtkPlane::IntersectWithLine(p1, p2, step_dir, p0, t, x);
1116 if (intersection == 1)
1117 intersection_points->InsertNextPoint(x);
1120 if (intersection_points->GetNumberOfPoints() != 2)
1123 "zigzagGeneration: " << intersection_points->GetNumberOfPoints()
1124 <<
" intersections. 2 expected intersections.");
1128 double final_point[3];
1131 zigzag_points->GetPoint((zigzag_points->GetNumberOfPoints() - 1), final_point);
1132 intersection_points->GetPoint(0, x_1);
1133 intersection_points->GetPoint(1, x_2);
1135 if (vtkMath::Distance2BetweenPoints(final_point, x_1) < vtkMath::Distance2BetweenPoints(final_point, x_2))
1137 zigzag_points->InsertNextPoint(x_1);
1138 zigzag_points->InsertNextPoint(x_2);
1142 zigzag_points->InsertNextPoint(x_2);
1143 zigzag_points->InsertNextPoint(x_1);
1145 l += deposited_material_width;
1149 double v1[3] = {e_p1[0] - e_p2[0], e_p1[1] - e_p2[1], e_p1[2] - e_p2[2]};
1150 double v2[3] = {next_p[0] - last_p[0], next_p[1] - last_p[1], next_p[2] - last_p[2]};
1151 if (vtkMath::AngleBetweenVectors(v1, v2) < 1e-3)
1152 zigzag_points->InsertNextPoint(next_p);
1153 zigzag_points->InsertNextPoint(last_p);
1157 template<
class ActionSpec>
1159 const vtkSmartPointer<vtkPoints> left_chain,
1160 const vtkSmartPointer<vtkPoints> right_chain,
1161 const vtkSmartPointer<vtkPoints> zigzag_points)
1163 vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
1164 vtkSmartPointer<vtkCellArray> polygon_array = vtkSmartPointer<vtkCellArray>::New();
1165 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
1166 vtkSmartPointer<vtkPolyData> new_poly_data = vtkSmartPointer<vtkPolyData>::New();
1168 for (vtkIdType i = 0; i < right_chain->GetNumberOfPoints(); ++i)
1171 right_chain->GetPoint(i, p);
1172 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1173 points->InsertNextPoint(p);
1175 for (vtkIdType i = 0; i < left_chain->GetNumberOfPoints(); ++i)
1178 left_chain->GetPoint(i, p);
1179 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1180 points->InsertNextPoint(p);
1182 for (vtkIdType i = 0; i < zigzag_points->GetNumberOfPoints(); ++i)
1185 zigzag_points->GetPoint(i, p);
1186 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1187 points->InsertNextPoint(p);
1190 polygon_array->InsertNextCell(polygon);
1191 new_poly_data->SetPolys(polygon_array);
1192 new_poly_data->SetPoints(points);
1194 poly_data->ShallowCopy(new_poly_data);
1197 template<
class ActionSpec>
1199 const vtkSmartPointer<vtkPoints> split_points,
1200 const vtkIdType split_line)
1202 unsigned n_polygons = polygon_source.size();
1206 split_points->GetPoint((2 * split_line), l0);
1207 split_points->GetPoint((2 * split_line + 1), l1);
1210 unsigned polygon_1 = -1;
1211 vtkIdType edge_1 = -1;
1212 double l0_to_edge_1 = DBL_MAX;
1214 unsigned polygon_2 = -1;
1215 vtkIdType edge_2 = -1;
1216 double l0_to_edge_2 = DBL_MAX;
1218 for (
unsigned polygon_id(0); polygon_id < n_polygons; ++polygon_id)
1220 bool find_parallel =
false;
1221 double min_distance_to_l0 = DBL_MAX;
1222 vtkIdType closest_edge = -1;
1223 vtkIdType n_edges = polygon_source[polygon_id]->GetCell(0)->GetNumberOfEdges();
1224 for (
int edge_id(0); edge_id < n_edges; ++edge_id)
1226 double distance_to_l0;
1229 polygon_source[polygon_id]->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(0, e_p0);
1230 polygon_source[polygon_id]->GetCell(0)->GetEdge(edge_id)->GetPoints()->GetPoint(1, e_p1);
1233 double v[3] = {e_p1[0] - e_p0[0], e_p1[1] - e_p0[1], e_p1[2] - e_p0[2]};
1234 double u[3] = {l1[0] - l0[0], l1[1] - l0[1], l1[2] - l0[2]};
1235 if (
sin(vtkMath::AngleBetweenVectors(u, v)) < 1e-3)
1237 distance_to_l0 =
sqrt(vtkLine::DistanceToLine(l0, e_p0, e_p1, t));
1238 if (distance_to_l0 < min_distance_to_l0)
1240 find_parallel =
true;
1241 min_distance_to_l0 = distance_to_l0;
1242 closest_edge = edge_id;
1248 if (min_distance_to_l0 < l0_to_edge_1)
1250 polygon_2 = polygon_1;
1252 l0_to_edge_2 = l0_to_edge_1;
1254 polygon_1 = polygon_id;
1255 edge_1 = closest_edge;
1256 l0_to_edge_1 = min_distance_to_l0;
1258 else if (min_distance_to_l0 < l0_to_edge_2)
1260 polygon_2 = polygon_id;
1261 edge_2 = closest_edge;
1262 l0_to_edge_2 = min_distance_to_l0;
1266 if (edge_1 == -1 || edge_2 == -1)
1268 ROS_ERROR_STREAM(
"mergeConvexPolygons: Error finding parallels edges to the split line");
1282 double connection_point_1[3];
1283 double connection_point_2[3];
1285 double connection_point_3[3];
1286 double connection_point_4[3];
1290 polygon_source[polygon_1]->GetCell(0)->GetEdge(edge_1)->GetPoints()->GetPoint(0, e1_p0);
1291 polygon_source[polygon_1]->GetCell(0)->GetEdge(edge_1)->GetPoints()->GetPoint(1, e1_p1);
1293 polygon_source[polygon_2]->GetCell(0)->GetEdge(edge_2)->GetPoints()->GetPoint(0, e2_p0);
1294 polygon_source[polygon_2]->GetCell(0)->GetEdge(edge_2)->GetPoints()->GetPoint(1, e2_p1);
1296 vtkMath::Subtract(e1_p1, e1_p0, e1_v);
1297 vtkMath::Normalize(e1_v);
1298 vtkMath::Subtract(e2_p1, e2_p0, e2_v);
1299 vtkMath::Normalize(e2_v);
1301 vtkLine::DistanceToLine(l0, e2_p0, e2_p1, t2, connection_point_2);
1302 t2 = (t2 > 1) ? 1 : (t2 < 0) ? 0 : t2;
1303 vtkLine::DistanceToLine(l0, e1_p0, e1_p1, t1, connection_point_1);
1304 t1 = (t1 > 1) ? 1 : (t1 < 0) ? 0 : t1;
1308 double connection_v[3];
1310 vtkMath::Subtract(connection_point_2, connection_point_1, connection_v);
1311 vtkMath::Normalize(connection_v);
1313 double e1_l =
sqrt(vtkMath::Distance2BetweenPoints(e1_p0, e1_p1));
1314 double e2_l =
sqrt(vtkMath::Distance2BetweenPoints(e2_p0, e2_p1));
1316 if ((t2 - l / e2_l) > 0 && t1 < 1)
1318 for (
int k = 0; k < 3; ++k)
1320 connection_point_4[k] = connection_point_1[k] + l * e1_v[k];
1321 connection_point_3[k] = connection_point_2[k] - l * e2_v[k];
1324 connection_point_4[k] = e1_p1[k];
1327 else if ((t1 - l / e1_l) > 0 && t2 < 1)
1329 for (
int k = 0; k < 3; ++k)
1331 connection_point_4[k] = connection_point_1[k];
1332 connection_point_3[k] = connection_point_2[k];
1334 connection_point_1[k] -= l * e1_v[k];
1335 connection_point_2[k] += l * e2_v[k];
1338 connection_point_2[k] = e2_p1[k];
1348 vtkSmartPointer<vtkCellArray> polygon_array = vtkSmartPointer<vtkCellArray>::New();
1349 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
1350 vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
1353 for (vtkIdType i(0); i <= edge_1; ++i)
1355 polygon_source[polygon_1]->GetCell(0)->GetPoints()->GetPoint(i, p);
1356 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1357 points->InsertNextPoint(p);
1360 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1361 points->InsertNextPoint(connection_point_1);
1363 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1364 points->InsertNextPoint(connection_point_2);
1366 for (vtkIdType i(0); i < polygon_source[polygon_2]->GetNumberOfPoints(); ++i)
1368 vtkIdType
id = (i + edge_2 + 1) % polygon_source[polygon_2]->GetNumberOfPoints();
1369 polygon_source[polygon_2]->GetCell(0)->GetPoints()->GetPoint(
id, p);
1370 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1371 points->InsertNextPoint(p);
1374 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1375 points->InsertNextPoint(connection_point_3);
1377 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1378 points->InsertNextPoint(connection_point_4);
1380 for (vtkIdType i(edge_1 + 1); i < polygon_source[polygon_1]->GetNumberOfPoints(); ++i)
1382 polygon_source[polygon_1]->GetCell(0)->GetPoints()->GetPoint(i, p);
1383 polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
1384 points->InsertNextPoint(p);
1387 polygon_array->InsertNextCell(polygon);
1388 vtkSmartPointer<vtkPolyData> poly_data = vtkSmartPointer<vtkPolyData>::New();
1389 poly_data->SetPolys(polygon_array);
1390 poly_data->SetPoints(points);
1392 if (polygon_2 > polygon_1)
1394 polygon_source.erase(polygon_source.begin() + polygon_2);
1395 polygon_source.erase(polygon_source.begin() + polygon_1);
1399 polygon_source.erase(polygon_source.begin() + polygon_1);
1400 polygon_source.erase(polygon_source.begin() + polygon_2);
1403 polygon_source.push_back(poly_data);
1407 template<
class ActionSpec>
1422 vtkIdType opposite_point_id;
1429 vtkSmartPointer<vtkPoints> left_chain = vtkSmartPointer<vtkPoints>::New();
1430 vtkSmartPointer<vtkPoints> right_chain = vtkSmartPointer<vtkPoints>::New();
1431 vtkSmartPointer<vtkPoints> zigzag_points = vtkSmartPointer<vtkPoints>::New();
1433 identifyLeftChain(poly_data, edge_id, opposite_point_id, left_chain, right_chain);
1434 if (!
offsetLeftChain(poly_data, edge_id, opposite_point_id, left_chain, right_chain))
bool findIntersectWithBisector(const Polygon poly_data, const vtkIdType notch_cell_id, const vtkIdType notch_pos, vtkIdType &vertex_cell_id, vtkIdType &vertex_pos, double vertex[3])
double angleBetweenVectors(const double v1[3], const double v2[3])
void identifyRelationships(const Polygon poly_data, std::vector< int > &level, std::vector< int > &father)
double contours_filtering_tolerance_
bool mergeColinearEdges(const Polygon poly_data, const double tolerance=1e-6)
bool divideInConvexPolygons(PolygonVector &polygon_source, const int polygon_position, const vtkSmartPointer< vtkPoints > split_points)
bool closest_to_bisector_
vtkSmartPointer< vtkPolyData > Polygon
bool yamlFileToPolydata(const std::string yaml_file, Polygon poly_data)
bool offsetLeftChain(const Polygon poly_data, const vtkIdType edge_id, const vtkIdType opposite_point_id, const vtkSmartPointer< vtkPoints > left_chain, const vtkSmartPointer< vtkPoints > right_chain)
bool intersectLineWithContours(const Polygon poly_data, double point_1[3], double point_2[3])
std::vector< PolygonVector > Layer
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
void computeNormal(vtkPoints *p, double *n)
double identifyZigzagDirection(const Polygon poly_data, vtkIdType &edge, vtkIdType &futhest_point)
bool zigzagGeneration(const Polygon poly_data, const vtkIdType edge_id, const vtkIdType opposite_point_id, const vtkSmartPointer< vtkPoints > zigzag_points, const double deposited_material_width)
bool organizePolygonContoursInLayer(const Polygon poly_data, const std::vector< int > level, const std::vector< int > father, Layer &layer)
bool publishStatusPercentageDone(const std::string progress_msg, const unsigned percentage, actionlib::ServerGoalHandle< ActionSpec > &gh)
bool removeDuplicatePoints(const Polygon poly_data, const double tolerance=1e-6)
bool verifyAngles(const Polygon poly_data, const vtkIdType notch_cell_id, const vtkIdType notch_pos, const vtkIdType vertex_cell_id, const vtkIdType vertex_pos)
bool yamlFileToPolydata2(const std::string yaml_file, Polygon poly_data, std::vector< unsigned > &layer_count)
TFSIMD_FORCE_INLINE const tfScalar & x() const
std::vector< Polygon > PolygonVector
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
bool generateTrajectoryInConvexPolygon(const Polygon poly_data)
#define ROS_WARN_STREAM(args)
void mergeListOfPoints(const Polygon poly_data, const vtkSmartPointer< vtkPoints > left_chain, const vtkSmartPointer< vtkPoints > right_chain, const vtkSmartPointer< vtkPoints > zigzag_points)
double deposited_material_width_
double polygon_division_tolerance_
#define ROS_INFO_STREAM(args)
bool intersectionBetweenContours(const Polygon poly_data)
const double calculation_tol_
bool offsetPolygonContour(const Polygon poly_data, const double deposited_material_width)
bool mergeConvexPolygons(PolygonVector &polygon_source, const vtkSmartPointer< vtkPoints > split_points, const vtkIdType split_line)
void identifyLeftChain(const Polygon poly_data, const vtkIdType edge_id, const vtkIdType opposite_point_id, const vtkSmartPointer< vtkPoints > left_chain, const vtkSmartPointer< vtkPoints > right_chain)
#define ROS_ERROR_STREAM(args)
bool findNotch(const Polygon poly_data, vtkIdType &cell_id, vtkIdType &pos, double &angle)
std::string generateOneLayerTrajectory(actionlib::ServerGoalHandle< ActionSpec > &gh, const int current_progrress_value, const int next_progress_value, const Polygon poly_data, Layer &layer, const double deposited_material_width, const double contours_filtering_tolerance, const std::array< double, 3 > normal_vector={0, 0, 1}, const double polygon_division_tolerance=M_PI/6, const bool closest_to_bisector=false, const bool use_gui=false)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
bool findVertex(const Polygon poly_data, const vtkIdType notch_cell_id, const vtkIdType notch_pos, vtkIdType &vertex_cell_id, vtkIdType &vertex_pos, const double notch_angle)