mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Fixed some rare support issues connected with the 1st print layer.
Fixed support issue, where the XY gap was ignored for the top contact layers and a fixed 50% was used instead.
This commit is contained in:
		
							parent
							
								
									ed2ee2f6f3
								
							
						
					
					
						commit
						688fe3e2b2
					
				
					 2 changed files with 40 additions and 38 deletions
				
			
		|  | @ -131,7 +131,7 @@ void export_print_z_polygons_and_extrusions_to_svg( | |||
| 
 | ||||
|     Polygons polygons_support, polygons_interface; | ||||
|     support_layer.support_fills.polygons_covered_by_width(polygons_support, SCALED_EPSILON); | ||||
|     support_layer.support_interface_fills.polygons_covered_by_width(polygons_interface, SCALED_EPSILON); | ||||
| //    support_layer.support_interface_fills.polygons_covered_by_width(polygons_interface, SCALED_EPSILON);
 | ||||
|     svg.draw(union_ex(polygons_support), "brown"); | ||||
|     svg.draw(union_ex(polygons_interface), "black"); | ||||
| 
 | ||||
|  | @ -192,6 +192,16 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object | |||
|         external_perimeter_width = std::max(external_perimeter_width, width); | ||||
|     } | ||||
|     m_gap_xy = m_object_config->support_material_xy_spacing.get_abs_value(external_perimeter_width); | ||||
| 
 | ||||
