mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-22 04:28:05 +08:00
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/MainFrame.hpp
|
||||||
${LIBDIR}/slic3r/GUI/Plater.cpp
|
${LIBDIR}/slic3r/GUI/Plater.cpp
|
||||||
${LIBDIR}/slic3r/GUI/Plater.hpp
|
${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.cpp
|
||||||
${LIBDIR}/slic3r/GUI/LambdaObjectDialog.hpp
|
${LIBDIR}/slic3r/GUI/LambdaObjectDialog.hpp
|
||||||
${LIBDIR}/slic3r/GUI/Tab.cpp
|
${LIBDIR}/slic3r/GUI/Tab.cpp
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "../../libslic3r/PrintConfig.hpp"
|
#include "../../libslic3r/PrintConfig.hpp"
|
||||||
#include "../../libslic3r/GCode/PreviewData.hpp"
|
#include "../../libslic3r/GCode/PreviewData.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
|
#include "GUI_ObjectManipulation.hpp"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
@ -2982,7 +2983,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||||||
#else
|
#else
|
||||||
m_on_gizmo_scale_uniformly_callback.call((double)m_gizmos.get_scale());
|
m_on_gizmo_scale_uniformly_callback.call((double)m_gizmos.get_scale());
|
||||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||||
update_scale_values();
|
wxGetApp().obj_manipul()->update_scale_values();
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2993,7 +2994,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||||||
#else
|
#else
|
||||||
m_on_gizmo_rotate_callback.call((double)m_gizmos.get_angle_z());
|
m_on_gizmo_rotate_callback.call((double)m_gizmos.get_angle_z());
|
||||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||||
update_rotation_values();
|
wxGetApp().obj_manipul()->update_rotation_values();
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3181,7 +3182,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||||||
v->set_offset(v->get_offset() + Vec3d(vector(0), vector(1), 0.0));
|
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_mouse.drag.start_position_3D = cur_pos;
|
||||||
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
@ -3222,7 +3223,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||||||
{
|
{
|
||||||
v->set_offset(v->get_offset() + offset);
|
v->set_offset(v->get_offset() + offset);
|
||||||
}
|
}
|
||||||
update_position_values(volume->get_offset());
|
wxGetApp().obj_manipul()->update_position_values(volume->get_offset());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Gizmos::Scale:
|
case Gizmos::Scale:
|
||||||
@ -3234,7 +3235,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||||||
{
|
{
|
||||||
v->set_scaling_factor(scale);
|
v->set_scaling_factor(scale);
|
||||||
}
|
}
|
||||||
update_scale_values(scale);
|
wxGetApp().obj_manipul()->update_scale_values(scale);
|
||||||
#else
|
#else
|
||||||
// Apply new temporary scale factor
|
// Apply new temporary scale factor
|
||||||
float scale_factor = m_gizmos.get_scale();
|
float scale_factor = m_gizmos.get_scale();
|
||||||
@ -3255,7 +3256,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||||||
{
|
{
|
||||||
v->set_rotation(rotation);
|
v->set_rotation(rotation);
|
||||||
}
|
}
|
||||||
update_rotation_value(rotation);
|
wxGetApp().obj_manipul()->update_rotation_value(rotation);
|
||||||
#else
|
#else
|
||||||
// Apply new temporary angle_z
|
// Apply new temporary angle_z
|
||||||
float angle_z = m_gizmos.get_angle_z();
|
float angle_z = m_gizmos.get_angle_z();
|
||||||
@ -3430,7 +3431,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_gizmos.stop_dragging();
|
m_gizmos.stop_dragging();
|
||||||
update_settings_value();
|
wxGetApp().obj_manipul()->update_values();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mouse.drag.move_volume_idx = -1;
|
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));
|
model_object->instances[instance_idx]->offset = Vec2d(offset(0), offset(1));
|
||||||
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
#endif // ENABLE_MODELINSTANCE_3D_FULL_TRANSFORM
|
||||||
model_object->invalidate_bounding_box();
|
model_object->invalidate_bounding_box();
|
||||||
update_position_values();
|
wxGetApp().obj_manipul()->update_position_values();
|
||||||
object_moved = true;
|
object_moved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -519,135 +519,6 @@ void set_model_events_from_perl(Model &model,
|
|||||||
// add_collapsible_panes(parent, sizer);
|
// 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)
|
void show_buttons(bool show)
|
||||||
{
|
{
|
||||||
g_buttons[abReslice]->Show(show);
|
g_buttons[abReslice]->Show(show);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
|
#include "GUI_ObjectManipulation.hpp"
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/algorithm/string.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;
|
return mainframe->m_tabpanel;
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,15 @@ public:
|
|||||||
// Tab* get_tab(const std::string& name);
|
// Tab* get_tab(const std::string& name);
|
||||||
void load_current_presets();
|
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 };
|
AppConfig* app_config{ nullptr };
|
||||||
PresetBundle* preset_bundle{ nullptr };
|
PresetBundle* preset_bundle{ nullptr };
|
||||||
PresetUpdater* preset_updater{ 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
|
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;
|
wxDataViewCtrl *m_objects_ctrl = nullptr;
|
||||||
PrusaObjectDataViewModel *m_objects_model = nullptr;
|
PrusaObjectDataViewModel *m_objects_model = nullptr;
|
||||||
wxCollapsiblePane *m_collpane_settings = nullptr;
|
|
||||||
PrusaDoubleSlider *m_slider = nullptr;
|
PrusaDoubleSlider *m_slider = nullptr;
|
||||||
wxGLCanvas *m_preview_canvas = nullptr;
|
wxGLCanvas *m_preview_canvas = nullptr;
|
||||||
|
|
||||||
@ -36,19 +32,12 @@ wxBitmap m_icon_manifold_warning;
|
|||||||
wxBitmap m_bmp_cog;
|
wxBitmap m_bmp_cog;
|
||||||
wxBitmap m_bmp_split;
|
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;
|
int m_selected_object_id = -1;
|
||||||
|
|
||||||
bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select()
|
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
|
// happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler
|
||||||
// calls this method again and again and again
|
// 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
|
bool g_is_uniform_scale = false; // It indicates if scale is uniform
|
||||||
ModelObjectPtrs* m_objects;
|
ModelObjectPtrs* m_objects;
|
||||||
std::shared_ptr<DynamicPrintConfig*> m_config;
|
std::shared_ptr<DynamicPrintConfig*> m_config;
|
||||||
@ -158,457 +147,6 @@ void init_mesh_icons(){
|
|||||||
bool is_parts_changed(){return m_parts_changed;}
|
bool is_parts_changed(){return m_parts_changed;}
|
||||||
bool is_part_settings_changed(){ return m_part_settings_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()
|
void delete_object_from_list()
|
||||||
{
|
{
|
||||||
auto item = m_objects_ctrl->GetSelection();
|
auto item = m_objects_ctrl->GetSelection();
|
||||||
@ -714,9 +252,7 @@ void object_ctrl_context_menu()
|
|||||||
{
|
{
|
||||||
wxDataViewItem item;
|
wxDataViewItem item;
|
||||||
wxDataViewColumn* col;
|
wxDataViewColumn* col;
|
||||||
// printf("object_ctrl_context_menu\n");
|
const wxPoint pt;//!!! = get_mouse_position_in_control();
|
||||||
const wxPoint pt = get_mouse_position_in_control();
|
|
||||||
// printf("mouse_position_in_control: x = %d, y = %d\n", pt.x, pt.y);
|
|
||||||
m_objects_ctrl->HitTest(pt, item, col);
|
m_objects_ctrl->HitTest(pt, item, col);
|
||||||
if (!item)
|
if (!item)
|
||||||
#ifdef __WXOSX__ // #ys_FIXME temporary workaround for OSX
|
#ifdef __WXOSX__ // #ys_FIXME temporary workaround for OSX
|
||||||
@ -730,9 +266,7 @@ void object_ctrl_context_menu()
|
|||||||
#else
|
#else
|
||||||
return;
|
return;
|
||||||
#endif // __WXOSX__
|
#endif // __WXOSX__
|
||||||
// printf("item exists\n");
|
|
||||||
const wxString title = col->GetTitle();
|
const wxString title = col->GetTitle();
|
||||||
// printf("title = *%s*\n", title.data().AsChar());
|
|
||||||
|
|
||||||
if (title == " ")
|
if (title == " ")
|
||||||
show_context_menu();
|
show_context_menu();
|
||||||
@ -1472,29 +1006,6 @@ void parts_changed(int obj_idx)
|
|||||||
e.SetString(event_str);
|
e.SetString(event_str);
|
||||||
// get_main_frame()->ProcessWindowEvent(e); // #ys_FIXME
|
// 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()
|
void part_selection_changed()
|
||||||
{
|
{
|
||||||
@ -1549,7 +1060,7 @@ void part_selection_changed()
|
|||||||
|
|
||||||
m_selected_object_id = obj_idx;
|
m_selected_object_id = obj_idx;
|
||||||
|
|
||||||
update_settings_value();
|
// update_values();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_extruder_column_hidden(bool hide)
|
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)
|
void set_uniform_scaling(const bool uniform_scale)
|
||||||
{
|
{
|
||||||
g_is_uniform_scale = uniform_scale;
|
g_is_uniform_scale = uniform_scale;
|
||||||
@ -1792,20 +1160,6 @@ void on_drop(wxDataViewEvent &event)
|
|||||||
g_prevent_list_events = false;
|
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)
|
void create_double_slider(wxWindow* parent, wxBoxSizer* sizer, wxGLCanvas* canvas)
|
||||||
{
|
{
|
||||||
m_slider = new PrusaDoubleSlider(parent, wxID_ANY, 0, 0, 0, 100);
|
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 parts_changed(int obj_idx);
|
||||||
void part_selection_changed();
|
void part_selection_changed();
|
||||||
|
|
||||||
void update_settings_value();
|
|
||||||
// show/hide "Extruder" column for Objects List
|
// show/hide "Extruder" column for Objects List
|
||||||
void set_extruder_column_hidden(bool hide);
|
void set_extruder_column_hidden(bool hide);
|
||||||
// update extruder in current config
|
// update extruder in current config
|
||||||
void update_extruder_in_config(const wxString& selection);
|
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 set_uniform_scaling(const bool uniform_scale);
|
||||||
|
|
||||||
void on_begin_drag(wxDataViewEvent &event);
|
void on_begin_drag(wxDataViewEvent &event);
|
||||||
|
@ -274,7 +274,7 @@ void MainFrame::create_preset_tabs()
|
|||||||
|
|
||||||
void MainFrame::add_created_tab(Tab* panel)
|
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.
|
// Load the currently selected preset into the GUI, update the preset selection box.
|
||||||
panel->load_current_preset();
|
panel->load_current_preset();
|
||||||
|
@ -231,6 +231,7 @@ public:
|
|||||||
bool m_full_labels {0};
|
bool m_full_labels {0};
|
||||||
t_opt_map m_opt_map;
|
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);
|
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*/{
|
Line create_single_option_line(const std::string& title, int idx = -1) /*const*/{
|
||||||
Option option = get_option(title, idx);
|
Option option = get_option(title, idx);
|
||||||
|
@ -27,10 +27,11 @@
|
|||||||
#include "libslic3r/Polygon.hpp"
|
#include "libslic3r/Polygon.hpp"
|
||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
|
#include "GUI_ObjectList.hpp"
|
||||||
|
#include "GUI_ObjectManipulation.hpp"
|
||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
#include "3DScene.hpp"
|
#include "3DScene.hpp"
|
||||||
#include "GLCanvas3D.hpp"
|
#include "GLCanvas3D.hpp"
|
||||||
#include "GUI_ObjectParts.hpp"
|
|
||||||
#include "GLToolbar.hpp"
|
#include "GLToolbar.hpp"
|
||||||
#include "GUI_Preview.hpp"
|
#include "GUI_Preview.hpp"
|
||||||
#include "Tab.hpp"
|
#include "Tab.hpp"
|
||||||
@ -200,6 +201,141 @@ PresetComboBox::PresetComboBox(wxWindow *parent, Preset::Type preset_type) :
|
|||||||
PresetComboBox::~PresetComboBox() {}
|
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
|
// Sidebar / private
|
||||||
|
|
||||||
struct Sidebar::priv
|
struct Sidebar::priv
|
||||||
@ -216,6 +352,9 @@ struct Sidebar::priv
|
|||||||
PresetComboBox *combo_printer;
|
PresetComboBox *combo_printer;
|
||||||
|
|
||||||
wxBoxSizer *sizer_params;
|
wxBoxSizer *sizer_params;
|
||||||
|
FreqChangedParams *frequently_changed_parameters;
|
||||||
|
ObjectList *object_list;
|
||||||
|
ObjectManipulation *object_manipulation;
|
||||||
ObjectInfo *object_info;
|
ObjectInfo *object_info;
|
||||||
SlicedInfo *sliced_info;
|
SlicedInfo *sliced_info;
|
||||||
|
|
||||||
@ -225,10 +364,6 @@ struct Sidebar::priv
|
|||||||
wxButton *btn_send_gcode;
|
wxButton *btn_send_gcode;
|
||||||
|
|
||||||
std::vector <std::shared_ptr<ConfigOptionsGroup>> optgroups {};
|
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_sla_material, _(L("SLA material")), Preset::TYPE_SLA_MATERIAL, false);
|
||||||
init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false);
|
init_combo(&p->combo_printer, _(L("Printer")), Preset::TYPE_PRINTER, false);
|
||||||
|
|
||||||
|
// calculate width of the preset labels
|
||||||
p->sizer_presets->Layout();
|
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
|
// Frequently changed parameters
|
||||||
p->sizer_params = new wxBoxSizer(wxVERTICAL);
|
p->frequently_changed_parameters = new FreqChangedParams(p->scrolled, label_width);
|
||||||
add_frequently_changed_parameters(p->scrolled, p->sizer_params/*, p->sizer_presets*/);
|
p->sizer_params->Add(p->frequently_changed_parameters->get_sizer(), 0, wxEXPAND | wxBOTTOM | wxLEFT, 2);
|
||||||
|
|
||||||
// Object List
|
// 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
|
// 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
|
// Buttons in the scrolled area
|
||||||
wxBitmap arrow_up(GUI::from_u8(Slic3r::var("brick_go.png")), wxBITMAP_TYPE_PNG);
|
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});
|
// wxTheApp->{preset_bundle}->export_selections(wxTheApp->{app_config});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectManipulation* Sidebar::obj_manipul()
|
||||||
|
{
|
||||||
|
return p->object_manipulation;
|
||||||
|
}
|
||||||
|
|
||||||
ConfigOptionsGroup* Sidebar::get_optgroup(size_t i)
|
ConfigOptionsGroup* Sidebar::get_optgroup(size_t i)
|
||||||
{
|
{
|
||||||
return p->optgroups.empty() ? nullptr : p->optgroups[i].get();
|
return p->optgroups.empty() ? nullptr : p->optgroups[i].get();
|
||||||
@ -375,7 +523,17 @@ t_optgroups& Sidebar::get_optgroups() {
|
|||||||
|
|
||||||
wxButton* Sidebar::get_wiping_dialog_button()
|
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;
|
wxNotebook *notebook;
|
||||||
Sidebar *sidebar;
|
Sidebar *sidebar;
|
||||||
wxGLCanvas *canvas3D; // TODO: Use GLCanvas3D when we can
|
wxGLCanvas *canvas3D; // TODO: Use GLCanvas3D when we can
|
||||||
GUI::Preview *preview;
|
Preview *preview;
|
||||||
BackgroundSlicingProcess background_process;
|
BackgroundSlicingProcess background_process;
|
||||||
|
|
||||||
static const int gl_attrs[];
|
static const int gl_attrs[];
|
||||||
@ -933,6 +1091,7 @@ Plater::~Plater()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Sidebar& Plater::sidebar() { return *p->sidebar; }
|
Sidebar& Plater::sidebar() { return *p->sidebar; }
|
||||||
|
Model& Plater::model() { return p->model; }
|
||||||
|
|
||||||
std::string Plater::export_gcode(const std::string &output_path)
|
std::string Plater::export_gcode(const std::string &output_path)
|
||||||
{
|
{
|
||||||
|
@ -4,17 +4,18 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
#include <wx/scrolwin.h>
|
|
||||||
|
|
||||||
#include "Preset.hpp"
|
#include "Preset.hpp"
|
||||||
|
|
||||||
class wxBoxSizer;
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class Model;
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
class MainFrame;
|
class MainFrame;
|
||||||
class ConfigOptionsGroup;
|
class ConfigOptionsGroup;
|
||||||
|
class ObjectManipulation;
|
||||||
|
|
||||||
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
|
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
|
||||||
|
|
||||||
@ -30,14 +31,14 @@ public:
|
|||||||
|
|
||||||
void update_presets(Slic3r::Preset::Type preset_type);
|
void update_presets(Slic3r::Preset::Type preset_type);
|
||||||
|
|
||||||
void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer);
|
ObjectManipulation* obj_manipul();
|
||||||
void add_objects_list(wxWindow* parent, wxBoxSizer* sizer);
|
|
||||||
void add_object_settings(wxWindow* parent, wxBoxSizer* sizer, t_optgroups& optgroups);
|
|
||||||
|
|
||||||
|
ConfigOptionsGroup* get_optgroup(size_t i); // #ys_FIXME_for_delete
|
||||||
ConfigOptionsGroup* get_optgroup(size_t i);
|
t_optgroups& get_optgroups();// #ys_FIXME_for_delete
|
||||||
t_optgroups& get_optgroups();
|
|
||||||
wxButton* get_wiping_dialog_button();
|
wxButton* get_wiping_dialog_button();
|
||||||
|
void update_objects_list_extruder_column(int extruders_count);
|
||||||
|
int get_ol_selection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct priv;
|
struct priv;
|
||||||
std::unique_ptr<priv> p;
|
std::unique_ptr<priv> p;
|
||||||
@ -57,6 +58,7 @@ public:
|
|||||||
~Plater();
|
~Plater();
|
||||||
|
|
||||||
Sidebar& sidebar();
|
Sidebar& sidebar();
|
||||||
|
Model& model();
|
||||||
|
|
||||||
// TODO: use fs::path
|
// TODO: use fs::path
|
||||||
// Note: empty string means request default path
|
// Note: empty string means request default path
|
||||||
|
@ -33,9 +33,9 @@
|
|||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
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.
|
// Vertical sizer to hold the choice menu and the rest of the page.
|
||||||
#ifdef __WXOSX__
|
#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
|
// Show/hide the 'purging volumes' button
|
||||||
void Tab::update_wiping_button_visibility() {
|
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
|
return; // ys_FIXME
|
||||||
bool wipe_tower_enabled = dynamic_cast<ConfigOptionBool*>( (m_preset_bundle->prints.get_edited_preset().config ).option("wipe_tower"))->value;
|
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;
|
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()
|
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
|
return; // ys_FIXME
|
||||||
|
|
||||||
Freeze();
|
Freeze();
|
||||||
@ -1410,7 +1410,7 @@ void TabFilament::reload_config(){
|
|||||||
|
|
||||||
void TabFilament::update()
|
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
|
return; // ys_FIXME
|
||||||
|
|
||||||
Freeze();
|
Freeze();
|
||||||
@ -1842,7 +1842,8 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){
|
|||||||
build_extruder_pages();
|
build_extruder_pages();
|
||||||
reload_config();
|
reload_config();
|
||||||
on_value_change("extruders_count", extruders_count);
|
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)
|
void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key)
|
||||||
@ -3030,7 +3031,7 @@ void TabSLAMaterial::build()
|
|||||||
|
|
||||||
void TabSLAMaterial::update()
|
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
|
return; // ys_FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ public:
|
|||||||
void set_event_value_change(wxEventType evt) { m_event_value_change = evt; }
|
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 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 load_current_preset();
|
||||||
void rebuild_page_tree(bool tree_sel_change_event = false);
|
void rebuild_page_tree(bool tree_sel_change_event = false);
|
||||||
void select_preset(std::string preset_name = "");
|
void select_preset(std::string preset_name = "");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user