FDM backend refactoring: Return PrintRegion by reference, not by pointer.

Added PrintRegion hashing.
This commit is contained in:
Vojtech Bubnik 2021-05-05 18:13:58 +02:00
parent b8db1922f7
commit ee15f00574
11 changed files with 71 additions and 62 deletions

View File

@ -122,10 +122,10 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
if (surface.surface_type == stInternalVoid)
has_internal_voids = true;
else {
const PrintRegionConfig &region_config = layerm.region()->config();
const PrintRegionConfig &region_config = layerm.region().config();
FlowRole extrusion_role = surface.is_top() ? frTopSolidInfill : (surface.is_solid() ? frSolidInfill : frInfill);
bool is_bridge = layer.id() > 0 && surface.is_bridge();
params.extruder = layerm.region()->extruder(extrusion_role);
params.extruder = layerm.region().extruder(extrusion_role);
params.pattern = region_config.fill_pattern.value;
params.density = float(region_config.fill_density);
@ -162,7 +162,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
} else {
// Internal infill. Calculating infill line spacing independent of the current layer height and 1st layer status,
// so that internall infill will be aligned over all layers of the current region.
params.spacing = layerm.region()->flow(*layer.object(), frInfill, layer.object()->config().layer_height, false).spacing();
params.spacing = layerm.region().flow(*layer.object(), frInfill, layer.object()->config().layer_height, false).spacing();
// Anchor a sparse infill to inner perimeters with the following anchor length:
params.anchor_length = float(region_config.infill_anchor);
if (region_config.infill_anchor.percent)
@ -274,11 +274,11 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
}
if (internal_solid_fill == nullptr) {
// Produce another solid fill.
params.extruder = layerm.region()->extruder(frSolidInfill);
params.pattern = layerm.region()->config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
params.extruder = layerm.region().extruder(frSolidInfill);
params.pattern = layerm.region().config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
params.density = 100.f;
params.extrusion_role = erInternalInfill;
params.angle = float(Geometry::deg2rad(layerm.region()->config().fill_angle.value));
params.angle = float(Geometry::deg2rad(layerm.region().config().fill_angle.value));
// calculate the actual flow we'll be using for this infill
params.flow = layerm.flow(frSolidInfill);
params.spacing = params.flow.spacing();
@ -501,7 +501,7 @@ void Layer::make_ironing()
for (LayerRegion *layerm : m_regions)
if (! layerm->slices.empty()) {
IroningParams ironing_params;
const PrintRegionConfig &config = layerm->region()->config();
const PrintRegionConfig &config = layerm->region().config();
if (config.ironing &&
(config.ironing_type == IroningType::AllSolid ||
(config.top_solid_layers > 0 &&
@ -556,7 +556,7 @@ void Layer::make_ironing()
Polygons infills;
for (size_t k = i; k < j; ++ k) {
const IroningParams &ironing_params = by_extruder[k];
const PrintRegionConfig &region_config = ironing_params.layerm->region()->config();
const PrintRegionConfig &region_config = ironing_params.layerm->region().config();
bool iron_everything = region_config.ironing_type == IroningType::AllSolid;
bool iron_completely = iron_everything;
if (iron_everything) {

View File

@ -1113,7 +1113,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
assert(! print.config().first_layer_height.percent);
const double first_layer_height = print.config().first_layer_height.value;
for (size_t region_id = 0; region_id < print.num_print_regions(); ++ region_id) {
const PrintRegion &region = *print.get_print_region(region_id);
const PrintRegion &region = print.get_print_region(region_id);
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frExternalPerimeter, layer_height).width());
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, layer_height).width());
_write_format(file, "; infill extrusion width = %.2fmm\n", region.flow(*first_object, frInfill, layer_height).width());
@ -1936,7 +1936,7 @@ void GCode::process_layer(
bool enable = (layer.id() > 0 || !print.has_brim()) && (layer.id() >= (size_t)print.config().skirt_height.value && ! print.has_infinite_skirt());
if (enable) {
for (const LayerRegion *layer_region : layer.regions())
if (size_t(layer_region->region()->config().bottom_solid_layers.value) > layer.id() ||
if (size_t(layer_region->region().config().bottom_solid_layers.value) > layer.id() ||
layer_region->perimeters.items_count() > 1u ||
layer_region->fills.items_count() > 0) {
enable = false;
@ -2110,7 +2110,7 @@ void GCode::process_layer(
const LayerRegion *layerm = layer.regions()[region_id];
if (layerm == nullptr)
continue;
const PrintRegion &region = *layerm->region();
const PrintRegion &region = layerm->region();
// Now we must process perimeters and infills and create islands of extrusions in by_region std::map.
// It is also necessary to save which extrusions are part of MM wiping and which are not.
@ -2571,7 +2571,7 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector<Obje
std::string gcode;
for (const ObjectByExtruder::Island::Region &region : by_region)
if (! region.perimeters.empty()) {
m_config.apply(print.get_print_region(&region - &by_region.front())->config());
m_config.apply(print.get_print_region(&region - &by_region.front()).config());
for (const ExtrusionEntity *ee : region.perimeters)
gcode += this->extrude_entity(*ee, "perimeter", -1., &lower_layer_edge_grid);
}
@ -2592,7 +2592,7 @@ std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectBy
if ((ee->role() == erIroning) == ironing)
extrusions.emplace_back(ee);
if (! extrusions.empty()) {
m_config.apply(print.get_print_region(&region - &by_region.front())->config());
m_config.apply(print.get_print_region(&region - &by_region.front()).config());
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
for (const ExtrusionEntity *fill : extrusions) {
auto *eec = dynamic_cast<const ExtrusionEntityCollection*>(fill);

View File

@ -227,7 +227,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr;
if (layerm == nullptr)
continue;
const PrintRegion &region = *layerm->region();
const PrintRegion &region = layerm->region();
if (! layerm->perimeters.entities.empty()) {
bool something_nonoverriddable = true;

View File

@ -102,7 +102,7 @@ ExPolygons Layer::merged(float offset_scaled) const
}
Polygons polygons;
for (LayerRegion *layerm : m_regions) {
const PrintRegionConfig &config = layerm->region()->config();
const PrintRegionConfig &config = layerm->region().config();
// Our users learned to bend Slic3r to produce empty volumes to act as subtracters. Only add the region if it is non-empty.
if (config.bottom_solid_layers > 0 || config.top_solid_layers > 0 || config.fill_density > 0. || config.perimeters > 0)
append(polygons, offset(layerm->slices.surfaces, offset_scaled));
@ -134,7 +134,7 @@ void Layer::make_perimeters()
continue;
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << ", region " << region_id;
done[region_id] = true;
const PrintRegionConfig &config = (*layerm)->region()->config();
const PrintRegionConfig &config = (*layerm)->region().config();
// find compatible regions
LayerRegionPtrs layerms;
@ -142,7 +142,7 @@ void Layer::make_perimeters()
for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it)
if (! (*it)->slices.empty()) {
LayerRegion* other_layerm = *it;
const PrintRegionConfig &other_config = other_layerm->region()->config();
const PrintRegionConfig &other_config = other_layerm->region().config();
if (config.perimeter_extruder == other_config.perimeter_extruder
&& config.perimeters == other_config.perimeters
&& config.perimeter_speed == other_config.perimeter_speed
@ -180,7 +180,7 @@ void Layer::make_perimeters()
for (LayerRegion *layerm : layerms) {
for (Surface &surface : layerm->slices.surfaces)
slices[surface.extra_perimeters].emplace_back(surface);
if (layerm->region()->config().fill_density > layerm_config->region()->config().fill_density)
if (layerm->region().config().fill_density > layerm_config->region().config().fill_density)
layerm_config = layerm;
}
// merge the surfaces assigned to each group

View File

@ -22,8 +22,8 @@ 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; }
PrintRegion& region() { return *m_region; }
const PrintRegion& region() const { return *m_region; }
// collection of surfaces generated by slicing the original geometry
// divided by type top/bottom/internal
@ -126,7 +126,7 @@ public:
std::vector<BoundingBox> lslices_bboxes;
size_t region_count() const { return m_regions.size(); }
const LayerRegion* get_region(int idx) const { return m_regions.at(idx); }
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);
const LayerRegionPtrs& regions() const { return m_regions; }

View File

@ -27,7 +27,7 @@ Flow LayerRegion::flow(FlowRole role, double layer_height) const
Flow LayerRegion::bridging_flow(FlowRole role) const
{
const PrintRegion &region = *this->region();
const PrintRegion &region = this->region();
const PrintRegionConfig &region_config = region.config();
const PrintObject &print_object = *this->layer()->object();
if (print_object.config().thick_bridges) {
@ -70,7 +70,7 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
this->thin_fills.clear();
const PrintConfig &print_config = this->layer()->object()->print()->config();
const PrintRegionConfig &region_config = this->region()->config();
const PrintRegionConfig &region_config = this->region().config();
// This needs to be in sync with PrintObject::_slice() slicing_mode_normal_below_layer!
bool spiral_vase = print_config.spiral_vase &&
//FIXME account for raft layers.
@ -111,7 +111,7 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered)
{
const bool has_infill = this->region()->config().fill_density.value > 0.;
const bool has_infill = this->region().config().fill_density.value > 0.;
const float margin = float(scale_(EXTERNAL_INFILL_MARGIN));
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
@ -285,7 +285,7 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
#ifdef SLIC3R_DEBUG
printf("Processing bridge at layer %zu:\n", this->layer()->id());
#endif
double custom_angle = Geometry::deg2rad(this->region()->config().bridge_angle.value);
double custom_angle = Geometry::deg2rad(this->region().config().bridge_angle.value);
if (bd.detect_angle(custom_angle)) {
bridges[idx_last].bridge_angle = bd.angle;
if (this->layer()->object()->has_support()) {
@ -384,21 +384,21 @@ void LayerRegion::prepare_fill_surfaces()
bool spiral_vase = this->layer()->object()->print()->config().spiral_vase;
// if no solid layers are requested, turn top/bottom surfaces to internal
if (! spiral_vase && this->region()->config().top_solid_layers == 0) {
if (! spiral_vase && this->region().config().top_solid_layers == 0) {
for (Surface &surface : this->fill_surfaces.surfaces)
if (surface.is_top())
surface.surface_type = this->layer()->object()->config().infill_only_where_needed ? stInternalVoid : stInternal;
}
if (this->region()->config().bottom_solid_layers == 0) {
if (this->region().config().bottom_solid_layers == 0) {
for (Surface &surface : this->fill_surfaces.surfaces)
if (surface.is_bottom()) // (surface.surface_type == stBottom)
surface.surface_type = stInternal;
}
// turn too small internal regions into solid regions according to the user setting
if (! spiral_vase && this->region()->config().fill_density.value > 0) {
if (! spiral_vase && this->region().config().fill_density.value > 0) {
// scaling an area requires two calls!
double min_area = scale_(scale_(this->region()->config().solid_infill_below_area.value));
double min_area = scale_(scale_(this->region().config().solid_infill_below_area.value));
for (Surface &surface : this->fill_surfaces.surfaces)
if (surface.surface_type == stInternal && surface.area() <= min_area)
surface.surface_type = stInternalSolid;

View File

@ -275,8 +275,8 @@ std::vector<unsigned int> Print::object_extruders() const
std::vector<unsigned int> extruders;
extruders.reserve(m_print_regions.size() * m_objects.size() * 3);
for (const PrintObject *object : m_objects)
for (const auto *region : object->all_regions())
region->collect_object_printing_extruders(*this, extruders);
for (const PrintRegion &region : object->all_regions())
region.collect_object_printing_extruders(*this, extruders);
sort_remove_duplicates(extruders);
return extruders;
}
@ -661,8 +661,8 @@ std::string Print::validate(std::string* warning) const
if ((object->has_support() || object->has_raft()) && ! validate_extrusion_width(object->config(), "support_material_extrusion_width", layer_height, err_msg))
return err_msg;
for (const char *opt_key : { "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width" })
for (const PrintRegion *region : object->all_regions())
if (! validate_extrusion_width(region->config(), opt_key, layer_height, err_msg))
for (const PrintRegion &region : object->all_regions())
if (! validate_extrusion_width(region.config(), opt_key, layer_height, err_msg))
return err_msg;
}
}

View File

@ -15,6 +15,9 @@
#include "libslic3r.h"
#include <functional>
#include <set>
namespace Slic3r {
class Print;
@ -59,12 +62,13 @@ class PrintRegion
{
public:
PrintRegion() : m_refcnt(0) {}
PrintRegion(const PrintRegionConfig &config) : m_refcnt(0), m_config(config) {}
PrintRegion(const PrintRegionConfig &config) : m_refcnt(0), m_config(config), m_config_hash(config.hash()) {}
~PrintRegion() = default;
// Methods NOT modifying the PrintRegion's state:
public:
const PrintRegionConfig& config() const { return m_config; }
const PrintRegionConfig& config() const throw() { return m_config; }
size_t config_hash() const throw() { return m_config_hash; }
// 1-based extruder identifier for this region and role.
unsigned int extruder(FlowRole role) const;
Flow flow(const PrintObject &object, FlowRole role, double layer_height, bool first_layer = false) const;
@ -79,10 +83,10 @@ public:
// Methods modifying the PrintRegion's state:
public:
void set_config(const PrintRegionConfig &config) { m_config = config; }
void set_config(PrintRegionConfig &&config) { m_config = std::move(config); }
void set_config(const PrintRegionConfig &config) { m_config = config; m_config_hash = m_config.hash(); }
void set_config(PrintRegionConfig &&config) { m_config = std::move(config); m_config_hash = m_config.hash(); }
void config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false)
{ this->m_config.apply_only(other, keys, ignore_nonexistent); }
{ m_config.apply_only(other, keys, ignore_nonexistent); m_config_hash = m_config.hash(); }
protected:
friend Print;
@ -90,8 +94,12 @@ protected:
private:
PrintRegionConfig m_config;
size_t m_config_hash;
};
inline bool operator==(const PrintRegion &lhs, const PrintRegion &rhs) { return lhs.config_hash() == rhs.config_hash() && lhs.config() == rhs.config(); }
inline bool operator!=(const PrintRegion &lhs, const PrintRegion &rhs) { return ! (lhs == rhs); }
template<typename T>
class ConstVectorOfPtrsAdaptor {
public:
@ -219,7 +227,7 @@ public:
size_t num_printing_regions() const throw() { return m_region_volumes.size(); }
const PrintRegion& printing_region(size_t idx) const throw();
//FIXME returing all possible regions before slicing, thus some of the regions may not be slicing at the end.
std::vector<const PrintRegion*> all_regions() const;
std::vector<std::reference_wrapper<const PrintRegion>> all_regions() const;
bool has_support() const { return m_config.support_material || m_config.support_material_enforce_layers > 0; }
bool has_raft() const { return m_config.raft_layers > 0; }
@ -295,6 +303,7 @@ private:
// This is the adjustment of the the Object's coordinate system towards PrintObject's coordinate system.
Point m_center_offset;
std::set<PrintRegion> m_map_regions;
// vector of (layer height ranges and vectors of volume ids), indexed by region_id
std::vector<std::vector<std::pair<t_layer_height_range, int>>> m_region_volumes;
@ -504,12 +513,12 @@ public:
// Accessed by SupportMaterial
size_t num_print_regions() const throw() { return m_print_regions.size(); }
const PrintRegion* get_print_region(size_t idx) const { return m_print_regions[idx]; }
const PrintRegion& get_print_region(size_t idx) const { return *m_print_regions[idx]; }
const ToolOrdering& get_tool_ordering() const { return m_wipe_tower_data.tool_ordering; } // #ys_FIXME just for testing
protected:
// methods for handling regions
PrintRegion* get_print_region(size_t idx) { return m_print_regions[idx]; }
PrintRegion& get_print_region(size_t idx) { return *m_print_regions[idx]; }
PrintRegion* add_print_region();
PrintRegion* add_print_region(const PrintRegionConfig &config);

View File

@ -99,12 +99,12 @@ PrintBase::ApplyStatus PrintObject::set_instances(PrintInstances &&instances)
const PrintRegion& PrintObject::printing_region(size_t idx) const throw()
{
return *m_print->get_print_region(idx);
return m_print->get_print_region(idx);
}
std::vector<const PrintRegion*> PrintObject::all_regions() const
std::vector<std::reference_wrapper<const PrintRegion>> PrintObject::all_regions() const
{
std::vector<const PrintRegion*> out;
std::vector<std::reference_wrapper<const PrintRegion>> out;
out.reserve(m_region_volumes.size());
for (size_t i = 0; i < m_region_volumes.size(); ++ i)
if (! m_region_volumes[i].empty())
@ -1010,7 +1010,7 @@ void PrintObject::process_external_surfaces()
m_print->throw_if_canceled();
Polygons voids;
for (const LayerRegion *layerm : m_layers[layer_idx]->regions()) {
if (layerm->region()->config().fill_density.value == 0.)
if (layerm->region().config().fill_density.value == 0.)
for (const Surface &surface : layerm->fill_surfaces.surfaces)
// Shrink the holes, let the layer above expand slightly inside the unsupported areas.
polygons_append(voids, offset(surface.expolygon, unsupported_width));
@ -1120,7 +1120,7 @@ void PrintObject::discover_vertical_shells()
unsigned int perimeters = 0;
for (Surface &s : layerm.slices.surfaces)
perimeters = std::max<unsigned int>(perimeters, s.extra_perimeters);
perimeters += layerm.region()->config().perimeters.value;
perimeters += layerm.region().config().perimeters.value;
// Then calculate the infill offset.
if (perimeters > 0) {
Flow extflow = layerm.flow(frExternalPerimeter);
@ -1216,7 +1216,7 @@ void PrintObject::discover_vertical_shells()
Layer *layer = m_layers[idx_layer];
LayerRegion *layerm = layer->m_regions[idx_region];
const PrintRegionConfig &region_config = layerm->region()->config();
const PrintRegionConfig &region_config = layerm->region().config();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
layerm->export_region_slices_to_svg_debug("4_discover_vertical_shells-initial");
@ -1680,8 +1680,8 @@ std::vector<unsigned int> PrintObject::object_extruders() const
{
std::vector<unsigned int> extruders;
extruders.reserve(this->all_regions().size() * 3);
for (const PrintRegion *region : this->all_regions())
region->collect_object_printing_extruders(*this->print(), extruders);
for (const PrintRegion &region : this->all_regions())
region.collect_object_printing_extruders(*this->print(), extruders);
sort_remove_duplicates(extruders);
return extruders;
}
@ -1750,7 +1750,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
}
// Make sure all layers contain layer region objects for all regions.
for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id)
layer->add_region(this->print()->get_print_region(region_id));
layer->add_region(&this->print()->get_print_region(region_id));
prev = layer;
}
}
@ -1799,7 +1799,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
if (spiral_vase) {
// Slice the bottom layers with SlicingMode::Regular.
// This needs to be in sync with LayerRegion::make_perimeters() spiral_vase!
const PrintRegionConfig &config = this->print()->get_print_region(region_id)->config();
const PrintRegionConfig &config = this->print()->get_print_region(region_id).config();
slicing_mode_normal_below_layer = size_t(config.bottom_solid_layers.value);
for (; slicing_mode_normal_below_layer < slice_zs.size() && slice_zs[slicing_mode_normal_below_layer] < config.bottom_solid_min_thickness - EPSILON;
++ slicing_mode_normal_below_layer);
@ -2462,7 +2462,7 @@ void PrintObject::clip_fill_surfaces()
upper_internal = intersection(overhangs, lower_layer_internal_surfaces);
// Apply new internal infill to regions.
for (LayerRegion *layerm : lower_layer->m_regions) {
if (layerm->region()->config().fill_density.value == 0)
if (layerm->region().config().fill_density.value == 0)
continue;
SurfaceType internal_surface_types[] = { stInternal, stInternalVoid };
Polygons internal;
@ -2492,7 +2492,7 @@ void PrintObject::discover_horizontal_shells()
m_print->throw_if_canceled();
Layer *layer = m_layers[i];
LayerRegion *layerm = layer->regions()[region_id];
const PrintRegionConfig &region_config = layerm->region()->config();
const PrintRegionConfig &region_config = layerm->region().config();
if (region_config.solid_infill_every_layers.value > 0 && region_config.fill_density.value > 0 &&
(i % region_config.solid_infill_every_layers) == 0) {
// Insert a solid internal layer. Mark stInternal surfaces as stInternalSolid or stInternalBridge.

View File

@ -1251,7 +1251,7 @@ namespace SupportMaterialInternal {
// Surface supporting this layer, expanded by 0.5 * nozzle_diameter, as we consider this kind of overhang to be sufficiently supported.
Polygons lower_grown_slices = offset(lower_layer_polygons,
//FIXME to mimic the decision in the perimeter generator, we should use half the external perimeter width.
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm->region()->config().perimeter_extruder-1))),
0.5f * float(scale_(print_config.nozzle_diameter.get_at(layerm->region().config().perimeter_extruder-1))),
SUPPORT_SURFACES_OFFSET_PARAMETERS);
// Collect perimeters of this layer.
//FIXME split_at_first_point() could split a bridge mid-way
@ -1637,7 +1637,7 @@ static inline std::pair<PrintObjectSupportMaterial::MyLayer*, PrintObjectSupport
if (object_config.thick_bridges && SupportMaterialInternal::has_bridging_extrusions(layer)) {
coordf_t bridging_height = 0.;
for (const LayerRegion* region : layer.regions())
bridging_height += region->region()->bridging_height_avg(print_config);
bridging_height += region->region().bridging_height_avg(print_config);
bridging_height /= coordf_t(layer.regions().size());
coordf_t bridging_print_z = layer.print_z - bridging_height - slicing_params.gap_support_object;
if (bridging_print_z >= slicing_params.first_print_layer_height - EPSILON) {
@ -2764,13 +2764,13 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
const Layer &object_layer = *object.layers()[i];
bool some_region_overlaps = false;
for (LayerRegion *region : object_layer.regions()) {
coordf_t bridging_height = region->region()->bridging_height_avg(*this->m_print_config);
coordf_t bridging_height = region->region().bridging_height_avg(*this->m_print_config);
if (object_layer.print_z - bridging_height > support_layer.print_z + gap_extra_above - EPSILON)
break;
some_region_overlaps = true;
polygons_append(polygons_trimming,
offset(region->fill_surfaces.filter_by_type(stBottomBridge), gap_xy_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS));
if (region->region()->config().overhangs.value)
if (region->region().config().overhangs.value)
// Add bridging perimeters.
SupportMaterialInternal::collect_bridging_perimeter_areas(region->perimeters, gap_xy_scaled, polygons_trimming);
}

View File

@ -5935,7 +5935,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
{
if (layerm->slices.surfaces.empty())
continue;
const PrintRegionConfig& cfg = layerm->region()->config();
const PrintRegionConfig& cfg = layerm->region().config();
if (cfg.perimeter_extruder.value == m_selected_extruder ||
cfg.infill_extruder.value == m_selected_extruder ||
cfg.solid_infill_extruder.value == m_selected_extruder ) {
@ -5958,7 +5958,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
for (const LayerRegion *layerm : layer->regions()) {
if (is_selected_separate_extruder)
{
const PrintRegionConfig& cfg = layerm->region()->config();
const PrintRegionConfig& cfg = layerm->region().config();
if (cfg.perimeter_extruder.value != m_selected_extruder ||
cfg.infill_extruder.value != m_selected_extruder ||
cfg.solid_infill_extruder.value != m_selected_extruder)
@ -5966,7 +5966,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
}
if (ctxt.has_perimeters)
_3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
volume(idx_layer, layerm->region()->config().perimeter_extruder.value, 0));
volume(idx_layer, layerm->region().config().perimeter_extruder.value, 0));
if (ctxt.has_infill) {
for (const ExtrusionEntity *ee : layerm->fills.entities) {
// fill represents infill extrusions of a single island.
@ -5975,8 +5975,8 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
_3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
volume(idx_layer,
is_solid_infill(fill->entities.front()->role()) ?
layerm->region()->config().solid_infill_extruder :
layerm->region()->config().infill_extruder,
layerm->region().config().solid_infill_extruder :
layerm->region().config().infill_extruder,
1));
}
}