NEW:add statistics of all plates in preview

Change-Id: Ia93ca5a31d07ae5d52a37bb7b6fb0e3b26cfd012
This commit is contained in:
liz.li 2023-01-05 09:06:18 +08:00 committed by Lane.Wei
parent b731ac8db8
commit 6114a415cf
11 changed files with 466 additions and 33 deletions

View file

@ -0,0 +1,7 @@
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="60" height="60" fill="#E7E7E7"/>
<path d="M27.1429 8H19.5238C18.6822 8 18 8.68223 18 9.52381V17.1429C18 17.9845 18.6822 18.6667 19.5238 18.6667H27.1429C27.9845 18.6667 28.6667 17.9845 28.6667 17.1429V9.52381C28.6667 8.68223 27.9845 8 27.1429 8Z" fill="#00AE42"/>
<path d="M27.1429 21.3333H19.5238C18.6822 21.3333 18 22.0155 18 22.8571V30.4762C18 31.3178 18.6822 32 19.5238 32H27.1429C27.9845 32 28.6667 31.3178 28.6667 30.4762V22.8571C28.6667 22.0155 27.9845 21.3333 27.1429 21.3333Z" fill="#00AE42"/>
<path d="M40.4762 8H32.8571C32.0155 8 31.3333 8.68223 31.3333 9.52381V17.1429C31.3333 17.9845 32.0155 18.6667 32.8571 18.6667H40.4762C41.3178 18.6667 42 17.9845 42 17.1429V9.52381C42 8.68223 41.3178 8 40.4762 8Z" fill="#00AE42"/>
<path d="M40.4762 21.3333H32.8571C32.0155 21.3333 31.3333 22.0155 31.3333 22.8571V30.4762C31.3333 31.3178 32.0155 32 32.8571 32H40.4762C41.3178 32 42 31.3178 42 30.4762V22.8571C42 22.0155 41.3178 21.3333 40.4762 21.3333Z" fill="#00AE42"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,7 @@
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="60" height="60" fill="#E7E7E7"/>
<path d="M27.1429 8H19.5238C18.6822 8 18 8.68223 18 9.52381V17.1429C18 17.9845 18.6822 18.6667 19.5238 18.6667H27.1429C27.9845 18.6667 28.6667 17.9845 28.6667 17.1429V9.52381C28.6667 8.68223 27.9845 8 27.1429 8Z" fill="#C8EBD5"/>
<path d="M27.1429 21.3333H19.5238C18.6822 21.3333 18 22.0155 18 22.8571V30.4762C18 31.3178 18.6822 32 19.5238 32H27.1429C27.9845 32 28.6667 31.3178 28.6667 30.4762V22.8571C28.6667 22.0155 27.9845 21.3333 27.1429 21.3333Z" fill="#C8EBD5"/>
<path d="M40.4762 8H32.8571C32.0155 8 31.3333 8.68223 31.3333 9.52381V17.1429C31.3333 17.9845 32.0155 18.6667 32.8571 18.6667H40.4762C41.3178 18.6667 42 17.9845 42 17.1429V9.52381C42 8.68223 41.3178 8 40.4762 8Z" fill="#C8EBD5"/>
<path d="M40.4762 21.3333H32.8571C32.0155 21.3333 31.3333 22.0155 31.3333 22.8571V30.4762C31.3333 31.3178 32.0155 32 32.8571 32H40.4762C41.3178 32 42 31.3178 42 30.4762V22.8571C42 22.0155 41.3178 21.3333 40.4762 21.3333Z" fill="#C8EBD5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -4118,6 +4118,210 @@ void GCodeViewer::render_shells()
// glsafe(::glDepthMask(GL_TRUE)); // glsafe(::glDepthMask(GL_TRUE));
} }
//BBS
void GCodeViewer::render_all_plates_stats(const std::vector<const GCodeProcessorResult*>& gcode_result_list, bool show /*= true*/) const {
if (!show)
return;
ImGuiWrapper& imgui = *wxGetApp().imgui();
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0, 10.0 * m_scale));
ImGui::PushStyleColor(ImGuiCol_Separator, ImVec4(1.0f, 1.0f, 1.0f, 0.6f));
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, ImVec4(0.42f, 0.42f, 0.42f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImVec4(0.93f, 0.93f, 0.93f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImVec4(0.93f, 0.93f, 0.93f, 1.00f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(340.f * m_scale * imgui.scaled(1.0f / 15.0f), 0));
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 0, ImVec2(0.5f, 0.5f));
ImGui::Begin(_L("Statistics of All Plates").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
std::vector<float> filament_diameters = gcode_result_list.front()->filament_diameters;
std::vector<float> filament_densities = gcode_result_list.front()->filament_densities;
std::vector<Color> filament_colors = decode_colors(wxGetApp().plater()->get_extruder_colors_from_plater_config(gcode_result_list.back()));
bool imperial_units = wxGetApp().app_config->get("use_inches") == "1";
float window_padding = 4.0f * m_scale;
const float icon_size = ImGui::GetTextLineHeight() * 0.7;
std::vector<float> offsets;
std::map<int, double> volume_of_extruders_all_plates; // map<extruder_idx, volume>
std::map<int, double> flushed_volume_of_extruders_all_plates; // map<extruder_idx, flushed volume>
std::vector<double> model_used_filaments_m_all_plates;
std::vector<double> model_used_filaments_g_all_plates;
std::vector<double> flushed_filaments_m_all_plates;
std::vector<double> flushed_filaments_g_all_plates;
float total_time_all_plates = 0.0f;
bool show_detailed_statistics_page = false;
auto max_width = [](const std::vector<std::string>& items, const std::string& title, float extra_size = 0.0f) {
float ret = ImGui::CalcTextSize(title.c_str()).x;
for (const std::string& item : items) {
ret = std::max(ret, extra_size + ImGui::CalcTextSize(item.c_str()).x);
}
return ret;
};
auto calculate_offsets = [max_width, window_padding](const std::vector<std::pair<std::string, std::vector<::string>>>& title_columns, float extra_size = 0.0f) {
const ImGuiStyle& style = ImGui::GetStyle();
std::vector<float> offsets;
offsets.push_back(max_width(title_columns[0].second, title_columns[0].first, extra_size) + 3.0f * style.ItemSpacing.x + style.WindowPadding.x);
for (size_t i = 1; i < title_columns.size() - 1; i++)
offsets.push_back(offsets.back() + max_width(title_columns[i].second, title_columns[i].first) + style.ItemSpacing.x);
if (title_columns.back().first == _u8L("Display"))
offsets.back() = ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x - ImGui::GetFrameHeight() / 2 - 2 * window_padding;
float average_col_width = ImGui::GetWindowWidth() / static_cast<float>(title_columns.size());
std::vector<float> ret;
ret.push_back(0);
for (size_t i = 1; i < title_columns.size(); i++) {
ret.push_back(std::max(offsets[i - 1], i * average_col_width));
}
return ret;
};
auto append_item = [icon_size, &imgui, imperial_units, &window_padding, &draw_list, this](const Color& color, const std::vector<std::pair<std::string, float>>& columns_offsets)
{
// render icon
ImVec2 pos = ImVec2(ImGui::GetCursorScreenPos().x + window_padding * 3, ImGui::GetCursorScreenPos().y);
draw_list->AddRectFilled({ pos.x + 1.0f * m_scale, pos.y + 3.0f * m_scale }, { pos.x + icon_size - 1.0f * m_scale, pos.y + icon_size + 1.0f * m_scale },
ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(20.0 * m_scale, 6.0 * m_scale));
// render selectable
ImGui::Dummy({ 0.0, 0.0 });
ImGui::SameLine();
// render column item
{
float dummy_size = ImGui::GetStyle().ItemSpacing.x + icon_size;
ImGui::SameLine(dummy_size);
imgui.text(columns_offsets[0].first);
for (auto i = 1; i < columns_offsets.size(); i++) {
ImGui::SameLine(columns_offsets[i].second);
imgui.text(columns_offsets[i].first);
}
}
ImGui::PopStyleVar(1);
};
auto append_headers = [&imgui](const std::vector<std::pair<std::string, float>>& title_offsets) {
for (size_t i = 0; i < title_offsets.size(); i++) {
ImGui::SameLine(title_offsets[i].second);
imgui.bold_text(title_offsets[i].first);
}
ImGui::Separator();
};
auto get_used_filament_from_volume = [this, imperial_units, &filament_diameters, &filament_densities](double volume, int extruder_id) {
double koef = imperial_units ? 1.0 / GizmoObjectManipulation::in_to_mm : 0.001;
std::pair<double, double> ret = { koef * volume / (PI * sqr(0.5 * filament_diameters[extruder_id])),
volume * filament_densities[extruder_id] * 0.001 };
return ret;
};
ImGui::Dummy({ window_padding, window_padding });
ImGui::SameLine();
// title and item data
{
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
for (auto plate : plate_list.get_nonempty_plate_list())
{
auto plate_print_statistics = plate->get_slice_result()->print_statistics;
auto plate_extruders = plate->get_extruders(true);
for (size_t extruder_id : plate_extruders) {
extruder_id -= 1;
if (plate_print_statistics.volumes_per_extruder.find(extruder_id) == plate_print_statistics.volumes_per_extruder.end())
continue;
double volume = plate_print_statistics.volumes_per_extruder.at(extruder_id);
volume_of_extruders_all_plates[extruder_id] += volume;
if (plate_print_statistics.flush_per_filament.find(extruder_id) == plate_print_statistics.flush_per_filament.end())
flushed_volume_of_extruders_all_plates[extruder_id] = 0;
else {
double flushed_volume = plate_print_statistics.flush_per_filament.at(extruder_id);
flushed_volume_of_extruders_all_plates[extruder_id] += flushed_volume;
}
}
const PrintEstimatedStatistics::Mode& plate_time_mode = plate_print_statistics.modes[static_cast<size_t>(m_time_estimate_mode)];
total_time_all_plates += plate_time_mode.time;
}
for (auto it = volume_of_extruders_all_plates.begin(); it != volume_of_extruders_all_plates.end(); it++) {
auto [model_used_filament_m, model_used_filament_g] = get_used_filament_from_volume(it->second, it->first);
model_used_filaments_m_all_plates.push_back(model_used_filament_m);
model_used_filaments_g_all_plates.push_back(model_used_filament_g);
}
for (auto it = flushed_volume_of_extruders_all_plates.begin(); it != flushed_volume_of_extruders_all_plates.end(); it++) {
auto [flushed_filament_m, flushed_filament_g] = get_used_filament_from_volume(it->second, it->first);
if (flushed_filament_m != 0.0 || flushed_filament_g != 0.0)
show_detailed_statistics_page = true;
flushed_filaments_m_all_plates.push_back(flushed_filament_m);
flushed_filaments_g_all_plates.push_back(flushed_filament_g);
}
char buff[64];
double longest_str = 0.0;
for (auto i : model_used_filaments_g_all_plates) {
if (i > longest_str)
longest_str = i;
}
::sprintf(buff, "%.2f", longest_str);
offsets = calculate_offsets({ {_u8L("Filament"), {""}}, {_u8L("Model"), {buff}}, {_u8L("Flushed"), {buff}}, /*{_u8L("Tower"), total_filaments},*/ {_u8L("Total"), {buff}} }, icon_size);
if (!show_detailed_statistics_page)
append_headers({ {_u8L("Filament"), offsets[0]}, {_u8L("Model"), offsets[2]} });
else
append_headers({ {_u8L("Filament"), offsets[0]}, {_u8L("Model"), offsets[1]}, {_u8L("Flushed"), offsets[2]}, /*{_u8L("Tower"), offsets[3]},*/ {_u8L("Total"), offsets[3]} });// to add Tower
}
// item
{
size_t i = 0;
for (auto it = volume_of_extruders_all_plates.begin(); it != volume_of_extruders_all_plates.end(); it++) {
if (i < model_used_filaments_m_all_plates.size() && i < model_used_filaments_g_all_plates.size()) {
std::vector<std::pair<std::string, float>> columns_offsets;
columns_offsets.push_back({ std::to_string(it->first + 1), offsets[0] });
char buf[64];
if (show_detailed_statistics_page) {
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", model_used_filaments_m_all_plates[i], model_used_filaments_g_all_plates[i]);
columns_offsets.push_back({ buf, offsets[1] });
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", flushed_filaments_m_all_plates[i], flushed_filaments_g_all_plates[i]);
columns_offsets.push_back({ buf, offsets[2] });
::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", model_used_filaments_m_all_plates[i] + flushed_filaments_m_all_plates[i], model_used_filaments_g_all_plates[i] + flushed_filaments_g_all_plates[i]);
columns_offsets.push_back({ buf, offsets[3] });
}
else {
::sprintf(buf, imperial_units ? "%.2f in %.2f oz" : "%.2f m %.2f g", model_used_filaments_m_all_plates[i], model_used_filaments_g_all_plates[i]);
columns_offsets.push_back({ buf, offsets[2] });
}
append_item(filament_colors[it->first], columns_offsets);
}
i++;
}
ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1));
ImGui::Dummy({ window_padding, window_padding });
ImGui::SameLine();
imgui.title(_u8L("Total Time Estimation"));
ImGui::Dummy({ window_padding, window_padding });
ImGui::SameLine();
imgui.text(_u8L("Total time") + ":");
ImGui::SameLine();
imgui.text(short_time(get_time_dhms(total_time_all_plates)));
}
ImGui::End();
ImGui::PopStyleColor(6);
ImGui::PopStyleVar(3);
return;
}
void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin) void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin)
{ {
if (!m_legend_enabled) if (!m_legend_enabled)
@ -4381,6 +4585,14 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
return std::make_pair(it->second.first * koef, it->second.second); return std::make_pair(it->second.first * koef, it->second.second);
}; };
// get used filament (meters and grams) from used volume in respect to the active extruder
auto get_used_filament_from_volume = [this, imperial_units](double volume, int extruder_id) {
double koef = imperial_units ? 1.0 / GizmoObjectManipulation::in_to_mm : 0.001;
std::pair<double, double> ret = { koef * volume / (PI * sqr(0.5 * m_filament_diameters[extruder_id])),
volume * m_filament_densities[extruder_id] * 0.001 };
return ret;
};
//BBS display Color Scheme //BBS display Color Scheme
ImGui::Dummy({ window_padding, window_padding }); ImGui::Dummy({ window_padding, window_padding });
ImGui::Dummy({ window_padding, window_padding }); ImGui::Dummy({ window_padding, window_padding });
@ -4460,13 +4672,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
double koef = imperial_units ? GizmoObjectManipulation::in_to_mm : 1000.0; double koef = imperial_units ? GizmoObjectManipulation::in_to_mm : 1000.0;
double unit_conver = imperial_units ? GizmoObjectManipulation::oz_to_g : 1; double unit_conver = imperial_units ? GizmoObjectManipulation::oz_to_g : 1;
// get used filament (meters and grams) from used volume in respect to the active extruder
auto get_used_filament_from_volume = [this, imperial_units](double volume, int extruder_id) {
double koef = imperial_units ? 1.0 / GizmoObjectManipulation::in_to_mm : 0.001;
std::pair<double, double> ret = { koef * volume / (PI * sqr(0.5 * m_filament_diameters[extruder_id])),
volume * m_filament_densities[extruder_id] * 0.001 };
return ret;
};
// extrusion paths section -> title // extrusion paths section -> title
ImGui::Dummy({ window_padding, window_padding }); ImGui::Dummy({ window_padding, window_padding });
@ -4746,13 +4951,13 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
char buf[64]; char buf[64];
if (show_flushed_filaments) { if (show_flushed_filaments) {
::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", model_used_filaments_m[i], model_used_filaments_g[i]); ::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", model_used_filaments_m[i], model_used_filaments_g[i]);
columns_offsets.push_back({ buf, offsets[1] }); columns_offsets.push_back({ buf, offsets[1] });
::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", flushed_filaments_m[i], flushed_filaments_g[i]); ::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", flushed_filaments_m[i], flushed_filaments_g[i]);
columns_offsets.push_back({ buf, offsets[2] }); columns_offsets.push_back({ buf, offsets[2] });
::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", model_used_filaments_m[i] + flushed_filaments_m[i], model_used_filaments_g[i] + flushed_filaments_g[i]); ::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", model_used_filaments_m[i] + flushed_filaments_m[i], model_used_filaments_g[i] + flushed_filaments_g[i]);
columns_offsets.push_back({ buf, offsets[3] }); columns_offsets.push_back({ buf, offsets[3] });
} }
else { else {
@ -5289,16 +5494,16 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
} }
default : { assert(false); break; } default : { assert(false); break; }
} }
}
if (m_view_type == EViewType::ColorPrint) { if (m_view_type == EViewType::ColorPrint) {
ImGui::Spacing(); ImGui::Spacing();
ImGui::Dummy({ window_padding, window_padding }); ImGui::Dummy({ window_padding, window_padding });
ImGui::SameLine(); ImGui::SameLine();
offsets = calculate_offsets({ { _u8L("Options"), { ""}}, { _u8L("Display"), {""}} }, icon_size); offsets = calculate_offsets({ { _u8L("Options"), { ""}}, { _u8L("Display"), {""}} }, icon_size);
append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} }); append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} });
for (auto item : options_items) for (auto item : options_items)
append_option_item(item, offsets); append_option_item(item, offsets);
}
} }
legend_height = ImGui::GetCurrentWindow()->Size.y; legend_height = ImGui::GetCurrentWindow()->Size.y;

