mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-01 15:22:21 +00:00
FIX: backend get the extruder id based on filament_map
Change-Id: Ib7679c0fc67336e462467dab9f5b4d4684d6eb19 (cherry picked from commit dcd9fd501354da33baea2adc0f645fabe8880cf1)
This commit is contained in:
@@ -12,7 +12,7 @@ Extruder::Extruder(unsigned int id, GCodeConfig *config, bool share_extruder) :
|
|||||||
m_share_extruder(share_extruder)
|
m_share_extruder(share_extruder)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
// cache values that are going to be called often
|
// cache values that are going to be called often
|
||||||
m_e_per_mm3 = this->filament_flow_ratio();
|
m_e_per_mm3 = this->filament_flow_ratio();
|
||||||
m_e_per_mm3 /= this->filament_crossection();
|
m_e_per_mm3 /= this->filament_crossection();
|
||||||
@@ -20,7 +20,11 @@ Extruder::Extruder(unsigned int id, GCodeConfig *config, bool share_extruder) :
|
|||||||
|
|
||||||
unsigned int Extruder::extruder_id() const
|
unsigned int Extruder::extruder_id() const
|
||||||
{
|
{
|
||||||
return get_extruder_index(m_id);
|
assert(m_config);
|
||||||
|
if (m_id < m_config->filament_map.size()) {
|
||||||
|
return m_config->filament_map.get_at(m_id);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Extruder::extrude(double dE)
|
double Extruder::extrude(double dE)
|
||||||
@@ -47,7 +51,7 @@ double Extruder::extrude(double dE)
|
|||||||
|
|
||||||
/* This method makes sure the extruder is retracted by the specified amount
|
/* This method makes sure the extruder is retracted by the specified amount
|
||||||
of filament and returns the amount of filament retracted.
|
of filament and returns the amount of filament retracted.
|
||||||
If the extruder is already retracted by the same or a greater amount,
|
If the extruder is already retracted by the same or a greater amount,
|
||||||
this method is a no-op.
|
this method is a no-op.
|
||||||
The restart_extra argument sets the extra length to be used for
|
The restart_extra argument sets the extra length to be used for
|
||||||
unretraction. If we're actually performing a retraction, any restart_extra
|
unretraction. If we're actually performing a retraction, any restart_extra
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
|||||||
if (new_filament_id != -1 && new_filament_id != tcr.new_tool)
|
if (new_filament_id != -1 && new_filament_id != tcr.new_tool)
|
||||||
throw Slic3r::InvalidArgument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect.");
|
throw Slic3r::InvalidArgument("Error: WipeTowerIntegration::append_tcr was asked to do a toolchange it didn't expect.");
|
||||||
|
|
||||||
int new_extruder_id = get_extruder_index(new_filament_id);
|
int new_extruder_id = get_extruder_index(*m_print_config, new_filament_id);
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
|
|
||||||
// Toolchangeresult.gcode assumes the wipe tower corner is at the origin (except for priming lines)
|
// Toolchangeresult.gcode assumes the wipe tower corner is at the origin (except for priming lines)
|
||||||
@@ -1534,7 +1534,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu
|
|||||||
bool activate_long_retraction_when_cut = false;
|
bool activate_long_retraction_when_cut = false;
|
||||||
for (const auto& extruder : m_writer.extruders())
|
for (const auto& extruder : m_writer.extruders())
|
||||||
activate_long_retraction_when_cut |= (
|
activate_long_retraction_when_cut |= (
|
||||||
m_config.long_retractions_when_cut.get_at(extruder.extruder_id())
|
m_config.long_retractions_when_cut.get_at(extruder.extruder_id())
|
||||||
&& m_config.retraction_distances_when_cut.get_at(extruder.extruder_id()) > 0
|
&& m_config.retraction_distances_when_cut.get_at(extruder.extruder_id()) > 0
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1821,6 +1821,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||||||
{
|
{
|
||||||
PROFILE_FUNC();
|
PROFILE_FUNC();
|
||||||
|
|
||||||
|
m_print = &print;
|
||||||
|
|
||||||
// modifies m_silent_time_estimator_enabled
|
// modifies m_silent_time_estimator_enabled
|
||||||
DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled);
|
DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled);
|
||||||
const bool is_bbl_printers = print.is_BBL_printer();
|
const bool is_bbl_printers = print.is_BBL_printer();
|
||||||
@@ -2155,7 +2157,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||||||
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
|
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
|
||||||
m_cooling_buffer->set_current_extruder(initial_extruder_id);
|
m_cooling_buffer->set_current_extruder(initial_extruder_id);
|
||||||
|
|
||||||
int extruder_id = get_extruder_index(initial_extruder_id);
|
int extruder_id = get_extruder_id(initial_extruder_id);
|
||||||
|
|
||||||
// Orca: Initialise AdaptivePA processor filter
|
// Orca: Initialise AdaptivePA processor filter
|
||||||
m_pa_processor = std::make_unique<AdaptivePAProcessor>(*this, tool_ordering.all_extruders());
|
m_pa_processor = std::make_unique<AdaptivePAProcessor>(*this, tool_ordering.all_extruders());
|
||||||
@@ -2741,6 +2743,18 @@ void GCode::check_placeholder_parser_failed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GCode::get_extruder_id(unsigned int filament_id) const
|
||||||
|
{
|
||||||
|
if (m_print) {
|
||||||
|
std::vector<int> filament_maps = m_print->get_filament_maps();
|
||||||
|
if (filament_id < filament_maps.size()) {
|
||||||
|
return filament_maps[filament_id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Process all layers of all objects (non-sequential mode) with a parallel pipeline:
|
// Process all layers of all objects (non-sequential mode) with a parallel pipeline:
|
||||||
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
||||||
// and export G-code into file.
|
// and export G-code into file.
|
||||||
@@ -6370,7 +6384,7 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li
|
|||||||
|
|
||||||
std::string GCode::set_extruder(unsigned int filament_id, double print_z, bool by_object)
|
std::string GCode::set_extruder(unsigned int filament_id, double print_z, bool by_object)
|
||||||
{
|
{
|
||||||
int extruder_id = get_extruder_index(filament_id);
|
int extruder_id = get_extruder_id(filament_id);
|
||||||
if (!m_writer.need_toolchange(filament_id))
|
if (!m_writer.need_toolchange(filament_id))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ public:
|
|||||||
m_plate_origin(plate_origin),
|
m_plate_origin(plate_origin),
|
||||||
m_single_extruder_multi_material(print_config.single_extruder_multi_material),
|
m_single_extruder_multi_material(print_config.single_extruder_multi_material),
|
||||||
m_enable_timelapse_print(print_config.timelapse_type.value == TimelapseType::tlSmooth),
|
m_enable_timelapse_print(print_config.timelapse_type.value == TimelapseType::tlSmooth),
|
||||||
m_is_first_print(true)
|
m_is_first_print(true),
|
||||||
|
m_print_config(&print_config)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string prime(GCode &gcodegen);
|
std::string prime(GCode &gcodegen);
|
||||||
@@ -136,6 +137,7 @@ private:
|
|||||||
bool m_single_extruder_multi_material;
|
bool m_single_extruder_multi_material;
|
||||||
bool m_enable_timelapse_print;
|
bool m_enable_timelapse_print;
|
||||||
bool m_is_first_print;
|
bool m_is_first_print;
|
||||||
|
const PrintConfig * m_print_config;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ColorPrintColors
|
class ColorPrintColors
|
||||||
@@ -352,6 +354,7 @@ private:
|
|||||||
|
|
||||||
//BBS
|
//BBS
|
||||||
void check_placeholder_parser_failed();
|
void check_placeholder_parser_failed();
|
||||||
|
size_t get_extruder_id(unsigned int filament_id) const;
|
||||||
|
|
||||||
void set_last_pos(const Point &pos) { m_last_pos = pos; m_last_pos_defined = true; }
|
void set_last_pos(const Point &pos) { m_last_pos = pos; m_last_pos_defined = true; }
|
||||||
bool last_pos_defined() const { return m_last_pos_defined; }
|
bool last_pos_defined() const { return m_last_pos_defined; }
|
||||||
@@ -584,6 +587,8 @@ private:
|
|||||||
|
|
||||||
bool m_silent_time_estimator_enabled;
|
bool m_silent_time_estimator_enabled;
|
||||||
|
|
||||||
|
Print *m_print{nullptr};
|
||||||
|
|
||||||
// Processor
|
// Processor
|
||||||
GCodeProcessor m_processor;
|
GCodeProcessor m_processor;
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ struct CoolingLine
|
|||||||
length(0.f), feedrate(0.f), time(0.f), time_max(0.f), slowdown(false) {}
|
length(0.f), feedrate(0.f), time(0.f), time_max(0.f), slowdown(false) {}
|
||||||
|
|
||||||
bool adjustable(bool slowdown_external_perimeters) const {
|
bool adjustable(bool slowdown_external_perimeters) const {
|
||||||
return (this->type & TYPE_ADJUSTABLE) &&
|
return (this->type & TYPE_ADJUSTABLE) &&
|
||||||
(! (this->type & TYPE_EXTERNAL_PERIMETER) || slowdown_external_perimeters) &&
|
(! (this->type & TYPE_EXTERNAL_PERIMETER) || slowdown_external_perimeters) &&
|
||||||
this->time < this->time_max;
|
this->time < this->time_max;
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ struct CoolingLine
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Calculate the required per extruder time stretches.
|
// Calculate the required per extruder time stretches.
|
||||||
struct PerExtruderAdjustments
|
struct PerExtruderAdjustments
|
||||||
{
|
{
|
||||||
// Calculate the total elapsed time per this extruder, adjusted for the slowdown.
|
// Calculate the total elapsed time per this extruder, adjusted for the slowdown.
|
||||||
float elapsed_time_total() const {
|
float elapsed_time_total() const {
|
||||||
@@ -114,7 +114,7 @@ struct PerExtruderAdjustments
|
|||||||
time_total += line.time;
|
time_total += line.time;
|
||||||
return time_total;
|
return time_total;
|
||||||
}
|
}
|
||||||
// Calculate the total elapsed time when slowing down
|
// Calculate the total elapsed time when slowing down
|
||||||
// to the minimum extrusion feed rate defined for the current material.
|
// to the minimum extrusion feed rate defined for the current material.
|
||||||
float maximum_time_after_slowdown(bool slowdown_external_perimeters) const {
|
float maximum_time_after_slowdown(bool slowdown_external_perimeters) const {
|
||||||
float time_total = 0.f;
|
float time_total = 0.f;
|
||||||
@@ -185,7 +185,7 @@ struct PerExtruderAdjustments
|
|||||||
bool adj2 = l2.adjustable();
|
bool adj2 = l2.adjustable();
|
||||||
return (adj1 == adj2) ? l1.feedrate > l2.feedrate : adj1;
|
return (adj1 == adj2) ? l1.feedrate > l2.feedrate : adj1;
|
||||||
});
|
});
|
||||||
for (n_lines_adjustable = 0;
|
for (n_lines_adjustable = 0;
|
||||||
n_lines_adjustable < lines.size() && this->lines[n_lines_adjustable].adjustable();
|
n_lines_adjustable < lines.size() && this->lines[n_lines_adjustable].adjustable();
|
||||||
++ n_lines_adjustable);
|
++ n_lines_adjustable);
|
||||||
time_non_adjustable = 0.f;
|
time_non_adjustable = 0.f;
|
||||||
@@ -242,7 +242,7 @@ struct PerExtruderAdjustments
|
|||||||
// The following two values are set by sort_lines_by_decreasing_feedrate():
|
// The following two values are set by sort_lines_by_decreasing_feedrate():
|
||||||
// Number of adjustable lines, at the start of lines.
|
// Number of adjustable lines, at the start of lines.
|
||||||
size_t n_lines_adjustable = 0;
|
size_t n_lines_adjustable = 0;
|
||||||
// Non-adjustable time of lines starting with n_lines_adjustable.
|
// Non-adjustable time of lines starting with n_lines_adjustable.
|
||||||
float time_non_adjustable = 0;
|
float time_non_adjustable = 0;
|
||||||
// Current total time for this extruder.
|
// Current total time for this extruder.
|
||||||
float time_total = 0;
|
float time_total = 0;
|
||||||
@@ -257,7 +257,7 @@ struct PerExtruderAdjustments
|
|||||||
// Calculate a new feedrate when slowing down by time_stretch for segments faster than min_feedrate.
|
// Calculate a new feedrate when slowing down by time_stretch for segments faster than min_feedrate.
|
||||||
// Used by non-proportional slow down.
|
// Used by non-proportional slow down.
|
||||||
float new_feedrate_to_reach_time_stretch(
|
float new_feedrate_to_reach_time_stretch(
|
||||||
std::vector<PerExtruderAdjustments*>::const_iterator it_begin, std::vector<PerExtruderAdjustments*>::const_iterator it_end,
|
std::vector<PerExtruderAdjustments*>::const_iterator it_begin, std::vector<PerExtruderAdjustments*>::const_iterator it_end,
|
||||||
float min_feedrate, float time_stretch, size_t max_iter = 20)
|
float min_feedrate, float time_stretch, size_t max_iter = 20)
|
||||||
{
|
{
|
||||||
float new_feedrate = min_feedrate;
|
float new_feedrate = min_feedrate;
|
||||||
@@ -285,7 +285,7 @@ float new_feedrate_to_reach_time_stretch(
|
|||||||
for (size_t i = 0; i < (*it)->n_lines_adjustable; ++i) {
|
for (size_t i = 0; i < (*it)->n_lines_adjustable; ++i) {
|
||||||
const CoolingLine &line = (*it)->lines[i];
|
const CoolingLine &line = (*it)->lines[i];
|
||||||
if (line.feedrate > min_feedrate && line.feedrate < new_feedrate)
|
if (line.feedrate > min_feedrate && line.feedrate < new_feedrate)
|
||||||
// Some of the line segments taken into account in the calculation of nomin / denom are now slower than new_feedrate,
|
// Some of the line segments taken into account in the calculation of nomin / denom are now slower than new_feedrate,
|
||||||
// which makes the new_feedrate lower than it should be.
|
// which makes the new_feedrate lower than it should be.
|
||||||
// Re-run the calculation with a new min_feedrate limit, so that the segments with current feedrate lower than new_feedrate
|
// Re-run the calculation with a new min_feedrate limit, so that the segments with current feedrate lower than new_feedrate
|
||||||
// are not taken into account.
|
// are not taken into account.
|
||||||
@@ -361,7 +361,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
|
|||||||
// Time of any other movements before the first extrusion will be excluded from the layer time.
|
// Time of any other movements before the first extrusion will be excluded from the layer time.
|
||||||
bool layer_had_extrusion = false;
|
bool layer_had_extrusion = false;
|
||||||
|
|
||||||
for (; *line_start != 0; line_start = line_end)
|
for (; *line_start != 0; line_start = line_end)
|
||||||
{
|
{
|
||||||
while (*line_end != '\n' && *line_end != 0)
|
while (*line_end != '\n' && *line_end != 0)
|
||||||
++ line_end;
|
++ line_end;
|
||||||
@@ -574,7 +574,7 @@ static inline void extruder_range_slow_down_non_proportional(
|
|||||||
}
|
}
|
||||||
assert(feedrate > 0.f);
|
assert(feedrate > 0.f);
|
||||||
// Sort by slow_down_min_speed, maximum speed first.
|
// Sort by slow_down_min_speed, maximum speed first.
|
||||||
std::sort(by_min_print_speed.begin(), by_min_print_speed.end(),
|
std::sort(by_min_print_speed.begin(), by_min_print_speed.end(),
|
||||||
[](const PerExtruderAdjustments *p1, const PerExtruderAdjustments *p2){ return p1->slow_down_min_speed > p2->slow_down_min_speed; });
|
[](const PerExtruderAdjustments *p1, const PerExtruderAdjustments *p2){ return p1->slow_down_min_speed > p2->slow_down_min_speed; });
|
||||||
// Slow down, fast moves first.
|
// Slow down, fast moves first.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -696,7 +696,7 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||||||
// Source G-code for the current layer.
|
// Source G-code for the current layer.
|
||||||
const std::string &gcode,
|
const std::string &gcode,
|
||||||
// ID of the current layer, used to disable fan for the first n layers.
|
// ID of the current layer, used to disable fan for the first n layers.
|
||||||
size_t layer_id,
|
size_t layer_id,
|
||||||
// Total time of this layer after slow down, used to control the fan.
|
// Total time of this layer after slow down, used to control the fan.
|
||||||
float layer_time,
|
float layer_time,
|
||||||
// Per extruder list of G-code lines and their cool down attributes.
|
// Per extruder list of G-code lines and their cool down attributes.
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ std::vector<unsigned int> ToolOrdering::generate_first_layer_tool_order(const Pr
|
|||||||
auto first_layer = object->get_layer(0);
|
auto first_layer = object->get_layer(0);
|
||||||
for (auto layerm : first_layer->regions()) {
|
for (auto layerm : first_layer->regions()) {
|
||||||
int extruder_id = layerm->region().config().option("wall_filament")->getInt();
|
int extruder_id = layerm->region().config().option("wall_filament")->getInt();
|
||||||
|
|
||||||
for (auto expoly : layerm->raw_slices) {
|
for (auto expoly : layerm->raw_slices) {
|
||||||
const double nozzle_diameter = print.config().nozzle_diameter.get_at(0);
|
const double nozzle_diameter = print.config().nozzle_diameter.get_at(0);
|
||||||
const coordf_t initial_layer_line_width = print.config().get_abs_value("initial_layer_line_width", nozzle_diameter);
|
const coordf_t initial_layer_line_width = print.config().get_abs_value("initial_layer_line_width", nozzle_diameter);
|
||||||
@@ -486,7 +486,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
|||||||
for (auto layer : object.layers()) {
|
for (auto layer : object.layers()) {
|
||||||
LayerTools &layer_tools = this->tools_for_layer(layer->print_z);
|
LayerTools &layer_tools = this->tools_for_layer(layer->print_z);
|
||||||
|
|
||||||
// Override extruder with the next
|
// Override extruder with the next
|
||||||
for (; it_per_layer_extruder_override != per_layer_extruder_switches.end() && it_per_layer_extruder_override->first < layer->print_z + EPSILON; ++ it_per_layer_extruder_override)
|
for (; it_per_layer_extruder_override != per_layer_extruder_switches.end() && it_per_layer_extruder_override->first < layer->print_z + EPSILON; ++ it_per_layer_extruder_override)
|
||||||
extruder_override = (int)it_per_layer_extruder_override->second;
|
extruder_override = (int)it_per_layer_extruder_override->second;
|
||||||
|
|
||||||
@@ -552,7 +552,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
|||||||
|
|
||||||
sort_remove_duplicates(firstLayerExtruders);
|
sort_remove_duplicates(firstLayerExtruders);
|
||||||
const_cast<PrintObject&>(object).object_first_layer_wall_extruders = firstLayerExtruders;
|
const_cast<PrintObject&>(object).object_first_layer_wall_extruders = firstLayerExtruders;
|
||||||
|
|
||||||
for (auto& layer : m_layer_tools) {
|
for (auto& layer : m_layer_tools) {
|
||||||
// Sort and remove duplicates
|
// Sort and remove duplicates
|
||||||
sort_remove_duplicates(layer.extruders);
|
sort_remove_duplicates(layer.extruders);
|
||||||
@@ -1057,7 +1057,11 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume()
|
|||||||
size_t nozzle_nums = print_config->nozzle_diameter.values.size();
|
size_t nozzle_nums = print_config->nozzle_diameter.values.size();
|
||||||
if (nozzle_nums > 1) {
|
if (nozzle_nums > 1) {
|
||||||
std::vector<int> filament_maps = get_recommended_filament_maps();
|
std::vector<int> filament_maps = get_recommended_filament_maps();
|
||||||
|
if (filament_maps.empty()) // multi-extruder and one-color
|
||||||
|
return;
|
||||||
|
|
||||||
reorder_extruders_for_minimum_flush_volume_multi_extruder(filament_maps);
|
reorder_extruders_for_minimum_flush_volume_multi_extruder(filament_maps);
|
||||||
|
m_print->update_filament_maps_to_config(filament_maps);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1177,7 +1181,7 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume_multi_extruder(con
|
|||||||
|
|
||||||
nozzle_flush_mtx.emplace_back(wipe_volumes);
|
nozzle_flush_mtx.emplace_back(wipe_volumes);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto extruders_to_hash_key = [](const std::vector<unsigned int> &extruders, std::optional<unsigned int> initial_extruder_id) -> uint32_t {
|
auto extruders_to_hash_key = [](const std::vector<unsigned int> &extruders, std::optional<unsigned int> initial_extruder_id) -> uint32_t {
|
||||||
uint32_t hash_key = 0;
|
uint32_t hash_key = 0;
|
||||||
// high 16 bit define initial extruder ,low 16 bit define extruder set
|
// high 16 bit define initial extruder ,low 16 bit define extruder set
|
||||||
@@ -1206,7 +1210,7 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume_multi_extruder(con
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::optional<unsigned int> current_extruder_id;
|
std::optional<unsigned int> current_extruder_id;
|
||||||
|
|
||||||
std::vector<std::optional<unsigned int>> nozzle_to_cur_filaments;
|
std::vector<std::optional<unsigned int>> nozzle_to_cur_filaments;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ void GCodeWriter::set_extruders(std::vector<unsigned int> extruder_ids)
|
|||||||
m_extruders.reserve(extruder_ids.size());
|
m_extruders.reserve(extruder_ids.size());
|
||||||
for (unsigned int extruder_id : extruder_ids)
|
for (unsigned int extruder_id : extruder_ids)
|
||||||
m_extruders.emplace_back(Extruder(extruder_id, &this->config, config.single_extruder_multi_material.value));
|
m_extruders.emplace_back(Extruder(extruder_id, &this->config, config.single_extruder_multi_material.value));
|
||||||
|
|
||||||
/* we enable support for multiple extruder if any extruder greater than 0 is used
|
/* we enable support for multiple extruder if any extruder greater than 0 is used
|
||||||
(even if prints only uses that one) since we need to output Tx commands
|
(even if prints only uses that one) since we need to output Tx commands
|
||||||
first extruder has index 0 */
|
first extruder has index 0 */
|
||||||
@@ -61,7 +61,7 @@ void GCodeWriter::set_extruders(std::vector<unsigned int> extruder_ids)
|
|||||||
std::string GCodeWriter::preamble()
|
std::string GCodeWriter::preamble()
|
||||||
{
|
{
|
||||||
std::ostringstream gcode;
|
std::ostringstream gcode;
|
||||||
|
|
||||||
if (FLAVOR_IS_NOT(gcfMakerWare)) {
|
if (FLAVOR_IS_NOT(gcfMakerWare)) {
|
||||||
gcode << "G90\n";
|
gcode << "G90\n";
|
||||||
gcode << "G21\n";
|
gcode << "G21\n";
|
||||||
@@ -82,7 +82,7 @@ std::string GCodeWriter::preamble()
|
|||||||
}
|
}
|
||||||
gcode << this->reset_e(true);
|
gcode << this->reset_e(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gcode.str();
|
return gcode.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,9 +207,9 @@ std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned i
|
|||||||
auto& last_value = separate_travel ? m_last_travel_acceleration : m_last_acceleration ;
|
auto& last_value = separate_travel ? m_last_travel_acceleration : m_last_acceleration ;
|
||||||
if (acceleration == 0 || acceleration == last_value)
|
if (acceleration == 0 || acceleration == last_value)
|
||||||
return std::string();
|
return std::string();
|
||||||
|
|
||||||
last_value = acceleration;
|
last_value = acceleration;
|
||||||
|
|
||||||
std::ostringstream gcode;
|
std::ostringstream gcode;
|
||||||
if (FLAVOR_IS(gcfRepetier))
|
if (FLAVOR_IS(gcfRepetier))
|
||||||
gcode << (separate_travel ? "M202 X" : "M201 X") << acceleration << " Y" << acceleration;
|
gcode << (separate_travel ? "M202 X" : "M201 X") << acceleration << " Y" << acceleration;
|
||||||
@@ -228,7 +228,7 @@ std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned i
|
|||||||
|
|
||||||
if (GCodeWriter::full_gcode_comment) gcode << " ; adjust acceleration";
|
if (GCodeWriter::full_gcode_comment) gcode << " ; adjust acceleration";
|
||||||
gcode << "\n";
|
gcode << "\n";
|
||||||
|
|
||||||
return gcode.str();
|
return gcode.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,7 +406,7 @@ std::string GCodeWriter::reset_e(bool force)
|
|||||||
|| FLAVOR_IS(gcfMakerWare)
|
|| FLAVOR_IS(gcfMakerWare)
|
||||||
|| FLAVOR_IS(gcfSailfish))
|
|| FLAVOR_IS(gcfSailfish))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
if (m_extruder != nullptr) {
|
if (m_extruder != nullptr) {
|
||||||
if (is_zero(m_extruder->E()) && ! force)
|
if (is_zero(m_extruder->E()) && ! force)
|
||||||
return "";
|
return "";
|
||||||
@@ -433,10 +433,10 @@ std::string GCodeWriter::update_progress(unsigned int num, unsigned int tot, boo
|
|||||||
if (config.disable_m73) {
|
if (config.disable_m73) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int percent = (unsigned int)floor(100.0 * num / tot + 0.5);
|
unsigned int percent = (unsigned int)floor(100.0 * num / tot + 0.5);
|
||||||
if (!allow_100) percent = std::min(percent, (unsigned int)99);
|
if (!allow_100) percent = std::min(percent, (unsigned int)99);
|
||||||
|
|
||||||
std::ostringstream gcode;
|
std::ostringstream gcode;
|
||||||
gcode << "M73 P" << percent;
|
gcode << "M73 P" << percent;
|
||||||
//BBS
|
//BBS
|
||||||
@@ -499,7 +499,7 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com
|
|||||||
this->set_current_position_clear(true);
|
this->set_current_position_clear(true);
|
||||||
//BBS: take plate offset into consider
|
//BBS: take plate offset into consider
|
||||||
Vec2d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset };
|
Vec2d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset };
|
||||||
|
|
||||||
GCodeG1Formatter w;
|
GCodeG1Formatter w;
|
||||||
w.emit_xy(point_on_plate);
|
w.emit_xy(point_on_plate);
|
||||||
auto speed = m_is_first_layer
|
auto speed = m_is_first_layer
|
||||||
@@ -519,7 +519,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
|||||||
|
|
||||||
/* If target Z is lower than current Z but higher than nominal Z we
|
/* If target Z is lower than current Z but higher than nominal Z we
|
||||||
don't perform the Z move but we only move in the XY plane and
|
don't perform the Z move but we only move in the XY plane and
|
||||||
adjust the nominal Z by reducing the lift amount that will be
|
adjust the nominal Z by reducing the lift amount that will be
|
||||||
used for unlift. */
|
used for unlift. */
|
||||||
// BBS
|
// BBS
|
||||||
Vec3d dest_point = point;
|
Vec3d dest_point = point;
|
||||||
@@ -557,7 +557,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
|||||||
}
|
}
|
||||||
//BBS: LazyLift
|
//BBS: LazyLift
|
||||||
else if (m_to_lift_type == LiftType::LazyLift &&
|
else if (m_to_lift_type == LiftType::LazyLift &&
|
||||||
this->is_current_position_clear() &&
|
this->is_current_position_clear() &&
|
||||||
atan2(delta(2), delta_no_z.norm()) < this->extruder()->travel_slope()) {
|
atan2(delta(2), delta_no_z.norm()) < this->extruder()->travel_slope()) {
|
||||||
//BBS: check whether we can make a travel like
|
//BBS: check whether we can make a travel like
|
||||||
// _____
|
// _____
|
||||||
@@ -612,7 +612,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
|||||||
the lift. */
|
the lift. */
|
||||||
m_lifted = 0;
|
m_lifted = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//BBS: take plate offset into consider
|
//BBS: take plate offset into consider
|
||||||
Vec3d point_on_plate = { dest_point(0) - m_x_offset, dest_point(1) - m_y_offset, dest_point(2) };
|
Vec3d point_on_plate = { dest_point(0) - m_x_offset, dest_point(1) - m_y_offset, dest_point(2) };
|
||||||
std::string out_string;
|
std::string out_string;
|
||||||
@@ -649,7 +649,7 @@ std::string GCodeWriter::travel_to_z(double z, const std::string &comment)
|
|||||||
m_lifted = 0.;
|
m_lifted = 0.;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In all the other cases, we perform an actual Z move and cancel
|
/* In all the other cases, we perform an actual Z move and cancel
|
||||||
the lift. */
|
the lift. */
|
||||||
m_lifted = 0;
|
m_lifted = 0;
|
||||||
@@ -665,7 +665,7 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
|
|||||||
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
||||||
: this->config.travel_speed.value;
|
: this->config.travel_speed.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
GCodeG1Formatter w;
|
GCodeG1Formatter w;
|
||||||
w.emit_z(z);
|
w.emit_z(z);
|
||||||
w.emit_f(speed * 60.0);
|
w.emit_f(speed * 60.0);
|
||||||
@@ -683,7 +683,7 @@ std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, c
|
|||||||
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
||||||
: this->config.travel_speed.value;
|
: this->config.travel_speed.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string output = "G17\n";
|
std::string output = "G17\n";
|
||||||
GCodeG2G3Formatter w(true);
|
GCodeG2G3Formatter w(true);
|
||||||
w.emit_z(z);
|
w.emit_z(z);
|
||||||
@@ -717,7 +717,7 @@ std::string GCodeWriter::extrude_to_xy(const Vec2d &point, double dE, const std:
|
|||||||
m_pos(1) = point(1);
|
m_pos(1) = point(1);
|
||||||
if(std::abs(dE) <= std::numeric_limits<double>::epsilon())
|
if(std::abs(dE) <= std::numeric_limits<double>::epsilon())
|
||||||
force_no_extrusion = true;
|
force_no_extrusion = true;
|
||||||
|
|
||||||
if (!force_no_extrusion)
|
if (!force_no_extrusion)
|
||||||
m_extruder->extrude(dE);
|
m_extruder->extrude(dE);
|
||||||
|
|
||||||
@@ -761,7 +761,7 @@ std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std
|
|||||||
m_lifted = 0;
|
m_lifted = 0;
|
||||||
if (!force_no_extrusion)
|
if (!force_no_extrusion)
|
||||||
m_extruder->extrude(dE);
|
m_extruder->extrude(dE);
|
||||||
|
|
||||||
//BBS: take plate offset into consider
|
//BBS: take plate offset into consider
|
||||||
Vec3d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset, point(2) };
|
Vec3d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset, point(2) };
|
||||||
|
|
||||||
@@ -819,7 +819,7 @@ std::string GCodeWriter::_retract(double length, double restart_extra, const std
|
|||||||
gcode = w.string();
|
gcode = w.string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAVOR_IS(gcfMakerWare))
|
if (FLAVOR_IS(gcfMakerWare))
|
||||||
gcode += "M103 ; extruder off\n";
|
gcode += "M103 ; extruder off\n";
|
||||||
|
|
||||||
@@ -829,10 +829,10 @@ std::string GCodeWriter::_retract(double length, double restart_extra, const std
|
|||||||
std::string GCodeWriter::unretract()
|
std::string GCodeWriter::unretract()
|
||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
|
|
||||||
if (FLAVOR_IS(gcfMakerWare))
|
if (FLAVOR_IS(gcfMakerWare))
|
||||||
gcode = "M101 ; extruder on\n";
|
gcode = "M101 ; extruder on\n";
|
||||||
|
|
||||||
if (double dE = m_extruder->unretract(); !is_zero(dE)) {
|
if (double dE = m_extruder->unretract(); !is_zero(dE)) {
|
||||||
if (this->config.use_firmware_retraction) {
|
if (this->config.use_firmware_retraction) {
|
||||||
gcode += FLAVOR_IS(gcfMachinekit) ? "G23 ; unretract\n" : "G11 ; unretract\n";
|
gcode += FLAVOR_IS(gcfMachinekit) ? "G23 ; unretract\n" : "G11 ; unretract\n";
|
||||||
@@ -849,7 +849,7 @@ std::string GCodeWriter::unretract()
|
|||||||
gcode += w.string();
|
gcode += w.string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -919,7 +919,7 @@ std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, unsigned int sp
|
|||||||
default:
|
default:
|
||||||
gcode << "M106 S" << static_cast<unsigned int>(255.5 * speed / 100.0); break;
|
gcode << "M106 S" << static_cast<unsigned int>(255.5 * speed / 100.0); break;
|
||||||
}
|
}
|
||||||
if (GCodeWriter::full_gcode_comment)
|
if (GCodeWriter::full_gcode_comment)
|
||||||
gcode << " ; enable fan";
|
gcode << " ; enable fan";
|
||||||
gcode << "\n";
|
gcode << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,19 +47,19 @@ void Layer::make_slices()
|
|||||||
polygons_append(slices_p, to_polygons(layerm->slices.surfaces));
|
polygons_append(slices_p, to_polygons(layerm->slices.surfaces));
|
||||||
slices = union_safety_offset_ex(slices_p);
|
slices = union_safety_offset_ex(slices_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->lslices.clear();
|
this->lslices.clear();
|
||||||
this->lslices.reserve(slices.size());
|
this->lslices.reserve(slices.size());
|
||||||
|
|
||||||
// prepare ordering points
|
// prepare ordering points
|
||||||
Points ordering_points;
|
Points ordering_points;
|
||||||
ordering_points.reserve(slices.size());
|
ordering_points.reserve(slices.size());
|
||||||
for (const ExPolygon &ex : slices)
|
for (const ExPolygon &ex : slices)
|
||||||
ordering_points.push_back(ex.contour.first_point());
|
ordering_points.push_back(ex.contour.first_point());
|
||||||
|
|
||||||
// sort slices
|
// sort slices
|
||||||
std::vector<Points::size_type> order = chain_points(ordering_points);
|
std::vector<Points::size_type> order = chain_points(ordering_points);
|
||||||
|
|
||||||
// populate slices vector
|
// populate slices vector
|
||||||
for (size_t i : order)
|
for (size_t i : order)
|
||||||
this->lslices.emplace_back(std::move(slices[i]));
|
this->lslices.emplace_back(std::move(slices[i]));
|
||||||
@@ -178,11 +178,11 @@ bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
|||||||
void Layer::make_perimeters()
|
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
|
||||||
std::vector<unsigned char> done(m_regions.size(), false);
|
std::vector<unsigned char> done(m_regions.size(), false);
|
||||||
|
|
||||||
for (LayerRegionPtrs::iterator layerm = m_regions.begin(); layerm != m_regions.end(); ++ layerm)
|
for (LayerRegionPtrs::iterator layerm = m_regions.begin(); layerm != m_regions.end(); ++ layerm)
|
||||||
if ((*layerm)->slices.empty()) {
|
if ((*layerm)->slices.empty()) {
|
||||||
(*layerm)->perimeters.clear();
|
(*layerm)->perimeters.clear();
|
||||||
(*layerm)->fills.clear();
|
(*layerm)->fills.clear();
|
||||||
@@ -194,7 +194,7 @@ void Layer::make_perimeters()
|
|||||||
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << ", region " << region_id;
|
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << ", region " << region_id;
|
||||||
done[region_id] = true;
|
done[region_id] = true;
|
||||||
const PrintRegion &this_region = (*layerm)->region();
|
const PrintRegion &this_region = (*layerm)->region();
|
||||||
|
|
||||||
// find compatible regions
|
// find compatible regions
|
||||||
LayerRegionPtrs layerms;
|
LayerRegionPtrs layerms;
|
||||||
layerms.push_back(*layerm);
|
layerms.push_back(*layerm);
|
||||||
@@ -211,7 +211,7 @@ void Layer::make_perimeters()
|
|||||||
done[it - m_regions.begin()] = true;
|
done[it - m_regions.begin()] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layerms.size() == 1) { // optimization
|
if (layerms.size() == 1) { // optimization
|
||||||
(*layerm)->fill_surfaces.surfaces.clear();
|
(*layerm)->fill_surfaces.surfaces.clear();
|
||||||
(*layerm)->make_perimeters((*layerm)->slices, {*layerm}, &(*layerm)->fill_surfaces, &(*layerm)->fill_no_overlap_expolygons);
|
(*layerm)->make_perimeters((*layerm)->slices, {*layerm}, &(*layerm)->fill_surfaces, &(*layerm)->fill_no_overlap_expolygons);
|
||||||
@@ -233,7 +233,7 @@ void Layer::make_perimeters()
|
|||||||
for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
|
for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
|
||||||
new_slices.append(offset_ex(surfaces_with_extra_perimeters.second, ClipperSafetyOffset), surfaces_with_extra_perimeters.second.front());
|
new_slices.append(offset_ex(surfaces_with_extra_perimeters.second, ClipperSafetyOffset), surfaces_with_extra_perimeters.second.front());
|
||||||
}
|
}
|
||||||
|
|
||||||
// make perimeters
|
// make perimeters
|
||||||
SurfaceCollection fill_surfaces;
|
SurfaceCollection fill_surfaces;
|
||||||
//BBS
|
//BBS
|
||||||
@@ -241,7 +241,7 @@ void Layer::make_perimeters()
|
|||||||
layerm_config->make_perimeters(new_slices, layerms, &fill_surfaces, &fill_no_overlap);
|
layerm_config->make_perimeters(new_slices, layerms, &fill_surfaces, &fill_no_overlap);
|
||||||
|
|
||||||
// assign fill_surfaces to each layer
|
// assign fill_surfaces to each layer
|
||||||
if (!fill_surfaces.surfaces.empty()) {
|
if (!fill_surfaces.surfaces.empty()) {
|
||||||
for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
|
for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
|
||||||
// Separate the fill surfaces.
|
// Separate the fill surfaces.
|
||||||
ExPolygons expp = intersection_ex(fill_surfaces.surfaces, (*l)->slices.surfaces);
|
ExPolygons expp = intersection_ex(fill_surfaces.surfaces, (*l)->slices.surfaces);
|
||||||
@@ -272,7 +272,7 @@ void Layer::export_region_slices_to_svg(const char *path) const
|
|||||||
for (const auto &surface : region->slices.surfaces)
|
for (const auto &surface : region->slices.surfaces)
|
||||||
svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
|
svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
|
||||||
export_surface_type_legend_to_svg(svg, legend_pos);
|
export_surface_type_legend_to_svg(svg, legend_pos);
|
||||||
svg.Close();
|
svg.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export to "out/LayerRegion-name-%d.svg" with an increasing index with every export.
|
// Export to "out/LayerRegion-name-%d.svg" with an increasing index with every export.
|
||||||
@@ -422,6 +422,15 @@ coordf_t Layer::get_sparse_infill_max_void_area()
|
|||||||
return max_void_area;
|
return max_void_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Layer::get_extruder_id(unsigned int filament_id) const
|
||||||
|
{
|
||||||
|
std::vector<int> filament_map = m_object->print()->get_filament_maps();
|
||||||
|
if (filament_id < filament_map.size()) {
|
||||||
|
return filament_map[filament_id];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BoundingBox get_extents(const LayerRegion &layer_region)
|
BoundingBox get_extents(const LayerRegion &layer_region)
|
||||||
{
|
{
|
||||||
BoundingBox bbox;
|
BoundingBox bbox;
|
||||||
|
|||||||
@@ -241,6 +241,8 @@ public:
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t get_extruder_id(unsigned int filament_id) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class PrintObject;
|
friend class PrintObject;
|
||||||
friend std::vector<Layer*> new_layers(PrintObject*, const std::vector<coordf_t>&);
|
friend std::vector<Layer*> new_layers(PrintObject*, const std::vector<coordf_t>&);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
unsigned short depth;
|
unsigned short depth;
|
||||||
// Children contour, may be both CCW and CW oriented (outer contours or holes).
|
// Children contour, may be both CCW and CW oriented (outer contours or holes).
|
||||||
std::vector<PerimeterGeneratorLoop> children;
|
std::vector<PerimeterGeneratorLoop> children;
|
||||||
|
|
||||||
PerimeterGeneratorLoop(const Polygon &polygon, unsigned short depth, bool is_contour, bool is_small_width_perimeter = false) :
|
PerimeterGeneratorLoop(const Polygon &polygon, unsigned short depth, bool is_contour, bool is_small_width_perimeter = false) :
|
||||||
polygon(polygon), is_contour(is_contour), is_smaller_width_perimeter(is_small_width_perimeter), depth(depth) {}
|
polygon(polygon), is_contour(is_contour), is_smaller_width_perimeter(is_small_width_perimeter), depth(depth) {}
|
||||||
// External perimeter. It may be CCW or CW oriented (outer contour or hole contour).
|
// External perimeter. It may be CCW or CW oriented (outer contour or hole contour).
|
||||||
@@ -111,7 +111,7 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
|
|||||||
for (const PerimeterGeneratorLoop &loop : loops) {
|
for (const PerimeterGeneratorLoop &loop : loops) {
|
||||||
bool is_external = loop.is_external();
|
bool is_external = loop.is_external();
|
||||||
bool is_small_width = loop.is_smaller_width_perimeter;
|
bool is_small_width = loop.is_smaller_width_perimeter;
|
||||||
|
|
||||||
ExtrusionRole role;
|
ExtrusionRole role;
|
||||||
ExtrusionLoopRole loop_role;
|
ExtrusionLoopRole loop_role;
|
||||||
role = is_external ? erExternalPerimeter : erPerimeter;
|
role = is_external ? erExternalPerimeter : erPerimeter;
|
||||||
@@ -225,13 +225,13 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime
|
|||||||
|
|
||||||
coll.append(ExtrusionLoop(std::move(paths), loop_role));
|
coll.append(ExtrusionLoop(std::move(paths), loop_role));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append thin walls to the nearest-neighbor search (only for first iteration)
|
// Append thin walls to the nearest-neighbor search (only for first iteration)
|
||||||
if (! thin_walls.empty()) {
|
if (! thin_walls.empty()) {
|
||||||
variable_width(thin_walls, erExternalPerimeter, perimeter_generator.ext_perimeter_flow, coll.entities);
|
variable_width(thin_walls, erExternalPerimeter, perimeter_generator.ext_perimeter_flow, coll.entities);
|
||||||
thin_walls.clear();
|
thin_walls.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traverse children and build the final collection.
|
// Traverse children and build the final collection.
|
||||||
Point zero_point(0, 0);
|
Point zero_point(0, 0);
|
||||||
std::vector<std::pair<size_t, bool>> chain = chain_extrusion_entities(coll.entities, &zero_point);
|
std::vector<std::pair<size_t, bool>> chain = chain_extrusion_entities(coll.entities, &zero_point);
|
||||||
@@ -1133,10 +1133,10 @@ void PerimeterGenerator::process_classic()
|
|||||||
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.width() + this->perimeter_flow.width()));
|
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.width() + this->perimeter_flow.width()));
|
||||||
else
|
else
|
||||||
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing()));
|
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing()));
|
||||||
|
|
||||||
// overhang perimeters
|
// overhang perimeters
|
||||||
m_mm3_per_mm_overhang = this->overhang_flow.mm3_per_mm();
|
m_mm3_per_mm_overhang = this->overhang_flow.mm3_per_mm();
|
||||||
|
|
||||||
// solid infill
|
// solid infill
|
||||||
coord_t solid_infill_spacing = this->solid_infill_flow.scaled_spacing();
|
coord_t solid_infill_spacing = this->solid_infill_flow.scaled_spacing();
|
||||||
|
|
||||||
@@ -1148,7 +1148,7 @@ void PerimeterGenerator::process_classic()
|
|||||||
double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->wall_filament - 1);
|
double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->wall_filament - 1);
|
||||||
m_lower_slices_polygons = offset(*this->lower_slices, float(scale_(+nozzle_diameter / 2)));
|
m_lower_slices_polygons = offset(*this->lower_slices, float(scale_(+nozzle_diameter / 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the minimum required spacing between two adjacent traces.
|
// Calculate the minimum required spacing between two adjacent traces.
|
||||||
// This should be equal to the nominal flow spacing but we experiment
|
// This should be equal to the nominal flow spacing but we experiment
|
||||||
// with some tolerance in order to avoid triggering medial axis when
|
// with some tolerance in order to avoid triggering medial axis when
|
||||||
@@ -1157,7 +1157,7 @@ void PerimeterGenerator::process_classic()
|
|||||||
// For ext_min_spacing we use the ext_perimeter_spacing calculated for two adjacent
|
// For ext_min_spacing we use the ext_perimeter_spacing calculated for two adjacent
|
||||||
// external loops (which is the correct way) instead of using ext_perimeter_spacing2
|
// external loops (which is the correct way) instead of using ext_perimeter_spacing2
|
||||||
// which is the spacing between external and internal, which is not correct
|
// which is the spacing between external and internal, which is not correct
|
||||||
// and would make the collapsing (thus the details resolution) dependent on
|
// and would make the collapsing (thus the details resolution) dependent on
|
||||||
// internal flow which is unrelated.
|
// internal flow which is unrelated.
|
||||||
coord_t min_spacing = coord_t(perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
coord_t min_spacing = coord_t(perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
||||||
coord_t ext_min_spacing = coord_t(ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
coord_t ext_min_spacing = coord_t(ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
||||||
@@ -1275,16 +1275,16 @@ void PerimeterGenerator::process_classic()
|
|||||||
coord_t distance = (i == 1) ? ext_perimeter_spacing2 : perimeter_spacing;
|
coord_t distance = (i == 1) ? ext_perimeter_spacing2 : perimeter_spacing;
|
||||||
//BBS
|
//BBS
|
||||||
//offsets = this->config->thin_walls ?
|
//offsets = this->config->thin_walls ?
|
||||||
// This path will ensure, that the perimeters do not overfill, as in
|
// This path will ensure, that the perimeters do not overfill, as in
|
||||||
// prusa3d/Slic3r GH #32, but with the cost of rounding the perimeters
|
// prusa3d/Slic3r GH #32, but with the cost of rounding the perimeters
|
||||||
// excessively, creating gaps, which then need to be filled in by the not very
|
// excessively, creating gaps, which then need to be filled in by the not very
|
||||||
// reliable gap fill algorithm.
|
// reliable gap fill algorithm.
|
||||||
// Also the offset2(perimeter, -x, x) may sometimes lead to a perimeter, which is larger than
|
// Also the offset2(perimeter, -x, x) may sometimes lead to a perimeter, which is larger than
|
||||||
// the original.
|
// the original.
|
||||||
//offset2_ex(last,
|
//offset2_ex(last,
|
||||||
// - float(distance + min_spacing / 2. - 1.),
|
// - float(distance + min_spacing / 2. - 1.),
|
||||||
// float(min_spacing / 2. - 1.)) :
|
// float(min_spacing / 2. - 1.)) :
|
||||||
// If "detect thin walls" is not enabled, this paths will be entered, which
|
// If "detect thin walls" is not enabled, this paths will be entered, which
|
||||||
// leads to overflows, as in prusa3d/Slic3r GH #32
|
// leads to overflows, as in prusa3d/Slic3r GH #32
|
||||||
//offset_ex(last, - float(distance));
|
//offset_ex(last, - float(distance));
|
||||||
|
|
||||||
@@ -1352,7 +1352,7 @@ void PerimeterGenerator::process_classic()
|
|||||||
|
|
||||||
if (i == loop_number && (! has_gap_fill || this->config->sparse_infill_density.value == 0)) {
|
if (i == loop_number && (! has_gap_fill || this->config->sparse_infill_density.value == 0)) {
|
||||||
// The last run of this loop is executed to collect gaps for gap fill.
|
// The last run of this loop is executed to collect gaps for gap fill.
|
||||||
// As the gap fill is either disabled or not
|
// As the gap fill is either disabled or not
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1545,7 +1545,7 @@ void PerimeterGenerator::process_classic()
|
|||||||
|
|
||||||
// fill gaps
|
// fill gaps
|
||||||
if (! gaps.empty()) {
|
if (! gaps.empty()) {
|
||||||
// collapse
|
// collapse
|
||||||
double min = 0.2 * perimeter_width * (1 - INSET_OVERLAP_TOLERANCE);
|
double min = 0.2 * perimeter_width * (1 - INSET_OVERLAP_TOLERANCE);
|
||||||
double max = 2. * perimeter_spacing;
|
double max = 2. * perimeter_spacing;
|
||||||
ExPolygons gaps_ex = diff_ex(
|
ExPolygons gaps_ex = diff_ex(
|
||||||
@@ -1602,7 +1602,7 @@ void PerimeterGenerator::process_classic()
|
|||||||
// we offset by half the perimeter spacing (to get to the actual infill boundary)
|
// we offset by half the perimeter spacing (to get to the actual infill boundary)
|
||||||
// and then we offset back and forth by half the infill spacing to only consider the
|
// and then we offset back and forth by half the infill spacing to only consider the
|
||||||
// non-collapsing regions
|
// non-collapsing regions
|
||||||
coord_t inset =
|
coord_t inset =
|
||||||
(loop_number < 0) ? 0 :
|
(loop_number < 0) ? 0 :
|
||||||
(loop_number == 0) ?
|
(loop_number == 0) ?
|
||||||
// one loop
|
// one loop
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ void PlaceholderParser::update_timestamp(DynamicConfig &config)
|
|||||||
time_t rawtime;
|
time_t rawtime;
|
||||||
time(&rawtime);
|
time(&rawtime);
|
||||||
struct tm* timeinfo = localtime(&rawtime);
|
struct tm* timeinfo = localtime(&rawtime);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << (1900 + timeinfo->tm_year);
|
ss << (1900 + timeinfo->tm_year);
|
||||||
@@ -214,7 +214,7 @@ namespace client
|
|||||||
explicit expr(const char *s) : m_type(TYPE_STRING) { m_data.s = new std::string(s); }
|
explicit expr(const char *s) : m_type(TYPE_STRING) { m_data.s = new std::string(s); }
|
||||||
explicit expr(const std::string &s) : m_type(TYPE_STRING) { m_data.s = new std::string(s); }
|
explicit expr(const std::string &s) : m_type(TYPE_STRING) { m_data.s = new std::string(s); }
|
||||||
explicit expr(std::string &&s) : m_type(TYPE_STRING) { m_data.s = new std::string(std::move(s)); }
|
explicit expr(std::string &&s) : m_type(TYPE_STRING) { m_data.s = new std::string(std::move(s)); }
|
||||||
explicit expr(const std::string &s, const Iterator &it_begin, const Iterator &it_end) :
|
explicit expr(const std::string &s, const Iterator &it_begin, const Iterator &it_end) :
|
||||||
m_type(TYPE_STRING), it_range(it_begin, it_end) { m_data.s = new std::string(s); }
|
m_type(TYPE_STRING), it_range(it_begin, it_end) { m_data.s = new std::string(s); }
|
||||||
explicit expr(expr &&rhs, const Iterator &it_begin, const Iterator &it_end) : m_type(rhs.type()), it_range{ it_begin, it_end }
|
explicit expr(expr &&rhs, const Iterator &it_begin, const Iterator &it_end) : m_type(rhs.type()), it_range{ it_begin, it_end }
|
||||||
{
|
{
|
||||||
@@ -233,8 +233,8 @@ namespace client
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr &operator=(expr &&rhs)
|
expr &operator=(expr &&rhs)
|
||||||
{
|
{
|
||||||
if (this != &rhs) {
|
if (this != &rhs) {
|
||||||
this->reset();
|
this->reset();
|
||||||
m_type = rhs.type();
|
m_type = rhs.type();
|
||||||
@@ -245,7 +245,7 @@ namespace client
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
if (this->type() == TYPE_STRING)
|
if (this->type() == TYPE_STRING)
|
||||||
delete m_data.s;
|
delete m_data.s;
|
||||||
@@ -298,8 +298,8 @@ namespace client
|
|||||||
else
|
else
|
||||||
this->set_s_take_ownership(new std::string(s));
|
this->set_s_take_ownership(new std::string(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string() const
|
std::string to_string() const
|
||||||
{
|
{
|
||||||
std::string out;
|
std::string out;
|
||||||
switch (this->type()) {
|
switch (this->type()) {
|
||||||
@@ -308,7 +308,7 @@ namespace client
|
|||||||
break;
|
break;
|
||||||
case TYPE_BOOL: out = this->b() ? "true" : "false"; break;
|
case TYPE_BOOL: out = this->b() ? "true" : "false"; break;
|
||||||
case TYPE_INT: out = std::to_string(this->i()); break;
|
case TYPE_INT: out = std::to_string(this->i()); break;
|
||||||
case TYPE_DOUBLE:
|
case TYPE_DOUBLE:
|
||||||
#if 0
|
#if 0
|
||||||
// The default converter produces trailing zeros after the decimal point.
|
// The default converter produces trailing zeros after the decimal point.
|
||||||
out = std::to_string(data.d);
|
out = std::to_string(data.d);
|
||||||
@@ -333,7 +333,7 @@ namespace client
|
|||||||
IteratorRange it_range;
|
IteratorRange it_range;
|
||||||
|
|
||||||
expr unary_minus(const Iterator start_pos) const
|
expr unary_minus(const Iterator start_pos) const
|
||||||
{
|
{
|
||||||
switch (this->type()) {
|
switch (this->type()) {
|
||||||
case TYPE_EMPTY:
|
case TYPE_EMPTY:
|
||||||
// Inside an if / else block to be skipped.
|
// Inside an if / else block to be skipped.
|
||||||
@@ -351,7 +351,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
expr unary_integer(const Iterator start_pos) const
|
expr unary_integer(const Iterator start_pos) const
|
||||||
{
|
{
|
||||||
switch (this->type()) {
|
switch (this->type()) {
|
||||||
case TYPE_EMPTY:
|
case TYPE_EMPTY:
|
||||||
// Inside an if / else block to be skipped.
|
// Inside an if / else block to be skipped.
|
||||||
@@ -369,7 +369,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
expr round(const Iterator start_pos) const
|
expr round(const Iterator start_pos) const
|
||||||
{
|
{
|
||||||
switch (this->type()) {
|
switch (this->type()) {
|
||||||
case TYPE_EMPTY:
|
case TYPE_EMPTY:
|
||||||
// Inside an if / else block to be skipped.
|
// Inside an if / else block to be skipped.
|
||||||
@@ -387,7 +387,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
expr unary_not(const Iterator start_pos) const
|
expr unary_not(const Iterator start_pos) const
|
||||||
{
|
{
|
||||||
switch (this->type()) {
|
switch (this->type()) {
|
||||||
case TYPE_EMPTY:
|
case TYPE_EMPTY:
|
||||||
// Inside an if / else block to be skipped.
|
// Inside an if / else block to be skipped.
|
||||||
@@ -403,7 +403,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
expr &operator+=(const expr &rhs)
|
expr &operator+=(const expr &rhs)
|
||||||
{
|
{
|
||||||
if (this->type() == TYPE_EMPTY) {
|
if (this->type() == TYPE_EMPTY) {
|
||||||
// Inside an if / else block to be skipped.
|
// Inside an if / else block to be skipped.
|
||||||
} else if (this->type() == TYPE_STRING) {
|
} else if (this->type() == TYPE_STRING) {
|
||||||
@@ -426,7 +426,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
expr &operator-=(const expr &rhs)
|
expr &operator-=(const expr &rhs)
|
||||||
{
|
{
|
||||||
if (this->type() == TYPE_EMPTY) {
|
if (this->type() == TYPE_EMPTY) {
|
||||||
// Inside an if / else block to be skipped.
|
// Inside an if / else block to be skipped.
|
||||||
this->reset();
|
this->reset();
|
||||||
@@ -444,7 +444,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
expr &operator*=(const expr &rhs)
|
expr &operator*=(const expr &rhs)
|
||||||
{
|
{
|
||||||
if (this->type() == TYPE_EMPTY) {
|
if (this->type() == TYPE_EMPTY) {
|
||||||
// Inside an if / else block to be skipped.
|
// Inside an if / else block to be skipped.
|
||||||
this->reset();
|
this->reset();
|
||||||
@@ -535,16 +535,16 @@ namespace client
|
|||||||
// Both types are numeric.
|
// Both types are numeric.
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case '=':
|
case '=':
|
||||||
value = (lhs.type() == TYPE_DOUBLE || rhs.type() == TYPE_DOUBLE) ?
|
value = (lhs.type() == TYPE_DOUBLE || rhs.type() == TYPE_DOUBLE) ?
|
||||||
(std::abs(lhs.as_d() - rhs.as_d()) < 1e-8) : (lhs.i() == rhs.i());
|
(std::abs(lhs.as_d() - rhs.as_d()) < 1e-8) : (lhs.i() == rhs.i());
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
value = (lhs.type() == TYPE_DOUBLE || rhs.type() == TYPE_DOUBLE) ?
|
value = (lhs.type() == TYPE_DOUBLE || rhs.type() == TYPE_DOUBLE) ?
|
||||||
(lhs.as_d() < rhs.as_d()) : (lhs.i() < rhs.i());
|
(lhs.as_d() < rhs.as_d()) : (lhs.i() < rhs.i());
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
default:
|
default:
|
||||||
value = (lhs.type() == TYPE_DOUBLE || rhs.type() == TYPE_DOUBLE) ?
|
value = (lhs.type() == TYPE_DOUBLE || rhs.type() == TYPE_DOUBLE) ?
|
||||||
(lhs.as_d() > rhs.as_d()) : (lhs.i() > rhs.i());
|
(lhs.as_d() > rhs.as_d()) : (lhs.i() > rhs.i());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -556,7 +556,7 @@ namespace client
|
|||||||
value = lhs.b() == rhs.b();
|
value = lhs.b() == rhs.b();
|
||||||
} else if (lhs.type() == TYPE_STRING || rhs.type() == TYPE_STRING) {
|
} else if (lhs.type() == TYPE_STRING || rhs.type() == TYPE_STRING) {
|
||||||
// One type is string, the other could be converted to string.
|
// One type is string, the other could be converted to string.
|
||||||
value = (op == '=') ? (lhs.to_string() == rhs.to_string()) :
|
value = (op == '=') ? (lhs.to_string() == rhs.to_string()) :
|
||||||
(op == '<') ? (lhs.to_string() < rhs.to_string()) : (lhs.to_string() > rhs.to_string());
|
(op == '<') ? (lhs.to_string() < rhs.to_string()) : (lhs.to_string() > rhs.to_string());
|
||||||
} else {
|
} else {
|
||||||
boost::throw_exception(qi::expectation_failure<Iterator>(
|
boost::throw_exception(qi::expectation_failure<Iterator>(
|
||||||
@@ -576,7 +576,7 @@ namespace client
|
|||||||
static void throw_if_not_numeric(const expr ¶m)
|
static void throw_if_not_numeric(const expr ¶m)
|
||||||
{
|
{
|
||||||
const char *err_msg = "Not a numeric type.";
|
const char *err_msg = "Not a numeric type.";
|
||||||
param.throw_if_not_numeric(err_msg);
|
param.throw_if_not_numeric(err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Function2ParamsType {
|
enum Function2ParamsType {
|
||||||
@@ -585,7 +585,7 @@ namespace client
|
|||||||
};
|
};
|
||||||
// Store the result into param1.
|
// Store the result into param1.
|
||||||
static void function_2params(expr ¶m1, expr ¶m2, Function2ParamsType fun)
|
static void function_2params(expr ¶m1, expr ¶m2, Function2ParamsType fun)
|
||||||
{
|
{
|
||||||
if (param1.type() == TYPE_EMPTY)
|
if (param1.type() == TYPE_EMPTY)
|
||||||
// Inside an if / else block to be skipped
|
// Inside an if / else block to be skipped
|
||||||
return;
|
return;
|
||||||
@@ -615,7 +615,7 @@ namespace client
|
|||||||
|
|
||||||
// Store the result into param1.
|
// Store the result into param1.
|
||||||
static void random(expr ¶m1, expr ¶m2, std::mt19937 &rng)
|
static void random(expr ¶m1, expr ¶m2, std::mt19937 &rng)
|
||||||
{
|
{
|
||||||
if (param1.type() == TYPE_EMPTY)
|
if (param1.type() == TYPE_EMPTY)
|
||||||
// Inside an if / else block to be skipped
|
// Inside an if / else block to be skipped
|
||||||
return;
|
return;
|
||||||
@@ -631,7 +631,7 @@ namespace client
|
|||||||
// param3 is optional
|
// param3 is optional
|
||||||
template<bool leading_zeros>
|
template<bool leading_zeros>
|
||||||
static void digits(expr ¶m1, expr ¶m2, expr ¶m3)
|
static void digits(expr ¶m1, expr ¶m2, expr ¶m3)
|
||||||
{
|
{
|
||||||
if (param1.type() == TYPE_EMPTY)
|
if (param1.type() == TYPE_EMPTY)
|
||||||
// Inside an if / else block to be skipped
|
// Inside an if / else block to be skipped
|
||||||
return;
|
return;
|
||||||
@@ -738,13 +738,13 @@ namespace client
|
|||||||
static void logical_or (expr &lhs, expr &rhs) { logical_op(lhs, rhs, '|'); }
|
static void logical_or (expr &lhs, expr &rhs) { logical_op(lhs, rhs, '|'); }
|
||||||
static void logical_and(expr &lhs, expr &rhs) { logical_op(lhs, rhs, '&'); }
|
static void logical_and(expr &lhs, expr &rhs) { logical_op(lhs, rhs, '&'); }
|
||||||
|
|
||||||
void throw_exception(const char *message) const
|
void throw_exception(const char *message) const
|
||||||
{
|
{
|
||||||
boost::throw_exception(qi::expectation_failure<Iterator>(
|
boost::throw_exception(qi::expectation_failure<Iterator>(
|
||||||
this->it_range.begin(), this->it_range.end(), spirit::info(std::string("*") + message)));
|
this->it_range.begin(), this->it_range.end(), spirit::info(std::string("*") + message)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void throw_if_not_numeric(const char *message) const
|
void throw_if_not_numeric(const char *message) const
|
||||||
{
|
{
|
||||||
if (! this->numeric_type())
|
if (! this->numeric_type())
|
||||||
this->throw_exception(message);
|
this->throw_exception(message);
|
||||||
@@ -794,7 +794,7 @@ namespace client
|
|||||||
mutable DynamicConfig *config_outputs = nullptr;
|
mutable DynamicConfig *config_outputs = nullptr;
|
||||||
// Local variables, read / write
|
// Local variables, read / write
|
||||||
mutable DynamicConfig config_local;
|
mutable DynamicConfig config_local;
|
||||||
size_t current_extruder_id = 0;
|
size_t current_extruder_id = 0; // This is filament_id actually
|
||||||
// Random number generator and optionally global variables.
|
// Random number generator and optionally global variables.
|
||||||
PlaceholderParser::ContextData *context_data = nullptr;
|
PlaceholderParser::ContextData *context_data = nullptr;
|
||||||
// If false, the macro_processor will evaluate a full macro.
|
// If false, the macro_processor will evaluate a full macro.
|
||||||
@@ -805,7 +805,14 @@ namespace client
|
|||||||
// Table to translate symbol tag to a human readable error message.
|
// Table to translate symbol tag to a human readable error message.
|
||||||
static std::map<std::string, std::string> tag_to_error_message;
|
static std::map<std::string, std::string> tag_to_error_message;
|
||||||
|
|
||||||
// Should the parser consider the parsed string to be a macro or a boolean expression?
|
size_t get_extruder_id() const {
|
||||||
|
const ConfigOptionInts * filament_map_opt = external_config->option<ConfigOptionInts>("filament_map");
|
||||||
|
if (filament_map_opt && current_extruder_id < filament_map_opt->values.size()) {
|
||||||
|
return filament_map_opt->values[current_extruder_id];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool evaluate_full_macro(const MyContext *ctx) { return ! ctx->just_boolean_expression; }
|
static bool evaluate_full_macro(const MyContext *ctx) { return ! ctx->just_boolean_expression; }
|
||||||
|
|
||||||
// Entering a conditional block.
|
// Entering a conditional block.
|
||||||
@@ -908,7 +915,7 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void legacy_variable_expansion2(
|
static void legacy_variable_expansion2(
|
||||||
const MyContext *ctx,
|
const MyContext *ctx,
|
||||||
IteratorRange &opt_key,
|
IteratorRange &opt_key,
|
||||||
IteratorRange &opt_vector_index,
|
IteratorRange &opt_vector_index,
|
||||||
std::string &output)
|
std::string &output)
|
||||||
@@ -1546,7 +1553,7 @@ namespace client
|
|||||||
static void evaluate_index(expr &expr_index, int &output)
|
static void evaluate_index(expr &expr_index, int &output)
|
||||||
{
|
{
|
||||||
if (expr_index.type() != expr::TYPE_EMPTY) {
|
if (expr_index.type() != expr::TYPE_EMPTY) {
|
||||||
if (expr_index.type() != expr::TYPE_INT)
|
if (expr_index.type() != expr::TYPE_INT)
|
||||||
expr_index.throw_exception("Non-integer index is not allowed to address a vector variable.");
|
expr_index.throw_exception("Non-integer index is not allowed to address a vector variable.");
|
||||||
output = expr_index.i();
|
output = expr_index.i();
|
||||||
}
|
}
|
||||||
@@ -1738,11 +1745,11 @@ namespace client
|
|||||||
// This parser is to be used inside a raw[] directive to accept a single valid UTF-8 character.
|
// This parser is to be used inside a raw[] directive to accept a single valid UTF-8 character.
|
||||||
// If an invalid UTF-8 sequence is encountered, a qi::expectation_failure is thrown.
|
// If an invalid UTF-8 sequence is encountered, a qi::expectation_failure is thrown.
|
||||||
struct utf8_char_parser : qi::primitive_parser<utf8_char_parser>
|
struct utf8_char_parser : qi::primitive_parser<utf8_char_parser>
|
||||||
{
|
{
|
||||||
// Define the attribute type exposed by this parser component
|
// Define the attribute type exposed by this parser component
|
||||||
template <typename Context, typename Iterator>
|
template <typename Context, typename Iterator>
|
||||||
struct attribute
|
struct attribute
|
||||||
{
|
{
|
||||||
typedef wchar_t type;
|
typedef wchar_t type;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1750,7 +1757,7 @@ namespace client
|
|||||||
// Also it throws if it encounters valid or invalid UTF-8 sequence.
|
// Also it throws if it encounters valid or invalid UTF-8 sequence.
|
||||||
template <typename Iterator, typename Context , typename Skipper, typename Attribute>
|
template <typename Iterator, typename Context , typename Skipper, typename Attribute>
|
||||||
bool parse(Iterator &first, Iterator const &last, Context &context, Skipper const &skipper, Attribute& attr) const
|
bool parse(Iterator &first, Iterator const &last, Context &context, Skipper const &skipper, Attribute& attr) const
|
||||||
{
|
{
|
||||||
// The skipper shall always be empty, any white space will be accepted.
|
// The skipper shall always be empty, any white space will be accepted.
|
||||||
// skip_over(first, last, skipper);
|
// skip_over(first, last, skipper);
|
||||||
if (first == last)
|
if (first == last)
|
||||||
@@ -1794,7 +1801,7 @@ namespace client
|
|||||||
// This function is called during error handling to create a human readable string for the error context.
|
// This function is called during error handling to create a human readable string for the error context.
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
spirit::info what(Context&) const
|
spirit::info what(Context&) const
|
||||||
{
|
{
|
||||||
return spirit::info("unicode_char");
|
return spirit::info("unicode_char");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2039,7 +2046,7 @@ namespace client
|
|||||||
legacy_variable_expansion =
|
legacy_variable_expansion =
|
||||||
(identifier >> &lit(']'))
|
(identifier >> &lit(']'))
|
||||||
[ px::bind(&MyContext::legacy_variable_expansion, _r1, _1, _val) ]
|
[ px::bind(&MyContext::legacy_variable_expansion, _r1, _1, _val) ]
|
||||||
| (identifier > lit('[') > identifier > ']')
|
| (identifier > lit('[') > identifier > ']')
|
||||||
[ px::bind(&MyContext::legacy_variable_expansion2, _r1, _1, _2, _val) ]
|
[ px::bind(&MyContext::legacy_variable_expansion2, _r1, _1, _2, _val) ]
|
||||||
;
|
;
|
||||||
legacy_variable_expansion.name("legacy_variable_expansion");
|
legacy_variable_expansion.name("legacy_variable_expansion");
|
||||||
@@ -2057,12 +2064,12 @@ namespace client
|
|||||||
eps[px::bind(&MyContext::block_enter, _r1, ! _a)] > conditional_expression(_r1)[px::bind(&MyContext::block_exit_ternary, _r1, ! _a, _1, _val)]);
|
eps[px::bind(&MyContext::block_enter, _r1, ! _a)] > conditional_expression(_r1)[px::bind(&MyContext::block_exit_ternary, _r1, ! _a, _1, _val)]);
|
||||||
conditional_expression.name("conditional_expression");
|
conditional_expression.name("conditional_expression");
|
||||||
|
|
||||||
logical_or_expression =
|
logical_or_expression =
|
||||||
logical_and_expression(_r1) [_val = _1]
|
logical_and_expression(_r1) [_val = _1]
|
||||||
>> *( ((kw["or"] | "||") > logical_and_expression(_r1) ) [px::bind(&expr::logical_or, _val, _1)] );
|
>> *( ((kw["or"] | "||") > logical_and_expression(_r1) ) [px::bind(&expr::logical_or, _val, _1)] );
|
||||||
logical_or_expression.name("logical_or_expression");
|
logical_or_expression.name("logical_or_expression");
|
||||||
|
|
||||||
logical_and_expression =
|
logical_and_expression =
|
||||||
equality_expression(_r1) [_val = _1]
|
equality_expression(_r1) [_val = _1]
|
||||||
>> *( ((kw["and"] | "&&") > equality_expression(_r1) ) [px::bind(&expr::logical_and, _val, _1)] );
|
>> *( ((kw["and"] | "&&") > equality_expression(_r1) ) [px::bind(&expr::logical_and, _val, _1)] );
|
||||||
logical_and_expression.name("logical_and_expression");
|
logical_and_expression.name("logical_and_expression");
|
||||||
@@ -2082,7 +2089,7 @@ namespace client
|
|||||||
bool_expr_eval = conditional_expression(_r1) [ px::bind(&expr::evaluate_boolean, _1, _val) ];
|
bool_expr_eval = conditional_expression(_r1) [ px::bind(&expr::evaluate_boolean, _1, _val) ];
|
||||||
bool_expr_eval.name("bool_expr_eval");
|
bool_expr_eval.name("bool_expr_eval");
|
||||||
|
|
||||||
relational_expression =
|
relational_expression =
|
||||||
additive_expression(_r1) [_val = _1]
|
additive_expression(_r1) [_val = _1]
|
||||||
>> *( ("<=" > additive_expression(_r1) ) [px::bind(&expr::leq, _val, _1)]
|
>> *( ("<=" > additive_expression(_r1) ) [px::bind(&expr::leq, _val, _1)]
|
||||||
| (">=" > additive_expression(_r1) ) [px::bind(&expr::geq, _val, _1)]
|
| (">=" > additive_expression(_r1) ) [px::bind(&expr::geq, _val, _1)]
|
||||||
@@ -2150,11 +2157,11 @@ namespace client
|
|||||||
| (lit('-') > unary_expression(_r1) ) [ px::bind(&FactorActions::minus_, _1, _val) ]
|
| (lit('-') > unary_expression(_r1) ) [ px::bind(&FactorActions::minus_, _1, _val) ]
|
||||||
| (lit('+') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ]
|
| (lit('+') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ]
|
||||||
| ((kw["not"] | '!') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::not_, _1, _val) ]
|
| ((kw["not"] | '!') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::not_, _1, _val) ]
|
||||||
| (kw["min"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
| (kw["min"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||||
[ px::bind(&expr::min, _val, _2) ]
|
[ px::bind(&expr::min, _val, _2) ]
|
||||||
| (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
| (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||||
[ px::bind(&expr::max, _val, _2) ]
|
[ px::bind(&expr::max, _val, _2) ]
|
||||||
| (kw["random"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
| (kw["random"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
|
||||||
[ px::bind(&MyContext::random, _r1, _val, _2) ]
|
[ px::bind(&MyContext::random, _r1, _val, _2) ]
|
||||||
| (kw["digits"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > optional_parameter(_r1))
|
| (kw["digits"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > optional_parameter(_r1))
|
||||||
[ px::bind(&expr::digits<false>, _val, _2, _3) ]
|
[ px::bind(&expr::digits<false>, _val, _2, _3) ]
|
||||||
|
|||||||
@@ -2603,6 +2603,15 @@ std::vector<int> Print::get_filament_maps() const
|
|||||||
return m_config.filament_map.values;
|
return m_config.filament_map.values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Print::get_extruder_id(unsigned int filament_id) const
|
||||||
|
{
|
||||||
|
std::vector<int> filament_map = get_filament_maps();
|
||||||
|
if (filament_id < filament_map.size()) {
|
||||||
|
return filament_map[filament_id];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Wipe tower support.
|
// Wipe tower support.
|
||||||
bool Print::has_wipe_tower() const
|
bool Print::has_wipe_tower() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -936,6 +936,7 @@ public:
|
|||||||
|
|
||||||
void update_filament_maps_to_config(std::vector<int> f_maps);
|
void update_filament_maps_to_config(std::vector<int> f_maps);
|
||||||
std::vector<int> get_filament_maps() const;
|
std::vector<int> get_filament_maps() const;
|
||||||
|
size_t get_extruder_id(unsigned int filament_id) const;
|
||||||
|
|
||||||
bool enable_timelapse_print() const;
|
bool enable_timelapse_print() const;
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,11 @@ namespace Slic3r {
|
|||||||
#define L(s) (s)
|
#define L(s) (s)
|
||||||
#define _(s) Slic3r::I18N::translate(s)
|
#define _(s) Slic3r::I18N::translate(s)
|
||||||
|
|
||||||
size_t get_extruder_index(unsigned int filament_id)
|
size_t get_extruder_index(const GCodeConfig& config, unsigned int filament_id)
|
||||||
{
|
{
|
||||||
// todo multi_extruders:
|
if (filament_id < config.filament_map.size()) {
|
||||||
|
return config.filament_map.get_at(filament_id);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -462,7 +462,6 @@ static std::string get_bed_temp_1st_layer_key(const BedType type)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_extruder_index(unsigned int filament_id);
|
|
||||||
#define CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(NAME) \
|
#define CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(NAME) \
|
||||||
template<> const t_config_enum_names& ConfigOptionEnum<NAME>::get_enum_names(); \
|
template<> const t_config_enum_names& ConfigOptionEnum<NAME>::get_enum_names(); \
|
||||||
template<> const t_config_enum_values& ConfigOptionEnum<NAME>::get_enum_values();
|
template<> const t_config_enum_values& ConfigOptionEnum<NAME>::get_enum_values();
|
||||||
@@ -1969,6 +1968,8 @@ static void set_flush_volumes_matrix(std::vector<T> &out_matrix, const std::vect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t get_extruder_index(const GCodeConfig& config, unsigned int filament_id);
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
// Serialization through the Cereal library
|
// Serialization through the Cereal library
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ namespace Slic3r {
|
|||||||
float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx)
|
float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx)
|
||||||
{
|
{
|
||||||
const double general_suggested_min_speed = 100.0;
|
const double general_suggested_min_speed = 100.0;
|
||||||
double filament_max_volumetric_speed = config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
|
double filament_max_volumetric_speed = config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(filament_idx);
|
||||||
const float nozzle_diameter = config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0);
|
// todo multi_extruders:
|
||||||
|
const float nozzle_diameter = config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0/*get_extruder_index(filament_idx)*/);
|
||||||
if (line_width <= 0.) line_width = Flow::auto_extrusion_width(frPerimeter, nozzle_diameter);
|
if (line_width <= 0.) line_width = Flow::auto_extrusion_width(frPerimeter, nozzle_diameter);
|
||||||
Flow pattern_line = Flow(line_width, layer_height, nozzle_diameter);
|
Flow pattern_line = Flow(line_width, layer_height, nozzle_diameter);
|
||||||
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloat>("outer_wall_speed")->value),
|
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloat>("outer_wall_speed")->value),
|
||||||
|
|||||||
@@ -303,6 +303,7 @@ public:
|
|||||||
Vec3d get_start_offset();
|
Vec3d get_start_offset();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// todo multi_extruders:
|
||||||
double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; };
|
double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; };
|
||||||
double speed_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_speed")->value; };
|
double speed_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_speed")->value; };
|
||||||
double accel_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_acceleration")->value; }
|
double accel_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_acceleration")->value; }
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#define SLIC3R_SNAPSHOTS_DIR "snapshots"
|
#define SLIC3R_SNAPSHOTS_DIR "snapshots"
|
||||||
#define SLIC3R_SNAPSHOT_FILE "snapshot.ini"
|
#define SLIC3R_SNAPSHOT_FILE "snapshot.ini"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
namespace Config {
|
namespace Config {
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ void Snapshot::load_ini(const std::string &path)
|
|||||||
vc.name = section.first.substr(group_name_vendor.size());
|
vc.name = section.first.substr(group_name_vendor.size());
|
||||||
for (auto &kvp : section.second) {
|
for (auto &kvp : section.second) {
|
||||||
if (kvp.first == "version" || kvp.first == "min_slic3r_version" || kvp.first == "max_slic3r_version") {
|
if (kvp.first == "version" || kvp.first == "min_slic3r_version" || kvp.first == "max_slic3r_version") {
|
||||||
// Version of the vendor specific config bundle bundled with this snapshot.
|
// Version of the vendor specific config bundle bundled with this snapshot.
|
||||||
auto semver = Semver::parse(kvp.second.data());
|
auto semver = Semver::parse(kvp.second.data());
|
||||||
if (! semver)
|
if (! semver)
|
||||||
throw_on_parse_error("invalid " + kvp.first + " format for " + section.first);
|
throw_on_parse_error("invalid " + kvp.first + " format for " + section.first);
|
||||||
@@ -155,11 +155,11 @@ void Snapshot::load_ini(const std::string &path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Sort the vendors lexicographically.
|
// Sort the vendors lexicographically.
|
||||||
std::sort(this->vendor_configs.begin(), this->vendor_configs.begin(),
|
std::sort(this->vendor_configs.begin(), this->vendor_configs.begin(),
|
||||||
[](const VendorConfig &cfg1, const VendorConfig &cfg2) { return cfg1.name < cfg2.name; });
|
[](const VendorConfig &cfg1, const VendorConfig &cfg2) { return cfg1.name < cfg2.name; });
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string reason_string(const Snapshot::Reason reason)
|
static std::string reason_string(const Snapshot::Reason reason)
|
||||||
{
|
{
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case Snapshot::SNAPSHOT_UPGRADE:
|
case Snapshot::SNAPSHOT_UPGRADE:
|
||||||
@@ -372,7 +372,7 @@ static void copy_config_dir_single_level(const boost::filesystem::path &path_src
|
|||||||
{
|
{
|
||||||
//BBS: remove snapshots function currently
|
//BBS: remove snapshots function currently
|
||||||
#if 0
|
#if 0
|
||||||
if (! boost::filesystem::is_directory(path_dst) &&
|
if (! boost::filesystem::is_directory(path_dst) &&
|
||||||
! boost::filesystem::create_directory(path_dst))
|
! boost::filesystem::create_directory(path_dst))
|
||||||
throw Slic3r::RuntimeError(std::string("OrcaSlicer was unable to create a directory at ") + path_dst.string());
|
throw Slic3r::RuntimeError(std::string("OrcaSlicer was unable to create a directory at ") + path_dst.string());
|
||||||
|
|
||||||
@@ -521,7 +521,7 @@ SnapshotDB::const_iterator SnapshotDB::snapshot_with_vendor_preset(const std::st
|
|||||||
key.name = vendor_name;
|
key.name = vendor_name;
|
||||||
for (auto it = m_snapshots.begin(); it != m_snapshots.end(); ++ it) {
|
for (auto it = m_snapshots.begin(); it != m_snapshots.end(); ++ it) {
|
||||||
const Snapshot &snapshot = *it;
|
const Snapshot &snapshot = *it;
|
||||||
auto it_vendor_config = std::lower_bound(snapshot.vendor_configs.begin(), snapshot.vendor_configs.end(),
|
auto it_vendor_config = std::lower_bound(snapshot.vendor_configs.begin(), snapshot.vendor_configs.end(),
|
||||||
key, [](const Snapshot::VendorConfig &cfg1, const Snapshot::VendorConfig &cfg2) { return cfg1.name < cfg2.name; });
|
key, [](const Snapshot::VendorConfig &cfg1, const Snapshot::VendorConfig &cfg2) { return cfg1.name < cfg2.name; });
|
||||||
if (it_vendor_config != snapshot.vendor_configs.end() && it_vendor_config->name == vendor_name &&
|
if (it_vendor_config != snapshot.vendor_configs.end() && it_vendor_config->name == vendor_name &&
|
||||||
config_version == it_vendor_config->version.config_version) {
|
config_version == it_vendor_config->version.config_version) {
|
||||||
@@ -548,7 +548,7 @@ boost::filesystem::path SnapshotDB::create_db_dir()
|
|||||||
for (const boost::filesystem::path &path : { data_dir, snapshots_dir }) {
|
for (const boost::filesystem::path &path : { data_dir, snapshots_dir }) {
|
||||||
boost::filesystem::path subdir = path;
|
boost::filesystem::path subdir = path;
|
||||||
subdir.make_preferred();
|
subdir.make_preferred();
|
||||||
if (! boost::filesystem::is_directory(subdir) &&
|
if (! boost::filesystem::is_directory(subdir) &&
|
||||||
! boost::filesystem::create_directory(subdir))
|
! boost::filesystem::create_directory(subdir))
|
||||||
throw Slic3r::RuntimeError(std::string("Slic3r was unable to create a directory at ") + subdir.string());
|
throw Slic3r::RuntimeError(std::string("Slic3r was unable to create a directory at ") + subdir.string());
|
||||||
}
|
}
|
||||||
@@ -580,7 +580,7 @@ const Snapshot* take_config_snapshot_report_error(const AppConfig &app_config, S
|
|||||||
try {
|
try {
|
||||||
return &SnapshotDB::singleton().take_snapshot(app_config, reason, comment);
|
return &SnapshotDB::singleton().take_snapshot(app_config, reason, comment);
|
||||||
} catch (std::exception &err) {
|
} catch (std::exception &err) {
|
||||||
show_error(static_cast<wxWindow*>(wxGetApp().mainframe),
|
show_error(static_cast<wxWindow*>(wxGetApp().mainframe),
|
||||||
_L("Taking a configuration snapshot failed.") + "\n\n" + from_u8(err.what()));
|
_L("Taking a configuration snapshot failed.") + "\n\n" + from_u8(err.what()));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,12 +48,14 @@ int get_extruder_idx(const DynamicPrintConfig& config, const std::string &opt_ke
|
|||||||
NozzleVolumeType nozzle_volume_type = (NozzleVolumeType) (opt_nozzle_volume_type->get_at(cur_extruder_id));
|
NozzleVolumeType nozzle_volume_type = (NozzleVolumeType) (opt_nozzle_volume_type->get_at(cur_extruder_id));
|
||||||
|
|
||||||
std::string id_name, variant_name;
|
std::string id_name, variant_name;
|
||||||
|
unsigned int stride = 1;
|
||||||
if (printer_options_with_variant_1.count(opt_key) > 0) { // printer parameter
|
if (printer_options_with_variant_1.count(opt_key) > 0) { // printer parameter
|
||||||
id_name = "printer_extruder_id";
|
id_name = "printer_extruder_id";
|
||||||
variant_name = "printer_extruder_variant";
|
variant_name = "printer_extruder_variant";
|
||||||
} else if (printer_options_with_variant_2.count(opt_key) > 0) {
|
} else if (printer_options_with_variant_2.count(opt_key) > 0) {
|
||||||
id_name = "printer_extruder_id";
|
id_name = "printer_extruder_id";
|
||||||
variant_name = "printer_extruder_variant";
|
variant_name = "printer_extruder_variant";
|
||||||
|
stride = 2;
|
||||||
} else if (filament_options_with_variant.count(opt_key) > 0) {
|
} else if (filament_options_with_variant.count(opt_key) > 0) {
|
||||||
//filament don't use id anymore
|
//filament don't use id anymore
|
||||||
//id_name = "filament_extruder_id";
|
//id_name = "filament_extruder_id";
|
||||||
@@ -66,7 +68,7 @@ int get_extruder_idx(const DynamicPrintConfig& config, const std::string &opt_ke
|
|||||||
}
|
}
|
||||||
|
|
||||||
// variant index
|
// variant index
|
||||||
int variant_index = config.get_index_for_extruder(cur_extruder_id + 1, id_name, extruder_type, nozzle_volume_type, variant_name);
|
int variant_index = config.get_index_for_extruder(cur_extruder_id + 1, id_name, extruder_type, nozzle_volume_type, variant_name, stride);
|
||||||
if (variant_index < 0) {
|
if (variant_index < 0) {
|
||||||
assert(false);
|
assert(false);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ void SidePopup::Popup(wxWindow* focus)
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pos.x = pos.x - FromDIP(20);
|
pos.x = pos.x - FromDIP(20);
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
if (pos.x + max_width > screenwidth)
|
if (pos.x + max_width > screenwidth)
|
||||||
Position({pos.x - (pos.x + max_width - screenwidth),pos.y}, {0, focus->GetSize().y + 12});
|
Position({pos.x - (pos.x + max_width - screenwidth),pos.y}, {0, focus->GetSize().y + 12});
|
||||||
else
|
else
|
||||||
@@ -88,7 +88,7 @@ void SidePopup::Create()
|
|||||||
size.x = max_width;
|
size.x = max_width;
|
||||||
btn->SetMinSize(size);
|
btn->SetMinSize(size);
|
||||||
btn->SetSize(size);
|
btn->SetSize(size);
|
||||||
sizer->Add(btn, 0, 0, 0);
|
sizer->Add(btn, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetSize(wxSize(max_width, height));
|
SetSize(wxSize(max_width, height));
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ static bool is_same_nozzle_diameters(const DynamicPrintConfig &full_config, cons
|
|||||||
error_msg = _L("Your nozzle diameter in preset is not consistent with memorized nozzle diameter. Did you change your nozzle lately?") + "\n " + nozzle_in_preset +
|
error_msg = _L("Your nozzle diameter in preset is not consistent with memorized nozzle diameter. Did you change your nozzle lately?") + "\n " + nozzle_in_preset +
|
||||||
"\n " + nozzle_in_printer + "\n";
|
"\n " + nozzle_in_printer + "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
@@ -615,7 +615,7 @@ void CalibUtils::calib_pa_pattern(const CalibInfo &calib_info, Model& model)
|
|||||||
new ConfigOptionFloat(CalibPressureAdvance::find_optimal_PA_speed(
|
new ConfigOptionFloat(CalibPressureAdvance::find_optimal_PA_speed(
|
||||||
full_config, print_config.get_abs_value("line_width"),
|
full_config, print_config.get_abs_value("line_width"),
|
||||||
print_config.get_abs_value("layer_height"), 0)));
|
print_config.get_abs_value("layer_height"), 0)));
|
||||||
|
|
||||||
for (const auto& opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) {
|
for (const auto& opt : SuggestedConfigCalibPAPattern().nozzle_ratio_pairs) {
|
||||||
print_config.set_key_value(opt.first, new ConfigOptionFloatOrPercent(nozzle_diameter * opt.second / 100, false));
|
print_config.set_key_value(opt.first, new ConfigOptionFloatOrPercent(nozzle_diameter * opt.second / 100, false));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user