FDM backend refactoring for const correctness, clarity ...

This commit is contained in:
Vojtech Bubnik 2021-05-06 15:08:57 +02:00
parent b5573f959b
commit dd72016159
5 changed files with 57 additions and 63 deletions

View File

@ -223,10 +223,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
layer_tools.extruder_override = extruder_override;
// What extruders are required to print this object layer?
for (size_t region_id = 0; region_id < object.num_printing_regions(); ++ region_id) {
const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr;
if (layerm == nullptr)
continue;
for (const LayerRegion *layerm : layer->regions()) {
const PrintRegion &region = layerm->region();
if (! layerm->perimeters.entities.empty()) {
@ -688,16 +685,14 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
// iterate through copies (aka PrintObject instances) first, so that we mark neighbouring infills to minimize travel moves
for (unsigned int copy = 0; copy < num_of_copies; ++copy) {
for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) {
const PrintRegion &region = object->printing_region(region_id);
for (const LayerRegion *layerm : this_layer->regions()) {
const auto &region = layerm->region();
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
continue;
bool wipe_into_infill_only = ! object->config().wipe_into_objects && region.config().wipe_into_infill;
if (print.config().infill_first != perimeters_done || wipe_into_infill_only) {
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections
for (const ExtrusionEntity* ee : layerm->fills.entities) { // iterate through all infill Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (!is_overriddable(*fill, print.config(), *object, region))
@ -721,7 +716,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
// Now the same for perimeters - see comments above for explanation:
if (object->config().wipe_into_objects && print.config().infill_first == perimeters_done)
{
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) {
for (const ExtrusionEntity* ee : layerm->perimeters.entities) {
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume) {
set_extruder_override(fill, copy, new_extruder, num_of_copies);
@ -762,13 +757,12 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
size_t num_of_copies = object->instances().size();
for (size_t copy = 0; copy < num_of_copies; ++copy) { // iterate through copies first, so that we mark neighbouring infills to minimize travel moves
for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) {
const auto& region = object->printing_region(region_id);
for (const LayerRegion *layerm : this_layer->regions()) {
const auto &region = layerm->region();
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
continue;
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections
for (const ExtrusionEntity* ee : layerm->fills.entities) { // iterate through all infill Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (!is_overriddable(*fill, print.config(), *object, region)
@ -791,7 +785,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
}
// Now the same for perimeters - see comments above for explanation:
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) { // iterate through all perimeter Collections
for (const ExtrusionEntity* ee : layerm->perimeters.entities) { // iterate through all perimeter Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, copy))
set_extruder_override(fill, copy, (print.config().infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies);

View File

@ -27,7 +27,7 @@ bool Layer::empty() const
return true;
}
LayerRegion* Layer::add_region(PrintRegion* print_region)
LayerRegion* Layer::add_region(const PrintRegion *print_region)
{
m_regions.emplace_back(new LayerRegion(this, print_region));
return m_regions.back();

View File

@ -22,7 +22,6 @@ class LayerRegion
public:
Layer* layer() { return m_layer; }
const Layer* layer() const { return m_layer; }
PrintRegion& region() { return *m_region; }
const PrintRegion& region() const { return *m_region; }
// collection of surfaces generated by slicing the original geometry
@ -86,12 +85,12 @@ public:
protected:
friend class Layer;
LayerRegion(Layer *layer, PrintRegion *region) : m_layer(layer), m_region(region) {}
LayerRegion(Layer *layer, const PrintRegion *region) : m_layer(layer), m_region(region) {}
~LayerRegion() {}
private:
Layer *m_layer;
PrintRegion *m_region;
Layer *m_layer;
const PrintRegion *m_region;
};
@ -128,7 +127,7 @@ public:
size_t region_count() const { return m_regions.size(); }
const LayerRegion* get_region(int idx) const { return m_regions[idx]; }
LayerRegion* get_region(int idx) { return m_regions[idx]; }
LayerRegion* add_region(PrintRegion* print_region);
LayerRegion* add_region(const PrintRegion *print_region);
const LayerRegionPtrs& regions() const { return m_regions; }
// Test whether whether there are any slices assigned to this layer.
bool empty() const;

View File

@ -413,10 +413,12 @@ static inline bool sequential_print_vertical_clearance_valid(const Print &print)
// Precondition: Print::validate() requires the Print::apply() to be called its invocation.
std::string Print::validate(std::string* warning) const
{
std::vector<unsigned int> extruders = this->extruders();
if (m_objects.empty())
return L("All objects are outside of the print volume.");
if (extruders().empty())
if (extruders.empty())
return L("The supplied settings will cause an empty print.");
if (m_config.complete_objects) {
@ -442,9 +444,9 @@ std::string Print::validate(std::string* warning) const
if (this->has_wipe_tower() && ! m_objects.empty()) {
// Make sure all extruders use same diameter filament and have the same nozzle diameter
// EPSILON comparison is used for nozzles and 10 % tolerance is used for filaments
double first_nozzle_diam = m_config.nozzle_diameter.get_at(extruders().front());
double first_filament_diam = m_config.filament_diameter.get_at(extruders().front());
for (const auto& extruder_idx : extruders()) {
double first_nozzle_diam = m_config.nozzle_diameter.get_at(extruders.front());
double first_filament_diam = m_config.filament_diameter.get_at(extruders.front());
for (const auto& extruder_idx : extruders) {
double nozzle_diam = m_config.nozzle_diameter.get_at(extruder_idx);
double filament_diam = m_config.filament_diameter.get_at(extruder_idx);
if (nozzle_diam - EPSILON > first_nozzle_diam || nozzle_diam + EPSILON < first_nozzle_diam
@ -462,7 +464,7 @@ std::string Print::validate(std::string* warning) const
return L("Ooze prevention is currently not supported with the wipe tower enabled.");
if (m_config.use_volumetric_e)
return L("The Wipe Tower currently does not support volumetric E (use_volumetric_e=0).");
if (m_config.complete_objects && extruders().size() > 1)
if (m_config.complete_objects && extruders.size() > 1)
return L("The Wipe Tower is currently not supported for multimaterial sequential prints.");
if (m_objects.size() > 1) {
@ -542,8 +544,6 @@ std::string Print::validate(std::string* warning) const
}
{
std::vector<unsigned int> extruders = this->extruders();
// Find the smallest used nozzle diameter and the number of unique nozzle diameters.
double min_nozzle_diameter = std::numeric_limits<double>::max();
double max_nozzle_diameter = 0;

View File

@ -772,11 +772,11 @@ void PrintObject::detect_surfaces_type()
bool interface_shells = ! spiral_vase && m_config.interface_shells.value;
size_t num_layers = spiral_vase ? std::min(size_t(this->printing_region(0).config().bottom_solid_layers), m_layers.size()) : m_layers.size();
for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++ idx_region) {
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start";
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << region_id << " in parallel - start";
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
for (Layer *layer : m_layers)
layer->m_regions[idx_region]->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial");
layer->m_regions[region_id]->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
// If interface shells are allowed, the region->surfaces cannot be overwritten as they may be used by other threads.
@ -792,7 +792,7 @@ void PrintObject::detect_surfaces_type()
((num_layers > 1) ? num_layers - 1 : num_layers) :
// In non-spiral vase mode, go over all layers.
m_layers.size()),
[this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
[this, region_id, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
// If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating
// the support from the print.
SurfaceType surface_type_bottom_other =
@ -800,9 +800,9 @@ void PrintObject::detect_surfaces_type()
stBottom : stBottomBridge;
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
m_print->throw_if_canceled();
// BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << idx_region << " and layer " << layer->print_z;
// BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << region_id << " and layer " << layer->print_z;
Layer *layer = m_layers[idx_layer];
LayerRegion *layerm = layer->m_regions[idx_region];
LayerRegion *layerm = layer->m_regions[region_id];
// comparison happens against the *full* slices (considering all regions)
// unless internal shells are requested
Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? m_layers[idx_layer + 1] : nullptr;
@ -815,7 +815,7 @@ void PrintObject::detect_surfaces_type()
Surfaces top;
if (upper_layer) {
ExPolygons upper_slices = interface_shells ?
diff_ex(layerm->slices.surfaces, upper_layer->m_regions[idx_region]->slices.surfaces, ApplySafetyOffset::Yes) :
diff_ex(layerm->slices.surfaces, upper_layer->m_regions[region_id]->slices.surfaces, ApplySafetyOffset::Yes) :
diff_ex(layerm->slices.surfaces, upper_layer->lslices, ApplySafetyOffset::Yes);
surfaces_append(top, offset2_ex(upper_slices, -offset, offset), stTop);
} else {
@ -832,7 +832,7 @@ void PrintObject::detect_surfaces_type()
#if 0
//FIXME Why is this branch failing t\multi.t ?
Polygons lower_slices = interface_shells ?
to_polygons(lower_layer->get_region(idx_region)->slices.surfaces) :
to_polygons(lower_layer->get_region(region_id)->slices.surfaces) :
to_polygons(lower_layer->slices);
surfaces_append(bottom,
offset2_ex(diff(layerm->slices.surfaces, lower_slices, true), -offset, offset),
@ -855,7 +855,7 @@ void PrintObject::detect_surfaces_type()
offset2_ex(
diff_ex(
intersection(layerm->slices.surfaces, lower_layer->lslices), // supported
lower_layer->m_regions[idx_region]->slices.surfaces,
lower_layer->m_regions[region_id]->slices.surfaces,
ApplySafetyOffset::Yes),
-offset, offset),
stBottom);
@ -888,7 +888,7 @@ void PrintObject::detect_surfaces_type()
expolygons_with_attributes.emplace_back(std::make_pair(union_ex(top), SVG::ExPolygonAttributes("green")));
expolygons_with_attributes.emplace_back(std::make_pair(union_ex(bottom), SVG::ExPolygonAttributes("brown")));
expolygons_with_attributes.emplace_back(std::make_pair(to_expolygons(layerm->slices.surfaces), SVG::ExPolygonAttributes("black")));
SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, idx_region, layer->print_z).c_str(), expolygons_with_attributes);
SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, region_id, layer->print_z).c_str(), expolygons_with_attributes);
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
@ -925,25 +925,25 @@ void PrintObject::detect_surfaces_type()
if (interface_shells) {
// Move surfaces_new to layerm->slices.surfaces
for (size_t idx_layer = 0; idx_layer < num_layers; ++ idx_layer)
m_layers[idx_layer]->m_regions[idx_region]->slices.surfaces = std::move(surfaces_new[idx_layer]);
m_layers[idx_layer]->m_regions[region_id]->slices.surfaces = std::move(surfaces_new[idx_layer]);
}
if (spiral_vase) {
if (num_layers > 1)
// Turn the last bottom layer infill to a top infill, so it will be extruded with a proper pattern.
m_layers[num_layers - 1]->m_regions[idx_region]->slices.set_type(stTop);
m_layers[num_layers - 1]->m_regions[region_id]->slices.set_type(stTop);
for (size_t i = num_layers; i < m_layers.size(); ++ i)
m_layers[i]->m_regions[idx_region]->slices.set_type(stInternal);
m_layers[i]->m_regions[region_id]->slices.set_type(stInternal);
}
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " - clipping in parallel - start";
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << region_id << " - clipping in parallel - start";
// Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces.
tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_layers.size()),
[this, idx_region](const tbb::blocked_range<size_t>& range) {
[this, region_id](const tbb::blocked_range<size_t>& range) {
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
m_print->throw_if_canceled();
LayerRegion *layerm = m_layers[idx_layer]->m_regions[idx_region];
LayerRegion *layerm = m_layers[idx_layer]->m_regions[region_id];
layerm->slices_to_fill_surfaces_clipped();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
layerm->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-final");
@ -951,7 +951,7 @@ void PrintObject::detect_surfaces_type()
} // for each layer of a region
});
m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " - clipping in parallel - end";
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << region_id << " - clipping in parallel - end";
} // for each this->print->region_count
// Mark the object to have the region slices classified (typed, which also means they are split based on whether they are supported, bridging, top layers etc.)
@ -1071,8 +1071,8 @@ void PrintObject::discover_vertical_shells()
// is calculated over all materials.
// Is the "ensure vertical wall thickness" applicable to any region?
bool has_extra_layers = false;
for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++idx_region) {
const PrintRegionConfig &config = this->printing_region(idx_region).config();
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++region_id) {
const PrintRegionConfig &config = this->printing_region(region_id).config();
if (config.ensure_vertical_shell_thickness.value && has_extra_layers_fn(config)) {
has_extra_layers = true;
break;
@ -1100,8 +1100,8 @@ void PrintObject::discover_vertical_shells()
static size_t debug_idx = 0;
++ debug_idx;
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
for (size_t idx_region = 0; idx_region < num_regions; ++ idx_region) {
LayerRegion &layerm = *layer.m_regions[idx_region];
for (size_t region_id = 0; region_id < num_regions; ++ region_id) {
LayerRegion &layerm = *layer.m_regions[region_id];
float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f;
// Top surfaces.
append(cache.top_surfaces, offset(layerm.slices.filter_by_type(stTop), min_perimeter_infill_spacing));
@ -1149,10 +1149,10 @@ void PrintObject::discover_vertical_shells()
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - end : cache top / bottom";
}
for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++ idx_region) {
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
PROFILE_BLOCK(discover_vertical_shells_region);
const PrintRegion &region = this->printing_region(idx_region);
const PrintRegion &region = this->printing_region(region_id);
if (! region.config().ensure_vertical_shell_thickness.value)
// This region will be handled by discover_horizontal_shells().
continue;
@ -1166,15 +1166,15 @@ void PrintObject::discover_vertical_shells()
if (! top_bottom_surfaces_all_regions) {
// This is either a single material print, or a multi-material print and interface_shells are enabled, meaning that the vertical shell thickness
// is calculated over a single material.
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - start : cache top / bottom";
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << region_id << " in parallel - start : cache top / bottom";
tbb::parallel_for(
tbb::blocked_range<size_t>(0, num_layers, grain_size),
[this, idx_region, &cache_top_botom_regions](const tbb::blocked_range<size_t>& range) {
[this, region_id, &cache_top_botom_regions](const tbb::blocked_range<size_t>& range) {
const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge };
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
m_print->throw_if_canceled();
Layer &layer = *m_layers[idx_layer];
LayerRegion &layerm = *layer.m_regions[idx_region];
LayerRegion &layerm = *layer.m_regions[region_id];
float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f;
// Top surfaces.
auto &cache = cache_top_botom_regions[idx_layer];
@ -1183,21 +1183,21 @@ void PrintObject::discover_vertical_shells()
// Bottom surfaces.
cache.bottom_surfaces = offset(layerm.slices.filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing);
append(cache.bottom_surfaces, offset(layerm.fill_surfaces.filter_by_types(surfaces_bottom, 2), min_perimeter_infill_spacing));
// Holes over all regions. Only collect them once, they are valid for all idx_region iterations.
// Holes over all regions. Only collect them once, they are valid for all region_id iterations.
if (cache.holes.empty()) {
for (size_t idx_region = 0; idx_region < layer.regions().size(); ++ idx_region)
polygons_append(cache.holes, to_polygons(layer.regions()[idx_region]->fill_expolygons));
for (size_t region_id = 0; region_id < layer.regions().size(); ++ region_id)
polygons_append(cache.holes, to_polygons(layer.regions()[region_id]->fill_expolygons));
}
}
});
m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - end : cache top / bottom";
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << region_id << " in parallel - end : cache top / bottom";
}
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - start : ensure vertical wall thickness";
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << region_id << " in parallel - start : ensure vertical wall thickness";
tbb::parallel_for(
tbb::blocked_range<size_t>(0, num_layers, grain_size),
[this, idx_region, &cache_top_botom_regions]
[this, region_id, &cache_top_botom_regions]
(const tbb::blocked_range<size_t>& range) {
// printf("discover_vertical_shells from %d to %d\n", range.begin(), range.end());
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
@ -1209,7 +1209,7 @@ void PrintObject::discover_vertical_shells()
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
Layer *layer = m_layers[idx_layer];
LayerRegion *layerm = layer->m_regions[idx_region];
LayerRegion *layerm = layer->m_regions[region_id];
const PrintRegionConfig &region_config = layerm->region().config();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
@ -1424,11 +1424,11 @@ void PrintObject::discover_vertical_shells()
} // for each layer
});
m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - end";
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << region_id << " in parallel - end";
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++idx_layer) {
LayerRegion *layerm = m_layers[idx_layer]->get_region(idx_region);
LayerRegion *layerm = m_layers[idx_layer]->get_region(region_id);
layerm->export_region_slices_to_svg_debug("4_discover_vertical_shells-final");
layerm->export_region_fill_surfaces_to_svg_debug("4_discover_vertical_shells-final");
}
@ -1663,6 +1663,7 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full
object_extruders);
}
sort_remove_duplicates(object_extruders);
//FIXME add painting extruders
if (object_max_z <= 0.f)
object_max_z = (float)model_object.raw_bounding_box().size().z();