mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-13 09:47:58 -06:00
ENH: use spiral lift only when it is needed
If a travel path goes through an overhang expolygons, and their distance is shorter than threshold, lift type will be set to SpiralLift. Signed-off-by: yifan.wu <yifan.wu@bambulab.com> Change-Id: I345788711755dd8611ecf385818e6052cd8abe9e
This commit is contained in:
parent
47a46010bd
commit
5d9bb61f8e
11 changed files with 199 additions and 17 deletions
|
@ -885,6 +885,9 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
||||||
{
|
{
|
||||||
PROFILE_CLEAR();
|
PROFILE_CLEAR();
|
||||||
|
|
||||||
|
// BBS
|
||||||
|
m_curr_print = print;
|
||||||
|
|
||||||
CNumericLocalesSetter locales_setter;
|
CNumericLocalesSetter locales_setter;
|
||||||
|
|
||||||
// Does the file exist? If so, we hope that it is still valid.
|
// Does the file exist? If so, we hope that it is still valid.
|
||||||
|
@ -3655,7 +3658,8 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
|
||||||
Polyline travel { this->last_pos(), point };
|
Polyline travel { this->last_pos(), point };
|
||||||
|
|
||||||
// check whether a straight travel move would need retraction
|
// check whether a straight travel move would need retraction
|
||||||
bool needs_retraction = this->needs_retraction(travel, role);
|
LiftType lift_type = LiftType::SpiralLift;
|
||||||
|
bool needs_retraction = this->needs_retraction(travel, role, lift_type);
|
||||||
// check whether wipe could be disabled without causing visible stringing
|
// check whether wipe could be disabled without causing visible stringing
|
||||||
bool could_be_wipe_disabled = false;
|
bool could_be_wipe_disabled = false;
|
||||||
// Save state of use_external_mp_once for the case that will be needed to call twice m_avoid_crossing_perimeters.travel_to.
|
// Save state of use_external_mp_once for the case that will be needed to call twice m_avoid_crossing_perimeters.travel_to.
|
||||||
|
@ -3670,10 +3674,15 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
|
||||||
&& m_writer.is_current_position_clear()) {
|
&& m_writer.is_current_position_clear()) {
|
||||||
travel = m_avoid_crossing_perimeters.travel_to(*this, point, &could_be_wipe_disabled);
|
travel = m_avoid_crossing_perimeters.travel_to(*this, point, &could_be_wipe_disabled);
|
||||||
// check again whether the new travel path still needs a retraction
|
// check again whether the new travel path still needs a retraction
|
||||||
needs_retraction = this->needs_retraction(travel, role);
|
needs_retraction = this->needs_retraction(travel, role, lift_type);
|
||||||
//if (needs_retraction && m_layer_index > 1) exit(0);
|
//if (needs_retraction && m_layer_index > 1) exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lift_type == LiftType::LazyLift)
|
||||||
|
printf("lazy lift\n");
|
||||||
|
else if (lift_type == LiftType::SpiralLift)
|
||||||
|
printf("spiral lift\n");
|
||||||
|
|
||||||
// Re-allow reduce_crossing_wall for the next travel moves
|
// Re-allow reduce_crossing_wall for the next travel moves
|
||||||
m_avoid_crossing_perimeters.reset_once_modifiers();
|
m_avoid_crossing_perimeters.reset_once_modifiers();
|
||||||
|
|
||||||
|
@ -3684,7 +3693,7 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
|
||||||
m_wipe.reset_path();
|
m_wipe.reset_path();
|
||||||
|
|
||||||
Point last_post_before_retract = this->last_pos();
|
Point last_post_before_retract = this->last_pos();
|
||||||
gcode += this->retract();
|
gcode += this->retract(false, false, lift_type);
|
||||||
// When "Wipe while retracting" is enabled, then extruder moves to another position, and travel from this position can cross perimeters.
|
// When "Wipe while retracting" is enabled, then extruder moves to another position, and travel from this position can cross perimeters.
|
||||||
// Because of it, it is necessary to call avoid crossing perimeters again with new starting point after calling retraction()
|
// Because of it, it is necessary to call avoid crossing perimeters again with new starting point after calling retraction()
|
||||||
// FIXME Lukas H.: Try to predict if this second calling of avoid crossing perimeters will be needed or not. It could save computations.
|
// FIXME Lukas H.: Try to predict if this second calling of avoid crossing perimeters will be needed or not. It could save computations.
|
||||||
|
@ -3719,35 +3728,100 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string
|
||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role)
|
bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftType& lift_type)
|
||||||
{
|
{
|
||||||
if (travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel))) {
|
if (travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel))) {
|
||||||
// skip retraction if the move is shorter than the configured threshold
|
// skip retraction if the move is shorter than the configured threshold
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto is_through_overhang = [this](const Polyline& travel) {
|
||||||
|
const float protect_z_scaled = scale_(0.4);
|
||||||
|
std::pair<float, float> z_range;
|
||||||
|
z_range.second = m_layer ? m_layer->print_z : 0.f;
|
||||||
|
z_range.first = std::max(0.f, z_range.second - protect_z_scaled);
|
||||||
|
for (auto object : m_curr_print->objects()) {
|
||||||
|
BoundingBox obj_bbox = object->bounding_box();
|
||||||
|
BoundingBox travel_bbox = get_extents(travel);
|
||||||
|
obj_bbox.offset(scale_(EPSILON));
|
||||||
|
if (!obj_bbox.overlap(travel_bbox))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto layer : object->layers()) {
|
||||||
|
if (layer->print_z < z_range.first)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (layer->print_z > z_range.second + EPSILON)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (ExPolygon& overhang : layer->loverhangs) {
|
||||||
|
if (overhang.contains(travel))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto to_lift_type = [](ZHopType z_hop_type) {
|
||||||
|
if (z_hop_type == ZHopType::zhtNormal)
|
||||||
|
return LiftType::NormalLift;
|
||||||
|
|
||||||
|
if (z_hop_type == ZHopType::zhtSlope)
|
||||||
|
return LiftType::LazyLift;
|
||||||
|
|
||||||
|
if (z_hop_type == ZHopType::zhtSpiral)
|
||||||
|
return LiftType::SpiralLift;
|
||||||
|
|
||||||
|
// if no corresponding lift type, use normal lift
|
||||||
|
return LiftType::NormalLift;
|
||||||
|
};
|
||||||
|
|
||||||
|
float max_z_hop = 0.f;
|
||||||
|
for (int i = 0; i < m_config.z_hop.size(); i++)
|
||||||
|
max_z_hop = std::max(max_z_hop, (float)m_config.z_hop.get_at(i));
|
||||||
|
float travel_len_thresh = max_z_hop / tan(GCodeWriter::slope_threshold);
|
||||||
|
float accum_len = 0.f;
|
||||||
|
Polyline clipped_travel;
|
||||||
|
for (auto line : travel.lines()) {
|
||||||
|
if (accum_len + line.length() > travel_len_thresh + EPSILON) {
|
||||||
|
Point end_pnt = line.a + line.normal() * (travel_len_thresh - accum_len);
|
||||||
|
clipped_travel.append(Polyline(line.a, end_pnt));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clipped_travel.append(Polyline(line.a, line.b));
|
||||||
|
accum_len += line.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//BBS: force to retract when leave from external perimeter for a long travel
|
//BBS: force to retract when leave from external perimeter for a long travel
|
||||||
//Better way is judging whether the travel move direction is same with last extrusion move.
|
//Better way is judging whether the travel move direction is same with last extrusion move.
|
||||||
if (is_perimeter(m_last_processor_extrusion_role) && m_last_processor_extrusion_role != erPerimeter)
|
if (is_perimeter(m_last_processor_extrusion_role) && m_last_processor_extrusion_role != erPerimeter) {
|
||||||
|
if (m_config.z_hop_type == ZHopType::zhtAuto) {
|
||||||
|
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lift_type = to_lift_type(m_config.z_hop_type);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (role == erSupportMaterial || role == erSupportTransition) {
|
if (role == erSupportMaterial || role == erSupportTransition) {
|
||||||
const SupportLayer* support_layer = dynamic_cast<const SupportLayer*>(m_layer);
|
const SupportLayer* support_layer = dynamic_cast<const SupportLayer*>(m_layer);
|
||||||
|
|
||||||
//FIXME support_layer->support_islands.contains should use some search structure!
|
//FIXME support_layer->support_islands.contains should use some search structure!
|
||||||
if (support_layer != NULL && support_layer->support_islands.contains(travel))
|
if (support_layer != NULL && support_layer->support_islands.contains(travel))
|
||||||
// skip retraction if this is a travel move inside a support material island
|
// skip retraction if this is a travel move inside a support material island
|
||||||
//FIXME not retracting over a long path may cause oozing, which in turn may result in missing material
|
//FIXME not retracting over a long path may cause oozing, which in turn may result in missing material
|
||||||
// at the end of the extrusion path!
|
// at the end of the extrusion path!
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//reduce the retractions in lightning infills for tree support
|
//reduce the retractions in lightning infills for tree support
|
||||||
if (support_layer != NULL && support_layer->support_type==stInnerTree)
|
if (support_layer != NULL && support_layer->support_type==stInnerTree)
|
||||||
for (auto &area : support_layer->base_areas)
|
for (auto &area : support_layer->base_areas)
|
||||||
if (area.contains(travel))
|
if (area.contains(travel))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//BBS: need retract when long moving to print perimeter to avoid dropping of material
|
//BBS: need retract when long moving to print perimeter to avoid dropping of material
|
||||||
if (!is_perimeter(role) && m_config.reduce_infill_retraction && m_layer != nullptr &&
|
if (!is_perimeter(role) && m_config.reduce_infill_retraction && m_layer != nullptr &&
|
||||||
m_config.sparse_infill_density.value > 0 && m_layer->any_internal_region_slice_contains(travel))
|
m_config.sparse_infill_density.value > 0 && m_layer->any_internal_region_slice_contains(travel))
|
||||||
|
@ -3757,10 +3831,16 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// retract if reduce_infill_retraction is disabled or doesn't apply when role is perimeter
|
// retract if reduce_infill_retraction is disabled or doesn't apply when role is perimeter
|
||||||
|
if (m_config.z_hop_type == ZHopType::zhtAuto) {
|
||||||
|
lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lift_type = to_lift_type(m_config.z_hop_type);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GCode::retract(bool toolchange, bool is_last_retraction)
|
std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType lift_type)
|
||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
|
|
||||||
|
@ -3784,7 +3864,7 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction)
|
||||||
if (m_writer.extruder()->retraction_length() > 0) {
|
if (m_writer.extruder()->retraction_length() > 0) {
|
||||||
// BBS: don't do lazy_lift when enable spiral vase
|
// BBS: don't do lazy_lift when enable spiral vase
|
||||||
size_t extruder_id = m_writer.extruder()->id();
|
size_t extruder_id = m_writer.extruder()->id();
|
||||||
gcode += m_writer.lift(!m_spiral_vase ? LiftType::SpiralLift : LiftType::NormalLift);
|
gcode += m_writer.lift(!m_spiral_vase ? lift_type : LiftType::NormalLift);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gcode;
|
return gcode;
|
||||||
|
|
|
@ -395,8 +395,9 @@ private:
|
||||||
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
|
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
|
||||||
|
|
||||||
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
||||||
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
|
// BBS: detect lift type in needs_retraction
|
||||||
std::string retract(bool toolchange = false, bool is_last_retraction = false);
|
bool needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type);
|
||||||
|
std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::SpiralLift);
|
||||||
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
||||||
std::string set_extruder(unsigned int extruder_id, double print_z);
|
std::string set_extruder(unsigned int extruder_id, double print_z);
|
||||||
std::set<ObjectID> m_objsWithBrim; // indicates the objs with brim
|
std::set<ObjectID> m_objsWithBrim; // indicates the objs with brim
|
||||||
|
@ -477,6 +478,7 @@ private:
|
||||||
GCodeProcessor m_processor;
|
GCodeProcessor m_processor;
|
||||||
|
|
||||||
// BBS
|
// BBS
|
||||||
|
Print* m_curr_print = nullptr;
|
||||||
unsigned int m_toolchange_count;
|
unsigned int m_toolchange_count;
|
||||||
coordf_t m_nominal_z;
|
coordf_t m_nominal_z;
|
||||||
bool m_need_change_layer_lift_z = false;
|
bool m_need_change_layer_lift_z = false;
|
||||||
|
|
|
@ -93,6 +93,8 @@ public:
|
||||||
bool is_current_position_clear() const { return m_is_current_pos_clear; };
|
bool is_current_position_clear() const { return m_is_current_pos_clear; };
|
||||||
//BBS:
|
//BBS:
|
||||||
static const bool full_gcode_comment;
|
static const bool full_gcode_comment;
|
||||||
|
//Radian threshold of slope for lazy lift and spiral lift;
|
||||||
|
static const double slope_threshold;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Extruders are sorted by their ID, so that binary search is possible.
|
// Extruders are sorted by their ID, so that binary search is possible.
|
||||||
|
@ -121,9 +123,6 @@ private:
|
||||||
double m_x_offset{ 0 };
|
double m_x_offset{ 0 };
|
||||||
double m_y_offset{ 0 };
|
double m_y_offset{ 0 };
|
||||||
|
|
||||||
//Radian threshold of slope for lazy lift and spiral lift;
|
|
||||||
static const double slope_threshold;
|
|
||||||
|
|
||||||
std::string _travel_to_z(double z, const std::string &comment);
|
std::string _travel_to_z(double z, const std::string &comment);
|
||||||
std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment);
|
std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment);
|
||||||
std::string _retract(double length, double restart_extra, const std::string &comment);
|
std::string _retract(double length, double restart_extra, const std::string &comment);
|
||||||
|
|
|
@ -143,6 +143,9 @@ public:
|
||||||
ExPolygons lslices;
|
ExPolygons lslices;
|
||||||
std::vector<BoundingBox> lslices_bboxes;
|
std::vector<BoundingBox> lslices_bboxes;
|
||||||
|
|
||||||
|
// BBS
|
||||||
|
ExPolygons loverhangs;
|
||||||
|
|
||||||
size_t region_count() const { return m_regions.size(); }
|
size_t region_count() const { return m_regions.size(); }
|
||||||
const LayerRegion* get_region(int idx) const { return m_regions[idx]; }
|
const LayerRegion* get_region(int idx) const { return m_regions[idx]; }
|
||||||
LayerRegion* get_region(int idx) { return m_regions[idx]; }
|
LayerRegion* get_region(int idx) { return m_regions[idx]; }
|
||||||
|
|
|
@ -789,7 +789,7 @@ static std::vector<std::string> s_Preset_printer_options {
|
||||||
"silent_mode",
|
"silent_mode",
|
||||||
// BBS
|
// BBS
|
||||||
"scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode", "template_custom_gcode",
|
"scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode", "template_custom_gcode",
|
||||||
"nozzle_type", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine",
|
"nozzle_type", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_type",
|
||||||
//SoftFever
|
//SoftFever
|
||||||
"host_type", "print_host", "printhost_apikey",
|
"host_type", "print_host", "printhost_apikey",
|
||||||
"printhost_cafile","printhost_port","printhost_authorization_type",
|
"printhost_cafile","printhost_port","printhost_authorization_type",
|
||||||
|
|
|
@ -224,6 +224,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||||
osteps.emplace_back(posSimplifyPath);
|
osteps.emplace_back(posSimplifyPath);
|
||||||
osteps.emplace_back(posSimplifySupportPath);
|
osteps.emplace_back(posSimplifySupportPath);
|
||||||
steps.emplace_back(psSkirtBrim);
|
steps.emplace_back(psSkirtBrim);
|
||||||
|
}
|
||||||
|
else if (opt_key == "z_hop_type") {
|
||||||
|
osteps.emplace_back(posDetectOverhangsForLift);
|
||||||
} else {
|
} else {
|
||||||
// for legacy, if we can't handle this option let's invalidate all steps
|
// for legacy, if we can't handle this option let's invalidate all steps
|
||||||
//FIXME invalidate all steps of all objects as well?
|
//FIXME invalidate all steps of all objects as well?
|
||||||
|
@ -1631,6 +1634,17 @@ void Print::process(bool use_cache)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BBS
|
||||||
|
for (PrintObject* obj : m_objects) {
|
||||||
|
if (need_slicing_objects.count(obj) != 0) {
|
||||||
|
obj->detect_overhangs_for_lift();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (obj->set_started(posDetectOverhangsForLift))
|
||||||
|
obj->set_done(posDetectOverhangsForLift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info();
|
BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,10 @@ enum PrintStep {
|
||||||
|
|
||||||
enum PrintObjectStep {
|
enum PrintObjectStep {
|
||||||
posSlice, posPerimeters, posPrepareInfill,
|
posSlice, posPerimeters, posPrepareInfill,
|
||||||
posInfill, posIroning, posSupportMaterial, posSimplifyPath, posSimplifySupportPath, posCount,
|
posInfill, posIroning, posSupportMaterial, posSimplifyPath, posSimplifySupportPath,
|
||||||
|
// BBS
|
||||||
|
posDetectOverhangsForLift,
|
||||||
|
posCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
// A PrintRegion object represents a group of volumes to print
|
// A PrintRegion object represents a group of volumes to print
|
||||||
|
@ -445,6 +448,10 @@ private:
|
||||||
void slice_volumes();
|
void slice_volumes();
|
||||||
//BBS
|
//BBS
|
||||||
ExPolygons _shrink_contour_holes(double contour_delta, double hole_delta, const ExPolygons& polys) const;
|
ExPolygons _shrink_contour_holes(double contour_delta, double hole_delta, const ExPolygons& polys) const;
|
||||||
|
// BBS
|
||||||
|
void detect_overhangs_for_lift();
|
||||||
|
void clear_overhangs_for_lift();
|
||||||
|
|
||||||
// Has any support (not counting the raft).
|
// Has any support (not counting the raft).
|
||||||
void detect_surfaces_type();
|
void detect_surfaces_type();
|
||||||
void process_external_surfaces();
|
void process_external_surfaces();
|
||||||
|
|
|
@ -292,6 +292,14 @@ static t_config_enum_values s_keys_map_PerimeterGeneratorType{
|
||||||
};
|
};
|
||||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType)
|
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType)
|
||||||
|
|
||||||
|
static const t_config_enum_values s_keys_map_ZHopType = {
|
||||||
|
{ "Auto Lift", zhtAuto },
|
||||||
|
{ "Normal Lift", zhtNormal },
|
||||||
|
{ "Slope Lift", zhtSlope },
|
||||||
|
{ "Spiral Lift", zhtSpiral }
|
||||||
|
};
|
||||||
|
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ZHopType)
|
||||||
|
|
||||||
static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology)
|
static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology)
|
||||||
{
|
{
|
||||||
for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options)
|
for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options)
|
||||||
|
@ -2127,6 +2135,21 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->mode = comSimple;
|
def->mode = comSimple;
|
||||||
def->set_default_value(new ConfigOptionFloats { 0.4 });
|
def->set_default_value(new ConfigOptionFloats { 0.4 });
|
||||||
|
|
||||||
|
def = this->add("z_hop_type", coEnum);
|
||||||
|
def->label = L("Z Hop Type");
|
||||||
|
def->tooltip = L("");
|
||||||
|
def->enum_keys_map = &ConfigOptionEnum<ZHopType>::get_enum_values();
|
||||||
|
def->enum_values.push_back("auto");
|
||||||
|
def->enum_values.push_back("normal");
|
||||||
|
def->enum_values.push_back("slope");
|
||||||
|
def->enum_values.push_back("spiral");
|
||||||
|
def->enum_labels.push_back(L("Auto"));
|
||||||
|
def->enum_labels.push_back(L("Normal"));
|
||||||
|
def->enum_labels.push_back(L("Slope"));
|
||||||
|
def->enum_labels.push_back(L("Spiral"));
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionEnum{ ZHopType::zhtSpiral });
|
||||||
|
|
||||||
def = this->add("retract_restart_extra", coFloats);
|
def = this->add("retract_restart_extra", coFloats);
|
||||||
//def->label = L("Extra length on restart");
|
//def->label = L("Extra length on restart");
|
||||||
def->label = "Extra length on restart";
|
def->label = "Extra length on restart";
|
||||||
|
|
|
@ -200,6 +200,15 @@ enum NozzleType {
|
||||||
ntCount
|
ntCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// BBS
|
||||||
|
enum ZHopType {
|
||||||
|
zhtAuto = 0,
|
||||||
|
zhtNormal,
|
||||||
|
zhtSlope,
|
||||||
|
zhtSpiral,
|
||||||
|
zhtCount
|
||||||
|
};
|
||||||
|
|
||||||
static std::string bed_type_to_gcode_string(const BedType type)
|
static std::string bed_type_to_gcode_string(const BedType type)
|
||||||
{
|
{
|
||||||
std::string type_str;
|
std::string type_str;
|
||||||
|
@ -812,6 +821,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||||
((ConfigOptionFloats, retraction_length))
|
((ConfigOptionFloats, retraction_length))
|
||||||
((ConfigOptionFloats, retract_length_toolchange))
|
((ConfigOptionFloats, retract_length_toolchange))
|
||||||
((ConfigOptionFloats, z_hop))
|
((ConfigOptionFloats, z_hop))
|
||||||
|
// BBS
|
||||||
|
((ConfigOptionEnum<ZHopType>, z_hop_type))
|
||||||
((ConfigOptionFloats, retract_restart_extra))
|
((ConfigOptionFloats, retract_restart_extra))
|
||||||
((ConfigOptionFloats, retract_restart_extra_toolchange))
|
((ConfigOptionFloats, retract_restart_extra_toolchange))
|
||||||
((ConfigOptionFloats, retraction_speed))
|
((ConfigOptionFloats, retraction_speed))
|
||||||
|
|
|
@ -409,6 +409,48 @@ void PrintObject::ironing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BBS
|
||||||
|
void PrintObject::clear_overhangs_for_lift()
|
||||||
|
{
|
||||||
|
if (!m_shared_object) {
|
||||||
|
for (Layer* l : m_layers)
|
||||||
|
l->loverhangs.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const float g_min_overhang_percent_for_lift = 0.3f;
|
||||||
|
|
||||||
|
void PrintObject::detect_overhangs_for_lift()
|
||||||
|
{
|
||||||
|
if (this->set_started(posDetectOverhangsForLift)) {
|
||||||
|
const float min_overlap = m_config.line_width * g_min_overhang_percent_for_lift;
|
||||||
|
size_t num_layers = this->layer_count();
|
||||||
|
size_t num_raft_layers = m_slicing_params.raft_layers();
|
||||||
|
|
||||||
|
m_print->set_status(78, L("Detect overhangs for auto-lift"));
|
||||||
|
|
||||||
|
this->clear_overhangs_for_lift();
|
||||||
|
|
||||||
|
if (m_print->config().z_hop_type != ZHopType::zhtAuto)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tbb::spin_mutex layer_storage_mutex;
|
||||||
|
tbb::parallel_for(tbb::blocked_range<size_t>(num_raft_layers + 1, num_layers),
|
||||||
|
[this, min_overlap](const tbb::blocked_range<size_t>& range)
|
||||||
|
{
|
||||||
|
for (size_t layer_id = range.begin(); layer_id < range.end(); ++layer_id) {
|
||||||
|
Layer& layer = *m_layers[layer_id];
|
||||||
|
Layer& lower_layer = *layer.lower_layer;
|
||||||
|
|
||||||
|
ExPolygons overhangs = diff_ex(layer.lslices, offset_ex(lower_layer.lslices, scale_(min_overlap)));
|
||||||
|
layer.loverhangs = std::move(offset2_ex(overhangs, -0.1f * scale_(m_config.line_width), 0.1f * scale_(m_config.line_width)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this->set_done(posDetectOverhangsForLift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PrintObject::generate_support_material()
|
void PrintObject::generate_support_material()
|
||||||
{
|
{
|
||||||
if (this->set_started(posSupportMaterial)) {
|
if (this->set_started(posSupportMaterial)) {
|
||||||
|
|
|
@ -3319,6 +3319,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
|
||||||
optgroup = page->new_optgroup(L("Retraction"), L"param_retraction");
|
optgroup = page->new_optgroup(L("Retraction"), L"param_retraction");
|
||||||
optgroup->append_single_option_line("retraction_length", "", extruder_idx);
|
optgroup->append_single_option_line("retraction_length", "", extruder_idx);
|
||||||
optgroup->append_single_option_line("z_hop", "", extruder_idx);
|
optgroup->append_single_option_line("z_hop", "", extruder_idx);
|
||||||
|
optgroup->append_single_option_line("z_hop_type", "");
|
||||||
optgroup->append_single_option_line("retraction_speed", "", extruder_idx);
|
optgroup->append_single_option_line("retraction_speed", "", extruder_idx);
|
||||||
optgroup->append_single_option_line("deretraction_speed", "", extruder_idx);
|
optgroup->append_single_option_line("deretraction_speed", "", extruder_idx);
|
||||||
//optgroup->append_single_option_line("retract_restart_extra", "", extruder_idx);
|
//optgroup->append_single_option_line("retract_restart_extra", "", extruder_idx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue