Merge branch 'master' into lm_tm_hollowing

This commit is contained in:
tamasmeszaros 2019-11-18 17:27:15 +01:00
commit 7011c58faa
80 changed files with 5008 additions and 577 deletions

View file

@ -32,6 +32,9 @@
#include "libslic3r/Format/AMF.hpp"
#include "libslic3r/Format/3mf.hpp"
#include "libslic3r/GCode/PreviewData.hpp"
#if ENABLE_THUMBNAIL_GENERATOR
#include "libslic3r/GCode/ThumbnailData.hpp"
#endif // ENABLE_THUMBNAIL_GENERATOR
#include "libslic3r/Model.hpp"
#include "libslic3r/SLA/Hollowing.hpp"
#include "libslic3r/SLA/Rotfinder.hpp"
@ -74,6 +77,7 @@
#include "../Utils/PrintHost.hpp"
#include "../Utils/FixModelByWin10.hpp"
#include "../Utils/UndoRedo.hpp"
#include "../Utils/Thread.hpp"
#include <wx/glcanvas.h> // Needs to be last because reasons :-/
#include "WipeTowerDialog.hpp"
@ -84,6 +88,9 @@ using Slic3r::_3DScene;
using Slic3r::Preset;
using Slic3r::PrintHostJob;
#if ENABLE_THUMBNAIL_GENERATOR
static const std::pair<unsigned int, unsigned int> THUMBNAIL_SIZE_3MF = { 256, 256 };
#endif // ENABLE_THUMBNAIL_GENERATOR
namespace Slic3r {
namespace GUI {
@ -224,7 +231,7 @@ SlicedInfo::SlicedInfo(wxWindow *parent) :
init_info_label(_(L("Used Filament (mm³)")));
init_info_label(_(L("Used Filament (g)")));
init_info_label(_(L("Used Material (unit)")));
init_info_label(_(L("Cost")));
init_info_label(_(L("Cost (money)")));
init_info_label(_(L("Estimated printing time")));
init_info_label(_(L("Number of tool changes")));
@ -1122,12 +1129,10 @@ void Sidebar::show_info_sizer()
}
}
void Sidebar::show_sliced_info_sizer(const bool show)
void Sidebar::update_sliced_info_sizer()
{
wxWindowUpdateLocker freeze_guard(this);
p->sliced_info->Show(show);
if (show) {
if (p->sliced_info->IsShown(size_t(0)))
{
if (p->plater->printer_technology() == ptSLA)
{
const SLAPrintStatistics& ps = p->plater->sla_print().print_statistics();
@ -1143,7 +1148,18 @@ void Sidebar::show_sliced_info_sizer(const bool show)
wxString::Format("%.2f", (ps.objects_used_material + ps.support_used_material) / 1000);
p->sliced_info->SetTextAndShow(siMateril_unit, info_text, new_label);
p->sliced_info->SetTextAndShow(siCost, "N/A"/*wxString::Format("%.2f", ps.total_cost)*/);
wxString str_total_cost = "N/A";
DynamicPrintConfig* cfg = wxGetApp().get_tab(Preset::TYPE_SLA_MATERIAL)->get_config();
if (cfg->option("bottle_cost")->getFloat() > 0.0 &&
cfg->option("bottle_volume")->getFloat() > 0.0)
{
double material_cost = cfg->option("bottle_cost")->getFloat() /
cfg->option("bottle_volume")->getFloat();
str_total_cost = wxString::Format("%.2f", material_cost*(ps.objects_used_material + ps.support_used_material) / 1000);
}
p->sliced_info->SetTextAndShow(siCost, str_total_cost);
wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : get_time_dhms(float(ps.estimated_print_time));
p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _(L("Estimated printing time")) + " :");
@ -1217,6 +1233,15 @@ void Sidebar::show_sliced_info_sizer(const bool show)
p->sliced_info->SetTextAndShow(siMateril_unit, "N/A");
}
}
}
void Sidebar::show_sliced_info_sizer(const bool show)
{
wxWindowUpdateLocker freeze_guard(this);
p->sliced_info->Show(show);
if (show)
update_sliced_info_sizer();
Layout();
p->scrolled->Refresh();
@ -1364,6 +1389,9 @@ struct Plater::priv
Slic3r::Model model;
PrinterTechnology printer_technology = ptFFF;
Slic3r::GCodePreviewData gcode_preview_data;
#if ENABLE_THUMBNAIL_GENERATOR
std::vector<Slic3r::ThumbnailData> thumbnail_data;
#endif // ENABLE_THUMBNAIL_GENERATOR
// GUI elements
wxSizer* panel_sizer{ nullptr };
@ -1430,7 +1458,7 @@ struct Plater::priv
class Job : public wxEvtHandler
{
int m_range = 100;
std::future<void> m_ftr;
boost::thread m_thread;
priv * m_plater = nullptr;
std::atomic<bool> m_running{false}, m_canceled{false};
bool m_finalized = false;
@ -1471,7 +1499,8 @@ struct Plater::priv
// Do a full refresh of scene tree, including regenerating
// all the GLVolumes. FIXME The update function shall just
// reload the modified matrices.
if (!was_canceled()) plater().update((unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH);
if (!was_canceled())
plater().update(unsigned(UpdateParams::FORCE_FULL_SCREEN_REFRESH));
}
public:
@ -1500,9 +1529,9 @@ struct Plater::priv
}
Job(const Job &) = delete;
Job(Job &&) = default;
Job(Job &&) = delete;
Job &operator=(const Job &) = delete;
Job &operator=(Job &&) = default;
Job &operator=(Job &&) = delete;
virtual void process() = 0;
@ -1526,7 +1555,7 @@ struct Plater::priv
wxBeginBusyCursor();
try { // Execute the job
m_ftr = std::async(std::launch::async, &Job::run, this);
m_thread = create_thread([this] { this->run(); });
} catch (std::exception &) {
update_status(status_range(),
_(L("ERROR: not enough resources to "
@ -1542,16 +1571,15 @@ struct Plater::priv
// returned if the timeout has been reached and the job is still
// running. Call cancel() before this fn if you want to explicitly
// end the job.
bool join(int timeout_ms = 0) const
bool join(int timeout_ms = 0)
{
if (!m_ftr.valid()) return true;
if (!m_thread.joinable()) return true;
if (timeout_ms <= 0)
m_ftr.wait();
else if (m_ftr.wait_for(std::chrono::milliseconds(
timeout_ms)) == std::future_status::timeout)
m_thread.join();
else if (!m_thread.try_join_for(boost::chrono::milliseconds(timeout_ms)))
return false;
return true;
}
@ -1939,6 +1967,10 @@ struct Plater::priv
bool can_mirror() const;
bool can_reload_from_disk() const;
#if ENABLE_THUMBNAIL_GENERATOR
void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background);
#endif // ENABLE_THUMBNAIL_GENERATOR
void msw_rescale_object_menu();
// returns the path to project file with the given extension (none if extension == wxEmptyString)
@ -2006,6 +2038,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
background_process.set_fff_print(&fff_print);
background_process.set_sla_print(&sla_print);
background_process.set_gcode_preview_data(&gcode_preview_data);
#if ENABLE_THUMBNAIL_GENERATOR
background_process.set_thumbnail_data(&thumbnail_data);
#endif // ENABLE_THUMBNAIL_GENERATOR
background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED);
background_process.set_finished_event(EVT_PROCESS_COMPLETED);
// Default printer technology for default config.
@ -3118,6 +3153,37 @@ bool Plater::priv::restart_background_process(unsigned int state)
( ((state & UPDATE_BACKGROUND_PROCESS_FORCE_RESTART) != 0 && ! this->background_process.finished()) ||
(state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) != 0 ||
(state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ) ) {
#if ENABLE_THUMBNAIL_GENERATOR
if (((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) &&
(this->background_process.state() != BackgroundSlicingProcess::STATE_RUNNING))
{
// update thumbnail data
const std::vector<Vec2d> &thumbnail_sizes = this->background_process.current_print()->full_print_config().option<ConfigOptionPoints>("thumbnails")->values;
if (this->printer_technology == ptFFF)
{
// for ptFFF we need to generate the thumbnails before the export of gcode starts
this->thumbnail_data.clear();
for (const Vec2d &sized : thumbnail_sizes)
{
this->thumbnail_data.push_back(ThumbnailData());
Point size(sized); // round to ints
generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, true, false);
}
}
else if (this->printer_technology == ptSLA)
{
// for ptSLA generate thumbnails without supports and pad (not yet calculated)
// to render also supports and pad see on_slicing_update()
this->thumbnail_data.clear();
for (const Vec2d &sized : thumbnail_sizes)
{
this->thumbnail_data.push_back(ThumbnailData());
Point size(sized); // round to ints
generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, true, false);
}
}
}
#endif // ENABLE_THUMBNAIL_GENERATOR
// The print is valid and it can be started.
if (this->background_process.start()) {
this->statusbar()->set_cancel_callback([this]() {
@ -3455,6 +3521,25 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
} else if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) {
// Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways.
this->preview->reload_print();
// uncomment the following lines if you want to render into the thumbnail also supports and pad for SLA printer
/*
#if ENABLE_THUMBNAIL_GENERATOR
// update thumbnail data
// for ptSLA generate the thumbnail after supports and pad have been calculated to have them rendered
if ((this->printer_technology == ptSLA) && (evt.status.percent == -3))
{
const std::vector<Vec2d>& thumbnail_sizes = this->background_process.current_print()->full_print_config().option<ConfigOptionPoints>("thumbnails")->values;
this->thumbnail_data.clear();
for (const Vec2d &sized : thumbnail_sizes)
{
this->thumbnail_data.push_back(ThumbnailData());
Point size(sized); // round to ints
generate_thumbnail(this->thumbnail_data.back(), size.x(), size.y(), true, false, false);
}
}
#endif // ENABLE_THUMBNAIL_GENERATOR
*/
}
}
@ -3680,6 +3765,13 @@ bool Plater::priv::init_object_menu()
return true;
}
#if ENABLE_THUMBNAIL_GENERATOR
void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background)
{
view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only, transparent_background);
}
#endif // ENABLE_THUMBNAIL_GENERATOR
void Plater::priv::msw_rescale_object_menu()
{
for (MenuWithSeparators* menu : { &object_menu, &sla_object_menu, &part_menu, &default_menu })
@ -4718,7 +4810,13 @@ void Plater::export_3mf(const boost::filesystem::path& output_path)
DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure();
const std::string path_u8 = into_u8(path);
wxBusyCursor wait;
#if ENABLE_THUMBNAIL_GENERATOR
ThumbnailData thumbnail_data;
p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true, true);
if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &thumbnail_data)) {
#else
if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) {
#endif // ENABLE_THUMBNAIL_GENERATOR
// Success
p->statusbar()->set_status_text(wxString::Format(_(L("3MF file exported to %s")), path));
p->set_project_filename(path);