mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-23 06:33:57 -06:00
Merge branch 'main' into dev/support-paint-vertical
This commit is contained in:
commit
a9a6f45f08
344 changed files with 29108 additions and 10950 deletions
|
@ -258,7 +258,7 @@ void AMSMaterialsSetting::create_panel_normal(wxWindow* parent)
|
|||
m_panel_SN->Fit();
|
||||
|
||||
wxBoxSizer* m_tip_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_tip_readonly = new Label(parent, _L(""));
|
||||
m_tip_readonly = new Label(parent, L"");
|
||||
m_tip_readonly->SetForegroundColour(*wxBLACK);
|
||||
m_tip_readonly->SetBackgroundColour(*wxWHITE);
|
||||
m_tip_readonly->SetMinSize(wxSize(FromDIP(380), -1));
|
||||
|
|
|
@ -527,19 +527,22 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
bool has_spiral_vase = config->opt_bool("spiral_mode");
|
||||
toggle_line("spiral_mode_smooth", has_spiral_vase);
|
||||
toggle_line("spiral_mode_max_xy_smoothing", has_spiral_vase && config->opt_bool("spiral_mode_smooth"));
|
||||
bool has_top_solid_infill = config->opt_int("top_shell_layers") > 0;
|
||||
bool has_bottom_solid_infill = config->opt_int("bottom_shell_layers") > 0;
|
||||
bool has_solid_infill = has_top_solid_infill || has_bottom_solid_infill;
|
||||
// solid_infill_filament uses the same logic as in Print::extruders()
|
||||
for (auto el : { "top_surface_pattern", "bottom_surface_pattern", "internal_solid_infill_pattern", "solid_infill_filament"})
|
||||
toggle_field(el, has_solid_infill);
|
||||
toggle_line("spiral_starting_flow_ratio", has_spiral_vase);
|
||||
toggle_line("spiral_finishing_flow_ratio", has_spiral_vase);
|
||||
bool has_top_shell = config->opt_int("top_shell_layers") > 0;
|
||||
bool has_bottom_shell = config->opt_int("bottom_shell_layers") > 0;
|
||||
bool has_solid_infill = has_top_shell || has_bottom_shell;
|
||||
toggle_field("top_surface_pattern", has_top_shell);
|
||||
toggle_field("bottom_surface_pattern", has_bottom_shell);
|
||||
|
||||
for (auto el : { "infill_direction", "sparse_infill_line_width",
|
||||
"sparse_infill_speed", "bridge_speed", "internal_bridge_speed", "bridge_angle","solid_infill_direction", "rotate_solid_infill_direction" })
|
||||
"sparse_infill_speed", "bridge_speed", "internal_bridge_speed", "bridge_angle","internal_bridge_angle",
|
||||
"solid_infill_direction", "rotate_solid_infill_direction", "internal_solid_infill_pattern", "solid_infill_filament",
|
||||
})
|
||||
toggle_field(el, have_infill || has_solid_infill);
|
||||
|
||||
toggle_field("top_shell_thickness", ! has_spiral_vase && has_top_solid_infill);
|
||||
toggle_field("bottom_shell_thickness", ! has_spiral_vase && has_bottom_solid_infill);
|
||||
toggle_field("top_shell_thickness", ! has_spiral_vase && has_top_shell);
|
||||
toggle_field("bottom_shell_thickness", ! has_spiral_vase && has_bottom_shell);
|
||||
|
||||
toggle_field("wall_direction", !has_spiral_vase);
|
||||
|
||||
|
@ -547,7 +550,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
toggle_field("gap_infill_speed", have_perimeters);
|
||||
|
||||
for (auto el : { "top_surface_line_width", "top_surface_speed" })
|
||||
toggle_field(el, has_top_solid_infill || (has_spiral_vase && has_bottom_solid_infill));
|
||||
toggle_field(el, has_top_shell || (has_spiral_vase && has_bottom_shell));
|
||||
|
||||
bool have_default_acceleration = config->opt_float("default_acceleration") > 0;
|
||||
|
||||
|
@ -567,7 +570,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
|
||||
bool have_brim = (config->opt_enum<BrimType>("brim_type") != btNoBrim);
|
||||
toggle_field("brim_object_gap", have_brim);
|
||||
bool have_brim_width = (config->opt_enum<BrimType>("brim_type") != btNoBrim) && config->opt_enum<BrimType>("brim_type") != btAutoBrim;
|
||||
bool have_brim_width = (config->opt_enum<BrimType>("brim_type") != btNoBrim) && config->opt_enum<BrimType>("brim_type") != btAutoBrim &&
|
||||
config->opt_enum<BrimType>("brim_type") != btPainted;
|
||||
toggle_field("brim_width", have_brim_width);
|
||||
// wall_filament uses the same logic as in Print::extruders()
|
||||
toggle_field("wall_filament", have_perimeters || have_brim);
|
||||
|
@ -782,6 +786,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
toggle_line("interlocking_beam_layer_count", use_beam_interlocking);
|
||||
toggle_line("interlocking_depth", use_beam_interlocking);
|
||||
toggle_line("interlocking_boundary_avoidance", use_beam_interlocking);
|
||||
|
||||
bool lattice_options = config->opt_enum<InfillPattern>("sparse_infill_pattern") == InfillPattern::ip2DLattice;
|
||||
for (auto el : { "lattice_angle_1", "lattice_angle_2"})
|
||||
toggle_line(el, lattice_options);
|
||||
}
|
||||
|
||||
void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "CreatePresetsDialog.hpp"
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
@ -4240,6 +4241,10 @@ void ExportConfigsDialog::data_init()
|
|||
Preset *new_filament_preset = new Preset(filament_preset);
|
||||
const Preset *base_filament_preset = preset_bundle.filaments.get_preset_base(*new_filament_preset);
|
||||
|
||||
if (base_filament_preset == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Failed to find base preset";
|
||||
continue;
|
||||
}
|
||||
std::string filament_preset_name = base_filament_preset->name;
|
||||
std::string machine_name = get_machine_name(filament_preset_name);
|
||||
m_filament_name_to_presets[get_filament_name(filament_preset_name)].push_back(std::make_pair(get_vendor_name(machine_name), new_filament_preset));
|
||||
|
|
|
@ -1441,6 +1441,8 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject
|
|||
&& !vol->is_modifier) {
|
||||
vol->force_neutral_color = true;
|
||||
}
|
||||
else if (gizmo_type == GLGizmosManager::BrimEars)
|
||||
vol->force_neutral_color = false;
|
||||
else if (gizmo_type == GLGizmosManager::MmuSegmentation)
|
||||
vol->is_active = false;
|
||||
else
|
||||
|
@ -1539,15 +1541,22 @@ void GLCanvas3D::refresh_camera_scene_box()
|
|||
BoundingBoxf3 GLCanvas3D::volumes_bounding_box(bool current_plate_only) const
|
||||
{
|
||||
BoundingBoxf3 bb;
|
||||
PartPlate *plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
|
||||
|
||||
BoundingBoxf3 expand_part_plate_list_box;
|
||||
bool is_limit = m_canvas_type != ECanvasType::CanvasAssembleView;
|
||||
if (is_limit) {
|
||||
auto plate_list_box = current_plate_only ? wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_bounding_box() :
|
||||
wxGetApp().plater()->get_partplate_list().get_bounding_box();
|
||||
auto horizontal_radius = 0.5 * sqrt(std::pow(plate_list_box.min[0] - plate_list_box.max[0], 2) + std::pow(plate_list_box.min[1] - plate_list_box.max[1], 2));
|
||||
const float scale = 2;
|
||||
expand_part_plate_list_box.merge(plate_list_box.min - scale * Vec3d(horizontal_radius, horizontal_radius, 0));
|
||||
expand_part_plate_list_box.merge(plate_list_box.max + scale * Vec3d(horizontal_radius, horizontal_radius, 0));
|
||||
}
|
||||
for (const GLVolume *volume : m_volumes.volumes) {
|
||||
if (!m_apply_zoom_to_volumes_filter || ((volume != nullptr) && volume->zoom_to_volumes)) {
|
||||
const auto plate_bb = plate->get_bounding_box();
|
||||
const auto v_bb = volume->transformed_bounding_box();
|
||||
if (!plate_bb.overlap(v_bb))
|
||||
continue;
|
||||
bb.merge(v_bb);
|
||||
const auto v_bb = volume->transformed_bounding_box();
|
||||
if (is_limit && !expand_part_plate_list_box.overlap(v_bb))
|
||||
continue;
|
||||
bb.merge(v_bb);
|
||||
}
|
||||
}
|
||||
return bb;
|
||||
|
@ -1893,6 +1902,7 @@ void GLCanvas3D::render(bool only_init)
|
|||
|
||||
//BBS add partplater rendering logic
|
||||
bool only_current = false, only_body = false, show_axes = true, no_partplate = false;
|
||||
bool show_grid = true;
|
||||
GLGizmosManager::EType gizmo_type = m_gizmos.get_current_type();
|
||||
if (!m_main_toolbar.is_enabled()) {
|
||||
//only_body = true;
|
||||
|
@ -1900,6 +1910,8 @@ void GLCanvas3D::render(bool only_init)
|
|||
}
|
||||
else if ((gizmo_type == GLGizmosManager::FdmSupports) || (gizmo_type == GLGizmosManager::Seam) || (gizmo_type == GLGizmosManager::MmuSegmentation))
|
||||
no_partplate = true;
|
||||
else if (gizmo_type == GLGizmosManager::BrimEars && !camera.is_looking_downward())
|
||||
show_grid = false;
|
||||
|
||||
/* view3D render*/
|
||||
int hover_id = (m_hover_plate_idxs.size() > 0)?m_hover_plate_idxs.front():-1;
|
||||
|
@ -1911,7 +1923,7 @@ void GLCanvas3D::render(bool only_init)
|
|||
if (!no_partplate)
|
||||
_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
|
||||
if (!no_partplate) //BBS: add outline logic
|
||||
_render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, only_body, hover_id, true);
|
||||
_render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, only_body, hover_id, true, show_grid);
|
||||
_render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running());
|
||||
}
|
||||
/* preview render */
|
||||
|
@ -7162,9 +7174,9 @@ void GLCanvas3D::_render_bed(const Transform3d& view_matrix, const Transform3d&
|
|||
m_bed.render(*this, view_matrix, projection_matrix, bottom, scale_factor, show_axes);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali)
|
||||
void GLCanvas3D::_render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali, bool show_grid)
|
||||
{
|
||||
wxGetApp().plater()->get_partplate_list().render(view_matrix, projection_matrix, bottom, only_current, only_body, hover_id, render_cali);
|
||||
wxGetApp().plater()->get_partplate_list().render(view_matrix, projection_matrix, bottom, only_current, only_body, hover_id, render_cali, show_grid);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_plane() const
|
||||
|
@ -7431,7 +7443,7 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale()
|
|||
return;
|
||||
}
|
||||
|
||||
float scale = wxGetApp().toolbar_icon_scale();
|
||||
float scale = wxGetApp().toolbar_icon_scale() * get_scale();
|
||||
Size cnv_size = get_canvas_size();
|
||||
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
|
@ -7442,26 +7454,12 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale()
|
|||
float size = size_i;
|
||||
|
||||
// Set current size for all top toolbars. It will be used for next calculations
|
||||
#if ENABLE_RETINA_GL
|
||||
const float sc = m_retina_helper->get_scale_factor() * scale;
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
m_main_toolbar.set_scale(sc);
|
||||
m_assemble_view_toolbar.set_scale(sc);
|
||||
m_separator_toolbar.set_scale(sc);
|
||||
collapse_toolbar.set_scale(sc / 2.0);
|
||||
size *= m_retina_helper->get_scale_factor();
|
||||
|
||||
auto* m_notification = wxGetApp().plater()->get_notification_manager();
|
||||
m_notification->set_scale(sc);
|
||||
m_gizmos.set_overlay_scale(sc);
|
||||
#else
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
m_main_toolbar.set_icons_size(size);
|
||||
m_assemble_view_toolbar.set_icons_size(size);
|
||||
m_separator_toolbar.set_icons_size(size);
|
||||
collapse_toolbar.set_icons_size(size / 2.0);
|
||||
m_gizmos.set_overlay_icon_size(size);
|
||||
#endif // ENABLE_RETINA_GL
|
||||
|
||||
//BBS: GUI refactor: GLToolbar
|
||||
#if BBS_TOOLBAR_ON_TOP
|
||||
|
@ -7498,9 +7496,7 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale()
|
|||
|
||||
// set minimum scale as a auto scale for the toolbars
|
||||
float new_scale = std::min(new_h_scale, new_v_scale);
|
||||
#if ENABLE_RETINA_GL
|
||||
new_scale /= m_retina_helper->get_scale_factor();
|
||||
#endif
|
||||
new_scale /= get_scale();
|
||||
if (fabs(new_scale - scale) > 0.05) // scale is changed by 5% and more
|
||||
wxGetApp().set_auto_toolbar_icon_scale(new_scale);
|
||||
}
|
||||
|
|
|
@ -1161,7 +1161,7 @@ private:
|
|||
void _render_background();
|
||||
void _render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes);
|
||||
//BBS: add part plate related logic
|
||||
void _render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body = false, int hover_id = -1, bool render_cali = false);
|
||||
void _render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body = false, int hover_id = -1, bool render_cali = false, bool show_grid = true);
|
||||
//BBS: add outline drawing logic
|
||||
void _render_objects(GLVolumeCollection::ERenderType type, bool with_outline = true);
|
||||
//BBS: GUI refactor: add canvas size as parameters
|
||||
|
|
|
@ -106,8 +106,8 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::PART_CAT
|
|||
}},
|
||||
{ L("Strength"), {{"wall_loops", "",1},{"top_shell_layers", L("Top Solid Layers"),1},{"top_shell_thickness", L("Top Minimum Shell Thickness"),1},
|
||||
{"bottom_shell_layers", L("Bottom Solid Layers"),1}, {"bottom_shell_thickness", L("Bottom Minimum Shell Thickness"),1},
|
||||
{"sparse_infill_density", "",1},{"sparse_infill_pattern", "",1},{"infill_anchor", "",1},{"infill_anchor_max", "",1},{"top_surface_pattern", "",1},{"bottom_surface_pattern", "",1}, {"internal_solid_infill_pattern", "",1},
|
||||
{"infill_combination", "",1}, {"infill_combination_max_layer_height", "",1}, {"infill_wall_overlap", "",1},{"top_bottom_infill_wall_overlap", "",1}, {"solid_infill_direction", "",1}, {"rotate_solid_infill_direction", "",1}, {"infill_direction", "",1}, {"bridge_angle", "",1}, {"minimum_sparse_infill_area", "",1}
|
||||
{"sparse_infill_density", "",1},{"sparse_infill_pattern", "",1},{"lattice_angle_1", "",1},{"lattice_angle_2", "",1},{"infill_anchor", "",1},{"infill_anchor_max", "",1},{"top_surface_pattern", "",1},{"bottom_surface_pattern", "",1}, {"internal_solid_infill_pattern", "",1},
|
||||
{"infill_combination", "",1}, {"infill_combination_max_layer_height", "",1}, {"infill_wall_overlap", "",1},{"top_bottom_infill_wall_overlap", "",1}, {"solid_infill_direction", "",1}, {"rotate_solid_infill_direction", "",1}, {"infill_direction", "",1}, {"bridge_angle", "",1}, {"internal_bridge_angle", "",1}, {"minimum_sparse_infill_area", "",1}
|
||||
}},
|
||||
{ L("Speed"), {{"outer_wall_speed", "",1},{"inner_wall_speed", "",2},{"sparse_infill_speed", "",3},{"top_surface_speed", "",4}, {"internal_solid_infill_speed", "",5},
|
||||
{"enable_overhang_speed", "",6}, {"overhang_speed_classic", "",6}, {"overhang_1_4_speed", "",7}, {"overhang_2_4_speed", "",8}, {"overhang_3_4_speed", "",9}, {"overhang_4_4_speed", "",10},
|
||||
|
|
|
@ -74,11 +74,11 @@ PickingModel GLGizmoBase::Grabber::s_cone;
|
|||
|
||||
GLGizmoBase::Grabber::~Grabber()
|
||||
{
|
||||
if (s_cube.model.is_initialized())
|
||||
s_cube.model.reset();
|
||||
//if (s_cube.model.is_initialized())
|
||||
// s_cube.model.reset();
|
||||
|
||||
if (s_cone.model.is_initialized())
|
||||
s_cone.model.reset();
|
||||
//if (s_cone.model.is_initialized())
|
||||
// s_cone.model.reset();
|
||||
}
|
||||
|
||||
float GLGizmoBase::Grabber::get_half_size(float size) const
|
||||
|
|
|
@ -32,6 +32,7 @@ class ImGuiWrapper;
|
|||
class GLCanvas3D;
|
||||
enum class CommonGizmosDataID;
|
||||
class CommonGizmosDataPool;
|
||||
class Selection;
|
||||
|
||||
class GLGizmoBase
|
||||
{
|
||||
|
|
1167
src/slic3r/GUI/Gizmos/GLGizmoBrimEars.cpp
Normal file
1167
src/slic3r/GUI/Gizmos/GLGizmoBrimEars.cpp
Normal file
File diff suppressed because it is too large
Load diff
180
src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp
Normal file
180
src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp
Normal file
|
@ -0,0 +1,180 @@
|
|||
#ifndef slic3r_GLGizmoBrimEars_hpp_
|
||||
#define slic3r_GLGizmoBrimEars_hpp_
|
||||
|
||||
#include "GLGizmoBase.hpp"
|
||||
#include "slic3r/GUI/GLSelectionRectangle.hpp"
|
||||
#include "libslic3r/BrimEarsPoint.hpp"
|
||||
#include "libslic3r/ObjectID.hpp"
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class ConfigOption;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
enum class SLAGizmoEventType : unsigned char;
|
||||
|
||||
class GLGizmoBrimEars : public GLGizmoBase
|
||||
{
|
||||
private:
|
||||
using PickRaycaster = SceneRaycasterItem;
|
||||
|
||||
bool unproject_on_mesh(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
|
||||
bool unproject_on_mesh2(const Vec2d& mouse_pos, std::pair<Vec3f, Vec3f>& pos_and_normal);
|
||||
|
||||
const float RenderPointScale = 1.f;
|
||||
|
||||
class CacheEntry {
|
||||
public:
|
||||
CacheEntry() :
|
||||
brim_point(BrimPoint()),
|
||||
selected(false),
|
||||
normal(Vec3f(0, 0, 1)),
|
||||
is_hover(false),
|
||||
is_error(false)
|
||||
{}
|
||||
|
||||
CacheEntry(const BrimPoint &point, bool sel = false, const Vec3f &norm = Vec3f(0, 0, 1), bool hover = false, bool error = false)
|
||||
: brim_point(point), selected(sel), normal(norm), is_hover(hover), is_error(error)
|
||||
{}
|
||||
|
||||
bool operator==(const CacheEntry& rhs) const {
|
||||
return (brim_point == rhs.brim_point);
|
||||
}
|
||||
|
||||
bool operator!=(const CacheEntry& rhs) const {
|
||||
return ! ((*this) == rhs);
|
||||
}
|
||||
|
||||
inline bool pos_is_zero() {
|
||||
return brim_point.pos.isZero();
|
||||
}
|
||||
|
||||
void set_empty() {
|
||||
brim_point = BrimPoint();
|
||||
selected = false;
|
||||
normal.setZero();
|
||||
is_hover = false;
|
||||
is_error = false;
|
||||
}
|
||||
|
||||
BrimPoint brim_point;
|
||||
bool selected; // whether the point is selected
|
||||
bool is_hover; // show mouse hover cylinder
|
||||
bool is_error;
|
||||
Vec3f normal;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar)
|
||||
{
|
||||
ar(brim_point, selected, normal);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
GLGizmoBrimEars(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
virtual ~GLGizmoBrimEars() = default;
|
||||
void data_changed(bool is_serializing) override;
|
||||
void set_brim_data();
|
||||
bool on_mouse(const wxMouseEvent& mouse_event) override;
|
||||
bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position, bool shift_down, bool alt_down, bool control_down);
|
||||
void delete_selected_points();
|
||||
void save_model();
|
||||
//ClippingPlane get_sla_clipping_plane() const;
|
||||
|
||||
bool is_selection_rectangle_dragging() const { return m_selection_rectangle.is_dragging(); }
|
||||
|
||||
bool wants_enter_leave_snapshots() const override { return true; }
|
||||
std::string get_gizmo_entering_text() const override { return "Entering Brim Ears"; }
|
||||
std::string get_gizmo_leaving_text() const override { return "Leaving Brim Ears"; }
|
||||
|
||||
private:
|
||||
bool on_init() override;
|
||||
void on_dragging(const UpdateData& data) override;
|
||||
void on_render() override;
|
||||
|
||||
void render_points(const Selection& selection);
|
||||
|
||||
float m_new_point_head_diameter; // Size of a new point.
|
||||
float m_max_angle = 125.f;
|
||||
float m_detection_radius = 1.f;
|
||||
double m_detection_radius_max = .0f;
|
||||
CacheEntry m_point_before_drag; // undo/redo - so we know what state was edited
|
||||
float m_old_point_head_diameter = 0.; // the same
|
||||
mutable std::vector<CacheEntry> m_editing_cache; // a support point and whether it is currently selectedchanges or undo/redo
|
||||
std::map<int, CacheEntry> m_single_brim;
|
||||
ObjectID m_old_mo_id;
|
||||
const Vec3d m_world_normal = {0, 0, 1};
|
||||
std::map<GLVolume*, std::shared_ptr<PickRaycaster>> m_mesh_raycaster_map;
|
||||
GLVolume* m_last_hit_volume;
|
||||
CacheEntry* render_hover_point = nullptr;
|
||||
|
||||
bool m_link_text_hover = false;
|
||||
|
||||
PickingModel m_cylinder;
|
||||
|
||||
// This map holds all translated description texts, so they can be easily referenced during layout calculations
|
||||
// etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect.
|
||||
std::map<std::string, wxString> m_desc;
|
||||
|
||||
GLSelectionRectangle m_selection_rectangle;
|
||||
|
||||
ExPolygons m_first_layer;
|
||||
|
||||
bool m_wait_for_up_event = false;
|
||||
bool m_selection_empty = true;
|
||||
EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state)
|
||||
|
||||
std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
|
||||
bool is_mesh_point_clipped(const Vec3d& point) const;
|
||||
|
||||
// Methods that do the model_object and editing cache synchronization,
|
||||
// editing mode selection, etc:
|
||||
enum {
|
||||
AllPoints = -2,
|
||||
NoPoints,
|
||||
};
|
||||
void select_point(int i);
|
||||
void unselect_point(int i);
|
||||
void reload_cache();
|
||||
Points generate_points(Polygon &obj_polygon, float ear_detection_length, float brim_ears_max_angle, bool is_outer);
|
||||
void auto_generate();
|
||||
void first_layer_slicer();
|
||||
void get_detection_radius_max();
|
||||
void update_raycasters();
|
||||
|
||||
protected:
|
||||
void on_set_state() override;
|
||||
void on_set_hover_id() override
|
||||
|
||||
{
|
||||
if ((int)m_editing_cache.size() <= m_hover_id)
|
||||
m_hover_id = -1;
|
||||
}
|
||||
void on_start_dragging() override;
|
||||
void on_stop_dragging() override;
|
||||
void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||
void show_tooltip_information(float x, float y);
|
||||
|
||||
std::string on_get_name() const override;
|
||||
bool on_is_activable() const override;
|
||||
//bool on_is_selectable() const override;
|
||||
virtual CommonGizmosDataID on_get_requirements() const override;
|
||||
void on_load(cereal::BinaryInputArchive& ar) override;
|
||||
void on_save(cereal::BinaryOutputArchive& ar) const override;
|
||||
virtual void on_register_raycasters_for_picking() override;
|
||||
virtual void on_unregister_raycasters_for_picking() override;
|
||||
void register_single_mesh_pick();
|
||||
//void update_single_mesh_pick(GLVolume* v);
|
||||
void reset_all_pick();
|
||||
bool add_point_to_cache(Vec3f pos, float head_radius, bool selected, Vec3f normal);
|
||||
float get_brim_default_radius() const;
|
||||
ExPolygon make_polygon(BrimPoint point, const Geometry::Transformation &trsf);
|
||||
void find_single();
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // slic3r_GLGizmoBrimEars_hpp_
|
|
@ -312,6 +312,11 @@ void ObjectClipper::render_cut(const std::vector<size_t>* ignore_idxs) const
|
|||
}
|
||||
}
|
||||
|
||||
void ObjectClipper::set_position_to_init_layer()
|
||||
{
|
||||
m_clp.reset(new ClippingPlane({0, 0, 1}, 0.1));
|
||||
get_pool()->get_canvas()->set_as_dirty();
|
||||
}
|
||||
|
||||
int ObjectClipper::get_number_of_contours() const
|
||||
{
|
||||
|
@ -351,17 +356,22 @@ std::vector<Vec3d> ObjectClipper::point_per_contour() const
|
|||
}
|
||||
|
||||
|
||||
void ObjectClipper::set_position_by_ratio(double pos, bool keep_normal)
|
||||
void ObjectClipper::set_position_by_ratio(double pos, bool keep_normal, bool vertical_normal)
|
||||
{
|
||||
const ModelObject* mo = get_pool()->selection_info()->model_object();
|
||||
int active_inst = get_pool()->selection_info()->get_active_instance();
|
||||
double z_shift = get_pool()->selection_info()->get_sla_shift();
|
||||
|
||||
//Vec3d camera_dir = wxGetApp().plater()->get_camera().get_dir_forward();
|
||||
//if (abs(camera_dir(0)) > EPSILON || abs(camera_dir(1)) > EPSILON)
|
||||
// camera_dir(2) = 0;
|
||||
Vec3d normal;
|
||||
if(vertical_normal) {
|
||||
normal = {0, 0, 1};
|
||||
}else {
|
||||
//Vec3d camera_dir = wxGetApp().plater()->get_camera().get_dir_forward();
|
||||
//if (abs(camera_dir(0)) > EPSILON || abs(camera_dir(1)) > EPSILON)
|
||||
// camera_dir(2) = 0;
|
||||
|
||||
Vec3d normal = (keep_normal && m_clp) ? m_clp->get_normal() : /*-camera_dir;*/ -wxGetApp().plater()->get_camera().get_dir_forward();
|
||||
normal = (keep_normal && m_clp) ? m_clp->get_normal() : /*-camera_dir;*/ -wxGetApp().plater()->get_camera().get_dir_forward();
|
||||
}
|
||||
Vec3d center;
|
||||
|
||||
if (get_pool()->get_canvas()->get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||
|
|
|
@ -232,9 +232,10 @@ public:
|
|||
CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
|
||||
#endif // NDEBUG
|
||||
double get_position() const { return m_clp_ratio; }
|
||||
void set_position_to_init_layer();
|
||||
const ClippingPlane* get_clipping_plane(bool ignore_hide_clipped = false) const;
|
||||
void render_cut(const std::vector<size_t>* ignore_idxs = nullptr) const;
|
||||
void set_position_by_ratio(double pos, bool keep_normal);
|
||||
void set_position_by_ratio(double pos, bool keep_normal, bool vertical_normal=false);
|
||||
void set_range_and_pos(const Vec3d& cpl_normal, double cpl_offset, double pos);
|
||||
void set_behavior(bool hide_clipped, bool fill_cut, double contour_width);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "slic3r/GUI/Gizmos/GLGizmoFlatten.hpp"
|
||||
//#include "slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoCut.hpp"
|
||||
//#include "slic3r/GUI/Gizmos/GLGizmoFaceDetector.hpp"
|
||||
//#include "slic3r/GUI/Gizmos/GLGizmoHollow.hpp"
|
||||
|
@ -206,6 +207,7 @@ bool GLGizmosManager::init()
|
|||
m_gizmos.emplace_back(new GLGizmoMeasure(m_parent, m_is_dark ? "toolbar_measure_dark.svg" : "toolbar_measure.svg", EType::Measure));
|
||||
m_gizmos.emplace_back(new GLGizmoAssembly(m_parent, m_is_dark ? "toolbar_assembly_dark.svg" : "toolbar_assembly.svg", EType::Assembly));
|
||||
m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify));
|
||||
m_gizmos.emplace_back(new GLGizmoBrimEars(m_parent, m_is_dark ? "toolbar_brimears_dark.svg" : "toolbar_brimears.svg", EType::BrimEars));
|
||||
//m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++));
|
||||
//m_gizmos.emplace_back(new GLGizmoFaceDetector(m_parent, "face recognition.svg", sprite_id++));
|
||||
//m_gizmos.emplace_back(new GLGizmoHollow(m_parent, "hollow.svg", sprite_id++));
|
||||
|
@ -453,6 +455,8 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
|
|||
return dynamic_cast<GLGizmoCut3D*>(m_gizmos[Cut].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else if (m_current == MeshBoolean)
|
||||
return dynamic_cast<GLGizmoMeshBoolean*>(m_gizmos[MeshBoolean].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else if (m_current == BrimEars)
|
||||
return dynamic_cast<GLGizmoBrimEars*>(m_gizmos[BrimEars].get())->gizmo_event(action, mouse_position, shift_down, alt_down, control_down);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -543,7 +547,7 @@ bool GLGizmosManager::on_mouse_wheel(const wxMouseEvent &evt)
|
|||
{
|
||||
bool processed = false;
|
||||
|
||||
if (/*m_current == SlaSupports || m_current == Hollow ||*/ m_current == FdmSupports || m_current == Seam || m_current == MmuSegmentation) {
|
||||
if (/*m_current == SlaSupports || m_current == Hollow ||*/ m_current == FdmSupports || m_current == Seam || m_current == MmuSegmentation || m_current == BrimEars) {
|
||||
float rot = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
|
||||
if (gizmo_event((rot > 0.f ? SLAGizmoEventType::MouseWheelUp : SLAGizmoEventType::MouseWheelDown), Vec2d::Zero(), evt.ShiftDown(), evt.AltDown()
|
||||
// BBS
|
||||
|
@ -813,21 +817,25 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
|
|||
int keyCode = evt.GetKeyCode();
|
||||
bool processed = false;
|
||||
|
||||
if (evt.GetEventType() == wxEVT_KEY_UP) {
|
||||
/*if (m_current == SlaSupports || m_current == Hollow)
|
||||
if (evt.GetEventType() == wxEVT_KEY_UP)
|
||||
{
|
||||
if (/*m_current == SlaSupports || m_current == Hollow ||*/ m_current == BrimEars)
|
||||
{
|
||||
bool is_editing = true;
|
||||
bool is_rectangle_dragging = false;
|
||||
|
||||
if (m_current == SlaSupports) {
|
||||
/*if (m_current == SlaSupports) {
|
||||
GLGizmoSlaSupports* gizmo = dynamic_cast<GLGizmoSlaSupports*>(get_current());
|
||||
is_editing = gizmo->is_in_editing_mode();
|
||||
is_rectangle_dragging = gizmo->is_selection_rectangle_dragging();
|
||||
}
|
||||
else {
|
||||
GLGizmoHollow* gizmo = dynamic_cast<GLGizmoHollow*>(get_current());
|
||||
} else*/ if (m_current == BrimEars) {
|
||||
GLGizmoBrimEars* gizmo = dynamic_cast<GLGizmoBrimEars*>(get_current());
|
||||
is_rectangle_dragging = gizmo->is_selection_rectangle_dragging();
|
||||
}
|
||||
/*else {
|
||||
GLGizmoHollow* gizmo = dynamic_cast<GLGizmoHollow*>(get_current());
|
||||
is_rectangle_dragging = gizmo->is_selection_rectangle_dragging();
|
||||
}*/
|
||||
|
||||
if (keyCode == WXK_SHIFT)
|
||||
{
|
||||
|
@ -847,7 +855,7 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
|
|||
// capture number key
|
||||
processed = true;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
if (m_current == Measure || m_current == Assembly) {
|
||||
if (keyCode == WXK_CONTROL)
|
||||
gizmo_event(SLAGizmoEventType::CtrlUp, Vec2d::Zero(), evt.ShiftDown(), evt.AltDown(), evt.CmdDown());
|
||||
|
@ -865,7 +873,12 @@ bool GLGizmosManager::on_key(wxKeyEvent& evt)
|
|||
// m_parent.set_cursor(GLCanvas3D::Cross);
|
||||
processed = true;
|
||||
}
|
||||
else*/ if (m_current == Cut) {
|
||||
else*/ if ((m_current == BrimEars) && ((keyCode == WXK_SHIFT) || (keyCode == WXK_ALT)))
|
||||
{
|
||||
processed = true;
|
||||
}
|
||||
else if (m_current == Cut)
|
||||
{
|
||||
auto do_move = [this, &processed](double delta_z) {
|
||||
GLGizmoCut3D* cut = dynamic_cast<GLGizmoCut3D*>(get_current());
|
||||
cut->shift_cut(delta_z);
|
||||
|
@ -1324,11 +1337,15 @@ bool GLGizmosManager::grabber_contains_mouse() const
|
|||
|
||||
bool GLGizmosManager::is_in_editing_mode(bool error_notification) const
|
||||
{
|
||||
//if (m_current != SlaSupports || ! dynamic_cast<GLGizmoSlaSupports*>(get_current())->is_in_editing_mode())
|
||||
/*if (m_current == SlaSupports && dynamic_cast<GLGizmoSlaSupports*>(get_current())->is_in_editing_mode()) {
|
||||
return true;
|
||||
} else*/ if (m_current == BrimEars) {
|
||||
dynamic_cast<GLGizmoBrimEars*>(get_current())->save_model();
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// BBS: remove SLA editing notification
|
||||
//return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
Measure,
|
||||
Assembly,
|
||||
Simplify,
|
||||
BrimEars,
|
||||
//SlaSupports,
|
||||
// BBS
|
||||
//FaceRecognition,
|
||||
|
|
|
@ -416,7 +416,7 @@ void ImGuiWrapper::set_language(const std::string &language)
|
|||
}
|
||||
else if (lang == "en") {
|
||||
ranges = ImGui::GetIO().Fonts->GetGlyphRangesEnglish(); // Basic Latin
|
||||
}
|
||||
}
|
||||
else{
|
||||
ranges = ImGui::GetIO().Fonts->GetGlyphRangesOthers();
|
||||
}
|
||||
|
@ -560,6 +560,15 @@ ImVec2 ImGuiWrapper::calc_text_size(const wxString &text,
|
|||
return size;
|
||||
}
|
||||
|
||||
float ImGuiWrapper::find_widest_text(std::vector<wxString> &text_list)
|
||||
{
|
||||
float width = .0f;
|
||||
for(const wxString &text : text_list) {
|
||||
width = std::max(width, this->calc_text_size(text).x);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
ImVec2 ImGuiWrapper::calc_button_size(const wxString &text, const ImVec2 &button_size) const
|
||||
{
|
||||
const ImVec2 text_size = this->calc_text_size(text);
|
||||
|
@ -1598,9 +1607,9 @@ bool begin_menu(const char *label, bool enabled)
|
|||
return menu_is_open;
|
||||
}
|
||||
|
||||
void end_menu()
|
||||
{
|
||||
ImGui::EndMenu();
|
||||
void end_menu()
|
||||
{
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
bool menu_item_with_icon(const char *label, const char *shortcut, ImVec2 icon_size /* = ImVec2(0, 0)*/, ImU32 icon_color /* = 0*/, bool selected /* = false*/, bool enabled /* = true*/, bool* hovered/* = nullptr*/)
|
||||
|
|
|
@ -107,7 +107,7 @@ public:
|
|||
static ImVec2 calc_text_size(const std::string& text, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||
static ImVec2 calc_text_size(const wxString &text, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||
ImVec2 calc_button_size(const wxString &text, const ImVec2 &button_size = ImVec2(0, 0)) const;
|
||||
|
||||
float find_widest_text(std::vector<wxString> &text_list);
|
||||
ImVec2 get_item_spacing() const;
|
||||
float get_slider_float_height() const;
|
||||
const LastSliderStatus& get_last_slider_status() const { return m_last_slider_status; }
|
||||
|
|
|
@ -269,7 +269,16 @@ void PrintJob::process(Ctl &ctl)
|
|||
auto model_name = model_info->metadata_items.find(BBL_DESIGNER_MODEL_TITLE_TAG);
|
||||
if (model_name != model_info->metadata_items.end()) {
|
||||
try {
|
||||
params.project_name = model_name->second;
|
||||
|
||||
std::string mall_model_name = model_name->second;
|
||||
std::replace(mall_model_name.begin(), mall_model_name.end(), ' ', '_');
|
||||
const char* unusable_symbols = "<>[]:/\\|?*\" ";
|
||||
for (const char* symbol = unusable_symbols; *symbol != '\0'; ++symbol) {
|
||||
std::replace(mall_model_name.begin(), mall_model_name.end(), *symbol, '_');
|
||||
}
|
||||
|
||||
std::regex pattern("_+");
|
||||
params.project_name = std::regex_replace(mall_model_name, pattern, "_");
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
|
|
|
@ -2721,7 +2721,7 @@ void MainFrame::init_menubar_as_editor()
|
|||
this, [this]() { return m_plater->is_view3D_shown(); }, [this]() { return m_plater->is_view3D_overhang_shown(); }, this);
|
||||
|
||||
append_menu_check_item(
|
||||
viewMenu, wxID_ANY, _L("Show Selected Outline (Experimental)"), _L("Show outline around selected object in 3D scene"),
|
||||
viewMenu, wxID_ANY, _L("Show Selected Outline (beta)"), _L("Show outline around selected object in 3D scene"),
|
||||
[this](wxCommandEvent&) {
|
||||
wxGetApp().toggle_show_outline();
|
||||
m_plater->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT));
|
||||
|
|
|
@ -304,10 +304,10 @@ void NotificationManager::PopNotification::render(GLCanvas3D& canvas, float init
|
|||
bbl_render_left_sign(imgui, win_size.x, win_size.y, win_pos.x, win_pos.y);
|
||||
render_left_sign(imgui);
|
||||
render_text(imgui, win_size.x, win_size.y, win_pos.x, win_pos.y);
|
||||
render_close_button(imgui, win_size.x, win_size.y, win_pos.x, win_pos.y);
|
||||
m_minimize_b_visible = false;
|
||||
if (m_multiline && m_lines_count > 3)
|
||||
render_minimize_button(imgui, win_pos.x, win_pos.y);
|
||||
render_close_button(imgui, win_size.x, win_size.y, win_pos.x, win_pos.y); // ORCA draw it after minimize button since its position related to minimize button
|
||||
}
|
||||
imgui.end();
|
||||
|
||||
|
|
|
@ -2724,7 +2724,7 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const
|
|||
return print_volume.intersects(bb);
|
||||
}
|
||||
|
||||
void PartPlate::render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id, bool render_cali)
|
||||
void PartPlate::render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id, bool render_cali, bool show_grid)
|
||||
{
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
||||
|
@ -2744,7 +2744,8 @@ void PartPlate::render(const Transform3d& view_matrix, const Transform3d& projec
|
|||
render_exclude_area(force_background_color);
|
||||
}
|
||||
|
||||
render_grid(bottom);
|
||||
if (show_grid)
|
||||
render_grid(bottom);
|
||||
|
||||
render_height_limit(mode);
|
||||
|
||||
|
@ -4781,7 +4782,7 @@ void PartPlateList::postprocess_arrange_polygon(arrangement::ArrangePolygon& arr
|
|||
|
||||
/*rendering related functions*/
|
||||
//render
|
||||
void PartPlateList::render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali)
|
||||
void PartPlateList::render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body, int hover_id, bool render_cali, bool show_grid)
|
||||
{
|
||||
const std::lock_guard<std::mutex> local_lock(m_plates_mutex);
|
||||
std::vector<PartPlate*>::iterator it = m_plate_list.begin();
|
||||
|
@ -4806,15 +4807,15 @@ void PartPlateList::render(const Transform3d& view_matrix, const Transform3d& pr
|
|||
if (current_index == m_current_plate) {
|
||||
PartPlate::HeightLimitMode height_mode = (only_current)?PartPlate::HEIGHT_LIMIT_NONE:m_height_limit_mode;
|
||||
if (plate_hover_index == current_index)
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, height_mode, plate_hover_action, render_cali);
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, height_mode, plate_hover_action, render_cali, show_grid);
|
||||
else
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, height_mode, -1, render_cali);
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, height_mode, -1, render_cali, show_grid);
|
||||
}
|
||||
else {
|
||||
if (plate_hover_index == current_index)
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, plate_hover_action, render_cali);
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, plate_hover_action, render_cali, show_grid);
|
||||
else
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, -1, render_cali);
|
||||
(*it)->render(view_matrix, projection_matrix, bottom, only_body, false, PartPlate::HEIGHT_LIMIT_NONE, -1, render_cali, show_grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,7 +363,7 @@ public:
|
|||
bool contains(const BoundingBoxf3& bb) const;
|
||||
bool intersects(const BoundingBoxf3& bb) const;
|
||||
|
||||
void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false);
|
||||
void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1, bool render_cali = false, bool show_grid = true);
|
||||
|
||||
void set_selected();
|
||||
void set_unselected();
|
||||
|
@ -781,7 +781,7 @@ public:
|
|||
|
||||
/*rendering related functions*/
|
||||
void on_change_color_mode(bool is_dark) { m_is_dark = is_dark; }
|
||||
void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1, bool render_cali = false);
|
||||
void render(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1, bool render_cali = false, bool show_grid = true);
|
||||
void set_render_option(bool bedtype_texture, bool plate_settings);
|
||||
void set_render_cali(bool value = true) { render_cali_logo = value; }
|
||||
void register_raycasters_for_picking(GLCanvas3D& canvas)
|
||||
|
|
|
@ -1298,8 +1298,10 @@ void Sidebar::update_all_preset_comboboxes()
|
|||
"curr_bed_type");
|
||||
if (!str_bed_type.empty()) {
|
||||
int bed_type_value = atoi(str_bed_type.c_str());
|
||||
if (bed_type_value == 0)
|
||||
bed_type_value = 1;
|
||||
if (bed_type_value <= 0 || bed_type_value >= btCount) {
|
||||
bed_type_value = preset_bundle.printers.get_edited_preset().get_default_bed_type(&preset_bundle);
|
||||
}
|
||||
|
||||
m_bed_type_list->SelectAndNotify(bed_type_value - 1);
|
||||
} else {
|
||||
BedType bed_type = preset_bundle.printers.get_edited_preset().get_default_bed_type(&preset_bundle);
|
||||
|
@ -1307,8 +1309,9 @@ void Sidebar::update_all_preset_comboboxes()
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// Orca: combobox don't have the btDefault option, so we need to -1
|
||||
m_bed_type_list->SelectAndNotify(btPEI - 1);
|
||||
// m_bed_type_list->SelectAndNotify(btPEI - 1);
|
||||
BedType bed_type = preset_bundle.printers.get_edited_preset().get_default_bed_type(&preset_bundle);
|
||||
m_bed_type_list->SelectAndNotify((int) bed_type - 1);
|
||||
m_bed_type_list->Disable();
|
||||
}
|
||||
|
||||
|
@ -3356,22 +3359,23 @@ wxColour Plater::get_next_color_for_filament()
|
|||
static int curr_color_filamenet = 0;
|
||||
// refs to https://www.ebaomonthly.com/window/photo/lesson/colorList.htm
|
||||
wxColour colors[FILAMENT_SYSTEM_COLORS_NUM] = {
|
||||
*wxYELLOW,
|
||||
* wxRED,
|
||||
*wxBLUE,
|
||||
*wxCYAN,
|
||||
*wxLIGHT_GREY,
|
||||
*wxWHITE,
|
||||
*wxBLACK,
|
||||
wxColour(0,127,255),
|
||||
wxColour(139,0,255),
|
||||
wxColour(102,255,0),
|
||||
wxColour(255,215,0),
|
||||
wxColour(0,35,100),
|
||||
wxColour(255,0,255),
|
||||
wxColour(8,37,103),
|
||||
wxColour(127,255,212),
|
||||
wxColour(255,191,0)
|
||||
// ORCA updated all color palette
|
||||
wxColour("#00C1AE"),
|
||||
wxColour("#F4E2C1"),
|
||||
wxColour("#ED1C24"),
|
||||
wxColour("#00FF7F"),
|
||||
wxColour("#F26722"),
|
||||
wxColour("#FFEB31"),
|
||||
wxColour("#7841CE"),
|
||||
wxColour("#115877"),
|
||||
wxColour("#ED1E79"),
|
||||
wxColour("#2EBDEF"),
|
||||
wxColour("#345B2F"),
|
||||
wxColour("#800080"),
|
||||
wxColour("#FA8173"),
|
||||
wxColour("#800000"),
|
||||
wxColour("#F7B763"),
|
||||
wxColour("#A4C41E"),
|
||||
};
|
||||
return colors[curr_color_filamenet++ % FILAMENT_SYSTEM_COLORS_NUM];
|
||||
}
|
||||
|
@ -8925,7 +8929,7 @@ int Plater::new_project(bool skip_confirm, bool silent, const wxString& project_
|
|||
return wxID_YES;
|
||||
}
|
||||
|
||||
|
||||
LoadType determine_load_type(std::string filename, std::string override_setting = "");
|
||||
|
||||
// BBS: FIXME, missing resotre logic
|
||||
void Plater::load_project(wxString const& filename2,
|
||||
|
@ -8977,8 +8981,16 @@ void Plater::load_project(wxString const& filename2,
|
|||
auto strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig;
|
||||
if (originfile == "<silence>") {
|
||||
strategy = strategy | LoadStrategy::Silence;
|
||||
} else if (originfile == "<loadall>") {
|
||||
// Do nothing
|
||||
} else if (originfile != "-") {
|
||||
strategy = strategy | LoadStrategy::Restore;
|
||||
} else {
|
||||
switch (determine_load_type(filename.ToStdString())) {
|
||||
case LoadType::OpenProject: break; // Do nothing
|
||||
case LoadType::LoadGeometry:; strategy = LoadStrategy::LoadModel; break;
|
||||
default: return; // User cancelled
|
||||
}
|
||||
}
|
||||
bool load_restore = strategy & LoadStrategy::Restore;
|
||||
|
||||
|
@ -9728,6 +9740,8 @@ auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config
|
|||
_obj->config.set_key_value("wall_loops", new ConfigOptionInt(1));
|
||||
_obj->config.set_key_value("only_one_wall_top", new ConfigOptionBool(true));
|
||||
_obj->config.set_key_value("thick_internal_bridges", new ConfigOptionBool(false));
|
||||
_obj->config.set_key_value("enable_extra_bridge_layer", new ConfigOptionEnum<EnableExtraBridgeLayer>(eblDisabled));
|
||||
_obj->config.set_key_value("internal_bridge_density", new ConfigOptionPercent(100));
|
||||
_obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(35));
|
||||
_obj->config.set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(100,true));
|
||||
_obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(2));
|
||||
|
@ -10440,7 +10454,7 @@ private:
|
|||
wxColour m_def_color = wxColour(255, 255, 255);
|
||||
RadioSelectorList m_radio_group;
|
||||
int m_action{1};
|
||||
bool m_show_again;
|
||||
bool m_remember_choice{false};
|
||||
|
||||
public:
|
||||
ProjectDropDialog(const std::string &filename);
|
||||
|
@ -10463,7 +10477,7 @@ public:
|
|||
int get_action() const { return m_action; }
|
||||
void set_action(int index) { m_action = index; }
|
||||
|
||||
wxBoxSizer *create_item_checkbox(wxString title, wxWindow *parent, wxString tooltip, std::string param);
|
||||
wxBoxSizer *create_remember_checkbox(wxString title, wxWindow* parent, wxString tooltip);
|
||||
wxBoxSizer *create_item_radiobox(wxString title, wxWindow *parent, int select_id, int groupid);
|
||||
|
||||
protected:
|
||||
|
@ -10557,14 +10571,12 @@ ProjectDropDialog::ProjectDropDialog(const std::string &filename)
|
|||
m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, 10);
|
||||
|
||||
wxBoxSizer *m_sizer_bottom = new wxBoxSizer(wxHORIZONTAL);
|
||||
// hide the "Don't show again" checkbox
|
||||
//wxBoxSizer *m_sizer_left = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxBoxSizer *m_sizer_left = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
//auto dont_show_again = create_item_checkbox(_L("Don't show again"), this, _L("Don't show again"), "show_drop_project_dialog");
|
||||
//m_sizer_left->Add(dont_show_again, 0, wxALL, 5);
|
||||
|
||||
//m_sizer_bottom->Add(m_sizer_left, 0, wxEXPAND, 5);
|
||||
auto dont_show_again = create_remember_checkbox(_L("Remember my choice."), this, _L("This option can be changed later in preferences, under 'Load Behaviour'."));
|
||||
m_sizer_left->Add(dont_show_again, 0, wxALL, 5);
|
||||
|
||||
m_sizer_bottom->Add(m_sizer_left, 0, wxEXPAND, 5);
|
||||
m_sizer_bottom->Add(0, 0, 1, wxEXPAND, 5);
|
||||
|
||||
wxBoxSizer *m_sizer_right = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
@ -10653,13 +10665,14 @@ wxBoxSizer *ProjectDropDialog ::create_item_radiobox(wxString title, wxWindow *p
|
|||
|
||||
return sizer;
|
||||
}
|
||||
wxBoxSizer *ProjectDropDialog::create_item_checkbox(wxString title, wxWindow *parent, wxString tooltip, std::string param)
|
||||
wxBoxSizer *ProjectDropDialog::create_remember_checkbox(wxString title, wxWindow *parent, wxString tooltip)
|
||||
{
|
||||
wxBoxSizer *m_sizer_checkbox = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 5);
|
||||
|
||||
auto checkbox = new ::CheckBox(parent);
|
||||
checkbox->SetValue(m_remember_choice);
|
||||
checkbox->SetToolTip(tooltip);
|
||||
m_sizer_checkbox->Add(checkbox, 0, wxALIGN_CENTER, 0);
|
||||
m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 8);
|
||||
|
||||
|
@ -10667,13 +10680,11 @@ wxBoxSizer *ProjectDropDialog::create_item_checkbox(wxString title, wxWindow *pa
|
|||
checkbox_title->SetForegroundColour(wxColour(144,144,144));
|
||||
checkbox_title->SetFont(::Label::Body_13);
|
||||
checkbox_title->Wrap(-1);
|
||||
checkbox_title->SetToolTip(tooltip);
|
||||
m_sizer_checkbox->Add(checkbox_title, 0, wxALIGN_CENTER | wxALL, 3);
|
||||
|
||||
m_show_again = wxGetApp().app_config->get(param) == "true" ? true : false;
|
||||
checkbox->SetValue(m_show_again);
|
||||
|
||||
checkbox->Bind(wxEVT_TOGGLEBUTTON, [this, checkbox, param](wxCommandEvent &e) {
|
||||
m_show_again = m_show_again ? false : true;
|
||||
checkbox->Bind(wxEVT_TOGGLEBUTTON, [this, checkbox](wxCommandEvent &e) {
|
||||
m_remember_choice = checkbox->GetValue();
|
||||
e.Skip();
|
||||
});
|
||||
|
||||
|
@ -10739,7 +10750,19 @@ void ProjectDropDialog::on_select_radio(wxMouseEvent &event)
|
|||
|
||||
void ProjectDropDialog::on_select_ok(wxMouseEvent &event)
|
||||
{
|
||||
wxGetApp().app_config->set_bool("show_drop_project_dialog", m_show_again);
|
||||
if (m_remember_choice) {
|
||||
LoadType load_type = static_cast<LoadType>(get_action());
|
||||
switch (load_type)
|
||||
{
|
||||
case LoadType::OpenProject:
|
||||
wxGetApp().app_config->set(SETTING_PROJECT_LOAD_BEHAVIOUR, OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_ALL);
|
||||
break;
|
||||
case LoadType::LoadGeometry:
|
||||
wxGetApp().app_config->set(SETTING_PROJECT_LOAD_BEHAVIOUR, OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_GEOMETRY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
|
@ -10919,6 +10942,35 @@ bool Plater::load_files(const wxArrayString& filenames)
|
|||
return res;
|
||||
}
|
||||
|
||||
LoadType determine_load_type(std::string filename, std::string override_setting)
|
||||
{
|
||||
std::string setting;
|
||||
|
||||
if (override_setting != "") {
|
||||
setting = override_setting;
|
||||
} else {
|
||||
setting = wxGetApp().app_config->get(SETTING_PROJECT_LOAD_BEHAVIOUR);
|
||||
}
|
||||
|
||||
if (setting == OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_GEOMETRY) {
|
||||
return LoadType::LoadGeometry;
|
||||
} else if (setting == OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK) {
|
||||
ProjectDropDialog dlg(filename);
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
int choice = dlg.get_action();
|
||||
LoadType load_type = static_cast<LoadType>(choice);
|
||||
wxGetApp().app_config->set("import_project_action", std::to_string(choice));
|
||||
|
||||
// BBS: jump to plater panel
|
||||
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
|
||||
return load_type;
|
||||
}
|
||||
|
||||
return LoadType::Unknown; // Cancel
|
||||
} else {
|
||||
return LoadType::OpenProject;
|
||||
}
|
||||
}
|
||||
|
||||
bool Plater::open_3mf_file(const fs::path &file_path)
|
||||
{
|
||||
|
@ -10927,31 +10979,16 @@ bool Plater::open_3mf_file(const fs::path &file_path)
|
|||
return false;
|
||||
}
|
||||
|
||||
LoadType load_type = LoadType::Unknown;
|
||||
if (!model().objects.empty()) {
|
||||
bool show_drop_project_dialog = true;
|
||||
if (show_drop_project_dialog) {
|
||||
ProjectDropDialog dlg(filename);
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
int choice = dlg.get_action();
|
||||
load_type = static_cast<LoadType>(choice);
|
||||
wxGetApp().app_config->set("import_project_action", std::to_string(choice));
|
||||
|
||||
// BBS: jump to plater panel
|
||||
wxGetApp().mainframe->select_tab(MainFrame::tp3DEditor);
|
||||
}
|
||||
} else
|
||||
load_type = static_cast<LoadType>(
|
||||
std::clamp(std::stoi(wxGetApp().app_config->get("import_project_action")), static_cast<int>(LoadType::OpenProject), static_cast<int>(LoadType::LoadConfig)));
|
||||
} else
|
||||
load_type = LoadType::OpenProject;
|
||||
bool not_empty_plate = !model().objects.empty();
|
||||
bool load_setting_ask_when_relevant = wxGetApp().app_config->get(SETTING_PROJECT_LOAD_BEHAVIOUR) == OPTION_PROJECT_LOAD_BEHAVIOUR_ASK_WHEN_RELEVANT;
|
||||
LoadType load_type = determine_load_type(filename, (not_empty_plate && load_setting_ask_when_relevant) ? OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK : "");
|
||||
|
||||
if (load_type == LoadType::Unknown) return false;
|
||||
|
||||
switch (load_type) {
|
||||
case LoadType::OpenProject: {
|
||||
if (wxGetApp().can_load_project())
|
||||
load_project(from_path(file_path));
|
||||
load_project(from_path(file_path), "<loadall>");
|
||||
break;
|
||||
}
|
||||
case LoadType::LoadGeometry: {
|
||||
|
@ -12626,38 +12663,58 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn, bool us
|
|||
}
|
||||
}
|
||||
|
||||
auto config = get_app_config();
|
||||
PrintHostSendDialog dlg(default_output_file, upload_job.printhost->get_post_upload_actions(), groups, storage_paths, storage_names, config->get_bool("open_device_tab_post_upload"));
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
config->set_bool("open_device_tab_post_upload", dlg.switch_to_device_tab());
|
||||
upload_job.switch_to_device_tab = dlg.switch_to_device_tab();
|
||||
upload_job.upload_data.upload_path = dlg.filename();
|
||||
upload_job.upload_data.post_action = dlg.post_action();
|
||||
upload_job.upload_data.group = dlg.group();
|
||||
upload_job.upload_data.storage = dlg.storage();
|
||||
{
|
||||
auto preset_bundle = wxGetApp().preset_bundle;
|
||||
const auto opt = physical_printer_config->option<ConfigOptionEnum<PrintHostType>>("host_type");
|
||||
const auto host_type = opt != nullptr ? opt->value : htElegooLink;
|
||||
auto config = get_app_config();
|
||||
|
||||
// Show "Is printer clean" dialog for PrusaConnect - Upload and print.
|
||||
if (std::string(upload_job.printhost->get_name()) == "PrusaConnect" && upload_job.upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
|
||||
GUI::MessageDialog dlg(nullptr, _L("Is the printer ready? Is the print sheet in place, empty and clean?"), _L("Upload and Print"), wxOK | wxCANCEL);
|
||||
if (dlg.ShowModal() != wxID_OK)
|
||||
return;
|
||||
std::unique_ptr<PrintHostSendDialog> pDlg;
|
||||
if (host_type == htElegooLink) {
|
||||
pDlg = std::make_unique<ElegooPrintHostSendDialog>(default_output_file, upload_job.printhost->get_post_upload_actions(), groups,
|
||||
storage_paths, storage_names,
|
||||
config->get_bool("open_device_tab_post_upload"));
|
||||
} else {
|
||||
pDlg = std::make_unique<PrintHostSendDialog>(default_output_file, upload_job.printhost->get_post_upload_actions(), groups,
|
||||
storage_paths, storage_names, config->get_bool("open_device_tab_post_upload"));
|
||||
}
|
||||
|
||||
if (use_3mf) {
|
||||
// Process gcode
|
||||
const int result = send_gcode(plate_idx, nullptr);
|
||||
|
||||
if (result < 0) {
|
||||
wxString msg = _L("Abnormal print file data. Please slice again");
|
||||
show_error(this, msg, false);
|
||||
return;
|
||||
}
|
||||
|
||||
upload_job.upload_data.source_path = p->m_print_job_data._3mf_path;
|
||||
pDlg->init();
|
||||
if (pDlg->ShowModal() != wxID_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
p->export_gcode(fs::path(), false, std::move(upload_job));
|
||||
config->set_bool("open_device_tab_post_upload", pDlg->switch_to_device_tab());
|
||||
// PrintHostUpload upload_data;
|
||||
upload_job.switch_to_device_tab = pDlg->switch_to_device_tab();
|
||||
upload_job.upload_data.upload_path = pDlg->filename();
|
||||
upload_job.upload_data.post_action = pDlg->post_action();
|
||||
upload_job.upload_data.group = pDlg->group();
|
||||
upload_job.upload_data.storage = pDlg->storage();
|
||||
upload_job.upload_data.extended_info = pDlg->extendedInfo();
|
||||
}
|
||||
|
||||
// Show "Is printer clean" dialog for PrusaConnect - Upload and print.
|
||||
if (std::string(upload_job.printhost->get_name()) == "PrusaConnect" && upload_job.upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
|
||||
GUI::MessageDialog dlg(nullptr, _L("Is the printer ready? Is the print sheet in place, empty and clean?"), _L("Upload and Print"), wxOK | wxCANCEL);
|
||||
if (dlg.ShowModal() != wxID_OK)
|
||||
return;
|
||||
}
|
||||
|
||||
if (use_3mf) {
|
||||
// Process gcode
|
||||
const int result = send_gcode(plate_idx, nullptr);
|
||||
|
||||
if (result < 0) {
|
||||
wxString msg = _L("Abnormal print file data. Please slice again");
|
||||
show_error(this, msg, false);
|
||||
return;
|
||||
}
|
||||
|
||||
upload_job.upload_data.source_path = p->m_print_job_data._3mf_path;
|
||||
}
|
||||
|
||||
p->export_gcode(fs::path(), false, std::move(upload_job));
|
||||
}
|
||||
int Plater::send_gcode(int plate_idx, Export3mfProgressFn proFn)
|
||||
{
|
||||
|
|
|
@ -67,7 +67,7 @@ wxBoxSizer *PreferencesDialog::create_item_title(wxString title, wxWindow *paren
|
|||
return m_sizer_title;
|
||||
}
|
||||
|
||||
wxBoxSizer *PreferencesDialog::create_item_combobox(wxString title, wxWindow *parent, wxString tooltip, std::string param, std::vector<wxString> vlist)
|
||||
std::tuple<wxBoxSizer*, ComboBox*> PreferencesDialog::create_item_combobox_base(wxString title, wxWindow* parent, wxString tooltip, std::string param, std::vector<wxString> vlist, unsigned int current_index)
|
||||
{
|
||||
wxBoxSizer *m_sizer_combox = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_sizer_combox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
|
||||
|
@ -84,20 +84,58 @@ wxBoxSizer *PreferencesDialog::create_item_combobox(wxString title, wxWindow *pa
|
|||
combobox->GetDropDown().SetFont(::Label::Body_13);
|
||||
|
||||
std::vector<wxString>::iterator iter;
|
||||
for (iter = vlist.begin(); iter != vlist.end(); iter++) { combobox->Append(*iter); }
|
||||
for (iter = vlist.begin(); iter != vlist.end(); iter++) {
|
||||
combobox->Append(*iter);
|
||||
}
|
||||
|
||||
|
||||
auto use_inch = app_config->get(param);
|
||||
if (!use_inch.empty()) { combobox->SetSelection(atoi(use_inch.c_str())); }
|
||||
combobox->SetSelection(current_index);
|
||||
|
||||
m_sizer_combox->Add(combobox, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
return {m_sizer_combox, combobox};
|
||||
}
|
||||
|
||||
wxBoxSizer* PreferencesDialog::create_item_combobox(wxString title, wxWindow* parent, wxString tooltip, std::string param, std::vector<wxString> vlist)
|
||||
{
|
||||
unsigned int current_index = 0;
|
||||
|
||||
auto current_setting = app_config->get(param);
|
||||
if (!current_setting.empty()) {
|
||||
current_index = atoi(current_setting.c_str());
|
||||
}
|
||||
|
||||
auto [sizer, combobox] = create_item_combobox_base(title, parent, tooltip, param, vlist, current_index);
|
||||
|
||||
//// save config
|
||||
combobox->GetDropDown().Bind(wxEVT_COMBOBOX, [this, param](wxCommandEvent &e) {
|
||||
combobox->GetDropDown().Bind(wxEVT_COMBOBOX, [this, param](wxCommandEvent& e) {
|
||||
app_config->set(param, std::to_string(e.GetSelection()));
|
||||
e.Skip();
|
||||
});
|
||||
return m_sizer_combox;
|
||||
|
||||
return sizer;
|
||||
}
|
||||
|
||||
wxBoxSizer *PreferencesDialog::create_item_combobox(wxString title, wxWindow *parent, wxString tooltip, std::string param, std::vector<wxString> vlist, std::vector<std::string> config_name_index)
|
||||
{
|
||||
assert(vlist.size() == config_name_index.size());
|
||||
unsigned int current_index = 0;
|
||||
|
||||
auto current_setting = app_config->get(param);
|
||||
if (!current_setting.empty()) {
|
||||
auto compare = [current_setting](string possible_setting) { return current_setting == possible_setting; };
|
||||
auto iterator = find_if(config_name_index.begin(), config_name_index.end(), compare);
|
||||
current_index = iterator - config_name_index.begin();
|
||||
}
|
||||
|
||||
auto [sizer, combobox] = create_item_combobox_base(title, parent, tooltip, param, vlist, current_index);
|
||||
|
||||
//// save config
|
||||
combobox->GetDropDown().Bind(wxEVT_COMBOBOX, [this, param, config_name_index](wxCommandEvent& e) {
|
||||
app_config->set(param, config_name_index[e.GetSelection()]);
|
||||
e.Skip();
|
||||
});
|
||||
|
||||
return sizer;
|
||||
}
|
||||
|
||||
wxBoxSizer *PreferencesDialog::create_item_language_combobox(
|
||||
|
@ -1166,6 +1204,11 @@ wxWindow* PreferencesDialog::create_general_page()
|
|||
// auto item_modelmall = create_item_checkbox(_L("Show online staff-picked models on the home page"), page, _L("Show online staff-picked models on the home page"), 50, "staff_pick_switch");
|
||||
|
||||
auto title_project = create_item_title(_L("Project"), page, "");
|
||||
|
||||
std::vector<wxString> projectLoadSettingsBehaviourOptions = {_L("Load All"), _L("Ask When Relevant"), _L("Always Ask"), _L("Load Geometry Only")};
|
||||
std::vector<string> projectLoadSettingsConfigOptions = { OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_ALL, OPTION_PROJECT_LOAD_BEHAVIOUR_ASK_WHEN_RELEVANT, OPTION_PROJECT_LOAD_BEHAVIOUR_ALWAYS_ASK, OPTION_PROJECT_LOAD_BEHAVIOUR_LOAD_GEOMETRY };
|
||||
auto item_project_load_behaviour = create_item_combobox(_L("Load Behaviour"), page, _L("Should printer/filament/process settings be loaded when opening a .3mf?"), SETTING_PROJECT_LOAD_BEHAVIOUR, projectLoadSettingsBehaviourOptions, projectLoadSettingsConfigOptions);
|
||||
|
||||
auto item_max_recent_count = create_item_input(_L("Maximum recent projects"), "", page, _L("Maximum count of recent projects"), "max_recent_count", [](wxString value) {
|
||||
long max = 0;
|
||||
if (value.ToLong(&max))
|
||||
|
@ -1241,6 +1284,7 @@ wxWindow* PreferencesDialog::create_general_page()
|
|||
// update_modelmall(eee);
|
||||
// item_region->GetItem(size_t(2))->GetWindow()->Bind(wxEVT_COMBOBOX, update_modelmall);
|
||||
sizer_page->Add(title_project, 0, wxTOP| wxEXPAND, FromDIP(20));
|
||||
sizer_page->Add(item_project_load_behaviour, 0, wxTOP, FromDIP(3));
|
||||
sizer_page->Add(item_max_recent_count, 0, wxTOP, FromDIP(3));
|
||||
sizer_page->Add(item_save_choise, 0, wxTOP, FromDIP(3));
|
||||
sizer_page->Add(item_gcodes_warning, 0, wxTOP, FromDIP(3));
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
|
||||
wxBoxSizer *create_item_title(wxString title, wxWindow *parent, wxString tooltip);
|
||||
wxBoxSizer *create_item_combobox(wxString title, wxWindow *parent, wxString tooltip, std::string param, std::vector<wxString> vlist);
|
||||
wxBoxSizer *create_item_combobox(wxString title, wxWindow *parent, wxString tooltip, std::string param, std::vector<wxString> vlist, std::vector<std::string> config_name_index);
|
||||
wxBoxSizer *create_item_region_combobox(wxString title, wxWindow *parent, wxString tooltip, std::vector<wxString> vlist);
|
||||
wxBoxSizer *create_item_language_combobox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param, std::vector<const wxLanguageInfo *> vlist);
|
||||
wxBoxSizer *create_item_loglevel_combobox(wxString title, wxWindow *parent, wxString tooltip, std::vector<wxString> vlist);
|
||||
|
@ -140,6 +141,9 @@ public:
|
|||
protected:
|
||||
void OnSelectTabel(wxCommandEvent &event);
|
||||
void OnSelectRadio(wxMouseEvent &event);
|
||||
|
||||
private:
|
||||
std::tuple<wxBoxSizer*, ComboBox*> create_item_combobox_base(wxString title, wxWindow* parent, wxString tooltip, std::string param, std::vector<wxString> vlist, unsigned int current_index);
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(EVT_PREFERENCES_SELECT_TAB, wxCommandEvent);
|
||||
|
|
|
@ -47,11 +47,22 @@ PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, PrintHostPostUplo
|
|||
, post_upload_action(PrintHostPostUploadAction::None)
|
||||
, m_paths(storage_paths)
|
||||
, m_switch_to_device_tab(switch_to_device_tab)
|
||||
, m_path(path)
|
||||
, m_post_actions(post_actions)
|
||||
, m_storage_names(storage_names)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
txt_filename->OSXDisableAllSmartSubstitutions();
|
||||
#endif
|
||||
const AppConfig *app_config = wxGetApp().app_config;
|
||||
}
|
||||
void PrintHostSendDialog::init()
|
||||
{
|
||||
const auto& path = m_path;
|
||||
const auto& storage_paths = m_paths;
|
||||
const auto& post_actions = m_post_actions;
|
||||
const auto& storage_names = m_storage_names;
|
||||
|
||||
const AppConfig* app_config = wxGetApp().app_config;
|
||||
|
||||
auto *label_dir_hint = new wxStaticText(this, wxID_ANY, _L("Use forward slashes ( / ) as a directory separator if needed."));
|
||||
label_dir_hint->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
|
||||
|
@ -614,4 +625,331 @@ bool PrintHostQueueDialog::load_user_data(int udt, std::vector<int>& vector)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ElegooPrintHostSendDialog::ElegooPrintHostSendDialog(const fs::path& path,
|
||||
PrintHostPostUploadActions post_actions,
|
||||
const wxArrayString& groups,
|
||||
const wxArrayString& storage_paths,
|
||||
const wxArrayString& storage_names,
|
||||
bool switch_to_device_tab)
|
||||
: PrintHostSendDialog(path, post_actions, groups, storage_paths, storage_names, switch_to_device_tab)
|
||||
, m_timeLapse(0)
|
||||
, m_heatedBedLeveling(0)
|
||||
, m_BedType(BedType::btPTE)
|
||||
{}
|
||||
|
||||
void ElegooPrintHostSendDialog::init() {
|
||||
|
||||
auto preset_bundle = wxGetApp().preset_bundle;
|
||||
auto model_id = preset_bundle->printers.get_edited_preset().get_printer_type(preset_bundle);
|
||||
|
||||
if (!(model_id == "Elegoo-CC" || model_id == "Elegoo-C")) {
|
||||
PrintHostSendDialog::init();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& path = m_path;
|
||||
const auto& storage_paths = m_paths;
|
||||
const auto& post_actions = m_post_actions;
|
||||
const auto& storage_names = m_storage_names;
|
||||
|
||||
this->SetMinSize(wxSize(500, 300));
|
||||
const AppConfig* app_config = wxGetApp().app_config;
|
||||
|
||||
std::string uploadAndPrint = app_config->get("recent", CONFIG_KEY_UPLOADANDPRINT);
|
||||
if (!uploadAndPrint.empty())
|
||||
post_upload_action = static_cast<PrintHostPostUploadAction>(std::stoi(uploadAndPrint));
|
||||
|
||||
std::string timeLapse = app_config->get("recent", CONFIG_KEY_TIMELAPSE);
|
||||
if (!timeLapse.empty())
|
||||
m_timeLapse = std::stoi(timeLapse);
|
||||
std::string heatedBedLeveling = app_config->get("recent", CONFIG_KEY_HEATEDBEDLEVELING);
|
||||
if (!heatedBedLeveling.empty())
|
||||
m_heatedBedLeveling = std::stoi(heatedBedLeveling);
|
||||
std::string bedType = app_config->get("recent", CONFIG_KEY_BEDTYPE);
|
||||
if (!bedType.empty())
|
||||
m_BedType = static_cast<BedType>(std::stoi(bedType));
|
||||
|
||||
auto* label_dir_hint = new wxStaticText(this, wxID_ANY, _L("Use forward slashes ( / ) as a directory separator if needed."));
|
||||
label_dir_hint->Wrap(CONTENT_WIDTH * wxGetApp().em_unit());
|
||||
|
||||
wxSizerFlags flags = wxSizerFlags().Border(wxRIGHT, 16).Expand();
|
||||
|
||||
content_sizer->Add(txt_filename, flags);
|
||||
content_sizer->AddSpacer(4);
|
||||
content_sizer->Add(label_dir_hint);
|
||||
content_sizer->AddSpacer(VERT_SPACING);
|
||||
|
||||
if (combo_groups != nullptr) {
|
||||
// Repetier specific: Show a selection of file groups.
|
||||
auto* label_group = new wxStaticText(this, wxID_ANY, _L("Group"));
|
||||
content_sizer->Add(label_group);
|
||||
content_sizer->Add(combo_groups, 0, wxBOTTOM, 2 * VERT_SPACING);
|
||||
wxString recent_group = from_u8(app_config->get("recent", CONFIG_KEY_GROUP));
|
||||
if (!recent_group.empty())
|
||||
combo_groups->SetValue(recent_group);
|
||||
}
|
||||
|
||||
if (combo_storage != nullptr) {
|
||||
// PrusaLink specific: User needs to choose a storage
|
||||
auto* label_group = new wxStaticText(this, wxID_ANY, _L("Upload to storage") + ":");
|
||||
content_sizer->Add(label_group);
|
||||
content_sizer->Add(combo_storage, 0, wxBOTTOM, 2 * VERT_SPACING);
|
||||
combo_storage->SetValue(storage_names.front());
|
||||
wxString recent_storage = from_u8(app_config->get("recent", CONFIG_KEY_STORAGE));
|
||||
if (!recent_storage.empty())
|
||||
combo_storage->SetValue(recent_storage);
|
||||
} else if (storage_names.GetCount() == 1) {
|
||||
// PrusaLink specific: Show which storage has been detected.
|
||||
auto* label_group = new wxStaticText(this, wxID_ANY, _L("Upload to storage") + ": " + storage_names.front());
|
||||
content_sizer->Add(label_group);
|
||||
m_preselected_storage = m_paths.front();
|
||||
}
|
||||
|
||||
wxString recent_path = from_u8(app_config->get("recent", CONFIG_KEY_PATH));
|
||||
if (recent_path.Length() > 0 && recent_path[recent_path.Length() - 1] != '/') {
|
||||
recent_path += '/';
|
||||
}
|
||||
const auto recent_path_len = recent_path.Length();
|
||||
recent_path += path.filename().wstring();
|
||||
wxString stem(path.stem().wstring());
|
||||
const auto stem_len = stem.Length();
|
||||
|
||||
txt_filename->SetValue(recent_path);
|
||||
|
||||
{
|
||||
auto checkbox_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto checkbox = new ::CheckBox(this, wxID_APPLY);
|
||||
checkbox->SetValue(m_switch_to_device_tab);
|
||||
checkbox->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& e) {
|
||||
m_switch_to_device_tab = e.IsChecked();
|
||||
e.Skip();
|
||||
});
|
||||
checkbox_sizer->Add(checkbox, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
|
||||
auto checkbox_text = new wxStaticText(this, wxID_ANY, _L("Switch to Device tab after upload."), wxDefaultPosition, wxDefaultSize, 0);
|
||||
checkbox_sizer->Add(checkbox_text, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
checkbox_text->SetFont(::Label::Body_13);
|
||||
checkbox_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#323A3D")));
|
||||
content_sizer->Add(checkbox_sizer);
|
||||
content_sizer->AddSpacer(VERT_SPACING);
|
||||
}
|
||||
warning_text = new wxStaticText(this, wxID_ANY,
|
||||
_L("The selected bed type does not match the file. Please confirm before starting the print."),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
uploadandprint_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
{
|
||||
auto checkbox_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto checkbox = new ::CheckBox(this);
|
||||
checkbox->SetValue(post_upload_action == PrintHostPostUploadAction::StartPrint);
|
||||
checkbox->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& e) {
|
||||
if (e.IsChecked()) {
|
||||
post_upload_action = PrintHostPostUploadAction::StartPrint;
|
||||
} else {
|
||||
post_upload_action = PrintHostPostUploadAction::None;
|
||||
}
|
||||
refresh();
|
||||
e.Skip();
|
||||
});
|
||||
checkbox_sizer->Add(checkbox, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
|
||||
auto checkbox_text = new wxStaticText(this, wxID_ANY, _L("Upload and Print"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
checkbox_sizer->Add(checkbox_text, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
checkbox_text->SetFont(::Label::Body_13);
|
||||
checkbox_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#323A3D")));
|
||||
content_sizer->Add(checkbox_sizer);
|
||||
content_sizer->AddSpacer(VERT_SPACING);
|
||||
}
|
||||
|
||||
{
|
||||
auto checkbox_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto checkbox = new ::CheckBox(this);
|
||||
checkbox->SetValue(m_timeLapse == 1);
|
||||
checkbox->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& e) {
|
||||
m_timeLapse = e.IsChecked() ? 1 : 0;
|
||||
e.Skip();
|
||||
});
|
||||
checkbox_sizer->AddSpacer(16);
|
||||
checkbox_sizer->Add(checkbox, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
|
||||
auto checkbox_text = new wxStaticText(this, wxID_ANY, _L("Time-lapse"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
checkbox_sizer->Add(checkbox_text, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
checkbox_text->SetFont(::Label::Body_13);
|
||||
checkbox_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#323A3D")));
|
||||
uploadandprint_sizer->Add(checkbox_sizer);
|
||||
uploadandprint_sizer->AddSpacer(VERT_SPACING);
|
||||
}
|
||||
|
||||
{
|
||||
auto checkbox_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto checkbox = new ::CheckBox(this);
|
||||
checkbox->SetValue(m_heatedBedLeveling == 1);
|
||||
checkbox->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& e) {
|
||||
m_heatedBedLeveling = e.IsChecked() ? 1 : 0;
|
||||
e.Skip();
|
||||
});
|
||||
checkbox_sizer->AddSpacer(16);
|
||||
checkbox_sizer->Add(checkbox, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
|
||||
auto checkbox_text = new wxStaticText(this, wxID_ANY, _L("Heated Bed Leveling"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
checkbox_sizer->Add(checkbox_text, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
checkbox_text->SetFont(::Label::Body_13);
|
||||
checkbox_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#323A3D")));
|
||||
uploadandprint_sizer->Add(checkbox_sizer);
|
||||
uploadandprint_sizer->AddSpacer(VERT_SPACING);
|
||||
}
|
||||
|
||||
{
|
||||
auto radioBoxA = new ::RadioBox(this);
|
||||
auto radioBoxB = new ::RadioBox(this);
|
||||
if (m_BedType == BedType::btPC)
|
||||
radioBoxB->SetValue(true);
|
||||
else
|
||||
radioBoxA->SetValue(true);
|
||||
|
||||
radioBoxA->Bind(wxEVT_LEFT_DOWN, [this, radioBoxA, radioBoxB](wxMouseEvent& e) {
|
||||
radioBoxA->SetValue(true);
|
||||
radioBoxB->SetValue(false);
|
||||
m_BedType = BedType::btPTE;
|
||||
refresh();
|
||||
});
|
||||
radioBoxB->Bind(wxEVT_LEFT_DOWN, [this, radioBoxA, radioBoxB](wxMouseEvent& e) {
|
||||
radioBoxA->SetValue(false);
|
||||
radioBoxB->SetValue(true);
|
||||
m_BedType = BedType::btPC;
|
||||
refresh();
|
||||
});
|
||||
|
||||
{
|
||||
auto radio_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
radio_sizer->AddSpacer(16);
|
||||
radio_sizer->Add(radioBoxA, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
|
||||
auto checkbox_text = new wxStaticText(this, wxID_ANY, _L("Textured Build Plate (Side A)"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
radio_sizer->Add(checkbox_text, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
checkbox_text->SetFont(::Label::Body_13);
|
||||
checkbox_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#323A3D")));
|
||||
uploadandprint_sizer->Add(radio_sizer);
|
||||
uploadandprint_sizer->AddSpacer(VERT_SPACING);
|
||||
}
|
||||
{
|
||||
auto radio_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
radio_sizer->AddSpacer(16);
|
||||
radio_sizer->Add(radioBoxB, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
|
||||
auto checkbox_text = new wxStaticText(this, wxID_ANY, _L("Smooth Build Plate (Side B)"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
radio_sizer->Add(checkbox_text, 0, wxALL | wxALIGN_CENTER, FromDIP(2));
|
||||
checkbox_text->SetFont(::Label::Body_13);
|
||||
checkbox_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#323A3D")));
|
||||
uploadandprint_sizer->Add(radio_sizer);
|
||||
uploadandprint_sizer->AddSpacer(VERT_SPACING);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto h_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
warning_text->SetFont(::Label::Body_13);
|
||||
warning_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#FF1001")));
|
||||
// wrapping the text
|
||||
warning_text->Wrap(350);
|
||||
h_sizer->AddSpacer(16);
|
||||
h_sizer->Add(warning_text);
|
||||
|
||||
uploadandprint_sizer->Add(h_sizer);
|
||||
uploadandprint_sizer->AddSpacer(VERT_SPACING);
|
||||
}
|
||||
|
||||
content_sizer->Add(uploadandprint_sizer);
|
||||
uploadandprint_sizer->Show(post_upload_action == PrintHostPostUploadAction::StartPrint);
|
||||
warning_text->Show(post_upload_action == PrintHostPostUploadAction::StartPrint && appBedType() != m_BedType);
|
||||
|
||||
uploadandprint_sizer->Layout();
|
||||
|
||||
if (size_t extension_start = recent_path.find_last_of('.'); extension_start != std::string::npos)
|
||||
m_valid_suffix = recent_path.substr(extension_start);
|
||||
// .gcode suffix control
|
||||
auto validate_path = [this](const wxString& path) -> bool {
|
||||
if (!path.Lower().EndsWith(m_valid_suffix.Lower())) {
|
||||
MessageDialog msg_wingow(this,
|
||||
wxString::Format(_L("Upload filename doesn't end with \"%s\". Do you wish to continue?"),
|
||||
m_valid_suffix),
|
||||
wxString(SLIC3R_APP_NAME), wxYES | wxNO);
|
||||
if (msg_wingow.ShowModal() == wxID_NO)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto* btn_ok = add_button(wxID_OK, true, _L("Upload"));
|
||||
btn_ok->Bind(wxEVT_BUTTON, [this, validate_path](wxCommandEvent&) {
|
||||
if (validate_path(txt_filename->GetValue())) {
|
||||
// post_upload_action = PrintHostPostUploadAction::None;
|
||||
EndDialog(wxID_OK);
|
||||
}
|
||||
});
|
||||
txt_filename->SetFocus();
|
||||
|
||||
add_button(wxID_CANCEL, false, _L("Cancel"));
|
||||
finalize();
|
||||
|
||||
#ifdef __linux__
|
||||
// On Linux with GTK2 when text control lose the focus then selection (colored background) disappears but text color stay white
|
||||
// and as a result the text is invisible with light mode
|
||||
// see https://github.com/prusa3d/PrusaSlicer/issues/4532
|
||||
// Workaround: Unselect text selection explicitly on kill focus
|
||||
txt_filename->Bind(
|
||||
wxEVT_KILL_FOCUS,
|
||||
[this](wxEvent& e) {
|
||||
e.Skip();
|
||||
txt_filename->SetInsertionPoint(txt_filename->GetLastPosition());
|
||||
},
|
||||
txt_filename->GetId());
|
||||
#endif /* __linux__ */
|
||||
|
||||
Bind(wxEVT_SHOW, [=](const wxShowEvent&) {
|
||||
// Another similar case where the function only works with EVT_SHOW + CallAfter,
|
||||
// this time on Mac.
|
||||
CallAfter([=]() {
|
||||
txt_filename->SetInsertionPoint(0);
|
||||
txt_filename->SetSelection(recent_path_len, recent_path_len + stem_len);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ElegooPrintHostSendDialog::EndModal(int ret)
|
||||
{
|
||||
if (ret == wxID_OK) {
|
||||
|
||||
AppConfig* app_config = wxGetApp().app_config;
|
||||
app_config->set("recent", CONFIG_KEY_UPLOADANDPRINT, std::to_string(static_cast<int>(post_upload_action)));
|
||||
app_config->set("recent", CONFIG_KEY_TIMELAPSE, std::to_string(m_timeLapse));
|
||||
app_config->set("recent", CONFIG_KEY_HEATEDBEDLEVELING, std::to_string(m_heatedBedLeveling));
|
||||
app_config->set("recent", CONFIG_KEY_BEDTYPE, std::to_string(static_cast<int>(m_BedType)));
|
||||
}
|
||||
|
||||
PrintHostSendDialog::EndModal(ret);
|
||||
}
|
||||
|
||||
BedType ElegooPrintHostSendDialog::appBedType() const
|
||||
{
|
||||
std::string str_bed_type = wxGetApp().app_config->get("curr_bed_type");
|
||||
int bed_type_value = atoi(str_bed_type.c_str());
|
||||
return static_cast<BedType>(bed_type_value);
|
||||
}
|
||||
|
||||
void ElegooPrintHostSendDialog::refresh()
|
||||
{
|
||||
if (uploadandprint_sizer) {
|
||||
if (post_upload_action == PrintHostPostUploadAction::StartPrint) {
|
||||
uploadandprint_sizer->Show(true);
|
||||
} else {
|
||||
uploadandprint_sizer->Show(false);
|
||||
}
|
||||
}
|
||||
if (warning_text) {
|
||||
warning_text->Show(post_upload_action == PrintHostPostUploadAction::StartPrint && appBedType() != m_BedType);
|
||||
}
|
||||
this->Layout();
|
||||
this->Fit();
|
||||
}
|
||||
|
||||
}}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "GUI_Utils.hpp"
|
||||
#include "MsgDialog.hpp"
|
||||
#include "../Utils/PrintHost.hpp"
|
||||
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
class wxButton;
|
||||
class wxTextCtrl;
|
||||
class wxChoice;
|
||||
|
@ -27,6 +27,7 @@ class PrintHostSendDialog : public GUI::MsgDialog
|
|||
{
|
||||
public:
|
||||
PrintHostSendDialog(const boost::filesystem::path &path, PrintHostPostUploadActions post_actions, const wxArrayString& groups, const wxArrayString& storage_paths, const wxArrayString& storage_names, bool switch_to_device_tab);
|
||||
virtual ~PrintHostSendDialog() {}
|
||||
boost::filesystem::path filename() const;
|
||||
PrintHostPostUploadAction post_action() const;
|
||||
std::string group() const;
|
||||
|
@ -34,7 +35,10 @@ public:
|
|||
bool switch_to_device_tab() const {return m_switch_to_device_tab;}
|
||||
|
||||
virtual void EndModal(int ret) override;
|
||||
private:
|
||||
virtual void init();
|
||||
virtual std::map<std::string, std::string> extendedInfo() const { return {}; }
|
||||
|
||||
protected:
|
||||
wxTextCtrl *txt_filename;
|
||||
wxComboBox *combo_groups;
|
||||
wxComboBox* combo_storage;
|
||||
|
@ -43,6 +47,10 @@ private:
|
|||
wxString m_preselected_storage;
|
||||
wxArrayString m_paths;
|
||||
bool m_switch_to_device_tab;
|
||||
|
||||
boost::filesystem::path m_path;
|
||||
PrintHostPostUploadActions m_post_actions;
|
||||
wxArrayString m_storage_names;
|
||||
};
|
||||
|
||||
|
||||
|
@ -131,6 +139,47 @@ private:
|
|||
bool load_user_data(int, std::vector<int>&);
|
||||
};
|
||||
|
||||
class ElegooPrintHostSendDialog : public PrintHostSendDialog
|
||||
{
|
||||
public:
|
||||
ElegooPrintHostSendDialog(const boost::filesystem::path& path,
|
||||
PrintHostPostUploadActions post_actions,
|
||||
const wxArrayString& groups,
|
||||
const wxArrayString& storage_paths,
|
||||
const wxArrayString& storage_names,
|
||||
bool switch_to_device_tab);
|
||||
|
||||
virtual void EndModal(int ret) override;
|
||||
int timeLapse() const { return m_timeLapse; }
|
||||
int heatedBedLeveling() const { return m_heatedBedLeveling; }
|
||||
BedType bedType() const { return m_BedType; }
|
||||
|
||||
virtual void init() override;
|
||||
virtual std::map<std::string, std::string> extendedInfo() const
|
||||
{
|
||||
return {{"bedType", std::to_string(static_cast<int>(m_BedType))},
|
||||
{"timeLapse", std::to_string(m_timeLapse)},
|
||||
{"heatedBedLeveling", std::to_string(m_heatedBedLeveling)}};
|
||||
}
|
||||
|
||||
private:
|
||||
BedType appBedType() const;
|
||||
void refresh();
|
||||
|
||||
const char* CONFIG_KEY_UPLOADANDPRINT = "elegoolink_upload_and_print";
|
||||
const char* CONFIG_KEY_TIMELAPSE = "elegoolink_timelapse";
|
||||
const char* CONFIG_KEY_HEATEDBEDLEVELING = "elegoolink_heated_bed_leveling";
|
||||
const char* CONFIG_KEY_BEDTYPE = "elegoolink_bed_type";
|
||||
|
||||
private:
|
||||
wxStaticText* warning_text{nullptr};
|
||||
wxBoxSizer* uploadandprint_sizer{nullptr};
|
||||
|
||||
int m_timeLapse;
|
||||
int m_heatedBedLeveling;
|
||||
BedType m_BedType;
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(EVT_PRINTHOST_PROGRESS, PrintHostQueueDialog::Event);
|
||||
wxDECLARE_EVENT(EVT_PRINTHOST_ERROR, PrintHostQueueDialog::Event);
|
||||
wxDECLARE_EVENT(EVT_PRINTHOST_CANCEL, PrintHostQueueDialog::Event);
|
||||
|
|
|
@ -1552,10 +1552,10 @@ wxWindow *SelectMachineDialog::create_ams_checkbox(wxString title, wxWindow *par
|
|||
sizer_check->Add(check, 0, wxBOTTOM | wxEXPAND | wxTOP, FromDIP(5));
|
||||
|
||||
sizer_checkbox->Add(sizer_check, 0, wxEXPAND, FromDIP(5));
|
||||
sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(11));
|
||||
sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(7));
|
||||
|
||||
auto text = new wxStaticText(checkbox, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, 0);
|
||||
text->SetFont(::Label::Body_13);
|
||||
text->SetFont(::Label::Body_12);
|
||||
text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#323A3C")));
|
||||
text->Wrap(-1);
|
||||
sizer_checkbox->Add(text, 0, wxALIGN_CENTER, 0);
|
||||
|
|
|
@ -2077,6 +2077,7 @@ void Selection::copy_to_clipboard()
|
|||
dst_object->sla_support_points = src_object->sla_support_points;
|
||||
dst_object->sla_points_status = src_object->sla_points_status;
|
||||
dst_object->sla_drain_holes = src_object->sla_drain_holes;
|
||||
dst_object->brim_points = src_object->brim_points;
|
||||
dst_object->layer_config_ranges = src_object->layer_config_ranges; // #ys_FIXME_experiment
|
||||
dst_object->layer_height_profile.assign(src_object->layer_height_profile);
|
||||
dst_object->origin_translation = src_object->origin_translation;
|
||||
|
|
|
@ -1628,6 +1628,13 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
|||
wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config);
|
||||
}
|
||||
|
||||
//Orca: disable purge_in_prime_tower if single_extruder_multi_material is disabled
|
||||
if (opt_key == "single_extruder_multi_material" && m_config->opt_bool("single_extruder_multi_material") == false){
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
new_conf.set_key_value("purge_in_prime_tower", new ConfigOptionBool(false));
|
||||
m_config_manipulation.apply(m_config, &new_conf);
|
||||
}
|
||||
|
||||
if (m_postpone_update_ui) {
|
||||
// It means that not all values are rolled to the system/last saved values jet.
|
||||
// And call of the update() can causes a redundant check of the config values,
|
||||
|
@ -2068,8 +2075,10 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("bridge_flow");
|
||||
optgroup->append_single_option_line("internal_bridge_flow");
|
||||
optgroup->append_single_option_line("bridge_density");
|
||||
optgroup->append_single_option_line("internal_bridge_density");
|
||||
optgroup->append_single_option_line("thick_bridges");
|
||||
optgroup->append_single_option_line("thick_internal_bridges");
|
||||
optgroup->append_single_option_line("enable_extra_bridge_layer");
|
||||
optgroup->append_single_option_line("dont_filter_internal_bridges");
|
||||
optgroup->append_single_option_line("counterbore_hole_bridging","counterbore-hole-bridging");
|
||||
|
||||
|
@ -2101,6 +2110,8 @@ void TabPrint::build()
|
|||
optgroup = page->new_optgroup(L("Infill"), L"param_infill");
|
||||
optgroup->append_single_option_line("sparse_infill_density");
|
||||
optgroup->append_single_option_line("sparse_infill_pattern", "fill-patterns#infill types and their properties of sparse");
|
||||
optgroup->append_single_option_line("lattice_angle_1");
|
||||
optgroup->append_single_option_line("lattice_angle_2");
|
||||
optgroup->append_single_option_line("infill_anchor_max");
|
||||
optgroup->append_single_option_line("infill_anchor");
|
||||
optgroup->append_single_option_line("internal_solid_infill_pattern");
|
||||
|
@ -2113,6 +2124,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("solid_infill_direction");
|
||||
optgroup->append_single_option_line("rotate_solid_infill_direction");
|
||||
optgroup->append_single_option_line("bridge_angle");
|
||||
optgroup->append_single_option_line("internal_bridge_angle"); // ORCA: Internal bridge angle override
|
||||
optgroup->append_single_option_line("minimum_sparse_infill_area");
|
||||
optgroup->append_single_option_line("infill_combination");
|
||||
optgroup->append_single_option_line("infill_combination_max_layer_height");
|
||||
|
@ -2279,6 +2291,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("flush_into_support", "reduce-wasting-during-filament-change#wipe-into-support-enabled-by-default");
|
||||
optgroup = page->new_optgroup(L("Advanced"), L"advanced");
|
||||
optgroup->append_single_option_line("interlocking_beam");
|
||||
optgroup->append_single_option_line("interface_shells");
|
||||
optgroup->append_single_option_line("mmu_segmented_region_max_width");
|
||||
optgroup->append_single_option_line("mmu_segmented_region_interlocking_depth");
|
||||
optgroup->append_single_option_line("interlocking_beam_width");
|
||||
|
@ -2312,6 +2325,9 @@ page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only v
|
|||
optgroup->append_single_option_line("spiral_mode", "spiral-vase");
|
||||
optgroup->append_single_option_line("spiral_mode_smooth", "spiral-vase#smooth");
|
||||
optgroup->append_single_option_line("spiral_mode_max_xy_smoothing", "spiral-vase#max-xy-smoothing");
|
||||
optgroup->append_single_option_line("spiral_starting_flow_ratio", "spiral-vase#starting-flow-ratio");
|
||||
optgroup->append_single_option_line("spiral_finishing_flow_ratio", "spiral-vase#finishing-flow-ratio");
|
||||
|
||||
optgroup->append_single_option_line("timelapse_type", "Timelapse");
|
||||
|
||||
optgroup->append_single_option_line("fuzzy_skin");
|
||||
|
@ -2349,18 +2365,19 @@ page = add_options_page(L("Others"), "custom-gcode_other"); // ORCA: icon only v
|
|||
option.opt.height = 25;//250;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
page = add_options_page(L("Dependencies"), "custom-gcode_advanced");
|
||||
optgroup = page->new_optgroup(L("Profile dependencies"));
|
||||
// Orca: hide the dependencies tab for process for now. The UI is not ready yet.
|
||||
// page = add_options_page(L("Dependencies"), "custom-gcode_advanced");
|
||||
// optgroup = page->new_optgroup(L("Profile dependencies"));
|
||||
|
||||
create_line_with_widget(optgroup.get(), "compatible_printers", "", [this](wxWindow* parent) {
|
||||
return compatible_widget_create(parent, m_compatible_printers);
|
||||
});
|
||||
// create_line_with_widget(optgroup.get(), "compatible_printers", "", [this](wxWindow* parent) {
|
||||
// return compatible_widget_create(parent, m_compatible_printers);
|
||||
// });
|
||||
|
||||
option = optgroup->get_option("compatible_printers_condition");
|
||||
option.opt.full_width = true;
|
||||
optgroup->append_single_option_line(option);
|
||||
// option = optgroup->get_option("compatible_printers_condition");
|
||||
// option.opt.full_width = true;
|
||||
// optgroup->append_single_option_line(option);
|
||||
|
||||
build_preset_description_line(optgroup.get());
|
||||
// build_preset_description_line(optgroup.get());
|
||||
}
|
||||
|
||||
// Reload current config (aka presets->edited_preset->config) into the UI fields.
|
||||
|
@ -3408,6 +3425,7 @@ void TabFilament::build()
|
|||
optgroup->append_single_option_line("enable_overhang_bridge_fan", "auto-cooling");
|
||||
optgroup->append_single_option_line("overhang_fan_threshold", "auto-cooling");
|
||||
optgroup->append_single_option_line("overhang_fan_speed", "auto-cooling");
|
||||
optgroup->append_single_option_line("internal_bridge_fan_speed"); // ORCA: Add support for separate internal bridge fan speed control
|
||||
optgroup->append_single_option_line("support_material_interface_fan_speed");
|
||||
|
||||
optgroup = page->new_optgroup(L("Auxiliary part cooling fan"), L"param_cooling_aux_fan");
|
||||
|
@ -3568,7 +3586,7 @@ void TabFilament::toggle_options()
|
|||
auto cfg = m_preset_bundle->printers.get_edited_preset().config;
|
||||
if (m_active_page->title() == L("Cooling")) {
|
||||
bool has_enable_overhang_bridge_fan = m_config->opt_bool("enable_overhang_bridge_fan", 0);
|
||||
for (auto el : {"overhang_fan_speed", "overhang_fan_threshold"})
|
||||
for (auto el : {"overhang_fan_speed", "overhang_fan_threshold", "internal_bridge_fan_speed"}) // ORCA: Add support for separate internal bridge fan speed control
|
||||
toggle_option(el, has_enable_overhang_bridge_fan);
|
||||
|
||||
toggle_option("additional_cooling_fan_speed", cfg.opt_bool("auxiliary_fan"));
|
||||
|
@ -3581,13 +3599,29 @@ void TabFilament::toggle_options()
|
|||
{
|
||||
bool pa = m_config->opt_bool("enable_pressure_advance", 0);
|
||||
toggle_option("pressure_advance", pa);
|
||||
// Orca: Enable the plates that should be visible when multi bed support is enabled or a BBL printer is selected
|
||||
auto support_multi_bed_types = is_BBL_printer || cfg.opt_bool("support_multi_bed_types");
|
||||
toggle_line("supertack_plate_temp_initial_layer", support_multi_bed_types );
|
||||
toggle_line("cool_plate_temp_initial_layer", support_multi_bed_types );
|
||||
toggle_line("textured_cool_plate_temp_initial_layer", support_multi_bed_types);
|
||||
toggle_line("eng_plate_temp_initial_layer", support_multi_bed_types);
|
||||
toggle_line("textured_plate_temp_initial_layer", support_multi_bed_types);
|
||||
|
||||
//Orca: Enable the plates that should be visible when multi bed support is enabled or a BBL printer is selected; otherwise, enable only the plate visible for the selected bed type.
|
||||
DynamicConfig& proj_cfg = m_preset_bundle->project_config;
|
||||
std::string bed_temp_1st_layer_key = "";
|
||||
if (proj_cfg.has("curr_bed_type"))
|
||||
{
|
||||
bed_temp_1st_layer_key = get_bed_temp_1st_layer_key(proj_cfg.opt_enum<BedType>("curr_bed_type"));
|
||||
}
|
||||
|
||||
const std::vector<std::string> bed_temp_keys = {"supertack_plate_temp_initial_layer", "cool_plate_temp_initial_layer",
|
||||
"textured_cool_plate_temp_initial_layer", "eng_plate_temp_initial_layer",
|
||||
"textured_plate_temp_initial_layer", "hot_plate_temp_initial_layer"};
|
||||
|
||||
bool support_multi_bed_types = std::find(bed_temp_keys.begin(), bed_temp_keys.end(), bed_temp_1st_layer_key) ==
|
||||
bed_temp_keys.end() ||
|
||||
is_BBL_printer || cfg.opt_bool("support_multi_bed_types");
|
||||
|
||||
for (const auto& key : bed_temp_keys)
|
||||
{
|
||||
toggle_line(key, support_multi_bed_types || bed_temp_1st_layer_key == key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Orca: adaptive pressure advance and calibration model
|
||||
// If PA is not enabled, disable adaptive pressure advance and hide the model section
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue