Start to Split GUI_ObjectParts:

+ created GUI_ObjectList & GUI_ObjectManipulation classes
This commit is contained in:
YuSanka 2018-10-04 16:43:10 +02:00
parent 7ed9ba5437
commit bcedd71e99
17 changed files with 836 additions and 834 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 };

View 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

View 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_

View 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

View 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_

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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)
{

View File

@ -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

View File

@ -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
}

View File

@ -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 = "");