mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Refactoring of adaptive cubic infill:
Don't create an octree for the infill if it is not needed.
This commit is contained in:
		
							parent
							
								
									97e62be902
								
							
						
					
					
						commit
						7b318e1698
					
				
					 3 changed files with 100 additions and 38 deletions
				
			
		|  | @ -3,12 +3,93 @@ | |||
| #include "../Surface.hpp" | ||||
| #include "../Geometry.hpp" | ||||
| #include "../AABBTreeIndirect.hpp" | ||||
| #include "../Layer.hpp" | ||||
| #include "../Print.hpp" | ||||
| #include "../ShortestPath.hpp" | ||||
| 
 | ||||
| #include "FillAdaptive.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object) | ||||
| { | ||||
|     // Output, spacing for icAdaptiveCubic and icSupportCubic
 | ||||
|     double  adaptive_line_spacing = 0.; | ||||
|     double  support_line_spacing = 0.; | ||||
| 
 | ||||
|     enum class Tristate { | ||||
|         Yes, | ||||
|         No, | ||||
|         Maybe | ||||
|     }; | ||||
|     struct RegionFillData { | ||||
|         Tristate        has_adaptive_infill; | ||||
|         Tristate        has_support_infill; | ||||
|         double          density; | ||||
|         double          extrusion_width; | ||||
|     }; | ||||
|     std::vector<RegionFillData> region_fill_data; | ||||
|     region_fill_data.reserve(print_object.print()->regions().size()); | ||||
|     bool                        build_octree = false; | ||||
|     for (const PrintRegion *region : print_object.print()->regions()) { | ||||
|         const PrintRegionConfig &config   = region->config(); | ||||
|         bool                     nonempty = config.fill_density > 0; | ||||
|         bool                     has_adaptive_infill = nonempty && config.fill_pattern == ipAdaptiveCubic; | ||||
|         bool                     has_support_infill  = nonempty && false; // config.fill_pattern == icSupportCubic;
 | ||||
|         region_fill_data.push_back(RegionFillData({ | ||||
|             has_adaptive_infill ? Tristate::Maybe : Tristate::No, | ||||
|             has_support_infill ? Tristate::Maybe : Tristate::No, | ||||
|             config.fill_density, | ||||
|             config.infill_extrusion_width | ||||
|         })); | ||||
|         build_octree |= has_adaptive_infill || has_support_infill; | ||||
|     } | ||||
| 
 | ||||
|     if (build_octree) { | ||||
|         // Compute the average of above parameters over all layers
 | ||||
|         for (const Layer *layer : print_object.layers()) | ||||
|             for (size_t region_id = 0; region_id < layer->regions().size(); ++ region_id) { | ||||
|                 RegionFillData &rd = region_fill_data[region_id]; | ||||
|                 if (rd.has_adaptive_infill == Tristate::Maybe && ! layer->regions()[region_id]->fill_surfaces.empty()) | ||||
|                     rd.has_adaptive_infill = Tristate::Yes; | ||||
|                 if (rd.has_support_infill == Tristate::Maybe && ! layer->regions()[region_id]->fill_surfaces.empty()) | ||||
|                     rd.has_support_infill = Tristate::Yes; | ||||
|             } | ||||
| 
 | ||||
|         double  adaptive_fill_density           = 0.; | ||||
|         double  adaptive_infill_extrusion_width = 0.; | ||||
|         int     adaptive_cnt                    = 0; | ||||
|         double  support_fill_density            = 0.; | ||||
|         double  support_infill_extrusion_width  = 0.; | ||||
|         int     support_cnt                     = 0; | ||||
| 
 | ||||
|         for (const RegionFillData &rd : region_fill_data) { | ||||
|             if (rd.has_adaptive_infill == Tristate::Yes) { | ||||
|                 adaptive_fill_density           += rd.density; | ||||
|                 adaptive_infill_extrusion_width += rd.extrusion_width; | ||||
|                 ++ adaptive_cnt; | ||||
|             } else if (rd.has_support_infill == Tristate::Yes) { | ||||
|                 support_fill_density           += rd.density; | ||||
|                 support_infill_extrusion_width += rd.extrusion_width; | ||||
|                 ++ support_cnt; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         auto to_line_spacing = [](int cnt, double density, double extrusion_width) { | ||||
|             if (cnt) { | ||||
|                 density         /= double(cnt); | ||||
|                 extrusion_width /= double(cnt); | ||||
|                 return extrusion_width / ((density / 100.0f) * 0.333333333f); | ||||
|             } else | ||||
|                 return 0.; | ||||
|         }; | ||||
|         adaptive_line_spacing = to_line_spacing(adaptive_cnt, adaptive_fill_density, adaptive_infill_extrusion_width); | ||||
|         support_line_spacing  = to_line_spacing(support_cnt, support_fill_density, support_infill_extrusion_width); | ||||
|     } | ||||
| 
 | ||||
|     return std::make_pair(adaptive_line_spacing, support_line_spacing); | ||||
| } | ||||
| 
 | ||||
| void FillAdaptive::_fill_surface_single( | ||||
|     const FillParams                ¶ms,  | ||||
|     unsigned int                     thickness_layers, | ||||
|  | @ -21,7 +102,7 @@ void FillAdaptive::_fill_surface_single( | |||
|     this->generate_infill_lines(this->adapt_fill_octree->root_cube.get(), | ||||
|                                 this->z, this->adapt_fill_octree->origin,infill_lines_dir, | ||||
|                                 this->adapt_fill_octree->cubes_properties, | ||||
|                                 this->adapt_fill_octree->cubes_properties.size() - 1); | ||||
|                                 int(this->adapt_fill_octree->cubes_properties.size()) - 1); | ||||
| 
 | ||||
|     Polylines all_polylines; | ||||
|     all_polylines.reserve(infill_lines_dir[0].size() * 3); | ||||
|  | @ -131,16 +212,16 @@ void FillAdaptive::generate_infill_lines( | |||
|         Point to(-from.x(), from.y()); | ||||
|         // Relative to cube center
 | ||||
| 
 | ||||
|         float rotation_angle = (2.0 * M_PI) / 3.0; | ||||
|         double rotation_angle = (2.0 * M_PI) / 3.0; | ||||
|         for (Lines &lines : dir_lines_out) | ||||
|         { | ||||
|             Vec3d offset = cube->center - origin; | ||||
|             Point from_abs(from), to_abs(to); | ||||
| 
 | ||||
|             from_abs.x() += scale_(offset.x()); | ||||
|             from_abs.y() += scale_(offset.y()); | ||||
|             to_abs.x() += scale_(offset.x()); | ||||
|             to_abs.y() += scale_(offset.y()); | ||||
|             from_abs.x() += int(scale_(offset.x())); | ||||
|             from_abs.y() += int(scale_(offset.y())); | ||||
|             to_abs.x() += int(scale_(offset.x())); | ||||
|             to_abs.y() += int(scale_(offset.y())); | ||||
| 
 | ||||
| //            lines.emplace_back(from_abs, to_abs);
 | ||||
|             this->connect_lines(lines, Line(from_abs, to_abs)); | ||||
|  | @ -161,7 +242,7 @@ void FillAdaptive::generate_infill_lines( | |||
| 
 | ||||
| void FillAdaptive::connect_lines(Lines &lines, Line new_line) | ||||
| { | ||||
|     int eps = scale_(0.10); | ||||
|     auto eps = int(scale_(0.10)); | ||||
|     for (size_t i = 0; i < lines.size(); ++i) | ||||
|     { | ||||
|         if (std::abs(new_line.a.x() - lines[i].b.x()) < eps && std::abs(new_line.a.y() - lines[i].b.y()) < eps) | ||||
|  | @ -227,7 +308,7 @@ std::unique_ptr<FillAdaptive_Internal::Octree> FillAdaptive::build_octree( | |||
|             triangle_mesh.its.vertices, triangle_mesh.its.indices); | ||||
|     auto octree = std::make_unique<Octree>(std::make_unique<Cube>(cube_center), cube_center, cubes_properties); | ||||
| 
 | ||||
|     FillAdaptive::expand_cube(octree->root_cube.get(), cubes_properties, rotation_matrix, aabbTree, triangle_mesh, cubes_properties.size() - 1); | ||||
|     FillAdaptive::expand_cube(octree->root_cube.get(), cubes_properties, rotation_matrix, aabbTree, triangle_mesh, int(cubes_properties.size()) - 1); | ||||
| 
 | ||||
|     return octree; | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,8 @@ | |||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
| class PrintObject; | ||||
| 
 | ||||
| namespace FillAdaptive_Internal | ||||
| { | ||||
|     struct CubeProperties | ||||
|  | @ -82,6 +84,12 @@ public: | |||
|         int                             depth); | ||||
| }; | ||||
| 
 | ||||
| // Calculate line spacing for
 | ||||
| // 1) adaptive cubic infill
 | ||||
| // 2) adaptive internal support cubic infill
 | ||||
| // Returns zero for a particular infill type if no such infill is to be generated.
 | ||||
| std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object); | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| #endif // slic3r_FillAdaptive_hpp_
 | ||||
|  |  | |||
|  | @ -434,44 +434,17 @@ void PrintObject::generate_support_material() | |||
| 
 | ||||
| std::unique_ptr<FillAdaptive_Internal::Octree> PrintObject::prepare_adaptive_infill_data() | ||||
| { | ||||
|     float fill_density = 0; | ||||
|     float infill_extrusion_width = 0; | ||||
| 
 | ||||
|     // Compute the average of above parameters over all layers
 | ||||
|     for (size_t layer_idx = 0; layer_idx < this->m_layers.size(); ++layer_idx) | ||||
|     { | ||||
|         for (size_t region_id = 0; region_id < this->m_layers[layer_idx]->m_regions.size(); ++region_id) | ||||
|         { | ||||
|             LayerRegion *layerm = this->m_layers[layer_idx]->m_regions[region_id]; | ||||
| 
 | ||||
|             // Check if region_id is used for this layer
 | ||||
|             if(!layerm->fill_surfaces.surfaces.empty()) { | ||||
|                 const PrintRegionConfig ®ion_config = layerm->region()->config(); | ||||
| 
 | ||||
|                 fill_density += region_config.fill_density; | ||||
|                 infill_extrusion_width += region_config.infill_extrusion_width; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fill_density /= this->m_layers.size(); | ||||
|     infill_extrusion_width /= this->m_layers.size(); | ||||
| 
 | ||||
|     if(fill_density <= 0 || infill_extrusion_width <= 0) | ||||
|     { | ||||
|     auto [adaptive_line_spacing, support_line_spacing] = adaptive_fill_line_spacing(*this); | ||||
|     if (adaptive_line_spacing == 0.) | ||||
|         return std::unique_ptr<FillAdaptive_Internal::Octree>{}; | ||||
|     } | ||||
| 
 | ||||
|     coordf_t line_spacing = infill_extrusion_width / ((fill_density / 100.0f) * 0.333333333f); | ||||
| 
 | ||||
|     TriangleMesh mesh = this->model_object()->raw_mesh(); | ||||
|     mesh.transform(m_trafo, true); | ||||
|     // Apply XY shift
 | ||||
|     mesh.translate(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0); | ||||
| 
 | ||||
|     // Center of the first cube in octree
 | ||||
|     Vec3d mesh_origin = mesh.bounding_box().center(); | ||||
|     return FillAdaptive::build_octree(mesh, line_spacing, mesh_origin); | ||||
|     return FillAdaptive::build_octree(mesh, adaptive_line_spacing, mesh_origin); | ||||
| } | ||||
| 
 | ||||
| void PrintObject::clear_layers() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Bubnik
						Vojtech Bubnik