mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	WIP: Initial Fuzzy Skin implementaiton #2010
Based on pull request Experimental fuzzy skin mode #4611 by @etet100 and on CuraEngine implementation of perimeter fuzzyfication void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh)
This commit is contained in:
		
							parent
							
								
									d9448c9f2a
								
							
						
					
					
						commit
						4620402ab4
					
				
					 9 changed files with 320 additions and 4 deletions
				
			
		|  | @ -5,6 +5,7 @@ | |||
| 
 | ||||
| #include <cmath> | ||||
| #include <cassert> | ||||
| #include <chrono> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
|  | @ -230,8 +231,128 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime | |||
|     return out; | ||||
| } | ||||
| 
 | ||||
| enum class FuzzyShape { | ||||
|     Triangle, | ||||
|     Sawtooth, | ||||
|     Random | ||||
| }; | ||||
| 
 | ||||
| static void fuzzy_polygon(Polygon &poly, FuzzyShape shape, double fuzzy_skin_thickness, double fuzzy_skin_point_dist) | ||||
| { | ||||
| #if 0 | ||||
|     Point last = poly.points.at(poly.points.size() - 1); | ||||
|     Point last_processed = last; | ||||
| 
 | ||||
|     double max_length = scale_(2); | ||||
|     double min_length = scale_(1); | ||||
| 
 | ||||
|     if (poly.length() < scale_(5)) | ||||
|         return; | ||||
| 
 | ||||
|     deepness *= 3; | ||||
| 
 | ||||
|     bool triangle_or_sawtooth = shape == FuzzyShape::Sawtooth; | ||||
|     double length_sum = 0; | ||||
|     Points::iterator it = poly.points.begin(); | ||||
|     while (it != poly.points.end()) { | ||||
|         Point &pt = *it; | ||||
| 
 | ||||
|         Line line(last, pt); | ||||
|         double length = line.length(); | ||||
| 
 | ||||
|         // split long line
 | ||||
|         if (length > max_length) { | ||||
|             auto parts = int(ceil(length / max_length)); | ||||
|             if (parts == 2) { | ||||
|                 Point point_to_insert(line.midpoint()); | ||||
|                 it = poly.points.insert(it, point_to_insert); | ||||
|             } | ||||
|             else { | ||||
|                 Vector part_vector = line.vector() / parts; | ||||
| 
 | ||||
|                 Points points_to_insert; | ||||
|                 Point point_to_insert(last); | ||||
|                 while (--parts) { | ||||
|                     point_to_insert += part_vector; | ||||
|                     Point point_to_insert_2(point_to_insert); | ||||
|                     points_to_insert.push_back(point_to_insert_2); | ||||
|                 } | ||||
| 
 | ||||
|                 it = poly.points.insert(it, points_to_insert.begin(), points_to_insert.end()); | ||||
|             } | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         length_sum += length; | ||||
| 
 | ||||
|         // join short lines
 | ||||
|         if (length_sum < min_length) { | ||||
|             last = pt; | ||||
|             it = poly.points.erase(it); | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         line = Line(last_processed, pt); | ||||
|         last = pt; | ||||
|         last_processed = pt; | ||||
| 
 | ||||
|         if (shape == FuzzyShape::Random) { | ||||
|             triangle_or_sawtooth = !(rand() % 2); | ||||
|         } | ||||
| 
 | ||||
|         Point point_to_insert(triangle_or_sawtooth ? pt : line.midpoint()); | ||||
| 
 | ||||
|         int scale = (rand() % deepness) + 1; | ||||
| 
 | ||||
|         Vec2d normal = line.normal().cast<double>(); | ||||
|         normal /= line.length() / scale_(1.) / ((double)scale / 20.); | ||||
| 
 | ||||
|         it = poly.points.insert(it, point_to_insert + normal.cast<coord_t>()) + 2; | ||||
| 
 | ||||
|         length_sum = 0; | ||||
|     } | ||||
| 
 | ||||
| #else | ||||
|     const double min_dist_between_points = fuzzy_skin_point_dist * 3. / 4.; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value
 | ||||
|     const double range_random_point_dist = fuzzy_skin_point_dist / 2.; | ||||
|     double dist_left_over = double(rand()) * (min_dist_between_points / 2) / double(RAND_MAX); // the distance to be traversed on the line before making the first new point
 | ||||
|     Point* p0 = &poly.points.back(); | ||||
|     Points out; | ||||
|     out.reserve(poly.points.size()); | ||||
|     for (Point &p1 : poly.points) | ||||
|     { // 'a' is the (next) new point between p0 and p1
 | ||||
|         Vec2d  p0p1      = (p1 - *p0).cast<double>(); | ||||
|         double p0p1_size = p0p1.norm(); | ||||
|         // so that p0p1_size - dist_last_point evaulates to dist_left_over - p0p1_size
 | ||||
|         double dist_last_point = dist_left_over + p0p1_size * 2.; | ||||
|         for (double p0pa_dist = dist_left_over; p0pa_dist < p0p1_size; | ||||
|             p0pa_dist += min_dist_between_points + double(rand()) * range_random_point_dist / double(RAND_MAX)) | ||||
|         { | ||||
|             double r = double(rand()) * (fuzzy_skin_thickness * 2.) / double(RAND_MAX) - fuzzy_skin_thickness; | ||||
|             out.emplace_back(*p0 + (p0p1 * (p0pa_dist / p0p1_size) + perp(p0p1).cast<double>().normalized() * r).cast<coord_t>()); | ||||
|             dist_last_point = p0pa_dist; | ||||
|         } | ||||
|         dist_left_over = p0p1_size - dist_last_point; | ||||
|         p0 = &p1; | ||||
|     } | ||||
|     while (out.size() < 3) { | ||||
|         size_t point_idx = poly.size() - 2; | ||||
|         out.emplace_back(poly[point_idx]); | ||||
|         if (point_idx == 0) | ||||
|             break; | ||||
|         -- point_idx; | ||||
|     } | ||||
|     if (out.size() >= 3) | ||||
|         poly.points = std::move(out); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void PerimeterGenerator::process() | ||||
| { | ||||
|     // nasty hack! initialize random generator
 | ||||
|     auto time_us = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()).time_since_epoch()).count(); | ||||
|     srand(this->layer_id * time_us); | ||||
| 
 | ||||
|     // other perimeters
 | ||||
|     m_mm3_per_mm               		= this->perimeter_flow.mm3_per_mm(); | ||||
|     coord_t perimeter_width         = this->perimeter_flow.scaled_width(); | ||||
|  | @ -272,6 +393,32 @@ void PerimeterGenerator::process() | |||
|         m_lower_slices_polygons = offset(*this->lower_slices, float(scale_(+nozzle_diameter/2))); | ||||
|     } | ||||
| 
 | ||||
|     // fuzzy skin configuration
 | ||||
|     double fuzzy_skin_thickness; | ||||
|     double fuzzy_skin_point_dist; | ||||
|     FuzzyShape fuzzy_skin_shape; | ||||
|     if (this->object_config->fuzzy_skin_perimeter_mode != FuzzySkinPerimeterMode::None) { | ||||
|         switch (this->object_config->fuzzy_skin_shape) { | ||||
|         case FuzzySkinShape::Triangle1: | ||||
|         case FuzzySkinShape::Triangle2: | ||||
|         case FuzzySkinShape::Triangle3: | ||||
|             fuzzy_skin_shape = FuzzyShape::Triangle; | ||||
|             break; | ||||
|         case FuzzySkinShape::Sawtooth1: | ||||
|         case FuzzySkinShape::Sawtooth2: | ||||
|         case FuzzySkinShape::Sawtooth3: | ||||
|             fuzzy_skin_shape = FuzzyShape::Sawtooth; | ||||
|             break; | ||||
|         case FuzzySkinShape::Random1: | ||||
|         case FuzzySkinShape::Random2: | ||||
|         case FuzzySkinShape::Random3: | ||||
|             fuzzy_skin_shape = FuzzyShape::Random; | ||||
|             break; | ||||
|         } | ||||
|         fuzzy_skin_thickness  = scale_(this->object_config->fuzzy_skin_thickness); | ||||
|         fuzzy_skin_point_dist = scale_(this->object_config->fuzzy_skin_point_dist); | ||||
|     } | ||||
| 
 | ||||
|     // we need to process each island separately because we might have different
 | ||||
|     // extra perimeters for each one
 | ||||
|     for (const Surface &surface : this->slices->surfaces) { | ||||
|  | @ -352,13 +499,35 @@ void PerimeterGenerator::process() | |||
|                     // If i > loop_number, we were looking just for gaps.
 | ||||
|                     break; | ||||
|                 } | ||||
|                 for (const ExPolygon &expolygon : offsets) { | ||||
|                 for (ExPolygon &expolygon : offsets) { | ||||
| 	                // Outer contour may overlap with an inner contour,
 | ||||
| 	                // inner contour may overlap with another inner contour,
 | ||||
| 	                // outer contour may overlap with itself.
 | ||||
| 	                //FIXME evaluate the overlaps, annotate each point with an overlap depth,
 | ||||
| 	                // compensate for the depth of intersection.
 | ||||
|                     contours[i].emplace_back(PerimeterGeneratorLoop(expolygon.contour, i, true)); | ||||
| 
 | ||||
|                     bool skip_polygon = false; | ||||
| 
 | ||||
|                     if (this->object_config->fuzzy_skin_perimeter_mode != FuzzySkinPerimeterMode::None) { | ||||
|                         if (i == 0 && (this->object_config->fuzzy_skin_perimeter_mode != FuzzySkinPerimeterMode::ExternalSkipFirst || this->layer_id > 0)) { | ||||
|                             if ( | ||||
|                                 this->object_config->fuzzy_skin_perimeter_mode == FuzzySkinPerimeterMode::External || | ||||
|                                 this->object_config->fuzzy_skin_perimeter_mode ==  FuzzySkinPerimeterMode::ExternalSkipFirst | ||||
|                             ) { | ||||
|                                 ExPolygon expolygon_fuzzy(expolygon); | ||||
|                                 fuzzy_polygon(expolygon_fuzzy.contour, fuzzy_skin_shape, fuzzy_skin_thickness, fuzzy_skin_point_dist); | ||||
|                                 // compensate for the depth of intersection.
 | ||||
|                                 contours[i].emplace_back(PerimeterGeneratorLoop(expolygon_fuzzy.contour, i, true));  | ||||
|                                 skip_polygon = true; | ||||
|                             } else | ||||
|                                 fuzzy_polygon(expolygon.contour, fuzzy_skin_shape, fuzzy_skin_thickness, fuzzy_skin_point_dist); | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     if (!skip_polygon) { | ||||
|                         // compensate for the depth of intersection.
 | ||||
|                         contours[i].emplace_back(PerimeterGeneratorLoop(expolygon.contour, i, true)); | ||||
|                     } | ||||
| 
 | ||||
|                     if (! expolygon.holes.empty()) { | ||||
|                         holes[i].reserve(holes[i].size() + expolygon.holes.size()); | ||||
|                         for (const Polygon &hole : expolygon.holes) | ||||
|  |  | |||
|  | @ -411,6 +411,7 @@ const std::vector<std::string>& Preset::print_options() | |||
|         "solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first",  | ||||
|     	"ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing", | ||||
|         "max_print_speed", "max_volumetric_speed", "avoid_crossing_perimeters_max_detour", | ||||
|         "fuzzy_skin_perimeter_mode", "fuzzy_skin_shape", "fuzzy_skin_thickness", "fuzzy_skin_point_dist", | ||||
| #ifdef HAS_PRESSURE_EQUALIZER | ||||
|         "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", | ||||
| #endif /* HAS_PRESSURE_EQUALIZER */ | ||||
|  |  | |||
|  | @ -1007,6 +1007,68 @@ void PrintConfigDef::init_fff_params() | |||
|     def->mode = comExpert; | ||||
|     def->set_default_value(new ConfigOptionInts { 0 }); | ||||
| 
 | ||||
|     def = this->add("fuzzy_skin_perimeter_mode", coEnum); | ||||
|     def->label = L("Fuzzy skin perimeter mode"); | ||||
|     def->category = L("Fuzzy Skin"); | ||||
|     def->tooltip = L("Fuzzy skin perimeter mode."); | ||||
| 
 | ||||
|     def->enum_keys_map = &ConfigOptionEnum<FuzzySkinPerimeterMode>::get_enum_values(); | ||||
|     def->enum_values.push_back("none"); | ||||
|     def->enum_values.push_back("external_only"); | ||||
|     def->enum_values.push_back("external_only_skip_first_layer"); | ||||
|     def->enum_values.push_back("all"); | ||||
|     def->enum_labels.push_back(L("None")); | ||||
|     def->enum_labels.push_back(L("External")); | ||||
|     def->enum_labels.push_back(L("External (skip first layer)")); | ||||
|     def->enum_labels.push_back(L("All perimeters")); | ||||
|     def->mode = comSimple; | ||||
|     def->set_default_value(new ConfigOptionEnum<FuzzySkinPerimeterMode>(FuzzySkinPerimeterMode::None)); | ||||
| 
 | ||||
|     def = this->add("fuzzy_skin_shape", coEnum); | ||||
|     def->label = L("Fuzzy skin shape"); | ||||
|     def->category = L("Fuzzy Skin"); | ||||
|     def->tooltip = L("Fuzzy skin shape."); | ||||
| 
 | ||||
|     def->enum_keys_map = &ConfigOptionEnum<FuzzySkinShape>::get_enum_values(); | ||||
|     def->enum_values.push_back("triangle1"); | ||||
|     def->enum_values.push_back("triangle2"); | ||||
|     def->enum_values.push_back("triangle3"); | ||||
|     def->enum_values.push_back("sawtooth1"); | ||||
|     def->enum_values.push_back("sawtooth2"); | ||||
|     def->enum_values.push_back("sawtooth3"); | ||||
|     def->enum_values.push_back("random1"); | ||||
|     def->enum_values.push_back("random2"); | ||||
|     def->enum_values.push_back("random3"); | ||||
|     def->enum_labels.push_back(L("Triangle (1)")); | ||||
|     def->enum_labels.push_back(L("Triangle (2)")); | ||||
|     def->enum_labels.push_back(L("Triangle (3)")); | ||||
|     def->enum_labels.push_back(L("Sawtooth (1)")); | ||||
|     def->enum_labels.push_back(L("Sawtooth (2)")); | ||||
|     def->enum_labels.push_back(L("Sawtooth (3)")); | ||||
|     def->enum_labels.push_back(L("Random (1)")); | ||||
|     def->enum_labels.push_back(L("Random (2)")); | ||||
|     def->enum_labels.push_back(L("Random (3)")); | ||||
|     def->mode = comSimple; | ||||
|     def->set_default_value(new ConfigOptionEnum<FuzzySkinShape>(FuzzySkinShape::Triangle1)); | ||||
| 
 | ||||
|     def = this->add("fuzzy_skin_thickness", coFloat); | ||||
|     def->label = L("Fuzzy skin thickness"); | ||||
|     def->category = L("Fuzzy Skin"); | ||||
|     def->tooltip = L(""); | ||||
|     def->sidetext = L("mm"); | ||||
|     def->min = 0; | ||||
|     def->mode = comAdvanced; | ||||
|     def->set_default_value(new ConfigOptionFloat(0.3)); | ||||
| 
 | ||||
|     def = this->add("fuzzy_skin_point_dist", coFloat); | ||||
|     def->label = L("Fuzzy skin point distance"); | ||||
|     def->category = L("Fuzzy Skin"); | ||||
|     def->tooltip = L(""); | ||||
|     def->sidetext = L("mm"); | ||||
|     def->min = 0; | ||||
|     def->mode = comAdvanced; | ||||
|     def->set_default_value(new ConfigOptionFloat(0.8)); | ||||
| 
 | ||||
|     def = this->add("gap_fill_speed", coFloat); | ||||
|     def->label = L("Gap fill"); | ||||
|     def->category = L("Speed"); | ||||
|  |  | |||
|  | @ -43,6 +43,25 @@ enum AuthorizationType { | |||
|     atKeyPassword, atUserPassword | ||||
| }; | ||||
| 
 | ||||
| enum class FuzzySkinPerimeterMode { | ||||
|     None, | ||||
|     External, | ||||
|     ExternalSkipFirst, | ||||
|     All | ||||
| }; | ||||
| 
 | ||||
| enum class FuzzySkinShape { | ||||
|     Triangle1, | ||||
|     Triangle2, | ||||
|     Triangle3, | ||||
|     Sawtooth1, | ||||
|     Sawtooth2, | ||||
|     Sawtooth3, | ||||
|     Random1, | ||||
|     Random2, | ||||
|     Random3 | ||||
| }; | ||||
| 
 | ||||
| enum InfillPattern : int { | ||||
|     ipRectilinear, ipMonotonic, ipAlignedRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb, | ||||
|     ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipAdaptiveCubic, ipSupportCubic, ipCount, | ||||
|  | @ -140,6 +159,33 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<AuthorizationType | |||
|     return keys_map; | ||||
| } | ||||
| 
 | ||||
| template<> inline const t_config_enum_values& ConfigOptionEnum<FuzzySkinPerimeterMode>::get_enum_values() { | ||||
|     static t_config_enum_values keys_map; | ||||
|     if (keys_map.empty()) { | ||||
|         keys_map["none"]                           = int(FuzzySkinPerimeterMode::None); | ||||
|         keys_map["external_only"]                  = int(FuzzySkinPerimeterMode::External); | ||||
|         keys_map["external_only_skip_first_layer"] = int(FuzzySkinPerimeterMode::ExternalSkipFirst); | ||||
|         keys_map["all"]                            = int(FuzzySkinPerimeterMode::All); | ||||
|     } | ||||
|     return keys_map; | ||||
| } | ||||
| 
 | ||||
| template<> inline const t_config_enum_values& ConfigOptionEnum<FuzzySkinShape>::get_enum_values() { | ||||
|     static t_config_enum_values keys_map; | ||||
|     if (keys_map.empty()) { | ||||
|         keys_map["triangle1"]           = int(FuzzySkinShape::Triangle1); | ||||
|         keys_map["triangle2"]           = int(FuzzySkinShape::Triangle2); | ||||
|         keys_map["triangle3"]           = int(FuzzySkinShape::Triangle3); | ||||
|         keys_map["sawtooth1"]           = int(FuzzySkinShape::Sawtooth1); | ||||
|         keys_map["sawtooth2"]           = int(FuzzySkinShape::Sawtooth2); | ||||
|         keys_map["sawtooth3"]           = int(FuzzySkinShape::Sawtooth3); | ||||
|         keys_map["random1"]             = int(FuzzySkinShape::Random1); | ||||
|         keys_map["random2"]             = int(FuzzySkinShape::Random2); | ||||
|         keys_map["random3"]             = int(FuzzySkinShape::Random3); | ||||
|     } | ||||
|     return keys_map; | ||||
| } | ||||
| 
 | ||||
| template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enum_values() { | ||||
|     static t_config_enum_values keys_map; | ||||
|     if (keys_map.empty()) { | ||||
|  | @ -432,6 +478,10 @@ public: | |||
|     ConfigOptionFloat               elefant_foot_compensation; | ||||
|     ConfigOptionFloatOrPercent      extrusion_width; | ||||
|     ConfigOptionFloatOrPercent      first_layer_height; | ||||
|     ConfigOptionEnum<FuzzySkinPerimeterMode>    fuzzy_skin_perimeter_mode; | ||||
|     ConfigOptionEnum<FuzzySkinShape>            fuzzy_skin_shape; | ||||
|     ConfigOptionFloat               fuzzy_skin_thickness; | ||||
|     ConfigOptionFloat               fuzzy_skin_point_dist; | ||||
|     ConfigOptionBool                infill_only_where_needed; | ||||
|     // Force the generation of solid shells between adjacent materials/volumes.
 | ||||
|     ConfigOptionBool                interface_shells; | ||||
|  | @ -477,6 +527,10 @@ protected: | |||
|         OPT_PTR(elefant_foot_compensation); | ||||
|         OPT_PTR(extrusion_width); | ||||
|         OPT_PTR(first_layer_height); | ||||
|         OPT_PTR(fuzzy_skin_perimeter_mode); | ||||
|         OPT_PTR(fuzzy_skin_shape); | ||||
|         OPT_PTR(fuzzy_skin_thickness); | ||||
|         OPT_PTR(fuzzy_skin_point_dist); | ||||
|         OPT_PTR(infill_only_where_needed); | ||||
|         OPT_PTR(interface_shells); | ||||
|         OPT_PTR(layer_height); | ||||
|  |  | |||
|  | @ -521,6 +521,10 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_ | |||
|             || opt_key == "gap_fill_speed" | ||||
|             || opt_key == "overhangs" | ||||
|             || opt_key == "first_layer_extrusion_width" | ||||
|             || opt_key == "fuzzy_skin_perimeter_mode" | ||||
|             || opt_key == "fuzzy_skin_shape" | ||||
|             || opt_key == "fuzzy_skin_thickness" | ||||
|             || opt_key == "fuzzy_skin_point_dist" | ||||
|             || opt_key == "perimeter_extrusion_width" | ||||
|             || opt_key == "infill_overlap" | ||||
|             || opt_key == "thin_walls" | ||||
|  |  | |||
|  | @ -1200,6 +1200,10 @@ boost::any& Choice::get_value() | |||
| 		} | ||||
| 		else if (m_opt_id.compare("ironing_type") == 0) | ||||
| 			m_value = static_cast<IroningType>(ret_enum); | ||||
|         else if (m_opt_id.compare("fuzzy_skin_perimeter_mode") == 0) | ||||
|             m_value = static_cast<FuzzySkinPerimeterMode>(ret_enum); | ||||
|         else if (m_opt_id.compare("fuzzy_skin_shape") == 0) | ||||
|             m_value = static_cast<FuzzySkinShape>(ret_enum); | ||||
| 		else if (m_opt_id.compare("gcode_flavor") == 0) | ||||
| 			m_value = static_cast<GCodeFlavor>(ret_enum); | ||||
| 		else if (m_opt_id.compare("machine_limits_usage") == 0) | ||||
|  |  | |||
|  | @ -182,6 +182,10 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt | |||
| 				config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value)));  | ||||
| 			else if (opt_key.compare("ironing_type") == 0) | ||||
| 				config.set_key_value(opt_key, new ConfigOptionEnum<IroningType>(boost::any_cast<IroningType>(value)));  | ||||
| 			else if (opt_key.compare("fuzzy_skin_perimeter_mode") == 0) | ||||
| 				config.set_key_value(opt_key, new ConfigOptionEnum<FuzzySkinPerimeterMode>(boost::any_cast<FuzzySkinPerimeterMode>(value)));  | ||||
| 			else if (opt_key.compare("fuzzy_skin_shape") == 0) | ||||
| 				config.set_key_value(opt_key, new ConfigOptionEnum<FuzzySkinShape>(boost::any_cast<FuzzySkinShape>(value)));  | ||||
| 			else if (opt_key.compare("gcode_flavor") == 0) | ||||
| 				config.set_key_value(opt_key, new ConfigOptionEnum<GCodeFlavor>(boost::any_cast<GCodeFlavor>(value)));  | ||||
| 			else if (opt_key.compare("machine_limits_usage") == 0) | ||||
|  |  | |||
|  | @ -870,6 +870,12 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config | |||
| 		else if (opt_key == "ironing_type") { | ||||
| 			ret = static_cast<int>(config.option<ConfigOptionEnum<IroningType>>(opt_key)->value); | ||||
| 		} | ||||
|         else if (opt_key == "fuzzy_skin_perimeter_mode") { | ||||
|             ret = static_cast<int>(config.option<ConfigOptionEnum<FuzzySkinPerimeterMode>>(opt_key)->value); | ||||
|         } | ||||
|         else if (opt_key == "fuzzy_skin_shape") { | ||||
|             ret = static_cast<int>(config.option<ConfigOptionEnum<FuzzySkinShape>>(opt_key)->value); | ||||
|         } | ||||
| 		else if (opt_key == "gcode_flavor") { | ||||
| 			ret = static_cast<int>(config.option<ConfigOptionEnum<GCodeFlavor>>(opt_key)->value); | ||||
| 		} | ||||
|  |  | |||
|  | @ -1434,6 +1434,18 @@ void TabPrint::build() | |||
|         optgroup->append_single_option_line("seam_position", category_path + "seam-position"); | ||||
|         optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first"); | ||||
| 
 | ||||
|         optgroup = page->new_optgroup(L("Fuzzy skin (experimental)")); | ||||
|         Option option = optgroup->get_option("fuzzy_skin_perimeter_mode"); | ||||
|         option.opt.width = 30; | ||||
|         optgroup->append_single_option_line(option); | ||||
| #if 0 | ||||
|         option = optgroup->get_option("fuzzy_skin_shape"); | ||||
|         option.opt.width = 30; | ||||
|         optgroup->append_single_option_line(option); | ||||
| #endif | ||||
|         optgroup->append_single_option_line(optgroup->get_option("fuzzy_skin_thickness")); | ||||
|         optgroup->append_single_option_line(optgroup->get_option("fuzzy_skin_point_dist")); | ||||
| 
 | ||||
|     page = add_options_page(L("Infill"), "infill"); | ||||
|         category_path = "infill_42#"; | ||||
|         optgroup = page->new_optgroup(L("Infill")); | ||||
|  | @ -1597,7 +1609,7 @@ void TabPrint::build() | |||
|         optgroup = page->new_optgroup(L("Output file")); | ||||
|         optgroup->append_single_option_line("gcode_comments"); | ||||
|         optgroup->append_single_option_line("gcode_label_objects"); | ||||
|         Option option = optgroup->get_option("output_filename_format"); | ||||
|         option = optgroup->get_option("output_filename_format"); | ||||
|         option.opt.full_width = true; | ||||
|         optgroup->append_single_option_line(option); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Bubnik
						Vojtech Bubnik