mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'main' into main
This commit is contained in:
		
						commit
						d90a0df330
					
				
					 15 changed files with 1287 additions and 3245 deletions
				
			
		
							
								
								
									
										14
									
								
								.github/workflows/build_deps.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/build_deps.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -25,12 +25,12 @@ jobs: | ||||||
|       fail-fast: false |       fail-fast: false | ||||||
|       matrix: |       matrix: | ||||||
|         include: |         include: | ||||||
|           # - os: ubuntu-22.04 |           - os: ubuntu-20.04 | ||||||
|           - os: windows-latest |           - os: windows-latest | ||||||
|           # - os: macos-12 |           - os: macos-12 | ||||||
|           #   arch: x86_64 |             arch: x86_64 | ||||||
|           # - os: macos-12 |           - os: macos-12 | ||||||
|           #   arch: arm64 |             arch: arm64 | ||||||
|     runs-on: ${{ matrix.os }} |     runs-on: ${{ matrix.os }} | ||||||
| 
 | 
 | ||||||
|     steps: |     steps: | ||||||
|  | @ -82,7 +82,7 @@ jobs: | ||||||
|             ./build_release_macos.sh -dp -a arm64 |             ./build_release_macos.sh -dp -a arm64 | ||||||
| 
 | 
 | ||||||
|       - name: Build on Ubuntu |       - name: Build on Ubuntu | ||||||
|         if: matrix.os == 'ubuntu-22.04' |         if: matrix.os == 'ubuntu-20.04' | ||||||
|         working-directory: ${{ github.workspace }} |         working-directory: ${{ github.workspace }} | ||||||
|         run: | |         run: | | ||||||
|             sudo apt-get update |             sudo apt-get update | ||||||
|  | @ -119,7 +119,7 @@ jobs: | ||||||
|           path: ${{ github.workspace }}/deps/build/OrcaSlicer_dep |           path: ${{ github.workspace }}/deps/build/OrcaSlicer_dep | ||||||
| 
 | 
 | ||||||
|       - name: Upload Ubuntu artifacts |       - name: Upload Ubuntu artifacts | ||||||
|         if: matrix.os == 'ubuntu-22.04' |         if: matrix.os == 'ubuntu-20.04' | ||||||
|         uses: actions/upload-artifact@v3 |         uses: actions/upload-artifact@v3 | ||||||
|         with: |         with: | ||||||
|           name: OrcaSlicer_dep_ubuntu_${{ env.date }} |           name: OrcaSlicer_dep_ubuntu_${{ env.date }} | ||||||
|  |  | ||||||
|  | @ -178,7 +178,7 @@ then | ||||||
|          |          | ||||||
|         # make deps |         # make deps | ||||||
|         echo "[4/9] Building dependencies..." |         echo "[4/9] Building dependencies..." | ||||||
|         make -j$NCORES |         make deps -j$NCORES | ||||||
|         echo "done" |         echo "done" | ||||||
| 
 | 
 | ||||||
