mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-28 19:31:22 +00:00
Make inner_wall_speed multi-variant
This commit is contained in:
@@ -1886,6 +1886,39 @@ t_config_option_keys DynamicConfig::equal(const DynamicConfig &other) const
|
||||
return equal;
|
||||
}
|
||||
|
||||
double& DynamicConfig::opt_float(const t_config_option_key &opt_key, unsigned int idx)
|
||||
{
|
||||
if (ConfigOptionFloats *opt_floats = dynamic_cast<ConfigOptionFloats *>(this->option(opt_key))) {
|
||||
return opt_floats->get_at(idx);
|
||||
} else {
|
||||
ConfigOptionFloatsNullable *opt_floats_nullable = dynamic_cast<ConfigOptionFloatsNullable *>(this->option(opt_key));
|
||||
assert(opt_floats_nullable != nullptr);
|
||||
return opt_floats_nullable->get_at(idx);
|
||||
}
|
||||
}
|
||||
const double& DynamicConfig::opt_float(const t_config_option_key &opt_key, unsigned int idx) const
|
||||
{
|
||||
if (const ConfigOptionFloats *opt_floats = dynamic_cast<const ConfigOptionFloats *>(this->option(opt_key))) {
|
||||
return opt_floats->get_at(idx);
|
||||
} else if (const ConfigOptionFloatsNullable *opt_floats_nullable = dynamic_cast<const ConfigOptionFloatsNullable *>(this->option(opt_key))) {
|
||||
return opt_floats_nullable->get_at(idx);
|
||||
} else {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool DynamicConfig::opt_bool(const t_config_option_key &opt_key, unsigned int idx) const {
|
||||
if (const ConfigOptionBools *opts = dynamic_cast<const ConfigOptionBools *>(this->option(opt_key))) {
|
||||
return opts->get_at(idx) != 0;
|
||||
}
|
||||
else {
|
||||
const ConfigOptionBoolsNullable *opt_s = dynamic_cast<const ConfigOptionBoolsNullable *>(this->option(opt_key));
|
||||
assert(opt_s != nullptr);
|
||||
return opt_s->get_at(idx) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <cereal/types/polymorphic.hpp>
|
||||
|
||||
@@ -2900,13 +2900,17 @@ public:
|
||||
|
||||
double& opt_float(const t_config_option_key &opt_key) { return this->option<ConfigOptionFloat>(opt_key)->value; }
|
||||
const double& opt_float(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionFloat*>(this->option(opt_key))->value; }
|
||||
double& opt_float(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionFloats>(opt_key)->get_at(idx); }
|
||||
const double& opt_float(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloats*>(this->option(opt_key))->get_at(idx); }
|
||||
double & opt_float(const t_config_option_key &opt_key, unsigned int idx);
|
||||
const double & opt_float(const t_config_option_key &opt_key, unsigned int idx) const;
|
||||
double & opt_float_nullable(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionFloatsNullable>(opt_key)->get_at(idx); }
|
||||
const double & opt_float_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloatsNullable *>(this->option(opt_key))->get_at(idx); }
|
||||
|
||||
int& opt_int(const t_config_option_key &opt_key) { return this->option<ConfigOptionInt>(opt_key)->value; }
|
||||
int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionInt*>(this->option(opt_key))->value; }
|
||||
int& opt_int(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionInts>(opt_key)->get_at(idx); }
|
||||
int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
||||
int& opt_int_nullable(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionIntsNullable>(opt_key)->get_at(idx);}
|
||||
const int & opt_int_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionIntsNullable*>(this->option(opt_key))->get_at(idx);}
|
||||
|
||||
// In ConfigManipulation::toggle_print_fff_options, it is called on option with type ConfigOptionEnumGeneric* and also ConfigOptionEnum*.
|
||||
// Thus the virtual method getInt() is used to retrieve the enum value.
|
||||
@@ -2914,9 +2918,13 @@ public:
|
||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return static_cast<ENUM>(this->option(opt_key)->getInt()); }
|
||||
// BBS
|
||||
int opt_enum(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionEnumsGeneric*>(this->option(opt_key))->get_at(idx); }
|
||||
int opt_enum_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionEnumsGenericNullable*>(this->option(opt_key))->get_at(idx); }
|
||||
|
||||
|
||||
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const;
|
||||
bool opt_bool_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionBoolsNullable*>(this->option(opt_key))->get_at(idx);}
|
||||
|
||||
|
||||
// Command line processing
|
||||
bool read_cli(int argc, const char* const argv[], t_config_option_keys* extra, t_config_option_keys* keys = nullptr);
|
||||
|
||||
+11
-4
@@ -3590,6 +3590,13 @@ void GCode::check_placeholder_parser_failed()
|
||||
}
|
||||
}
|
||||
|
||||
size_t GCode::cur_extruder_index() const
|
||||
{
|
||||
//TODO: check if the function is duplicated
|
||||
//just return m_writer.filament()->extruder_id()
|
||||
return get_extruder_id(m_writer.filament()->id());
|
||||
}
|
||||
|
||||
size_t GCode::get_extruder_id(unsigned int filament_id) const
|
||||
{
|
||||
if (m_print) {
|
||||
@@ -6436,14 +6443,14 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
// set speed
|
||||
if (speed == -1) {
|
||||
if (path.role() == erPerimeter) {
|
||||
speed = m_config.get_abs_value("inner_wall_speed");
|
||||
speed = m_config.inner_wall_speed.get_at(cur_extruder_index());
|
||||
if (sloped) {
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("inner_wall_speed")));
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(speed));
|
||||
}
|
||||
} else if (path.role() == erExternalPerimeter) {
|
||||
speed = m_config.get_abs_value("outer_wall_speed");
|
||||
if (sloped) {
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("outer_wall_speed")));
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(speed));
|
||||
}
|
||||
}
|
||||
else if(path.role() == erInternalBridgeInfill) {
|
||||
@@ -6578,7 +6585,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
if (m_config.enable_overhang_speed && !this->on_first_layer() && !object_layer_over_raft() &&
|
||||
(is_bridge(path.role()) || is_perimeter(path.role()))) {
|
||||
bool is_external = is_external_perimeter(path.role());
|
||||
double ref_speed = is_external ? m_config.get_abs_value("outer_wall_speed") : m_config.get_abs_value("inner_wall_speed");
|
||||
double ref_speed = is_external ? m_config.get_abs_value("outer_wall_speed") : m_config.inner_wall_speed.get_at(cur_extruder_index());
|
||||
if (ref_speed == 0)
|
||||
ref_speed = FILAMENT_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm;
|
||||
|
||||
|
||||
@@ -383,6 +383,7 @@ private:
|
||||
|
||||
//BBS
|
||||
void check_placeholder_parser_failed();
|
||||
size_t cur_extruder_index() const;
|
||||
size_t get_extruder_id(unsigned int filament_id) const;
|
||||
|
||||
void set_last_pos(const Point &pos) { m_last_pos = Point3(pos, 0); m_last_pos_defined = true; }
|
||||
|
||||
@@ -1264,7 +1264,7 @@ WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& defau
|
||||
m_gcode_flavor(config.gcode_flavor),
|
||||
m_travel_speed(config.travel_speed),
|
||||
m_infill_speed(default_region_config.sparse_infill_speed),
|
||||
m_perimeter_speed(default_region_config.inner_wall_speed),
|
||||
m_perimeter_speed(default_region_config.inner_wall_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_current_tool(initial_tool),
|
||||
wipe_volumes(wiping_matrix), m_wipe_tower_max_purge_speed(float(config.wipe_tower_max_purge_speed)),
|
||||
m_enable_arc_fitting(config.enable_arc_fitting),
|
||||
|
||||
@@ -136,7 +136,7 @@ ExPolygons Layer::merged(float offset_scaled) const
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
||||
bool Layer::is_perimeter_compatible(const Print& print, const PrintRegion& a, const PrintRegion& b)
|
||||
{
|
||||
const PrintRegionConfig& config = a.config();
|
||||
const PrintRegionConfig& other_config = b.config();
|
||||
@@ -145,7 +145,7 @@ bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
||||
&& config.wall_loops == other_config.wall_loops
|
||||
&& config.wall_sequence == other_config.wall_sequence
|
||||
&& config.is_infill_first == other_config.is_infill_first
|
||||
&& config.inner_wall_speed == other_config.inner_wall_speed
|
||||
&& config.inner_wall_speed.get_at(print.get_extruder_id(config.wall_filament)) == other_config.inner_wall_speed.get_at(print.get_extruder_id(config.wall_filament))
|
||||
&& config.outer_wall_speed == other_config.outer_wall_speed
|
||||
&& config.small_perimeter_speed == other_config.small_perimeter_speed
|
||||
&& config.gap_infill_speed.value == other_config.gap_infill_speed.value
|
||||
@@ -208,7 +208,7 @@ void Layer::make_perimeters()
|
||||
if (! (*it)->slices.empty()) {
|
||||
LayerRegion* other_layerm = *it;
|
||||
const PrintRegion &other_region = other_layerm->region();
|
||||
if (is_perimeter_compatible(this_region, other_region))
|
||||
if (is_perimeter_compatible(*m_object->print(), this_region, other_region))
|
||||
{
|
||||
other_layerm->perimeters.clear();
|
||||
other_layerm->fills.clear();
|
||||
|
||||
@@ -17,6 +17,7 @@ class LayerRegion;
|
||||
using LayerRegionPtrs = std::vector<LayerRegion*>;
|
||||
class PrintRegion;
|
||||
class PrintObject;
|
||||
class Print;
|
||||
|
||||
namespace FillAdaptive {
|
||||
struct Octree;
|
||||
@@ -186,7 +187,7 @@ public:
|
||||
}
|
||||
|
||||
// Whether two regions can be printed in a continues perimeter
|
||||
static bool is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b);
|
||||
static bool is_perimeter_compatible(const Print& print, const PrintRegion& a, const PrintRegion& b);
|
||||
void make_perimeters();
|
||||
// Phony version of make_fills() without parameters for Perl integration only.
|
||||
void make_fills() { this->make_fills(nullptr, nullptr); }
|
||||
|
||||
@@ -2966,7 +2966,7 @@ void Model::setPrintSpeedTable(const DynamicPrintConfig& config, const PrintConf
|
||||
//Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config();
|
||||
printSpeedMap.maxSpeed = 0;
|
||||
if (config.has("inner_wall_speed")) {
|
||||
printSpeedMap.perimeterSpeed = config.opt_float("inner_wall_speed");
|
||||
printSpeedMap.perimeterSpeed = config.opt_float_nullable("inner_wall_speed", 0);
|
||||
if (printSpeedMap.perimeterSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.perimeterSpeed;
|
||||
}
|
||||
@@ -3222,7 +3222,7 @@ double Model::findMaxSpeed(const ModelObject* object) {
|
||||
double smallPerimeterSpeedObj = Model::printSpeedMap.smallPerimeterSpeed;
|
||||
for (std::string objectKey : objectKeys) {
|
||||
if (objectKey == "inner_wall_speed"){
|
||||
perimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
perimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
externalPerimeterSpeedObj = Model::printSpeedMap.externalPerimeterSpeed / Model::printSpeedMap.perimeterSpeed * perimeterSpeedObj;
|
||||
}
|
||||
if (objectKey == "sparse_infill_speed")
|
||||
|
||||
@@ -1343,8 +1343,8 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||
const auto all_regions = m_objects.front()->all_regions();
|
||||
if (all_regions.size() > 1) {
|
||||
// Orca: make sure regions are not compatible
|
||||
if (std::any_of(all_regions.begin() + 1, all_regions.end(), [ra = all_regions.front()](const auto rb) {
|
||||
return !Layer::is_perimeter_compatible(ra, rb);
|
||||
if (std::any_of(all_regions.begin() + 1, all_regions.end(), [this, ra = all_regions.front()](const auto rb) {
|
||||
return !Layer::is_perimeter_compatible(*this, ra, rb);
|
||||
})) {
|
||||
return {L("The spiral vase mode does not work when an object contains more than one materials."), nullptr, "spiral_mode"};
|
||||
}
|
||||
|
||||
@@ -4905,7 +4905,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0., false));
|
||||
|
||||
def = this->add("inner_wall_speed", coFloat);
|
||||
def = this->add("inner_wall_speed", coFloats);
|
||||
def->label = L("Inner wall");
|
||||
def->category = L("Speed");
|
||||
def->tooltip = L("Speed of inner wall.");
|
||||
@@ -4913,7 +4913,8 @@ void PrintConfigDef::init_fff_params()
|
||||
def->aliases = { "perimeter_feed_rate" };
|
||||
def->min = 1;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(60));
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{60});
|
||||
|
||||
def = this->add("wall_loops", coInt);
|
||||
def->label = L("Wall loops");
|
||||
@@ -8157,7 +8158,7 @@ std::set<std::string> print_options_with_variant = {
|
||||
//"initial_layer_speed",
|
||||
//"initial_layer_infill_speed",
|
||||
//"outer_wall_speed",
|
||||
//"inner_wall_speed",
|
||||
"inner_wall_speed",
|
||||
//"small_perimeter_speed", //coFloatsOrPercents
|
||||
//"small_perimeter_threshold",
|
||||
//"sparse_infill_speed",
|
||||
|
||||
@@ -1164,7 +1164,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionBool, detect_overhang_wall))
|
||||
((ConfigOptionInt, wall_filament))
|
||||
((ConfigOptionFloatOrPercent, inner_wall_line_width))
|
||||
((ConfigOptionFloat, inner_wall_speed))
|
||||
((ConfigOptionFloatsNullable, inner_wall_speed))
|
||||
// Total number of perimeters.
|
||||
((ConfigOptionInt, wall_loops))
|
||||
((ConfigOptionBool, alternate_extra_wall))
|
||||
|
||||
@@ -12943,7 +12943,7 @@ void Plater::_calib_pa_tower(const Calib_Params& params) {
|
||||
full_config, full_config.get_abs_value("line_width", nozzle_diameter),
|
||||
full_config.get_abs_value("layer_height"), 0, 0);
|
||||
obj_cfg.set_key_value("outer_wall_speed", new ConfigOptionFloat(wall_speed));
|
||||
obj_cfg.set_key_value("inner_wall_speed", new ConfigOptionFloat(wall_speed));
|
||||
obj_cfg.set_key_value("inner_wall_speed", new ConfigOptionFloatsNullable({wall_speed}));
|
||||
obj_cfg.set_key_value("seam_position", new ConfigOptionEnum<SeamPosition>(spRear));
|
||||
obj_cfg.set_key_value("wall_loops", new ConfigOptionInt(2));
|
||||
obj_cfg.set_key_value("top_shell_layers", new ConfigOptionInt(0));
|
||||
|
||||
@@ -2762,7 +2762,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("slow_down_layers", "speed_settings_initial_layer_speed#number-of-slow-layers");
|
||||
optgroup = page->new_optgroup(L("Other layers speed"), L"param_speed", 15);
|
||||
optgroup->append_single_option_line("outer_wall_speed", "speed_settings_other_layers_speed#outer-wall");
|
||||
optgroup->append_single_option_line("inner_wall_speed", "speed_settings_other_layers_speed#inner-wall");
|
||||
optgroup->append_single_option_line("inner_wall_speed", "speed_settings_other_layers_speed#inner-wall", 0);
|
||||
optgroup->append_single_option_line("small_perimeter_speed", "speed_settings_other_layers_speed#small-perimeters");
|
||||
optgroup->append_single_option_line("small_perimeter_threshold", "speed_settings_other_layers_speed#small-perimeters-threshold");
|
||||
optgroup->append_single_option_line("sparse_infill_speed", "speed_settings_other_layers_speed#sparse-infill");
|
||||
|
||||
Reference in New Issue
Block a user