mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-24 11:22:07 +00:00
Feature: Small perimeters speed for supports (#13459)
This commit is contained in:
@@ -96,12 +96,21 @@ inline bool is_solid_infill(ExtrusionRole role)
|
||||
|| role == erIroning;
|
||||
}
|
||||
|
||||
inline bool is_bridge(ExtrusionRole role) {
|
||||
inline bool is_bridge(ExtrusionRole role)
|
||||
{
|
||||
return role == erBridgeInfill
|
||||
|| role == erInternalBridgeInfill
|
||||
|| role == erOverhangPerimeter;
|
||||
}
|
||||
|
||||
// Orca
|
||||
inline bool is_support(ExtrusionRole role)
|
||||
{
|
||||
return role == erSupportMaterial
|
||||
|| role == erSupportMaterialInterface
|
||||
|| role == erSupportTransition;
|
||||
}
|
||||
|
||||
class ExtrusionEntity
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -5925,8 +5925,8 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref,
|
||||
|
||||
const auto speed_for_path = [&speed, &small_peri_speed](const ExtrusionPath& path) {
|
||||
// don't apply small perimeter setting for overhangs/bridges/non-perimeters
|
||||
const bool is_small_peri = is_perimeter(path.role()) && !is_bridge(path.role()) && small_peri_speed > 0;
|
||||
return is_small_peri ? small_peri_speed : speed;
|
||||
const bool is_small_small_perimeter = small_peri_speed > 0 && !is_bridge(path.role()) && is_perimeter(path.role());
|
||||
return is_small_small_perimeter ? small_peri_speed : speed;
|
||||
};
|
||||
|
||||
|
||||
@@ -5948,8 +5948,8 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref,
|
||||
// Orca: end of multipath average mm3_per_mm value calculation
|
||||
|
||||
if (!enable_seam_slope) {
|
||||
for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) {
|
||||
gcode += this->_extrude(*path, description, speed_for_path(*path));
|
||||
for (const ExtrusionPath& path : paths) {
|
||||
gcode += this->_extrude(path, description, speed_for_path(path));
|
||||
// Orca: Adaptive PA - dont adapt PA after the first multipath extrusion is completed
|
||||
// as we have already set the PA value to the average flow over the totality of the path
|
||||
// in the first extrude move
|
||||
@@ -5985,8 +5985,8 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref,
|
||||
new_loop.clip_slope(seam_gap);
|
||||
|
||||
// Then extrude it
|
||||
for (const auto& p : new_loop.get_all_paths()) {
|
||||
gcode += this->_extrude(*p, description, speed_for_path(*p));
|
||||
for (const ExtrusionPath* path : new_loop.get_all_paths()) {
|
||||
gcode += this->_extrude(*path, description, speed_for_path(*path));
|
||||
// Orca: Adaptive PA - dont adapt PA after the first pultipath extrusion is completed
|
||||
// as we have already set the PA value to the average flow over the totality of the path
|
||||
// in the first extrude move
|
||||
@@ -6142,7 +6142,7 @@ std::string GCode::extrude_path(const ExtrusionPath& path, const std::string& de
|
||||
std::string gcode = this->_extrude(path, description, speed);
|
||||
if (m_wipe.enable && FILAMENT_CONFIG(wipe)) {
|
||||
m_wipe.path = path.polyline.to_polyline();
|
||||
if (is_tree(this->config().support_type) && (path.role() == erSupportMaterial || path.role() == erSupportMaterialInterface || path.role() == erSupportTransition)) {
|
||||
if (is_tree(this->config().support_type) && is_support(path.role())) {
|
||||
if ((m_wipe.path.first_point() - m_wipe.path.last_point()).cast<double>().norm() > scale_(0.2)) {
|
||||
double min_dist = scale_(0.2);
|
||||
int i = 0;
|
||||
@@ -6210,13 +6210,30 @@ std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectBy
|
||||
|
||||
std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fills, const ExtrusionRole support_extrusion_role)
|
||||
{
|
||||
static constexpr const char *support_label = "support material";
|
||||
static constexpr const char *support_interface_label = "support material interface";
|
||||
static constexpr const char* support_label = "support material";
|
||||
static constexpr const char* support_interface_label = "support material interface";
|
||||
static constexpr const char* support_transition_label = "support transition";
|
||||
static constexpr const char* support_ironing_label = "support ironing";
|
||||
|
||||
static const auto speed_for_path = [&](double length, ExtrusionRole role, double default_speed = -1.0) {
|
||||
if (!is_support(role) || length > SMALL_PERIMETER_LENGTH(NOZZLE_CONFIG(small_support_perimeter_threshold)))
|
||||
return default_speed;
|
||||
|
||||
double small_perimeter_speed = -1.0;
|
||||
|
||||
const auto base_speed = (role == erSupportMaterialInterface)
|
||||
? NOZZLE_CONFIG(support_interface_speed) : NOZZLE_CONFIG(support_speed);
|
||||
|
||||
if (NOZZLE_CONFIG(small_support_perimeter_speed).value == 0)
|
||||
small_perimeter_speed = base_speed * 0.5;
|
||||
else
|
||||
small_perimeter_speed = NOZZLE_CONFIG(small_support_perimeter_speed).get_abs_value(base_speed);
|
||||
|
||||
return small_perimeter_speed > 0 ? small_perimeter_speed : default_speed;
|
||||
};
|
||||
|
||||
std::string gcode;
|
||||
if (! support_fills.entities.empty()) {
|
||||
if (!support_fills.entities.empty()) {
|
||||
|
||||
ExtrusionEntitiesPtr extrusions;
|
||||
extrusions.reserve(support_fills.entities.size());
|
||||
@@ -6233,28 +6250,27 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
|
||||
if (!support_fills.no_sort)
|
||||
chain_and_reorder_extrusion_entities(extrusions, m_last_pos.to_point());
|
||||
|
||||
//const double support_speed = m_config.support_speed.value;
|
||||
//const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
for (const ExtrusionEntity *ee : extrusions) {
|
||||
ExtrusionRole role = ee->role();
|
||||
assert(role == erSupportMaterial || role == erSupportMaterialInterface || role == erSupportTransition || role == erIroning);
|
||||
assert(is_support(role) || role == erIroning);
|
||||
|
||||
const char* label = (role == erSupportMaterial) ? support_label :
|
||||
((role == erSupportMaterialInterface) ? support_interface_label :
|
||||
((role == erIroning) ? support_ironing_label : support_transition_label));
|
||||
// BBS
|
||||
//const double speed = (role == erSupportMaterial) ? support_speed : support_interface_speed;
|
||||
const double speed = -1.0;
|
||||
|
||||
const ExtrusionPath* path = dynamic_cast<const ExtrusionPath*>(ee);
|
||||
const ExtrusionMultiPath* multipath = dynamic_cast<const ExtrusionMultiPath*>(ee);
|
||||
const ExtrusionLoop* loop = dynamic_cast<const ExtrusionLoop*>(ee);
|
||||
const ExtrusionEntityCollection* collection = dynamic_cast<const ExtrusionEntityCollection*>(ee);
|
||||
if (path)
|
||||
gcode += this->extrude_path(*path, label, speed);
|
||||
|
||||
if (path) {
|
||||
gcode += extrude_path(*path, label, speed_for_path(path->length(), role));
|
||||
}
|
||||
else if (multipath) {
|
||||
gcode += this->extrude_multi_path(*multipath, label, speed);
|
||||
gcode += extrude_multi_path(*multipath, label, speed_for_path(multipath->length(), role));
|
||||
}
|
||||
else if (loop) {
|
||||
gcode += this->extrude_loop(*loop, label, speed);
|
||||
gcode += extrude_loop(*loop, label, speed_for_path(loop->length(), role));
|
||||
}
|
||||
else if (collection) {
|
||||
gcode += extrude_support(*collection, support_extrusion_role);
|
||||
@@ -6574,12 +6590,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
speed = NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
} else if (path.role() == erGapFill) {
|
||||
speed = NOZZLE_CONFIG(gap_infill_speed);
|
||||
}
|
||||
else if (path.role() == erSupportMaterial ||
|
||||
path.role() == erSupportMaterialInterface) {
|
||||
const double support_speed = NOZZLE_CONFIG(support_speed);
|
||||
const double support_interface_speed = NOZZLE_CONFIG(support_interface_speed);
|
||||
speed = (path.role() == erSupportMaterial) ? support_speed : support_interface_speed;
|
||||
} else if (path.role() == erSupportMaterial) {
|
||||
speed = NOZZLE_CONFIG(support_speed);
|
||||
} else if (path.role() == erSupportMaterialInterface) {
|
||||
speed = NOZZLE_CONFIG(support_interface_speed);
|
||||
} else {
|
||||
throw Slic3r::InvalidArgument("Invalid speed");
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ bool Layer::is_perimeter_compatible(const Print& print, const PrintRegion& a, co
|
||||
&& config.inner_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.inner_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.outer_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.outer_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.small_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.small_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.small_support_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.small_support_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.gap_infill_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.gap_infill_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.filter_out_gap_fill.value == other_config.filter_out_gap_fill.value
|
||||
&& config.detect_overhang_wall == other_config.detect_overhang_wall
|
||||
|
||||
@@ -3226,6 +3226,7 @@ double Model::findMaxSpeed(const ModelObject* object) {
|
||||
double topSolidInfillSpeedObj = Model::printSpeedMap.topSolidInfillSpeed;
|
||||
double supportSpeedObj = Model::printSpeedMap.supportSpeed;
|
||||
double smallPerimeterSpeedObj = Model::printSpeedMap.smallPerimeterSpeed;
|
||||
double smallSupportPerimeterSpeedObj = Model::printSpeedMap.smallSupportPerimeterSpeed;
|
||||
for (std::string objectKey : objectKeys) {
|
||||
if (objectKey == "inner_wall_speed"){
|
||||
perimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
@@ -3243,8 +3244,10 @@ double Model::findMaxSpeed(const ModelObject* object) {
|
||||
externalPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "small_perimeter_speed")
|
||||
smallPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "small_support_perimeter_speed")
|
||||
smallSupportPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
}
|
||||
objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, std::max(smallPerimeterSpeedObj, objMaxSpeed)))))));
|
||||
objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, std::max(smallPerimeterSpeedObj, std::max(smallSupportPerimeterSpeedObj, objMaxSpeed))))))));
|
||||
if (objMaxSpeed <= 0) objMaxSpeed = 250.;
|
||||
return objMaxSpeed;
|
||||
}
|
||||
|
||||
@@ -1467,6 +1467,7 @@ struct GlobalSpeedMap
|
||||
double topSolidInfillSpeed;
|
||||
double supportSpeed;
|
||||
double smallPerimeterSpeed;
|
||||
double smallSupportPerimeterSpeed;
|
||||
double maxSpeed;
|
||||
Polygon bed_poly;
|
||||
};
|
||||
|
||||
@@ -1200,6 +1200,8 @@ static std::vector<std::string> s_Preset_print_options{
|
||||
"wall_maximum_deviation",
|
||||
"small_perimeter_speed",
|
||||
"small_perimeter_threshold",
|
||||
"small_support_perimeter_speed",
|
||||
"small_support_perimeter_threshold",
|
||||
"bridge_angle",
|
||||
"internal_bridge_angle",
|
||||
"relative_bridge_angle",
|
||||
|
||||
@@ -2191,6 +2191,28 @@ void PrintConfigDef::init_fff_params()
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{0});
|
||||
|
||||
def = this->add("small_support_perimeter_speed", coFloatsOrPercents);
|
||||
def->label = L("Small support perimeters");
|
||||
def->category = L("Speed");
|
||||
def->tooltip = L("Same as \"Small perimeters\", but for supports. "
|
||||
"This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. "
|
||||
"If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. "
|
||||
"Set to zero for auto.");
|
||||
def->sidetext = L("mm/s or %");
|
||||
def->ratio_over = "outer_wall_speed";
|
||||
def->min = 1;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatsOrPercentsNullable{FloatOrPercent(50, true)});
|
||||
|
||||
def = this->add("small_support_perimeter_threshold", coFloats);
|
||||
def->label = L("Small support perimeters threshold");
|
||||
def->category = L("Speed");
|
||||
def->tooltip = L("This sets the threshold for small support perimeter length. The default threshold is 0mm.");
|
||||
def->sidetext = L("mm"); // millimeters, CIS languages need translation
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{0});
|
||||
|
||||
def = this->add("wall_sequence", coEnum);
|
||||
def->label = L("Walls printing order");
|
||||
def->category = L("Quality");
|
||||
|
||||
@@ -1211,6 +1211,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, filter_out_gap_fill))
|
||||
((ConfigOptionFloatsOrPercentsNullable, small_perimeter_speed))
|
||||
((ConfigOptionFloatsNullable, small_perimeter_threshold))
|
||||
((ConfigOptionFloatsOrPercentsNullable, small_support_perimeter_speed))
|
||||
((ConfigOptionFloatsNullable, small_support_perimeter_threshold))
|
||||
((ConfigOptionFloat, top_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloat, bottom_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloatOrPercent, infill_anchor))
|
||||
|
||||
@@ -1111,6 +1111,8 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "outer_wall_speed"
|
||||
|| opt_key == "small_perimeter_speed"
|
||||
|| opt_key == "small_perimeter_threshold"
|
||||
|| opt_key == "small_support_perimeter_speed"
|
||||
|| opt_key == "small_support_perimeter_threshold"
|
||||
|| opt_key == "sparse_infill_speed"
|
||||
|| opt_key == "inner_wall_speed"
|
||||
|| opt_key == "support_speed"
|
||||
@@ -1426,6 +1428,8 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "outer_wall_speed"
|
||||
|| opt_key == "small_perimeter_speed"
|
||||
|| opt_key == "small_perimeter_threshold"
|
||||
|| opt_key == "small_support_perimeter_speed"
|
||||
|| opt_key == "small_support_perimeter_threshold"
|
||||
|| opt_key == "sparse_infill_speed"
|
||||
|| opt_key == "inner_wall_speed"
|
||||
|| opt_key == "internal_solid_infill_speed"
|
||||
|
||||
Reference in New Issue
Block a user