Fixed crash when generating gcode of multimaterial objects with some object out of the bed

This commit is contained in:
Enrico Turri 2018-07-23 15:58:08 +02:00
parent 1c6d3c9c69
commit cac4b29153
2 changed files with 27 additions and 23 deletions

View File

@ -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 &copy : 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);

View File

@ -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(), [&lt](const Layer* lay) { return std::abs(lt.print_z - lay->print_z)<EPSILON; });
if (this_layer_it == object->layers.end())