|         # rename wxscintilla # TODO: DeftDawg: Does OrcaSlicer need this? |         # rename wxscintilla # TODO: DeftDawg: Does OrcaSlicer need this? | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ You can download Orca Slicer here: [github releases page](https://github.com/Sof | ||||||
| - Auto calibrations for all printers | - Auto calibrations for all printers | ||||||
| - Sandwich(inner-outer-inner) mode - an improved version of the `External perimeters first` mode | - Sandwich(inner-outer-inner) mode - an improved version of the `External perimeters first` mode | ||||||
| - Precise wall | - Precise wall | ||||||
|  | - Polyholes conversion support [SuperSlicer Wiki: Polyholes](https://github.com/supermerill/SuperSlicer/wiki/Polyholes) | ||||||
| - Klipper support | - Klipper support | ||||||
| - More granular controls | - More granular controls | ||||||
| - More features can be found in [change notes](https://github.com/SoftFever/OrcaSlicer/releases/)   | - More features can be found in [change notes](https://github.com/SoftFever/OrcaSlicer/releases/)   | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								deps/CURL/CURL.cmake
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/CURL/CURL.cmake
									
										
									
									
										vendored
									
									
								
							|  | @ -65,6 +65,7 @@ orcaslicer_add_cmake_project(CURL | ||||||
|   #                     ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/curl-mods.patch |   #                     ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/curl-mods.patch | ||||||
|   CMAKE_ARGS |   CMAKE_ARGS | ||||||
|     -DBUILD_TESTING:BOOL=OFF |     -DBUILD_TESTING:BOOL=OFF | ||||||
|  |     -DBUILD_CURL_EXE:BOOL=OFF | ||||||
|     -DCMAKE_POSITION_INDEPENDENT_CODE=ON |     -DCMAKE_POSITION_INDEPENDENT_CODE=ON | ||||||
|     -DCURL_STATICLIB=${_curl_static} |     -DCURL_STATICLIB=${_curl_static} | ||||||
|     ${_curl_platform_flags} |     ${_curl_platform_flags} | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								deps/GMP/GMP.cmake
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								deps/GMP/GMP.cmake
									
										
									
									
										vendored
									
									
								
							|  | @ -57,7 +57,7 @@ else () | ||||||
|     endif () |     endif () | ||||||
| 
 | 
 | ||||||
|     ExternalProject_Add(dep_GMP |     ExternalProject_Add(dep_GMP | ||||||
|         URL https://gmplib.org/download/gmp/gmp-6.2.1.tar.bz2 |         URL https://github.com/SoftFever/OrcaSlicer_deps/releases/download/gmp-6.2.1/gmp-6.2.1.tar.bz2 | ||||||
|         URL_HASH SHA256=eae9326beb4158c386e39a356818031bd28f3124cf915f8c5b1dc4c7a36b4d7c |         URL_HASH SHA256=eae9326beb4158c386e39a356818031bd28f3124cf915f8c5b1dc4c7a36b4d7c | ||||||
|         DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/GMP |         DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/GMP | ||||||
|         BUILD_IN_SOURCE ON  |         BUILD_IN_SOURCE ON  | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -209,6 +209,8 @@ public: | ||||||
|     double ccw_angle(const Point &p1, const Point &p2) const; |     double ccw_angle(const Point &p1, const Point &p2) const; | ||||||
|     Point  projection_onto(const MultiPoint &poly) const; |     Point  projection_onto(const MultiPoint &poly) const; | ||||||
|     Point  projection_onto(const Line &line) const; |     Point  projection_onto(const Line &line) const; | ||||||
|  | 
 | ||||||
|  |     double distance_to(const Point &point) const { return (point - *this).cast<double>().norm(); } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| inline bool operator<(const Point &l, const Point &r)  | inline bool operator<(const Point &l, const Point &r)  | ||||||
|  |  | ||||||
|  | @ -765,8 +765,8 @@ static std::vector<std::string> s_Preset_print_options { | ||||||
|      "initial_layer_travel_speed", "exclude_object", "slow_down_layers", "infill_anchor", "infill_anchor_max","initial_layer_min_bead_width", |      "initial_layer_travel_speed", "exclude_object", "slow_down_layers", "infill_anchor", "infill_anchor_max","initial_layer_min_bead_width", | ||||||
|      "make_overhang_printable", "make_overhang_printable_angle", "make_overhang_printable_hole_size" ,"notes", |      "make_overhang_printable", "make_overhang_printable_angle", "make_overhang_printable_hole_size" ,"notes", | ||||||
|      "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extruder", "wiping_volumes_extruders","wipe_tower_bridging", "single_extruder_multi_material_priming", |      "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extruder", "wiping_volumes_extruders","wipe_tower_bridging", "single_extruder_multi_material_priming", | ||||||
|      "wipe_tower_rotation_angle", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_branch_angle_organic" |      "wipe_tower_rotation_angle", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_branch_angle_organic", | ||||||
| 
 |      "hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted" | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static std::vector<std::string> s_Preset_filament_options { | static std::vector<std::string> s_Preset_filament_options { | ||||||
|  |  | ||||||
|  | @ -480,6 +480,8 @@ private: | ||||||
|     void detect_overhangs_for_lift(); |     void detect_overhangs_for_lift(); | ||||||
|     void clear_overhangs_for_lift(); |     void clear_overhangs_for_lift(); | ||||||
| 
 | 
 | ||||||
|  |    void _transform_hole_to_polyholes(); | ||||||
|  | 
 | ||||||
|     // Has any support (not counting the raft).
 |     // Has any support (not counting the raft).
 | ||||||
|     void detect_surfaces_type(); |     void detect_surfaces_type(); | ||||||
|     void process_external_surfaces(); |     void process_external_surfaces(); | ||||||
|  |  | ||||||
|  | @ -4153,6 +4153,34 @@ def = this->add("filament_loading_speed", coFloats); | ||||||
|     def->mode = comAdvanced; |     def->mode = comAdvanced; | ||||||
|     def->set_default_value(new ConfigOptionFloat(0)); |     def->set_default_value(new ConfigOptionFloat(0)); | ||||||
| 
 | 
 | ||||||
|  |     def = this->add("hole_to_polyhole", coBool); | ||||||
|  |     def->label = L("Convert holes to polyholes"); | ||||||
|  |     def->category = L("Quality"); | ||||||
|  |     def->tooltip = L("Search for almost-circular holes that span more than one layer and convert the geometry to polyholes." | ||||||
|  |                      " Use the nozzle size and the (biggest) diameter to compute the polyhole." | ||||||
|  |                      "\nSee http://hydraraptor.blogspot.com/2011/02/polyholes.html"); | ||||||
|  |     def->mode = comAdvanced; | ||||||
|  |     def->set_default_value(new ConfigOptionBool(false)); | ||||||
|  | 
 | ||||||
|  |     def = this->add("hole_to_polyhole_threshold", coFloatOrPercent); | ||||||
|  |     def->label = L("Polyhole detection margin"); | ||||||
|  |     def->category = L("Quality"); | ||||||
|  |     def->tooltip = L("Maximum defection of a point to the estimated radius of the circle." | ||||||
|  |                      "\nAs cylinders are often exported as triangles of varying size, points may not be on the circle circumference." | ||||||
|  |                      " This setting allows you some leway to broaden the detection." | ||||||
|  |                      "\nIn mm or in % of the radius."); | ||||||
|  |     def->sidetext = L("mm or %"); | ||||||
|  |     def->max_literal = 10; | ||||||
|  |     def->mode = comAdvanced; | ||||||
|  |     def->set_default_value(new ConfigOptionFloatOrPercent(0.01, false)); | ||||||
|  | 
 | ||||||
|  |     def = this->add("hole_to_polyhole_twisted", coBool); | ||||||
|  |     def->label = L("Polyhole twist"); | ||||||
|  |     def->category = L("Quality"); | ||||||
|  |     def->tooltip = L("Rotate the polyhole every layer."); | ||||||
|  |     def->mode = comAdvanced; | ||||||
|  |     def->set_default_value(new ConfigOptionBool(true)); | ||||||
|  | 
 | ||||||
|     def = this->add("thumbnails", coPoints); |     def = this->add("thumbnails", coPoints); | ||||||
|     def->label = L("G-code thumbnails"); |     def->label = L("G-code thumbnails"); | ||||||
|     def->tooltip = L("Picture sizes to be stored into a .gcode and .sl1 / .sl1s files, in the following format: \"XxY, XxY, ...\""); |     def->tooltip = L("Picture sizes to be stored into a .gcode and .sl1 / .sl1s files, in the following format: \"XxY, XxY, ...\""); | ||||||
|  |  | ||||||
|  | @ -825,6 +825,9 @@ PRINT_CONFIG_CLASS_DEFINE( | ||||||
|     ((ConfigOptionBool,                 make_overhang_printable)) |     ((ConfigOptionBool,                 make_overhang_printable)) | ||||||
|     ((ConfigOptionBool,                 extra_perimeters_on_overhangs)) |     ((ConfigOptionBool,                 extra_perimeters_on_overhangs)) | ||||||
|     ((ConfigOptionBool,                 slowdown_for_curled_perimeters)) |     ((ConfigOptionBool,                 slowdown_for_curled_perimeters)) | ||||||
|  |     ((ConfigOptionBool,                 hole_to_polyhole)) | ||||||
|  |     ((ConfigOptionFloatOrPercent,       hole_to_polyhole_threshold)) | ||||||
|  |     ((ConfigOptionBool,                 hole_to_polyhole_twisted)) | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| PRINT_CONFIG_CLASS_DEFINE( | PRINT_CONFIG_CLASS_DEFINE( | ||||||
|  |  | ||||||
|  | @ -152,6 +152,145 @@ std::vector<std::reference_wrapper<const PrintRegion>> PrintObject::all_regions( | ||||||
|     return out; |     return out; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Polygons create_polyholes(const Point center, const coord_t radius, const coord_t nozzle_diameter, bool multiple) | ||||||
|  | { | ||||||
|  |     // n = max(round(2 * d), 3); // for 0.4mm nozzle
 | ||||||
|  |     size_t nb_edges = (int)std::max(3, (int)std::round(4.0 * unscaled(radius) * 0.4 / unscaled(nozzle_diameter))); | ||||||
|  |     // cylinder(h = h, r = d / cos (180 / n), $fn = n);
 | ||||||
|  |     //create x polyholes by rotation if multiple
 | ||||||
|  |     int nb_polyhole = 1; | ||||||
|  |     float rotation = 0; | ||||||
|  |     if (multiple) { | ||||||
|  |         nb_polyhole = 5; | ||||||
|  |         rotation = 2 * float(PI) / (nb_edges * nb_polyhole); | ||||||
|  |     } | ||||||
|  |     Polygons list; | ||||||
|  |     for (int i_poly = 0; i_poly < nb_polyhole; i_poly++) | ||||||
|  |         list.emplace_back(); | ||||||
|  |     for (int i_poly = 0; i_poly < nb_polyhole; i_poly++) { | ||||||
|  |         Polygon& pts = (((i_poly % 2) == 0) ? list[i_poly / 2] : list[(nb_polyhole + 1) / 2 + i_poly / 2]); | ||||||
|  |         const float new_radius = radius / float(std::cos(PI / nb_edges)); | ||||||
|  |         for (size_t i_edge = 0; i_edge < nb_edges; ++i_edge) { | ||||||
|  |             float angle = rotation * i_poly + (float(PI) * 2 * (float)i_edge) / nb_edges; | ||||||
|  |             pts.points.emplace_back(center.x() + new_radius * cos(angle), center.y() + new_radius * sin(angle)); | ||||||
|  |         } | ||||||
|  |         pts.make_clockwise(); | ||||||
|  |     } | ||||||
|  |     //alternate
 | ||||||
|  |     return list; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Detect and convert holes to polyholes, implementation is ported from SuperSlicer
 | ||||||
|  | void PrintObject::_transform_hole_to_polyholes() | ||||||
|  | { | ||||||
|  |     // get all circular holes for each layer
 | ||||||
|  |     // the id is center-diameter-extruderid
 | ||||||
|  |     //the tuple is Point center; float diameter_max; int extruder_id; coord_t max_variation; bool twist;
 | ||||||
|  |     std::vector<std::vector<std::pair<std::tuple<Point, float, int, coord_t, bool>, Polygon*>>> layerid2center; | ||||||
|  |     for (size_t i = 0; i < this->m_layers.size(); i++) layerid2center.emplace_back(); | ||||||
|  |     tbb::parallel_for( | ||||||
|  |         tbb::blocked_range<size_t>(0, m_layers.size()), | ||||||
|  |         [this, &layerid2center](const tbb::blocked_range<size_t>& range) { | ||||||
|  |         for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { | ||||||
|  |             m_print->throw_if_canceled(); | ||||||
|  |             Layer* layer = m_layers[layer_idx]; | ||||||
|  |             for (size_t region_idx = 0; region_idx < layer->m_regions.size(); ++region_idx) | ||||||
|  |             { | ||||||
|  |                 if (layer->m_regions[region_idx]->region().config().hole_to_polyhole) { | ||||||
|  |                     for (Surface& surf : layer->m_regions[region_idx]->slices.surfaces) { | ||||||
|  |                         for (Polygon& hole : surf.expolygon.holes) { | ||||||
|  |                             //test if convex (as it's clockwise bc it's a hole, we have to do the opposite)
 | ||||||
|  |                             if (hole.convex_points(PI).empty() && hole.points.size() > 8) { | ||||||
|  |                                 // Computing circle center
 | ||||||
|  |                                 Point center = hole.centroid(); | ||||||
|  |                                 double diameter_min = std::numeric_limits<float>::max(), diameter_max = 0; | ||||||
|  |                                 double diameter_sum = 0; | ||||||
|  |                                 for (int i = 0; i < hole.points.size(); ++i) { | ||||||
|  |                                     double dist = hole.points[i].distance_to(center); | ||||||
|  |                                     diameter_min = std::min(diameter_min, dist); | ||||||
|  |                                     diameter_max = std::max(diameter_max, dist); | ||||||
|  |                                     diameter_sum += dist; | ||||||
|  |                                 } | ||||||
|  |                                 //also use center of lines to check it's not a rectangle
 | ||||||
|  |                                 double diameter_line_min = std::numeric_limits<float>::max(), diameter_line_max = 0; | ||||||
|  |                                 Lines hole_lines = hole.lines(); | ||||||
|  |                                 for (Line l : hole_lines) { | ||||||
|  |                                     Point midline = (l.a + l.b) / 2; | ||||||
|  |                                     double dist = center.distance_to(midline); | ||||||
|  |                                     diameter_line_min = std::min(diameter_line_min, dist); | ||||||
|  |                                     diameter_line_max = std::max(diameter_line_max, dist); | ||||||
|  |                                 } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |                                 // SCALED_EPSILON was a bit too harsh. Now using a config, as some may want some harsh setting and some don't.
 | ||||||
|  |                                 coord_t max_variation = std::max(SCALED_EPSILON, scale_(this->m_layers[layer_idx]->m_regions[region_idx]->region().config().hole_to_polyhole_threshold.get_abs_value(unscaled(diameter_sum / hole.points.size())))); | ||||||
|  |                                 bool twist = this->m_layers[layer_idx]->m_regions[region_idx]->region().config().hole_to_polyhole_twisted.value; | ||||||
|  |                                 if (diameter_max - diameter_min < max_variation * 2 && diameter_line_max - diameter_line_min < max_variation * 2) { | ||||||
|  |                                     layerid2center[layer_idx].emplace_back( | ||||||
|  |                                         std::tuple<Point, float, int, coord_t, bool>{center, diameter_max, layer->m_regions[region_idx]->region().config().wall_filament.value, max_variation, twist}, & hole); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             // for layer->slices, it will be also replaced later.
 | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |     //sort holes per center-diameter
 | ||||||
|  |     std::map<std::tuple<Point, float, int, coord_t, bool>, std::vector<std::pair<Polygon*, int>>> id2layerz2hole; | ||||||
|  | 
 | ||||||
|  |     //search & find hole that span at least X layers
 | ||||||
|  |     const size_t min_nb_layers = 2; | ||||||
|  |     for (size_t layer_idx = 0; layer_idx < this->m_layers.size(); ++layer_idx) { | ||||||
|  |         for (size_t hole_idx = 0; hole_idx < layerid2center[layer_idx].size(); ++hole_idx) { | ||||||
|  |             //get all other same polygons
 | ||||||
|  |             std::tuple<Point, float, int, coord_t, bool>& id = layerid2center[layer_idx][hole_idx].first; | ||||||
|  |             float max_z = layers()[layer_idx]->print_z; | ||||||
|  |             std::vector<std::pair<Polygon*, int>> holes; | ||||||
|  |             holes.emplace_back(layerid2center[layer_idx][hole_idx].second, layer_idx); | ||||||
|  |             for (size_t search_layer_idx = layer_idx + 1; search_layer_idx < this->m_layers.size(); ++search_layer_idx) { | ||||||
|  |                 if (layers()[search_layer_idx]->print_z - layers()[search_layer_idx]->height - max_z > EPSILON) break; | ||||||
|  |                 //search an other polygon with same id
 | ||||||
|  |                 for (size_t search_hole_idx = 0; search_hole_idx < layerid2center[search_layer_idx].size(); ++search_hole_idx) { | ||||||
|  |                     std::tuple<Point, float, int, coord_t, bool>& search_id = layerid2center[search_layer_idx][search_hole_idx].first; | ||||||
|  |                     if (std::get<2>(id) == std::get<2>(search_id) | ||||||
|  |                         && std::get<0>(id).distance_to(std::get<0>(search_id)) < std::get<3>(id) | ||||||
|  |                         && std::abs(std::get<1>(id) - std::get<1>(search_id)) < std::get<3>(id) | ||||||
|  |                         ) { | ||||||
|  |                         max_z = layers()[search_layer_idx]->print_z; | ||||||
|  |                         holes.emplace_back(layerid2center[search_layer_idx][search_hole_idx].second, search_layer_idx); | ||||||
|  |                         layerid2center[search_layer_idx].erase(layerid2center[search_layer_idx].begin() + search_hole_idx); | ||||||
|  |                         search_hole_idx--; | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             //check if strait hole or first layer hole (cause of first layer compensation)
 | ||||||
|  |             if (holes.size() >= min_nb_layers || (holes.size() == 1 && holes[0].second == 0)) { | ||||||
|  |                 id2layerz2hole.emplace(std::move(id), std::move(holes)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     //create a polyhole per id and replace holes points by it.
 | ||||||
|  |     for (auto entry : id2layerz2hole) { | ||||||
|  |         Polygons polyholes = create_polyholes(std::get<0>(entry.first), std::get<1>(entry.first), scale_(print()->config().nozzle_diameter.get_at(std::get<2>(entry.first) - 1)), std::get<4>(entry.first)); | ||||||
|  |         for (auto& poly_to_replace : entry.second) { | ||||||
|  |             Polygon polyhole = polyholes[poly_to_replace.second % polyholes.size()]; | ||||||
|  |             //search the clone in layers->slices
 | ||||||
|  |             for (ExPolygon& explo_slice : m_layers[poly_to_replace.second]->lslices) { | ||||||
|  |                 for (Polygon& poly_slice : explo_slice.holes) { | ||||||
|  |                     if (poly_slice.points == poly_to_replace.first->points) { | ||||||
|  |                         poly_slice.points = polyhole.points; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             // copy
 | ||||||
|  |             poly_to_replace.first->points = polyhole.points; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // 1) Merges typed region slices into stInternal type.
 | // 1) Merges typed region slices into stInternal type.
 | ||||||
| // 2) Increases an "extra perimeters" counter at region slices where needed.
 | // 2) Increases an "extra perimeters" counter at region slices where needed.
 | ||||||
| // 3) Generates perimeters, gap fills and fill regions (fill regions of type stInternal).
 | // 3) Generates perimeters, gap fills and fill regions (fill regions of type stInternal).
 | ||||||
|  | @ -816,6 +955,9 @@ bool PrintObject::invalidate_state_by_config_options( | ||||||
|             || opt_key == "max_bridge_length" |             || opt_key == "max_bridge_length" | ||||||
|             || opt_key == "support_interface_top_layers" |             || opt_key == "support_interface_top_layers" | ||||||
|             || opt_key == "support_critical_regions_only" |             || opt_key == "support_critical_regions_only" | ||||||
|  |             || opt_key == "hole_to_polyhole" | ||||||
|  |             || opt_key == "hole_to_polyhole_threshold" | ||||||
|  |             || opt_key == "hole_to_polyhole_twisted" | ||||||
|             ) { |             ) { | ||||||
|             steps.emplace_back(posSlice); |             steps.emplace_back(posSlice); | ||||||
|         } else if (opt_key == "enable_support") { |         } else if (opt_key == "enable_support") { | ||||||
|  |  | ||||||
|  | @ -825,6 +825,9 @@ void PrintObject::slice() | ||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |     // Detect and process holes that should be converted to polyholes
 | ||||||
|  |     this->_transform_hole_to_polyholes(); | ||||||
|  | 
 | ||||||
|     // BBS: the actual first layer slices stored in layers are re-sorted by volume group and will be used to generate brim
 |     // BBS: the actual first layer slices stored in layers are re-sorted by volume group and will be used to generate brim
 | ||||||
|     groupingVolumesForBrim(this, m_layers, firstLayerReplacedBy); |     groupingVolumesForBrim(this, m_layers, firstLayerReplacedBy); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -721,6 +721,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co | ||||||
|     toggle_line("exclude_object", gcflavor == gcfKlipper); |     toggle_line("exclude_object", gcflavor == gcfKlipper); | ||||||
| 
 | 
 | ||||||
|     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")); | ||||||
|  | 
 | ||||||
|  |     for (auto el : { "hole_to_polyhole_threshold", "hole_to_polyhole_twisted" }) | ||||||
|  |         toggle_line(el, config->opt_bool("hole_to_polyhole")); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/) | void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/) | ||||||
|  |  | ||||||
|  | @ -1870,6 +1870,9 @@ void TabPrint::build() | ||||||
|         optgroup->append_single_option_line("elefant_foot_compensation"); |         optgroup->append_single_option_line("elefant_foot_compensation"); | ||||||
|         optgroup->append_single_option_line("elefant_foot_compensation_layers"); |         optgroup->append_single_option_line("elefant_foot_compensation_layers"); | ||||||
|         optgroup->append_single_option_line("precise_outer_wall"); |         optgroup->append_single_option_line("precise_outer_wall"); | ||||||
|  |         optgroup->append_single_option_line("hole_to_polyhole"); | ||||||
|  |         optgroup->append_single_option_line("hole_to_polyhole_threshold"); | ||||||
|  |         optgroup->append_single_option_line("hole_to_polyhole_twisted"); | ||||||
| 
 | 
 | ||||||
|         optgroup = page->new_optgroup(L("Ironing"), L"param_ironing"); |         optgroup = page->new_optgroup(L("Ironing"), L"param_ironing"); | ||||||
|         optgroup->append_single_option_line("ironing_type"); |         optgroup->append_single_option_line("ironing_type"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Musicdad
						Musicdad