View file

@ -805,6 +805,8 @@ public:
void reset_shell(); void reset_shell();
void load_shells(const Print& print, bool initialized, bool force_previewing = false); void load_shells(const Print& print, bool initialized, bool force_previewing = false);
void set_shells_on_preview(bool is_previewing) { m_shells.previewing = is_previewing; } void set_shells_on_preview(bool is_previewing) { m_shells.previewing = is_previewing; }
//BBS: add all plates filament statistics
void render_all_plates_stats(const std::vector<const GCodeProcessorResult*>& gcode_result_list, bool show = true) const;
//BBS: GUI refactor: add canvas width and height //BBS: GUI refactor: add canvas width and height
void render(int canvas_width, int canvas_height, int right_margin); void render(int canvas_width, int canvas_height, int right_margin);
//BBS //BBS

View file

@ -1145,6 +1145,7 @@ GLCanvas3D::~GLCanvas3D()
reset_volumes(); reset_volumes();
m_sel_plate_toolbar.del_all_item(); m_sel_plate_toolbar.del_all_item();
m_sel_plate_toolbar.del_stats_item();
} }
void GLCanvas3D::post_event(wxEvent &&event) void GLCanvas3D::post_event(wxEvent &&event)
@ -1593,6 +1594,11 @@ void GLCanvas3D::enable_main_toolbar(bool enable)
m_main_toolbar.set_enabled(enable); m_main_toolbar.set_enabled(enable);
} }
void GLCanvas3D::reset_select_plate_toolbar_selection() {
if (m_sel_plate_toolbar.m_all_plates_stats_item)
m_sel_plate_toolbar.m_all_plates_stats_item->selected = false;
}
void GLCanvas3D::enable_select_plate_toolbar(bool enable) void GLCanvas3D::enable_select_plate_toolbar(bool enable)
{ {
m_sel_plate_toolbar.set_enabled(enable); m_sel_plate_toolbar.set_enabled(enable);
@ -1832,7 +1838,7 @@ void GLCanvas3D::render(bool only_init)
_render_platelist(!camera.is_looking_downward(), only_current, only_body, hover_id); _render_platelist(!camera.is_looking_downward(), only_current, only_body, hover_id);
} }
/* preview render */ /* preview render */
else if (m_canvas_type == ECanvasType::CanvasPreview) { else if (m_canvas_type == ECanvasType::CanvasPreview && m_render_preview) {
//BBS: add outline logic //BBS: add outline logic
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running()); _render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
//BBS: GUI refactor: add canvas size as parameters //BBS: GUI refactor: add canvas size as parameters
@ -5802,6 +5808,9 @@ bool GLCanvas3D::_init_toolbars()
if (!_init_separator_toolbar()) if (!_init_separator_toolbar())
return false; return false;
if (!_init_select_plate_toolbar())
return false;
#if 0 #if 0
if (!_init_view_toolbar()) if (!_init_view_toolbar())
return false; return false;
@ -5967,7 +5976,24 @@ bool GLCanvas3D::_init_main_toolbar()
//BBS: GUI refactor: GLToolbar //BBS: GUI refactor: GLToolbar
bool GLCanvas3D::_init_select_plate_toolbar() bool GLCanvas3D::_init_select_plate_toolbar()
{ {
return true; std::string path = resources_dir() + "/images/";
IMToolbarItem* item = new IMToolbarItem();
bool result = item->image_texture.load_from_svg_file(path + "im_all_plates_stats.svg", false, false, false, 128);
result = result && item->image_texture_transparent.load_from_svg_file(path + "im_all_plates_stats_transparent.svg", false, false, false, 128);
m_sel_plate_toolbar.m_all_plates_stats_item = item;
return result;
}
void GLCanvas3D::_update_select_plate_toolbar_stats_item(bool force_selected) {
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
if (plate_list.get_nonempty_plate_list().size() > 1)
m_sel_plate_toolbar.show_stats_item = true;
else
m_sel_plate_toolbar.show_stats_item = false;
if (force_selected && m_sel_plate_toolbar.show_stats_item)
m_sel_plate_toolbar.m_all_plates_stats_item->selected = true;
} }
bool GLCanvas3D::_update_imgui_select_plate_toolbar() bool GLCanvas3D::_update_imgui_select_plate_toolbar()
@ -5975,6 +6001,8 @@ bool GLCanvas3D::_update_imgui_select_plate_toolbar()
bool result = true; bool result = true;
if (!m_sel_plate_toolbar.is_enabled()) return false; if (!m_sel_plate_toolbar.is_enabled()) return false;
_update_select_plate_toolbar_stats_item();
m_sel_plate_toolbar.del_all_item(); m_sel_plate_toolbar.del_all_item();
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list(); PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
@ -5990,6 +6018,7 @@ bool GLCanvas3D::_update_imgui_select_plate_toolbar()
} }
m_sel_plate_toolbar.m_items.push_back(item); m_sel_plate_toolbar.m_items.push_back(item);
} }
m_sel_plate_toolbar.is_display_scrollbar = false; m_sel_plate_toolbar.is_display_scrollbar = false;
return result; return result;
} }
@ -7080,20 +7109,23 @@ void GLCanvas3D::_render_main_toolbar()
//BBS: GUI refactor: GLToolbar adjust //BBS: GUI refactor: GLToolbar adjust
//when rendering, {0, 0} is at the center, {-0.5, 0.5} at the left-up //when rendering, {0, 0} is at the center, {-0.5, 0.5} at the left-up
void GLCanvas3D::_render_imgui_select_plate_toolbar() const void GLCanvas3D::_render_imgui_select_plate_toolbar()
{ {
if (!m_sel_plate_toolbar.is_enabled()) if (!m_sel_plate_toolbar.is_enabled())
return; return;
IMToolbarItem* all_plates_stats_item = m_sel_plate_toolbar.m_all_plates_stats_item;
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list(); PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
for (int i = 0; i < plate_list.get_plate_count(); i++) { for (int i = 0; i < plate_list.get_plate_count(); i++) {
if (i < m_sel_plate_toolbar.m_items.size()) { if (i < m_sel_plate_toolbar.m_items.size()) {
if (i == plate_list.get_curr_plate_index()) if (i == plate_list.get_curr_plate_index() && !all_plates_stats_item->selected)
m_sel_plate_toolbar.m_items[i]->selected = true; m_sel_plate_toolbar.m_items[i]->selected = true;
else else
m_sel_plate_toolbar.m_items[i]->selected = false; m_sel_plate_toolbar.m_items[i]->selected = false;
m_sel_plate_toolbar.m_items[i]->percent = plate_list.get_plate(i)->get_slicing_percent(); m_sel_plate_toolbar.m_items[i]->percent = plate_list.get_plate(i)->get_slicing_percent();
if (plate_list.get_plate(i)->is_slice_result_valid()) { if (plate_list.get_plate(i)->is_slice_result_valid()) {
if (plate_list.get_plate(i)->is_slice_result_ready_for_print()) if (plate_list.get_plate(i)->is_slice_result_ready_for_print())
m_sel_plate_toolbar.m_items[i]->slice_state = IMToolbarItem::SliceState::SLICED; m_sel_plate_toolbar.m_items[i]->slice_state = IMToolbarItem::SliceState::SLICED;
@ -7107,6 +7139,39 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
m_sel_plate_toolbar.m_items[i]->slice_state = IMToolbarItem::SliceState::SLICING; m_sel_plate_toolbar.m_items[i]->slice_state = IMToolbarItem::SliceState::SLICING;
} }
} }
if (m_sel_plate_toolbar.show_stats_item) {
all_plates_stats_item->percent = 0.0f;
size_t sliced_plates_cnt = 0;
bool slice_failed = false;
for (auto plate : plate_list.get_nonempty_plate_list()) {
if (plate->is_slice_result_valid() && plate->is_slice_result_ready_for_print())
sliced_plates_cnt++;
if (plate->is_slice_result_valid() && !plate->is_slice_result_ready_for_print())
slice_failed = true;
}
all_plates_stats_item->percent = (float)(sliced_plates_cnt) / (float)(plate_list.get_nonempty_plate_list().size()) * 100.0f;
if (all_plates_stats_item->percent == 0.0f)
all_plates_stats_item->slice_state = IMToolbarItem::SliceState::UNSLICED;
else if (sliced_plates_cnt == plate_list.get_nonempty_plate_list().size())
all_plates_stats_item->slice_state = IMToolbarItem::SliceState::SLICED;
else if (all_plates_stats_item->percent < 100.0f)
all_plates_stats_item->slice_state = IMToolbarItem::SliceState::SLICING;
if (slice_failed)
all_plates_stats_item->slice_state = IMToolbarItem::SliceState::SLICE_FAILED;
if (all_plates_stats_item->selected && all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICED) {
m_gcode_viewer.render_all_plates_stats(plate_list.get_nonempty_plates_slice_results());
m_render_preview = false;
}
else{
m_gcode_viewer.render_all_plates_stats(plate_list.get_nonempty_plates_slice_results(), false);
m_render_preview = true;
}
}else
m_render_preview = true;
// places the toolbar on the top_left corner of the 3d scene // places the toolbar on the top_left corner of the 3d scene
#if ENABLE_RETINA_GL #if ENABLE_RETINA_GL
@ -7130,7 +7195,7 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
float button_margin = frame_padding; float button_margin = frame_padding;
ImGuiWrapper& imgui = *wxGetApp().imgui(); ImGuiWrapper& imgui = *wxGetApp().imgui();
int item_count = m_sel_plate_toolbar.m_items.size(); int item_count = m_sel_plate_toolbar.m_items.size() + (m_sel_plate_toolbar.show_stats_item ? 1 : 0);
bool show_scroll = item_count * (button_height + frame_padding * 2.0f + button_margin) - button_margin + 22.0f * f_scale > canvas_h ? true: false; bool show_scroll = item_count * (button_height + frame_padding * 2.0f + button_margin) - button_margin + 22.0f * f_scale > canvas_h ? true: false;
show_scroll = m_sel_plate_toolbar.is_display_scrollbar && show_scroll; show_scroll = m_sel_plate_toolbar.is_display_scrollbar && show_scroll;
float window_height = std::min(item_count * (button_height + (frame_padding + margin_size) * 2.0f + button_margin) - button_margin + 28.0f * f_scale, canvas_h); float window_height = std::min(item_count * (button_height + (frame_padding + margin_size) * 2.0f + button_margin) - button_margin + 28.0f * f_scale, canvas_h);
@ -7171,7 +7236,89 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
ImVec2 margin = ImVec2(margin_size, margin_size); ImVec2 margin = ImVec2(margin_size, margin_size);
for (int i = 0; i < item_count; i++) { if(m_sel_plate_toolbar.show_stats_item)
{
// draw image
ImVec2 button_start_pos = ImGui::GetCursorScreenPos();
if (all_plates_stats_item->selected) {
ImGui::PushStyleColor(ImGuiCol_Button, button_active);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_active);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, button_active);
}
else {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(128.0f, 128.0f, 128.0f, 0.0f));
if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICE_FAILED) {
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::GetStyleColorVec4(ImGuiCol_Button));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_Button));
}
else {
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_hover);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.42f, 0.42f, 0.42f, 1.0f));
}
}
ImVec4 text_clr;
ImTextureID btn_texture_id;
if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::UNSLICED || all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICING || all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICE_FAILED)
{
text_clr = ImVec4(0, 174.0f / 255.0f, 66.0f / 255.0f, 0.2f);
btn_texture_id = (ImTextureID)(intptr_t)(all_plates_stats_item->image_texture_transparent.get_id());
}
else
{
text_clr = ImVec4(0, 174.0f / 255.0f, 66.0f / 255.0f, 1);
btn_texture_id = (ImTextureID)(intptr_t)(all_plates_stats_item->image_texture.get_id());
}
if (ImGui::ImageButton2(btn_texture_id, size, {0,0}, {1,1}, frame_padding, bg_col, tint_col, margin)) {
if (all_plates_stats_item->slice_state != IMToolbarItem::SliceState::SLICE_FAILED) {
if (m_process && !m_process->running()) {
for (int i = 0; i < m_sel_plate_toolbar.m_items.size(); i++) {
m_sel_plate_toolbar.m_items[i]->selected = false;
}
all_plates_stats_item->selected = true;
wxCommandEvent evt = wxCommandEvent(EVT_GLTOOLBAR_SLICE_ALL);
wxPostEvent(wxGetApp().plater(), evt);
}
}
}
ImGui::PopStyleColor(3);
ImVec2 start_pos = ImVec2(button_start_pos.x + frame_padding + margin.x, button_start_pos.y + frame_padding + margin.y);
if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::UNSLICED) {
ImVec2 size = ImVec2(button_width, button_height);
ImVec2 end_pos = ImVec2(start_pos.x + size.x, start_pos.y + size.y);
ImGui::GetForegroundDrawList()->AddRectFilled(start_pos, end_pos, IM_COL32(0, 0, 0, 80));
}
else if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICING) {
ImVec2 size = ImVec2(button_width, button_height * all_plates_stats_item->percent / 100.0f);
ImVec2 rect_start_pos = ImVec2(start_pos.x, start_pos.y + size.y);
ImVec2 rect_end_pos = ImVec2(start_pos.x + button_width, start_pos.y + button_height);
ImGui::GetForegroundDrawList()->AddRectFilled(rect_start_pos, rect_end_pos, IM_COL32(0, 0, 0, 80));
}
else if (all_plates_stats_item->slice_state == IMToolbarItem::SliceState::SLICE_FAILED) {
ImVec2 size = ImVec2(button_width, button_height);
ImVec2 end_pos = ImVec2(start_pos.x + size.x, start_pos.y + size.y);
ImGui::GetForegroundDrawList()->AddRectFilled(start_pos, end_pos, IM_COL32(40, 1, 1, 64));
ImGui::GetForegroundDrawList()->AddRect(start_pos, end_pos, IM_COL32(208, 27, 27, 255), 0.0f, 0, 1.0f);
}
// draw text
GImGui->FontSize = 15.0f;
ImGui::PushStyleColor(ImGuiCol_Text, text_clr);
ImVec2 text_size = ImGui::CalcTextSize(_L("All Plates").c_str());
ImVec2 text_start_pos = ImVec2(start_pos.x + (button_width - text_size.x) / 2, start_pos.y + 3.0f * button_height / 5.0f);
ImGui::RenderText(text_start_pos, _L("All Plates").c_str());
text_size = ImGui::CalcTextSize(_L("Stats").c_str());
text_start_pos = ImVec2(start_pos.x + (button_width - text_size.x) / 2, text_start_pos.y + ImGui::GetTextLineHeight());
ImGui::RenderText(text_start_pos, _L("Stats").c_str());
ImGui::PopStyleColor();
ImGui::SetWindowFontScale(1.2f);
}
for (int i = 0; i < m_sel_plate_toolbar.m_items.size(); i++) {
IMToolbarItem* item = m_sel_plate_toolbar.m_items[i]; IMToolbarItem* item = m_sel_plate_toolbar.m_items[i];
// draw image // draw image
@ -7183,11 +7330,16 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
if (item->selected) { if (item->selected) {
ImGui::PushStyleColor(ImGuiCol_Button, button_active); ImGui::PushStyleColor(ImGuiCol_Button, button_active);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_active); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_active);
} else }
else {
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(128.0f, 128.0f, 128.0f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.42f, 0.42f, 0.42f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.42f, 0.42f, 0.42f, 1.0f));
}
if (ImGui::ImageButton2(item->texture_id, size, uv0, uv1, frame_padding, bg_col, tint_col, margin)) { if (ImGui::ImageButton2(item->texture_id, size, uv0, uv1, frame_padding, bg_col, tint_col, margin)) {
if (m_process && !m_process->running()) { if (m_process && !m_process->running()) {
all_plates_stats_item->selected = false;
item->selected = true;
// begin to slicing plate // begin to slicing plate
wxCommandEvent* evt = new wxCommandEvent(EVT_GLTOOLBAR_SELECT_SLICED_PLATE); wxCommandEvent* evt = new wxCommandEvent(EVT_GLTOOLBAR_SELECT_SLICED_PLATE);
evt->SetInt(i); evt->SetInt(i);
@ -7195,10 +7347,7 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() const
} }
} }
if (item->selected) ImGui::PopStyleColor(2);
ImGui::PopStyleColor(2);
else
ImGui::PopStyleColor(1);
ImVec2 start_pos = ImVec2(button_start_pos.x + frame_padding + margin.x, button_start_pos.y + frame_padding + margin.y); ImVec2 start_pos = ImVec2(button_start_pos.x + frame_padding + margin.x, button_start_pos.y + frame_padding + margin.y);
if (item->slice_state == IMToolbarItem::SliceState::UNSLICED) { if (item->slice_state == IMToolbarItem::SliceState::UNSLICED) {

View file

@ -543,6 +543,7 @@ private:
bool m_dirty; bool m_dirty;
bool m_initialized; bool m_initialized;
//BBS: add flag to controll rendering //BBS: add flag to controll rendering
bool m_render_preview{ true };
bool m_enable_render { true }; bool m_enable_render { true };
bool m_apply_zoom_to_volumes_filter; bool m_apply_zoom_to_volumes_filter;
bool m_picking_enabled; bool m_picking_enabled;
@ -785,6 +786,8 @@ public:
void enable_selection(bool enable); void enable_selection(bool enable);
void enable_main_toolbar(bool enable); void enable_main_toolbar(bool enable);
//BBS: GUI refactor: GLToolbar //BBS: GUI refactor: GLToolbar
void _update_select_plate_toolbar_stats_item(bool force_selected = false);
void reset_select_plate_toolbar_selection();
void enable_select_plate_toolbar(bool enable); void enable_select_plate_toolbar(bool enable);
void enable_assemble_view_toolbar(bool enable); void enable_assemble_view_toolbar(bool enable);
void enable_return_toolbar(bool enable); void enable_return_toolbar(bool enable);
@ -1097,7 +1100,7 @@ private:
void _render_current_gizmo() const; void _render_current_gizmo() const;
void _render_gizmos_overlay(); void _render_gizmos_overlay();
void _render_main_toolbar(); void _render_main_toolbar();
void _render_imgui_select_plate_toolbar() const; void _render_imgui_select_plate_toolbar();
void _render_assemble_view_toolbar() const; void _render_assemble_view_toolbar() const;
void _render_return_toolbar() const; void _render_return_toolbar() const;
void _render_separator_toolbar_right() const; void _render_separator_toolbar_right() const;

View file

@ -52,6 +52,11 @@ void IMToolbar::del_all_item()
m_items.clear(); m_items.clear();
} }
void IMToolbar::del_stats_item()
{
delete m_all_plates_stats_item;
m_all_plates_stats_item = nullptr;
}
bool IMReturnToolbar::init() bool IMReturnToolbar::init()
{ {

View file

@ -27,10 +27,11 @@ public:
bool selected{ false }; bool selected{ false };
float percent; float percent;
ImTextureID texture_id { 0 };
GLTexture image_texture; GLTexture image_texture;
GLTexture image_texture_transparent;
SliceState slice_state; SliceState slice_state;
ImTextureID texture_id { 0 };
std::vector<unsigned char> image_data; std::vector<unsigned char> image_data;
unsigned int image_width; unsigned int image_width;
unsigned int image_height; unsigned int image_height;
@ -47,6 +48,7 @@ public:
float icon_width; float icon_width;
float icon_height; float icon_height;
bool is_display_scrollbar; bool is_display_scrollbar;
bool show_stats_item{ false };
IMToolbar() { IMToolbar() {
icon_width = DEFAULT_TOOLBAR_BUTTON_WIDTH; icon_width = DEFAULT_TOOLBAR_BUTTON_WIDTH;
@ -54,7 +56,9 @@ public:
} }
void del_all_item(); void del_all_item();
void del_stats_item();
IMToolbarItem* m_all_plates_stats_item = nullptr;
std::vector<IMToolbarItem*> m_items; std::vector<IMToolbarItem*> m_items;
float fontScale; float fontScale;

View file

@ -3105,6 +3105,25 @@ PartPlate* PartPlateList::get_selected_plate()
return m_plate_list[m_current_plate]; return m_plate_list[m_current_plate];
} }
std::vector<PartPlate*> PartPlateList::get_nonempty_plate_list()
{
std::vector<PartPlate*> nonempty_plate_list;
for (auto plate : m_plate_list){
if (plate->get_extruders().size() != 0) {
nonempty_plate_list.push_back(plate);
}
}
return nonempty_plate_list;
}
std::vector<const GCodeProcessorResult*> PartPlateList::get_nonempty_plates_slice_results() {
std::vector<const GCodeProcessorResult*> nonempty_plates_slice_result;
for (auto plate : get_nonempty_plate_list()) {
nonempty_plates_slice_result.push_back(plate->get_slice_result());
}
return nonempty_plates_slice_result;
}
//select plate //select plate
int PartPlateList::select_plate(int index) int PartPlateList::select_plate(int index)
{ {

View file

@ -626,6 +626,10 @@ public:
PartPlate* get_selected_plate(); PartPlate* get_selected_plate();
std::vector<PartPlate*> get_nonempty_plate_list();
std::vector<const GCodeProcessorResult*> get_nonempty_plates_slice_results();
Vec3d get_current_plate_origin() { return compute_origin(m_current_plate, m_plate_cols); } Vec3d get_current_plate_origin() { return compute_origin(m_current_plate, m_plate_cols); }
Vec2d get_current_shape_position() { return compute_shape_position(m_current_plate, m_plate_cols); } Vec2d get_current_shape_position() { return compute_shape_position(m_current_plate, m_plate_cols); }
Pointfs get_exclude_area() { return m_exclude_areas; } Pointfs get_exclude_area() { return m_exclude_areas; }

View file

@ -1688,6 +1688,8 @@ struct Plater::priv
bool m_is_slicing {false}; bool m_is_slicing {false};
bool m_is_publishing {false}; bool m_is_publishing {false};
int m_cur_slice_plate; int m_cur_slice_plate;
//BBS: m_slice_all in .gcode.3mf file case, set true when slice all
bool m_slice_all_only_has_gcode{ false };
bool m_need_update{false}; bool m_need_update{false};
//BBS: add popup object table logic //BBS: add popup object table logic
@ -5310,6 +5312,9 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice)
return; return;
} }
//BBS: wish to reset all plates stats item selected state when back to View3D Tab
preview->get_canvas3d()->reset_select_plate_toolbar_selection();
wxPanel* old_panel = current_panel; wxPanel* old_panel = current_panel;
//#if BBL_HAS_FIRST_PAGE //#if BBL_HAS_FIRST_PAGE
if (!old_panel) { if (!old_panel) {
@ -5810,6 +5815,20 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
//BBS: add project slice logic //BBS: add project slice logic
bool is_finished = !m_slice_all || (m_cur_slice_plate == (partplate_list.get_plate_count() - 1)); bool is_finished = !m_slice_all || (m_cur_slice_plate == (partplate_list.get_plate_count() - 1));
//BBS: slice .gcode.3mf file related logic, assign is_finished again
bool only_has_gcode_need_preview = false;
auto plate_list = this->partplate_list.get_plate_list();
bool has_print_instances = false;
for (auto plate : plate_list)
has_print_instances = has_print_instances || plate->has_printable_instances();
if (this->model.objects.empty() && !has_print_instances)
only_has_gcode_need_preview = true;
if (only_has_gcode_need_preview && m_slice_all_only_has_gcode) {
is_finished = (m_cur_slice_plate == (partplate_list.get_plate_count() - 1));
if (is_finished)
m_slice_all_only_has_gcode = false;
}
// Stop the background task, wait until the thread goes into the "Idle" state. // Stop the background task, wait until the thread goes into the "Idle" state.
// At this point of time the thread should be either finished or canceled, // At this point of time the thread should be either finished or canceled,
// so the following call just confirms, that the produced data were consumed. // so the following call just confirms, that the produced data were consumed.
@ -6058,12 +6077,15 @@ void Plater::priv::on_action_slice_all(SimpleEvent&)
Plater::setExtruderParams(Slic3r::Model::extruderParamsMap); Plater::setExtruderParams(Slic3r::Model::extruderParamsMap);
Plater::setPrintSpeedTable(Slic3r::Model::printSpeedMap); Plater::setPrintSpeedTable(Slic3r::Model::printSpeedMap);
m_slice_all = true; m_slice_all = true;
m_slice_all_only_has_gcode = true;
m_cur_slice_plate = 0; m_cur_slice_plate = 0;
//select plate //select plate
q->select_plate(m_cur_slice_plate); q->select_plate(m_cur_slice_plate);
q->reslice(); q->reslice();
if (!m_is_publishing) if (!m_is_publishing)
q->select_view_3D("Preview"); q->select_view_3D("Preview");
//BBS: wish to select all plates stats item
preview->get_canvas3d()->_update_select_plate_toolbar_stats_item(true);
} }
} }
@ -8090,7 +8112,13 @@ void Plater::force_update_all_plate_thumbnails()
} }
// BBS: backup // BBS: backup
std::vector<size_t> Plater::load_files(const std::vector<fs::path>& input_files, LoadStrategy strategy, bool ask_multi) { return p->load_files(input_files, strategy, ask_multi); } std::vector<size_t> Plater::load_files(const std::vector<fs::path>& input_files, LoadStrategy strategy, bool ask_multi) {
//BBS: wish to reset state when load a new file
p->m_slice_all_only_has_gcode = false;
//BBS: wish to reset all plates stats item selected state when load a new file
p->preview->get_canvas3d()->reset_select_plate_toolbar_selection();
return p->load_files(input_files, strategy, ask_multi);
}
// To be called when providing a list of files to the GUI slic3r on command line. // To be called when providing a list of files to the GUI slic3r on command line.
std::vector<size_t> Plater::load_files(const std::vector<std::string>& input_files, LoadStrategy strategy, bool ask_multi) std::vector<size_t> Plater::load_files(const std::vector<std::string>& input_files, LoadStrategy strategy, bool ask_multi)