|     m_can_merge_support_regions = m_object_config->support_material_extruder.value == m_object_config->support_material_interface_extruder.value; | ||||
|     if (! m_can_merge_support_regions && (m_object_config->support_material_extruder.value == 0 || m_object_config->support_material_interface_extruder.value == 0)) { | ||||
|         // One of the support extruders is of "don't care" type.
 | ||||
|         auto object_extruders = m_object->print()->object_extruders(); | ||||
|         if (object_extruders.size() == 1 && | ||||
|             *object_extruders.begin() == std::max(m_object_config->support_material_extruder.value, m_object_config->support_material_interface_extruder.value)) | ||||
|             // Object is printed with the same extruder as the support.
 | ||||
|             m_can_merge_support_regions = true; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Using the std::deque as an allocator.
 | ||||
|  | @ -836,7 +846,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ | |||
|                         // on the other side of the object (if it's very thin).
 | ||||
|                         { | ||||
|                             //FIMXE 1) Make the offset configurable, 2) Make the Z span configurable.
 | ||||
|                             float slices_margin_offset = float(0.5*fw); | ||||
|                             float slices_margin_offset = float(scale_(m_gap_xy));  | ||||
|                             if (slices_margin_cached_offset != slices_margin_offset) { | ||||
|                                 slices_margin_cached_offset = slices_margin_offset; | ||||
|                                 slices_margin_cached = offset(lower_layer.slices.expolygons, slices_margin_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS); | ||||
|  | @ -913,28 +923,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ | |||
|                                 new_layer.bottom_z = 0; | ||||
|                                 new_layer.height   = m_slicing_params.first_print_layer_height; | ||||
|                             } else if (this->synchronize_layers()) { | ||||
|                                 // Align bottom of this layer with a top of the closest object layer
 | ||||
|                                 // while not trespassing into the 1st layer and keeping the support layer thickness bounded.
 | ||||
|                                 int layer_id_below = int(layer_id) - 1; | ||||
|                                 for (; layer_id_below >= 0; -- layer_id_below) { | ||||
|                                     layer_below = object.layers[layer_id_below]; | ||||
|                                     if (layer_below->print_z <= new_layer.print_z - m_support_layer_height_min) { | ||||
|                                         // This is a feasible support layer height.
 | ||||
|                                         new_layer.bottom_z = layer_below->print_z; | ||||
|                                         new_layer.height = new_layer.print_z - new_layer.bottom_z; | ||||
|                                         assert(new_layer.height <= m_slicing_params.max_suport_layer_height); | ||||
|                                         break; | ||||
|                                     }                         | ||||
|                                 } | ||||
|                                 if (layer_id_below == -1) { | ||||
|                                     // Could not align with any of the top surfaces of object layers.
 | ||||
|                                     if (this->has_raft()) { | ||||
|                                         // If having a raft, all the other layers will be aligned one with the other.
 | ||||
|                                     } else { | ||||
|                                         // Give up, ignore this layer.
 | ||||
|                                         continue; | ||||
|                                     } | ||||
|                                 } | ||||
|                                 // Don't do anything special for the top contact surfaces in regard to synchronizing the layers.
 | ||||
|                                 // Bottom contact surfaces will be synchronized though.
 | ||||
|                             } else { | ||||
|                                 // Don't know the height of the top contact layer yet. The top contact layer is printed with a normal flow and 
 | ||||
|                                 // its height will be set adaptively later on.
 | ||||
|  | @ -1298,8 +1288,17 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int | |||
| 			continue; | ||||
|         } | ||||
|         if (std::abs(extr2z - m_slicing_params.first_print_layer_height) < EPSILON) { | ||||
|             // This is a 1st layer supporting some of the early object print layers, its height has been decided in this->top_contact_layers().
 | ||||
|             // This is a bottom of a synchronized (or soluble) top contact layer, its height has been decided in this->top_contact_layers().
 | ||||
|             assert(extr2->layer_type == sltTopContact); | ||||
| 			assert(extr2->bottom_z == m_slicing_params.first_print_layer_height); | ||||
| 			assert(extr2->print_z >= m_slicing_params.first_print_layer_height + this->m_support_layer_height_min - EPSILON); | ||||
| 			if (intermediate_layers.empty() || intermediate_layers.back()->print_z < m_slicing_params.first_print_layer_height) { | ||||
| 				MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate); | ||||
| 				layer_new.bottom_z = 0.; | ||||
| 				layer_new.print_z  = m_slicing_params.first_print_layer_height; | ||||
| 				layer_new.height   = m_slicing_params.first_print_layer_height; | ||||
| 				intermediate_layers.push_back(&layer_new); | ||||
| 			} | ||||
|             continue; | ||||
|         } | ||||
|         assert(extr2z >= m_slicing_params.raft_interface_top_z + EPSILON); | ||||
|  | @ -1633,12 +1632,12 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf | |||
|     MyLayerStorage      &layer_storage) const | ||||
| { | ||||
|     // How much to inflate the support columns to be stable. This also applies to the 1st layer, if no raft layers are to be printed.
 | ||||
|     const float inflate_factor_fine      = float(scale_(0.5)); | ||||
|     const float inflate_factor_fine      = float(scale_((m_slicing_params.raft_layers() > 1) ? 0.5 : EPSILON)); | ||||
|     const float inflate_factor_1st_layer = float(scale_(3.)) - inflate_factor_fine; | ||||
|     MyLayer       *contacts      = top_contacts    .empty() ? nullptr : top_contacts    .front(); | ||||
|     MyLayer       *interfaces    = interface_layers.empty() ? nullptr : interface_layers.front(); | ||||
|     MyLayer       *columns_base  = base_layers     .empty() ? nullptr : base_layers     .front(); | ||||
| 	if (contacts != nullptr && contacts->print_z > m_slicing_params.raft_contact_top_z + EPSILON) | ||||
| 	if (contacts != nullptr && contacts->print_z > std::max(m_slicing_params.first_print_layer_height, m_slicing_params.raft_contact_top_z) + EPSILON) | ||||
| 		// This is not the raft contact layer.
 | ||||
| 		contacts = nullptr; | ||||
|     if (interfaces != nullptr && interfaces->bottom_print_z() > m_slicing_params.raft_interface_top_z + EPSILON) | ||||
|  | @ -2181,7 +2180,7 @@ void modulate_extrusion_by_overlapping_layers( | |||
|     // Get the initial extrusion parameters.
 | ||||
|     ExtrusionPath *extrusion_path_template = dynamic_cast<ExtrusionPath*>(extrusions_in_out.front()); | ||||
|     assert(extrusion_path_template != nullptr); | ||||
|     ExtrusionRole extrusion_role  = extrusion_path_template->role; | ||||
|     ExtrusionRole extrusion_role  = extrusion_path_template->role(); | ||||
|     float         extrusion_width = extrusion_path_template->width; | ||||
| 
 | ||||
|     struct ExtrusionPathFragment | ||||
|  | @ -2491,8 +2490,6 @@ void PrintObjectSupportMaterial::generate_toolpaths( | |||
|             assert(support_layer_id < raft_layers.size()); | ||||
|             SupportLayer &support_layer = *object.support_layers[support_layer_id]; | ||||
|             assert(support_layer.support_fills.entities.empty()); | ||||
|             assert(support_layer.support_interface_fills.entities.empty()); | ||||
|             assert(support_layer.support_islands.expolygons.empty()); | ||||
|             MyLayer      &raft_layer    = *raft_layers[support_layer_id]; | ||||
| 
 | ||||
|             std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(ipRectilinear)); | ||||
|  | @ -2587,6 +2584,7 @@ void PrintObjectSupportMaterial::generate_toolpaths( | |||
|         std::vector<LayerCacheItem>     overlaps; | ||||
|     }; | ||||
|     std::vector<LayerCache>             layer_caches(object.support_layers.size(), LayerCache()); | ||||
| 
 | ||||
|     tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, object.support_layers.size()), | ||||
|         [this, &object, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &layer_caches, &loop_interface_processor,  | ||||
|             infill_pattern, &bbox_object, support_density, interface_density, interface_angle, &angles, link_max_length_factor, with_sheath] | ||||
|  | @ -2630,14 +2628,16 @@ void PrintObjectSupportMaterial::generate_toolpaths( | |||
| 
 | ||||
|             if (m_object_config->support_material_interface_layers == 0) { | ||||
|                 // If no interface layers were requested, we treat the contact layer exactly as a generic base layer.
 | ||||
|     			if (base_layer.could_merge(top_contact_layer))  | ||||
|     				base_layer.merge(std::move(top_contact_layer)); | ||||
|     			else if (base_layer.empty() && !top_contact_layer.empty() && !top_contact_layer.layer->bridging) | ||||
|     				std::swap(base_layer, top_contact_layer); | ||||
|                 if (base_layer.could_merge(bottom_contact_layer)) | ||||
|                     base_layer.merge(std::move(bottom_contact_layer)); | ||||
|                 else if (base_layer.empty() && !bottom_contact_layer.empty() && !bottom_contact_layer.layer->bridging) | ||||
|                     std::swap(base_layer, bottom_contact_layer); | ||||
|                 if (m_can_merge_support_regions) { | ||||
|         			if (base_layer.could_merge(top_contact_layer))  | ||||
|         				base_layer.merge(std::move(top_contact_layer)); | ||||
|         			else if (base_layer.empty() && !top_contact_layer.empty() && !top_contact_layer.layer->bridging) | ||||
|         				std::swap(base_layer, top_contact_layer); | ||||
|                     if (base_layer.could_merge(bottom_contact_layer)) | ||||
|                         base_layer.merge(std::move(bottom_contact_layer)); | ||||
|                     else if (base_layer.empty() && !bottom_contact_layer.empty() && !bottom_contact_layer.layer->bridging) | ||||
|                         std::swap(base_layer, bottom_contact_layer); | ||||
|                 } | ||||
|             } else { | ||||
|                 loop_interface_processor.generate(top_contact_layer, m_support_material_interface_flow); | ||||
|                 // If no loops are allowed, we treat the contact layer exactly as a generic interface layer.
 | ||||
|  |  | |||
|  | @ -226,6 +226,8 @@ private: | |||
| 	Flow 			 	 m_first_layer_flow; | ||||
| 	Flow 			 	 m_support_material_flow; | ||||
| 	Flow 			 	 m_support_material_interface_flow; | ||||
| 	// Is merging of regions allowed? Could the interface & base support regions be printed with the same extruder?
 | ||||
| 	bool 				 m_can_merge_support_regions; | ||||
| 
 | ||||
|     coordf_t 			 m_support_layer_height_min; | ||||
| 	coordf_t		 	 m_support_layer_height_max; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv