Information from DoubleSlider is saved to Model

GCode creating can work with that values.
This commit is contained in:
YuSanka 2019-10-10 16:03:58 +02:00
parent 6ac53aa4f3
commit 70ef0f25ef
10 changed files with 193 additions and 43 deletions

View File

@ -870,8 +870,11 @@ void GCode::_do_export(Print &print, FILE *file)
this->apply_print_config(print.config());
this->set_extruders(print.extruders());
// Initialize colorprint.
// #ys_FIXME_COLOR // Initialize colorprint.
m_colorprint_heights = cast<float>(print.config().colorprint_heights.values);
// Initialize custom gcode
Model* model = print.get_object(0)->model_object()->get_model();
m_custom_g_code_heights = model->custom_gcode_per_height;
// Initialize autospeed.
{
@ -1676,8 +1679,15 @@ void GCode::process_layer(
// In case there are more toolchange requests that weren't done yet and should happen simultaneously, erase them all.
// (Layers can be close to each other, model could have been resliced with bigger layer height, ...).
bool colorprint_change = false;
while (!m_colorprint_heights.empty() && m_colorprint_heights.front()-EPSILON < layer.print_z) {
m_colorprint_heights.erase(m_colorprint_heights.begin());
// #ys_FIXME_COLOR
// while (!m_colorprint_heights.empty() && m_colorprint_heights.front()-EPSILON < layer.print_z) {
// m_colorprint_heights.erase(m_colorprint_heights.begin());
// colorprint_change = true;
// }
std::string custom_code = "";
while (!m_custom_g_code_heights.empty() && m_custom_g_code_heights.front().height-EPSILON < layer.print_z) {
custom_code = m_custom_g_code_heights.front().gcode;
m_custom_g_code_heights.erase(m_custom_g_code_heights.begin());
colorprint_change = true;
}
@ -1688,7 +1698,9 @@ void GCode::process_layer(
gcode += "; " + GCodeAnalyzer::Color_Change_Tag + "\n";
// add tag for time estimator
gcode += "; " + GCodeTimeEstimator::Color_Change_Tag + "\n";
gcode += "M600\n";
// #ys_FIXME_COLOR
// gcode += "M600\n";
gcode += custom_code + "\n";
}

View File

@ -353,6 +353,8 @@ protected:
// Layer heights for colorprint - updated before the export and erased during the process
// so no toolchange occurs twice.
std::vector<float> m_colorprint_heights;
// extensions for colorprint - now it's not a just color_print, there can be some custom gcode
std::vector<Model::CustomGCode> m_custom_g_code_heights;
// Time estimators
GCodeTimeEstimator m_normal_time_estimator;

View File

@ -746,6 +746,32 @@ public:
// Wipe tower object.
ModelWipeTower wipe_tower;
// Extensions for
struct CustomGCode
{
CustomGCode(double height, const std::string& code, int extruder) :
height(height), gcode(code), extruder(extruder) {}
bool operator<(const CustomGCode& other) const { return other.height > this->height; }
bool operator==(const CustomGCode& other) const
{
return (other.height == this->height) &&
(other.gcode == this->gcode) &&
(other.extruder == this->extruder );
}
bool operator!=(const CustomGCode& other) const
{
return (other.height != this->height) ||
(other.gcode != this->gcode) ||
(other.extruder != this->extruder );
}
double height;
std::string gcode;
int extruder;
};
std::vector<CustomGCode> custom_gcode_per_height;
// Default constructor assigns a new ID to the model.
Model() { assert(this->id().valid()); }
~Model() { this->clear_objects(); this->clear_materials(); }

View File

@ -749,6 +749,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
delete model_object;
}
}
if (model.custom_gcode_per_height != m_model.custom_gcode_per_height)
{
update_apply_status(this->invalidate_step(psGCodeExport));
m_model.custom_gcode_per_height = model.custom_gcode_per_height;
}
}
// 2) Map print objects including their transformation matrices.

View File

