diff --git a/CMakeLists.txt b/CMakeLists.txt index b6fe88e48..b8b9add60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,8 @@ option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1) option(SLIC3R_PERL_XS "Compile XS Perl module and enable Perl unit and integration tests" 0) option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0) +set(OPENVDB_FIND_MODULE_PATH "" CACHE PATH "Path to OpenVDB installation's find modules.") + set(SLIC3R_GTK "2" CACHE STRING "GTK version to use with wxWidgets on Linux") set(IS_CROSS_COMPILE FALSE) @@ -492,13 +494,17 @@ find_package(NLopt 1.4 REQUIRED) if(SLIC3R_STATIC) set(OPENVDB_USE_STATIC_LIBS ON) set(USE_BLOSC TRUE) -endif() +endif () -find_package(OpenVDB 5.0 REQUIRED COMPONENTS openvdb) +find_package(OpenVDB 5.0 COMPONENTS openvdb) if(OpenVDB_FOUND) slic3r_remap_configs(IlmBase::Half RelWithDebInfo Release) slic3r_remap_configs(Blosc::blosc RelWithDebInfo Release) -endif() +else () + message(FATAL_ERROR "OpenVDB could not be found with the bundled find module. " + "You can try to specify the find module location of your " + "OpenVDB installation with the OPENVDB_FIND_MODULE_PATH cache variable.") +endif () set(TOP_LEVEL_PROJECT_DIR ${PROJECT_SOURCE_DIR}) function(prusaslicer_copy_dlls target) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake index 02420fed8..3b60ac9d3 100644 --- a/cmake/modules/FindOpenVDB.cmake +++ b/cmake/modules/FindOpenVDB.cmake @@ -102,6 +102,27 @@ may be provided to tell this module where to look. #]=======================================================================] +# If an explicit openvdb module path was specified, that will be used +if (OPENVDB_FIND_MODULE_PATH) + set(_module_path_bak ${CMAKE_MODULE_PATH}) + set(CMAKE_MODULE_PATH ${OPENVDB_FIND_MODULE_PATH}) + find_package( + OpenVDB ${OpenVDB_FIND_VERSION} QUIET + COMPONENTS + ${OpenVDB_FIND_COMPONENTS} + ) + + set(CMAKE_MODULE_PATH ${_module_path_bak}) + if (OpenVDB_FOUND) + return() + endif () + + if (NOT OpenVDB_FIND_QUIETLY) + message(STATUS "Using bundled find module for OpenVDB") + endif () +endif () +# ########################################################################### + cmake_minimum_required(VERSION 3.3) # Monitoring _ROOT variables if(POLICY CMP0074) diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 06bbfb7ef..8cc22647f 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -207,32 +207,34 @@ void SeamPlacer::init(const Print& print) auto merge_and_offset = [po, &temp_polygons, max_nozzle_dmr](EnforcerBlockerType type, std::vector& out) { // Offset the triangles out slightly. + auto offset_out = [](Polygon& input, float offset) -> ExPolygons { + ClipperLib::Paths out(1); + std::vector deltas(input.points.size(), offset); + input.make_counter_clockwise(); + out.front() = mittered_offset_path_scaled(input.points, deltas, 3.); + return ClipperPaths_to_Slic3rExPolygons(out); + }; + + temp_polygons.clear(); po->project_and_append_custom_facets(true, type, temp_polygons); out.clear(); out.reserve(temp_polygons.size()); - float offset = max_nozzle_dmr + po->config().elefant_foot_compensation; - for (const Polygons &src : temp_polygons) { - out.emplace_back(Slic3r::offset_ex(src, scale_(offset))); - offset = max_nozzle_dmr; + float offset = scale_(max_nozzle_dmr + po->config().elefant_foot_compensation); + for (Polygons &src : temp_polygons) { + out.emplace_back(ExPolygons()); + for (Polygon& plg : src) { + ExPolygons offset_explg = offset_out(plg, offset); + if (! offset_explg.empty()) + out.back().emplace_back(std::move(offset_explg.front())); + } + + offset = scale_(max_nozzle_dmr); } }; merge_and_offset(EnforcerBlockerType::BLOCKER, temp_blk); merge_and_offset(EnforcerBlockerType::ENFORCER, temp_enf); -// FIXME: Offsetting should be done somehow cheaper, but following does not work -// for (auto* custom_per_object : {&temp_enf, &temp_blk}) { -// for (ExPolygons& plgs : *custom_per_object) { -// for (ExPolygon& plg : plgs) { -// auto out = Slic3r::offset_ex(plg, scale_(max_nozzle_dmr)); -// plg = out.empty() ? ExPolygon() : out.front(); -// assert(out.empty() || out.size() == 1); -// } -// } -// } - - - // Remember this PrintObject and initialize a store of enforcers and blockers for it. m_po_list.push_back(po); size_t po_idx = m_po_list.size() - 1; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d91770d77..3c554012d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -462,6 +462,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Horizontal width of the brim that will be printed around each object on the first layer."); def->sidetext = L("mm"); def->min = 0; + def->max = 200; def->mode = comSimple; def->set_default_value(new ConfigOptionFloat(0)); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 13246c543..4a4711972 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -608,7 +608,7 @@ static void generic_exception_handle() std::terminate(); throw; } catch (const std::exception& ex) { - wxLogError("Internal error: %s", ex.what()); + wxLogError(format_wxstr(_L("Internal error: %1%"), ex.what())); BOOST_LOG_TRIVIAL(error) << boost::format("Uncaught exception: %1%") % ex.what(); throw; } @@ -1138,7 +1138,7 @@ void GUI_App::UpdateDlgDarkUI(wxDialog* dlg, bool just_buttons_update/* = false* void GUI_App::UpdateDVCDarkUI(wxDataViewCtrl* dvc, bool highlited/* = false*/) { #ifdef _WIN32 - UpdateDarkUI(dvc, highlited); + UpdateDarkUI(dvc, highlited ? dark_mode() : false); wxItemAttr attr(dark_mode() ? m_color_highlight_default : m_color_label_default, m_color_window_default, m_normal_font); diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index 1dfa0eabb..6a945c061 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -433,7 +433,7 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty [type, item](wxCommandEvent&) { obj_list()->load_generic_subobject(item, type); }, "", menu); } - if (wxGetApp().get_mode() == comExpert && type != ModelVolumeType::INVALID) { + if (wxGetApp().get_mode() == comExpert) { sub_menu->AppendSeparator(); append_menu_item(sub_menu, wxID_ANY, _L("Gallery"), "", [type](wxCommandEvent&) { obj_list()->load_subobject(type, true); }, "", menu); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a95791a2b..2776ba9f8 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1358,6 +1358,11 @@ bool ObjectList::is_instance_or_object_selected() void ObjectList::load_subobject(ModelVolumeType type, bool from_galery/* = false*/) { + if (type == ModelVolumeType::INVALID && from_galery) { + load_shape_object_from_gallery(); + return; + } + wxDataViewItem item = GetSelection(); // we can add volumes for Object or Instance if (!item || !(m_objects_model->GetItemType(item)&(itObject|itInstance))) @@ -1663,6 +1668,39 @@ void ObjectList::load_shape_object(const std::string& type_name) #endif // ENABLE_PROJECT_DIRTY_STATE } +void ObjectList::load_shape_object_from_gallery() +{ + if (wxGetApp().plater()->canvas3D()->get_selection().get_object_idx() != -1) + return;// Add nothing if something is selected on 3DScene + + wxArrayString input_files; + GalleryDialog gallery_dlg(this); + if (gallery_dlg.ShowModal() == wxID_CANCEL) + return; + gallery_dlg.get_input_files(input_files); + if (input_files.IsEmpty()) + return; + + std::vector paths; + for (const auto& file : input_files) + paths.push_back(into_path(file)); + + assert(!paths.empty()); + wxString snapshot_label = (paths.size() == 1 ? _L("Add Shape") : _L("Add Shapes")) + ": " + + wxString::FromUTF8(paths.front().filename().string().c_str()); + for (size_t i = 1; i < paths.size(); ++i) + snapshot_label += ", " + wxString::FromUTF8(paths[i].filename().string().c_str()); + + take_snapshot(snapshot_label); +#if ENABLE_PROJECT_DIRTY_STATE + std::vector res = wxGetApp().plater()->load_files(paths, true, false); + if (!res.empty()) + wxGetApp().mainframe->update_title(); +#else + load_files(paths, true, false); +#endif // ENABLE_PROJECT_DIRTY_STATE +} + void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center) { // Add mesh to model as a new object diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 00037b997..4bfe3e9ff 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -244,6 +244,7 @@ public: void load_modifier(ModelObject& model_object, std::vector& added_volumes, ModelVolumeType type, bool from_galery = false); void load_generic_subobject(const std::string& type_name, const ModelVolumeType type); void load_shape_object(const std::string &type_name); + void load_shape_object_from_gallery(); void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true); void del_object(const int obj_idx); void del_subobject_item(wxDataViewItem& item); diff --git a/src/slic3r/GUI/GalleryDialog.cpp b/src/slic3r/GUI/GalleryDialog.cpp index adc21ed0b..d124eda69 100644 --- a/src/slic3r/GUI/GalleryDialog.cpp +++ b/src/slic3r/GUI/GalleryDialog.cpp @@ -219,11 +219,6 @@ static fs::path get_dir(bool sys_dir) return fs::absolute(fs::path(data_dir()) / "shapes").make_preferred(); } -static bool custom_exists() -{ - return fs::exists(get_dir(false)); -} - static std::string get_dir_path(bool sys_dir) { fs::path dir = get_dir(sys_dir); @@ -299,6 +294,9 @@ void GalleryDialog::load_label_icon_list() auto add_files_from_gallery = [](std::vector& items, bool sys_dir, std::string& dir_path) { fs::path dir = get_dir(sys_dir); + if (!fs::exists(dir)) + return; + dir_path = get_dir_path(sys_dir); std::vector sorted_names; @@ -319,8 +317,7 @@ void GalleryDialog::load_label_icon_list() std::string m_sys_dir_path, m_cust_dir_path; std::vector list_items; add_files_from_gallery(list_items, true, m_sys_dir_path); - if (custom_exists()) - add_files_from_gallery(list_items, false, m_cust_dir_path); + add_files_from_gallery(list_items, false, m_cust_dir_path); // Make an image list containing large icons diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 8aaab1ed5..3cda9e3e4 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3005,6 +3005,7 @@ void TabPrinter::update() m_presets->get_edited_preset().printer_technology() == ptFFF ? update_fff() : update_sla(); m_update_cnt--; + update_description_lines(); Layout(); if (m_update_cnt == 0) @@ -4290,6 +4291,9 @@ void TabSLAMaterial::update() if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) return; + update_description_lines(); + Layout(); + // #ys_FIXME. Just a template for this function // m_update_cnt++; // ! something to update