Information from DoubleSlider is saved to Model
GCode creating can work with that values.
This commit is contained in:
parent
6ac53aa4f3
commit
70ef0f25ef
@ -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";
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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(); }
|
||||
|
@ -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.
|
||||
|
@ -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) )
|
||||
|
@ -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) )
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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")) :
|
||||
// #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")) :
|
||||
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")) : "";
|
||||
// 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)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user