mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-17 20:57:26 +00:00
Merge branch 'main' into claude/inspiring-knuth-7cp6pk-upstream
This commit is contained in:
967 files changed
+32649
-175
No files matched your search
@@ -103,6 +103,7 @@
|
||||
#include "Selection.hpp"
|
||||
#include "GLToolbar.hpp"
|
||||
#include "GUI_Preview.hpp"
|
||||
#include "UVEditorCanvas.hpp"
|
||||
#include "3DBed.hpp"
|
||||
#include "PartPlate.hpp"
|
||||
#include "Camera.hpp"
|
||||
@@ -1797,11 +1798,14 @@ bool Sidebar::priv::switch_diameter_to(const wxString &diameter)
|
||||
Preset& printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset();
|
||||
// The combo lists printer variants, and the variant of a mixed-nozzle machine ("0.4+0.6") is no
|
||||
// single extruder's diameter, so the preset's own variant answers first.
|
||||
if (printer_preset.config.opt_string("printer_variant") == diameter.ToStdString()) {
|
||||
const std::string &printer_variant = printer_preset.config.opt_string("printer_variant");
|
||||
if (printer_variant == diameter.ToStdString()) {
|
||||
return true;
|
||||
}
|
||||
// A named variant ("0.4 High Flow") shares its diameter with the standard profile, which selecting
|
||||
// the plain diameter switches back to, so only a preset naming no variant is kept by its diameter.
|
||||
auto* nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printer_preset.config.option("nozzle_diameter"));
|
||||
if (nozzle_diameter && nozzle_diameter->size() > 0) {
|
||||
if (printer_variant.empty() && nozzle_diameter && nozzle_diameter->size() > 0) {
|
||||
auto current_nozzle_dia = get_diameter_string(nozzle_diameter->values[0]);
|
||||
// If the selected diameter is the same as current nozzle, don't switch profiles
|
||||
if (current_nozzle_dia == diameter.ToStdString()) {
|
||||
@@ -3933,13 +3937,18 @@ void Sidebar::update_presets(Preset::Type preset_type)
|
||||
combo_flow->Show(combo_flow->GetCount() > 0);
|
||||
};
|
||||
|
||||
auto update_extruder_diameter = [&diameters, &nozzle_diameter](int extruder_index,ExtruderGroup & extruder) {
|
||||
auto update_extruder_diameter = [&diameters, &nozzle_diameter, &diameter](int extruder_index,ExtruderGroup & extruder) {
|
||||
extruder.combo_diameter->Clear();
|
||||
if (extruder_index >= int(nozzle_diameter->values.size()))
|
||||
return;
|
||||
int select = -1;
|
||||
// ORCA get the actual nozzle diameter from printer config
|
||||
auto nozzle_dia = get_diameter_string(nozzle_diameter->values[extruder_index]);
|
||||
// Named variants such as "0.4HS" and "0.4 High Flow" share a physical diameter.
|
||||
// Retain the variant selection unless the diameter was customized.
|
||||
const bool keep_variant = diameter.substr(0, diameter.find_first_not_of("0123456789.")) == nozzle_dia &&
|
||||
std::find(diameters.begin(), diameters.end(), diameter) != diameters.end();
|
||||
const std::string &selected_variant = keep_variant ? diameter : nozzle_dia;
|
||||
// ORCA try to add nozzle diameter from config if list is empty. fixes blank nozzle combo box when preset has no alias
|
||||
if(!diameters.empty() && diameters[0].empty() && !nozzle_dia.empty()){
|
||||
diameters[0] = nozzle_dia;
|
||||
@@ -3949,7 +3958,7 @@ void Sidebar::update_presets(Preset::Type preset_type)
|
||||
diameters.push_back(nozzle_dia);
|
||||
}
|
||||
for (size_t i = 0; i < diameters.size(); ++i) {
|
||||
if (diameters[i] == nozzle_dia)
|
||||
if (diameters[i] == selected_variant)
|
||||
select = extruder.combo_diameter->GetCount();
|
||||
extruder.combo_diameter->Append(diameters[i], {});
|
||||
}
|
||||
@@ -7108,6 +7117,13 @@ struct Plater::priv
|
||||
GLToolbar collapse_toolbar;
|
||||
Preview *preview;
|
||||
AssembleView* assemble_view { nullptr };
|
||||
// Docked/resizable 2D pane showing GLGizmoTextureDisplacement's LSCM unwrap of a painted
|
||||
// patch; a sibling AUI pane alongside "sidebar"/"main", not part of the view3D/preview/
|
||||
// assemble_view sizer - see its registration below and Plater::get_uv_editor_canvas(). The
|
||||
// pane hosts the panel (toolbar + canvas + status line); uv_editor_canvas is its inner canvas,
|
||||
// cached so the gizmo can reach it directly.
|
||||
UVEditorPanel* uv_editor_panel { nullptr };
|
||||
UVEditorCanvas* uv_editor_canvas { nullptr };
|
||||
bool first_enter_assemble{ true };
|
||||
std::unique_ptr<NotificationManager> notification_manager;
|
||||
|
||||
@@ -7357,6 +7373,8 @@ struct Plater::priv
|
||||
|
||||
void undo();
|
||||
void redo();
|
||||
// True, and tells the user, while a background job is working on the model - see the definition.
|
||||
bool undo_redo_blocked_by_job();
|
||||
void undo_redo_to(size_t time_to_load);
|
||||
|
||||
// BBS: backup
|
||||
@@ -7810,6 +7828,26 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
.BottomDockable(false)
|
||||
.BestSize(wxSize(39 * wxGetApp().em_unit(), 90 * wxGetApp().em_unit())));
|
||||
|
||||
// UV editor pane for GLGizmoTextureDisplacement's LSCM unwrap preview - a resizable/dockable
|
||||
// sibling of "sidebar"/"main" like everything else registered on this same AUI manager, not a
|
||||
// change to the view3D/preview/assemble_view sizer above. Hidden by default: only relevant
|
||||
// while that gizmo is active with a layer using the "Unwrap (LSCM)" projection method (see
|
||||
// Plater::show_uv_editor()), so it stays out of the way of everyone else's window layout.
|
||||
uv_editor_panel = new UVEditorPanel(q);
|
||||
uv_editor_canvas = uv_editor_panel->canvas();
|
||||
m_aui_mgr.AddPane(uv_editor_panel, wxAuiPaneInfo()
|
||||
.Name("uv_editor")
|
||||
.Caption(_L("UV Editor"))
|
||||
.Right()
|
||||
.Hide()
|
||||
.BestSize(wxSize(40 * wxGetApp().em_unit(), 40 * wxGetApp().em_unit())));
|
||||
// Closing the pane with its own X has to reach the gizmo, or its next update would simply show the pane again.
|
||||
q->Bind(wxEVT_AUI_PANE_CLOSE, [this](wxAuiManagerEvent &evt) {
|
||||
evt.Skip();
|
||||
if (evt.GetPane() != nullptr && evt.GetPane()->window == uv_editor_panel && uv_editor_canvas != nullptr)
|
||||
uv_editor_canvas->run_command(UVEditorCanvas::Command::PaneClosed);
|
||||
});
|
||||
|
||||
auto* panel_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
panel_sizer->Add(view3D, 1, wxEXPAND | wxALL, 0);
|
||||
panel_sizer->Add(preview, 1, wxEXPAND | wxALL, 0);
|
||||
@@ -7851,6 +7889,13 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
BOOST_LOG_TRIVIAL(info) << "Removed floating AUI state from saved window layout for Wayland";
|
||||
}
|
||||
|
||||
// The UV editor is a transient, gizmo-driven pane (see show_uv_editor()); a saved layout
|
||||
// from a session that happened to close with it open would otherwise restore it visible on
|
||||
// startup, with nothing painted in it. Force it hidden here so it only ever appears when the
|
||||
// texture-displacement gizmo asks for it.
|
||||
if (wxAuiPaneInfo &uv_pane = m_aui_mgr.GetPane("uv_editor"); uv_pane.IsOk())
|
||||
uv_pane.Hide();
|
||||
|
||||
sidebar_layout.is_collapsed = !sidebar.IsShown();
|
||||
}
|
||||
|
||||
@@ -15006,8 +15051,25 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed
|
||||
BOOST_LOG_TRIVIAL(info) << "Undo / Redo snapshot taken: " << snapshot_name << ", Undo / Redo stack memory: " << Slic3r::format_memsize_MB(this->undo_redo_stack().memsize()) << log_memory_info();
|
||||
}
|
||||
|
||||
// A background job holds the model it is working on: the texture displacement bake, for one, hands its
|
||||
// result to the volume when it finishes, and it was queued against the geometry as it was at the time.
|
||||
// Undoing while it runs restores an older state under it - a different transform, a different mesh -
|
||||
// and the result then lands on geometry it was never computed for. Undo and redo therefore wait for
|
||||
// the job, and say so rather than doing nothing.
|
||||
bool Plater::priv::undo_redo_blocked_by_job()
|
||||
{
|
||||
if (m_worker.is_idle())
|
||||
return false;
|
||||
notification_manager->push_notification(NotificationType::CustomNotification,
|
||||
NotificationManager::NotificationLevel::RegularNotificationLevel,
|
||||
_u8L("Cannot undo or redo while an operation is running. Stop it first."));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Plater::priv::undo()
|
||||
{
|
||||
if (this->undo_redo_blocked_by_job())
|
||||
return;
|
||||
const std::vector<UndoRedo::Snapshot> &snapshots = this->undo_redo_stack().snapshots();
|
||||
auto it_current = std::lower_bound(snapshots.begin(), snapshots.end(), UndoRedo::Snapshot(this->undo_redo_stack().active_snapshot_time()));
|
||||
// BBS: undo-redo until modify record
|
||||
@@ -15025,6 +15087,8 @@ void Plater::priv::undo()
|
||||
|
||||
void Plater::priv::redo()
|
||||
{
|
||||
if (this->undo_redo_blocked_by_job())
|
||||
return;
|
||||
const std::vector<UndoRedo::Snapshot> &snapshots = this->undo_redo_stack().snapshots();
|
||||
auto it_current = std::lower_bound(snapshots.begin(), snapshots.end(), UndoRedo::Snapshot(this->undo_redo_stack().active_snapshot_time()));
|
||||
// BBS: undo-redo until modify record
|
||||
@@ -16670,7 +16734,7 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i
|
||||
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
|
||||
|
||||
/// --- scale ---
|
||||
/// -- scale --
|
||||
// model is created for a 0.4 nozzle, scale z with nozzle size.
|
||||
const ConfigOptionFloats* nozzle_diameter_config = printer_config->option<ConfigOptionFloats>("nozzle_diameter");
|
||||
std::vector<int> extruder_types = printer_config->option<ConfigOptionEnumsGeneric>("extruder_type")->values;
|
||||
@@ -21147,6 +21211,33 @@ GLCanvas3D* Plater::get_assmeble_canvas3D()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UVEditorCanvas* Plater::get_uv_editor_canvas()
|
||||
{
|
||||
return p->uv_editor_canvas;
|
||||
}
|
||||
|
||||
void Plater::show_uv_editor(bool show)
|
||||
{
|
||||
if (p->uv_editor_panel == nullptr)
|
||||
return;
|
||||
const wxAuiPaneInfo &pane = p->m_aui_mgr.GetPane(p->uv_editor_panel);
|
||||
if (!pane.IsOk() || pane.IsShown() == show)
|
||||
return;
|
||||
|
||||
// Deferred, because GLGizmoTextureDisplacement calls this from its ImGui panel - that is, from
|
||||
// the middle of the 3D canvas's GL frame. Showing an AUI pane re-lays out the window and
|
||||
// delivers the resulting size/paint events synchronously, and the UV canvas painting itself
|
||||
// makes its own surface current in the app's *shared* GL context, which mid-frame is the one
|
||||
// the 3D canvas is drawing into. Doing the layout once the frame is over avoids that entirely.
|
||||
CallAfter([this, show]() {
|
||||
wxAuiPaneInfo &deferred_pane = p->m_aui_mgr.GetPane(p->uv_editor_panel);
|
||||
if (!deferred_pane.IsOk() || deferred_pane.IsShown() == show)
|
||||
return;
|
||||
deferred_pane.Show(show);
|
||||
p->m_aui_mgr.Update();
|
||||
});
|
||||
}
|
||||
|
||||
GLCanvas3D* Plater::get_current_canvas3D(bool exclude_preview)
|
||||
{
|
||||
return p->get_current_canvas3D(exclude_preview);
|
||||
@@ -22886,8 +22977,9 @@ bool Plater::can_copy_to_clipboard() const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Plater::can_undo() const { return IsShown() && p->is_view3D_shown() && p->undo_redo_stack().has_undo_snapshot(); }
|
||||
bool Plater::can_redo() const { return IsShown() && p->is_view3D_shown() && p->undo_redo_stack().has_redo_snapshot(); }
|
||||
// The job check keeps the buttons in step with priv::undo()/redo(), which refuse while one runs.
|
||||
bool Plater::can_undo() const { return IsShown() && p->is_view3D_shown() && p->m_worker.is_idle() && p->undo_redo_stack().has_undo_snapshot(); }
|
||||
bool Plater::can_redo() const { return IsShown() && p->is_view3D_shown() && p->m_worker.is_idle() && p->undo_redo_stack().has_redo_snapshot(); }
|
||||
bool Plater::can_reload_from_disk() const { return p->can_reload_from_disk(); }
|
||||
//BBS
|
||||
bool Plater::can_fillcolor() const { return p->can_fillcolor(); }
|
||||
|
||||
Reference in new issue
Block a user