ExtrusionEntityCollection.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include "ExtrusionEntityCollection.hpp"
  2. #include <algorithm>
  3. #include <map>
  4. #ifdef SLIC3RXS
  5. #include "perlglue.hpp"
  6. #endif
  7. namespace Slic3r {
  8. ExtrusionEntityCollection::ExtrusionEntityCollection(const ExtrusionEntityCollection& collection)
  9. : no_sort(collection.no_sort), orig_indices(collection.orig_indices)
  10. {
  11. this->entities.reserve(collection.entities.size());
  12. for (ExtrusionEntitiesPtr::const_iterator it = collection.entities.begin(); it != collection.entities.end(); ++it)
  13. this->entities.push_back((*it)->clone());
  14. }
  15. ExtrusionEntityCollection& ExtrusionEntityCollection::operator= (const ExtrusionEntityCollection &other)
  16. {
  17. ExtrusionEntityCollection tmp(other);
  18. this->swap(tmp);
  19. return *this;
  20. }
  21. void
  22. ExtrusionEntityCollection::swap (ExtrusionEntityCollection &c)
  23. {
  24. std::swap(this->entities, c.entities);
  25. std::swap(this->orig_indices, c.orig_indices);
  26. std::swap(this->no_sort, c.no_sort);
  27. }
  28. ExtrusionEntityCollection*
  29. ExtrusionEntityCollection::clone() const
  30. {
  31. return new ExtrusionEntityCollection(*this);
  32. }
  33. void
  34. ExtrusionEntityCollection::reverse()
  35. {
  36. for (ExtrusionEntitiesPtr::iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
  37. (*it)->reverse();
  38. }
  39. std::reverse(this->entities.begin(), this->entities.end());
  40. }
  41. Point
  42. ExtrusionEntityCollection::first_point() const
  43. {
  44. return this->entities.front()->first_point();
  45. }
  46. Point
  47. ExtrusionEntityCollection::last_point() const
  48. {
  49. return this->entities.back()->last_point();
  50. }
  51. void
  52. ExtrusionEntityCollection::chained_path(ExtrusionEntityCollection* retval, bool no_reverse, std::vector<size_t>* orig_indices) const
  53. {
  54. if (this->entities.empty()) return;
  55. this->chained_path_from(this->entities.front()->first_point(), retval, no_reverse, orig_indices);
  56. }
  57. void
  58. ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEntityCollection* retval, bool no_reverse, std::vector<size_t>* orig_indices) const
  59. {
  60. if (this->no_sort) {
  61. *retval = *this;
  62. return;
  63. }
  64. retval->entities.reserve(this->entities.size());
  65. retval->orig_indices.reserve(this->entities.size());
  66. // if we're asked to return the original indices, build a map
  67. std::map<ExtrusionEntity*,size_t> indices_map;
  68. ExtrusionEntitiesPtr my_paths;
  69. for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
  70. ExtrusionEntity* entity = (*it)->clone();
  71. my_paths.push_back(entity);
  72. if (orig_indices != NULL) indices_map[entity] = it - this->entities.begin();
  73. }
  74. Points endpoints;
  75. for (ExtrusionEntitiesPtr::iterator it = my_paths.begin(); it != my_paths.end(); ++it) {
  76. endpoints.push_back((*it)->first_point());
  77. if (no_reverse) {
  78. endpoints.push_back((*it)->first_point());
  79. } else {
  80. endpoints.push_back((*it)->last_point());
  81. }
  82. }
  83. while (!my_paths.empty()) {
  84. // find nearest point
  85. int start_index = start_near.nearest_point_index(endpoints);
  86. int path_index = start_index/2;
  87. ExtrusionEntity* entity = my_paths.at(path_index);
  88. if (start_index % 2 && !no_reverse) {
  89. entity->reverse();
  90. }
  91. retval->entities.push_back(my_paths.at(path_index));
  92. if (orig_indices != NULL) orig_indices->push_back(indices_map[entity]);
  93. my_paths.erase(my_paths.begin() + path_index);
  94. endpoints.erase(endpoints.begin() + 2*path_index, endpoints.begin() + 2*path_index + 2);
  95. start_near = retval->entities.back()->last_point();
  96. }
  97. }
  98. #ifdef SLIC3RXS
  99. // there is no ExtrusionLoop::Collection or ExtrusionEntity::Collection
  100. REGISTER_CLASS(ExtrusionEntityCollection, "ExtrusionPath::Collection");
  101. #endif
  102. }