mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Vojtech's optimizations
This commit is contained in:
		
							parent
							
								
									9dff44a8ad
								
							
						
					
					
						commit
						0e8b526af3
					
				
					 3 changed files with 137 additions and 105 deletions
				
			
		|  | @ -1,6 +1,8 @@ | |||
| #include "igl/random_points_on_mesh.h" | ||||
| #include "igl/AABB.h" | ||||
| 
 | ||||
| #include <tbb/parallel_for.h> | ||||
| 
 | ||||
| #include "SLAAutoSupports.hpp" | ||||
| #include "Model.hpp" | ||||
| #include "ExPolygon.hpp" | ||||
|  | @ -58,42 +60,52 @@ void SLAAutoSupports::project_onto_mesh(std::vector<sla::SupportPoint>& points) | |||
|     igl::Hit hit_up{0, 0, 0.f, 0.f, 0.f}; | ||||
|     igl::Hit hit_down{0, 0, 0.f, 0.f, 0.f}; | ||||
| 
 | ||||
|     for (sla::SupportPoint& support_point : points) { | ||||
|         Vec3f& p = support_point.pos; | ||||
|         // Project the point upward and downward and choose the closer intersection with the mesh.
 | ||||
|         //bool up   = igl::ray_mesh_intersect(p.cast<float>(), Vec3f(0., 0., 1.), m_V, m_F, hit_up);
 | ||||
|         //bool down = igl::ray_mesh_intersect(p.cast<float>(), Vec3f(0., 0., -1.), m_V, m_F, hit_down);
 | ||||
|     // Use a reasonable granularity to account for the worker thread synchronization cost.
 | ||||
|     tbb::parallel_for(tbb::blocked_range<size_t>(0, points.size(), 64), | ||||
|         [this, &points](const tbb::blocked_range<size_t>& range) { | ||||
|             for (size_t point_id = range.begin(); point_id < range.end(); ++ point_id) { | ||||
|                 if ((point_id % 16) == 0) | ||||
|                     // Don't call the following function too often as it flushes CPU write caches due to synchronization primitves.
 | ||||
|                     m_throw_on_cancel(); | ||||
|                 Vec3f& p = points[point_id].pos; | ||||
|                 // Project the point upward and downward and choose the closer intersection with the mesh.
 | ||||
|                 //bool up   = igl::ray_mesh_intersect(p.cast<float>(), Vec3f(0., 0., 1.), m_V, m_F, hit_up);
 | ||||
|                 //bool down = igl::ray_mesh_intersect(p.cast<float>(), Vec3f(0., 0., -1.), m_V, m_F, hit_down);
 | ||||
| 
 | ||||
|         sla::EigenMesh3D::hit_result hit_up   = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., 1.)); | ||||
|         sla::EigenMesh3D::hit_result hit_down = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., -1.)); | ||||
|                 sla::EigenMesh3D::hit_result hit_up   = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., 1.)); | ||||
|                 sla::EigenMesh3D::hit_result hit_down = m_emesh.query_ray_hit(p.cast<double>(), Vec3d(0., 0., -1.)); | ||||
| 
 | ||||
|         bool up   = hit_up.face() != -1; | ||||
|         bool down = hit_down.face() != -1; | ||||
|                 bool up   = hit_up.face() != -1; | ||||
|                 bool down = hit_down.face() != -1; | ||||
| 
 | ||||
|         if (!up && !down) | ||||
|             continue; | ||||
|                 if (!up && !down) | ||||
|                     continue; | ||||
| 
 | ||||
|         sla::EigenMesh3D::hit_result& hit = (!down || (hit_up.distance() < hit_down.distance())) ? hit_up : hit_down; | ||||
|         //int fid = hit.face();
 | ||||
|         //Vec3f bc(1-hit.u-hit.v, hit.u, hit.v);
 | ||||
|         //p = (bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2))).cast<float>();
 | ||||
|                 sla::EigenMesh3D::hit_result& hit = (!down || (hit_up.distance() < hit_down.distance())) ? hit_up : hit_down; | ||||
|                 //int fid = hit.face();
 | ||||
|                 //Vec3f bc(1-hit.u-hit.v, hit.u, hit.v);
 | ||||
