Start to Split GUI_ObjectParts:
+ created GUI_ObjectList & GUI_ObjectManipulation classes
This commit is contained in:
parent
7ed9ba5437
commit
bcedd71e99
@ -45,6 +45,10 @@ add_library(libslic3r_gui STATIC
|
||||
${LIBDIR}/slic3r/GUI/MainFrame.hpp
|
||||
${LIBDIR}/slic3r/GUI/Plater.cpp
|
||||
${LIBDIR}/slic3r/GUI/Plater.hpp
|
||||
${LIBDIR}/slic3r/GUI/GUI_ObjectList.cpp
|
||||
${LIBDIR}/slic3r/GUI/GUI_ObjectList.hpp
|
||||
${LIBDIR}/slic3r/GUI/GUI_ObjectManipulation.cpp
|
||||
${LIBDIR}/slic3r/GUI/GUI_ObjectManipulation.hpp
|
||||
${LIBDIR}/slic3r/GUI/LambdaObjectDialog.cpp
|
||||
${LIBDIR}/slic3r/GUI/LambdaObjectDialog.hpp
|
||||
${LIBDIR}/slic3r/GUI/Tab.cpp
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "../../libslic3r/PrintConfig.hpp"
|
||||
#include "../../libslic3r/GCode/PreviewData.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_ObjectManipulation.hpp"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
@ -2982,7 +2983,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
#else
|
||||
m_on_gizmo_scale_uniformly_callback.call((double)m_gizmos.get_scale());
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
update_scale_values();
|
||||
wxGetApp().obj_manipul()->update_scale_values();
|
||||
m_dirty = true;
|
||||
break;
|
||||
}
|
||||
@ -2993,7 +2994,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
#else
|
||||
m_on_gizmo_rotate_callback.call((double)m_gizmos.get_angle_z());
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
update_rotation_values();
|
||||
wxGetApp().obj_manipul()->update_rotation_values();
|
||||
m_dirty = true;
|
||||
break;
|
||||
}
|
||||
@ -3181,7 +3182,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
v->set_offset(v->get_offset() + Vec3d(vector(0), vector(1), 0.0));
|
||||
}
|
||||
|
||||
update_position_values(volume->get_offset());
|
||||
wxGetApp().obj_manipul()->update_position_values(volume->get_offset());
|
||||
m_mouse.drag.start_position_3D = cur_pos;
|
||||
|
||||
m_dirty = true;
|
||||
@ -3222,7 +3223,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
{
|
||||
v->set_offset(v->get_offset() + offset);
|
||||
}
|
||||
update_position_values(volume->get_offset());
|
||||
wxGetApp().obj_manipul()->update_position_values(volume->get_offset());
|
||||
break;
|
||||
}
|
||||
case Gizmos::Scale:
|
||||
@ -3234,7 +3235,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
{
|
||||
v->set_scaling_factor(scale);
|
||||
}
|
||||
update_scale_values(scale);
|
||||
wxGetApp().obj_manipul()->update_scale_values(scale);
|
||||
#else
|
||||
// Apply new temporary scale factor
|
||||
float scale_factor = m_gizmos.get_scale();
|
||||
@ -3255,7 +3256,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
{
|
||||
v->set_rotation(rotation);
|
||||
}
|
||||
update_rotation_value(rotation);
|
||||
wxGetApp().obj_manipul()->update_rotation_value(rotation);
|
||||
#else
|
||||
// Apply new temporary angle_z
|
||||
float angle_z = m_gizmos.get_angle_z();
|
||||
@ -3430,7 +3431,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
break;
|
||||
}
|
||||
m_gizmos.stop_dragging();
|
||||
update_settings_value();
|
||||
wxGetApp().obj_manipul()->update_values();
|
||||
}
|
||||
|
||||
m_mouse.drag.move_volume_idx = -1;
|
||||
@ -5351,7 +5352,7 @@ void GLCanvas3D::_on_move(const std::vector<int>& volume_idxs)
|
||||
model_object->instances[instance_idx]->offset = Vec2d(offset(0), offset(1));
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
model_object->invalidate_bounding_box();
|
||||
update_position_values();
|
||||
wxGetApp().obj_manipul()->update_position_values();
|
||||
object_moved = true;
|
||||
}
|
||||
}
|
||||
|
@ -519,135 +519,6 @@ void set_model_events_from_perl(Model &model,
|
||||
// add_collapsible_panes(parent, sizer);
|
||||
}
|
||||
|
||||
void Sidebar::add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer/*, wxFlexGridSizer* preset_sizer*/)
|
||||
{
|
||||
DynamicPrintConfig* config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
std::shared_ptr<ConfigOptionsGroup> optgroup = std::make_shared<ConfigOptionsGroup>(parent, "", config);
|
||||
// const wxArrayInt& ar = preset_sizer->GetColWidths();
|
||||
// m_label_width = ar.IsEmpty() ? 100 : ar.front()-4;
|
||||
optgroup->label_width = 100;// m_label_width;
|
||||
|
||||
auto m_optgroups = get_optgroups();
|
||||
|
||||
//Frequently changed parameters
|
||||
optgroup->m_on_change = [config, m_optgroups](t_config_option_key opt_key, boost::any value){
|
||||
TabPrint* tab_print = nullptr;
|
||||
for (size_t i = 0; i < wxGetApp().tab_panel()->GetPageCount(); ++i) {
|
||||
Tab *tab = dynamic_cast<Tab*>(wxGetApp().tab_panel()->GetPage(i));
|
||||
if (!tab)
|
||||
continue;
|
||||
if (tab->name() == "print"){
|
||||
tab_print = static_cast<TabPrint*>(tab);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tab_print == nullptr)
|
||||
return;
|
||||
|
||||
if (opt_key == "fill_density"){
|
||||
value = m_optgroups[ogFrequentlyChangingParameters]->get_config_value(*config, opt_key);
|
||||
tab_print->set_value(opt_key, value);
|
||||
tab_print->update();
|
||||
}
|
||||
else{
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
if (opt_key == "brim"){
|
||||
double new_val;
|
||||
double brim_width = config->opt_float("brim_width");
|
||||
if (boost::any_cast<bool>(value) == true)
|
||||
{
|
||||
new_val = 10;// m_brim_width == 0.0 ? 10 :
|
||||
// m_brim_width < 0.0 ? m_brim_width * (-1) :
|
||||
// m_brim_width;
|
||||
}
|
||||
else{
|
||||
// m_brim_width = brim_width * (-1);
|
||||
new_val = 0;
|
||||
}
|
||||
new_conf.set_key_value("brim_width", new ConfigOptionFloat(new_val));
|
||||
}
|
||||
else{ //(opt_key == "support")
|
||||
const wxString& selection = boost::any_cast<wxString>(value);
|
||||
|
||||
auto support_material = selection == _("None") ? false : true;
|
||||
new_conf.set_key_value("support_material", new ConfigOptionBool(support_material));
|
||||
|
||||
if (selection == _("Everywhere"))
|
||||
new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false));
|
||||
else if (selection == _("Support on build plate only"))
|
||||
new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true));
|
||||
}
|
||||
tab_print->load_config(new_conf);
|
||||
}
|
||||
|
||||
tab_print->update_dirty();
|
||||
};
|
||||
|
||||
Option option = optgroup->get_option("fill_density");
|
||||
option.opt.sidetext = "";
|
||||
option.opt.full_width = true;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
ConfigOptionDef def;
|
||||
|
||||
def.label = L("Support");
|
||||
def.type = coStrings;
|
||||
def.gui_type = "select_open";
|
||||
def.tooltip = L("Select what kind of support do you need");
|
||||
def.enum_labels.push_back(L("None"));
|
||||
def.enum_labels.push_back(L("Support on build plate only"));
|
||||
def.enum_labels.push_back(L("Everywhere"));
|
||||
std::string selection = !config->opt_bool("support_material") ?
|
||||
"None" :
|
||||
config->opt_bool("support_material_buildplate_only") ?
|
||||
"Support on build plate only" :
|
||||
"Everywhere";
|
||||
def.default_value = new ConfigOptionStrings { selection };
|
||||
option = Option(def, "support");
|
||||
option.opt.full_width = true;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
auto m_brim_width = config->opt_float("brim_width");
|
||||
def.label = L("Brim");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("This flag enables the brim that will be printed around each object on the first layer.");
|
||||
def.gui_type = "";
|
||||
def.default_value = new ConfigOptionBool{ m_brim_width > 0.0 ? true : false };
|
||||
option = Option(def, "brim");
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
|
||||
Line line = { "", "" };
|
||||
line.widget = [config, this](wxWindow* parent){
|
||||
auto g_wiping_dialog_button = get_wiping_dialog_button();
|
||||
g_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(g_wiping_dialog_button);
|
||||
g_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e)
|
||||
{
|
||||
auto &config = wxGetApp().preset_bundle->project_config;
|
||||
const std::vector<double> &init_matrix = (config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values;
|
||||
const std::vector<double> &init_extruders = (config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values;
|
||||
|
||||
WipingDialog dlg(parent,cast<float>(init_matrix),cast<float>(init_extruders));
|
||||
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
std::vector<float> matrix = dlg.get_matrix();
|
||||
std::vector<float> extruders = dlg.get_extruders();
|
||||
(config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values = std::vector<double>(matrix.begin(),matrix.end());
|
||||
(config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values = std::vector<double>(extruders.begin(),extruders.end());
|
||||
g_on_request_update_callback.call();
|
||||
}
|
||||
}));
|
||||
return sizer;
|
||||
};
|
||||
optgroup->append_line(line);
|
||||
|
||||
sizer->Add(optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT, 2);
|
||||
|
||||
m_optgroups.push_back(optgroup);// ogFrequentlyChangingParameters
|
||||
}
|
||||
|
||||
void show_buttons(bool show)
|
||||
{
|
||||
g_buttons[abReslice]->Show(show);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_ObjectManipulation.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
@ -647,7 +648,17 @@ void GUI_App::load_current_presets()
|
||||
}
|
||||
}
|
||||
|
||||
wxNotebook* GUI_App::tab_panel() const
|
||||
Sidebar& GUI_App::sidebar()
|
||||
{
|
||||
return mainframe->m_plater->sidebar();
|
||||
}
|
||||
|
||||
ObjectManipulation* GUI_App::obj_manipul()
|
||||
{
|
||||
return sidebar().obj_manipul();
|
||||
}
|
||||
|
||||
wxNotebook* GUI_App::tab_panel() const
|
||||
{
|
||||
return mainframe->m_tabpanel;
|
||||
}
|
||||
|
@ -123,6 +123,15 @@ public:
|
||||
// Tab* get_tab(const std::string& name);
|
||||
void load_current_presets();
|
||||
|
||||
|
||||
Sidebar& sidebar();
|
||||
ObjectManipulation* obj_manipul();
|
||||
// ObjectList& get_obj_list();
|
||||
|
||||
// Functions for updating of the object manipulation values
|
||||
void update_position_values();
|
||||
void update_position_values(const Vec3d& position);
|
||||
|
||||
AppConfig* app_config{ nullptr };
|
||||
PresetBundle* preset_bundle{ nullptr };
|
||||
PresetUpdater* preset_updater{ nullptr };
|
||||
|
188
src/slic3r/GUI/GUI_ObjectList.cpp
Normal file
188
src/slic3r/GUI/GUI_ObjectList.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
|
||||
#include "OptionsGroup.hpp"
|
||||
#include "PresetBundle.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
|
||||
// #include "Model.hpp"
|
||||
// #include "LambdaObjectDialog.hpp"
|
||||
// #include "../../libslic3r/Utils.hpp"
|
||||
//
|
||||
// #include <wx/msgdlg.h>
|
||||
// #include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
// #include "Geometry.hpp"
|
||||
#include "slic3r/Utils/FixModelByWin10.hpp"
|
||||
|
||||
//
|
||||
// #include <wx/glcanvas.h>
|
||||
// #include "3DScene.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
namespace GUI
|
||||
{
|
||||
|
||||
ObjectList::ObjectList(wxWindow* parent) :
|
||||
m_parent(parent)
|
||||
{
|
||||
// wxBoxSizer* sizer;
|
||||
// create control
|
||||
create_objects_ctrl();
|
||||
|
||||
// describe control behavior
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) {
|
||||
object_ctrl_selection_changed();
|
||||
#ifndef __WXMSW__
|
||||
set_tooltip_for_item(get_mouse_position_in_control());
|
||||
#endif //__WXMSW__
|
||||
});
|
||||
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) {
|
||||
object_ctrl_context_menu();
|
||||
// event.Skip();
|
||||
});
|
||||
|
||||
m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { object_ctrl_key_event(event); }); // doesn't work on OSX
|
||||
|
||||
#ifdef __WXMSW__
|
||||
// Extruder value changed
|
||||
m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); });
|
||||
|
||||
m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [this](wxMouseEvent& event) {
|
||||
set_tooltip_for_item(event.GetPosition());
|
||||
event.Skip();
|
||||
});
|
||||
#else
|
||||
// equivalent to wxEVT_CHOICE on __WXMSW__
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { object_ctrl_item_value_change(event); });
|
||||
#endif //__WXMSW__
|
||||
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, [](wxDataViewEvent& e) {on_begin_drag(e); });
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, [](wxDataViewEvent& e) {on_drop_possible(e); });
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_DROP, [](wxDataViewEvent& e) {on_drop(e); });
|
||||
}
|
||||
|
||||
void ObjectList::create_objects_ctrl()
|
||||
{
|
||||
m_objects_ctrl = new wxDataViewCtrl(m_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
m_objects_ctrl->SetMinSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects
|
||||
|
||||
m_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20);
|
||||
|
||||
m_objects_model = new PrusaObjectDataViewModel;
|
||||
m_objects_ctrl->AssociateModel(m_objects_model);
|
||||
#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
|
||||
m_objects_ctrl->EnableDragSource(wxDF_UNICODETEXT);
|
||||
m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT);
|
||||
#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
|
||||
|
||||
// column 0(Icon+Text) of the view control:
|
||||
// And Icon can be consisting of several bitmaps
|
||||
m_objects_ctrl->AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(),
|
||||
0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE));
|
||||
|
||||
// column 1 of the view control:
|
||||
m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45,
|
||||
wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
|
||||
|
||||
// column 2 of the view control:
|
||||
m_objects_ctrl->AppendColumn(create_objects_list_extruder_column(4));
|
||||
|
||||
// column 3 of the view control:
|
||||
m_objects_ctrl->AppendBitmapColumn(" ", 3, wxDATAVIEW_CELL_INERT, 25,
|
||||
wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
|
||||
}
|
||||
|
||||
// ModelObjectPtrs& ObjectList::get_objects()
|
||||
// {
|
||||
// return wxGetApp().mainframe->m_plater->model().objects;
|
||||
// }
|
||||
|
||||
|
||||
void ObjectList::set_tooltip_for_item(const wxPoint& pt)
|
||||
{
|
||||
wxDataViewItem item;
|
||||
wxDataViewColumn* col;
|
||||
m_objects_ctrl->HitTest(pt, item, col);
|
||||
if (!item) return;
|
||||
|
||||
if (col->GetTitle() == " ")
|
||||
m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings")));
|
||||
// else if (col->GetTitle() == _("Name") &&
|
||||
// m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) {
|
||||
// int obj_idx = m_objects_model->GetIdByItem(item);
|
||||
// auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats;
|
||||
// int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
|
||||
// stats.facets_added + stats.facets_reversed + stats.backwards_edges;
|
||||
//
|
||||
// wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors);
|
||||
//
|
||||
// std::map<std::string, int> error_msg;
|
||||
// error_msg[L("degenerate facets")] = stats.degenerate_facets;
|
||||
// error_msg[L("edges fixed")] = stats.edges_fixed;
|
||||
// error_msg[L("facets removed")] = stats.facets_removed;
|
||||
// error_msg[L("facets added")] = stats.facets_added;
|
||||
// error_msg[L("facets reversed")] = stats.facets_reversed;
|
||||
// error_msg[L("backwards edges")] = stats.backwards_edges;
|
||||
//
|
||||
// for (auto error : error_msg)
|
||||
// {
|
||||
// if (error.second > 0)
|
||||
// tooltip += wxString::Format(_("\t%d %s\n"), error.second, error.first);
|
||||
// }
|
||||
// // OR
|
||||
// // tooltip += wxString::Format(_(L("%d degenerate facets, %d edges fixed, %d facets removed, "
|
||||
// // "%d facets added, %d facets reversed, %d backwards edges")),
|
||||
// // stats.degenerate_facets, stats.edges_fixed, stats.facets_removed,
|
||||
// // stats.facets_added, stats.facets_reversed, stats.backwards_edges);
|
||||
//
|
||||
// if (is_windows10())
|
||||
// tooltip += _(L("Right button click the icon to fix STL through Netfabb"));
|
||||
//
|
||||
// m_objects_ctrl->GetMainWindow()->SetToolTip(tooltip);
|
||||
// }
|
||||
else
|
||||
m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip
|
||||
}
|
||||
|
||||
wxPoint ObjectList::get_mouse_position_in_control() {
|
||||
const wxPoint& pt = wxGetMousePosition();
|
||||
wxWindow* win = m_objects_ctrl->GetMainWindow();
|
||||
return wxPoint(pt.x - win->GetScreenPosition().x,
|
||||
pt.y - win->GetScreenPosition().y);
|
||||
}
|
||||
|
||||
wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count)
|
||||
{
|
||||
wxArrayString choices;
|
||||
choices.Add("default");
|
||||
for (int i = 1; i <= extruders_count; ++i)
|
||||
choices.Add(wxString::Format("%d", i));
|
||||
wxDataViewChoiceRenderer *c =
|
||||
new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL);
|
||||
wxDataViewColumn* column = new wxDataViewColumn(_(L("Extruder")), c, 2, 60, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
|
||||
return column;
|
||||
}
|
||||
|
||||
void ObjectList::update_objects_list_extruder_column(int extruders_count)
|
||||
{
|
||||
if (!m_objects_ctrl) return; // #ys_FIXME
|
||||
if (wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
|
||||
extruders_count = 1;
|
||||
|
||||
// delete old 3rd column
|
||||
m_objects_ctrl->DeleteColumn(m_objects_ctrl->GetColumn(2));
|
||||
// insert new created 3rd column
|
||||
m_objects_ctrl->InsertColumn(2, create_objects_list_extruder_column(extruders_count));
|
||||
// set show/hide for this column
|
||||
set_extruder_column_hidden(extruders_count <= 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} //namespace GUI
|
||||
} //namespace Slic3r
|
50
src/slic3r/GUI/GUI_ObjectList.hpp
Normal file
50
src/slic3r/GUI/GUI_ObjectList.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef slic3r_GUI_ObjectList_hpp_
|
||||
#define slic3r_GUI_ObjectList_hpp_
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <wx/bitmap.h>
|
||||
|
||||
class wxBoxSizer;
|
||||
class wxDataViewCtrl;
|
||||
class wxDataViewColumn;
|
||||
class PrusaObjectDataViewModel;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
class ConfigOptionsGroup;
|
||||
|
||||
class ObjectList
|
||||
{
|
||||
wxBoxSizer *m_sizer {nullptr};
|
||||
wxDataViewCtrl *m_objects_ctrl{ nullptr };
|
||||
PrusaObjectDataViewModel *m_objects_model{ nullptr };
|
||||
wxWindow *m_parent{ nullptr };
|
||||
|
||||
wxBitmap m_icon_modifiermesh;
|
||||
wxBitmap m_icon_solidmesh;
|
||||
wxBitmap m_icon_manifold_warning;
|
||||
wxBitmap m_bmp_cog;
|
||||
wxBitmap m_bmp_split;
|
||||
|
||||
int m_selected_object_id = -1;
|
||||
|
||||
public:
|
||||
ObjectList(wxWindow* parent);
|
||||
~ObjectList() {}
|
||||
|
||||
void create_objects_ctrl();
|
||||
wxDataViewColumn* create_objects_list_extruder_column(int extruders_count);
|
||||
void update_objects_list_extruder_column(int extruders_count);
|
||||
|
||||
void set_tooltip_for_item(const wxPoint& pt);
|
||||
|
||||
wxPoint get_mouse_position_in_control();
|
||||
wxBoxSizer* get_sizer(){return m_sizer;}
|
||||
int get_sel_obj_id() { return m_selected_object_id; }
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif //slic3r_GUI_ObjectList_hpp_
|
304
src/slic3r/GUI/GUI_ObjectManipulation.cpp
Normal file
304
src/slic3r/GUI/GUI_ObjectManipulation.cpp
Normal file
@ -0,0 +1,304 @@
|
||||
#include "GUI_ObjectManipulation.hpp"
|
||||
|
||||
#include "OptionsGroup.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "Geometry.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
namespace GUI
|
||||
{
|
||||
|
||||
OG_Settings::OG_Settings(wxWindow* parent, const bool staticbox)
|
||||
{
|
||||
wxString title = staticbox ? " " : ""; // temporary workaround - #ys_FIXME
|
||||
m_og = std::make_shared<ConfigOptionsGroup>(parent, title);
|
||||
}
|
||||
|
||||
wxSizer* OG_Settings::get_sizer()
|
||||
{
|
||||
return m_og->sizer;
|
||||
}
|
||||
|
||||
ObjectManipulation::ObjectManipulation(wxWindow* parent):
|
||||
OG_Settings(parent, true)
|
||||
{
|
||||
m_og->set_name(_(L("Object Manipulation")));
|
||||
m_og->label_width = 100;
|
||||
m_og->set_grid_vgap(5);
|
||||
|
||||
m_og->m_on_change = [this](t_config_option_key opt_key, boost::any value){
|
||||
if (opt_key == "scale_unit"){
|
||||
const wxString& selection = boost::any_cast<wxString>(value);
|
||||
std::vector<std::string> axes{ "x", "y", "z" };
|
||||
for (auto axis : axes) {
|
||||
std::string key = "scale_" + axis;
|
||||
get_optgroup(ogFrequentlyObjectSettings)->set_side_text(key, selection);
|
||||
}
|
||||
|
||||
m_is_percent_scale = selection == _("%");
|
||||
update_scale_values();
|
||||
}
|
||||
};
|
||||
|
||||
ConfigOptionDef def;
|
||||
|
||||
// Objects(sub-objects) name
|
||||
def.label = L("Name");
|
||||
// def.type = coString;
|
||||
def.gui_type = "legend";
|
||||
def.tooltip = L("Object name");
|
||||
def.full_width = true;
|
||||
def.default_value = new ConfigOptionString{ " " };
|
||||
m_og->append_single_option_line(Option(def, "object_name"));
|
||||
|
||||
// Legend for object modification
|
||||
auto line = Line{ "", "" };
|
||||
def.label = "";
|
||||
def.type = coString;
|
||||
def.width = 55;
|
||||
|
||||
std::vector<std::string> axes{ "x", "y", "z" };
|
||||
for (const auto axis : axes) {
|
||||
const auto label = boost::algorithm::to_upper_copy(axis);
|
||||
def.default_value = new ConfigOptionString{ " " + label };
|
||||
Option option = Option(def, axis + "_axis_legend");
|
||||
line.append_option(option);
|
||||
}
|
||||
m_og->append_line(line);
|
||||
|
||||
|
||||
auto add_og_to_object_settings = [](const std::string& option_name, const std::string& sidetext)
|
||||
{
|
||||
int def_value = 0;
|
||||
Line line = { _(option_name), "" };
|
||||
if (option_name == "Scale") {
|
||||
line.near_label_widget = [](wxWindow* parent) {
|
||||
auto btn = new PrusaLockButton(parent, wxID_ANY);
|
||||
btn->Bind(wxEVT_BUTTON, [btn](wxCommandEvent &event){
|
||||
event.Skip();
|
||||
wxTheApp->CallAfter([btn]() { set_uniform_scaling(btn->IsLocked()); });
|
||||
});
|
||||
return btn;
|
||||
};
|
||||
}
|
||||
|
||||
ConfigOptionDef def;
|
||||
def.type = coInt;
|
||||
def.default_value = new ConfigOptionInt(def_value);
|
||||
def.width = 55;
|
||||
|
||||
if (option_name == "Rotation")
|
||||
def.min = -360;
|
||||
|
||||
const std::string lower_name = boost::algorithm::to_lower_copy(option_name);
|
||||
|
||||
std::vector<std::string> axes{ "x", "y", "z" };
|
||||
for (auto axis : axes) {
|
||||
if (axis == "z" && option_name != "Scale")
|
||||
def.sidetext = sidetext;
|
||||
Option option = Option(def, lower_name + "_" + axis);
|
||||
option.opt.full_width = true;
|
||||
line.append_option(option);
|
||||
}
|
||||
|
||||
if (option_name == "Scale")
|
||||
{
|
||||
def.width = 45;
|
||||
def.type = coStrings;
|
||||
def.gui_type = "select_open";
|
||||
def.enum_labels.push_back(L("%"));
|
||||
def.enum_labels.push_back(L("mm"));
|
||||
def.default_value = new ConfigOptionStrings{ "mm" };
|
||||
|
||||
const Option option = Option(def, lower_name + "_unit");
|
||||
line.append_option(option);
|
||||
}
|
||||
|
||||
return line;
|
||||
};
|
||||
|
||||
|
||||
// Settings table
|
||||
m_og->append_line(add_og_to_object_settings(L("Position"), L("mm")));
|
||||
m_og->append_line(add_og_to_object_settings(L("Rotation"), "°"));
|
||||
m_og->append_line(add_og_to_object_settings(L("Scale"), "mm"));
|
||||
|
||||
|
||||
def.label = L("Place on bed");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("Automatic placing of models on printing bed in Y axis");
|
||||
def.gui_type = "";
|
||||
def.sidetext = "";
|
||||
def.default_value = new ConfigOptionBool{ false };
|
||||
m_og->append_single_option_line(Option(def, "place_on_bed"));
|
||||
|
||||
m_extra_settings_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_og->sizer->Add(m_extra_settings_sizer, 1, wxEXPAND | wxLEFT, 5);
|
||||
|
||||
m_og->disable();
|
||||
}
|
||||
|
||||
int ObjectManipulation::ol_selection()
|
||||
{
|
||||
return wxGetApp().sidebar().get_ol_selection();
|
||||
}
|
||||
|
||||
void ObjectManipulation::update_values()
|
||||
{
|
||||
int selection = ol_selection();
|
||||
if (selection < 0 || wxGetApp().mainframe->m_plater->model().objects.size() <= selection) {
|
||||
m_og->set_value("position_x", 0);
|
||||
m_og->set_value("position_y", 0);
|
||||
m_og->set_value("position_z", 0);
|
||||
m_og->set_value("scale_x", 0);
|
||||
m_og->set_value("scale_y", 0);
|
||||
m_og->set_value("scale_z", 0);
|
||||
m_og->set_value("rotation_x", 0);
|
||||
m_og->set_value("rotation_y", 0);
|
||||
m_og->set_value("rotation_z", 0);
|
||||
m_og->disable();
|
||||
return;
|
||||
}
|
||||
m_is_percent_scale = boost::any_cast<wxString>(m_og->get_value("scale_unit")) == _("%");
|
||||
|
||||
update_position_values();
|
||||
update_scale_values();
|
||||
update_rotation_values();
|
||||
m_og->enable();
|
||||
}
|
||||
|
||||
void ObjectManipulation::update_scale_values()
|
||||
{
|
||||
int selection = ol_selection();
|
||||
ModelObjectPtrs& objects = wxGetApp().mainframe->m_plater->model().objects;
|
||||
|
||||
auto instance = objects[selection]->instances.front();
|
||||
auto size = objects[selection]->instance_bounding_box(0).size();
|
||||
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
if (m_is_percent_scale) {
|
||||
m_og->set_value("scale_x", int(instance->get_scaling_factor(X) * 100));
|
||||
m_og->set_value("scale_y", int(instance->get_scaling_factor(Y) * 100));
|
||||
m_og->set_value("scale_z", int(instance->get_scaling_factor(Z) * 100));
|
||||
}
|
||||
else {
|
||||
m_og->set_value("scale_x", int(instance->get_scaling_factor(X) * size(0) + 0.5));
|
||||
m_og->set_value("scale_y", int(instance->get_scaling_factor(Y) * size(1) + 0.5));
|
||||
m_og->set_value("scale_z", int(instance->get_scaling_factor(Z) * size(2) + 0.5));
|
||||
}
|
||||
#else
|
||||
if (m_is_percent_scale) {
|
||||
auto scale = instance->scaling_factor * 100.0;
|
||||
m_og->set_value("scale_x", int(scale));
|
||||
m_og->set_value("scale_y", int(scale));
|
||||
m_og->set_value("scale_z", int(scale));
|
||||
}
|
||||
else {
|
||||
m_og->set_value("scale_x", int(instance->scaling_factor * size(0) + 0.5));
|
||||
m_og->set_value("scale_y", int(instance->scaling_factor * size(1) + 0.5));
|
||||
m_og->set_value("scale_z", int(instance->scaling_factor * size(2) + 0.5));
|
||||
}
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
}
|
||||
|
||||
void ObjectManipulation::update_position_values()
|
||||
{
|
||||
auto instance = wxGetApp().mainframe->m_plater->model().objects[ol_selection()]->instances.front();
|
||||
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
m_og->set_value("position_x", int(instance->get_offset(X)));
|
||||
m_og->set_value("position_y", int(instance->get_offset(Y)));
|
||||
m_og->set_value("position_z", int(instance->get_offset(Z)));
|
||||
#else
|
||||
m_og->set_value("position_x", int(instance->offset(0)));
|
||||
m_og->set_value("position_y", int(instance->offset(1)));
|
||||
m_og->set_value("position_z", 0);
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
}
|
||||
|
||||
void ObjectManipulation::update_position_values(const Vec3d& position)
|
||||
{
|
||||
m_og->set_value("position_x", int(position(0)));
|
||||
m_og->set_value("position_y", int(position(1)));
|
||||
m_og->set_value("position_z", int(position(2)));
|
||||
}
|
||||
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
void ObjectManipulation::update_scale_values(const Vec3d& scaling_factor)
|
||||
{
|
||||
// this is temporary
|
||||
// to be able to update the values as size
|
||||
// we need to store somewhere the original size
|
||||
// or have it passed as parameter
|
||||
if (!m_is_percent_scale)
|
||||
m_og->set_value("scale_unit", _("%"));
|
||||
|
||||
auto scale = scaling_factor * 100.0;
|
||||
m_og->set_value("scale_x", int(scale(0)));
|
||||
m_og->set_value("scale_y", int(scale(1)));
|
||||
m_og->set_value("scale_z", int(scale(2)));
|
||||
}
|
||||
#else
|
||||
void ObjectManipulation::update_scale_values(double scaling_factor)
|
||||
{
|
||||
// this is temporary
|
||||
// to be able to update the values as size
|
||||
// we need to store somewhere the original size
|
||||
// or have it passed as parameter
|
||||
if (!m_is_percent_scale)
|
||||
m_og->set_value("scale_unit", _("%"));
|
||||
|
||||
auto scale = scaling_factor * 100.0;
|
||||
m_og->set_value("scale_x", int(scale));
|
||||
m_og->set_value("scale_y", int(scale));
|
||||
m_og->set_value("scale_z", int(scale));
|
||||
}
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
|
||||
void ObjectManipulation::update_rotation_values()
|
||||
{
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
update_rotation_value(wxGetApp().mainframe->m_plater->model().objects[ol_selection()]->instances.front()->get_rotation());
|
||||
#else
|
||||
auto instance = wxGetApp().mainframe->m_plater->model().objects[ol_selection()]->instances.front();
|
||||
m_og->set_value("rotation_x", 0);
|
||||
m_og->set_value("rotation_y", 0);
|
||||
m_og->set_value("rotation_z", int(Geometry::rad2deg(instance->rotation)));
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
}
|
||||
|
||||
void ObjectManipulation::update_rotation_value(double angle, Axis axis)
|
||||
{
|
||||
std::string axis_str;
|
||||
switch (axis) {
|
||||
case X: {
|
||||
axis_str = "rotation_x";
|
||||
break; }
|
||||
case Y: {
|
||||
axis_str = "rotation_y";
|
||||
break; }
|
||||
case Z: {
|
||||
axis_str = "rotation_z";
|
||||
break; }
|
||||
}
|
||||
|
||||
m_og->set_value(axis_str, round_nearest(int(Geometry::rad2deg(angle)), 0));
|
||||
}
|
||||
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
void ObjectManipulation::update_rotation_value(const Vec3d& rotation)
|
||||
{
|
||||
m_og->set_value("rotation_x", int(round_nearest(Geometry::rad2deg(rotation(0)), 0)));
|
||||
m_og->set_value("rotation_y", int(round_nearest(Geometry::rad2deg(rotation(1)), 0)));
|
||||
m_og->set_value("rotation_z", int(round_nearest(Geometry::rad2deg(rotation(2)), 0)));
|
||||
}
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
|
||||
|
||||
|
||||
} //namespace GUI
|
||||
} //namespace Slic3r
|
64
src/slic3r/GUI/GUI_ObjectManipulation.hpp
Normal file
64
src/slic3r/GUI/GUI_ObjectManipulation.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef slic3r_GUI_ObjectManipulation_hpp_
|
||||
#define slic3r_GUI_ObjectManipulation_hpp_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <wx/panel.h>
|
||||
|
||||
#include "Preset.hpp"
|
||||
|
||||
class wxBoxSizer;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
class ConfigOptionsGroup;
|
||||
|
||||
|
||||
class OG_Settings
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<ConfigOptionsGroup> m_og;
|
||||
public:
|
||||
OG_Settings(wxWindow* parent, const bool staticbox);
|
||||
~OG_Settings() {}
|
||||
|
||||
wxSizer* get_sizer();
|
||||
};
|
||||
|
||||
|
||||
class ObjectManipulation : public OG_Settings
|
||||
{
|
||||
bool m_is_percent_scale = false; // true -> percentage scale unit
|
||||
// false -> uniform scale unit
|
||||
wxBoxSizer* m_extra_settings_sizer{ nullptr }; // sizer for extra Object/Part's settings
|
||||
|
||||
public:
|
||||
ObjectManipulation(wxWindow* parent);
|
||||
~ObjectManipulation() {}
|
||||
|
||||
int ol_selection();
|
||||
|
||||
void update_values();
|
||||
// update position values displacements or "gizmos"
|
||||
void update_position_values();
|
||||
void update_position_values(const Vec3d& position);
|
||||
// update scale values after scale unit changing or "gizmos"
|
||||
void update_scale_values();
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
void update_scale_values(const Vec3d& scaling_factor);
|
||||
#else
|
||||
void update_scale_values(double scaling_factor);
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
// update rotation values object selection changing
|
||||
void update_rotation_values();
|
||||
// update rotation value after "gizmos"
|
||||
void update_rotation_value(double angle, Axis axis);
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
void update_rotation_value(const Vec3d& rotation);
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // slic3r_GUI_ObjectManipulation_hpp_
|
@ -21,12 +21,8 @@ namespace Slic3r
|
||||
{
|
||||
namespace GUI
|
||||
{
|
||||
wxSizer *m_sizer_object_buttons = nullptr;
|
||||
wxSizer *m_sizer_part_buttons = nullptr;
|
||||
wxSizer *m_sizer_object_movers = nullptr;
|
||||
wxDataViewCtrl *m_objects_ctrl = nullptr;
|
||||
PrusaObjectDataViewModel *m_objects_model = nullptr;
|
||||
wxCollapsiblePane *m_collpane_settings = nullptr;
|
||||
PrusaDoubleSlider *m_slider = nullptr;
|
||||
wxGLCanvas *m_preview_canvas = nullptr;
|
||||
|
||||
@ -36,19 +32,12 @@ wxBitmap m_icon_manifold_warning;
|
||||
wxBitmap m_bmp_cog;
|
||||
wxBitmap m_bmp_split;
|
||||
|
||||
wxSlider* m_mover_x = nullptr;
|
||||
wxSlider* m_mover_y = nullptr;
|
||||
wxSlider* m_mover_z = nullptr;
|
||||
wxButton* m_btn_move_up = nullptr;
|
||||
wxButton* m_btn_move_down = nullptr;
|
||||
Vec3d m_move_options;
|
||||
Vec3d m_last_coords;
|
||||
int m_selected_object_id = -1;
|
||||
|
||||
bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select()
|
||||
// happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler
|
||||
// calls this method again and again and again
|
||||
bool g_is_percent_scale = false; // It indicates if scale unit is percentage
|
||||
// bool g_is_percent_scale = false; // It indicates if scale unit is percentage
|
||||
bool g_is_uniform_scale = false; // It indicates if scale is uniform
|
||||
ModelObjectPtrs* m_objects;
|
||||
std::shared_ptr<DynamicPrintConfig*> m_config;
|
||||
@ -158,457 +147,6 @@ void init_mesh_icons(){
|
||||
bool is_parts_changed(){return m_parts_changed;}
|
||||
bool is_part_settings_changed(){ return m_part_settings_changed; }
|
||||
|
||||
void set_tooltip_for_item(const wxPoint& pt)
|
||||
{
|
||||
wxDataViewItem item;
|
||||
wxDataViewColumn* col;
|
||||
m_objects_ctrl->HitTest(pt, item, col);
|
||||
if (!item) return;
|
||||
|
||||
if (col->GetTitle() == " ")
|
||||
m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings")));
|
||||
else if (col->GetTitle() == _("Name") &&
|
||||
m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) {
|
||||
int obj_idx = m_objects_model->GetIdByItem(item);
|
||||
auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats;
|
||||
int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
|
||||
stats.facets_added + stats.facets_reversed + stats.backwards_edges;
|
||||
|
||||
wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors);
|
||||
|
||||
std::map<std::string, int> error_msg;
|
||||
error_msg[L("degenerate facets")] = stats.degenerate_facets;
|
||||
error_msg[L("edges fixed")] = stats.edges_fixed;
|
||||
error_msg[L("facets removed")] = stats.facets_removed;
|
||||
error_msg[L("facets added")] = stats.facets_added;
|
||||
error_msg[L("facets reversed")] = stats.facets_reversed;
|
||||
error_msg[L("backwards edges")] = stats.backwards_edges;
|
||||
|
||||
for (auto error : error_msg)
|
||||
{
|
||||
if (error.second > 0)
|
||||
tooltip += wxString::Format(_("\t%d %s\n"), error.second, error.first);
|
||||
}
|
||||
// OR
|
||||
// tooltip += wxString::Format(_(L("%d degenerate facets, %d edges fixed, %d facets removed, "
|
||||
// "%d facets added, %d facets reversed, %d backwards edges")),
|
||||
// stats.degenerate_facets, stats.edges_fixed, stats.facets_removed,
|
||||
// stats.facets_added, stats.facets_reversed, stats.backwards_edges);
|
||||
|
||||
if (is_windows10())
|
||||
tooltip += _(L("Right button click the icon to fix STL through Netfabb"));
|
||||
|
||||
m_objects_ctrl->GetMainWindow()->SetToolTip(tooltip);
|
||||
}
|
||||
else
|
||||
m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip
|
||||
}
|
||||
|
||||
wxPoint get_mouse_position_in_control() {
|
||||
const wxPoint& pt = wxGetMousePosition();
|
||||
wxWindow* win = m_objects_ctrl->GetMainWindow();
|
||||
return wxPoint(pt.x - win->GetScreenPosition().x,
|
||||
pt.y - win->GetScreenPosition().y);
|
||||
}
|
||||
|
||||
bool is_mouse_position_in_control(wxPoint& pt) {
|
||||
pt = get_mouse_position_in_control();
|
||||
const wxSize& cz = m_objects_ctrl->GetSize();
|
||||
if (pt.x > 0 && pt.x < cz.x &&
|
||||
pt.y > 0 && pt.y < cz.y)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
wxDataViewColumn* object_ctrl_create_extruder_column(int extruders_count)
|
||||
{
|
||||
wxArrayString choices;
|
||||
choices.Add("default");
|
||||
for (int i = 1; i <= extruders_count; ++i)
|
||||
choices.Add(wxString::Format("%d", i));
|
||||
wxDataViewChoiceRenderer *c =
|
||||
new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL);
|
||||
wxDataViewColumn* column = new wxDataViewColumn(_(L("Extruder")), c, 2, 60, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
|
||||
return column;
|
||||
}
|
||||
|
||||
void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz)
|
||||
{
|
||||
m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
m_objects_ctrl->SetMinSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects
|
||||
|
||||
objects_sz = new wxBoxSizer(wxVERTICAL);
|
||||
objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20);
|
||||
|
||||
m_objects_model = new PrusaObjectDataViewModel;
|
||||
m_objects_ctrl->AssociateModel(m_objects_model);
|
||||
#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
|
||||
m_objects_ctrl->EnableDragSource(wxDF_UNICODETEXT);
|
||||
m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT);
|
||||
#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
|
||||
|
||||
// column 0(Icon+Text) of the view control:
|
||||
// And Icon can be consisting of several bitmaps
|
||||
m_objects_ctrl->AppendColumn(new wxDataViewColumn(_(L("Name")), new PrusaBitmapTextRenderer(),
|
||||
0, 200, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE));
|
||||
|
||||
// column 1 of the view control:
|
||||
m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45,
|
||||
wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
|
||||
|
||||
// column 2 of the view control:
|
||||
m_objects_ctrl->AppendColumn(object_ctrl_create_extruder_column(4));
|
||||
|
||||
// column 3 of the view control:
|
||||
m_objects_ctrl->AppendBitmapColumn(" ", 3, wxDATAVIEW_CELL_INERT, 25,
|
||||
wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
|
||||
}
|
||||
|
||||
// ****** from GUI.cpp
|
||||
wxBoxSizer* create_objects_list(wxWindow *win)
|
||||
{
|
||||
wxBoxSizer* objects_sz;
|
||||
// create control
|
||||
create_objects_ctrl(win, objects_sz);
|
||||
|
||||
// describe control behavior
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) {
|
||||
object_ctrl_selection_changed();
|
||||
#ifndef __WXMSW__
|
||||
set_tooltip_for_item(get_mouse_position_in_control());
|
||||
#endif //__WXMSW__
|
||||
});
|
||||
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) {
|
||||
object_ctrl_context_menu();
|
||||
// event.Skip();
|
||||
});
|
||||
|
||||
m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { object_ctrl_key_event(event); }); // doesn't work on OSX
|
||||
|
||||
#ifdef __WXMSW__
|
||||
// Extruder value changed
|
||||
m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); });
|
||||
|
||||
m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) {
|
||||
set_tooltip_for_item(event.GetPosition());
|
||||
event.Skip();
|
||||
});
|
||||
#else
|
||||
// equivalent to wxEVT_CHOICE on __WXMSW__
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { object_ctrl_item_value_change(event); });
|
||||
#endif //__WXMSW__
|
||||
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, [](wxDataViewEvent& e) {on_begin_drag(e);});
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, [](wxDataViewEvent& e) {on_drop_possible(e); });
|
||||
m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_DROP, [](wxDataViewEvent& e) {on_drop(e);});
|
||||
return objects_sz;
|
||||
}
|
||||
|
||||
wxBoxSizer* create_edit_object_buttons(wxWindow* win)
|
||||
{
|
||||
auto sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto btn_load_part = new wxButton(win, wxID_ANY, /*Load */"part" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
|
||||
auto btn_load_modifier = new wxButton(win, wxID_ANY, /*Load */"modifier" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
|
||||
auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, /*Load */"generic" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
|
||||
auto btn_delete = new wxButton(win, wxID_ANY, "Delete"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
|
||||
auto btn_split = new wxButton(win, wxID_ANY, "Split"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
|
||||
m_btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT);
|
||||
m_btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT);
|
||||
|
||||
//*** button's functions
|
||||
btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) {
|
||||
// on_btn_load(win);
|
||||
});
|
||||
|
||||
btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) {
|
||||
// on_btn_load(win, true);
|
||||
});
|
||||
|
||||
btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) {
|
||||
// on_btn_load(win, true, true);
|
||||
});
|
||||
|
||||
btn_delete ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_del(); });
|
||||
btn_split ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_split(true); });
|
||||
m_btn_move_up ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_move_up(); });
|
||||
m_btn_move_down ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_move_down(); });
|
||||
//***
|
||||
|
||||
m_btn_move_up->SetMinSize(wxSize(20, -1));
|
||||
m_btn_move_down->SetMinSize(wxSize(20, -1));
|
||||
btn_load_part->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG));
|
||||
btn_load_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG));
|
||||
btn_load_lambda_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG));
|
||||
btn_delete->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG));
|
||||
btn_split->SetBitmap(wxBitmap(from_u8(Slic3r::var("shape_ungroup.png")), wxBITMAP_TYPE_PNG));
|
||||
m_btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG));
|
||||
m_btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG));
|
||||
|
||||
m_sizer_object_buttons = new wxGridSizer(1, 3, 0, 0);
|
||||
m_sizer_object_buttons->Add(btn_load_part, 0, wxEXPAND);
|
||||
m_sizer_object_buttons->Add(btn_load_modifier, 0, wxEXPAND);
|
||||
m_sizer_object_buttons->Add(btn_load_lambda_modifier, 0, wxEXPAND);
|
||||
m_sizer_object_buttons->Show(false);
|
||||
|
||||
m_sizer_part_buttons = new wxGridSizer(1, 3, 0, 0);
|
||||
m_sizer_part_buttons->Add(btn_delete, 0, wxEXPAND);
|
||||
m_sizer_part_buttons->Add(btn_split, 0, wxEXPAND);
|
||||
{
|
||||
auto up_down_sizer = new wxGridSizer(1, 2, 0, 0);
|
||||
up_down_sizer->Add(m_btn_move_up, 1, wxEXPAND);
|
||||
up_down_sizer->Add(m_btn_move_down, 1, wxEXPAND);
|
||||
m_sizer_part_buttons->Add(up_down_sizer, 0, wxEXPAND);
|
||||
}
|
||||
m_sizer_part_buttons->Show(false);
|
||||
|
||||
btn_load_part->SetFont(wxGetApp().small_font());
|
||||
btn_load_modifier->SetFont(wxGetApp().small_font());
|
||||
btn_load_lambda_modifier->SetFont(wxGetApp().small_font());
|
||||
btn_delete->SetFont(wxGetApp().small_font());
|
||||
btn_split->SetFont(wxGetApp().small_font());
|
||||
m_btn_move_up->SetFont(wxGetApp().small_font());
|
||||
m_btn_move_down->SetFont(wxGetApp().small_font());
|
||||
|
||||
sizer->Add(m_sizer_object_buttons, 0, wxEXPAND | wxLEFT, 20);
|
||||
sizer->Add(m_sizer_part_buttons, 0, wxEXPAND | wxLEFT, 20);
|
||||
return sizer;
|
||||
}
|
||||
|
||||
void update_after_moving()
|
||||
{
|
||||
auto item = m_objects_ctrl->GetSelection();
|
||||
if (!item || m_selected_object_id<0)
|
||||
return;
|
||||
|
||||
auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
if (volume_id < 0)
|
||||
return;
|
||||
|
||||
auto d = m_move_options - m_last_coords;
|
||||
auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
|
||||
volume->mesh.translate(d(0), d(1), d(2));
|
||||
m_last_coords = m_move_options;
|
||||
|
||||
m_parts_changed = true;
|
||||
parts_changed(m_selected_object_id);
|
||||
}
|
||||
|
||||
wxSizer* object_movers(wxWindow *win)
|
||||
{
|
||||
// DynamicPrintConfig* config = &wxGetApp().preset_bundle->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume
|
||||
std::shared_ptr<ConfigOptionsGroup> optgroup = std::make_shared<ConfigOptionsGroup>(win, "Move"/*, config*/);
|
||||
optgroup->label_width = 20;
|
||||
optgroup->m_on_change = [](t_config_option_key opt_key, boost::any value){
|
||||
int val = boost::any_cast<int>(value);
|
||||
bool update = false;
|
||||
if (opt_key == "x" && m_move_options(0) != val){
|
||||
update = true;
|
||||
m_move_options(0) = val;
|
||||
}
|
||||
else if (opt_key == "y" && m_move_options(1) != val){
|
||||
update = true;
|
||||
m_move_options(1) = val;
|
||||
}
|
||||
else if (opt_key == "z" && m_move_options(2) != val){
|
||||
update = true;
|
||||
m_move_options(2) = val;
|
||||
}
|
||||
if (update) update_after_moving();
|
||||
};
|
||||
|
||||
ConfigOptionDef def;
|
||||
def.label = L("X");
|
||||
def.type = coInt;
|
||||
def.gui_type = "slider";
|
||||
def.default_value = new ConfigOptionInt(0);
|
||||
|
||||
Option option = Option(def, "x");
|
||||
option.opt.full_width = true;
|
||||
optgroup->append_single_option_line(option);
|
||||
m_mover_x = dynamic_cast<wxSlider*>(optgroup->get_field("x")->getWindow());
|
||||
|
||||
def.label = L("Y");
|
||||
option = Option(def, "y");
|
||||
optgroup->append_single_option_line(option);
|
||||
m_mover_y = dynamic_cast<wxSlider*>(optgroup->get_field("y")->getWindow());
|
||||
|
||||
def.label = L("Z");
|
||||
option = Option(def, "z");
|
||||
optgroup->append_single_option_line(option);
|
||||
m_mover_z = dynamic_cast<wxSlider*>(optgroup->get_field("z")->getWindow());
|
||||
|
||||
get_optgroups().push_back(optgroup); // ogObjectMovers
|
||||
|
||||
m_sizer_object_movers = optgroup->sizer;
|
||||
m_sizer_object_movers->Show(false);
|
||||
|
||||
m_move_options = Vec3d(0, 0, 0);
|
||||
m_last_coords = Vec3d(0, 0, 0);
|
||||
|
||||
return optgroup->sizer;
|
||||
}
|
||||
|
||||
void Sidebar::add_objects_list(wxWindow* parent, wxBoxSizer* sizer)
|
||||
{
|
||||
const auto ol_sizer = create_objects_list(parent);
|
||||
sizer->Add(ol_sizer, 1, wxEXPAND | wxTOP, 20);
|
||||
set_objects_list_sizer(ol_sizer);
|
||||
}
|
||||
|
||||
Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0)
|
||||
{
|
||||
Line line = { _(option_name), "" };
|
||||
if (option_name == "Scale") {
|
||||
line.near_label_widget = [](wxWindow* parent) {
|
||||
auto btn = new PrusaLockButton(parent, wxID_ANY);
|
||||
btn->Bind(wxEVT_BUTTON, [btn](wxCommandEvent &event){
|
||||
event.Skip();
|
||||
wxTheApp->CallAfter([btn]() { set_uniform_scaling(btn->IsLocked()); });
|
||||
});
|
||||
return btn;
|
||||
};
|
||||
}
|
||||
|
||||
ConfigOptionDef def;
|
||||
def.type = coInt;
|
||||
def.default_value = new ConfigOptionInt(def_value);
|
||||
def.width = 55;
|
||||
|
||||
if (option_name == "Rotation")
|
||||
def.min = -360;
|
||||
|
||||
const std::string lower_name = boost::algorithm::to_lower_copy(option_name);
|
||||
|
||||
std::vector<std::string> axes{ "x", "y", "z" };
|
||||
for (auto axis : axes) {
|
||||
if (axis == "z" && option_name != "Scale")
|
||||
def.sidetext = sidetext;
|
||||
Option option = Option(def, lower_name + "_" + axis);
|
||||
option.opt.full_width = true;
|
||||
line.append_option(option);
|
||||
}
|
||||
|
||||
if (option_name == "Scale")
|
||||
{
|
||||
def.width = 45;
|
||||
def.type = coStrings;
|
||||
def.gui_type = "select_open";
|
||||
def.enum_labels.push_back(L("%"));
|
||||
def.enum_labels.push_back(L("mm"));
|
||||
def.default_value = new ConfigOptionStrings{ "mm" };
|
||||
|
||||
const Option option = Option(def, lower_name + "_unit");
|
||||
line.append_option(option);
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
void Sidebar::add_object_settings(wxWindow* parent, wxBoxSizer* sizer, t_optgroups& optgroups)
|
||||
{
|
||||
auto optgroup = std::make_shared<ConfigOptionsGroup>(parent, _(L("Object Settings")));
|
||||
optgroup->label_width = 100;
|
||||
optgroup->set_grid_vgap(5);
|
||||
|
||||
optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
|
||||
if (opt_key == "scale_unit"){
|
||||
const wxString& selection = boost::any_cast<wxString>(value);
|
||||
std::vector<std::string> axes{ "x", "y", "z" };
|
||||
for (auto axis : axes) {
|
||||
std::string key = "scale_" + axis;
|
||||
get_optgroup(ogFrequentlyObjectSettings)->set_side_text(key, selection);
|
||||
}
|
||||
|
||||
g_is_percent_scale = selection == _("%");
|
||||
update_scale_values();
|
||||
}
|
||||
};
|
||||
|
||||
ConfigOptionDef def;
|
||||
|
||||
// Objects(sub-objects) name
|
||||
def.label = L("Name");
|
||||
// def.type = coString;
|
||||
def.gui_type = "legend";
|
||||
def.tooltip = L("Object name");
|
||||
def.full_width = true;
|
||||
def.default_value = new ConfigOptionString{ " " };
|
||||
optgroup->append_single_option_line(Option(def, "object_name"));
|
||||
|
||||
// Legend for object modification
|
||||
auto line = Line{ "", "" };
|
||||
def.label = "";
|
||||
def.type = coString;
|
||||
def.width = 55;
|
||||
|
||||
std::vector<std::string> axes{ "x", "y", "z" };
|
||||
for (const auto axis : axes) {
|
||||
const auto label = boost::algorithm::to_upper_copy(axis);
|
||||
def.default_value = new ConfigOptionString{ " "+label };
|
||||
Option option = Option(def, axis + "_axis_legend");
|
||||
line.append_option(option);
|
||||
}
|
||||
optgroup->append_line(line);
|
||||
|
||||
|
||||
// Settings table
|
||||
optgroup->append_line(add_og_to_object_settings(L("Position"), L("mm")));
|
||||
optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°"));
|
||||
optgroup->append_line(add_og_to_object_settings(L("Scale"), "mm"));
|
||||
|
||||
|
||||
def.label = L("Place on bed");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("Automatic placing of models on printing bed in Y axis");
|
||||
def.gui_type = "";
|
||||
def.sidetext = "";
|
||||
def.default_value = new ConfigOptionBool{ false };
|
||||
optgroup->append_single_option_line(Option(def, "place_on_bed"));
|
||||
|
||||
m_option_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
optgroup->sizer->Add(m_option_sizer, 1, wxEXPAND | wxLEFT, 5);
|
||||
|
||||
sizer->Add(optgroup->sizer, 0, wxEXPAND | wxLEFT | wxTOP, 20);
|
||||
|
||||
optgroup->disable();
|
||||
|
||||
optgroups.push_back(optgroup); // ogFrequentlyObjectSettings
|
||||
}
|
||||
|
||||
void add_object_to_list(const std::string &name, ModelObject* model_object)
|
||||
{
|
||||
wxString item_name = name;
|
||||
auto item = m_objects_model->Add(item_name, model_object->instances.size());
|
||||
m_objects_ctrl->Select(item);
|
||||
|
||||
// Add error icon if detected auto-repaire
|
||||
auto stats = model_object->volumes[0]->mesh.stl.stats;
|
||||
int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
|
||||
stats.facets_added + stats.facets_reversed + stats.backwards_edges;
|
||||
if (errors > 0) {
|
||||
const PrusaDataViewBitmapText data(item_name, m_icon_manifold_warning);
|
||||
wxVariant variant;
|
||||
variant << data;
|
||||
m_objects_model->SetValue(variant, item, 0);
|
||||
}
|
||||
|
||||
if (model_object->volumes.size() > 1) {
|
||||
for (auto id = 0; id < model_object->volumes.size(); id++)
|
||||
m_objects_model->AddChild(item,
|
||||
model_object->volumes[id]->name,
|
||||
m_icon_solidmesh,
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value,
|
||||
false);
|
||||
m_objects_ctrl->Expand(item);
|
||||
}
|
||||
|
||||
#ifndef __WXOSX__
|
||||
object_ctrl_selection_changed();
|
||||
#endif //__WXMSW__
|
||||
}
|
||||
|
||||
void delete_object_from_list()
|
||||
{
|
||||
auto item = m_objects_ctrl->GetSelection();
|
||||
@ -714,9 +252,7 @@ void object_ctrl_context_menu()
|
||||
{
|
||||
wxDataViewItem item;
|
||||
wxDataViewColumn* col;
|
||||
// printf("object_ctrl_context_menu\n");
|
||||
const wxPoint pt = get_mouse_position_in_control();
|
||||
// printf("mouse_position_in_control: x = %d, y = %d\n", pt.x, pt.y);
|
||||
const wxPoint pt;//!!! = get_mouse_position_in_control();
|
||||
m_objects_ctrl->HitTest(pt, item, col);
|
||||
if (!item)
|
||||
#ifdef __WXOSX__ // #ys_FIXME temporary workaround for OSX
|
||||
@ -730,9 +266,7 @@ void object_ctrl_context_menu()
|
||||
#else
|
||||
return;
|
||||
#endif // __WXOSX__
|
||||
// printf("item exists\n");
|
||||
const wxString title = col->GetTitle();
|
||||
// printf("title = *%s*\n", title.data().AsChar());
|
||||
|
||||
if (title == " ")
|
||||
show_context_menu();
|
||||
@ -1472,29 +1006,6 @@ void parts_changed(int obj_idx)
|
||||
e.SetString(event_str);
|
||||
// get_main_frame()->ProcessWindowEvent(e); // #ys_FIXME
|
||||
}
|
||||
|
||||
void update_settings_value()
|
||||
{
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
if (m_selected_object_id < 0 || m_objects->size() <= m_selected_object_id) {
|
||||
og->set_value("position_x", 0);
|
||||
og->set_value("position_y", 0);
|
||||
og->set_value("position_z", 0);
|
||||
og->set_value("scale_x", 0);
|
||||
og->set_value("scale_y", 0);
|
||||
og->set_value("scale_z", 0);
|
||||
og->set_value("rotation_x", 0);
|
||||
og->set_value("rotation_y", 0);
|
||||
og->set_value("rotation_z", 0);
|
||||
og->disable();
|
||||
return;
|
||||
}
|
||||
g_is_percent_scale = boost::any_cast<wxString>(og->get_value("scale_unit")) == _("%");
|
||||
update_position_values();
|
||||
update_scale_values();
|
||||
update_rotation_values();
|
||||
og->enable();
|
||||
}
|
||||
|
||||
void part_selection_changed()
|
||||
{
|
||||
@ -1549,7 +1060,7 @@ void part_selection_changed()
|
||||
|
||||
m_selected_object_id = obj_idx;
|
||||
|
||||
update_settings_value();
|
||||
// update_values();
|
||||
}
|
||||
|
||||
void set_extruder_column_hidden(bool hide)
|
||||
@ -1571,149 +1082,6 @@ void update_extruder_in_config(const wxString& selection)
|
||||
}
|
||||
}
|
||||
|
||||
void update_scale_values()
|
||||
{
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
auto instance = (*m_objects)[m_selected_object_id]->instances.front();
|
||||
auto size = (*m_objects)[m_selected_object_id]->instance_bounding_box(0).size();
|
||||
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
if (g_is_percent_scale) {
|
||||
og->set_value("scale_x", int(instance->get_scaling_factor(X) * 100));
|
||||
og->set_value("scale_y", int(instance->get_scaling_factor(Y) * 100));
|
||||
og->set_value("scale_z", int(instance->get_scaling_factor(Z) * 100));
|
||||
}
|
||||
else {
|
||||
og->set_value("scale_x", int(instance->get_scaling_factor(X) * size(0) + 0.5));
|
||||
og->set_value("scale_y", int(instance->get_scaling_factor(Y) * size(1) + 0.5));
|
||||
og->set_value("scale_z", int(instance->get_scaling_factor(Z) * size(2) + 0.5));
|
||||
}
|
||||
#else
|
||||
if (g_is_percent_scale) {
|
||||
auto scale = instance->scaling_factor * 100.0;
|
||||
og->set_value("scale_x", int(scale));
|
||||
og->set_value("scale_y", int(scale));
|
||||
og->set_value("scale_z", int(scale));
|
||||
}
|
||||
else {
|
||||
og->set_value("scale_x", int(instance->scaling_factor * size(0) + 0.5));
|
||||
og->set_value("scale_y", int(instance->scaling_factor * size(1) + 0.5));
|
||||
og->set_value("scale_z", int(instance->scaling_factor * size(2) + 0.5));
|
||||
}
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
}
|
||||
|
||||
void update_position_values()
|
||||
{
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
auto instance = (*m_objects)[m_selected_object_id]->instances.front();
|
||||
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
og->set_value("position_x", int(instance->get_offset(X)));
|
||||
og->set_value("position_y", int(instance->get_offset(Y)));
|
||||
og->set_value("position_z", int(instance->get_offset(Z)));
|
||||
#else
|
||||
og->set_value("position_x", int(instance->offset(0)));
|
||||
og->set_value("position_y", int(instance->offset(1)));
|
||||
og->set_value("position_z", 0);
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
}
|
||||
|
||||
void update_position_values(const Vec3d& position)
|
||||
{
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
|
||||
og->set_value("position_x", int(position(0)));
|
||||
og->set_value("position_y", int(position(1)));
|
||||
og->set_value("position_z", int(position(2)));
|
||||
}
|
||||
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
void update_scale_values(const Vec3d& scaling_factor)
|
||||
{
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
|
||||
// this is temporary
|
||||
// to be able to update the values as size
|
||||
// we need to store somewhere the original size
|
||||
// or have it passed as parameter
|
||||
if (!g_is_percent_scale)
|
||||
og->set_value("scale_unit", _("%"));
|
||||
|
||||
auto scale = scaling_factor * 100.0;
|
||||
og->set_value("scale_x", int(scale(0)));
|
||||
og->set_value("scale_y", int(scale(1)));
|
||||
og->set_value("scale_z", int(scale(2)));
|
||||
}
|
||||
#else
|
||||
void update_scale_values(double scaling_factor)
|
||||
{
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
|
||||
// this is temporary
|
||||
// to be able to update the values as size
|
||||
// we need to store somewhere the original size
|
||||
// or have it passed as parameter
|
||||
if (!g_is_percent_scale)
|
||||
og->set_value("scale_unit", _("%"));
|
||||
|
||||
auto scale = scaling_factor * 100.0;
|
||||
og->set_value("scale_x", int(scale));
|
||||
og->set_value("scale_y", int(scale));
|
||||
og->set_value("scale_z", int(scale));
|
||||
}
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
|
||||
void update_rotation_values()
|
||||
{
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
update_rotation_value((*m_objects)[m_selected_object_id]->instances.front()->get_rotation());
|
||||
#else
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
auto instance = (*m_objects)[m_selected_object_id]->instances.front();
|
||||
og->set_value("rotation_x", 0);
|
||||
og->set_value("rotation_y", 0);
|
||||
og->set_value("rotation_z", int(Geometry::rad2deg(instance->rotation)));
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
}
|
||||
|
||||
void update_rotation_value(double angle, Axis axis)
|
||||
{
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
|
||||
std::string axis_str;
|
||||
switch (axis)
|
||||
{
|
||||
case X:
|
||||
{
|
||||
axis_str = "rotation_x";
|
||||
break;
|
||||
}
|
||||
case Y:
|
||||
{
|
||||
axis_str = "rotation_y";
|
||||
break;
|
||||
}
|
||||
case Z:
|
||||
{
|
||||
axis_str = "rotation_z";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
og->set_value(axis_str, round_nearest(int(Geometry::rad2deg(angle)), 0));
|
||||
}
|
||||
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
void update_rotation_value(const Vec3d& rotation)
|
||||
{
|
||||
auto og = get_optgroup(ogFrequentlyObjectSettings);
|
||||
og->set_value("rotation_x", int(round_nearest(Geometry::rad2deg(rotation(0)), 0)));
|
||||
og->set_value("rotation_y", int(round_nearest(Geometry::rad2deg(rotation(1)), 0)));
|
||||
og->set_value("rotation_z", int(round_nearest(Geometry::rad2deg(rotation(2)), 0)));
|
||||
}
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
|
||||
void set_uniform_scaling(const bool uniform_scale)
|
||||
{
|
||||
g_is_uniform_scale = uniform_scale;
|
||||
@ -1792,20 +1160,6 @@ void on_drop(wxDataViewEvent &event)
|
||||
g_prevent_list_events = false;
|
||||
}
|
||||
|
||||
void update_objects_list_extruder_column(int extruders_count)
|
||||
{
|
||||
if (!m_objects_ctrl) return; // #ys_FIXME
|
||||
if (wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
|
||||
extruders_count = 1;
|
||||
|
||||
// delete old 3rd column
|
||||
m_objects_ctrl->DeleteColumn(m_objects_ctrl->GetColumn(2));
|
||||
// insert new created 3rd column
|
||||
m_objects_ctrl->InsertColumn(2, object_ctrl_create_extruder_column(extruders_count));
|
||||
// set show/hide for this column
|
||||
set_extruder_column_hidden(extruders_count <= 1);
|
||||
}
|
||||
|
||||
void create_double_slider(wxWindow* parent, wxBoxSizer* sizer, wxGLCanvas* canvas)
|
||||
{
|
||||
m_slider = new PrusaDoubleSlider(parent, wxID_ANY, 0, 0, 0, 100);
|
||||
|
@ -106,28 +106,11 @@ void on_btn_move_down();
|
||||
void parts_changed(int obj_idx);
|
||||
void part_selection_changed();
|
||||
|
||||
void update_settings_value();
|
||||
// show/hide "Extruder" column for Objects List
|
||||
void set_extruder_column_hidden(bool hide);
|
||||
// update extruder in current config
|
||||
void update_extruder_in_config(const wxString& selection);
|
||||
// update position values displacements or "gizmos"
|
||||
void update_position_values();
|
||||
void update_position_values(const Vec3d& position);
|
||||
// update scale values after scale unit changing or "gizmos"
|
||||
void update_scale_values();
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
void update_scale_values(const Vec3d& scaling_factor);
|
||||
#else
|
||||
void update_scale_values(double scaling_factor);
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
// update rotation values object selection changing
|
||||
void update_rotation_values();
|
||||
// update rotation value after "gizmos"
|
||||
void update_rotation_value(double angle, Axis axis);
|
||||
#if ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
void update_rotation_value(const Vec3d& rotation);
|
||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||
|
||||
void set_uniform_scaling(const bool uniform_scale);
|
||||
|
||||
void on_begin_drag(wxDataViewEvent &event);
|
||||
|
@ -274,7 +274,7 @@ void MainFrame::create_preset_tabs()
|
||||
|
||||
void MainFrame::add_created_tab(Tab* panel)
|
||||
{
|
||||
panel->create_preset_tab(wxGetApp().preset_bundle);
|
||||
panel->create_preset_tab();
|
||||
|
||||
// Load the currently selected preset into the GUI, update the preset selection box.
|
||||
panel->load_current_preset();
|
||||
|
@ -231,6 +231,7 @@ public:
|
||||
bool m_full_labels {0};
|
||||
t_opt_map m_opt_map;
|
||||
|
||||
void set_config(DynamicPrintConfig* config){ m_config = config; }
|
||||
Option get_option(const std::string& opt_key, int opt_index = -1);
|
||||
Line create_single_option_line(const std::string& title, int idx = -1) /*const*/{
|
||||
Option option = get_option(title, idx);
|
||||
|
@ -27,10 +27,11 @@
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "GUI_ObjectManipulation.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "3DScene.hpp"
|
||||
#include "GLCanvas3D.hpp"
|
||||
#include "GUI_ObjectParts.hpp"
|
||||
#include "GLToolbar.hpp"
|
||||
#include "GUI_Preview.hpp"
|
||||
#include "Tab.hpp"
|
||||
@ -200,6 +201,141 @@ PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
|
||||
PresetComboBox::~PresetComboBox() {}
|
||||
|
||||
|
||||
// Frequently changed parameters
|
||||
|
||||
class FreqChangedParams : public OG_Settings
|
||||
{
|
||||
double m_brim_width = 0.0;
|
||||
wxButton* m_wiping_dialog_button{ nullptr };
|
||||
public:
|
||||
FreqChangedParams(wxWindow* parent, const int label_width);
|
||||
~FreqChangedParams() {}
|
||||
|
||||
wxButton* get_wiping_dialog_button() { return m_wiping_dialog_button; }
|
||||
};
|
||||
|
||||
FreqChangedParams::FreqChangedParams(wxWindow* parent, const int label_width) :
|
||||
OG_Settings(parent, false)
|
||||
{
|
||||
DynamicPrintConfig* config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
|
||||
m_og->set_config(config);
|
||||
m_og->label_width = label_width;
|
||||
|
||||
m_og->m_on_change = [config, this](t_config_option_key opt_key, boost::any value){
|
||||
TabPrint* tab_print = nullptr;
|
||||
for (size_t i = 0; i < wxGetApp().tab_panel()->GetPageCount(); ++i) {
|
||||
Tab *tab = dynamic_cast<Tab*>(wxGetApp().tab_panel()->GetPage(i));
|
||||
if (!tab)
|
||||
continue;
|
||||
if (tab->name() == "print"){
|
||||
tab_print = static_cast<TabPrint*>(tab);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tab_print == nullptr)
|
||||
return;
|
||||
|
||||
if (opt_key == "fill_density"){
|
||||
value = m_og->get_config_value(*config, opt_key);
|
||||
tab_print->set_value(opt_key, value);
|
||||
tab_print->update();
|
||||
}
|
||||
else{
|
||||
DynamicPrintConfig new_conf = *config;
|
||||
if (opt_key == "brim"){
|
||||
double new_val;
|
||||
double brim_width = config->opt_float("brim_width");
|
||||
if (boost::any_cast<bool>(value) == true)
|
||||
{
|
||||
new_val = m_brim_width == 0.0 ? 10 :
|
||||
m_brim_width < 0.0 ? m_brim_width * (-1) :
|
||||
m_brim_width;
|
||||
}
|
||||
else{
|
||||
m_brim_width = brim_width * (-1);
|
||||
new_val = 0;
|
||||
}
|
||||
new_conf.set_key_value("brim_width", new ConfigOptionFloat(new_val));
|
||||
}
|
||||
else{ //(opt_key == "support")
|
||||
const wxString& selection = boost::any_cast<wxString>(value);
|
||||
|
||||
auto support_material = selection == _("None") ? false : true;
|
||||
new_conf.set_key_value("support_material", new ConfigOptionBool(support_material));
|
||||
|
||||
if (selection == _("Everywhere"))
|
||||
new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false));
|
||||
else if (selection == _("Support on build plate only"))
|
||||
new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true));
|
||||
}
|
||||
tab_print->load_config(new_conf);
|
||||
}
|
||||
|
||||
tab_print->update_dirty();
|
||||
};
|
||||
|
||||
Option option = m_og->get_option("fill_density");
|
||||
option.opt.sidetext = "";
|
||||
option.opt.full_width = true;
|
||||
m_og->append_single_option_line(option);
|
||||
|
||||
ConfigOptionDef def;
|
||||
|
||||
def.label = L("Support");
|
||||
def.type = coStrings;
|
||||
def.gui_type = "select_open";
|
||||
def.tooltip = L("Select what kind of support do you need");
|
||||
def.enum_labels.push_back(L("None"));
|
||||
def.enum_labels.push_back(L("Support on build plate only"));
|
||||
def.enum_labels.push_back(L("Everywhere"));
|
||||
std::string selection = !config->opt_bool("support_material") ?
|
||||
"None" :
|
||||
config->opt_bool("support_material_buildplate_only") ?
|
||||
"Support on build plate only" :
|
||||
"Everywhere";
|
||||
def.default_value = new ConfigOptionStrings{ selection };
|
||||
option = Option(def, "support");
|
||||
option.opt.full_width = true;
|
||||
m_og->append_single_option_line(option);
|
||||
|
||||
m_brim_width = config->opt_float("brim_width");
|
||||
def.label = L("Brim");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("This flag enables the brim that will be printed around each object on the first layer.");
|
||||
def.gui_type = "";
|
||||
def.default_value = new ConfigOptionBool{ m_brim_width > 0.0 ? true : false };
|
||||
option = Option(def, "brim");
|
||||
m_og->append_single_option_line(option);
|
||||
|
||||
|
||||
Line line = { "", "" };
|
||||
line.widget = [config, this](wxWindow* parent){
|
||||
m_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(m_wiping_dialog_button);
|
||||
m_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e)
|
||||
{
|
||||
auto &config = wxGetApp().preset_bundle->project_config;
|
||||
const std::vector<double> &init_matrix = (config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values;
|
||||
const std::vector<double> &init_extruders = (config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values;
|
||||
|
||||
WipingDialog dlg(parent, cast<float>(init_matrix), cast<float>(init_extruders));
|
||||
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
std::vector<float> matrix = dlg.get_matrix();
|
||||
std::vector<float> extruders = dlg.get_extruders();
|
||||
(config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
|
||||
(config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values = std::vector<double>(extruders.begin(), extruders.end());
|
||||
g_on_request_update_callback.call();
|
||||
}
|
||||
}));
|
||||
return sizer;
|
||||
};
|
||||
m_og->append_line(line);
|
||||
}
|
||||
|
||||
|
||||
// Sidebar / private
|
||||
|
||||
struct Sidebar::priv
|
||||
@ -216,6 +352,9 @@ struct Sidebar::priv
|
||||
PresetComboBox *combo_printer;
|
||||
|
||||
wxBoxSizer *sizer_params;
|
||||
FreqChangedParams *frequently_changed_parameters;
|
||||
ObjectList *object_list;
|
||||
ObjectManipulation *object_manipulation;
|
||||
ObjectInfo *object_info;
|
||||
SlicedInfo *sliced_info;
|
||||
|
||||
@ -225,10 +364,6 @@ struct Sidebar::priv
|
||||
wxButton *btn_send_gcode;
|
||||
|
||||
std::vector <std::shared_ptr<ConfigOptionsGroup>> optgroups {};
|
||||
double brim_width = 0.0;
|
||||
size_t label_width = 100;
|
||||
wxButton* btn_wiping_dialog {nullptr};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -268,16 +403,24 @@ Sidebar::Sidebar(wxWindow *parent)
|
||||
init_combo(&p->combo_sla_material, _(L("SLA material")), Preset::TYPE_SLA_MATERIAL, false);
|
||||
init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false);
|
||||
|
||||
// calculate width of the preset labels
|
||||
p->sizer_presets->Layout();
|
||||
const wxArrayInt& ar = p->sizer_presets->GetColWidths();
|
||||
int label_width = ar.IsEmpty() ? 100 : ar.front()-4;
|
||||
|
||||
p->sizer_params = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
// Frequently changed parameters
|
||||
p->sizer_params = new wxBoxSizer(wxVERTICAL);
|
||||
add_frequently_changed_parameters(p->scrolled, p->sizer_params/*, p->sizer_presets*/);
|
||||
p->frequently_changed_parameters = new FreqChangedParams(p->scrolled, label_width);
|
||||
p->sizer_params->Add(p->frequently_changed_parameters->get_sizer(), 0, wxEXPAND | wxBOTTOM | wxLEFT, 2);
|
||||
|
||||
// Object List
|
||||
add_objects_list(p->scrolled, p->sizer_params);
|
||||
p->object_list = new ObjectList(p->scrolled);
|
||||
p->sizer_params->Add(p->object_list->get_sizer(), 1, wxEXPAND | wxTOP, 20);
|
||||
|
||||
// Frequently Object Settings
|
||||
add_object_settings(p->scrolled, p->sizer_params, p->optgroups);
|
||||
p->object_manipulation = new ObjectManipulation(p->scrolled);
|
||||
p->sizer_params->Add(p->object_manipulation->get_sizer(), 0, wxEXPAND | wxLEFT | wxTOP, 20);
|
||||
|
||||
// Buttons in the scrolled area
|
||||
wxBitmap arrow_up(GUI::from_u8(Slic3r::var("brick_go.png")), wxBITMAP_TYPE_PNG);
|
||||
@ -364,6 +507,11 @@ void Sidebar::update_presets(Preset::Type preset_type)
|
||||
// wxTheApp->{preset_bundle}->export_selections(wxTheApp->{app_config});
|
||||
}
|
||||
|
||||
ObjectManipulation* Sidebar::obj_manipul()
|
||||
{
|
||||
return p->object_manipulation;
|
||||
}
|
||||
|
||||
ConfigOptionsGroup* Sidebar::get_optgroup(size_t i)
|
||||
{
|
||||
return p->optgroups.empty() ? nullptr : p->optgroups[i].get();
|
||||
@ -375,7 +523,17 @@ t_optgroups& Sidebar::get_optgroups() {
|
||||
|
||||
wxButton* Sidebar::get_wiping_dialog_button()
|
||||
{
|
||||
return p->btn_wiping_dialog;
|
||||
return p->frequently_changed_parameters->get_wiping_dialog_button();
|
||||
}
|
||||
|
||||
void Sidebar::update_objects_list_extruder_column(int extruders_count)
|
||||
{
|
||||
p->object_list->update_objects_list_extruder_column(extruders_count);
|
||||
}
|
||||
|
||||
int Sidebar::get_ol_selection()
|
||||
{
|
||||
return p->object_list->get_sel_obj_id();
|
||||
}
|
||||
|
||||
|
||||
@ -431,7 +589,7 @@ struct Plater::priv
|
||||
wxNotebook *notebook;
|
||||
Sidebar *sidebar;
|
||||
wxGLCanvas *canvas3D; // TODO: Use GLCanvas3D when we can
|
||||
GUI::Preview *preview;
|
||||
Preview *preview;
|
||||
BackgroundSlicingProcess background_process;
|
||||
|
||||
static const int gl_attrs[];
|
||||
@ -933,6 +1091,7 @@ Plater::~Plater()
|
||||
}
|
||||
|
||||
Sidebar& Plater::sidebar() { return *p->sidebar; }
|
||||
Model& Plater::model() { return p->model; }
|
||||
|
||||
std::string Plater::export_gcode(const std::string &output_path)
|
||||
{
|
||||
|
@ -4,17 +4,18 @@
|
||||
#include <memory>
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <wx/scrolwin.h>
|
||||
|
||||
#include "Preset.hpp"
|
||||
|
||||
class wxBoxSizer;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class Model;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
class MainFrame;
|
||||
class ConfigOptionsGroup;
|
||||
class ObjectManipulation;
|
||||
|
||||
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
|
||||
|
||||
@ -30,14 +31,14 @@ public:
|
||||
|
||||
void update_presets(Slic3r::Preset::Type preset_type);
|
||||
|
||||
void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer);
|
||||
void add_objects_list(wxWindow* parent, wxBoxSizer* sizer);
|
||||
void add_object_settings(wxWindow* parent, wxBoxSizer* sizer, t_optgroups& optgroups);
|
||||
ObjectManipulation* obj_manipul();
|
||||
|
||||
|
||||
ConfigOptionsGroup* get_optgroup(size_t i);
|
||||
t_optgroups& get_optgroups();
|
||||
ConfigOptionsGroup* get_optgroup(size_t i); // #ys_FIXME_for_delete
|
||||
t_optgroups& get_optgroups();// #ys_FIXME_for_delete
|
||||
wxButton* get_wiping_dialog_button();
|
||||
void update_objects_list_extruder_column(int extruders_count);
|
||||
int get_ol_selection();
|
||||
|
||||
private:
|
||||
struct priv;
|
||||
std::unique_ptr<priv> p;
|
||||
@ -57,6 +58,7 @@ public:
|
||||
~Plater();
|
||||
|
||||
Sidebar& sidebar();
|
||||
Model& model();
|
||||
|
||||
// TODO: use fs::path
|
||||
// Note: empty string means request default path
|
||||
|
@ -33,9 +33,9 @@
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
void Tab::create_preset_tab(PresetBundle *preset_bundle)
|
||||
void Tab::create_preset_tab()
|
||||
{
|
||||
m_preset_bundle = preset_bundle;
|
||||
m_preset_bundle = wxGetApp().preset_bundle;
|
||||
|
||||
// Vertical sizer to hold the choice menu and the rest of the page.
|
||||
#ifdef __WXOSX__
|
||||
@ -711,7 +711,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
||||
|
||||
// Show/hide the 'purging volumes' button
|
||||
void Tab::update_wiping_button_visibility() {
|
||||
if (wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
|
||||
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
|
||||
return; // ys_FIXME
|
||||
bool wipe_tower_enabled = dynamic_cast<ConfigOptionBool*>( (m_preset_bundle->prints.get_edited_preset().config ).option("wipe_tower"))->value;
|
||||
bool multiple_extruders = dynamic_cast<ConfigOptionFloats*>((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1;
|
||||
@ -1044,7 +1044,7 @@ void TabPrint::reload_config(){
|
||||
|
||||
void TabPrint::update()
|
||||
{
|
||||
if (wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
|
||||
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
|
||||
return; // ys_FIXME
|
||||
|
||||
Freeze();
|
||||
@ -1410,7 +1410,7 @@ void TabFilament::reload_config(){
|
||||
|
||||
void TabFilament::update()
|
||||
{
|
||||
if (wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
|
||||
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
|
||||
return; // ys_FIXME
|
||||
|
||||
Freeze();
|
||||
@ -1842,7 +1842,8 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){
|
||||
build_extruder_pages();
|
||||
reload_config();
|
||||
on_value_change("extruders_count", extruders_count);
|
||||
update_objects_list_extruder_column(extruders_count);
|
||||
if (wxGetApp().mainframe)
|
||||
wxGetApp().mainframe->m_plater->sidebar().update_objects_list_extruder_column(extruders_count);
|
||||
}
|
||||
|
||||
void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key)
|
||||
@ -3030,7 +3031,7 @@ void TabSLAMaterial::build()
|
||||
|
||||
void TabSLAMaterial::update()
|
||||
{
|
||||
if (wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF)
|
||||
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF)
|
||||
return; // ys_FIXME
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ public:
|
||||
void set_event_value_change(wxEventType evt) { m_event_value_change = evt; }
|
||||
void set_event_presets_changed(wxEventType evt) { m_event_presets_changed = evt; }
|
||||
|
||||
void create_preset_tab(PresetBundle *preset_bundle);
|
||||
void create_preset_tab();
|
||||
void load_current_preset();
|
||||
void rebuild_page_tree(bool tree_sel_change_event = false);
|
||||
void select_preset(std::string preset_name = "");
|
||||
|
Loading…
Reference in New Issue
Block a user