mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Fixed crash when generating gcode of multimaterial objects with some object out of the bed
This commit is contained in:
		
							parent
							
								
									1c6d3c9c69
								
							
						
					
					
						commit
						cac4b29153
					
				
					 2 changed files with 27 additions and 23 deletions
				
			
		|  | @ -309,10 +309,12 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec | |||
|         size_t      object_idx; | ||||
|         size_t      layer_idx; | ||||
|     }; | ||||
|     std::vector<std::vector<LayerToPrint>>  per_object(print.objects.size(), std::vector<LayerToPrint>()); | ||||
| 
 | ||||
|     PrintObjectPtrs printable_objects = print.get_printable_objects(); | ||||
|     std::vector<std::vector<LayerToPrint>>  per_object(printable_objects.size(), std::vector<LayerToPrint>()); | ||||
|     std::vector<OrderingItem>               ordering; | ||||
|     for (size_t i = 0; i < print.objects.size(); ++ i) { | ||||
|         per_object[i] = collect_layers_to_print(*print.objects[i]); | ||||
|     for (size_t i = 0; i < printable_objects.size(); ++i) { | ||||
|         per_object[i] = collect_layers_to_print(*printable_objects[i]); | ||||
|         OrderingItem ordering_item; | ||||
|         ordering_item.object_idx = i; | ||||
|         ordering.reserve(ordering.size() + per_object[i].size()); | ||||
|  | @ -337,8 +339,8 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec | |||
|         std::pair<coordf_t, std::vector<LayerToPrint>> merged; | ||||
|         // Assign an average print_z to the set of layers with nearly equal print_z.
 | ||||
|         merged.first = 0.5 * (ordering[i].print_z + ordering[j-1].print_z); | ||||
|         merged.second.assign(print.objects.size(), LayerToPrint()); | ||||
|         for (; i < j; ++ i) { | ||||
|         merged.second.assign(printable_objects.size(), LayerToPrint()); | ||||
|         for (; i < j; ++i) { | ||||
|             const OrderingItem &oi = ordering[i]; | ||||
|             assert(merged.second[oi.object_idx].layer() == nullptr); | ||||
|             merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]); | ||||
|  | @ -472,9 +474,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) | |||
|     // How many times will be change_layer() called?
 | ||||
|     // change_layer() in turn increments the progress bar status.
 | ||||
|     m_layer_count = 0; | ||||
|     PrintObjectPtrs printable_objects = print.get_printable_objects(); | ||||
|     if (print.config.complete_objects.value) { | ||||
|         // Add each of the object's layers separately.
 | ||||
|         for (auto object : print.objects) { | ||||
|         for (auto object : printable_objects) { | ||||
|             std::vector<coordf_t> zs; | ||||
|             zs.reserve(object->layers.size() + object->support_layers.size()); | ||||
|             for (auto layer : object->layers) | ||||
|  | @ -487,7 +490,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) | |||
|     } else { | ||||
|         // Print all objects with the same print_z together.
 | ||||
|         std::vector<coordf_t> zs; | ||||
|         for (auto object : print.objects) { | ||||
|         for (auto object : printable_objects) { | ||||
|             zs.reserve(zs.size() + object->layers.size() + object->support_layers.size()); | ||||
|             for (auto layer : object->layers) | ||||
|                 zs.push_back(layer->print_z); | ||||
|  | @ -506,8 +509,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) | |||
|     { | ||||
|         // get the minimum cross-section used in the print
 | ||||
|         std::vector<double> mm3_per_mm; | ||||
|         for (auto object : print.objects) { | ||||
|             for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) { | ||||
|         for (auto object : printable_objects) { | ||||
|             for (size_t region_id = 0; region_id < print.regions.size(); ++region_id) { | ||||
|                 auto region = print.regions[region_id]; | ||||
|                 for (auto layer : object->layers) { | ||||
|                     auto layerm = layer->regions[region_id]; | ||||
|  | @ -567,7 +570,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) | |||
|             _write(file, "\n"); | ||||
|     } | ||||
|     // Write some terse information on the slicing parameters.
 | ||||
|     const PrintObject *first_object         = print.objects.front(); | ||||
|     const PrintObject *first_object         = printable_objects.front(); | ||||
|     const double       layer_height         = first_object->config.layer_height.value; | ||||
|     const double       first_layer_height   = first_object->config.first_layer_height.get_abs_value(layer_height); | ||||
|     for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) { | ||||
|  | @ -596,13 +599,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) | |||
|     size_t       initial_print_object_id = 0; | ||||
|     bool         has_wipe_tower      = false; | ||||
|     if (print.config.complete_objects.value) { | ||||
| 		// Find the 1st printing object, find its tool ordering and the initial extruder ID.
 | ||||
| 		for (; initial_print_object_id < print.objects.size(); ++initial_print_object_id) { | ||||
| 			tool_ordering = ToolOrdering(*print.objects[initial_print_object_id], initial_extruder_id); | ||||
| 			if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1) | ||||
| 				break; | ||||
| 		} | ||||
| 	} else { | ||||
|         // Find the 1st printing object, find its tool ordering and the initial extruder ID.
 | ||||
|         for (; initial_print_object_id < printable_objects.size(); ++initial_print_object_id) { | ||||
|             tool_ordering = ToolOrdering(*printable_objects[initial_print_object_id], initial_extruder_id); | ||||
|             if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1) | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
| 		// Find tool ordering for all the objects at once, and the initial extruder ID.
 | ||||
|         // If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it.
 | ||||
| 		tool_ordering = print.m_tool_ordering.empty() ? | ||||
|  | @ -676,7 +680,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) | |||
|         // Collect outer contours of all objects over all layers.
 | ||||
|         // Discard objects only containing thin walls (offset would fail on an empty polygon).
 | ||||
|         Polygons islands; | ||||
|         for (const PrintObject *object : print.objects) | ||||
|         for (const PrintObject *object : printable_objects) | ||||
|             for (const Layer *layer : object->layers) | ||||
|                 for (const ExPolygon &expoly : layer->slices.expolygons) | ||||
|                     for (const Point © : object->_shifted_copies) { | ||||
|  | @ -724,7 +728,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) | |||
|     if (print.config.complete_objects.value) { | ||||
|         // Print objects from the smallest to the tallest to avoid collisions
 | ||||
|         // when moving onto next object starting point.
 | ||||
|         std::vector<PrintObject*> objects(print.objects); | ||||
|         std::vector<PrintObject*> objects(printable_objects); | ||||
|         std::sort(objects.begin(), objects.end(), [](const PrintObject* po1, const PrintObject* po2) { return po1->size.z < po2->size.z; });         | ||||
|         size_t finished_objects = 0; | ||||
|         for (size_t object_id = initial_print_object_id; object_id < objects.size(); ++ object_id) { | ||||
|  | @ -788,7 +792,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) | |||
|         PrintObjectPtrs printable_objects = print.get_printable_objects(); | ||||
|         for (PrintObject *object : printable_objects) | ||||
|             object_reference_points.push_back(object->_shifted_copies.front()); | ||||
|             Slic3r::Geometry::chained_path(object_reference_points, object_indices); | ||||
|         Slic3r::Geometry::chained_path(object_reference_points, object_indices); | ||||
|         // Sort layers by Z.
 | ||||
|         // All extrusion moves with the same top layer height are extruded uninterrupted.
 | ||||
|         std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print = collect_layers_to_print(print); | ||||
|  |  | |||
|  | @ -451,10 +451,9 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int | |||
|         return volume_to_wipe;      // Soluble filament cannot be wiped in a random infill, neither the filament after it
 | ||||
| 
 | ||||
|     // we will sort objects so that dedicated for wiping are at the beginning:
 | ||||
|     PrintObjectPtrs object_list = print.objects; | ||||
|     PrintObjectPtrs object_list = print.get_printable_objects(); | ||||
|     std::sort(object_list.begin(), object_list.end(), [](const PrintObject* a, const PrintObject* b) { return a->config.wipe_into_objects; }); | ||||
| 
 | ||||
| 
 | ||||
|     // We will now iterate through
 | ||||
|     //  - first the dedicated objects to mark perimeters or infills (depending on infill_first)
 | ||||
|     //  - second through the dedicated ones again to mark infills or perimeters (depending on infill_first)
 | ||||
|  | @ -548,7 +547,8 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) | |||
|     unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config); | ||||
|     unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config); | ||||
| 
 | ||||
|     for (const PrintObject* object : print.objects) { | ||||
|     PrintObjectPtrs printable_objects = print.get_printable_objects(); | ||||
|     for (const PrintObject* object : printable_objects) { | ||||
|         // Finds this layer:
 | ||||
|         auto this_layer_it = std::find_if(object->layers.begin(), object->layers.end(), [<](const Layer* lay) { return std::abs(lt.print_z - lay->print_z)<EPSILON; }); | ||||
|         if (this_layer_it == object->layers.end()) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Enrico Turri
						Enrico Turri