|                 //p = (bc(0) * m_V.row(m_F(fid, 0)) + bc(1) * m_V.row(m_F(fid, 1)) + bc(2)*m_V.row(m_F(fid, 2))).cast<float>();
 | ||||
| 
 | ||||
|         p = p + (hit.distance() * hit.direction()).cast<float>(); | ||||
|     } | ||||
|                 p = p + (hit.distance() * hit.direction()).cast<float>(); | ||||
|             } | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std::vector<float>& heights) | ||||
| { | ||||
|     std::vector<std::pair<ExPolygon, coord_t>> islands; | ||||
|     std::vector<Structure> structures_old; | ||||
|     std::vector<Structure> structures_new; | ||||
| 
 | ||||
|     for (unsigned int i = 0; i<slices.size(); ++i) { | ||||
|         const ExPolygons& expolys_top = slices[i]; | ||||
| 
 | ||||
|         //FIXME WTF?
 | ||||
|         const float height = (i>2 ? heights[i-3] : heights[0]-(heights[1]-heights[0])); | ||||
|         const float layer_height = (i!=0 ? heights[i]-heights[i-1] : heights[0]); | ||||
|          | ||||
|         const float safe_angle = 5.f * (M_PI/180.f); // smaller number - less supports
 | ||||
|         const float offset =  scale_(layer_height / std::tan(safe_angle)); | ||||
|         const float safe_angle = 5.f * (float(M_PI)/180.f); // smaller number - less supports
 | ||||
|         const float between_layers_offset =  float(scale_(layer_height / std::tan(safe_angle))); | ||||
| 
 | ||||
|         // FIXME: calculate actual pixel area from printer config:
 | ||||
|         //const float pixel_area = pow(wxGetApp().preset_bundle->project_config.option<ConfigOptionFloat>("display_width") / wxGetApp().preset_bundle->project_config.option<ConfigOptionInt>("display_pixels_x"), 2.f); //
 | ||||
|  | @ -101,87 +113,76 @@ void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std:: | |||
| 
 | ||||
|         // Check all ExPolygons on this slice and check whether they are new or belonging to something below.
 | ||||
|         for (const ExPolygon& polygon : expolys_top) { | ||||
|             if (polygon.area() * SCALING_FACTOR * SCALING_FACTOR < pixel_area) | ||||
|             float area = float(polygon.area() * SCALING_FACTOR * SCALING_FACTOR); | ||||
|             if (area < pixel_area) | ||||
|                 continue; | ||||
| 
 | ||||
|             m_structures_new.emplace_back(polygon, height); | ||||
|             for (Structure& s : m_structures_old) { | ||||
|                 const ExPolygon* bottom = s.polygon; | ||||
|                 if (polygon.overlaps(*bottom) || bottom->overlaps(polygon)) { | ||||
|                     m_structures_new.back().structures_below.push_back(&s); | ||||
| 
 | ||||
|                     coord_t centroids_dist = (bottom->contour.centroid() - polygon.contour.centroid()).norm(); | ||||
| 
 | ||||
|             //FIXME this is not a correct centroid of a polygon with holes.
 | ||||
|             structures_new.emplace_back(polygon, get_extents(polygon.contour), Slic3r::unscale(polygon.contour.centroid()).cast<float>(), area, height); | ||||
|             Structure& top = structures_new.back(); | ||||
|             //FIXME This has a quadratic time complexity, it will be excessively slow for many tiny islands.
 | ||||
|             // At least it is now using a bounding box check for pre-filtering.
 | ||||
| 			for (Structure& bottom : structures_old) | ||||
| 				if (top.overlaps(bottom)) { | ||||
| 					top.structures_below.push_back(&bottom); | ||||
|                     float centroids_dist = (bottom.centroid - top.centroid).norm(); | ||||
|                     // Penalization resulting from centroid offset:
 | ||||
|                     s.supports_force *= std::min(1.f, 1.f - std::min(1.f, (1600.f * layer_height) * (float)(centroids_dist * centroids_dist) / (float)bottom->area())); | ||||
| 
 | ||||
| //					bottom.supports_force *= std::min(1.f, 1.f - std::min(1.f, (1600.f * layer_height) * centroids_dist * centroids_dist / bottom.area));
 | ||||
|                     bottom.supports_force *= std::min(1.f, 1.f - std::min(1.f, 80.f * centroids_dist * centroids_dist / bottom.area)); | ||||
|                     // Penalization resulting from increasing polygon area:
 | ||||
|                     s.supports_force *= std::min(1.f, 20.f * ((float)bottom->area() / (float)polygon.area())); | ||||
| 					bottom.supports_force *= std::min(1.f, 20.f * bottom.area / top.area); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Let's assign proper support force to each of them:
 | ||||
|         for (Structure& old_str : m_structures_old) { | ||||
|             std::vector<Structure*> children; | ||||
|             float children_area = 0.f; | ||||
|             for (Structure& new_str : m_structures_new) | ||||
|                 for (const Structure* below : new_str.structures_below) | ||||
|                     if (&old_str == below) { | ||||
|                         children.push_back(&new_str); | ||||
|                         children_area += children.back()->polygon->area() * pow(SCALING_FACTOR, 2); | ||||
|         for (const Structure& below : structures_old) { | ||||
|             std::vector<Structure*> above_list; | ||||
|             float above_area = 0.f; | ||||
|             for (Structure& new_str : structures_new) | ||||
|                 for (const Structure* below1 : new_str.structures_below) | ||||
|                     if (&below == below1) { | ||||
|                         above_list.push_back(&new_str); | ||||
|                         above_area += above_list.back()->area; | ||||
|                     } | ||||
|             for (Structure* child : children) | ||||
|                 child->supports_force += (old_str.supports_force/children_area) * (child->polygon->area() * pow(SCALING_FACTOR, 2)); | ||||
|             for (Structure* above : above_list) | ||||
|                 above->supports_force += below.supports_force * above->area / above_area; | ||||
|         } | ||||
|          | ||||
|         // Now iterate over all polygons and append new points if needed.
 | ||||
|         for (Structure& s : m_structures_new) { | ||||
|             if (s.structures_below.empty()) {// completely new island - needs support no doubt
 | ||||
|         for (Structure& s : structures_new) { | ||||
|             if (s.structures_below.empty()) // completely new island - needs support no doubt
 | ||||
|                 uniformly_cover(*s.polygon, s, true); | ||||
|             } | ||||
|             else { | ||||
|             else | ||||
|                 // Let's see if there's anything that overlaps enough to need supports:
 | ||||
|                 ExPolygons polygons; | ||||
|                 float bottom_area = 0.f; | ||||
|                 for (const Structure* sb : s.structures_below) { | ||||
|                     polygons.push_back(*sb->polygon); | ||||
|                     bottom_area += polygons.back().area() * pow(SCALING_FACTOR, 2); | ||||
|                 } | ||||
| 
 | ||||
|                 polygons = offset_ex(polygons, offset); | ||||
|                 polygons = diff_ex(ExPolygons{*s.polygon}, polygons); | ||||
|                  | ||||
|                 // What we now have in polygons needs support, regardless of what the forces are, so we can add them.
 | ||||
|                 for (const ExPolygon& p : polygons) | ||||
| 				for (const ExPolygon& p : diff_ex(to_polygons(*s.polygon), offset(s.expolygons_below(), between_layers_offset))) | ||||
|                     //FIXME is it an island point or not? Vojtech thinks it is.
 | ||||
|                     uniformly_cover(p, s); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // We should also check if current support is enough given the polygon area.
 | ||||
|         for (Structure& s : m_structures_new) { | ||||
|             ExPolygons e; | ||||
|             float e_area = 0.f; | ||||
|             for (const Structure* a : s.structures_below) { | ||||
|                 e.push_back(*a->polygon); | ||||
|                 e_area += e.back().area() * SCALING_FACTOR * SCALING_FACTOR; | ||||
|             } | ||||
| 
 | ||||
|             e = diff_ex(ExPolygons{*s.polygon}, e); | ||||
| 
 | ||||
|         for (Structure& s : structures_new) { | ||||
|             // Areas not supported by the areas below.
 | ||||
|             ExPolygons e = diff_ex(to_polygons(*s.polygon), s.polygons_below()); | ||||
| 			float e_area = 0.f; | ||||
| 			for (const ExPolygon &ex : e) | ||||
| 				e_area += float(ex.area()); | ||||
|             // Penalization resulting from large diff from the last layer:
 | ||||
|             s.supports_force /= std::max(1., (layer_height / 0.3f) * (e_area / (s.polygon->area()*SCALING_FACTOR*SCALING_FACTOR))); | ||||
| //            s.supports_force /= std::max(1.f, (layer_height / 0.3f) * e_area / s.area);
 | ||||
| 			s.supports_force /= std::max(1.f, 0.17f * (e_area * float(SCALING_FACTOR * SCALING_FACTOR)) / s.area); | ||||
| 
 | ||||
|             if ( (s.polygon->area() * pow(SCALING_FACTOR, 2)) * m_config.tear_pressure > s.supports_force) { | ||||
|             if (s.area * m_config.tear_pressure > s.supports_force) { | ||||
|                 //FIXME Don't calculate area inside the compare function!
 | ||||
|                 //FIXME Cover until the force deficit is covered. Cover multiple areas, sort by decreasing area.
 | ||||
|                 ExPolygons::iterator largest_it = std::max_element(e.begin(), e.end(), [](const ExPolygon& a, const ExPolygon& b) { return a.area() < b.area(); }); | ||||
|                 if (!e.empty()) | ||||
|                     //FIXME add the support force deficit as a parameter, only cover until the defficiency is covered.
 | ||||
|                     uniformly_cover(*largest_it, s); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // All is done. Prepare to advance to the next layer. 
 | ||||
|         m_structures_old = m_structures_new; | ||||
|         m_structures_new.clear(); | ||||
|         structures_old = std::move(structures_new); | ||||
|         structures_new.clear(); | ||||
| 
 | ||||
|         m_throw_on_cancel(); | ||||
| 
 | ||||
|  | @ -195,15 +196,6 @@ void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std:: | |||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void SLAAutoSupports::add_point(const Point& point, Structure& structure, bool is_new_island) | ||||
| { | ||||
|     sla::SupportPoint new_point(point(0) * SCALING_FACTOR, point(1) * SCALING_FACTOR, structure.height, 0.4f, (float)is_new_island); | ||||
|      | ||||
|     m_output.emplace_back(new_point); | ||||
|     structure.supports_force += m_config.support_force; | ||||
| } | ||||
| 
 | ||||
| void SLAAutoSupports::uniformly_cover(const ExPolygon& island, Structure& structure, bool is_new_island, bool just_one) | ||||
| { | ||||
|     //int num_of_points = std::max(1, (int)((island.area()*pow(SCALING_FACTOR, 2) * m_config.tear_pressure)/m_config.support_force));
 | ||||
|  | @ -212,14 +204,18 @@ void SLAAutoSupports::uniformly_cover(const ExPolygon& island, Structure& struct | |||
| 
 | ||||
|     // We will cover the island another way.
 | ||||
|     // For now we'll just place the points randomly not too close to the others.
 | ||||
|     //FIXME share the random generator. The random generator may be not so cheap to initialize, also we don't want the random generator to be restarted for each polygon.
 | ||||
|     std::random_device rd; | ||||
|     std::mt19937 gen(rd()); | ||||
|     std::uniform_real_distribution<> dis(0., 1.); | ||||
| 
 | ||||
|     std::vector<Vec3d> island_new_points; | ||||
|     const BoundingBox& bb = get_extents(island); | ||||
|     const int refused_limit = 30 * ((float)bb.size()(0)*bb.size()(1) / (float)island.area()); | ||||
|     const BoundingBox bb = get_extents(island); | ||||
|     const int refused_limit = (int)floor(30.f * ((float)bb.size()(0)*bb.size()(1) / (float)island.area()) + 0.5f); | ||||
|     int refused_points = 0; | ||||
|     //FIXME this is very inefficient (may be blind) for long narrow polygons (thin crescent, thin ring). Use some search structure: Triangulate the polygon first?
 | ||||
|     //FIXME use a low discrepancy sequence, Poisson sampling.
 | ||||
|     // Poisson sampling (adapt from 3D to 2D by triangulation): https://github.com/zewt/maya-implicit-skinning/blob/master/src/meshes/vcg_lib/utils_sampling.cpp
 | ||||
|     while (refused_points < refused_limit) { | ||||
|         Point out; | ||||
|         if (refused_points == 0 && island_new_points.empty()) // first iteration
 | ||||
|  | @ -227,15 +223,17 @@ void SLAAutoSupports::uniformly_cover(const ExPolygon& island, Structure& struct | |||
|         else | ||||
|             out = Point(bb.min(0) + bb.size()(0)  * dis(gen), bb.min(1) + bb.size()(1)  * dis(gen)); | ||||
| 
 | ||||
|         Vec3d unscaled_out = unscale(out(0), out(1), 0.f); | ||||
|         Vec3d unscaled_out = unscale(out(0), out(1), 0); | ||||
|         bool add_it = true; | ||||
| 
 | ||||
|         if (!island.contour.contains(out)) | ||||
|             add_it = false; | ||||
|         else | ||||
|             for (const Polygon& hole : island.holes) | ||||
|                 if (hole.contains(out)) | ||||
|                 if (hole.contains(out)) { | ||||
|                     add_it = false; | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|         if (add_it) { | ||||
|             for (const Vec3d& p : island_new_points) { | ||||
|  | @ -254,14 +252,15 @@ void SLAAutoSupports::uniformly_cover(const ExPolygon& island, Structure& struct | |||
|             ++refused_points; | ||||
|     } | ||||
| 
 | ||||
|     for (const Vec3d& p : island_new_points) | ||||
|         add_point(Point(scale_(p.x()), scale_(p.y())), structure, is_new_island); | ||||
|     for (const Vec3d& p : island_new_points) { | ||||
|         m_output.emplace_back(float(p(0)), float(p(1)), structure.height, 0.4f, is_new_island); | ||||
|         structure.supports_force += m_config.support_force; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #ifdef SLA_AUTOSUPPORTS_DEBUG | ||||
| void SLAAutoSupports::output_structures() const | ||||
| void SLAAutoSupports::output_structures(const std::vector<Structure>& structures) | ||||
| { | ||||
|     const std::vector<Structure>& structures = m_structures_new; | ||||
|     for (unsigned int i=0 ; i<structures.size(); ++i) { | ||||
|         std::stringstream ss; | ||||
|         ss << structures[i].unique_id.count() << "_" << std::setw(10) << std::setfill('0') << 1000 + (int)structures[i].height/1000 << ".png"; | ||||
|  | @ -269,7 +268,7 @@ void SLAAutoSupports::output_structures() const | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void SLAAutoSupports::output_expolygons(const ExPolygons& expolys, std::string filename) const | ||||
| void SLAAutoSupports::output_expolygons(const ExPolygons& expolys, const std::string &filename) | ||||
| { | ||||
|     BoundingBox bb(Point(-30000000, -30000000), Point(30000000, 30000000)); | ||||
|     Slic3r::SVG svg_cummulative(filename, bb); | ||||
|  |  | |||
|  | @ -16,8 +16,8 @@ public: | |||
|             float density_at_45; | ||||
|             float minimal_z; | ||||
|             ///////////////
 | ||||
|             float support_force = 30; // a force one point can support       (arbitrary force unit)
 | ||||
|             float tear_pressure = 1; // pressure that the display exerts    (the force unit per mm2)
 | ||||
|             float support_force = 30.f; // a force one point can support       (arbitrary force unit)
 | ||||
|             float tear_pressure = 1.f; // pressure that the display exerts    (the force unit per mm2)
 | ||||
|         }; | ||||
| 
 | ||||
|     SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3D& emesh, const std::vector<ExPolygons>& slices, | ||||
|  | @ -27,32 +27,65 @@ public: | |||
| private: | ||||
|     std::vector<sla::SupportPoint> m_output; | ||||
| 
 | ||||
| #ifdef SLA_AUTOSUPPORTS_DEBUG | ||||
|     void output_expolygons(const ExPolygons& expolys, std::string filename) const; | ||||
|     void output_structures() const; | ||||
| #endif // SLA_AUTOSUPPORTS_DEBUG
 | ||||
| 
 | ||||
|     SLAAutoSupports::Config m_config; | ||||
| 
 | ||||
|     struct Structure { | ||||
|         Structure(const ExPolygon& poly, float h) : height(h), unique_id(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())) { | ||||
|             polygon = &poly; | ||||
|         } | ||||
|         Structure(const ExPolygon& poly, const BoundingBox &bbox, const Vec2f ¢roid, float area, float h) : polygon(&poly), bbox(bbox), centroid(centroid), area(area), height(h) | ||||
| #ifdef SLA_AUTOSUPPORTS_DEBUG | ||||
|             , unique_id(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch())) | ||||
| #endif /* SLA_AUTOSUPPORTS_DEBUG */ | ||||
|             {} | ||||
|         const ExPolygon* polygon = nullptr; | ||||
|         const BoundingBox bbox; | ||||
|         const Vec2f centroid = Vec3f::Zero(); | ||||
|         const float area = 0.f; | ||||
|         std::vector<const Structure*> structures_below; | ||||
|         float height = 0; | ||||
|         // How well is this ExPolygon held to the print base?
 | ||||
|         // Positive number, the higher the better.
 | ||||
|         float supports_force = 0.f; | ||||
| #ifdef SLA_AUTOSUPPORTS_DEBUG | ||||
|         std::chrono::milliseconds unique_id; | ||||
| #endif /* SLA_AUTOSUPPORTS_DEBUG */ | ||||
| 
 | ||||
|         bool overlaps(const Structure &rhs) const { return this->bbox.overlap(rhs.bbox) && (this->polygon->overlaps(*rhs.polygon) || rhs.polygon->overlaps(*this->polygon)); } | ||||
|         float area_below() const {  | ||||
|             float area = 0.f;  | ||||
|             for (const Structure *below : this->structures_below)  | ||||
|                 area += below->area;  | ||||
|             return area; | ||||
|         } | ||||
|         Polygons polygons_below() const {  | ||||
|             size_t cnt = 0; | ||||
|             for (const Structure *below : this->structures_below) | ||||
|                 cnt += 1 + below->polygon->holes.size(); | ||||
|             Polygons out; | ||||
|             out.reserve(cnt); | ||||
|             for (const Structure *below : this->structures_below) { | ||||
|                 out.emplace_back(below->polygon->contour); | ||||
|                 append(out, below->polygon->holes); | ||||
|             } | ||||
|             return out; | ||||
|         } | ||||
|         ExPolygons expolygons_below() const {  | ||||
|             ExPolygons out; | ||||
| 			out.reserve(this->structures_below.size()); | ||||
|             for (const Structure *below : this->structures_below) | ||||
|                 out.emplace_back(*below->polygon); | ||||
|             return out; | ||||
|         } | ||||
|     }; | ||||
|     std::vector<Structure> m_structures_old; | ||||
|     std::vector<Structure> m_structures_new; | ||||
| 
 | ||||
|     float m_supports_force_total = 0.f; | ||||
| 
 | ||||
|     void process(const std::vector<ExPolygons>& slices, const std::vector<float>& heights); | ||||
|     void add_point(const Point& point, Structure& structure, bool island  = false); | ||||
|     void uniformly_cover(const ExPolygon& island, Structure& structure, bool is_new_island = false, bool just_one = false); | ||||
|     void project_onto_mesh(std::vector<sla::SupportPoint>& points) const; | ||||
| 
 | ||||
| #ifdef SLA_AUTOSUPPORTS_DEBUG | ||||
|     static void output_expolygons(const ExPolygons& expolys, const std::string &filename); | ||||
|     static void output_structures(const std::vector<Structure> &structures); | ||||
| #endif // SLA_AUTOSUPPORTS_DEBUG
 | ||||
| 
 | ||||
|     std::function<void(void)> m_throw_on_cancel; | ||||
|     const sla::EigenMesh3D& m_emesh; | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ struct SupportPoint { | |||
|     pos(position), head_front_radius(head_radius), is_new_island(new_island) {} | ||||
| 
 | ||||
|     SupportPoint(Eigen::Matrix<float, 5, 1, Eigen::DontAlign> data) : | ||||
|     pos(data(0), data(1), data(2)), head_front_radius(data(3)), is_new_island(data(4)) {} | ||||
|     pos(data(0), data(1), data(2)), head_front_radius(data(3)), is_new_island(data(4) != 0.f) {} | ||||
| 
 | ||||
|     bool operator==(const SupportPoint& sp) const { return (pos==sp.pos) && head_front_radius==sp.head_front_radius && is_new_island==sp.is_new_island; } | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv