mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 20:51:12 -06:00 
			
		
		
		
	Merge branch 'main' into enh-port-edit-gcode-dlg
This commit is contained in:
		
						commit
						02258b4391
					
				
					 15 changed files with 93 additions and 34 deletions
				
			
		|  | @ -3,8 +3,9 @@ cmake_minimum_required(VERSION 3.13) | |||
| if (APPLE) | ||||
|     # if CMAKE_OSX_DEPLOYMENT_TARGET is not set, set it to 11.3 | ||||
|     if (NOT CMAKE_OSX_DEPLOYMENT_TARGET) | ||||
|         set(CMAKE_OSX_DEPLOYMENT_TARGET "11.3" CACHE STRING "Minimum OS X deployment version") | ||||
|         set(CMAKE_OSX_DEPLOYMENT_TARGET "11.3" CACHE STRING "Minimum OS X deployment version" FORCE) | ||||
|     endif () | ||||
|     message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: ${CMAKE_OSX_DEPLOYMENT_TARGET}") | ||||
| endif () | ||||
| 
 | ||||
| project(OrcaSlicer) | ||||
|  |  | |||
							
								
								
									
										4
									
								
								deps/Boost/Boost.cmake
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/Boost/Boost.cmake
									
										
									
									
										vendored
									
									
								
							|  | @ -2,12 +2,12 @@ include(ExternalProject) | |||
| 
 | ||||
| # Use boost 1.78 for Windows, to support VS2022 | ||||
| if (WIN32) | ||||
| 	set(_boost_url "https://boostorg.jfrog.io/artifactory/main/release/1.78.0/source/boost_1_78_0.tar.gz") | ||||
| 	set(_boost_url "https://github.com/SoftFever/OrcaSlicer_deps/releases/download/boost/boost_1_78_0.tar.gz") | ||||
| 	set(_boost_hash 94CED8B72956591C4775AE2207A9763D3600B30D9D7446562C552F0A14A63BE7) | ||||
|     set(_bootstrap_cmd bootstrap.bat) | ||||
|     set(_build_cmd  b2.exe) | ||||
| else() | ||||
| 	set(_boost_url "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz") | ||||
| 	set(_boost_url "https://github.com/SoftFever/OrcaSlicer_deps/releases/download/boost/boost_1_75_0.tar.gz") | ||||
| 	set(_boost_hash AEB26F80E80945E82EE93E5939BAEBDCA47B9DEE80A07D3144BE1E1A6A66DD6A) | ||||
|     set(_bootstrap_cmd ./bootstrap.sh) | ||||
|     set(_build_cmd ./b2) | ||||
|  |  | |||
							
								
								
									
										4
									
								
								deps/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								deps/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -24,8 +24,10 @@ cmake_minimum_required(VERSION 3.2) | |||
| if (APPLE) | ||||
|     # if CMAKE_OSX_DEPLOYMENT_TARGET is not set, set it to 11.3 | ||||
|     if (NOT CMAKE_OSX_DEPLOYMENT_TARGET) | ||||
|         set(CMAKE_OSX_DEPLOYMENT_TARGET "11.3" CACHE STRING "Minimum OS X deployment version") | ||||
|         set(CMAKE_OSX_DEPLOYMENT_TARGET "11.3" CACHE STRING "Minimum OS X deployment version" FORCE) | ||||
|     endif () | ||||
|     message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: ${CMAKE_OSX_DEPLOYMENT_TARGET}") | ||||
| 
 | ||||
| endif () | ||||
| 
 | ||||
