FIX: error overhang on auto circle compensation

Jira: none

Signed-off-by: qing.zhang <qing.zhang@bambulab.com>
Change-Id: I8281f617cc4dde848d4dd795fe9afc7b2b8c72ce
This commit is contained in:
qing.zhang 2025-02-13 17:12:34 +08:00 committed by lane.wei
parent 93d0c59ed0
commit d69fce58cb
6 changed files with 28 additions and 18 deletions

View File

@ -35,6 +35,12 @@ LayerRegion* Layer::add_region(const PrintRegion *print_region)
m_regions.emplace_back(new LayerRegion(this, print_region)); m_regions.emplace_back(new LayerRegion(this, print_region));
return m_regions.back(); return m_regions.back();
} }
void Layer::apply_auto_circle_compensation()
{
for (LayerRegion *layerm : m_regions) {
layerm->auto_circle_compensation(layerm->slices, this->object()->get_auto_circle_compenstaion_params(), scale_(this->object()->config().circle_compensation_manual_offset));
}
}
// merge all regions' slices to get islands // merge all regions' slices to get islands
void Layer::make_slices() void Layer::make_slices()
@ -141,7 +147,7 @@ ExPolygons Layer::merged(float offset_scaled) const
// Here the perimeters are created cummulatively for all layer regions sharing the same parameters influencing the perimeters. // Here the perimeters are created cummulatively for all layer regions sharing the same parameters influencing the perimeters.
// The perimeter paths and the thin fills (ExtrusionEntityCollection) are assigned to the first compatible layer region. // The perimeter paths and the thin fills (ExtrusionEntityCollection) are assigned to the first compatible layer region.
// The resulting fill surface is split back among the originating regions. // The resulting fill surface is split back among the originating regions.
void Layer::make_perimeters(const AutoContourHolesCompensationParams &auto_contour_holes_compensation_params) void Layer::make_perimeters()
{ {
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id(); BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id();
// keep track of regions whose perimeters we have already generated // keep track of regions whose perimeters we have already generated
@ -196,11 +202,6 @@ void Layer::make_perimeters(const AutoContourHolesCompensationParams &auto_conto
if (layerms.size() == 1) { // optimization if (layerms.size() == 1) { // optimization
(*layerm)->fill_surfaces.surfaces.clear(); (*layerm)->fill_surfaces.surfaces.clear();
if (this->object()->config().enable_circle_compensation) {
SurfaceCollection copy_slices = (*layerm)->slices;
(*layerm)->auto_circle_compensation(copy_slices, auto_contour_holes_compensation_params, scale_(this->object()->config().circle_compensation_manual_offset));
(*layerm)->make_perimeters(copy_slices, &(*layerm)->fill_surfaces, &(*layerm)->fill_no_overlap_expolygons, this->loop_nodes);
} else
(*layerm)->make_perimeters((*layerm)->slices, &(*layerm)->fill_surfaces, &(*layerm)->fill_no_overlap_expolygons, this->loop_nodes); (*layerm)->make_perimeters((*layerm)->slices, &(*layerm)->fill_surfaces, &(*layerm)->fill_no_overlap_expolygons, this->loop_nodes);
(*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces); (*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces);
@ -226,8 +227,6 @@ void Layer::make_perimeters(const AutoContourHolesCompensationParams &auto_conto
SurfaceCollection fill_surfaces; SurfaceCollection fill_surfaces;
//BBS //BBS
ExPolygons fill_no_overlap; ExPolygons fill_no_overlap;
if (this->object()->config().enable_circle_compensation)
layerm_config->auto_circle_compensation(new_slices, auto_contour_holes_compensation_params, scale_(this->object()->config().circle_compensation_manual_offset));
layerm_config->make_perimeters(new_slices, &fill_surfaces, &fill_no_overlap, this->loop_nodes); layerm_config->make_perimeters(new_slices, &fill_surfaces, &fill_no_overlap, this->loop_nodes);
// assign fill_surfaces to each layer // assign fill_surfaces to each layer

View File

@ -165,6 +165,7 @@ public:
const LayerRegionPtrs& regions() const { return m_regions; } const LayerRegionPtrs& regions() const { return m_regions; }
// Test whether whether there are any slices assigned to this layer. // Test whether whether there are any slices assigned to this layer.
bool empty() const; bool empty() const;
void apply_auto_circle_compensation();
void make_slices(); void make_slices();
// Backup and restore raw sliced regions if needed. // Backup and restore raw sliced regions if needed.
//FIXME Review whether not to simplify the code by keeping the raw_slices all the time. //FIXME Review whether not to simplify the code by keeping the raw_slices all the time.
@ -182,7 +183,7 @@ public:
for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_bottom_contains(item)) return true; for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_bottom_contains(item)) return true;
return false; return false;
} }
void make_perimeters(const AutoContourHolesCompensationParams &auto_contour_holes_compensation_params); void make_perimeters();
//BBS //BBS
void calculate_perimeter_continuity(std::vector<LoopNode> &prev_nodes); void calculate_perimeter_continuity(std::vector<LoopNode> &prev_nodes);
void recrod_cooling_node_for_each_extrusion(); void recrod_cooling_node_for_each_extrusion();

View File

@ -231,6 +231,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|| opt_key == "resolution" || opt_key == "resolution"
|| opt_key == "precise_z_height" || opt_key == "precise_z_height"
|| opt_key == "filament_shrink" || opt_key == "filament_shrink"
|| opt_key == "enable_circle_compensation"
|| opt_key == "circle_compensation_manual_offset"
// Spiral Vase forces different kind of slicing than the normal model: // Spiral Vase forces different kind of slicing than the normal model:
// In Spiral Vase mode, holes are closed and only the largest area contour is kept at each layer. // In Spiral Vase mode, holes are closed and only the largest area contour is kept at each layer.
// Therefore toggling the Spiral Vase on / off requires complete reslicing. // Therefore toggling the Spiral Vase on / off requires complete reslicing.
@ -1723,7 +1725,8 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
for (PrintObject* obj : m_objects) { for (PrintObject* obj : m_objects) {
if (need_slicing_objects.count(obj) != 0) { if (need_slicing_objects.count(obj) != 0) {
obj->make_perimeters(auto_contour_holes_compensation_params); obj->set_auto_circle_compenstaion_params(auto_contour_holes_compensation_params);
obj->make_perimeters();
} }
else { else {
if (obj->set_started(posSlice)) if (obj->set_started(posSlice))
@ -1819,7 +1822,7 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
obj->set_done(posDetectOverhangsForLift); obj->set_done(posDetectOverhangsForLift);
} }
else { else {
obj->make_perimeters(auto_contour_holes_compensation_params); obj->make_perimeters();
obj->infill(); obj->infill();
obj->ironing(); obj->ironing();
obj->generate_support_material(); obj->generate_support_material();

View File

@ -314,6 +314,9 @@ struct AutoContourHolesCompensationParams
circle_compensation_speed = config.circle_compensation_speed.values; circle_compensation_speed = config.circle_compensation_speed.values;
diameter_limit = config.diameter_limit.values; diameter_limit = config.diameter_limit.values;
} }
AutoContourHolesCompensationParams(){}
// BBS: params for auto contour and holes compensation // BBS: params for auto contour and holes compensation
std::vector<double> counter_speed_coef; std::vector<double> counter_speed_coef;
std::vector<double> counter_diameter_coef; std::vector<double> counter_diameter_coef;
@ -489,6 +492,9 @@ public:
size_t get_klipper_object_id() const { return m_klipper_object_id; } size_t get_klipper_object_id() const { return m_klipper_object_id; }
void set_klipper_object_id(size_t id) { m_klipper_object_id = id; } void set_klipper_object_id(size_t id) { m_klipper_object_id = id; }
void set_auto_circle_compenstaion_params(const AutoContourHolesCompensationParams &params){auto_contour_holes_compensation_params = params;};
AutoContourHolesCompensationParams get_auto_circle_compenstaion_params() { return auto_contour_holes_compensation_params; };
private: private:
// to be called from Print only. // to be called from Print only.
friend class Print; friend class Print;
@ -513,7 +519,7 @@ private:
static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders, std::vector<int>& variant_index); static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders, std::vector<int>& variant_index);
private: private:
void make_perimeters(const AutoContourHolesCompensationParams &auto_contour_holes_compensation_params); void make_perimeters();
void prepare_infill(); void prepare_infill();
void infill(); void infill();
void ironing(); void ironing();
@ -558,6 +564,7 @@ private:
Vec3crd m_size; Vec3crd m_size;
double m_max_z; double m_max_z;
PrintObjectConfig m_config; PrintObjectConfig m_config;
AutoContourHolesCompensationParams auto_contour_holes_compensation_params;
// Translation in Z + Rotation + Scaling / Mirroring. // Translation in Z + Rotation + Scaling / Mirroring.
Transform3d m_trafo = Transform3d::Identity(); Transform3d m_trafo = Transform3d::Identity();
// Slic3r::Point objects in scaled G-code coordinates // Slic3r::Point objects in scaled G-code coordinates

View File

@ -316,7 +316,7 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
// 1) Merges typed region slices into stInternal type. // 1) Merges typed region slices into stInternal type.
// 2) Increases an "extra perimeters" counter at region slices where needed. // 2) Increases an "extra perimeters" counter at region slices where needed.
// 3) Generates perimeters, gap fills and fill regions (fill regions of type stInternal). // 3) Generates perimeters, gap fills and fill regions (fill regions of type stInternal).
void PrintObject::make_perimeters(const AutoContourHolesCompensationParams &auto_contour_holes_compensation_params) void PrintObject::make_perimeters()
{ {
// prerequisites // prerequisites
this->slice(); this->slice();
@ -423,10 +423,10 @@ void PrintObject::make_perimeters(const AutoContourHolesCompensationParams &auto
BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - start"; BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - start";
tbb::parallel_for( tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_layers.size()), tbb::blocked_range<size_t>(0, m_layers.size()),
[this, auto_contour_holes_compensation_params](const tbb::blocked_range<size_t>& range) { [this](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
m_print->throw_if_canceled(); m_print->throw_if_canceled();
m_layers[layer_idx]->make_perimeters(auto_contour_holes_compensation_params); m_layers[layer_idx]->make_perimeters();
} }
} }
); );
@ -951,8 +951,6 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "initial_layer_line_width" || opt_key == "initial_layer_line_width"
|| opt_key == "inner_wall_line_width" || opt_key == "inner_wall_line_width"
|| opt_key == "infill_wall_overlap" || opt_key == "infill_wall_overlap"
|| opt_key == "enable_circle_compensation"
|| opt_key == "circle_compensation_manual_offset"
|| opt_key == "apply_scarf_seam_on_circles") { || opt_key == "apply_scarf_seam_on_circles") {
steps.emplace_back(posPerimeters); steps.emplace_back(posPerimeters);
} else if (opt_key == "gap_infill_speed" || opt_key == "filter_out_gap_fill") { } else if (opt_key == "gap_infill_speed" || opt_key == "filter_out_gap_fill") {

View File

@ -1188,6 +1188,8 @@ void PrintObject::slice_volumes()
} }
} }
// Merge all regions' slices to get islands, chain them by a shortest path. // Merge all regions' slices to get islands, chain them by a shortest path.
if (this->config().enable_circle_compensation)
layer->apply_auto_circle_compensation();
layer->make_slices(); layer->make_slices();
} }
}); });