@ -839,6 +839,8 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePrevie
if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint &&
wxGetApp().extruders_edited_cnt() == 1) // show color change legend only for single-material presets
{
/*
// #ys_FIXME_COLOR
auto& config = wxGetApp().preset_bundle->project_config;
const std::vector<double>& color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values;
@ -854,6 +856,27 @@ void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePrevie
double current_z = *lower_b;
double previous_z = lower_b == print_zs.begin() ? 0.0 : *(--lower_b);
// to avoid duplicate values, check adding values
if (cp_legend_values.empty() ||
!(cp_legend_values.back().first == previous_z && cp_legend_values.back().second == current_z) )
cp_legend_values.push_back(std::pair<double, double>(previous_z, current_z));
}
}
*/
std::vector<Model::CustomGCode> custom_gcode_per_height = wxGetApp().plater()->model().custom_gcode_per_height;
if (!custom_gcode_per_height.empty()) {
std::vector<double> print_zs = canvas.get_current_print_zs(true);
for (auto custom_code : custom_gcode_per_height)
{
auto lower_b = std::lower_bound(print_zs.begin(), print_zs.end(), custom_code.height - DoubleSlider::epsilon());
if (lower_b == print_zs.end())
continue;
double current_z = *lower_b;
double previous_z = lower_b == print_zs.begin() ? 0.0 : *(--lower_b);
// to avoid duplicate values, check adding values
if (cp_legend_values.empty() ||
!(cp_legend_values.back().first == previous_z && cp_legend_values.back().second == current_z) )

View File

@ -562,12 +562,22 @@ void Preview::update_view_type()
{
const DynamicPrintConfig& config = wxGetApp().preset_bundle->project_config;
/*
// #ys_FIXME_COLOR
const wxString& choice = !config.option<ConfigOptionFloats>("colorprint_heights")->values.empty() &&
wxGetApp().extruders_edited_cnt()==1 ?
_(L("Color Print")) :
config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values.size() > 1 ?
_(L("Tool")) :
_(L("Feature type"));
*/
const wxString& choice = !wxGetApp().plater()->model().custom_gcode_per_height.empty() &&
wxGetApp().extruders_edited_cnt()==1 ?
_(L("Color Print")) :
config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values.size() > 1 ?
_(L("Tool")) :
_(L("Feature type"));
int type = m_choice_view_type->FindString(choice);
if (m_choice_view_type->GetSelection() != type) {
@ -609,7 +619,11 @@ void Preview::create_double_slider()
Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) {
wxGetApp().preset_bundle->project_config.option<ConfigOptionFloats>("colorprint_heights")->values = m_slider->GetTicksValues();
// #ys_FIXME_COLOR
// wxGetApp().preset_bundle->project_config.option<ConfigOptionFloats>("colorprint_heights")->values = m_slider->GetTicksValues();
Model& model = wxGetApp().plater()->model();
model.custom_gcode_per_height = m_slider->GetTicksValues_();
m_schedule_background_process();
update_view_type();
@ -645,6 +659,24 @@ static int find_close_layer_idx(const std::vector<double>& zs, double &z, double
return -1;
}
void Preview::check_slider_values(std::vector<Model::CustomGCode>& ticks_from_model,
const std::vector<double>& layers_z)
{
// All ticks that would end up outside the slider range should be erased.
// TODO: this should be placed into more appropriate part of code,
// this function is e.g. not called when the last object is deleted
unsigned int old_size = ticks_from_model.size();
ticks_from_model.erase(std::remove_if(ticks_from_model.begin(), ticks_from_model.end(),
[layers_z](Model::CustomGCode val)
{
auto it = std::lower_bound(layers_z.begin(), layers_z.end(), val.height - DoubleSlider::epsilon());
return it == layers_z.end();
}),
ticks_from_model.end());
if (ticks_from_model.size() != old_size)
m_schedule_background_process();
}
void Preview::update_double_slider(const std::vector<double>& layers_z, bool keep_z_range)
{
// Save the initial slider span.
@ -660,8 +692,11 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool kee
bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min();
bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max();
std::vector<double> &ticks_from_config = (wxGetApp().preset_bundle->project_config.option<ConfigOptionFloats>("colorprint_heights"))->values;
check_slider_values(ticks_from_config, layers_z);
// #ys_FIXME_COLOR
// std::vector<double> &ticks_from_config = (wxGetApp().preset_bundle->project_config.option<ConfigOptionFloats>("colorprint_heights"))->values;
// check_slider_values(ticks_from_config, layers_z);
std::vector<Model::CustomGCode> &ticks_from_model = wxGetApp().plater()->model().custom_gcode_per_height;
check_slider_values(ticks_from_model, layers_z);
m_slider->SetSliderValues(layers_z);
assert(m_slider->GetMinValue() == 0);
@ -683,7 +718,9 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool kee
}
m_slider->SetSelectionSpan(idx_low, idx_high);
m_slider->SetTicksValues(ticks_from_config);
// #ys_FIXME_COLOR
// m_slider->SetTicksValues(ticks_from_config);
m_slider->SetTicksValues_(ticks_from_model);
bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF);
if (color_print_enable) {
@ -693,7 +730,7 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool kee
}
m_slider->EnableTickManipulation(color_print_enable);
}
// #ys_FIXME_COLOR
void Preview::check_slider_values(std::vector<double>& ticks_from_config,
const std::vector<double> &layers_z)
{
@ -799,10 +836,13 @@ void Preview::load_print_as_fff(bool keep_z_range)
{
colors = GCodePreviewData::ColorPrintColors();
if (! gcode_preview_data_valid) {
//FIXME accessing full_config() is pretty expensive.
// Only initialize color_print_values for the initial preview, not for the full preview where the color_print_values is extracted from the G-code.
const auto& config = wxGetApp().preset_bundle->project_config;
color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values;
// #ys_FIXME_COLOR
// const auto& config = wxGetApp().preset_bundle->project_config;
// color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values;
const std::vector<Model::CustomGCode>& custom_codes = wxGetApp().plater()->model().custom_gcode_per_height;
color_print_values.reserve(custom_codes.size());
for (const Model::CustomGCode& code : custom_codes)
color_print_values.push_back(code.height);
}
}
else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) )

View File

@ -5,6 +5,7 @@
#include "libslic3r/Point.hpp"
#include <string>
#include "libslic3r/Model.hpp"
class wxNotebook;
class wxGLCanvas;
@ -154,9 +155,11 @@ private:
// Create/Update/Reset double slider on 3dPreview
void create_double_slider();
void check_slider_values(std::vector<Model::CustomGCode> &ticks_from_model,
const std::vector<double> &layers_z);
void update_double_slider(const std::vector<double>& layers_z, bool keep_z_range = false);
void check_slider_values(std::vector<double> &ticks_from_config,
const std::vector<double> &layers_z);
const std::vector<double> &layers_z); // #ys_FIXME_COLOR
void reset_double_slider();
// update DoubleSlider after keyDown in canvas
void update_double_slider_from_canvas(wxKeyEvent& event);

View File

@ -2688,8 +2688,10 @@ void Plater::priv::reset()
// The hiding of the slicing results, if shown, is not taken care by the background process, so we do it here
this->sidebar->show_sliced_info_sizer(false);
auto& config = wxGetApp().preset_bundle->project_config;
config.option<ConfigOptionFloats>("colorprint_heights")->values.clear();
// #ys_FIXME_COLOR
// auto& config = wxGetApp().preset_bundle->project_config;
// config.option<ConfigOptionFloats>("colorprint_heights")->values.clear();
model.custom_gcode_per_height.clear();
}
void Plater::priv::mirror(Axis axis)