| project(OrcaSlicer-deps) | ||||
|  |  | |||
|  | @ -31,6 +31,11 @@ WallToolPathsParams make_paths_params(const int layer_id, const PrintObjectConfi | |||
|         if (const auto &min_feature_size_opt = print_object_config.min_feature_size) | ||||
|             input_params.min_feature_size = min_feature_size_opt.value * 0.01 * min_nozzle_diameter; | ||||
| 
 | ||||
|         if (const auto &min_wall_length_factor_opt = print_object_config.min_length_factor) | ||||
|             input_params.min_length_factor = min_wall_length_factor_opt.value; | ||||
|         else | ||||
|             input_params.min_length_factor = 0.5f; | ||||
| 
 | ||||
|         if (layer_id == 0) { | ||||
|             if (const auto &initial_layer_min_bead_width_opt = print_object_config.initial_layer_min_bead_width) | ||||
|                 input_params.min_bead_width = initial_layer_min_bead_width_opt.value * 0.01 * min_nozzle_diameter; | ||||
|  | @ -47,6 +52,8 @@ WallToolPathsParams make_paths_params(const int layer_id, const PrintObjectConfi | |||
| 
 | ||||
|         input_params.wall_transition_angle   = print_object_config.wall_transition_angle.value; | ||||
|         input_params.wall_distribution_count = print_object_config.wall_distribution_count.value; | ||||
| 
 | ||||
|         input_params.is_top_or_bottom_layer = false; // Set to default value
 | ||||
|     } | ||||
| 
 | ||||
|     return input_params; | ||||
|  | @ -671,7 +678,8 @@ void WallToolPaths::removeSmallLines(std::vector<VariableWidthLines> &toolpaths) | |||
|             coord_t        min_width = std::numeric_limits<coord_t>::max(); | ||||
|             for (const ExtrusionJunction &j : line) | ||||
|                 min_width = std::min(min_width, j.w); | ||||
|             if (line.is_odd && !line.is_closed && shorterThan(line, min_width / 2)) { // remove line
 | ||||
|             // Only use min_length_factor for non-topmost, to prevent top gaps. Otherwise use default value.
 | ||||
|             if (line.is_odd && !line.is_closed && shorterThan(line, m_params.is_top_or_bottom_layer ? (min_width / 2) : (min_width * m_params.min_length_factor))) { // remove line
 | ||||
|                 line = std::move(inset.back()); | ||||
|                 inset.erase(--inset.end()); | ||||
|                 line_idx--; // reconsider the current position
 | ||||
|  |  | |||
|  | @ -25,10 +25,12 @@ class WallToolPathsParams | |||
| public: | ||||
|     float   min_bead_width; | ||||
|     float   min_feature_size; | ||||
|     float   min_length_factor; | ||||
|     float   wall_transition_length; | ||||
|     float   wall_transition_angle; | ||||
|     float   wall_transition_filter_deviation; | ||||
|     int     wall_distribution_count; | ||||
|     bool    is_top_or_bottom_layer; | ||||
| }; | ||||
| 
 | ||||
| WallToolPathsParams make_paths_params(const int layer_id, const PrintObjectConfig &print_object_config, const PrintConfig &print_config); | ||||
|  | @ -109,7 +111,7 @@ protected: | |||
|     /*!
 | ||||
|      * Remove polylines shorter than half the smallest line width along that polyline. | ||||
|      */ | ||||
|     static void removeSmallLines(std::vector<VariableWidthLines> &toolpaths); | ||||
|     void removeSmallLines(std::vector<VariableWidthLines> &toolpaths); | ||||
| 
 | ||||
|     /*!
 | ||||
|      * Simplifies the variable-width toolpaths by calling the simplify on every line in the toolpath using the provided | ||||
|  |  | |||
|  | @ -1941,10 +1941,15 @@ void PerimeterGenerator::process_arachne() | |||
|         int        loop_number = this->config->wall_loops + surface.extra_perimeters - 1; // 0-indexed loops
 | ||||
|         if (this->config->alternate_extra_wall && this->layer_id % 2 == 1 && !m_spiral_vase) // add alternating extra wall
 | ||||
|             loop_number++; | ||||
|         if (this->layer_id == 0 && this->config->only_one_wall_first_layer) | ||||
| 
 | ||||
|         // Set the bottommost layer to be one wall
 | ||||
|         const bool is_bottom_layer = (this->layer_id == 0) ? true : false; | ||||
|         if (is_bottom_layer && this->config->only_one_wall_first_layer) | ||||
|             loop_number = 0; | ||||
| 
 | ||||
|         // Orca: set the topmost layer to be one wall according to the config
 | ||||
|         if (loop_number > 0 && config->only_one_wall_top && this->upper_slices == nullptr) | ||||
|         const bool is_topmost_layer = (this->upper_slices == nullptr) ? true : false; | ||||
|         if (is_topmost_layer && loop_number > 0 && config->only_one_wall_top) | ||||
|             loop_number = 0; | ||||
|         // Orca: properly adjust offset for the outer wall if precise_outer_wall is enabled.
 | ||||
|         ExPolygons last = offset_ex(surface.expolygon.simplify_p(surface_simplify_resolution), | ||||
|  | @ -1952,6 +1957,9 @@ void PerimeterGenerator::process_arachne() | |||
|                                                  : -float(ext_perimeter_width / 2. - ext_perimeter_spacing / 2.)); | ||||
|          | ||||
|         Arachne::WallToolPathsParams input_params = Arachne::make_paths_params(this->layer_id, *object_config, *print_config); | ||||
|         // Set params is_top_or_bottom_layer for adjusting short-wall removal sensitivity.
 | ||||
|         input_params.is_top_or_bottom_layer = (is_bottom_layer || is_topmost_layer) ? true : false; | ||||
| 
 | ||||
|         coord_t wall_0_inset = 0; | ||||
|         if (config->precise_outer_wall) | ||||
|            wall_0_inset = -coord_t(ext_perimeter_width / 2 - ext_perimeter_spacing / 2); | ||||
|  | @ -1959,29 +1967,45 @@ void PerimeterGenerator::process_arachne() | |||
|         std::vector<Arachne::VariableWidthLines> out_shell; | ||||
|         ExPolygons top_fills; | ||||
|         ExPolygons fill_clip; | ||||
|         if (loop_number > 0 && config->only_one_wall_top && !surface.is_bridge() && this->upper_slices != nullptr) { | ||||
|             // Check if current layer has surfaces that are not covered by upper layer (i.e., top surfaces)
 | ||||
|             ExPolygons non_top_polygons; | ||||
|             this->split_top_surfaces(last, top_fills, non_top_polygons, fill_clip); | ||||
| 
 | ||||
|             if (top_fills.empty()) { | ||||
|         // Check if we're on a top surface, and make adjustments where needed
 | ||||
|         if (!surface.is_bridge() && !is_topmost_layer) { | ||||
|             ExPolygons non_top_polygons; | ||||
|             // Temporary storage, in the event all we need to do is set is_top_or_bottom_layer
 | ||||
|             ExPolygons top_fills_tmp; | ||||
|             ExPolygons fill_clip_tmp; | ||||
|             // Check if current layer has surfaces that are not covered by upper layer (i.e., top surfaces)
 | ||||
|             this->split_top_surfaces(last, top_fills_tmp, non_top_polygons, fill_clip_tmp); | ||||
| 
 | ||||
|             if (top_fills_tmp.empty()) { | ||||
|                 // No top surfaces, no special handling needed
 | ||||
|             } else { | ||||
|                 // First we slice the outer shell
 | ||||
|                 Polygons last_p = to_polygons(last); | ||||
|                 Arachne::WallToolPaths wallToolPaths(last_p, bead_width_0, perimeter_spacing, coord_t(1), | ||||
|                                                      wall_0_inset, layer_height, input_params); | ||||
|                 out_shell = wallToolPaths.getToolPaths(); | ||||
|                 // Make sure infill not overlap with wall
 | ||||
|                 top_fills = intersection_ex(top_fills, wallToolPaths.getInnerContour()); | ||||
|                 // Use single-wall on top-surfaces if configured
 | ||||
|                 if (loop_number > 0 && config->only_one_wall_top) { | ||||
|                     // Adjust arachne input params to prevent removal of larger short walls, which could lead to gaps
 | ||||
|                     Arachne::WallToolPathsParams input_params_tmp = input_params; | ||||
|                     input_params_tmp.is_top_or_bottom_layer = true; | ||||
|                  | ||||
|                     // Swap in the temporary storage
 | ||||
|                     top_fills.swap(top_fills_tmp); | ||||
|                     fill_clip.swap(fill_clip_tmp); | ||||
|                      | ||||
|                     // First we slice the outer shell
 | ||||
|                     Polygons last_p = to_polygons(last); | ||||
|                     Arachne::WallToolPaths wallToolPaths(last_p, bead_width_0, perimeter_spacing, coord_t(1), | ||||
|                                                         wall_0_inset, layer_height, input_params_tmp); | ||||
|                     out_shell = wallToolPaths.getToolPaths(); | ||||
|                     // Make sure infill not overlap with wall
 | ||||
|                     top_fills = intersection_ex(top_fills, wallToolPaths.getInnerContour()); | ||||
| 
 | ||||
|                 if (!top_fills.empty()) { | ||||
|                     // Then get the inner part that needs more walls
 | ||||
|                     last = intersection_ex(non_top_polygons, wallToolPaths.getInnerContour()); | ||||
|                     loop_number--; | ||||
|                 } else { | ||||
|                     // Give up the outer shell because we don't have any meaningful top surface
 | ||||
|                     out_shell.clear(); | ||||
|                     if (!top_fills.empty()) { | ||||
|                         // Then get the inner part that needs more walls
 | ||||
|                         last = intersection_ex(non_top_polygons, wallToolPaths.getInnerContour()); | ||||
|                         loop_number--; | ||||
|                     } else { | ||||
|                         // Give up the outer shell because we don't have any meaningful top surface
 | ||||
|                         out_shell.clear(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -804,7 +804,7 @@ static std::vector<std::string> s_Preset_print_options { | |||
|      "initial_layer_infill_speed", "only_one_wall_top",  | ||||
|      "timelapse_type", | ||||
|      "wall_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", | ||||
|      "wall_distribution_count", "min_feature_size", "min_bead_width", "post_process", | ||||
|      "wall_distribution_count", "min_feature_size", "min_bead_width", "post_process", "min_length_factor", | ||||
|      "small_perimeter_speed", "small_perimeter_threshold","bridge_angle", "filter_out_gap_fill", "travel_acceleration","inner_wall_acceleration", "min_width_top_surface", | ||||
|      "default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", "top_surface_jerk", "initial_layer_jerk","travel_jerk", | ||||
|      "top_solid_infill_flow_ratio","bottom_solid_infill_flow_ratio","only_one_wall_first_layer", "print_flow_ratio", "seam_gap", | ||||
|  |  | |||
|  | @ -4540,6 +4540,20 @@ def = this->add("filament_loading_speed", coFloats); | |||
|     def->min = 0; | ||||
|     def->set_default_value(new ConfigOptionPercent(25)); | ||||
| 
 | ||||
|     def = this->add("min_length_factor", coFloat); | ||||
|     def->label = L("Minimum wall length"); | ||||
|     def->category = L("Quality"); | ||||
|     def->tooltip = L("Adjust this value to prevent short, unclosed walls from being printed, which could increase print time. " | ||||
|     "Higher values remove more and longer walls.\n\n" | ||||
|     "NOTE: Bottom and top surfaces will not be affected by this value to prevent visual gaps on the ouside of the model. " | ||||
|     "Adjust 'One wall threshold' in the Advanced settings below to adjust the sensitivity of what is considered a top-surface. " | ||||
|     "'One wall threshold' is only visibile if this setting is set above the default value of 0.5, or if single-wall top surfaces is enabled."); | ||||
|     def->sidetext = L(""); | ||||
|     def->mode = comAdvanced; | ||||
|     def->min = 0.0; | ||||
|     def->max = 25.0; | ||||
|     def->set_default_value(new ConfigOptionFloat(0.5)); | ||||
| 
 | ||||
|     def = this->add("initial_layer_min_bead_width", coPercent); | ||||
|     def->label = L("First layer minimum wall width"); | ||||
|     def->category = L("Quality"); | ||||
|  |  | |||
|  | @ -784,6 +784,7 @@ PRINT_CONFIG_CLASS_DEFINE( | |||
|     ((ConfigOptionPercent,            tree_support_top_rate)) | ||||
|     ((ConfigOptionFloat,              tree_support_branch_diameter_organic)) | ||||
|     ((ConfigOptionFloat,              tree_support_branch_angle_organic)) | ||||
|     ((ConfigOptionFloat,              min_length_factor)) | ||||
| 
 | ||||
|     // Move all acceleration and jerk settings to object
 | ||||
|     ((ConfigOptionFloat,              default_acceleration)) | ||||
|  |  | |||
|  | @ -1127,6 +1127,7 @@ bool PrintObject::invalidate_state_by_config_options( | |||
|             || opt_key == "wall_transition_angle" | ||||
|             || opt_key == "wall_distribution_count" | ||||
|             || opt_key == "min_feature_size" | ||||
|             || opt_key == "min_length_factor" | ||||
|             || opt_key == "min_bead_width") { | ||||
|             steps.emplace_back(posSlice); | ||||
|         } else if ( | ||||
|  |  | |||
|  | @ -90,13 +90,18 @@ std::vector<Slic3r::ColorRGBA> get_extruders_colors() | |||
| } | ||||
| float FullyTransparentMaterialThreshold  = 0.1f; | ||||
| float FullTransparentModdifiedToFixAlpha = 0.3f; | ||||
| float FULL_BLACK_THRESHOLD = 0.18f; | ||||
| 
 | ||||
| Slic3r::ColorRGBA adjust_color_for_rendering(const Slic3r::ColorRGBA &colors) | ||||
| { | ||||
|     if (colors.a() < FullyTransparentMaterialThreshold) { // completely transparent
 | ||||
|         return {1, 1, 1, FullTransparentModdifiedToFixAlpha}; | ||||
|     } | ||||
|     return colors; | ||||
|     else if(colors.r() < FULL_BLACK_THRESHOLD && colors.g() < FULL_BLACK_THRESHOLD && colors.b() < FULL_BLACK_THRESHOLD) { // black
 | ||||
|         return {FULL_BLACK_THRESHOLD, FULL_BLACK_THRESHOLD, FULL_BLACK_THRESHOLD, colors.a()}; | ||||
|     } | ||||
|     else | ||||
|         return colors; | ||||
| } | ||||
| 
 | ||||
| namespace Slic3r { | ||||
|  |  | |||
|  | @ -695,7 +695,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co | |||
|      | ||||
|     bool have_arachne = config->opt_enum<PerimeterGeneratorType>("wall_generator") == PerimeterGeneratorType::Arachne; | ||||
|     for (auto el : { "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle", | ||||
|         "min_feature_size", "min_bead_width", "wall_distribution_count", "initial_layer_min_bead_width"}) | ||||
|         "min_feature_size", "min_length_factor", "min_bead_width", "wall_distribution_count", "initial_layer_min_bead_width"}) | ||||
|         toggle_line(el, have_arachne); | ||||
|     toggle_field("detect_thin_wall", !have_arachne); | ||||
|      | ||||
|  | @ -712,8 +712,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co | |||
|     toggle_line("make_overhang_printable_angle", have_make_overhang_printable); | ||||
|     toggle_line("make_overhang_printable_hole_size", have_make_overhang_printable); | ||||
|      | ||||
|     toggle_line("min_width_top_surface",config->opt_bool("only_one_wall_top")); | ||||
|      | ||||
|     toggle_line("min_width_top_surface", config->opt_bool("only_one_wall_top") || ((config->opt_float("min_length_factor") > 0.5f) && have_arachne)); // 0.5 is default value
 | ||||
| 
 | ||||
|     for (auto el : { "hole_to_polyhole_threshold", "hole_to_polyhole_twisted" }) | ||||
|         toggle_line(el, config->opt_bool("hole_to_polyhole")); | ||||
|      | ||||
|  |  | |||
|  | @ -2484,7 +2484,7 @@ bool GLGizmoEmboss::rev_checkbox(const std::string &name, | |||
|     // draw offseted input
 | ||||
|     auto draw_offseted_input = [this, &offset = m_gui_cfg->advanced_input_offset, &name, &value](){ | ||||
|         ImGui::SameLine(offset); | ||||
|         return m_imgui->bbl_checkbox(("##" + name).c_str(), value); | ||||
|         return m_imgui->bbl_checkbox(wxString::FromUTF8("##" + name), value); | ||||
|     }; | ||||
|     float undo_offset  = ImGui::GetStyle().WindowPadding.x; | ||||
|     return revertible(name, value, default_value, undo_tooltip, | ||||
|  |  | |||
|  | @ -1975,6 +1975,7 @@ void TabPrint::build() | |||
|         optgroup->append_single_option_line("initial_layer_min_bead_width"); | ||||
|         optgroup->append_single_option_line("min_bead_width"); | ||||
|         optgroup->append_single_option_line("min_feature_size"); | ||||
|         optgroup->append_single_option_line("min_length_factor"); | ||||
| 
 | ||||
|         optgroup = page->new_optgroup(L("Walls and surfaces"), L"param_advanced"); | ||||
|         optgroup->append_single_option_line("wall_sequence"); | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ endif() | |||
| if(NOT DEFINED BBL_INTERNAL_TESTING) | ||||
| set(BBL_INTERNAL_TESTING "0") | ||||
| endif() | ||||
| set(SoftFever_VERSION "1.9.0-beta") | ||||
| set(SoftFever_VERSION "2.0.0-dev") | ||||
| string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" | ||||
|        SoftFever_VERSION_MATCH ${SoftFever_VERSION}) | ||||
| set(ORCA_VERSION_MAJOR ${CMAKE_MATCH_1}) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 SoftFever
						SoftFever