Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
commit
56fa84c9d9
6 changed files with 80 additions and 42 deletions
|
@ -368,6 +368,8 @@ void Mouse3DController::render_settings_dialog(GLCanvas3D& canvas) const
|
|||
|
||||
void Mouse3DController::connected(std::string device_name)
|
||||
{
|
||||
assert(! m_connected);
|
||||
assert(m_device_str.empty());
|
||||
m_device_str = device_name;
|
||||
// Copy the parameters for m_device_str into the current parameters.
|
||||
if (auto it_params = m_params_by_device.find(m_device_str); it_params != m_params_by_device.end()) {
|
||||
|
@ -380,13 +382,13 @@ void Mouse3DController::connected(std::string device_name)
|
|||
void Mouse3DController::disconnected()
|
||||
{
|
||||
// Copy the current parameters for m_device_str into the parameter database.
|
||||
assert(! m_device_str.empty());
|
||||
if (! m_device_str.empty()) {
|
||||
assert(m_connected == ! m_device_str.empty());
|
||||
if (m_connected) {
|
||||
tbb::mutex::scoped_lock lock(m_params_ui_mutex);
|
||||
m_params_by_device[m_device_str] = m_params_ui;
|
||||
m_device_str.clear();
|
||||
m_connected = false;
|
||||
}
|
||||
m_device_str.clear();
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
bool Mouse3DController::handle_input(const DataPacketAxis& packet)
|
||||
|
|
|
@ -152,6 +152,8 @@ static void DeviceAdded(uint32_t unused)
|
|||
static void DeviceRemoved(uint32_t unused)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "3dx device removed\n";
|
||||
assert(m_connected);
|
||||
assert(! m_device_str.empty());
|
||||
mouse_3d_controller->disconnected();
|
||||
}
|
||||
|
||||
|
@ -214,6 +216,8 @@ void Mouse3DController::shutdown()
|
|||
CleanupConnexionHandlers();
|
||||
unload_driver();
|
||||
}
|
||||
// Copy the current parameters to parameter database, mark the device as disconnected.
|
||||
this->disconnected();
|
||||
mouse_3d_controller = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1509,6 +1509,7 @@ struct Plater::priv
|
|||
ret.poly.contour = std::move(p);
|
||||
ret.translation = scaled(m_pos);
|
||||
ret.rotation = m_rotation;
|
||||
ret.priority++;
|
||||
return ret;
|
||||
}
|
||||
} wipetower;
|
||||
|
@ -1572,18 +1573,23 @@ struct Plater::priv
|
|||
// the current bed width.
|
||||
static const constexpr double LOGICAL_BED_GAP = 1. / 5.;
|
||||
|
||||
ArrangePolygons m_selected, m_unselected;
|
||||
ArrangePolygons m_selected, m_unselected, m_unprintable;
|
||||
|
||||
// clear m_selected and m_unselected, reserve space for next usage
|
||||
void clear_input() {
|
||||
const Model &model = plater().model;
|
||||
|
||||
size_t count = 0; // To know how much space to reserve
|
||||
for (auto obj : model.objects) count += obj->instances.size();
|
||||
size_t count = 0, cunprint = 0; // To know how much space to reserve
|
||||
for (auto obj : model.objects)
|
||||
for (auto mi : obj->instances)
|
||||
mi->printable ? count++ : cunprint++;
|
||||
|
||||
m_selected.clear();
|
||||
m_unselected.clear();
|
||||
m_unprintable.clear();
|
||||
m_selected.reserve(count + 1 /* for optional wti */);
|
||||
m_unselected.reserve(count + 1 /* for optional wti */);
|
||||
m_unprintable.reserve(cunprint /* for optional wti */);
|
||||
}
|
||||
|
||||
// Stride between logical beds
|
||||
|
@ -1612,8 +1618,10 @@ struct Plater::priv
|
|||
clear_input();
|
||||
|
||||
for (ModelObject *obj: plater().model.objects)
|
||||
for (ModelInstance *mi : obj->instances)
|
||||
m_selected.emplace_back(get_arrange_poly(mi));
|
||||
for (ModelInstance *mi : obj->instances) {
|
||||
ArrangePolygons & cont = mi->printable ? m_selected : m_unprintable;
|
||||
cont.emplace_back(get_arrange_poly(mi));
|
||||
}
|
||||
|
||||
auto& wti = plater().updated_wipe_tower();
|
||||
if (wti) m_selected.emplace_back(get_arrange_poly(&wti));
|
||||
|
@ -1648,9 +1656,12 @@ struct Plater::priv
|
|||
for (size_t i = 0; i < inst_sel.size(); ++i) {
|
||||
ArrangePolygon &&ap = get_arrange_poly(mo->instances[i]);
|
||||
|
||||
inst_sel[i] ?
|
||||
m_selected.emplace_back(std::move(ap)) :
|
||||
m_unselected.emplace_back(std::move(ap));
|
||||
ArrangePolygons &cont = mo->instances[i]->printable ?
|
||||
(inst_sel[i] ? m_selected :
|
||||
m_unselected) :
|
||||
m_unprintable;
|
||||
|
||||
cont.emplace_back(std::move(ap));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1682,16 +1693,35 @@ struct Plater::priv
|
|||
public:
|
||||
using PlaterJob::PlaterJob;
|
||||
|
||||
int status_range() const override { return int(m_selected.size()); }
|
||||
int status_range() const override
|
||||
{
|
||||
return int(m_selected.size() + m_unprintable.size());
|
||||
}
|
||||
|
||||
void process() override;
|
||||
|
||||
void finalize() override {
|
||||
// Ignore the arrange result if aborted.
|
||||
if (was_canceled()) return;
|
||||
|
||||
|
||||
// Unprintable items go to the last virtual bed
|
||||
int beds = 0;
|
||||
|
||||
// Apply the arrange result to all selected objects
|
||||
for (ArrangePolygon &ap : m_selected) ap.apply();
|
||||
for (ArrangePolygon &ap : m_selected) {
|
||||
beds = std::max(ap.bed_idx, beds);
|
||||
ap.apply();
|
||||
}
|
||||
|
||||
// Get the virtual beds from the unselected items
|
||||
for (ArrangePolygon &ap : m_unselected)
|
||||
beds = std::max(ap.bed_idx, beds);
|
||||
|
||||
// Move the unprintable items to the last virtual bed.
|
||||
for (ArrangePolygon &ap : m_unprintable) {
|
||||
ap.bed_idx += beds + 1;
|
||||
ap.apply();
|
||||
}
|
||||
|
||||
plater().update();
|
||||
}
|
||||
|
@ -2846,16 +2876,21 @@ void Plater::priv::ArrangeJob::process() {
|
|||
}
|
||||
|
||||
coord_t min_d = scaled(dist);
|
||||
auto count = unsigned(m_selected.size());
|
||||
auto count = unsigned(m_selected.size() + m_unprintable.size());
|
||||
arrangement::BedShapeHint bedshape = plater().get_bed_shape_hint();
|
||||
|
||||
|
||||
auto stopfn = [this]() { return was_canceled(); };
|
||||
|
||||
try {
|
||||
arrangement::arrange(m_selected, m_unselected, min_d, bedshape,
|
||||
[this, count](unsigned st) {
|
||||
if (st > 0) // will not finalize after last one
|
||||
update_status(int(count - st), arrangestr);
|
||||
},
|
||||
[this]() { return was_canceled(); });
|
||||
[this, count](unsigned st) {
|
||||
st += m_unprintable.size();
|
||||
if (st > 0) update_status(int(count - st), arrangestr);
|
||||
}, stopfn);
|
||||
arrangement::arrange(m_unprintable, {}, min_d, bedshape,
|
||||
[this, count](unsigned st) {
|
||||
if (st > 0) update_status(int(count - st), arrangestr);
|
||||
}, stopfn);
|
||||
} catch (std::exception & /*e*/) {
|
||||
GUI::show_error(plater().q,
|
||||
_(L("Could not arrange model objects! "
|
||||
|
|
|
@ -103,7 +103,10 @@ void RemovableDriveManager::eject_drive()
|
|||
return;
|
||||
}
|
||||
CloseHandle(handle);
|
||||
m_drive_data_last_eject = *it_drive_data;
|
||||
assert(m_callback_evt_handler);
|
||||
if (m_callback_evt_handler)
|
||||
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::move(*it_drive_data)));
|
||||
m_current_drives.erase(it_drive_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,7 +351,10 @@ void RemovableDriveManager::eject_drive()
|
|||
return;
|
||||
}
|
||||
|
||||
m_drive_data_last_eject = *it_drive_data;
|
||||
assert(m_callback_evt_handler);
|
||||
if (m_callback_evt_handler)
|
||||
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::move(*it_drive_data)));
|
||||
m_current_drives.erase(it_drive_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,16 +479,9 @@ void RemovableDriveManager::update()
|
|||
tbb::mutex::scoped_lock lock(m_drives_mutex);
|
||||
std::sort(current_drives.begin(), current_drives.end());
|
||||
if (current_drives != m_current_drives) {
|
||||
if (! m_drive_data_last_eject.empty() && std::find(current_drives.begin(), current_drives.end(), m_drive_data_last_eject) == current_drives.end()) {
|
||||
assert(m_callback_evt_handler);
|
||||
if (m_callback_evt_handler)
|
||||
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::move(m_drive_data_last_eject)));
|
||||
m_drive_data_last_eject.clear();
|
||||
} else {
|
||||
assert(m_callback_evt_handler);
|
||||
if (m_callback_evt_handler)
|
||||
wxPostEvent(m_callback_evt_handler, RemovableDrivesChangedEvent(EVT_REMOVABLE_DRIVES_CHANGED));
|
||||
}
|
||||
assert(m_callback_evt_handler);
|
||||
if (m_callback_evt_handler)
|
||||
wxPostEvent(m_callback_evt_handler, RemovableDrivesChangedEvent(EVT_REMOVABLE_DRIVES_CHANGED));
|
||||
}
|
||||
m_current_drives = std::move(current_drives);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,8 @@ public:
|
|||
// Verify whether the path provided is on removable media. If so, save the path for further eject and return true, otherwise return false.
|
||||
bool set_and_verify_last_save_path(const std::string &path);
|
||||
// Eject drive of a file set by set_and_verify_last_save_path().
|
||||
// On Unix / OSX, the function blocks and sends out the EVT_REMOVABLE_DRIVE_EJECTED event on success.
|
||||
// On Windows, the function does not block, and the eject is detected in the background thread.
|
||||
void eject_drive();
|
||||
|
||||
struct RemovableDrivesStatus {
|
||||
|
@ -99,10 +101,6 @@ private:
|
|||
// m_current_drives is guarded by m_drives_mutex
|
||||
// sorted ascending by path
|
||||
std::vector<DriveData> m_current_drives;
|
||||
// When user requested an eject, the drive to be forcefuly ejected is stored here, so the next update will
|
||||
// recognize that the eject was finished with success and an eject event is sent out.
|
||||
// guarded with m_drives_mutex
|
||||
DriveData m_drive_data_last_eject;
|
||||
mutable tbb::mutex m_drives_mutex;
|
||||
|
||||
// Returns drive path (same as path in DriveData) if exists otherwise empty string.
|
||||
|
|
|
@ -2861,10 +2861,10 @@ void Tab::select_preset(std::string preset_name, bool delete_current)
|
|||
// Mark the print & filament enabled if they are compatible with the currently selected preset.
|
||||
// The following method should not discard changes of current print or filament presets on change of a printer profile,
|
||||
// if they are compatible with the current printer.
|
||||
auto update_compatible_type = [](bool technology_changed, bool on_page, bool show_incompatible_presets) {
|
||||
return technology_changed ? PresetSelectCompatibleType::Always :
|
||||
on_page ? PresetSelectCompatibleType::Never :
|
||||
(show_incompatible_presets ? PresetSelectCompatibleType::OnlyIfWasCompatible : PresetSelectCompatibleType::Always);
|
||||
auto update_compatible_type = [delete_current](bool technology_changed, bool on_page, bool show_incompatible_presets) {
|
||||
return (delete_current || technology_changed) ? PresetSelectCompatibleType::Always :
|
||||
on_page ? PresetSelectCompatibleType::Never :
|
||||
show_incompatible_presets ? PresetSelectCompatibleType::OnlyIfWasCompatible : PresetSelectCompatibleType::Always;
|
||||
};
|
||||
if (current_dirty || delete_current || print_tab || printer_tab)
|
||||
m_preset_bundle->update_compatible(
|
||||
|
|
Loading…
Reference in a new issue