View File

@ -2469,6 +2469,44 @@ std::vector<double> DoubleSlider::GetTicksValues() const
return values;
}
using t_custom_code = Slic3r::Model::CustomGCode;
std::vector<t_custom_code> DoubleSlider::GetTicksValues_() const
{
std::vector<t_custom_code> values;
const int val_size = m_values.size();
if (!m_values.empty())
for (const TICK_CODE& tick : m_ticks_) {
if (tick.tick > val_size)
break;
values.push_back(t_custom_code(m_values[tick.tick], tick.gcode, tick.extruder));
}
return values;
}
void DoubleSlider::SetTicksValues_(const std::vector<t_custom_code>& heights)
{
if (m_values.empty())
return;
const bool was_empty = m_ticks_.empty();
m_ticks_.clear();
for (auto h : heights) {
auto it = std::lower_bound(m_values.begin(), m_values.end(), h.height - epsilon());
if (it == m_values.end())
continue;
m_ticks_.insert(TICK_CODE(it-m_values.begin(), h.gcode, h.extruder));
}
if (!was_empty && m_ticks_.empty())
// Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
}
void DoubleSlider::SetTicksValues(const std::vector<double>& heights)
{
if (m_values.empty())
@ -2577,19 +2615,12 @@ void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoin
if (tick == 0)
return;
wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp();
// #ys_FIXME_COLOR
// wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp();
// if (m_ticks.find(tick) != m_ticks.end())
// icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp();
wxBitmap* icon = m_action_icon_focesed > 0 ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp();
auto tick_code_it = m_ticks_.find(tick);
if (tick_code_it != m_ticks_.end()) {
icon = m_action_icon_focesed > 0 ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp();
if (m_action_icon_focesed > 0)
m_action_icon_focesed = tick_code_it->gcode == "M600" ? fiDelColorChange :
tick_code_it->gcode == "M25" ? fiDelPause : fiDelCustomCode;
}
if (m_ticks_.find(tick) != m_ticks_.end())
icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp();
wxCoord x_draw, y_draw;
is_horizontal() ? x_draw = pt_beg.x - 0.5*m_tick_icon_dim : y_draw = pt_beg.y - 0.5*m_tick_icon_dim;
@ -3017,10 +3048,9 @@ void DoubleSlider::OnMotion(wxMouseEvent& event)
bool is_revert_icon_focused = false;
if (!m_is_left_down && !m_is_one_layer) {
m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action);
// #ys_FIXME_COLOR
// m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action);
// is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon);
m_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action) ? fiAdd : fiNone;
is_revert_icon_focused = !m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon);
}
else if (m_is_left_down || m_is_right_down) {
@ -3042,13 +3072,25 @@ void DoubleSlider::OnMotion(wxMouseEvent& event)
event.Skip();
// Set tooltips with information for each icon
const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) :
// m_is_action_icon_focesed ? _(L("Add/Del color change")) :
m_action_icon_focesed == fiAdd ? _(L("Add color change")) :
m_action_icon_focesed == fiDelColorChange ? _(L("Delete color change")) :
m_action_icon_focesed == fiDelPause ? _(L("Delete pause")) :
m_action_icon_focesed == fiDelCustomCode ? _(L("Delete custom code")) :
is_revert_icon_focused ? _(L("Discard all color changes")) : "";
// #ys_FIXME_COLOR
// const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) :
// m_is_action_icon_focesed ? _(L("Add/Del color change")) :
// is_revert_icon_focused ? _(L("Discard all color changes")) : "";
wxString tooltip(wxEmptyString);
if (m_is_one_layer_icon_focesed)
tooltip = _(L("One layer mode"));
if (is_revert_icon_focused)
tooltip = _(L("Discard all custom changes"));
else if (m_is_action_icon_focesed)
{
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
const auto tick_code_it = m_ticks_.find(tick);
tooltip = tick_code_it == m_ticks_.end() ? _(L("Add color change")) :
tick_code_it->gcode == "M600" ? _(L("Delete color change")) :
tick_code_it->gcode == "M25" ? _(L("Delete pause")) :
from_u8((boost::format(_utf8(L("Delete \"%1%\" code"))) % tick_code_it->gcode).str());
}
this->SetToolTip(tooltip);
if (action)

View File

@ -16,6 +16,7 @@
#include <vector>
#include <set>
#include <functional>
#include "libslic3r/Model.hpp"
namespace Slic3r {
enum class ModelVolumeType : int;
@ -795,6 +796,8 @@ public:
}
void ChangeOneLayerLock();
std::vector<double> GetTicksValues() const;
std::vector<Slic3r::Model::CustomGCode> GetTicksValues_() const;
void SetTicksValues_(const std::vector<Slic3r::Model::CustomGCode> &heights);
void SetTicksValues(const std::vector<double>& heights);
void EnableTickManipulation(bool enable = true) {
m_is_enabled_tick_manipulation = enable;
@ -883,14 +886,6 @@ private:
bool m_is_one_layer = false;
bool m_is_focused = false;
bool m_is_action_icon_focesed = false;
enum FocusedIcon
{
fiNone = 0,
fiAdd,
fiDelColorChange,
fiDelPause,
fiDelCustomCode
} m_action_icon_focesed { fiNone };
bool m_is_one_layer_icon_focesed = false;
bool m_is_enabled_tick_manipulation = true;
bool m_show_context_menu = false;