mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-18 14:21:12 -06:00
Merge branch 'main' into enh-port-edit-gcode-dlg
This commit is contained in:
commit
11fd73a90d
34 changed files with 2622 additions and 745 deletions
|
@ -33,17 +33,29 @@ wxDEFINE_EVENT(EVT_AUXILIARY_IMPORT, wxCommandEvent);
|
|||
wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_COVER, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_DELETE, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_AUXILIARY_UPDATE_RENAME, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_AUXILIARY_DONE, wxCommandEvent);
|
||||
|
||||
|
||||
const std::vector<std::string> license_list = {
|
||||
"BSD License",
|
||||
"Apache License",
|
||||
"GPL License",
|
||||
"LGPL License",
|
||||
"MIT License",
|
||||
"CC License"
|
||||
"",
|
||||
"CC0",
|
||||
"BY",
|
||||
"BY-SA",
|
||||
"BY-ND",
|
||||
"BY-NC",
|
||||
"BY-NC-SA",
|
||||
"BY-NC-ND",
|
||||
};
|
||||
|
||||
static std::shared_ptr<ModelInfo> ensure_model_info()
|
||||
{
|
||||
auto& model = wxGetApp().plater()->model();
|
||||
if (model.model_info == nullptr) {
|
||||
model.model_info = std::make_shared<ModelInfo>();
|
||||
}
|
||||
return model.model_info;
|
||||
}
|
||||
|
||||
AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, AuxiliaryFolderType type, wxWindowID id, const wxPoint &pos, const wxSize &size, long style)
|
||||
{
|
||||
m_type = type;
|
||||
|
@ -344,7 +356,7 @@ void AuFile::on_input_enter(wxCommandEvent &evt)
|
|||
}
|
||||
|
||||
auto existing = false;
|
||||
auto dir = m_file_path.branch_path();
|
||||
auto dir = m_file_path.parent_path();
|
||||
auto new_fullname = new_file_name + m_file_path.extension().string();
|
||||
|
||||
|
||||
|
@ -454,14 +466,12 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt)
|
|||
|
||||
void AuFile::on_set_cover()
|
||||
{
|
||||
if (wxGetApp().plater()->model().model_info == nullptr) { wxGetApp().plater()->model().model_info = std::make_shared<ModelInfo>(); }
|
||||
|
||||
fs::path path(into_path(m_file_name));
|
||||
wxGetApp().plater()->model().model_info->cover_file = path.string();
|
||||
ensure_model_info()->cover_file = path.string();
|
||||
//wxGetApp().plater()->model().model_info->cover_file = m_file_name.ToStdString();
|
||||
|
||||
auto full_path = m_file_path.branch_path();
|
||||
auto full_root_path = full_path.branch_path();
|
||||
auto full_path = m_file_path.parent_path();
|
||||
auto full_root_path = full_path.parent_path();
|
||||
auto full_root_path_str = encode_path(full_root_path.string().c_str());
|
||||
auto dir = wxString::Format("%s/.thumbnails", full_root_path_str);
|
||||
|
||||
|
@ -505,8 +515,8 @@ void AuFile::on_set_delete()
|
|||
auto is_fine = fs::remove(bfs_path);
|
||||
|
||||
if (m_cover) {
|
||||
auto full_path = m_file_path.branch_path();
|
||||
auto full_root_path = full_path.branch_path();
|
||||
auto full_path = m_file_path.parent_path();
|
||||
auto full_root_path = full_path.parent_path();
|
||||
auto full_root_path_str = encode_path(full_root_path.string().c_str());
|
||||
auto dir = wxString::Format("%s/.thumbnails", full_root_path_str);
|
||||
fs::path dir_path(dir.ToStdWstring());
|
||||
|
@ -520,8 +530,11 @@ void AuFile::on_set_delete()
|
|||
if (fs::exists(fs::path(middle_img_path))) { fs::remove(fs::path(middle_img_path)); }
|
||||
}
|
||||
|
||||
if (wxGetApp().plater()->model().model_info == nullptr) { wxGetApp().plater()->model().model_info = std::make_shared<ModelInfo>(); }
|
||||
if (wxGetApp().plater()->model().model_info->cover_file == m_file_name) { wxGetApp().plater()->model().model_info->cover_file = ""; }
|
||||
if (wxGetApp().plater()->model().model_info != nullptr) {
|
||||
if (wxGetApp().plater()->model().model_info->cover_file == m_file_name) {
|
||||
wxGetApp().plater()->model().model_info->cover_file = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (is_fine) {
|
||||
auto evt = wxCommandEvent(EVT_AUXILIARY_UPDATE_DELETE);
|
||||
|
@ -669,6 +682,7 @@ void AuFolderPanel::update(std::vector<fs::path> paths)
|
|||
}
|
||||
m_gsizer_content->Layout();
|
||||
Layout();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void AuFolderPanel::msw_rescale()
|
||||
|
@ -820,9 +834,22 @@ void AuxiliaryPanel::init_bitmap()
|
|||
|
||||
void AuxiliaryPanel::init_tabpanel()
|
||||
{
|
||||
auto m_side_tools = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(220), FromDIP(18)));
|
||||
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Disabled),
|
||||
std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
|
||||
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal));
|
||||
auto back_btn = new Button(this, _L("Back"), "assemble_return", wxBORDER_NONE | wxBU_LEFT | wxBU_EXACTFIT);
|
||||
back_btn->SetSize(wxSize(FromDIP(220), FromDIP(18)));
|
||||
back_btn->SetBackgroundColor(btn_bg_green);
|
||||
back_btn->SetCornerRadius(0);
|
||||
back_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxEvent& e) {
|
||||
auto event = wxCommandEvent(EVT_AUXILIARY_DONE);
|
||||
event.SetEventObject(m_parent);
|
||||
wxPostEvent(m_parent, event);
|
||||
});
|
||||
|
||||
wxBoxSizer *sizer_side_tools = new wxBoxSizer(wxVERTICAL);
|
||||
sizer_side_tools->Add(m_side_tools, 1, wxEXPAND, 0);
|
||||
sizer_side_tools->Add(back_btn, 1, wxEXPAND, 0);
|
||||
m_tabpanel = new Tabbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, sizer_side_tools, wxNB_LEFT | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
|
||||
m_tabpanel->SetBackgroundColour(wxColour("#FEFFFF"));
|
||||
m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent &e) { ; });
|
||||
|
@ -872,20 +899,7 @@ bool AuxiliaryPanel::Show(bool show) { return wxPanel::Show(show); }
|
|||
void AuxiliaryPanel::init_auxiliary()
|
||||
{
|
||||
Model &model = wxGetApp().plater()->model();
|
||||
m_root_dir = encode_path(model.get_auxiliary_file_temp_path().c_str());
|
||||
if (wxDirExists(m_root_dir)) {
|
||||
fs::path path_to_del(m_root_dir.ToStdWstring());
|
||||
try {
|
||||
fs::remove_all(path_to_del);
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory " << m_root_dir.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
fs::path top_dir_path(m_root_dir.ToStdWstring());
|
||||
fs::create_directory(top_dir_path);
|
||||
|
||||
for (auto folder : s_default_folders) create_folder(folder);
|
||||
Reload(encode_path(model.get_auxiliary_file_temp_path().c_str()), {});
|
||||
}
|
||||
|
||||
void AuxiliaryPanel::on_import_file(wxCommandEvent &event)
|
||||
|
@ -947,7 +961,7 @@ void AuxiliaryPanel::on_import_file(wxCommandEvent &event)
|
|||
|
||||
|
||||
boost::system::error_code ec;
|
||||
if (!fs::copy_file(src_bfs_path, fs::path(dir_path.ToStdWstring()), fs::copy_option::overwrite_if_exists, ec)) continue;
|
||||
if (!fs::copy_file(src_bfs_path, fs::path(dir_path.ToStdWstring()), fs::copy_options::overwrite_existing, ec)) continue;
|
||||
Slic3r::put_other_changes();
|
||||
|
||||
// add in file list
|
||||
|
@ -987,76 +1001,22 @@ std::string AuxiliaryPanel::replaceSpace(std::string s, std::string ts, std::str
|
|||
return s;
|
||||
}
|
||||
|
||||
void AuxiliaryPanel::Reload(wxString aux_path)
|
||||
void AuxiliaryPanel::Reload(wxString aux_path, std::map<std::string, std::vector<json>> paths)
|
||||
{
|
||||
fs::path new_aux_path(aux_path.ToStdWstring());
|
||||
|
||||
try {
|
||||
fs::remove_all(fs::path(m_root_dir.ToStdWstring()));
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory " << m_root_dir.c_str();
|
||||
}
|
||||
|
||||
m_root_dir = aux_path;
|
||||
m_paths_list.clear();
|
||||
// Check new path. If not exist, create a new one.
|
||||
if (!fs::exists(new_aux_path)) {
|
||||
fs::create_directory(new_aux_path);
|
||||
// Create default folders if they are not loaded
|
||||
for (auto folder : s_default_folders) {
|
||||
wxString folder_path = aux_path + "/" + folder;
|
||||
if (fs::exists(folder_path.ToStdWstring())) continue;
|
||||
fs::create_directory(folder_path.ToStdWstring());
|
||||
|
||||
for (const auto & path : paths) {
|
||||
m_paths_list[path.first] = std::vector<fs::path>{};
|
||||
for (const auto & j : path.second) {
|
||||
m_paths_list[path.first].push_back(j["_filepath"]);
|
||||
}
|
||||
update_all_panel();
|
||||
m_designer_panel->update_info();
|
||||
return;
|
||||
}
|
||||
|
||||
// Load from new path
|
||||
std::vector<fs::path> dir_cache;
|
||||
fs::directory_iterator iter_end;
|
||||
|
||||
for (fs::directory_iterator iter(new_aux_path); iter != iter_end; iter++) {
|
||||
wxString path = iter->path().generic_wstring();
|
||||
dir_cache.push_back(iter->path());
|
||||
}
|
||||
|
||||
for (auto dir : dir_cache) {
|
||||
for (fs::directory_iterator iter(dir); iter != iter_end; iter++) {
|
||||
if (fs::is_directory(iter->path())) continue;
|
||||
wxString file_path = iter->path().generic_wstring();
|
||||
//auto file_path_str = encode_path(file_path.c_str());
|
||||
|
||||
for (auto folder : s_default_folders) {
|
||||
auto idx = file_path.find(folder.ToStdString());
|
||||
if (idx != std::string::npos) {
|
||||
auto iter = m_paths_list.find(folder.ToStdString());
|
||||
auto file_path_str = fs::path(file_path.ToStdWstring());
|
||||
|
||||
if (iter != m_paths_list.end()) {
|
||||
m_paths_list[folder.ToStdString()].push_back(file_path_str);
|
||||
break;
|
||||
} else {
|
||||
m_paths_list[folder.ToStdString()] = std::vector<fs::path>{file_path_str};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create default folders if they are not loaded
|
||||
wxDataViewItemArray default_items;
|
||||
for (auto folder : s_default_folders) {
|
||||
wxString folder_path = aux_path + "/" + folder;
|
||||
if (fs::exists(folder_path.ToStdWstring())) continue;
|
||||
fs::create_directory(folder_path.ToStdWstring());
|
||||
}
|
||||
|
||||
update_all_panel();
|
||||
update_all_cover();
|
||||
m_designer_panel->update_info();
|
||||
m_tabpanel->SetSelection(0);
|
||||
}
|
||||
|
||||
void AuxiliaryPanel::update_all_panel()
|
||||
|
@ -1121,22 +1081,21 @@ void AuxiliaryPanel::update_all_cover()
|
|||
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
|
||||
m_sizer_model_name->Add(m_imput_model_name, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
/*
|
||||
wxBoxSizer *m_sizer_license = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto m_text_license = new wxStaticText(this, wxID_ANY, _L("License"), wxDefaultPosition, wxSize(120, -1), 0);
|
||||
auto m_text_license = new wxStaticText(this, wxID_ANY, _L("License"), wxDefaultPosition, wxSize(180, -1), 0);
|
||||
m_text_license->Wrap(-1);
|
||||
m_sizer_license->Add(m_text_license, 0, wxALIGN_CENTER, 0);
|
||||
|
||||
m_combo_license = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(450, -1), 0, NULL, wxCB_READONLY);
|
||||
m_combo_license = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(450), -1), 0, NULL, wxCB_READONLY);
|
||||
m_sizer_license->Add(m_combo_license, 0, wxALIGN_CENTER, 0);
|
||||
*/
|
||||
|
||||
m_sizer_body->Add( 0, 0, 0, wxTOP, FromDIP(50) );
|
||||
m_sizer_body->Add(m_sizer_designer, 0, wxLEFT, FromDIP(50));
|
||||
m_sizer_body->Add( 0, 0, 0, wxTOP, FromDIP(20));
|
||||
m_sizer_body->Add(m_sizer_model_name, 0, wxLEFT, FromDIP(50));
|
||||
//m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20));
|
||||
//m_sizer_body->Add(m_sizer_license, 0, wxLEFT, FromDIP(50));
|
||||
//init_license_list();
|
||||
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(20));
|
||||
m_sizer_body->Add(m_sizer_license, 0, wxLEFT, FromDIP(50));
|
||||
init_license_list();
|
||||
|
||||
SetSizer(m_sizer_body);
|
||||
Layout();
|
||||
|
@ -1144,52 +1103,35 @@ void AuxiliaryPanel::update_all_cover()
|
|||
|
||||
m_input_designer->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_designer, this);
|
||||
m_imput_model_name->Bind(wxEVT_TEXT, &DesignerPanel::on_input_enter_model, this);
|
||||
//m_combo_license->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(DesignerPanel::on_select_license), NULL, this);
|
||||
m_combo_license->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DesignerPanel::on_select_license, this);
|
||||
}
|
||||
|
||||
DesignerPanel::~DesignerPanel()
|
||||
{
|
||||
//m_combo_license->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(DesignerPanel::on_select_license), NULL, this);
|
||||
}
|
||||
|
||||
void DesignerPanel::init_license_list()
|
||||
{
|
||||
/*
|
||||
wxArrayString text_licese;
|
||||
for (int i = 0; i < license_list.size(); i++) {
|
||||
text_licese.Add(license_list[i]);
|
||||
}
|
||||
m_combo_license->Set(text_licese);
|
||||
*/
|
||||
}
|
||||
|
||||
void DesignerPanel::on_select_license(wxCommandEvent&evt)
|
||||
{
|
||||
int selected = evt.GetInt();
|
||||
if (selected >= 0 && selected < license_list.size()) {
|
||||
if (wxGetApp().plater()->model().model_info == nullptr) {
|
||||
wxGetApp().plater()->model().model_info = std::make_shared<ModelInfo>();
|
||||
}
|
||||
if (wxGetApp().plater()->model().model_info != nullptr) {
|
||||
wxGetApp().plater()->model().model_info->license = license_list[selected];
|
||||
}
|
||||
ensure_model_info()->license = license_list[selected];
|
||||
}
|
||||
}
|
||||
|
||||
bool DesignerPanel::Show(bool show)
|
||||
{
|
||||
if ( wxGetApp().plater()->model().design_info != nullptr) {
|
||||
wxString text = wxString::FromUTF8(wxGetApp().plater()->model().design_info->Designer);
|
||||
m_input_designer->GetTextCtrl()->SetValue(text);
|
||||
}
|
||||
|
||||
if (wxGetApp().plater()->model().model_info != nullptr) {
|
||||
wxString text = wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name);
|
||||
m_imput_model_name->GetTextCtrl()->SetValue(text);
|
||||
}
|
||||
|
||||
return wxPanel::Show(show);
|
||||
}
|
||||
bool DesignerPanel::Show(bool show)
|
||||
{
|
||||
if (show) update_info();
|
||||
return wxPanel::Show(show);
|
||||
}
|
||||
|
||||
void DesignerPanel::on_input_enter_designer(wxCommandEvent &evt)
|
||||
{
|
||||
|
@ -1200,9 +1142,7 @@ void DesignerPanel::on_input_enter_designer(wxCommandEvent &evt)
|
|||
void DesignerPanel::on_input_enter_model(wxCommandEvent &evt)
|
||||
{
|
||||
auto text = evt.GetString();
|
||||
if (wxGetApp().plater()->model().model_info) {
|
||||
wxGetApp().plater()->model().model_info->model_name = std::string(text.ToUTF8().data());
|
||||
}
|
||||
ensure_model_info()->model_name = std::string(text.ToUTF8().data());
|
||||
}
|
||||
|
||||
void DesignerPanel::update_info()
|
||||
|
@ -1215,10 +1155,13 @@ void DesignerPanel::update_info()
|
|||
}
|
||||
|
||||
if (wxGetApp().plater()->model().model_info != nullptr) {
|
||||
wxString text = wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name);
|
||||
m_imput_model_name->GetTextCtrl()->SetValue(text);
|
||||
m_imput_model_name->GetTextCtrl()->SetValue(wxString::FromUTF8(wxGetApp().plater()->model().model_info->model_name));
|
||||
if (!m_combo_license->SetStringSelection(wxString::FromUTF8(wxGetApp().plater()->model().model_info->license))) {
|
||||
m_combo_license->SetSelection(0);
|
||||
}
|
||||
} else {
|
||||
m_imput_model_name->GetTextCtrl()->SetValue(wxEmptyString);
|
||||
m_imput_model_name->GetTextCtrl()->SetValue(wxEmptyString);
|
||||
m_combo_license->SetSelection(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1226,6 +1169,7 @@ void DesignerPanel::msw_rescale()
|
|||
{
|
||||
m_input_designer->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
|
||||
m_imput_model_name->GetTextCtrl()->SetSize(wxSize(FromDIP(450), -1));
|
||||
m_combo_license->SetSize(wxSize(FromDIP(450), -1));
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
@ -181,7 +181,7 @@ public:
|
|||
|
||||
::TextInput* m_input_designer {nullptr};
|
||||
::TextInput* m_imput_model_name {nullptr};
|
||||
//wxComboBox* m_combo_license {nullptr};
|
||||
ComboBox* m_combo_license {nullptr};
|
||||
bool Show(bool show) override;
|
||||
void init_license_list();
|
||||
void on_input_enter_designer(wxCommandEvent &evt);
|
||||
|
@ -232,7 +232,7 @@ public:
|
|||
void create_folder(wxString name = wxEmptyString);
|
||||
std::string replaceSpace(std::string s, std::string ts, std::string ns);
|
||||
void on_import_file(wxCommandEvent &event);
|
||||
void Reload(wxString aux_path);
|
||||
void Reload(wxString aux_path, std::map<std::string, std::vector<json>> paths);
|
||||
|
||||
void update_all_panel();
|
||||
void update_all_cover();
|
||||
|
@ -242,6 +242,7 @@ wxDECLARE_EVENT(EVT_AUXILIARY_IMPORT, wxCommandEvent);
|
|||
wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_COVER, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_DELETE, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_AUXILIARY_UPDATE_RENAME, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_AUXILIARY_DONE, wxCommandEvent);
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
||||
|
|
|
@ -661,9 +661,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
for (auto el : { "ironing_pattern", "ironing_flow", "ironing_spacing", "ironing_speed", "ironing_angle" })
|
||||
toggle_line(el, has_ironing);
|
||||
|
||||
// bool have_sequential_printing = (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
|
||||
bool have_sequential_printing = (config->opt_enum<PrintSequence>("print_sequence") == PrintSequence::ByObject);
|
||||
// for (auto el : { "extruder_clearance_radius", "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid" })
|
||||
// toggle_field(el, have_sequential_printing);
|
||||
toggle_field("print_order", !have_sequential_printing);
|
||||
|
||||
bool have_ooze_prevention = config->opt_bool("ooze_prevention");
|
||||
toggle_field("standby_temperature_delta", have_ooze_prevention);
|
||||
|
@ -742,6 +743,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
apply(config, &new_conf);
|
||||
}
|
||||
toggle_line("timelapse_type", is_BBL_Printer);
|
||||
|
||||
|
||||
bool have_small_area_infill_flow_compensation = config->opt_bool("small_area_infill_flow_compensation");
|
||||
toggle_line("small_area_infill_flow_compensation_model", have_small_area_infill_flow_compensation);
|
||||
}
|
||||
|
||||
void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/)
|
||||
|
|
|
@ -7304,10 +7304,10 @@ void GLCanvas3D::_render_overlays()
|
|||
|
||||
auto curr_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
|
||||
auto curr_print_seq = curr_plate->get_real_print_seq();
|
||||
bool sequential_print = (curr_print_seq == PrintSequence::ByObject);
|
||||
const Print* print = fff_print();
|
||||
bool sequential_print = (curr_print_seq == PrintSequence::ByObject) || print->config().print_order == PrintOrder::AsObjectList;
|
||||
std::vector<const ModelInstance*> sorted_instances;
|
||||
if (sequential_print) {
|
||||
const Print* print = fff_print();
|
||||
if (print) {
|
||||
for (const PrintObject *print_object : print->objects())
|
||||
{
|
||||
|
|
|
@ -2656,7 +2656,7 @@ bool GUI_App::on_init_inner()
|
|||
|
||||
sidebar().obj_list()->init();
|
||||
//sidebar().aux_list()->init_auxiliary();
|
||||
//mainframe->m_auxiliary->init_auxiliary();
|
||||
mainframe->m_project->init_auxiliary();
|
||||
|
||||
// update_mode(); // !!! do that later
|
||||
SetTopWindow(mainframe);
|
||||
|
|
|
@ -1545,26 +1545,6 @@ void ObjectList::OnBeginDrag(wxDataViewEvent &event)
|
|||
}
|
||||
|
||||
if (type & itObject) {
|
||||
int curr_obj_id = m_objects_model->GetIdByItem(event.GetItem());
|
||||
PartPlateList& partplate_list = wxGetApp().plater()->get_partplate_list();
|
||||
int from_plate = partplate_list.find_instance(curr_obj_id, 0);
|
||||
if (from_plate == -1) {
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
auto curr_plate_seq = partplate_list.get_plate(from_plate)->get_print_seq();
|
||||
if (curr_plate_seq == PrintSequence::ByDefault) {
|
||||
auto curr_preset_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
if (curr_preset_config.has("print_sequence"))
|
||||
curr_plate_seq = curr_preset_config.option<ConfigOptionEnum<PrintSequence>>("print_sequence")->value;
|
||||
}
|
||||
|
||||
if (curr_plate_seq != PrintSequence::ByObject) {
|
||||
//drag forbidden under bylayer mode
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
|
||||
m_dragged_data.init(m_objects_model->GetIdByItem(item), type);
|
||||
}
|
||||
else if (type & itVolume){
|
||||
|
|
|
@ -717,7 +717,12 @@ bool GLGizmoCut3D::render_reset_button(const std::string& label_id, const std::s
|
|||
|
||||
static double get_grabber_mean_size(const BoundingBoxf3& bb)
|
||||
{
|
||||
#if ENABLE_FIXED_GRABBER
|
||||
// Orca: make grabber larger
|
||||
return 32. * GLGizmoBase::INV_ZOOM;
|
||||
#else
|
||||
return (bb.size().x() + bb.size().y() + bb.size().z()) / 30.;
|
||||
#endif
|
||||
}
|
||||
|
||||
indexed_triangle_set GLGizmoCut3D::its_make_groove_plane()
|
||||
|
@ -2503,13 +2508,13 @@ void GLGizmoCut3D::add_horizontal_shift(float shift)
|
|||
|
||||
void GLGizmoCut3D::render_color_marker(float size, const ImU32& color)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
const float radius = 0.5f * size;
|
||||
ImVec2 pos = ImGui::GetCurrentWindow()->DC.CursorPos;
|
||||
pos.x += size;
|
||||
pos.y += 1.25f * radius;
|
||||
pos.x += radius;
|
||||
pos.y += 1.4f * radius;
|
||||
ImGui::GetCurrentWindow()->DrawList->AddNgonFilled(pos, radius, color, 6);
|
||||
m_imgui->text(" ");
|
||||
m_imgui->text(" ");
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_groove_float_input(const std::string& label, float& in_val, const float& init_val, float& in_tolerance)
|
||||
|
@ -2730,20 +2735,27 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors, floa
|
|||
|
||||
// render "After Cut" section
|
||||
|
||||
float label_width = 0;
|
||||
ImVec2 label_size;
|
||||
for (const wxString &label : {_L("Upper part"), _L("Lower part")}) {
|
||||
const float width = m_imgui->calc_text_size(label).x + m_imgui->scaled(1.5f);
|
||||
if (label_width < width)
|
||||
label_width = width;
|
||||
const ImVec2 text_size = ImGuiWrapper::calc_text_size(label);
|
||||
if (label_size.x < text_size.x)
|
||||
label_size.x = text_size.x;
|
||||
if (label_size.y < text_size.y)
|
||||
label_size.y = text_size.y;
|
||||
}
|
||||
|
||||
auto render_part_action_line = [this, label_width, &connectors](const wxString &label, const wxString &suffix, bool &keep_part,
|
||||
const float marker_size = label_size.y;
|
||||
const float h_shift = marker_size + label_size.x + m_imgui->scaled(2.f);
|
||||
|
||||
auto render_part_action_line = [this, h_shift, marker_size, &connectors](const wxString &label, const wxString &suffix, bool &keep_part,
|
||||
bool &place_on_cut_part, bool &rotate_part) {
|
||||
bool keep = true;
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
render_color_marker(marker_size, ImGuiWrapper::to_ImU32(suffix == "##upper" ? UPPER_PART_COLOR : LOWER_PART_COLOR));
|
||||
m_imgui->text(label);
|
||||
|
||||
ImGui::SameLine(label_width);
|
||||
ImGui::SameLine(h_shift);
|
||||
|
||||
m_imgui->disabled_begin(!connectors.empty() || m_keep_as_parts);
|
||||
m_imgui->bbl_checkbox(_L("Keep") + suffix, connectors.empty() ? keep_part : keep);
|
||||
|
|
|
@ -51,6 +51,7 @@ static unsigned int GLOBAL_PLATE_INDEX = 0;
|
|||
|
||||
static const double LOGICAL_PART_PLATE_GAP = 1. / 5.;
|
||||
static const int PARTPLATE_ICON_SIZE = 16;
|
||||
static const int PARTPLATE_EDIT_PLATE_NAME_ICON_SIZE = 12;
|
||||
static const int PARTPLATE_ICON_GAP_TOP = 3;
|
||||
static const int PARTPLATE_ICON_GAP_LEFT = 3;
|
||||
static const int PARTPLATE_ICON_GAP_Y = 5;
|
||||
|
@ -571,6 +572,42 @@ void PartPlate::calc_vertex_for_number(int index, bool one_number, GLModel &buff
|
|||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n";
|
||||
}
|
||||
|
||||
void PartPlate::calc_vertex_for_plate_name_edit_icon(GLTexture *texture, int index, PickingModel &model) {
|
||||
model.reset();
|
||||
|
||||
auto bed_ext = get_extents(m_shape);
|
||||
auto factor = bed_ext.size()(1) / 200.0;
|
||||
wxCoord w, h;
|
||||
h = int(factor * 16);
|
||||
ExPolygon poly;
|
||||
Vec2d p = bed_ext[3];
|
||||
float offset_x = 1;
|
||||
h = PARTPLATE_EDIT_PLATE_NAME_ICON_SIZE;
|
||||
p += Vec2d(0, PARTPLATE_TEXT_OFFSET_Y + h);
|
||||
if (texture && texture->get_width() > 0 && texture->get_height()) {
|
||||
w = int(factor * (texture->get_original_width() * 16) / texture->get_height()) + 1;
|
||||
|
||||
poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w), scale_(p(1) - h )});
|
||||
poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w + PARTPLATE_EDIT_PLATE_NAME_ICON_SIZE), scale_(p(1) - h)});
|
||||
poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w + PARTPLATE_EDIT_PLATE_NAME_ICON_SIZE), scale_(p(1))});
|
||||
poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w), scale_(p(1) )});
|
||||
|
||||
if (!init_model_from_poly(model.model, poly, GROUND_Z))
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n";
|
||||
} else {
|
||||
|
||||
poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x ), scale_(p(1) - h )});
|
||||
poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x + PARTPLATE_EDIT_PLATE_NAME_ICON_SIZE), scale_(p(1) - h)});
|
||||
poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x + PARTPLATE_EDIT_PLATE_NAME_ICON_SIZE), scale_(p(1))});
|
||||
poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) )});
|
||||
|
||||
if (!init_model_from_poly(model.model, poly, GROUND_Z))
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n";
|
||||
}
|
||||
|
||||
init_raycaster_from_model(model);
|
||||
}
|
||||
|
||||
void PartPlate::calc_vertex_for_icons(int index, PickingModel &model)
|
||||
{
|
||||
model.reset();
|
||||
|
@ -975,6 +1012,13 @@ void PartPlate::render_icons(bool bottom, bool only_name, int hover_id)
|
|||
render_icon_texture(m_lock_icon.model, m_partplate_list->m_lockopen_texture);
|
||||
}
|
||||
|
||||
if (hover_id == 6) {
|
||||
render_icon_texture(m_plate_name_edit_icon.model, m_partplate_list->m_plate_name_edit_hovered_texture);
|
||||
show_tooltip(_u8L("Edit current plate name"));
|
||||
}
|
||||
else
|
||||
render_icon_texture(m_plate_name_edit_icon.model, m_partplate_list->m_plate_name_edit_texture);
|
||||
|
||||
if (m_partplate_list->render_plate_settings) {
|
||||
if (hover_id == 5) {
|
||||
if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault && get_first_layer_print_sequence().empty())
|
||||
|
@ -1272,6 +1316,9 @@ void PartPlate::register_raycasters_for_picking(GLCanvas3D &canvas)
|
|||
register_model_for_picking(canvas, m_lock_icon, picking_id_component(4));
|
||||
if (m_partplate_list->render_plate_settings)
|
||||
register_model_for_picking(canvas, m_plate_settings_icon, picking_id_component(5));
|
||||
|
||||
canvas.remove_raycasters_for_picking(SceneRaycaster::EType::Bed, picking_id_component(6));
|
||||
register_model_for_picking(canvas, m_plate_name_edit_icon, picking_id_component(6));
|
||||
}
|
||||
|
||||
int PartPlate::picking_id_component(int idx) const
|
||||
|
@ -1781,7 +1828,12 @@ void PartPlate::generate_plate_name_texture()
|
|||
poly.contour.append({ scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) - PARTPLATE_TEXT_OFFSET_Y) });
|
||||
|
||||
if (!init_model_from_poly(m_plate_name_icon, poly, GROUND_Z))
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n";
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n";
|
||||
|
||||
auto canvas = this->m_partplate_list->m_plater->get_view3D_canvas3D();
|
||||
canvas->remove_raycasters_for_picking(SceneRaycaster::EType::Bed, picking_id_component(6));
|
||||
calc_vertex_for_plate_name_edit_icon(&m_name_texture, 0, m_plate_name_edit_icon);
|
||||
register_model_for_picking(*canvas, m_plate_name_edit_icon, picking_id_component(6));
|
||||
}
|
||||
void PartPlate::set_plate_name(const std::string& name)
|
||||
{
|
||||
|
@ -3124,6 +3176,20 @@ void PartPlateList::generate_icon_textures()
|
|||
}
|
||||
}
|
||||
|
||||
// if (m_plate_name_edit_texture.get_id() == 0)
|
||||
{
|
||||
file_name = path + (m_is_dark ? "plate_name_edit_dark.svg" : "plate_name_edit.svg");
|
||||
if (!m_plate_name_edit_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name;
|
||||
}
|
||||
}
|
||||
// if (m_plate_name_edit_hovered_texture.get_id() == 0)
|
||||
{
|
||||
file_name = path + (m_is_dark ? "plate_name_edit_hover_dark.svg" : "plate_name_edit_hover.svg");
|
||||
if (!m_plate_name_edit_hovered_texture.load_from_svg_file(file_name, true, false, false, icon_size)) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name;
|
||||
}
|
||||
}
|
||||
|
||||
std::string text_str = "01";
|
||||
wxFont* font = find_font(text_str,32);
|
||||
|
@ -3161,7 +3227,8 @@ void PartPlateList::release_icon_textures()
|
|||
m_plate_settings_texture.reset();
|
||||
m_plate_settings_texture.reset();
|
||||
m_plate_settings_hovered_texture.reset();
|
||||
|
||||
m_plate_name_edit_texture.reset();
|
||||
m_plate_name_edit_hovered_texture.reset();
|
||||
for (int i = 0;i < MAX_PLATE_COUNT; i++) {
|
||||
m_idx_textures[i].reset();
|
||||
}
|
||||
|
|
|
@ -138,6 +138,7 @@ private:
|
|||
PickingModel m_orient_icon;
|
||||
PickingModel m_lock_icon;
|
||||
PickingModel m_plate_settings_icon;
|
||||
PickingModel m_plate_name_edit_icon;
|
||||
GLModel m_plate_idx_icon;
|
||||
GLTexture m_texture;
|
||||
|
||||
|
@ -169,6 +170,7 @@ private:
|
|||
void calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox);
|
||||
void calc_height_limit();
|
||||
void calc_vertex_for_number(int index, bool one_number, GLModel &buffer);
|
||||
void calc_vertex_for_plate_name_edit_icon(GLTexture *texture, int index, PickingModel &model);
|
||||
void calc_vertex_for_icons(int index, PickingModel &model);
|
||||
// void calc_vertex_for_icons_background(int icon_count, GLModel &buffer);
|
||||
void render_background(bool force_default_color = false);
|
||||
|
|
|
@ -62,6 +62,11 @@ ProjectPanel::ProjectPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos,
|
|||
|
||||
Bind(EVT_PROJECT_RELOAD, &ProjectPanel::on_reload, this);
|
||||
|
||||
m_auxiliary = new AuxiliaryPanel(this);
|
||||
m_auxiliary->Hide();
|
||||
main_sizer->Add(m_auxiliary, wxSizerFlags().Expand().Proportion(1));
|
||||
Bind(EVT_AUXILIARY_DONE, [this](wxCommandEvent& e) { update_model_data();});
|
||||
|
||||
SetSizer(main_sizer);
|
||||
Layout();
|
||||
Fit();
|
||||
|
@ -91,38 +96,39 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
|
|||
std::string model_author;
|
||||
std::string cover_file;
|
||||
std::string description;
|
||||
std::map<std::string, std::vector<json>> files;
|
||||
|
||||
std::string p_name;
|
||||
std::string p_author;
|
||||
std::string p_description;
|
||||
std::string p_cover_file;
|
||||
|
||||
std::map<std::string, std::vector<json>> files;
|
||||
|
||||
Model model = wxGetApp().plater()->model();
|
||||
|
||||
license = model.model_info->license;
|
||||
model_name = model.model_info->model_name;
|
||||
cover_file = model.model_info->cover_file;
|
||||
description = model.model_info->description;
|
||||
update_type = model.model_info->origin;
|
||||
auto model_info = model.model_info;
|
||||
if (model_info != nullptr) {
|
||||
license = model_info->license;
|
||||
model_name = model_info->model_name;
|
||||
cover_file = model_info->cover_file;
|
||||
description = model_info->description;
|
||||
update_type = model_info->origin;
|
||||
|
||||
try {
|
||||
if (!model_info->copyright.empty()) {
|
||||
json copy_right = json::parse(model_info->copyright);
|
||||
|
||||
try {
|
||||
if (!model.model_info->copyright.empty()) {
|
||||
json copy_right = json::parse(model.model_info->copyright);
|
||||
|
||||
if (copy_right.is_array()) {
|
||||
for (auto it = copy_right.begin(); it != copy_right.end(); it++) {
|
||||
if ((*it).contains("author")) {
|
||||
model_author = (*it)["author"].get<std::string>();
|
||||
if (copy_right.is_array()) {
|
||||
for (auto it = copy_right.begin(); it != copy_right.end(); it++) {
|
||||
if ((*it).contains("author")) {
|
||||
model_author = (*it)["author"].get<std::string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
;
|
||||
}
|
||||
|
||||
if (model_author.empty() && model.design_info != nullptr)
|
||||
model_author = model.design_info->Designer;
|
||||
|
@ -134,12 +140,44 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
|
|||
p_author = model.profile_info->ProfileUserName;
|
||||
}
|
||||
|
||||
//file info
|
||||
// file info
|
||||
std::string file_path = encode_path(wxGetApp().plater()->model().get_auxiliary_file_temp_path().c_str());
|
||||
if (!file_path.empty()) {
|
||||
files = Reload(file_path);
|
||||
wxGetApp().CallAfter([this, file_path, files] { m_auxiliary->Reload(file_path, files); });
|
||||
} else {
|
||||
clear_model_info();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
||||
bool has_content = false;
|
||||
for (const string& v : {
|
||||
update_type,
|
||||
license,
|
||||
model_name,
|
||||
model_author,
|
||||
cover_file,
|
||||
description,
|
||||
p_name,
|
||||
p_author,
|
||||
p_description,
|
||||
p_cover_file,
|
||||
}) {
|
||||
if (!v.empty()) {
|
||||
has_content = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_content) {
|
||||
for (const auto & file : files) {
|
||||
if (!file.second.empty()) {
|
||||
has_content = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!has_content) {
|
||||
// Nothing to show, just return
|
||||
clear_model_info();
|
||||
return;
|
||||
}
|
||||
|
@ -180,6 +218,7 @@ void ProjectPanel::on_reload(wxCommandEvent& evt)
|
|||
|
||||
void ProjectPanel::msw_rescale()
|
||||
{
|
||||
m_auxiliary->msw_rescale();
|
||||
}
|
||||
|
||||
void ProjectPanel::on_size(wxSizeEvent &event)
|
||||
|
@ -215,6 +254,9 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt)
|
|||
else if (strCmd == "request_3mf_info") {
|
||||
m_web_init_completed = true;
|
||||
}
|
||||
else if (strCmd == "edit_project_info") {
|
||||
show_info_editor(true);
|
||||
}
|
||||
else if (strCmd == "debug_info") {
|
||||
//wxString msg = j["msg"];
|
||||
//OutputDebugString(wxString::Format("Model_Web: msg = %s \r\n", msg));
|
||||
|
@ -227,14 +269,24 @@ void ProjectPanel::OnScriptMessage(wxWebViewEvent& evt)
|
|||
}
|
||||
}
|
||||
|
||||
void ProjectPanel::show_info_editor(bool show)
|
||||
{
|
||||
m_browser->Show(!show);
|
||||
m_auxiliary->Show(show);
|
||||
Layout();
|
||||
}
|
||||
|
||||
void ProjectPanel::update_model_data()
|
||||
{
|
||||
Model model = wxGetApp().plater()->model();
|
||||
show_info_editor(false);
|
||||
clear_model_info();
|
||||
|
||||
m_auxiliary->init_auxiliary();
|
||||
|
||||
//basics info
|
||||
if (model.model_info == nullptr)
|
||||
return;
|
||||
//if (model.model_info == nullptr)
|
||||
// return;
|
||||
|
||||
auto event = wxCommandEvent(EVT_PROJECT_RELOAD);
|
||||
event.SetEventObject(this);
|
||||
|
@ -258,7 +310,6 @@ std::map<std::string, std::vector<json>> ProjectPanel::Reload(wxString aux_path)
|
|||
{
|
||||
std::vector<fs::path> dir_cache;
|
||||
fs::directory_iterator iter_end;
|
||||
wxString m_root_dir;
|
||||
std::map<std::string, std::vector<json>> m_paths_list;
|
||||
|
||||
const static std::array<wxString, 5> s_default_folders = {
|
||||
|
@ -276,24 +327,16 @@ std::map<std::string, std::vector<json>> ProjectPanel::Reload(wxString aux_path)
|
|||
|
||||
fs::path new_aux_path(aux_path.ToStdWstring());
|
||||
|
||||
try {
|
||||
fs::remove_all(fs::path(m_root_dir.ToStdWstring()));
|
||||
}
|
||||
catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed removing the auxiliary directory" << m_root_dir.c_str();
|
||||
}
|
||||
|
||||
m_root_dir = aux_path;
|
||||
// Check new path. If not exist, create a new one.
|
||||
if (!fs::exists(new_aux_path)) {
|
||||
fs::create_directory(new_aux_path);
|
||||
// Create default folders if they are not loaded
|
||||
for (auto folder : s_default_folders) {
|
||||
wxString folder_path = aux_path + "/" + folder;
|
||||
if (fs::exists(folder_path.ToStdWstring())) continue;
|
||||
fs::create_directory(folder_path.ToStdWstring());
|
||||
}
|
||||
return m_paths_list;
|
||||
}
|
||||
|
||||
// Create default folders if they are not loaded
|
||||
for (auto folder : s_default_folders) {
|
||||
wxString folder_path = aux_path + "/" + folder;
|
||||
if (fs::exists(folder_path.ToStdWstring())) continue;
|
||||
fs::create_directory(folder_path.ToStdWstring());
|
||||
}
|
||||
|
||||
// Load from new path
|
||||
|
@ -320,7 +363,8 @@ std::map<std::string, std::vector<json>> ProjectPanel::Reload(wxString aux_path)
|
|||
wxString file_name = encode_path(file_path.c_str());
|
||||
wxStat(file_name, &strucStat);
|
||||
wxFileOffset filelen = strucStat.st_size;
|
||||
|
||||
|
||||
pfile_obj["_filepath"] = file_path;
|
||||
pfile_obj["filename"] = wxGetApp().url_encode(file_path_obj.filename().string().c_str());
|
||||
pfile_obj["size"] = formatBytes((unsigned long)filelen);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "Event.hpp"
|
||||
#include "libslic3r/ProjectTask.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
#include "Auxiliary.hpp"
|
||||
|
||||
#define AUFILE_GREY700 wxColour(107, 107, 107)
|
||||
#define AUFILE_GREY500 wxColour(158, 158, 158)
|
||||
|
@ -63,9 +64,12 @@ private:
|
|||
bool m_reload_already = {false};
|
||||
|
||||
wxWebView* m_browser = {nullptr};
|
||||
AuxiliaryPanel* m_auxiliary{nullptr};
|
||||
wxString m_project_home_url;
|
||||
wxString m_root_dir;
|
||||
static inline int m_sequence_id = 8000;
|
||||
|
||||
void show_info_editor(bool show);
|
||||
|
||||
|
||||
public:
|
||||
|
@ -81,6 +85,7 @@ public:
|
|||
void msw_rescale();
|
||||
void update_model_data();
|
||||
void clear_model_info();
|
||||
void init_auxiliary() { m_auxiliary->init_auxiliary(); }
|
||||
|
||||
bool Show(bool show);
|
||||
void OnScriptMessage(wxWebViewEvent& evt);
|
||||
|
|
|
@ -1324,8 +1324,11 @@ void Selection::scale_legacy(const Vec3d& scale, TransformationType transformati
|
|||
v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
|
||||
v.set_instance_scaling_factor(new_scale);
|
||||
// Restore mirror state
|
||||
v.set_instance_mirror(m_cache.volumes_data[i].get_instance_transform().get_mirror());
|
||||
}
|
||||
else {
|
||||
const auto mirror = v.get_instance_mirror();
|
||||
if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) {
|
||||
// Non-uniform scaling. Transform the scaling factors into the local coordinate system.
|
||||
// This is only possible, if the instance rotation is mulitples of ninety degrees.
|
||||
|
@ -1334,16 +1337,24 @@ void Selection::scale_legacy(const Vec3d& scale, TransformationType transformati
|
|||
}
|
||||
else
|
||||
v.set_instance_scaling_factor(scale);
|
||||
// Restore mirror state
|
||||
v.set_instance_mirror(mirror);
|
||||
}
|
||||
|
||||
// update the instance assemble transform
|
||||
ModelObject* object = m_model->objects[v.object_idx()];
|
||||
Geometry::Transformation assemble_transform = object->instances[v.instance_idx()]->get_assemble_transformation();
|
||||
const auto mirror = assemble_transform.get_mirror();
|
||||
assemble_transform.set_scaling_factor(v.get_instance_scaling_factor());
|
||||
assemble_transform.set_mirror(mirror);
|
||||
object->instances[v.instance_idx()]->set_assemble_transformation(assemble_transform);
|
||||
}
|
||||
else if (is_single_volume() || is_single_modifier())
|
||||
else if (is_single_volume() || is_single_modifier()) {
|
||||
const auto mirror = v.get_volume_transformation().get_mirror();
|
||||
v.set_volume_scaling_factor(scale);
|
||||
// Restore mirror state
|
||||
v.set_volume_mirror(mirror);
|
||||
}
|
||||
else {
|
||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
||||
if (m_mode == Instance) {
|
||||
|
@ -1354,6 +1365,8 @@ void Selection::scale_legacy(const Vec3d& scale, TransformationType transformati
|
|||
v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
||||
|
||||
v.set_instance_scaling_factor(new_scale);
|
||||
// Restore mirror state
|
||||
v.set_instance_mirror(m_cache.volumes_data[i].get_instance_transform().get_mirror());
|
||||
}
|
||||
else if (m_mode == Volume) {
|
||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_volume_scale_matrix()).matrix().block(0, 0, 3, 3);
|
||||
|
@ -1364,6 +1377,8 @@ void Selection::scale_legacy(const Vec3d& scale, TransformationType transformati
|
|||
v.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset);
|
||||
}
|
||||
v.set_volume_scaling_factor(new_scale);
|
||||
// Restore mirror state
|
||||
v.set_volume_mirror(m_cache.volumes_data[i].get_volume_transform().get_mirror());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1988,6 +1988,14 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("only_one_wall_first_layer");
|
||||
optgroup->append_single_option_line("reduce_crossing_wall");
|
||||
optgroup->append_single_option_line("max_travel_detour_distance");
|
||||
|
||||
optgroup = page->new_optgroup(L("Small Area Infill Flow Compensation (experimental)"), L"param_advanced");
|
||||
optgroup->append_single_option_line("small_area_infill_flow_compensation");
|
||||
Option option = optgroup->get_option("small_area_infill_flow_compensation_model");
|
||||
option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.height = 15;
|
||||
optgroup->append_single_option_line(option);
|
||||
|
||||
optgroup = page->new_optgroup(L("Bridging"), L"param_advanced");
|
||||
optgroup->append_single_option_line("bridge_flow");
|
||||
|
@ -2198,6 +2206,7 @@ void TabPrint::build()
|
|||
optgroup = page->new_optgroup(L("Special mode"), L"param_special");
|
||||
optgroup->append_single_option_line("slicing_mode");
|
||||
optgroup->append_single_option_line("print_sequence", "sequent-print");
|
||||
optgroup->append_single_option_line("print_order");
|
||||
optgroup->append_single_option_line("spiral_mode", "spiral-vase");
|
||||
optgroup->append_single_option_line("spiral_mode_smooth", "spiral-vase#smooth");
|
||||
optgroup->append_single_option_line("spiral_mode_max_xy_smoothing", "spiral-vase#max-xy-smoothing");
|
||||
|
@ -2218,7 +2227,7 @@ void TabPrint::build()
|
|||
optgroup->append_single_option_line("gcode_comments");
|
||||
optgroup->append_single_option_line("gcode_label_objects");
|
||||
optgroup->append_single_option_line("exclude_object");
|
||||
Option option = optgroup->get_option("filename_format");
|
||||
option = optgroup->get_option("filename_format");
|
||||
// option.opt.full_width = true;
|
||||
option.opt.is_code = true;
|
||||
option.opt.multiline = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue