diff --git a/README.md b/README.md index 7716210a5..159195f1f 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ can be used separately. * Many other little options and corrections (like the filled concentric pattern). * It has also all the current slic3rPE features. +#### Complete changelog [here](https://github.com/supermerill/Slic3r/wiki) + See the wiki for examples. ### What are Slic3r's main features? diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 6f22ba89e..cad059616 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -198,6 +198,20 @@ void ConfigBase::apply_only(const ConfigBase &other, const t_config_option_keys // If the key is not in the parameter definition, or this ConfigBase is a static type and it does not support the parameter, // an exception is thrown if not ignore_nonexistent. ConfigOption *my_opt = this->option(opt_key, true); + // If we didn't find an option, look for any other option having this as an alias. + if (my_opt == nullptr) { + const ConfigDef *def = this->def(); + for (const auto &opt : def->options) { + for (const t_config_option_key &opt_key2 : opt.second.aliases) { + if (opt_key2 == opt_key) { + my_opt = this->option(opt.first, true); + break; + } + } + if (my_opt != nullptr) + break; + } + } if (my_opt == nullptr) { // opt_key does not exist in this ConfigBase and it cannot be created, because it is not defined by this->def(). // This is only possible if other is of DynamicConfig type. diff --git a/src/libslic3r/ExPolygon.cpp b/src/libslic3r/ExPolygon.cpp index d0f6d3fdc..dca992b6c 100644 --- a/src/libslic3r/ExPolygon.cpp +++ b/src/libslic3r/ExPolygon.cpp @@ -201,11 +201,11 @@ void ExPolygon::remove_point_too_near(const coord_t tolerance) { size_t id = 1; while (id < this->contour.points.size() - 1) { - size_t newdist = min(this->contour.points[id].distance_to(this->contour.points[id - 1]) + coord_t newdist = (coord_t)std::min(this->contour.points[id].distance_to(this->contour.points[id - 1]) , this->contour.points[id].distance_to(this->contour.points[id + 1])); if (newdist < tolerance) { this->contour.points.erase(this->contour.points.begin() + id); - newdist = this->contour.points[id].distance_to(this->contour.points[id - 1]); + newdist = (coord_t)this->contour.points[id].distance_to(this->contour.points[id - 1]); } //go to next one //if you removed a point, it check if the next one isn't too near from the previous one. @@ -221,7 +221,7 @@ ExPolygon::remove_point_too_near(const coord_t tolerance) { void ExPolygon::medial_axis(const ExPolygon &bounds, double max_width, double min_width, ThickPolylines* polylines, double height) const { - Slic3r::MedialAxis ma(*this, bounds, max_width, min_width, height); + Slic3r::MedialAxis ma(*this, bounds, (coord_t)max_width, (coord_t)min_width, height); ma.build(polylines); } @@ -319,7 +319,7 @@ ExPolygon::get_trapezoids3_half(Polygons* polygons, float spacing) const { if (min_x > p->x()) min_x = p->x(); if (max_x < p->x()) max_x = p->x(); } - for (int x = min_x; x < max_x-spacing/2; x += spacing) { + for (coord_t x = min_x; x < max_x - (coord_t)(spacing / 2); x += (coord_t)spacing) { xx.push_back(x); } xx.push_back(max_x); @@ -333,13 +333,13 @@ ExPolygon::get_trapezoids3_half(Polygons* polygons, float spacing) const { // build rectangle Polygon poly; poly.points.resize(4); - poly[0].x() = *x + spacing / 4; + poly[0].x() = *x + (coord_t)spacing / 4; poly[0].y() = bb.min(1); - poly[1].x() = next_x - spacing / 4; + poly[1].x() = next_x - (coord_t)spacing / 4; poly[1].y() = bb.min(1); - poly[2].x() = next_x - spacing / 4; + poly[2].x() = next_x - (coord_t)spacing / 4; poly[2].y() = bb.max(1); - poly[3].x() = *x + spacing / 4; + poly[3].x() = *x + (coord_t)spacing / 4; poly[3].y() = bb.max(1); // intersect with this expolygon @@ -431,8 +431,8 @@ std::list expoly_to_polypartition_input(const ExPolygon &ex) p.Init(int(ex.contour.points.size())); for (const Point &point : ex.contour.points) { size_t i = &point - &ex.contour.points.front(); - p[i].x = point(0); - p[i].y = point(1); + p[i].x = point.x(); + p[i].y = point.y(); } p.SetHole(false); } diff --git a/src/libslic3r/MedialAxis.cpp b/src/libslic3r/MedialAxis.cpp index c4ddd1399..e0416ecb7 100644 --- a/src/libslic3r/MedialAxis.cpp +++ b/src/libslic3r/MedialAxis.cpp @@ -292,15 +292,15 @@ MedialAxis::retrieve_endpoint(const VD::cell_type* cell) const void remove_point_too_near(ThickPolyline* to_reduce) { - const coord_t smallest = SCALED_EPSILON * 2; + const coord_t smallest = (coord_t)SCALED_EPSILON * 2; size_t id = 1; while (id < to_reduce->points.size() - 1) { - size_t newdist = min(to_reduce->points[id].distance_to(to_reduce->points[id - 1]) + coord_t newdist = (coord_t)std::min(to_reduce->points[id].distance_to(to_reduce->points[id - 1]) , to_reduce->points[id].distance_to(to_reduce->points[id + 1])); if (newdist < smallest) { to_reduce->points.erase(to_reduce->points.begin() + id); to_reduce->width.erase(to_reduce->width.begin() + id); - newdist = to_reduce->points[id].distance_to(to_reduce->points[id - 1]); + newdist = (coord_t)to_reduce->points[id].distance_to(to_reduce->points[id - 1]); //if you removed a point, it check if the next one isn't too near from the previous one. // if not, it bypass it. if (newdist > smallest) { @@ -410,11 +410,11 @@ get_coeff_from_angle_countour(Point &point, const ExPolygon &contour, coord_t mi if (angle >= PI) angle = 2 * PI - angle; // smaller angle //compute the diff from 90° angle = abs(angle - PI / 2); - if (point_near.coincides_with(point_nearest) && max(nearest_dist, near_dist) + SCALED_EPSILON < point_nearest.distance_to(point_near)) { + if (point_near.coincides_with(point_nearest) && std::max(nearest_dist, near_dist) + SCALED_EPSILON < point_nearest.distance_to(point_near)) { //not only nearest Point point_before = id_near == 0 ? contour.contour.points.back() : contour.contour.points[id_near - 1]; Point point_after = id_near == contour.contour.points.size() - 1 ? contour.contour.points.front() : contour.contour.points[id_near + 1]; - double angle2 = min(point_nearest.ccw_angle(point_before, point_after), point_nearest.ccw_angle(point_after, point_before)); + double angle2 = std::min(point_nearest.ccw_angle(point_before, point_after), point_nearest.ccw_angle(point_after, point_before)); angle2 = abs(angle - PI / 2); angle = (angle + angle2) / 2; } @@ -457,9 +457,9 @@ MedialAxis::fusion_curve(ThickPolylines &pp) size_t prev_idx = closest_point_idx == 0 ? this->expolygon.contour.points.size() - 1 : closest_point_idx - 1; size_t next_idx = closest_point_idx == this->expolygon.contour.points.size() - 1 ? 0 : closest_point_idx + 1; double mindot = 1; - mindot = min(mindot, abs(dot(Line(polyline.points[polyline.points.size() - 1], polyline.points[polyline.points.size() - 2]), + mindot = std::min(mindot, abs(dot(Line(polyline.points[polyline.points.size() - 1], polyline.points[polyline.points.size() - 2]), (Line(this->expolygon.contour.points[closest_point_idx], this->expolygon.contour.points[prev_idx]))))); - mindot = min(mindot, abs(dot(Line(polyline.points[polyline.points.size() - 1], polyline.points[polyline.points.size() - 2]), + mindot = std::min(mindot, abs(dot(Line(polyline.points[polyline.points.size() - 1], polyline.points[polyline.points.size() - 2]), (Line(this->expolygon.contour.points[closest_point_idx], this->expolygon.contour.points[next_idx]))))); //compute angle @@ -473,7 +473,7 @@ MedialAxis::fusion_curve(ThickPolylines &pp) double sum_dot = 0; double min_dot = 0; // look if other end is a cross point with multiple other branch - vector crosspoint; + std::vector crosspoint; for (size_t j = 0; j < pp.size(); ++j) { if (j == i) continue; ThickPolyline& other = pp[j]; @@ -481,12 +481,12 @@ MedialAxis::fusion_curve(ThickPolylines &pp) other.reverse(); crosspoint.push_back(j); double dot_temp = dot(Line(polyline.points[0], polyline.points[1]), (Line(other.points[0], other.points[1]))); - min_dot = min(min_dot, abs(dot_temp)); + min_dot = std::min(min_dot, abs(dot_temp)); sum_dot += dot_temp; } else if (polyline.first_point().coincides_with(other.first_point())) { crosspoint.push_back(j); double dot_temp = dot(Line(polyline.points[0], polyline.points[1]), (Line(other.points[0], other.points[1]))); - min_dot = min(min_dot, abs(dot_temp)); + min_dot = std::min(min_dot, abs(dot_temp)); sum_dot += dot_temp; } } @@ -502,7 +502,7 @@ MedialAxis::fusion_curve(ThickPolylines &pp) //don't pull, it distords the line if there are too many points. //// pull it a bit, depends on my size, the dot?, and the coeff at my 0-end (~14% for a square, almost 0 for a gentle curve) //coord_t length_pull = polyline.length(); - //length_pull *= 0.144 * get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, polyline.length() / 2)); + //length_pull *= 0.144 * get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, std::min(min_width, polyline.length() / 2)); ////compute dir //Vectorf pull_direction(polyline.points[1].x() - polyline.points[0].x(), polyline.points[1].y() - polyline.points[0].y()); @@ -546,11 +546,11 @@ MedialAxis::fusion_corners(ThickPolylines &pp) if (polyline.width.back() > 0) continue; //check my length is small - coord_t length = polyline.length(); + coord_t length = (coord_t)polyline.length(); if (length > max_width) continue; // look if other end is a cross point with multiple other branch - vector crosspoint; + std::vector crosspoint; for (size_t j = 0; j < pp.size(); ++j) { if (j == i) continue; ThickPolyline& other = pp[j]; @@ -577,8 +577,8 @@ MedialAxis::fusion_corners(ThickPolylines &pp) //FIXME: also pull (a bit less) points that are near to this one. // if true, pull it a bit, depends on my size, the dot?, and the coeff at my 0-end (~14% for a square, almost 0 for a gentle curve) - coord_t length_pull = polyline.length(); - length_pull *= 0.144 * get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2))); + coord_t length_pull = (coord_t)polyline.length(); + length_pull *= (coord_t) 0.144 * get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, std::min(min_width, (coord_t)(polyline.length() / 2))); //compute dir Vec2d pull_direction(polyline.points[1].x() - polyline.points[0].x(), polyline.points[1].y() - polyline.points[0].y()); @@ -588,12 +588,12 @@ MedialAxis::fusion_corners(ThickPolylines &pp) //pull the points Point &p1 = pp[crosspoint[0]].points[0]; - p1.x() = p1.x() + pull_direction.x(); - p1.y() = p1.y() + pull_direction.y(); + p1.x() = p1.x() + (coord_t)pull_direction.x(); + p1.y() = p1.y() + (coord_t)pull_direction.y(); Point &p2 = pp[crosspoint[1]].points[0]; - p2.x() = p2.x() + pull_direction.x(); - p2.y() = p2.y() + pull_direction.y(); + p2.x() = p2.x() + (coord_t)pull_direction.x(); + p2.y() = p2.y() + (coord_t)pull_direction.y(); //delete the now unused polyline pp.erase(pp.begin() + i); @@ -737,7 +737,7 @@ MedialAxis::main_fusion(ThickPolylines& pp) //int idf = 0; bool changes = true; - map coeff_angle_cache; + std::map coeff_angle_cache; while (changes) { concatThickPolylines(pp); //reoder pp by length (ascending) It's really important to do that to avoid building the line from the width insteand of the length @@ -801,11 +801,11 @@ MedialAxis::main_fusion(ThickPolylines& pp) //test if we don't merge with something too different and without any relevance. double coeffSizePolyI = 1; if (polyline.width.back() == 0) { - coeffSizePolyI = 0.1 + 0.9*get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2))); + coeffSizePolyI = 0.1 + 0.9*get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, std::min(min_width, (coord_t)(polyline.length() / 2))); } double coeffSizeOtherJ = 1; if (other.width.back() == 0) { - coeffSizeOtherJ = 0.1 + 0.9*get_coeff_from_angle_countour(other.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2))); + coeffSizeOtherJ = 0.1 + 0.9*get_coeff_from_angle_countour(other.points.back(), this->expolygon, std::min(min_width, (coord_t)(polyline.length() / 2))); } //std::cout << " try2 : " << i << ":" << j << " : " // << (abs(polyline.length()*coeffSizePolyI - other.length()*coeffSizeOtherJ) > max_width / 2) @@ -904,29 +904,29 @@ MedialAxis::main_fusion(ThickPolylines& pp) //TODO: try if we can achieve a better result if we use a different algo if the angle is <90° const double coeff_angle_poly = (coeff_angle_cache.find(polyline.points.back()) != coeff_angle_cache.end()) ? coeff_angle_cache[polyline.points.back()] - : (get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, min(min_width, (coord_t)(polyline.length() / 2)))); + : (get_coeff_from_angle_countour(polyline.points.back(), this->expolygon, std::min(min_width, (coord_t)(polyline.length() / 2)))); const double coeff_angle_candi = (coeff_angle_cache.find(best_candidate->points.back()) != coeff_angle_cache.end()) ? coeff_angle_cache[best_candidate->points.back()] - : (get_coeff_from_angle_countour(best_candidate->points.back(), this->expolygon, min(min_width, (coord_t)(best_candidate->length() / 2)))); + : (get_coeff_from_angle_countour(best_candidate->points.back(), this->expolygon, std::min(min_width, (coord_t)(best_candidate->length() / 2)))); //this will encourage to follow the curve, a little, because it's shorter near the center //without that, it tends to go to the outter rim. - //std::cout << " max(polyline.length(), best_candidate->length())=" << max(polyline.length(), best_candidate->length()) + //std::cout << " std::max(polyline.length(), best_candidate->length())=" << std::max(polyline.length(), best_candidate->length()) // << ", polyline.length()=" << polyline.length() // << ", best_candidate->length()=" << best_candidate->length() - // << ", polyline.length() / max=" << (polyline.length() / max(polyline.length(), best_candidate->length())) - // << ", best_candidate->length() / max=" << (best_candidate->length() / max(polyline.length(), best_candidate->length())) + // << ", polyline.length() / max=" << (polyline.length() / std::max(polyline.length(), best_candidate->length())) + // << ", best_candidate->length() / max=" << (best_candidate->length() / std::max(polyline.length(), best_candidate->length())) // << "\n"; - double weight_poly = 2 - (polyline.length() / max(polyline.length(), best_candidate->length())); - double weight_candi = 2 - (best_candidate->length() / max(polyline.length(), best_candidate->length())); + double weight_poly = 2 - (polyline.length() / std::max(polyline.length(), best_candidate->length())); + double weight_candi = 2 - (best_candidate->length() / std::max(polyline.length(), best_candidate->length())); weight_poly *= coeff_angle_poly; weight_candi *= coeff_angle_candi; const double coeff_poly = (dot_poly_branch * weight_poly) / (dot_poly_branch * weight_poly + dot_candidate_branch * weight_candi); const double coeff_candi = 1.0 - coeff_poly; //std::cout << "coeff_angle_poly=" << coeff_angle_poly // << ", coeff_angle_candi=" << coeff_angle_candi - // << ", weight_poly=" << (2 - (polyline.length() / max(polyline.length(), best_candidate->length()))) - // << ", weight_candi=" << (2 - (best_candidate->length() / max(polyline.length(), best_candidate->length()))) + // << ", weight_poly=" << (2 - (polyline.length() / std::max(polyline.length(), best_candidate->length()))) + // << ", weight_candi=" << (2 - (best_candidate->length() / std::max(polyline.length(), best_candidate->length()))) // << ", sumpoly=" << weight_poly // << ", sumcandi=" << weight_candi // << ", dot_poly_branch=" << dot_poly_branch @@ -937,7 +937,7 @@ MedialAxis::main_fusion(ThickPolylines& pp) //iterate the points // as voronoi should create symetric thing, we can iterate synchonously size_t idx_point = 1; - while (idx_point < min(polyline.points.size(), best_candidate->points.size())) { + while (idx_point < std::min(polyline.points.size(), best_candidate->points.size())) { //fusion polyline.points[idx_point].x() = polyline.points[idx_point].x() * coeff_poly + best_candidate->points[idx_point].x() * coeff_candi; polyline.points[idx_point].y() = polyline.points[idx_point].y() * coeff_poly + best_candidate->points[idx_point].y() * coeff_candi; @@ -946,10 +946,10 @@ MedialAxis::main_fusion(ThickPolylines& pp) // This formula is what works the best, even if it's not perfect (created empirically). 0->3% error on a gap fill on some tests. //If someone find an other formula based on the properties of the voronoi algorithm used here, and it works better, please use it. //or maybe just use the distance to nearest edge in bounds... - double value_from_current_width = 0.5*polyline.width[idx_point] * dot_poly_branch / max(dot_poly_branch, dot_candidate_branch); - value_from_current_width += 0.5*best_candidate->width[idx_point] * dot_candidate_branch / max(dot_poly_branch, dot_candidate_branch); + double value_from_current_width = 0.5*polyline.width[idx_point] * dot_poly_branch / std::max(dot_poly_branch, dot_candidate_branch); + value_from_current_width += 0.5*best_candidate->width[idx_point] * dot_candidate_branch / std::max(dot_poly_branch, dot_candidate_branch); double value_from_dist = 2 * polyline.points[idx_point].distance_to(best_candidate->points[idx_point]); - value_from_dist *= sqrt(min(dot_poly_branch, dot_candidate_branch) / max(dot_poly_branch, dot_candidate_branch)); + value_from_dist *= sqrt(std::min(dot_poly_branch, dot_candidate_branch) / std::max(dot_poly_branch, dot_candidate_branch)); polyline.width[idx_point] = value_from_current_width + value_from_dist; //std::cout << "width:" << polyline.width[idx_point] << " = " << value_from_current_width << " + " << value_from_dist // << " (<" << max_width << " && " << (bounds.contour.closest_point(polyline.points[idx_point])->distance_to(polyline.points[idx_point]) * 2.1)<<")\n"; @@ -1306,7 +1306,7 @@ MedialAxis::simplify_polygon_frontier() size_t next_i = i == simplified_poly.contour.points.size() - 1 ? 0 : (i + 1); const Point* closest = bounds.contour.closest_point(p_check); if (closest != nullptr && closest->distance_to(p_check) + SCALED_EPSILON - < min(p_check.distance_to(simplified_poly.contour.points[prev_i]), p_check.distance_to(simplified_poly.contour.points[next_i])) / 2) { + < std::min(p_check.distance_to(simplified_poly.contour.points[prev_i]), p_check.distance_to(simplified_poly.contour.points[next_i])) / 2) { p_check.x() = closest->x(); p_check.y() = closest->y(); need_intersect = true; @@ -1596,7 +1596,7 @@ ExtrusionEntityCollection thin_variable_width(const ThickPolylines &polylines, E continue; } - const double w = fmax(line.a_width, line.b_width); + const double w = std::fmax(line.a_width, line.b_width); if (path.polyline.points.empty()) { path.polyline.append(line.a); path.polyline.append(line.b); diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 5302a3b5a..fa39f9b8f 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -61,8 +61,8 @@ void PerimeterGenerator::process() // which is the spacing between external and internal, which is not correct // and would make the collapsing (thus the details resolution) dependent on // internal flow which is unrelated. - coord_t min_spacing = perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE); - coord_t ext_min_spacing = ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE); + coord_t min_spacing = (coord_t)perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE); + coord_t ext_min_spacing = (coord_t)ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE); // prepare grown lower layer slices for overhang detection if (this->lower_slices != NULL && this->config->overhangs) { @@ -952,7 +952,7 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop, int child_idx = 0; //Polylines myPolylines = { myPolyline }; //iterate on each point ot find the best place to go into the child - vector childs = children; + PerimeterGeneratorLoops childs = children; while (!childs.empty()) { child_idx++; PerimeterIntersectionPoint nearest = this->_get_nearest_point(childs, my_loop, this->perimeter_flow.scaled_width(), this->perimeter_flow.scaled_width()* 1.42); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 699bbe632..1150e45bc 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -337,7 +337,7 @@ std::vector Print::extruders() const unsigned int Print::num_object_instances() const { - unsigned int instances = 0; + size_t instances = 0; for (const PrintObject *print_object : m_objects) instances += print_object->copies().size(); return instances; @@ -1290,13 +1290,13 @@ std::string Print::validate() const "all nozzles have to be of the same diameter."); } if (this->has_wipe_tower()) { - if (object->config().support_material_contact_distance == 0) { + if (object->config().support_material_contact_distance_type == zdNone) { // Soluble interface - if (object->config().support_material_contact_distance == 0 && ! object->config().support_material_synchronize_layers) + if (! object->config().support_material_synchronize_layers) return L("For the Wipe Tower to work with the soluble supports, the support layers need to be synchronized with the object layers."); } else { // Non-soluble interface - if (object->config().support_material_extruder != 0 || object->config().support_material_interface_extruder != 0) + if (object->config().support_material_contact_distance_type != zdNone || object->config().support_material_interface_extruder != 0) return L("The Wipe Tower currently supports the non-soluble supports only if they are printed with the current extruder without triggering a tool change. " "(both support_material_extruder and support_material_interface_extruder need to be set to 0)."); } @@ -1947,7 +1947,7 @@ void Print::_make_wipe_tower() wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id,false); for (const auto extruder_id : layer_tools.extruders) { if ((first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || extruder_id != current_extruder_id) { - float volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id]; // total volume to wipe after this toolchange + double volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id]; // total volume to wipe after this toolchange // Not all of that can be used for infill purging: volume_to_wipe -= m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 140dedcec..775c3826a 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2217,39 +2217,40 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->default_value = new ConfigOptionEnum(zdFilament); - def = this->add("support_material_contact_distance_top", coFloat); + def = this->add("support_material_contact_distance_top", coFloatOrPercent); def->gui_type = "f_enum_open"; def->label = L("Top"); def->category = L("Support material"); def->tooltip = L("The vertical distance between support material interface and the object" "(when the object is printed on top of the support). " "Setting this to 0 will also prevent Slic3r from using bridge flow and speed " - "for the first object layer."); + "for the first object layer. Can be a % of the extruder size used for the interface layers."); def->sidetext = L("mm"); def->cli = "support-material-contact-distance-top=f"; // def->min = 0; def->enum_values.push_back("0"); def->enum_values.push_back("0.2"); - def->enum_labels.push_back((boost::format("0 (%1%)") % L("soluble")).str()); - def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("detachable")).str()); + def->enum_labels.push_back((boost::format("0 (%1%)") % L("bad bond")).str()); + def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("ordinary")).str()); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0.2); + def->aliases = { "support_material_contact_distance" }; + def->default_value = new ConfigOptionFloatOrPercent(50,true); - def = this->add("support_material_contact_distance_bottom", coFloat); + def = this->add("support_material_contact_distance_bottom", coFloatOrPercent); def->gui_type = "f_enum_open"; def->label = L("Bottom"); def->category = L("Support material"); def->tooltip = L("The vertical distance between object and support material interface" - "(when the support is printed on top of the object)."); + "(when the support is printed on top of the object). Can be a % of the extruder size used for the interface layers."); def->sidetext = L("mm"); def->cli = "support-material-contact-distance-bottom=f"; // def->min = 0; def->enum_values.push_back("0"); def->enum_values.push_back("0.2"); - def->enum_labels.push_back((boost::format("0 (%1%)") % L("soluble")).str()); - def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("detachable")).str()); + def->enum_labels.push_back((boost::format("0 (%1%)") % L("bad bond")).str()); + def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("ordinary")).str()); def->mode = comAdvanced; - def->default_value = new ConfigOptionFloat(0.2); + def->default_value = new ConfigOptionFloatOrPercent(50,true); def = this->add("support_material_enforce_layers", coInt); def->label = L("Enforce support for the first"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 02fb1e7c0..7ad914297 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -426,8 +426,8 @@ public: ConfigOptionFloat support_material_angle; ConfigOptionBool support_material_buildplate_only; ConfigOptionEnum support_material_contact_distance_type; - ConfigOptionFloat support_material_contact_distance_top; - ConfigOptionFloat support_material_contact_distance_bottom; + ConfigOptionFloatOrPercent support_material_contact_distance_top; + ConfigOptionFloatOrPercent support_material_contact_distance_bottom; ConfigOptionInt support_material_enforce_layers; ConfigOptionInt support_material_extruder; ConfigOptionFloatOrPercent support_material_extrusion_width; diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index f0647736a..7712c0efb 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -95,9 +95,9 @@ SlicingParameters SlicingParameters::create_from_config( params.max_layer_height = std::max(params.max_layer_height, params.layer_height); if (! soluble_interface) { - params.gap_raft_object = object_config.support_material_contact_distance_top.value; - params.gap_object_support = object_config.support_material_contact_distance_bottom.value; - params.gap_support_object = object_config.support_material_contact_distance_top.value; + params.gap_raft_object = object_config.support_material_contact_distance_top.get_abs_value(support_material_interface_extruder_dmr); + params.gap_object_support = object_config.support_material_contact_distance_bottom.get_abs_value(support_material_interface_extruder_dmr); + params.gap_support_object = params.gap_raft_object; } if (params.base_raft_layers > 0) { diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index f208a2ed4..bd3e5406d 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -282,10 +282,11 @@ void PrintObjectSupportMaterial::generate(PrintObject &object) MyLayersPtr intermediate_layers = this->raft_and_intermediate_support_layers( object, bottom_contacts, top_contacts, layer_storage); + // this->trim_support_layers_by_object(object, top_contacts, m_slicing_params.soluble_interface ? 0. : m_support_layer_height_min, 0., m_gap_xy); this->trim_support_layers_by_object(object, top_contacts, - m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_top.value, - m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_bottom.value, m_gap_xy); + m_slicing_params.soluble_interface ? 0. : this->m_slicing_params.gap_support_object, + m_slicing_params.soluble_interface ? 0. : this->m_slicing_params.gap_object_support, m_gap_xy); #ifdef SLIC3R_DEBUG for (const MyLayer *layer : top_contacts) @@ -1207,7 +1208,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ new_layer.height = object.layers()[layer_id - 1]->height; new_layer.bottom_z = (layer_id == 1) ? m_slicing_params.object_print_z_min : object.layers()[layer_id - 2]->print_z; } else { - new_layer.print_z = layer.print_z - layer.height - m_object_config->support_material_contact_distance_top; + new_layer.print_z = layer.print_z - layer.height - this->m_slicing_params.gap_support_object; new_layer.bottom_z = new_layer.print_z; new_layer.height = 0.; // Ignore this contact area if it's too low. @@ -1237,7 +1238,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ bridging_height += region->region()->bridging_height_avg(*m_print_config); bridging_height /= coordf_t(layer.regions().size()); } - coordf_t bridging_print_z = layer.print_z - bridging_height - m_object_config->support_material_contact_distance_top; + coordf_t bridging_print_z = layer.print_z - bridging_height - this->m_slicing_params.gap_support_object; if (bridging_print_z >= m_slicing_params.first_print_layer_height - EPSILON) { // Not below the first layer height means this layer is printable. if (new_layer.print_z < m_slicing_params.first_print_layer_height + EPSILON) { @@ -1504,7 +1505,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta m_support_material_interface_flow.nozzle_diameter; layer_new.height_block = ((m_object_config->support_material_contact_distance_type == zdPlane) ? object.layers()[layer_id + 1]->height : layer_new.height); layer_new.print_z = m_slicing_params.soluble_interface ? object.layers()[layer_id + 1]->print_z : - (layer.print_z + layer_new.height_block + m_object_config->support_material_contact_distance_bottom.value); + (layer.print_z + layer_new.height_block + this->m_slicing_params.gap_object_support); layer_new.bottom_z = layer.print_z; layer_new.idx_object_layer_below = layer_id; layer_new.bridging = ! m_slicing_params.soluble_interface; @@ -1642,8 +1643,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta std::reverse(bottom_contacts.begin(), bottom_contacts.end()); // trim_support_layers_by_object(object, bottom_contacts, 0., 0., m_gap_xy); trim_support_layers_by_object(object, bottom_contacts, - m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_top.value, - m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_bottom.value, m_gap_xy); + m_slicing_params.soluble_interface ? 0. : this->m_slicing_params.gap_support_object, + m_slicing_params.soluble_interface ? 0. : this->m_slicing_params.gap_object_support, m_gap_xy); } // ! top_contacts.empty() @@ -2071,8 +2072,8 @@ void PrintObjectSupportMaterial::generate_base_layers( // trim_support_layers_by_object(object, intermediate_layers, 0., 0., m_gap_xy); this->trim_support_layers_by_object(object, intermediate_layers, - m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_top.value, - m_slicing_params.soluble_interface ? 0. : m_object_config->support_material_contact_distance_bottom.value, m_gap_xy); + m_slicing_params.soluble_interface ? 0. : this->m_slicing_params.gap_support_object, + m_slicing_params.soluble_interface ? 0. : this->m_slicing_params.gap_object_support, m_gap_xy); } void PrintObjectSupportMaterial::trim_support_layers_by_object( diff --git a/src/polypartition/polypartition.h b/src/polypartition/polypartition.h index a89873296..f3543acb5 100644 --- a/src/polypartition/polypartition.h +++ b/src/polypartition/polypartition.h @@ -119,11 +119,11 @@ class TPPLPoly { return points; } - TPPLPoint& operator[] (int i) { + TPPLPoint& operator[] (size_t i) { return points[i]; } - const TPPLPoint& operator[] (int i) const { + const TPPLPoint& operator[] (size_t i) const { return points[i]; }