improves loading of 3MFs generated by BambuStudio

This commit is contained in:
QIDI TECH
2024-04-10 13:44:24 +08:00
parent 0491f84149
commit 05e2b540ab
6 changed files with 88 additions and 59 deletions

View File

@@ -190,6 +190,8 @@ static constexpr const char *SVG_FILE_PATH_IN_3MF_ATTR = "filepath3mf";
static constexpr const char *DEPTH_ATTR = "depth"; static constexpr const char *DEPTH_ATTR = "depth";
static constexpr const char *USE_SURFACE_ATTR = "use_surface"; static constexpr const char *USE_SURFACE_ATTR = "use_surface";
// static constexpr const char *FIX_TRANSFORMATION_ATTR = "transform"; // static constexpr const char *FIX_TRANSFORMATION_ATTR = "transform";
const unsigned int VALID_OBJECT_TYPES_COUNT = 1; const unsigned int VALID_OBJECT_TYPES_COUNT = 1;
const char* VALID_OBJECT_TYPES[] = const char* VALID_OBJECT_TYPES[] =
{ {
@@ -336,6 +338,7 @@ namespace Slic3r {
class _3MF_Importer : public _3MF_Base class _3MF_Importer : public _3MF_Base
{ {
typedef std::pair<std::string, int> PathId; typedef std::pair<std::string, int> PathId;
struct Component struct Component
{ {
PathId object_id; PathId object_id;
@@ -476,7 +479,6 @@ namespace Slic3r {
typedef std::map<int, CutObjectInfo> IdToCutObjectInfoMap; typedef std::map<int, CutObjectInfo> IdToCutObjectInfoMap;
typedef std::map<int, std::vector<sla::SupportPoint>> IdToSlaSupportPointsMap; typedef std::map<int, std::vector<sla::SupportPoint>> IdToSlaSupportPointsMap;
typedef std::map<int, std::vector<sla::DrainHole>> IdToSlaDrainHolesMap; typedef std::map<int, std::vector<sla::DrainHole>> IdToSlaDrainHolesMap;
using PathToEmbossShapeFileMap = std::map<std::string, std::shared_ptr<std::string>>; using PathToEmbossShapeFileMap = std::map<std::string, std::shared_ptr<std::string>>;
// Version of the 3mf file // Version of the 3mf file
unsigned int m_version; unsigned int m_version;
@@ -554,6 +556,7 @@ namespace Slic3r {
// handlers to parse the .rels file // handlers to parse the .rels file
void _handle_start_relationships_element(const char* name, const char** attributes); void _handle_start_relationships_element(const char* name, const char** attributes);
bool _handle_start_relationship(const char **attributes, unsigned int num_attributes); bool _handle_start_relationship(const char **attributes, unsigned int num_attributes);
// handlers to parse the .model file // handlers to parse the .model file
void _handle_start_model_xml_element(const char* name, const char** attributes); void _handle_start_model_xml_element(const char* name, const char** attributes);
void _handle_end_model_xml_element(const char* name); void _handle_end_model_xml_element(const char* name);
@@ -627,6 +630,7 @@ namespace Slic3r {
// callbacks to parse the .rels file // callbacks to parse the .rels file
static void XMLCALL _handle_start_relationships_element(void *userData, const char *name, const char **attributes); static void XMLCALL _handle_start_relationships_element(void *userData, const char *name, const char **attributes);
// callbacks to parse the .model file // callbacks to parse the .model file
static void XMLCALL _handle_start_model_xml_element(void* userData, const char* name, const char** attributes); static void XMLCALL _handle_start_model_xml_element(void* userData, const char* name, const char** attributes);
static void XMLCALL _handle_end_model_xml_element(void* userData, const char* name); static void XMLCALL _handle_end_model_xml_element(void* userData, const char* name);
@@ -724,6 +728,7 @@ namespace Slic3r {
m_model_path = MODEL_FILE; m_model_path = MODEL_FILE;
_extract_relationships_from_archive(archive, stat); _extract_relationships_from_archive(archive, stat);
bool found_model = false; bool found_model = false;
// we first loop the entries to read from the .model files which are not root // we first loop the entries to read from the .model files which are not root
for (mz_uint i = 0; i < num_entries; ++i) { for (mz_uint i = 0; i < num_entries; ++i) {
if (mz_zip_reader_file_stat(&archive, i, &stat)) { if (mz_zip_reader_file_stat(&archive, i, &stat)) {
@@ -754,6 +759,7 @@ namespace Slic3r {
} }
} }
} }
// Read root model file // Read root model file
if (start_part_stat.m_file_index < num_entries) { if (start_part_stat.m_file_index < num_entries) {
try { try {
@@ -1045,6 +1051,7 @@ namespace Slic3r {
bool _3MF_Importer::_is_svg_shape_file(const std::string &name) const { bool _3MF_Importer::_is_svg_shape_file(const std::string &name) const {
return boost::starts_with(name, MODEL_FOLDER) && boost::ends_with(name, ".svg"); return boost::starts_with(name, MODEL_FOLDER) && boost::ends_with(name, ".svg");
} }
bool _3MF_Importer::_extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat) bool _3MF_Importer::_extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat)
{ {
if (stat.m_uncomp_size == 0) { if (stat.m_uncomp_size == 0) {
@@ -1502,6 +1509,7 @@ namespace Slic3r {
svg->file_data = m_path_to_emboss_shape_files[filename]; svg->file_data = m_path_to_emboss_shape_files[filename];
} }
} }
bool _3MF_Importer::_extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model) bool _3MF_Importer::_extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model)
{ {
if (stat.m_uncomp_size == 0) { if (stat.m_uncomp_size == 0) {
@@ -1634,7 +1642,8 @@ namespace Slic3r {
} }
return true; return true;
} }
void _3MF_Importer::_handle_start_model_xml_element(const char* name, const char** attributes)
void _3MF_Importer::_handle_start_model_xml_element(const char *name, const char **attributes)
{ {
if (m_xml_parser == nullptr) if (m_xml_parser == nullptr)
return; return;
@@ -1775,6 +1784,7 @@ namespace Slic3r {
{ {
if (!m_model_path.empty()) if (!m_model_path.empty())
return true; return true;
// deletes all non-built or non-instanced objects // deletes all non-built or non-instanced objects
for (const IdToModelObjectMap::value_type& object : m_objects) { for (const IdToModelObjectMap::value_type& object : m_objects) {
if (object.second >= int(m_model->objects.size())) { if (object.second >= int(m_model->objects.size())) {
@@ -1956,7 +1966,11 @@ namespace Slic3r {
m_curr_object.geometry.custom_supports.push_back(get_attribute_value_string(attributes, num_attributes, CUSTOM_SUPPORTS_ATTR)); m_curr_object.geometry.custom_supports.push_back(get_attribute_value_string(attributes, num_attributes, CUSTOM_SUPPORTS_ATTR));
m_curr_object.geometry.custom_seam.push_back(get_attribute_value_string(attributes, num_attributes, CUSTOM_SEAM_ATTR)); m_curr_object.geometry.custom_seam.push_back(get_attribute_value_string(attributes, num_attributes, CUSTOM_SEAM_ATTR));
m_curr_object.geometry.mm_segmentation.push_back(get_attribute_value_string(attributes, num_attributes, MM_SEGMENTATION_ATTR)); std::string mm_segmentation_serialized = get_attribute_value_string(attributes, num_attributes, MM_SEGMENTATION_ATTR);
if (mm_segmentation_serialized.empty())
mm_segmentation_serialized = get_attribute_value_string(attributes, num_attributes, "paint_color");
m_curr_object.geometry.mm_segmentation.push_back(mm_segmentation_serialized);
return true; return true;
} }
@@ -1983,7 +1997,8 @@ namespace Slic3r {
{ {
std::string path = get_attribute_value_string(attributes, num_attributes, PPATH_ATTR); std::string path = get_attribute_value_string(attributes, num_attributes, PPATH_ATTR);
if (path.empty()) path = m_model_path; if (path.empty()) path = m_model_path;
int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR);
int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR);
Transform3d transform = get_transform_from_3mf_specs_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR)); Transform3d transform = get_transform_from_3mf_specs_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
PathId path_id { path, object_id }; PathId path_id { path, object_id };
@@ -2131,11 +2146,11 @@ namespace Slic3r {
{ {
IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id); IdToMetadataMap::iterator object = m_objects_metadata.find(m_curr_config.object_id);
if (object == m_objects_metadata.end()) { if (object == m_objects_metadata.end()) {
add_error("Cannot assign volume mesh to a valid object"); add_error("Can not assign volume mesh to a valid object");
return false; return false;
} }
if (object->second.volumes.empty()) { if (object->second.volumes.empty()) {
add_error("Cannot assign mesh to a valid volume"); add_error("Can not assign mesh to a valid volume");
return false; return false;
} }
ObjectMetadata::VolumeMetadata& volume = object->second.volumes.back(); ObjectMetadata::VolumeMetadata& volume = object->second.volumes.back();
@@ -2470,12 +2485,12 @@ namespace Slic3r {
volume->supported_facets.shrink_to_fit(); volume->supported_facets.shrink_to_fit();
volume->seam_facets.shrink_to_fit(); volume->seam_facets.shrink_to_fit();
volume->mm_segmentation_facets.shrink_to_fit(); volume->mm_segmentation_facets.shrink_to_fit();
if (auto &es = volume_data.shape_configuration; es.has_value()) if (auto &es = volume_data.shape_configuration; es.has_value())
volume->emboss_shape = std::move(es); volume->emboss_shape = std::move(es);
if (auto &tc = volume_data.text_configuration; tc.has_value()) if (auto &tc = volume_data.text_configuration; tc.has_value())
volume->text_configuration = std::move(tc); volume->text_configuration = std::move(tc);
// apply the remaining volume's metadata // apply the remaining volume's metadata
for (const Metadata& metadata : volume_data.metadata) { for (const Metadata& metadata : volume_data.metadata) {
if (metadata.key == NAME_KEY) if (metadata.key == NAME_KEY)
@@ -3554,6 +3569,7 @@ namespace Slic3r {
if (const std::optional<EmbossShape> &es = volume->emboss_shape; if (const std::optional<EmbossShape> &es = volume->emboss_shape;
es.has_value()) es.has_value())
to_xml(stream, *es, *volume, archive); to_xml(stream, *es, *volume, archive);
if (const std::optional<TextConfiguration> &tc = volume->text_configuration; if (const std::optional<TextConfiguration> &tc = volume->text_configuration;
tc.has_value()) tc.has_value())
TextConfigurationSerialization::to_xml(stream, *tc); TextConfigurationSerialization::to_xml(stream, *tc);
@@ -3759,11 +3775,12 @@ S bimap_cvt(const boost::bimap<F, S> &bmap, F f, const S &def_value)
} }
} // namespace } // namespace
/// <summary> /// <summary>
/// TextConfiguration serialization /// TextConfiguration serialization
/// </summary> /// </summary>
const TextConfigurationSerialization::TypeToName TextConfigurationSerialization::type_to_name = const TextConfigurationSerialization::TypeToName TextConfigurationSerialization::type_to_name =
boost::assign::list_of<TypeToName::relation> boost::assign::list_of<TypeToName::relation>
(EmbossStyle::Type::file_path, "file_name") (EmbossStyle::Type::file_path, "file_name")
(EmbossStyle::Type::wx_win_font_descr, "wxFontDescriptor_Windows") (EmbossStyle::Type::wx_win_font_descr, "wxFontDescriptor_Windows")
(EmbossStyle::Type::wx_lin_font_descr, "wxFontDescriptor_Linux") (EmbossStyle::Type::wx_lin_font_descr, "wxFontDescriptor_Linux")
@@ -3780,6 +3797,8 @@ const TextConfigurationSerialization::VerticalAlignToName TextConfigurationSeria
(FontProp::VerticalAlign::top, "top") (FontProp::VerticalAlign::top, "top")
(FontProp::VerticalAlign::center, "middle") (FontProp::VerticalAlign::center, "middle")
(FontProp::VerticalAlign::bottom, "bottom"); (FontProp::VerticalAlign::bottom, "bottom");
void TextConfigurationSerialization::to_xml(std::stringstream &stream, const TextConfiguration &tc) void TextConfigurationSerialization::to_xml(std::stringstream &stream, const TextConfiguration &tc)
{ {
stream << " <" << TEXT_TAG << " "; stream << " <" << TEXT_TAG << " ";
@@ -3827,6 +3846,7 @@ namespace {
FontProp::HorizontalAlign read_horizontal_align(const char **attributes, unsigned int num_attributes, const TextConfigurationSerialization::HorizontalAlignToName& horizontal_align_to_name){ FontProp::HorizontalAlign read_horizontal_align(const char **attributes, unsigned int num_attributes, const TextConfigurationSerialization::HorizontalAlignToName& horizontal_align_to_name){
std::string horizontal_align_str = get_attribute_value_string(attributes, num_attributes, HORIZONTAL_ALIGN_ATTR); std::string horizontal_align_str = get_attribute_value_string(attributes, num_attributes, HORIZONTAL_ALIGN_ATTR);
// Back compatibility // Back compatibility
// PS 2.6.0 do not have align // PS 2.6.0 do not have align
if (horizontal_align_str.empty()) if (horizontal_align_str.empty())
@@ -3838,10 +3858,11 @@ FontProp::HorizontalAlign read_horizontal_align(const char **attributes, unsigne
int horizontal_align_int = 0; int horizontal_align_int = 0;
if(boost::spirit::qi::parse(horizontal_align_str.c_str(), horizontal_align_str.c_str() + 1, boost::spirit::qi::int_, horizontal_align_int)) if(boost::spirit::qi::parse(horizontal_align_str.c_str(), horizontal_align_str.c_str() + 1, boost::spirit::qi::int_, horizontal_align_int))
return static_cast<FontProp::HorizontalAlign>(horizontal_align_int); return static_cast<FontProp::HorizontalAlign>(horizontal_align_int);
} }
return bimap_cvt(horizontal_align_to_name, std::string_view(horizontal_align_str), FontProp::HorizontalAlign::center); return bimap_cvt(horizontal_align_to_name, std::string_view(horizontal_align_str), FontProp::HorizontalAlign::center);
} }
FontProp::VerticalAlign read_vertical_align(const char **attributes, unsigned int num_attributes, const TextConfigurationSerialization::VerticalAlignToName& vertical_align_to_name){ FontProp::VerticalAlign read_vertical_align(const char **attributes, unsigned int num_attributes, const TextConfigurationSerialization::VerticalAlignToName& vertical_align_to_name){
std::string vertical_align_str = get_attribute_value_string(attributes, num_attributes, VERTICAL_ALIGN_ATTR); std::string vertical_align_str = get_attribute_value_string(attributes, num_attributes, VERTICAL_ALIGN_ATTR);
@@ -3860,7 +3881,8 @@ FontProp::VerticalAlign read_vertical_align(const char **attributes, unsigned in
} }
return bimap_cvt(vertical_align_to_name, std::string_view(vertical_align_str), FontProp::VerticalAlign::center); return bimap_cvt(vertical_align_to_name, std::string_view(vertical_align_str), FontProp::VerticalAlign::center);
} }
} // namespace } // namespace
std::optional<TextConfiguration> TextConfigurationSerialization::read(const char **attributes, unsigned int num_attributes) std::optional<TextConfiguration> TextConfigurationSerialization::read(const char **attributes, unsigned int num_attributes)
@@ -3882,6 +3904,7 @@ std::optional<TextConfiguration> TextConfigurationSerialization::read(const char
fp.align = FontProp::Align( fp.align = FontProp::Align(
read_horizontal_align(attributes, num_attributes, horizontal_align_to_name), read_horizontal_align(attributes, num_attributes, horizontal_align_to_name),
read_vertical_align(attributes, num_attributes, vertical_align_to_name)); read_vertical_align(attributes, num_attributes, vertical_align_to_name));
int collection_number = get_attribute_value_int(attributes, num_attributes, COLLECTION_NUMBER_ATTR); int collection_number = get_attribute_value_int(attributes, num_attributes, COLLECTION_NUMBER_ATTR);
if (collection_number > 0) fp.collection_number = static_cast<unsigned int>(collection_number); if (collection_number > 0) fp.collection_number = static_cast<unsigned int>(collection_number);

View File

@@ -418,6 +418,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
wxGetApp().SetWindowVariantForButton(sel_all_std); wxGetApp().SetWindowVariantForButton(sel_all_std);
wxGetApp().SetWindowVariantForButton(sel_all); wxGetApp().SetWindowVariantForButton(sel_all);
wxGetApp().SetWindowVariantForButton(sel_none); wxGetApp().SetWindowVariantForButton(sel_none);
wxGetApp().UpdateDarkUI(sel_all_std); wxGetApp().UpdateDarkUI(sel_all_std);
wxGetApp().UpdateDarkUI(sel_all); wxGetApp().UpdateDarkUI(sel_all);
wxGetApp().UpdateDarkUI(sel_none); wxGetApp().UpdateDarkUI(sel_none);
@@ -750,6 +751,7 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
wxGetApp().SetWindowVariantForButton(sel_all); wxGetApp().SetWindowVariantForButton(sel_all);
wxGetApp().SetWindowVariantForButton(sel_none); wxGetApp().SetWindowVariantForButton(sel_none);
grid->Add(new wxBoxSizer(wxHORIZONTAL)); grid->Add(new wxBoxSizer(wxHORIZONTAL));
grid->Add(new wxBoxSizer(wxHORIZONTAL)); grid->Add(new wxBoxSizer(wxHORIZONTAL));
grid->Add(new wxBoxSizer(wxHORIZONTAL)); grid->Add(new wxBoxSizer(wxHORIZONTAL));
@@ -788,6 +790,7 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
reload_presets(); reload_presets();
set_compatible_printers_html_window(std::vector<std::string>(), false); set_compatible_printers_html_window(std::vector<std::string>(), false);
} }
void PageMaterials::check_and_update_presets(bool force_reload_presets /*= false*/) void PageMaterials::check_and_update_presets(bool force_reload_presets /*= false*/)
{ {
if (presets_loaded) if (presets_loaded)
@@ -796,6 +799,7 @@ void PageMaterials::check_and_update_presets(bool force_reload_presets /*= false
// if (force_reload_presets) // if (force_reload_presets)
reload_presets(); reload_presets();
} }
void PageMaterials::on_paint() void PageMaterials::on_paint()
{ {
} }
@@ -910,7 +914,6 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
} }
} }
wxFont font = wxGetApp().normal_font();// get_default_font_for_dpi(this, get_dpi_for_window(this)); wxFont font = wxGetApp().normal_font();// get_default_font_for_dpi(this, get_dpi_for_window(this));
const int fs = font.GetPointSize(); const int fs = font.GetPointSize();
int size[] = { fs,fs,fs,fs,fs,fs,fs }; int size[] = { fs,fs,fs,fs,fs,fs,fs };
@@ -2613,9 +2616,11 @@ void ConfigWizard::priv::update_materials(Technology technology)
materials.compatibility_counter[preset.alias].insert(printer); materials.compatibility_counter[preset.alias].insert(printer);
} }
}; };
if ((any_fff_selected || custom_printer_in_bundle || custom_printer_selected) && (technology & T_FFF)) { if ((any_fff_selected || custom_printer_in_bundle || custom_printer_selected) && (technology & T_FFF)) {
filaments.clear(); filaments.clear();
aliases_fff.clear(); aliases_fff.clear();
for (const auto &[name, bundle] : bundles) { for (const auto &[name, bundle] : bundles) {
for (const auto &filament : bundle.preset_bundle->filaments) { for (const auto &filament : bundle.preset_bundle->filaments) {
// Iterate printers in all bundles // Iterate printers in all bundles
@@ -2629,9 +2634,9 @@ void ConfigWizard::priv::update_materials(Technology technology)
// template filament bundle has no printers - filament would be never added // template filament bundle has no printers - filament would be never added
if(bundle.vendor_profile && bundle.vendor_profile->templates_profile && bundle.preset_bundle->printers.begin() == bundle.preset_bundle->printers.end()) if(bundle.vendor_profile && bundle.vendor_profile->templates_profile && bundle.preset_bundle->printers.begin() == bundle.preset_bundle->printers.end())
add_material(filaments, aliases_fff, filament); add_material(filaments, aliases_fff, filament);
}
} }
} }
}
if (any_sla_selected && (technology & T_SLA)) { if (any_sla_selected && (technology & T_SLA)) {
sla_materials.clear(); sla_materials.clear();
@@ -2649,10 +2654,10 @@ void ConfigWizard::priv::update_materials(Technology technology)
if (is_compatible_with_printer(PresetWithVendorProfile(material, nullptr), PresetWithVendorProfile(printer, nullptr))) if (is_compatible_with_printer(PresetWithVendorProfile(material, nullptr), PresetWithVendorProfile(printer, nullptr)))
// Check if material is already added // Check if material is already added
add_material(sla_materials, aliases_sla, material, &printer); add_material(sla_materials, aliases_sla, material, &printer);
}
} }
} }
} }
}
} }
void ConfigWizard::priv::on_custom_setup(const bool custom_wanted) void ConfigWizard::priv::on_custom_setup(const bool custom_wanted)
@@ -2781,25 +2786,25 @@ bool ConfigWizard::priv::on_bnt_finish()
{ {
wxBusyCursor wait; wxBusyCursor wait;
#if !defined(__linux__) || (defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION))
if (!page_downloader->on_finish_downloader()) { if (!page_downloader->on_finish_downloader()) {
index->go_to(page_downloader); index->go_to(page_downloader);
return false; return false;
} }
#endif
/* If some printers were added/deleted, but related MaterialPage wasn't activated, /* If some printers were added/deleted, but related MaterialPage wasn't activated,
* than last changes wouldn't be updated for filaments/materials. * than last changes wouldn't be updated for filaments/materials.
* SO, do that before check_and_install_missing_materials() * SO, do that before check_and_install_missing_materials()
*/ */
if (page_filaments) if (page_filaments)
page_filaments->check_and_update_presets(); page_filaments->check_and_update_presets();
if (page_sla_materials) if (page_sla_materials)
page_sla_materials->check_and_update_presets(); page_sla_materials->check_and_update_presets();
// Even if we have only custom printer installed, check filament selection. // Even if we have only custom printer installed, check filament selection.
// Template filaments could be selected in this case. // Template filaments could be selected in this case.
if (custom_printer_selected && !any_fff_selected && !any_sla_selected) if (custom_printer_selected && !any_fff_selected && !any_sla_selected)
return check_and_install_missing_materials(T_FFF); return check_and_install_missing_materials(T_FFF);
// check, that there is selected at least one filament/material // check, that there is selected at least one filament/material
return check_and_install_missing_materials(T_ANY); return check_and_install_missing_materials(T_ANY);
} }
@@ -3235,6 +3240,7 @@ bool ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
wxGetApp().associate_3mf_files(); wxGetApp().associate_3mf_files();
if (page_files_association->associate_stl()) if (page_files_association->associate_stl())
wxGetApp().associate_stl_files(); wxGetApp().associate_stl_files();
//Y
if (page_files_association->associate_step()) if (page_files_association->associate_step())
wxGetApp().associate_step_files(); wxGetApp().associate_step_files();
} }
@@ -3414,9 +3420,7 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
p->add_page(p->page_update = new PageUpdate(this)); p->add_page(p->page_update = new PageUpdate(this));
#if !defined(__linux__) || (defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION))
p->add_page(p->page_downloader = new PageDownloader(this)); p->add_page(p->page_downloader = new PageDownloader(this));
#endif
p->add_page(p->page_reload_from_disk = new PageReloadFromDisk(this)); p->add_page(p->page_reload_from_disk = new PageReloadFromDisk(this));
#ifdef _WIN32 #ifdef _WIN32
p->add_page(p->page_files_association = new PageFilesAssociation(this)); p->add_page(p->page_files_association = new PageFilesAssociation(this));

View File

@@ -62,11 +62,11 @@ void open_folder(const std::string& path)
std::string filename_from_url(const std::string& url) std::string filename_from_url(const std::string& url)
{ {
// TODO: can it be done with curl? std::string url_plain = std::string(url.begin(), std::find(url.begin(), url.end(), '?'));
size_t slash = url.find_last_of("/"); size_t slash = url_plain.find_last_of("/");
if (slash == std::string::npos && slash != url.size() - 1) if (slash == std::string::npos)
return std::string(); return std::string();
return url.substr(slash + 1, url.size() - slash + 1); return std::string(url_plain.begin() + slash + 1, url_plain.end());
} }
} }

View File

@@ -822,6 +822,7 @@ void GUI_App::post_init()
// This is ugly but I honestly found no better way to do it. // This is ugly but I honestly found no better way to do it.
// Neither wxShowEvent nor wxWindowCreateEvent work reliably. // Neither wxShowEvent nor wxWindowCreateEvent work reliably.
if (this->preset_updater) { // G-Code Viewer does not initialize preset_updater. if (this->preset_updater) { // G-Code Viewer does not initialize preset_updater.
#if 0 // This code was moved to EVT_CONFIG_UPDATER_SYNC_DONE bind - after preset_updater finishes synchronization. #if 0 // This code was moved to EVT_CONFIG_UPDATER_SYNC_DONE bind - after preset_updater finishes synchronization.
if (! this->check_updates(false)) if (! this->check_updates(false))
// Configuration is not compatible and reconfigure was refused by the user. Application is closing. // Configuration is not compatible and reconfigure was refused by the user. Application is closing.
@@ -1097,10 +1098,12 @@ static int get_app_font_pt_size(const AppConfig* app_config)
return (font_pt_size > max_font_pt_size) ? max_font_pt_size : font_pt_size; return (font_pt_size > max_font_pt_size) ? max_font_pt_size : font_pt_size;
} }
bool GUI_App::on_init_inner() bool GUI_App::on_init_inner()
{ {
// TODO: remove this when all asserts are gone. // TODO: remove this when all asserts are gone.
wxDisableAsserts(); wxDisableAsserts();
// Set initialization of image handlers before any UI actions - See GH issue #7469 // Set initialization of image handlers before any UI actions - See GH issue #7469
wxInitAllImageHandlers(); wxInitAllImageHandlers();
@@ -1299,6 +1302,7 @@ bool GUI_App::on_init_inner()
Bind(EVT_CONFIG_UPDATER_SYNC_DONE, [this](const wxCommandEvent& evt) { Bind(EVT_CONFIG_UPDATER_SYNC_DONE, [this](const wxCommandEvent& evt) {
this->check_updates(false); this->check_updates(false);
}); });
} }
else { else {
#ifdef __WXMSW__ #ifdef __WXMSW__
@@ -1642,7 +1646,7 @@ void GUI_App::UpdateDVCDarkUI(wxDataViewCtrl* dvc, bool highlited/* = false*/)
UpdateDarkUI(dvc, highlited ? dark_mode() : false); UpdateDarkUI(dvc, highlited ? dark_mode() : false);
#ifdef _MSW_DARK_MODE #ifdef _MSW_DARK_MODE
if (!dvc->HasFlag(wxDV_NO_HEADER)) if (!dvc->HasFlag(wxDV_NO_HEADER))
dvc->RefreshHeaderDarkMode(&m_normal_font); dvc->RefreshHeaderDarkMode(&m_normal_font);
#endif //_MSW_DARK_MODE #endif //_MSW_DARK_MODE
if (dvc->HasFlag(wxDV_ROW_LINES)) if (dvc->HasFlag(wxDV_ROW_LINES))
dvc->SetAlternateRowColour(m_color_highlight_default); dvc->SetAlternateRowColour(m_color_highlight_default);
@@ -1687,6 +1691,7 @@ int GUI_App::get_max_font_pt_size()
} }
return 15; return 15;
} }
void GUI_App::init_fonts() void GUI_App::init_fonts()
{ {
m_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); m_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
@@ -3160,9 +3165,6 @@ void GUI_App::show_desktop_integration_dialog()
void GUI_App::show_downloader_registration_dialog() void GUI_App::show_downloader_registration_dialog()
{ {
#if defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)
return;
#endif
InfoDialog msg(nullptr InfoDialog msg(nullptr
, format_wxstr(_L("Welcome to %1% version %2%."), SLIC3R_APP_NAME, SLIC3R_VERSION) , format_wxstr(_L("Welcome to %1% version %2%."), SLIC3R_APP_NAME, SLIC3R_VERSION)
, format_wxstr(_L( , format_wxstr(_L(
@@ -3174,10 +3176,10 @@ void GUI_App::show_downloader_registration_dialog()
if (msg.ShowModal() == wxID_YES) { if (msg.ShowModal() == wxID_YES) {
auto downloader_worker = new DownloaderUtils::Worker(nullptr); auto downloader_worker = new DownloaderUtils::Worker(nullptr);
downloader_worker->perform_register(app_config->get("url_downloader_dest")); downloader_worker->perform_register(app_config->get("url_downloader_dest"));
#if defined(__linux__) #if defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
if (downloader_worker->get_perform_registration_linux()) if (downloader_worker->get_perform_registration_linux())
DesktopIntegrationDialog::perform_downloader_desktop_integration(); DesktopIntegrationDialog::perform_downloader_desktop_integration();
#endif //(__linux__) #endif //(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
} else { } else {
app_config->set("downloader_url_registered", "0"); app_config->set("downloader_url_registered", "0");
} }
@@ -3459,7 +3461,6 @@ void GUI_App::associate_bgcode_files()
{ {
associate_file_type(L".bgcode", L"QIDISlicer.GCodeViewer.1", L"QIDISlicerGCodeViewer", true); associate_file_type(L".bgcode", L"QIDISlicer.GCodeViewer.1", L"QIDISlicerGCodeViewer", true);
} }
#endif // __WXMSW__ #endif // __WXMSW__
void GUI_App::on_version_read(wxCommandEvent& evt) void GUI_App::on_version_read(wxCommandEvent& evt)
@@ -3564,17 +3565,16 @@ void GUI_App::start_download(std::string url)
BOOST_LOG_TRIVIAL(error) << "Could not start URL download: plater is nullptr."; BOOST_LOG_TRIVIAL(error) << "Could not start URL download: plater is nullptr.";
return; return;
} }
// Windows register and deregister executable path to registry - cant get here when not registered
// Apple registers via info.plist attached to exectable - might get here #if defined(__APPLE__) || (defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION))
// Linux registers via desktop integration file - might get here only if such file was created outside Slicer. if (app_config && !app_config->get_bool("downloader_url_registered"))
// Desktop integration is limited with SLIC3R_DESKTOP_INTEGRATION (cmake option). {
#if defined(__APPLE__) || (defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION))
if (app_config && app_config->get_bool("downloader_url_registered")) {
notification_manager()->push_notification(NotificationType::URLNotRegistered); notification_manager()->push_notification(NotificationType::URLNotRegistered);
BOOST_LOG_TRIVIAL(error) << "Recieved command to open URL, but it is not allowed in app configuration. URL: " << url; BOOST_LOG_TRIVIAL(error) << "Received command to open URL, but it is not allowed in app configuration. URL: " << url;
return; return;
} }
#endif //defined(__APPLE__) || (defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)) #endif //defined(__APPLE__) || (defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION))
//lets always init so if the download dest folder was changed, new dest is used //lets always init so if the download dest folder was changed, new dest is used
boost::filesystem::path dest_folder(app_config->get("url_downloader_dest")); boost::filesystem::path dest_folder(app_config->get("url_downloader_dest"));
if (dest_folder.empty() || !boost::filesystem::is_directory(dest_folder)) { if (dest_folder.empty() || !boost::filesystem::is_directory(dest_folder)) {
@@ -3619,5 +3619,6 @@ void GUI_App::open_wifi_config_dialog(bool forced, const wxString& drive_path/*
} }
m_wifi_config_dialog_shown = false; m_wifi_config_dialog_shown = false;
} }
} // GUI } // GUI
} //Slic3r } //Slic3r

View File

@@ -909,6 +909,13 @@ private:
return true; return true;
} }
}, },
{NotificationType::PresetUpdateAvailableNewPrinter, NotificationLevel::ImportantNotificationLevel, 20, _u8L("Configuration update is available. Update contains new printer releases."), _u8L("See more."),
[](wxEvtHandler* evnthndlr) {
if (evnthndlr != nullptr)
wxPostEvent(evnthndlr, PresetUpdateAvailableClickedEvent(EVT_PRESET_UPDATE_AVAILABLE_CLICKED));
return true;
}
},
{NotificationType::EmptyColorChangeCode, NotificationLevel::PrintInfoNotificationLevel, 10, {NotificationType::EmptyColorChangeCode, NotificationLevel::PrintInfoNotificationLevel, 10,
_u8L("You have just added a G-code for color change, but its value is empty.\n" _u8L("You have just added a G-code for color change, but its value is empty.\n"
"To export the G-code correctly, check the \"Color Change G-code\" in \"Printer Settings > Custom G-code\"") }, "To export the G-code correctly, check the \"Color Change G-code\" in \"Printer Settings > Custom G-code\"") },

View File

@@ -14,6 +14,7 @@
#include "ConfigWizard.hpp" #include "ConfigWizard.hpp"
#include "Widgets/SpinInput.hpp" #include "Widgets/SpinInput.hpp"
#include <boost/dll/runtime_symbol_info.hpp> #include <boost/dll/runtime_symbol_info.hpp>
#ifdef WIN32 #ifdef WIN32
@@ -23,10 +24,6 @@
#include "DesktopIntegrationDialog.hpp" #include "DesktopIntegrationDialog.hpp"
#endif //(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION) #endif //(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
#if defined(__linux__) && !defined(SLIC3R_DESKTOP_INTEGRATION)
#include "NotificationManager.hpp"
#endif //(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
namespace Slic3r { namespace Slic3r {
static t_config_enum_names enum_names_from_keys_map(const t_config_enum_values& enum_keys_map) static t_config_enum_names enum_names_from_keys_map(const t_config_enum_values& enum_keys_map)
@@ -88,6 +85,7 @@ PreferencesDialog::PreferencesDialog(wxWindow* parent) :
sz.x += 1; sz.x += 1;
#endif #endif
SetSize(sz); SetSize(sz);
m_highlighter.set_timer_owner(this, 0); m_highlighter.set_timer_owner(this, 0);
} }
@@ -125,11 +123,9 @@ void PreferencesDialog::show(const std::string& highlight_opt_key /*= std::strin
if (wxGetApp().is_editor()) { if (wxGetApp().is_editor()) {
auto app_config = get_app_config(); auto app_config = get_app_config();
#if !defined(__linux__) || (defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION))
downloader->set_path_name(app_config->get("url_downloader_dest")); downloader->set_path_name(app_config->get("url_downloader_dest"));
downloader->allow(!app_config->has("downloader_url_registered") || app_config->get_bool("downloader_url_registered")); downloader->allow(!app_config->has("downloader_url_registered") || app_config->get_bool("downloader_url_registered"));
#endif
for (const std::string& opt_key : {"suppress_hyperlinks", "downloader_url_registered"}) for (const std::string& opt_key : {"suppress_hyperlinks", "downloader_url_registered"})
m_optgroup_other->set_value(opt_key, app_config->get_bool(opt_key)); m_optgroup_other->set_value(opt_key, app_config->get_bool(opt_key));
@@ -138,6 +134,7 @@ void PreferencesDialog::show(const std::string& highlight_opt_key /*= std::strin
,"default_action_on_select_preset" }) ,"default_action_on_select_preset" })
m_optgroup_general->set_value(opt_key, app_config->get(opt_key) == "none"); m_optgroup_general->set_value(opt_key, app_config->get(opt_key) == "none");
m_optgroup_general->set_value("default_action_on_dirty_project", app_config->get("default_action_on_dirty_project").empty()); m_optgroup_general->set_value("default_action_on_dirty_project", app_config->get("default_action_on_dirty_project").empty());
// update colors for color pickers of the labels // update colors for color pickers of the labels
update_color(m_sys_colour, wxGetApp().get_label_clr_sys()); update_color(m_sys_colour, wxGetApp().get_label_clr_sys());
update_color(m_mod_colour, wxGetApp().get_label_clr_modified()); update_color(m_mod_colour, wxGetApp().get_label_clr_modified());
@@ -155,6 +152,7 @@ void PreferencesDialog::show(const std::string& highlight_opt_key /*= std::strin
static std::shared_ptr<ConfigOptionsGroup>create_options_tab(const wxString& title, wxBookCtrlBase* tabs) static std::shared_ptr<ConfigOptionsGroup>create_options_tab(const wxString& title, wxBookCtrlBase* tabs)
{ {
wxPanel* tab = new wxPanel(tabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); wxPanel* tab = new wxPanel(tabs, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
tabs->AddPage(tab, _(title)); tabs->AddPage(tab, _(title));
tab->SetFont(wxGetApp().normal_font()); tab->SetFont(wxGetApp().normal_font());
@@ -163,6 +161,7 @@ static std::shared_ptr<ConfigOptionsGroup>create_options_tab(const wxString& tit
// Sizer in the scrolled area // Sizer in the scrolled area
auto* scrolled_sizer = new wxBoxSizer(wxVERTICAL); auto* scrolled_sizer = new wxBoxSizer(wxVERTICAL);
scrolled->SetSizer(scrolled_sizer); scrolled->SetSizer(scrolled_sizer);
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(scrolled, 1, wxEXPAND); sizer->Add(scrolled, 1, wxEXPAND);
sizer->SetSizeHints(tab); sizer->SetSizeHints(tab);
@@ -182,6 +181,7 @@ static void activate_options_tab(std::shared_ptr<ConfigOptionsGroup> optgroup)
sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);
optgroup->parent()->Layout(); optgroup->parent()->Layout();
// apply sercher // apply sercher
wxGetApp().sidebar().get_searcher().append_preferences_options(optgroup->get_lines()); wxGetApp().sidebar().get_searcher().append_preferences_options(optgroup->get_lines());
} }
@@ -323,7 +323,6 @@ void PreferencesDialog::build()
L("Associate .stl files to QIDISlicer"), L("Associate .stl files to QIDISlicer"),
L("If enabled, sets QIDISlicer as default application to open .stl files."), L("If enabled, sets QIDISlicer as default application to open .stl files."),
app_config->get_bool("associate_stl")); app_config->get_bool("associate_stl"));
#endif // _WIN32 #endif // _WIN32
m_optgroup_general->append_separator(); m_optgroup_general->append_separator();
@@ -626,6 +625,7 @@ void PreferencesDialog::build()
L("If the 'Supports binary G-code' option is enabled in Printer Settings, " L("If the 'Supports binary G-code' option is enabled in Printer Settings, "
"checking this option will result in the export of G-code in binary format."), "checking this option will result in the export of G-code in binary format."),
app_config->get_bool("use_binary_gcode_when_supported")); app_config->get_bool("use_binary_gcode_when_supported"));
append_bool_option(m_optgroup_other, "suppress_hyperlinks", append_bool_option(m_optgroup_other, "suppress_hyperlinks",
L("Suppress to open hyperlink in browser"), L("Suppress to open hyperlink in browser"),
L("If enabled, QIDISlicer will not open a hyperlinks in your browser."), L("If enabled, QIDISlicer will not open a hyperlinks in your browser."),
@@ -633,18 +633,14 @@ void PreferencesDialog::build()
// "If disabled, the descriptions of configuration parameters in settings tabs will work as hyperlinks."), // "If disabled, the descriptions of configuration parameters in settings tabs will work as hyperlinks."),
app_config->get_bool("suppress_hyperlinks")); app_config->get_bool("suppress_hyperlinks"));
#if !defined(__linux__) || (defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION))
append_bool_option(m_optgroup_other, "downloader_url_registered", append_bool_option(m_optgroup_other, "downloader_url_registered",
L("Allow downloads from Printables.com"), L("Allow downloads from Printables.com"),
L("If enabled, QIDISlicer will be allowed to download from Printables.com"), L("If enabled, QIDISlicer will be allowed to download from Printables.com"),
app_config->get_bool("downloader_url_registered")); app_config->get_bool("downloader_url_registered"));
#endif
activate_options_tab(m_optgroup_other); activate_options_tab(m_optgroup_other);
#if !defined(__linux__) || (defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION))
create_downloader_path_sizer(); create_downloader_path_sizer();
#endif
create_settings_font_widget(); create_settings_font_widget();
#if ENABLE_ENVIRONMENT_MAP #if ENABLE_ENVIRONMENT_MAP
@@ -749,18 +745,16 @@ void PreferencesDialog::update_ctrls_alignment()
void PreferencesDialog::accept(wxEvent&) void PreferencesDialog::accept(wxEvent&)
{ {
#if !defined(__linux__) || (defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION))
if(wxGetApp().is_editor()) { if(wxGetApp().is_editor()) {
if (const auto it = m_values.find("downloader_url_registered"); it != m_values.end()) if (const auto it = m_values.find("downloader_url_registered"); it != m_values.end())
downloader->allow(it->second == "1"); downloader->allow(it->second == "1");
if (!downloader->on_finish()) if (!downloader->on_finish())
return; return;
#if defined(__linux__) #if defined(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
if( downloader->get_perform_registration_linux()) if( downloader->get_perform_registration_linux())
DesktopIntegrationDialog::perform_downloader_desktop_integration(); DesktopIntegrationDialog::perform_downloader_desktop_integration();
#endif #endif //(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
} }
#endif
std::vector<std::string> options_to_recreate_GUI = { "no_defaults", "tabs_as_menu", "sys_menu_enabled", "font_pt_size", "suppress_round_corners" }; std::vector<std::string> options_to_recreate_GUI = { "no_defaults", "tabs_as_menu", "sys_menu_enabled", "font_pt_size", "suppress_round_corners" };