donghong_ding_base_imp.hpp
Go to the documentation of this file.
1 #ifndef RAM_PATH_PLANNING_DONGHONG_DINGBASE_IMP_HPP
2 #define RAM_PATH_PLANNING_DONGHONG_DINGBASE_IMP_HPP
3 
4 namespace ram_path_planning
5 {
6 
7 template<class ActionSpec>
9  const std::string description,
10  const std::string service_name) :
11  PathPlanningAlgorithm<ActionSpec>(name, description, service_name)
12  {
13  }
14 
15 template<class ActionSpec>
17  {
18  }
19 
20 // Connect layers
21 template<class ActionSpec>
23  const int current_progrress_value,
24  const int next_progress_value,
25  std::vector<Layer> &layers,
26  ram_msgs::AdditiveManufacturingTrajectory &msg)
27  {
28  // 1. divide in groups with the same number of polygons
29  // 2. divide this groups in layer with only one polygon
30  // 3. connect the simple layers
31 
32  //std::vector<Layer> layers_vector;
33  unsigned first_layer = 0;
34  unsigned n_polygons = layers[0].size();
35 
36  if (n_polygons != 1)
37  return "connectMeshLayers: function to connect layers with several polygons is not implemented";
38 
39  for (unsigned layer_id(0); layer_id < layers.size(); ++layer_id)
40  {
41  if (layers[layer_id].size() != n_polygons)
42  {
43  return "connectMeshLayers: function to connect layers with several polygons is not implemented";
44 
45  //send layers_vector
46  //divideInLayersWithOnePolygon(layers_vector,msg,first_layer,slicing_direction);
47  //layers_vector.clear();
48  //first_layer = layer_id;
49  //n_polygons = layers[layer_id].size();
50  }
51  //layers_vector.push_back(layers[layer_id]);
52  }
53  //send layers_vector
54  //divideInLayersWithOnePolygon(layers_vector,msg,first_layer,slicing_direction);
55  connectLayersWithOnePolygon(gh, current_progrress_value, next_progress_value, layers, msg, first_layer);
56  return "";
57  }
58 
59 template<class ActionSpec>
61  const int current_progrress_value,
62  const int next_progress_value,
63  const Layer &current_layer,
64  ram_msgs::AdditiveManufacturingTrajectory &msg,
65  const double number_of_layers,
66  const double height_between_layers,
67  const std::array<double, 3> offset_direction)
68  {
69  double v = 0.0;
70  int progress_value = 0;
71 
72  double offset_dir[3] = {offset_direction[0], offset_direction[1], offset_direction[2]};
73 
74  if (vtkMath::Norm(offset_dir) == 0)
75  {
76  ROS_ERROR_STREAM("connectYamlLayers: offset direction is not valid");
77  return;
78  }
79  vtkMath::Normalize(offset_dir);
80 
81  unsigned layer_index(0);
82  for (auto polygon_vector : current_layer)
83  {
84  for (auto polygon : polygon_vector)
85  {
86  vtkIdType n_points = polygon->GetNumberOfPoints();
87  for (vtkIdType layer_id(0); layer_id < number_of_layers; ++layer_id)
88  {
89  double offset_vector[3];
90  offset_vector[0] = height_between_layers * layer_id * offset_dir[0];
91  offset_vector[1] = height_between_layers * layer_id * offset_dir[1];
92  offset_vector[2] = height_between_layers * layer_id * offset_dir[2];
93 
94  for (vtkIdType point_id(0); point_id <= n_points; ++point_id)
95  {
96  double p[3];
97  Eigen::Isometry3d pose_isometry = Eigen::Isometry3d::Identity();
98  polygon->GetCell(0)->GetPoints()->GetPoint(point_id % n_points, p);
99 
100  pose_isometry.translation()[0] = (p[0] + offset_vector[0]);
101  pose_isometry.translation()[1] = (p[1] + offset_vector[1]);
102  pose_isometry.translation()[2] = (p[2] + offset_vector[2]);
103 
104  ram_msgs::AdditiveManufacturingPose pose_srv;
105  tf::poseEigenToMsg(pose_isometry, pose_srv.pose);
106  pose_srv.layer_level = layer_id;
107  pose_srv.layer_index = layer_index;
108 
109  if (layer_id == 0 && point_id == 0) // First point
110  {
111  pose_srv.polygon_start = true;
112  }
113  msg.poses.push_back(pose_srv);
114  }
115  ++layer_index;
116  v = (layer_id + 1.0) / number_of_layers;
117  progress_value = (int)(current_progrress_value + v * (next_progress_value - current_progrress_value));
118  if (!this->publishStatusPercentageDone(
119  "Adding layer " + std::to_string(layer_index) + " to a trajectory message", progress_value, gh))
120  return;
121  }
122  msg.poses.back().polygon_end = true; // Last point
123  }
124  }
125  }
126 
127 template<class ActionSpec>
129  const int current_progrress_value,
130  const int next_progress_value,
131  std::vector<Layer> &layers,
132  ram_msgs::AdditiveManufacturingTrajectory &msg,
133  const unsigned first_layer)
134  {
135  double v = 0.0;
136  int progress_value = 0;
137  unsigned n_layers(layers.size());
138 
139  // layers are connected close to this line
140  double l1[3]; // Point in the plane of the first layer
141  double l2[3]; // Point in the last layer
142 
143  double p_first_layer[3]; // Point in the first layer
144 
145  layers.back()[0][0]->GetCell(0)->GetPoints()->GetPoint(0, l2);
146  //find l1
147  double l2_p[3]; // Vector between l2 and p_first layer
148  vtkMath::Subtract(p_first_layer, l2, l2_p);
149  double l2_l1[3]; // Vector between l2 and l1
150  vtkMath::ProjectVector(l2_p, normal_vector_, l2_l1);
151  vtkMath::Add(l2, l2_l1, l1); //l1
152 
153  for (unsigned layer_id(0); layer_id < n_layers; ++layer_id)
154  {
155  vtkIdType n_points = layers[layer_id][0][0]->GetCell(0)->GetNumberOfPoints();
156  //vtkIdType closest_point_id = 0;
157  vtkIdType closest_edge_id = 0;
158  double connection_point[3] = {0, 0, 0};
159  double shortest_distance = DBL_MAX;
160  bool is_close_to_a_vertex = false;
161 
162  // Find the closest point to the line between the points l1 and l2
163  for (vtkIdType id(0); id < n_points; ++id)
164  {
165  double e_p0[3];
166  double e_p1[3];
167  layers[layer_id][0][0]->GetCell(0)->GetEdge(id)->GetPoints()->GetPoint(0, e_p0);
168  layers[layer_id][0][0]->GetCell(0)->GetEdge(id)->GetPoints()->GetPoint(1, e_p1);
169  double closestPt1[3];
170  double closestPt2[3];
171  double t1;
172  double t2;
173  double distance_to_line = vtkLine::DistanceBetweenLineSegments(l1, l2, e_p0, e_p1, closestPt1, closestPt2, t1,
174  t2);
175 
176  if (distance_to_line < shortest_distance)
177  {
178  shortest_distance = distance_to_line;
179 
180  if (sqrt(vtkMath::Distance2BetweenPoints(e_p0, closestPt2)) < deposited_material_width_ / 2) // Close to e_p0
181  {
182  closest_edge_id = id;
183 
184  connection_point[0] = e_p0[0];
185  connection_point[1] = e_p0[1];
186  connection_point[2] = e_p0[2];
187  is_close_to_a_vertex = true;
188  }
189  else if (sqrt(vtkMath::Distance2BetweenPoints(e_p1, closestPt2)) < deposited_material_width_ / 2) // Close to e_p1
190  {
191  closest_edge_id = id + 1;
192 
193  connection_point[0] = e_p1[0];
194  connection_point[1] = e_p1[1];
195  connection_point[2] = e_p1[2];
196  is_close_to_a_vertex = true;
197  }
198  else
199  {
200  closest_edge_id = id;
201 
202  connection_point[0] = closestPt2[0];
203  connection_point[1] = closestPt2[1];
204  connection_point[2] = closestPt2[2];
205  is_close_to_a_vertex = false;
206  }
207  }
208  }
209  //save the layer points in the msg
210  Eigen::Isometry3d first_pose_isometry = Eigen::Isometry3d::Identity();
211  ram_msgs::AdditiveManufacturingPose first_pose_srv;
212 
213  first_pose_isometry.translation()[0] = connection_point[0];
214  first_pose_isometry.translation()[1] = connection_point[1];
215  first_pose_isometry.translation()[2] = connection_point[2];
216  tf::poseEigenToMsg(first_pose_isometry, first_pose_srv.pose);
217 
218  first_pose_srv.layer_level = layer_id + first_layer;
219  first_pose_srv.layer_index = first_pose_srv.layer_level;
220 
221  if (layer_id == 0) // first point
222  first_pose_srv.polygon_start = true;
223  msg.poses.push_back(first_pose_srv);
224 
225  for (vtkIdType i(0); i < n_points; ++i)
226  {
227  double p[3];
228  layers[layer_id][0][0]->GetCell(0)->GetPoints()->GetPoint((closest_edge_id + i + 1) % n_points, p);
229  Eigen::Isometry3d pose_isometry = Eigen::Isometry3d::Identity();
230  ram_msgs::AdditiveManufacturingPose pose_srv;
231 
232  pose_isometry.translation()[0] = p[0];
233  pose_isometry.translation()[1] = p[1];
234  pose_isometry.translation()[2] = p[2];
235  tf::poseEigenToMsg(pose_isometry, pose_srv.pose);
236 
237  pose_srv.layer_level = layer_id + first_layer;
238  pose_srv.layer_index = pose_srv.layer_level;
239 
240  msg.poses.push_back(pose_srv);
241  }
242  if (!is_close_to_a_vertex)
243  {
244  first_pose_srv.polygon_start = false;
245  first_pose_srv.layer_level = layer_id + first_layer;
246  msg.poses.push_back(first_pose_srv);
247  }
248 
249  v = (layer_id + 1.0) / n_layers;
250  progress_value = (int)(current_progrress_value + v * (next_progress_value - current_progrress_value));
251  if (!this->publishStatusPercentageDone("Adding layer " + std::to_string(layer_id) + " to a trajectory message",
252  progress_value,
253  gh))
254  return;
255  }
256  msg.poses.back().polygon_end = true; // last point
257  }
258 
259 // Others functions
260 template<class ActionSpec>
262  const double v2[3])
263  {
264  double norm = vtkMath::Norm(v1) * vtkMath::Norm(v2);
265 
266  double cross_v1_v2[3];
267  vtkMath::Cross(v1, v2, cross_v1_v2);
268  double sin_angle = vtkMath::Dot(normal_vector_, cross_v1_v2) / norm;
269  double cos_angle = vtkMath::Dot(v1, v2) / norm;
270  return atan2(sin_angle, cos_angle);
271  }
272 
273 template<class ActionSpec>
275  double *n)
276  {
277  double ax, ay, az, bx, by, bz;
278 
279  vtkIdType n_points = p->GetNumberOfPoints();
280  double p0[3];
281  p->GetPoint(0, p0);
282  n[0] = 0;
283  n[1] = 0;
284  n[2] = 0;
285  for (vtkIdType i = 0; i < n_points; ++i)
286  {
287  double v1[3];
288  p->GetPoint(i, v1);
289  double v2[3];
290  p->GetPoint((i + 1) % n_points, v2);
291  ax = v1[0] - p0[0];
292  ay = v1[1] - p0[1];
293  az = v1[2] - p0[2];
294 
295  bx = v2[0] - p0[0];
296  by = v2[1] - p0[1];
297  bz = v2[2] - p0[2];
298 
299  // Cross Product
300  n[0] += (ay * bz - az * by);
301  n[1] += (az * bx - ax * bz);
302  n[2] += (ax * by - ay * bx);
303 
304  }
305  vtkMath::Normalize(n);
306  }
307 
308 template<class ActionSpec>
310  const double deposited_material_width)
311  {
312  vtkSmartPointer<vtkCellArray> polygon_array = vtkSmartPointer<vtkCellArray>::New();
313  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
314  vtkIdType n_cells = poly_data->GetNumberOfCells();
315  for (vtkIdType cell_id = 0; cell_id < n_cells; ++cell_id)
316  {
317  vtkIdType n_points = poly_data->GetCell(cell_id)->GetNumberOfPoints();
318  vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
319  for (vtkIdType point_id = 0; point_id < n_points; ++point_id)
320  {
321  double p0[3];
322  double p1[3]; // Central point
323  double p2[3];
324  if (point_id == 0)
325  poly_data->GetCell(cell_id)->GetPoints()->GetPoint((n_points - 1), p0);
326  else
327  poly_data->GetCell(cell_id)->GetPoints()->GetPoint((point_id - 1), p0);
328  poly_data->GetCell(cell_id)->GetPoints()->GetPoint(point_id, p1);
329  poly_data->GetCell(cell_id)->GetPoints()->GetPoint((point_id + 1) % n_points, p2);
330  double v2[3];
331  double v1[3];
332  vtkMath::Subtract(p0, p1, v1);
333  vtkMath::Subtract(p2, p1, v2);
334  vtkMath::Normalize(v1);
335  vtkMath::Normalize(v2);
336  double angle = angleBetweenVectors(v1, v2);
337  double bisector[3];
338  vtkMath::Add(v1, v2, bisector);
339  vtkMath::Normalize(bisector);
340  double new_point[3];
341  for (int k = 0; k < 3; ++k)
342  new_point[k] = p1[k] + deposited_material_width / sin(angle / 2) * bisector[k];
343 
344  polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
345  polygon->GetPoints()->InsertNextPoint(new_point);
346  points->InsertNextPoint(new_point);
347  }
348 
349  // First verification: intersection among the lines
350  for (vtkIdType i(0); i < n_points; ++i)
351  {
352  double p_i[3];
353  double new_p_i[3];
354  poly_data->GetCell(cell_id)->GetPoints()->GetPoint(i, p_i);
355  polygon->GetPoints()->GetPoint(i, new_p_i);
356 
357  for (vtkIdType j(0); j < n_points; ++j)
358  {
359  double p_j[3];
360  double new_p_j[3];
361  poly_data->GetCell(cell_id)->GetPoints()->GetPoint(j, p_j);
362  polygon->GetPoints()->GetPoint(j, new_p_j);
363 
364  double u; // Parametric coordinate of the line 1
365  double v; // Parametric coordinate of the line 2
366  int intersection = vtkLine::Intersection3D(p_i, new_p_i, p_j, new_p_j, u, v);
367 
368  if (intersection == 2)
369  {
370  ROS_ERROR_STREAM("offsetPolygonContour: one or multiple edges are too short! Lines: " << i << " and " << j);
371  return false;
372  }
373  }
374  }
375  polygon_array->InsertNextCell(polygon);
376  }
377  poly_data->SetPolys(polygon_array);
378  poly_data->SetPoints(points);
379 
380  return true;
381  }
382 
383 template<class ActionSpec>
385  {
386  vtkIdType n_cells = poly_data->GetNumberOfCells(); // Numbers of cells in the polyData
387 
388  for (vtkIdType i(0); i < n_cells; ++i)
389  {
390  for (vtkIdType j(i + 1); j < n_cells; ++j)
391  {
392  //intersection between i contour and the (i+1=j) contour
393  vtkIdType n_edges_i = poly_data->GetCell(i)->GetNumberOfEdges();
394  vtkIdType n_edges_j = poly_data->GetCell(j)->GetNumberOfEdges();
395  for (vtkIdType e_i(0); e_i < n_edges_i; ++e_i)
396  {
397  for (vtkIdType e_j(0); e_j < n_edges_j; ++e_j)
398  {
399  // Get the two points of the edge i
400  double ei_p1[3];
401  double ei_p2[3];
402  poly_data->GetCell(i)->GetEdge(e_i)->GetPoints()->GetPoint(0, ei_p1);
403  poly_data->GetCell(i)->GetEdge(e_i)->GetPoints()->GetPoint(1, ei_p2);
404  // Get the two points of the edge j
405  double ej_p1[3];
406  double ej_p2[3];
407  poly_data->GetCell(j)->GetEdge(e_j)->GetPoints()->GetPoint(0, ej_p1);
408  poly_data->GetCell(j)->GetEdge(e_j)->GetPoints()->GetPoint(1, ej_p2);
409 
410  double u; // Parametric coordinate of the line 1
411  double v; // Parametric coordinate of the line 2
412  int intersection = vtkLine::Intersection3D(ei_p1, ei_p2, ej_p1, ej_p2, u, v);
413 
414  if (intersection == 2)
415  {
416  ROS_ERROR_STREAM("intersectionBetweenContours: contours " << i << " and " << j << " intersects");
417  return true;
418  }
419  else if (intersection == 3)
420  {
421  // Overlapping = error
422  double closest_pt1[3];
423  double closest_pt2[3];
424  if (vtkLine::DistanceBetweenLineSegments(ei_p1, ei_p2, ej_p1, ej_p2, closest_pt1, closest_pt2, u, v) == 0)
425  {
426  ROS_ERROR_STREAM("intersectionBetweenContours: contours " << i << " and " << j << " are overlapping");
427  return true;
428  }
429  }
430  }
431  }
432  }
433  }
434  return false;
435  }
436 
437 template<class ActionSpec>
439  std::vector<int> &level,
440  std::vector<int> &father)
441  {
442  vtkIdType n_cells = poly_data->GetNumberOfCells();
443 
444  //relationship matrix: if the j cell is inside i cell, relationship[i][j]=1
445  std::vector<std::vector<int> > relationship(n_cells, std::vector<int>(n_cells, 0));
446 
447  level = std::vector<int>(n_cells, 0);
448  father = std::vector<int>(n_cells, -1);
449 
450  for (vtkIdType i(0); i < n_cells; ++i)
451  {
452  // Points in i cell
453  vtkSmartPointer<vtkPoints> point_list = vtkSmartPointer<vtkPoints>::New();
454  point_list = poly_data->GetCell(i)->GetPoints();
455 
456  //Create the polygon with the points in "point_list"
457  vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
458  for (vtkIdType k(0); k < point_list->GetNumberOfPoints(); ++k)
459  {
460  double p[3];
461  point_list->GetPoint(k, p);
462  polygon->GetPoints()->InsertNextPoint(p[0], p[1], p[2]);
463  }
464  // arguments of the PointInPolygon function
465  double n[3];
466  computeNormal(polygon->GetPoints(), n);
467  double bounds[6];
468  polygon->GetPoints()->GetBounds(bounds);
469 
470  for (vtkIdType j(0); j < n_cells; ++j)
471  {
472  if (i != j)
473  {
474  //first point in the j cell
475  double p[3];
476  poly_data->GetCell(j)->GetPoints()->GetPoint(0, p);
477  int in_polygon = polygon->PointInPolygon(
478  p, polygon->GetPoints()->GetNumberOfPoints(),
479  static_cast<double*>(polygon->GetPoints()->GetData()->GetVoidPointer(0)),
480  bounds, n); //
481  if (in_polygon)
482  {
483  level[j]++; // level of the polygon in the depth-tree
484  relationship[i][j] = 1;
485  }
486  }
487  }
488  }
489  //find the father of each contour
490  for (unsigned j(0); j < n_cells; ++j)
491  {
492  for (unsigned i(0); i < n_cells; ++i)
493  {
494  if (relationship[i][j] == 1 && level[i] == (level[j] - 1)) // the level of the father cell is
495  {
496  father[j] = i;
497  break;
498  }
499  }
500  }
501 
502  }
503 
504 template<class ActionSpec>
506  const std::vector<int> level,
507  const std::vector<int> father,
508  Layer &layer)
509  {
510  typedef vtkSmartPointer<vtkPolygon> Contour;
511 
512  if (!poly_data)
513  {
514  ROS_ERROR_STREAM("organizePolygonContoursInLayer: poly_data is not initialized!");
515  return false;
516  }
517 
518  vtkIdType n_cells_contours = poly_data->GetNumberOfCells();
519  if (n_cells_contours == 0)
520  {
521  ROS_ERROR_STREAM("organizePolygonContoursInLayer: poly_data is empty!");
522  return false;
523  }
524 
525  layer.clear(); // We might have deleted poly_data if it belonged to layer
526 
527  for (vtkIdType i(0); i < n_cells_contours; ++i)
528  {
529  if (level[i] % 2 != 0)
530  continue;
531 
532  vtkSmartPointer<vtkCellArray> contour_array = vtkSmartPointer<vtkCellArray>::New();
533  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
534  //save the father
535  Contour contour = Contour::New();
536  vtkSmartPointer<vtkPoints> point_list = vtkSmartPointer<vtkPoints>::New();
537  point_list = poly_data->GetCell(i)->GetPoints(); // Points of the i cell
538 
539  // Copy all points in the new contour
540  double n[3];
541  computeNormal(point_list, n); // Contour orientation
542 
543  // Contour is not in the XY plane
544  double angle = vtkMath::AngleBetweenVectors(n, normal_vector_);
545  if (sin(angle) > calculation_tol_)
546  {
547  ROS_ERROR_STREAM("organizePolygonContoursInLayer: Contour is not co-planar to slicing plane ");
548  return false;
549  }
550 
551  if (std::abs(cos(angle) + 1) < calculation_tol_) // Clockwise direction
552  {
553  for (vtkIdType k(0); k < point_list->GetNumberOfPoints(); ++k)
554  {
555  double p[3];
556  point_list->GetPoint(k, p);
557  contour->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
558  points->InsertNextPoint(p);
559  }
560  }
561  else if (std::abs(cos(angle) - 1) < calculation_tol_) // Counter-clockwise direction. Reverse order
562  {
563  for (vtkIdType k = point_list->GetNumberOfPoints(); k > 0; --k)
564  {
565  double p[3];
566  point_list->GetPoint((k - 1), p);
567  contour->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
568  points->InsertNextPoint(p);
569  }
570  }
571 
572  contour_array->InsertNextCell(contour);
573 
574  // Process children of the contour we just have re-ordered
575  for (vtkIdType j(0); j < n_cells_contours; ++j)
576  {
577  if (father[j] != i)
578  continue;
579  //save children (father[j] == i)
580  contour = vtkSmartPointer<vtkPolygon>::New();
581  point_list = vtkSmartPointer<vtkPoints>::New();
582  point_list = poly_data->GetCell(j)->GetPoints(); // Points of the j-th cell
583  //copy all points in the new contour
584  double n[3];
585  computeNormal(point_list, n); // polygon orientation
586  double angle = vtkMath::AngleBetweenVectors(n, normal_vector_);
587  if (sin(angle) > calculation_tol_)
588  {
589  ROS_ERROR_STREAM("organizePolygonContoursInLayer: Contour is not co-planar to slicing plane ");
590  return false;
591  }
592  if (std::abs(cos(angle) - 1) < calculation_tol_) //counter-clockwise direction
593  {
594  for (vtkIdType k = 0; k < point_list->GetNumberOfPoints(); k++)
595  {
596  double p[3];
597  point_list->GetPoint(k, p);
598  contour->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
599  points->InsertNextPoint(p[0], p[1], p[2]);
600  }
601  }
602  else if (std::abs(cos(angle) + 1) < calculation_tol_) //clockwise direction. Change order
603  {
604  for (vtkIdType k = point_list->GetNumberOfPoints(); k > 0; k--)
605  {
606  double p[3];
607  point_list->GetPoint((k - 1), p);
608  contour->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
609  points->InsertNextPoint(p);
610  }
611  }
612  else
613  {
614  ROS_ERROR_STREAM("organizePolygonContoursInLayer: normal vector is not parallel to Z axis");
615  return false;
616  }
617  contour_array->InsertNextCell(contour);
618 
619  }
620 
621  // Make polygon
622  Polygon polygon = Polygon::New();
623  PolygonVector poly_vector;
624  polygon->SetPolys(contour_array); // polygon_array contains the contours
625  polygon->SetPoints(points);
626  poly_vector.push_back(polygon);
627  layer.push_back(poly_vector);
628  }
629 
630  return true;
631  }
632 
633 template<class ActionSpec>
635  const double tolerance)
636  {/*
637  vtkSmartPointer<vtkCellArray> polygon_array = vtkSmartPointer<vtkCellArray>::New();
638  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
639  vtkSmartPointer<vtkPolyData> new_poly_data = vtkSmartPointer<vtkPolyData>::New();
640  vtkIdType n_cells = poly_data->GetNumberOfCells();
641  for (vtkIdType cell_id(0); cell_id < n_cells; ++cell_id)
642  {
643  vtkIdType n_points = poly_data->GetCell(cell_id)->GetNumberOfPoints();
644  vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
645  for (vtkIdType point_id(0); point_id < n_points; ++point_id)
646  {
647  double p0[3];
648  double p1[3];
649  poly_data->GetCell(cell_id)->GetPoints()->GetPoint(point_id, p0);
650  poly_data->GetCell(cell_id)->GetPoints()->GetPoint((point_id + 1) % n_points, p1);
651  // 1. duplicate point
652  if (vtkMath::Distance2BetweenPoints(p0, p1) > tolerance)
653  {
654  polygon->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
655  points->InsertNextPoint(p0);
656  }
657  }
658  polygon_array->InsertNextCell(polygon);
659  }
660  new_poly_data->SetPolys(polygon_array);
661  new_poly_data->SetPoints(points);
662 
663  poly_data->ShallowCopy(new_poly_data);
664  */
665  vtkSmartPointer<vtkCleanPolyData> cleaner = vtkSmartPointer<vtkCleanPolyData>::New();
666  cleaner->SetInputData(poly_data);
667  cleaner->ToleranceIsAbsoluteOn();
668  cleaner->SetAbsoluteTolerance(tolerance);
669  cleaner->Update();
670  if (cleaner->GetOutput()->GetNumberOfPoints() < 3)
671  {
673  "removeDuplicatePoints: Not enough points" << std::endl <<
674  "vtkPolyData contains " << cleaner->GetOutput()->GetNumberOfPoints() << " points");
675  return false;
676  }
677  poly_data->ShallowCopy(cleaner->GetOutput());
678  return true;
679 
680  }
681 
682 template<class ActionSpec>
684  const double tolerance)
685  {
686  vtkSmartPointer<vtkCellArray> polygon_array = vtkSmartPointer<vtkCellArray>::New();
687  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
688  vtkSmartPointer<vtkPolyData> new_poly_data = vtkSmartPointer<vtkPolyData>::New();
689 
690  vtkIdType n_cells = polygon->GetNumberOfCells();
691  for (vtkIdType cell_id(0); cell_id < n_cells; ++cell_id)
692  {
693  vtkIdType n_points = polygon->GetCell(cell_id)->GetNumberOfPoints();
694  vtkSmartPointer<vtkPolygon> contour = vtkSmartPointer<vtkPolygon>::New();
695  double p0[3];
696  polygon->GetCell(cell_id)->GetPoints()->GetPoint(0, p0); //fist point in this contour
697  for (vtkIdType point_id(0); point_id < n_points; ++point_id)
698  {
699  double p1[3]; // Central point
700  double p2[3];
701  polygon->GetCell(cell_id)->GetPoints()->GetPoint((point_id + 1) % n_points, p1);
702  polygon->GetCell(cell_id)->GetPoints()->GetPoint((point_id + 2) % n_points, p2);
703 
704  double distance = sqrt(vtkLine::DistanceToLine(p1, p0, p2));
705  if (std::abs(distance) > tolerance)
706  {
707 
708  contour->GetPointIds()->InsertNextId(points->GetNumberOfPoints());
709  points->InsertNextPoint(p1);
710  p0[0] = p1[0];
711  p0[1] = p1[1];
712  p0[2] = p1[2];
713  }
714 
715  }
716  if (contour->GetPointIds()->GetNumberOfIds() < 3)
717  {
719  "mergeColinearEdges: Cell " << cell_id << " must have at least 3 points outside the region of tolerance");
720 
721  return false;
722  }
723  polygon_array->InsertNextCell(contour);
724  }
725 
726  new_poly_data->SetPolys(polygon_array);
727  new_poly_data->SetPoints(points);
728 
729  polygon->ShallowCopy(new_poly_data);
730  return true;
731  }
732 
733 template<class ActionSpec>
735  ram_msgs::AdditiveManufacturingTrajectory &msg,
736  const unsigned first_layer)
737  {
738  std::vector<Layer> layers_vector;
739  Layer current_layer;
740  unsigned n_polygons = layers[0].size();
741  vtkSmartPointer<vtkCenterOfMass> center_of_mass_filter = vtkSmartPointer<vtkCenterOfMass>::New();
742 
743  while (n_polygons > 0)
744  {
745  double center_0[3];
746  double center_1[3];
747  // Compute the center of mass
748  center_of_mass_filter->SetInputData(layers[0][0][0]);
749  center_of_mass_filter->SetUseScalarsAsWeights(false);
750  center_of_mass_filter->Update();
751  center_of_mass_filter->GetCenter(center_0);
752 
753  current_layer.clear();
754  layers_vector.clear();
755  current_layer.push_back(layers[0][0]); //layer with only 1 polygon
756  layers_vector.push_back(current_layer);
757 
758  layers[0].erase(layers[0].begin());
759 
760  for (unsigned layer_id(1); layer_id < layers.size(); ++layer_id)
761  {
762  unsigned closest_polygon_vector_id = 0;
763  double min_distance = DBL_MAX;
764  for (unsigned polygon_vector_id(1); polygon_vector_id < layers[layer_id].size(); ++polygon_vector_id)
765  {
766  // Compute the center of mass
767  center_of_mass_filter->SetInputData(layers[layer_id][polygon_vector_id][0]);
768  center_of_mass_filter->SetUseScalarsAsWeights(false);
769  center_of_mass_filter->Update();
770  center_of_mass_filter->GetCenter(center_1);
771 
772  double distance = sqrt(vtkMath::Distance2BetweenPoints(center_0, center_1));
773  if (distance < min_distance)
774  {
775  min_distance = distance;
776  closest_polygon_vector_id = polygon_vector_id;
777  }
778  }
779  //
780  current_layer.clear();
781  current_layer.push_back(layers[layer_id][closest_polygon_vector_id]); //layer with only 1 polygon
782  layers_vector.push_back(current_layer);
783 
784  layers[layer_id].erase(layers[layer_id].begin() + closest_polygon_vector_id);
785  }
786  //send layers
787  connectLayersWithOnePolygon(layers_vector, msg, first_layer);
788  n_polygons--;
789 
790  } //--- end while
791 
792  }
793 
794 }
795 
796 #endif
double angleBetweenVectors(const double v1[3], const double v2[3])
void identifyRelationships(const Polygon poly_data, std::vector< int > &level, std::vector< int > &father)
bool mergeColinearEdges(const Polygon poly_data, const double tolerance=1e-6)
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
void connectYamlLayers(actionlib::ServerGoalHandle< ActionSpec > &gh, const int current_progrress_value, const int next_progress_value, const Layer &current_layer, ram_msgs::AdditiveManufacturingTrajectory &msg, const double number_of_layers, const double height_between_layers, const std::array< double, 3 > offset_direction={0, 0, 1})
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
void computeNormal(vtkPoints *p, double *n)
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)
std::string connectMeshLayers(actionlib::ServerGoalHandle< ActionSpec > &gh, const int current_progrress_value, const int next_progress_value, std::vector< Layer > &layers, ram_msgs::AdditiveManufacturingTrajectory &msg)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
vtkSmartPointer< vtkPolyData > Polygon
std::vector< PolygonVector > Layer
bool intersectionBetweenContours(const Polygon poly_data)
bool offsetPolygonContour(const Polygon poly_data, const double deposited_material_width)
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
void connectLayersWithOnePolygon(actionlib::ServerGoalHandle< ActionSpec > &gh, const int current_progrress_value, const int next_progress_value, std::vector< Layer > &layers, ram_msgs::AdditiveManufacturingTrajectory &msg, const unsigned first_layer)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
#define ROS_ERROR_STREAM(args)
void divideInLayersWithOnePolygon(std::vector< Layer > &layers, ram_msgs::AdditiveManufacturingTrajectory &msg, const unsigned first_layer)
DonghongDingBase(const std::string name, const std::string description, const std::string service_name)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)


ram_path_planning
Author(s): Andres Campos - Institut Maupertuis
autogenerated on Mon Jun 10 2019 14:50:03