diff --git a/resources/ui_layout/print.ui b/resources/ui_layout/print.ui index 3e5f5a09a..e6339ff27 100644 --- a/resources/ui_layout/print.ui +++ b/resources/ui_layout/print.ui @@ -49,14 +49,15 @@ group:Overhangs setting:width$5:overhangs_reverse_threshold end_line group:Advanced - setting:no_perimeter_unsupported_algo + setting:width$25:no_perimeter_unsupported_algo line:Gap Fill setting:gap_fill setting:width$5:gap_fill_min_area end_line line:Seam - setting:seam_position - setting:seam_travel + setting:sidetext_width$2:seam_position + setting:label_width$10:width$3:sidetext_width$2:seam_angle_cost + setting:label_width$10:width$3:sidetext_width$2:seam_travel_cost end_line line:Looping perimeter setting:perimeter_loop diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 23ce2bc69..e54486e4e 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -60,9 +60,9 @@ void AppConfig::set_defaults() set("freecad_path", "."); if (get("version_check").empty()) - set("version_check", "1"); + set("version_check", "0"); if (get("preset_update").empty()) - set("preset_update", "1"); + set("preset_update", "0"); if (get("export_sources_full_pathnames").empty()) set("export_sources_full_pathnames", "0"); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 1e20c0052..0ad7c42ed 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3227,7 +3227,7 @@ void GCode::split_at_seam_pos(ExtrusionLoop& loop, std::unique_ptrget() : nullptr; //TODO modify m_seam_placer to takers into account extra options. - Point seam = m_seam_placer.get_seam(m_layer->id(), seam_position, loop, + Point seam = m_seam_placer.get_seam(m_layer, seam_position, loop, last_pos, EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0), (m_layer == NULL ? nullptr : m_layer->object()), was_clockwise, edge_grid_ptr); diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 8d8929571..99158ee08 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -2,6 +2,7 @@ #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/Print.hpp" +#include "libslic3r/Layer.hpp" #include "libslic3r/BoundingBox.hpp" #include "libslic3r/EdgeGrid.hpp" #include "libslic3r/ClipperUtils.hpp" @@ -50,6 +51,7 @@ plot(p2.subs(r,0.2).subs(z,1.), (x, -1, 3), adaptive=False, nb_of_points=400) // Return a value in <0, 1> of a cubic B-spline kernel centered around zero. // The B-spline is re-scaled so it has value 1 at zero. +// 0 -> 1 ; ~0.465 -> 0.75 ; ~0.72 -> 0.5 ; 1 -> 0.25 ; ~1.23 -> 0.125 ; 2+ -> 0 static inline float bspline_kernel(float x) { x = std::abs(x); @@ -208,13 +210,16 @@ void SeamPlacer::init(const Print& print) -Point SeamPlacer::get_seam(const size_t layer_idx, const SeamPosition seam_position, +Point SeamPlacer::get_seam(const Layer *layer, SeamPosition seam_position, const ExtrusionLoop& loop, Point last_pos, coordf_t nozzle_dmr, const PrintObject* po, bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid) { + const size_t layer_idx = layer->id(); Polygon polygon = loop.polygon(); BoundingBox polygon_bb = polygon.bounding_box(); const coord_t nozzle_r = coord_t(scale_(0.5 * nozzle_dmr) + 0.5); + float last_pos_weight = 1.f; + float angle_weight = 1.f; if (this->is_custom_seam_on_layer(layer_idx)) { // Seam enf/blockers can begin and end in between the original vertices. @@ -222,9 +227,53 @@ Point SeamPlacer::get_seam(const size_t layer_idx, const SeamPosition seam_posit polygon.densify(MINIMAL_POLYGON_SIDE); } + bool has_seam_custom = false; + for (ModelVolume* v : po->model_object()->volumes) + if (v->is_seam_position()) { + has_seam_custom = true; + break; + } + if (has_seam_custom) { + // Look for all lambda-seam-modifiers below current z, choose the highest one + ModelVolume* v_lambda_seam = nullptr; + Vec3d lambda_pos; + double lambda_dist; + double lambda_radius; + for (ModelVolume* v : po->model_object()->volumes) + if (v->is_seam_position()) { + //xy in object coordinates, z in plater coordinates + Vec3d test_lambda_pos = po->model_object()->instances.front()->transform_vector(v->get_offset(), true); + Vec3d test_lambda_pos_plater = po->model_object()->instances.front()->transform_vector(v->get_offset(), false); + Point xy_lambda(scale_(test_lambda_pos.x()), scale_(test_lambda_pos.y())); + Point nearest = polygon.point_projection(xy_lambda); + Vec3d polygon_3dpoint{ unscaled(nearest.x()), unscaled(nearest.y()), (double)layer->print_z }; + double test_lambda_dist = (polygon_3dpoint - test_lambda_pos).norm(); + double sphere_radius = po->model_object()->instances.front()->transform_bounding_box(v->mesh().bounding_box(), true).size().x() / 2; + //if (test_lambda_dist > sphere_radius) + // continue; + + //use this one if the first or nearer (in z) + if (v_lambda_seam == nullptr || lambda_dist > test_lambda_dist) { + v_lambda_seam = v; + lambda_pos = test_lambda_pos; + lambda_radius = sphere_radius; + lambda_dist = test_lambda_dist; + } + } + + if (v_lambda_seam != nullptr) { + lambda_pos = po->model_object()->instances.front()->transform_vector(v_lambda_seam->get_offset(), true); + // Found, get the center point and apply rotation and scaling of Model instance. Continues to spAligned if not found or Weight set to Zero. + last_pos = Point::new_scale(lambda_pos.x(), lambda_pos.y()); + // Weight is set by user and stored in the radius of the sphere + last_pos_weight = std::max(0.0, std::round(100 * (lambda_radius))); + if (last_pos_weight > 0.0) + seam_position = spCustom; + } + } + if (seam_position != spRandom) { // Retrieve the last start position for this object. - float last_pos_weight = 1.f; if (seam_position == spAligned) { // Seam is aligned to the seam at the preceding layer. @@ -233,32 +282,51 @@ Point SeamPlacer::get_seam(const size_t layer_idx, const SeamPosition seam_posit if (pos.has_value()) { //last_pos = m_last_seam_position[po]; last_pos = *pos; - last_pos_weight = is_custom_enforcer_on_layer(layer_idx) ? 0.f : 1.f; } + last_pos_weight = is_custom_enforcer_on_layer(layer_idx) ? 0.f : 1.f; } - } - else if (seam_position == spRear) { + }else if (seam_position == spRear) { // Object is centered around (0,0) in its current coordinate system. last_pos.x() = 0; last_pos.y() += coord_t(3. * po->bounding_box().radius()); last_pos_weight = 5.f; - } if (seam_position == spNearest) { + }else if (seam_position == spNearest) { // last_pos already contains current nozzle position + // set base last_pos_weight to the same value as penaltyFlatSurface + last_pos_weight = 5.f; + if (po != nullptr) { + last_pos_weight = po->config().seam_travel_cost.get_abs_value(last_pos_weight); + angle_weight = po->config().seam_angle_cost.get_abs_value(angle_weight); + } } + + // Insert a projection of last_pos into the polygon. size_t last_pos_proj_idx; { - auto it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r); + Points::const_iterator it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r ); last_pos_proj_idx = it - polygon.points.begin(); } + Point last_pos_proj = polygon.points[last_pos_proj_idx]; // Parametrize the polygon by its length. std::vector lengths = polygon.parameter_by_length(); + //find the max dist the seam can be + float dist_max = 0.1f * lengths.back();// 5.f * nozzle_dmr + if (po != nullptr && po->config().seam_travel_cost.get_abs_value(1) >= 1) { + last_pos_weight *= 2; + dist_max = 0; + for (size_t i = 0; i < polygon.points.size(); ++i) { + dist_max = std::max(dist_max, (float)polygon.points[i].distance_to(last_pos_proj)); + } + } + // For each polygon point, store a penalty. // First calculate the angles, store them as penalties. The angles are caluculated over a minimum arm length of nozzle_r. - std::vector penalties = polygon_angles_at_vertices(polygon, lengths, float(nozzle_r)); + std::vector penalties = polygon_angles_at_vertices(polygon, lengths, + this->is_custom_seam_on_layer(layer_idx) ? std::min(MINIMAL_POLYGON_SIDE / 2.f, float(nozzle_r)) : float(nozzle_r)); // No penalty for reflex points, slight penalty for convex points, high penalty for flat surfaces. const float penaltyConvexVertex = 1.f; const float penaltyFlatSurface = 5.f; @@ -269,26 +337,33 @@ Point SeamPlacer::get_seam(const size_t layer_idx, const SeamPosition seam_posit if (was_clockwise) ccwAngle = - ccwAngle; float penalty = 0; - if (ccwAngle <- float(0.6 * PI)) - // Sharp reflex vertex. We love that, it hides the seam perfectly. - penalty = 0.f; - else if (ccwAngle > float(0.6 * PI)) - // Seams on sharp convex vertices are more visible than on reflex vertices. - penalty = penaltyConvexVertex; - else if (ccwAngle < 0.f) { + //if (ccwAngle < -float(0.6 * PI)) + // penalty = 0.f; + //else if (ccwAngle > float(0.6 * PI)) + // + // penalty = penaltyConvexVertex; + //else + if (ccwAngle < 0.f) { + // We love Sharp reflex vertex (high negative ccwAngle). It hides the seam perfectly. // Interpolate penalty between maximum and zero. - penalty = penaltyFlatSurface * bspline_kernel(ccwAngle * float(PI * 2. / 3.)); + penalty = penaltyFlatSurface * bspline_kernel(ccwAngle); + } else if (ccwAngle > float(0.67 * PI)) { + //penalize too sharp convex angle, it's best to be nearer to ~100° + penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel( (PI - ccwAngle) * 1.5); } else { - assert(ccwAngle >= 0.f); // Interpolate penalty between maximum and the penalty for a convex vertex. - penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle * float(PI * 2. / 3.)); + penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle); + } + penalty *= angle_weight; + if (po != nullptr && po->config().seam_travel_cost.get_abs_value(1) >= 1) { + penalty += last_pos_weight * polygon.points[i].distance_to(last_pos_proj) / dist_max; + } else { + // Give a negative penalty for points close to the last point or the prefered seam location. + float dist_to_last_pos_proj = (i < last_pos_proj_idx) ? + std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) : + std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]); + penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max); } - // Give a negative penalty for points close to the last point or the prefered seam location. - float dist_to_last_pos_proj = (i < last_pos_proj_idx) ? - std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) : - std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]); - float dist_max = 0.1f * lengths.back(); // 5.f * nozzle_dmr - penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max); penalties[i] = std::max(0.f, penalty); } @@ -313,28 +388,29 @@ Point SeamPlacer::get_seam(const size_t layer_idx, const SeamPosition seam_posit // Custom seam. Huge (negative) constant penalty is applied inside // blockers (enforcers) to rule out points that should not win. - this->apply_custom_seam(polygon, penalties, lengths, layer_idx, seam_position); + std::vector penalties_with_custom_seam = penalties; + this->apply_custom_seam(polygon, penalties_with_custom_seam, lengths, layer_idx, seam_position); // Find a point with a minimum penalty. - size_t idx_min = std::min_element(penalties.begin(), penalties.end()) - penalties.begin(); + size_t idx_min = std::min_element(penalties_with_custom_seam.begin(), penalties_with_custom_seam.end()) - penalties_with_custom_seam.begin(); if (seam_position != spAligned || ! is_custom_enforcer_on_layer(layer_idx)) { // Very likely the weight of idx_min is very close to the weight of last_pos_proj_idx. // In that case use last_pos_proj_idx instead. float penalty_aligned = penalties[last_pos_proj_idx]; float penalty_min = penalties[idx_min]; - float penalty_diff_abs = std::abs(penalty_min - penalty_aligned); - float penalty_max = std::max(penalty_min, penalty_aligned); + float penalty_diff_abs = std::abs(penalties_with_custom_seam[idx_min] - penalties_with_custom_seam[last_pos_proj_idx]); + float penalty_max = std::max(penalties[idx_min], penalties[last_pos_proj_idx]); float penalty_diff_rel = (penalty_max == 0.f) ? 0.f : penalty_diff_abs / penalty_max; // printf("Align seams, penalty aligned: %f, min: %f, diff abs: %f, diff rel: %f\n", penalty_aligned, penalty_min, penalty_diff_abs, penalty_diff_rel); - if (std::abs(penalty_diff_rel) < 0.05) { + if (std::abs(penalty_diff_rel) < 0.05 && penalty_diff_abs < 3) { // Penalty of the aligned point is very close to the minimum penalty. // Align the seams as accurately as possible. idx_min = last_pos_proj_idx; } } - if (seam_position == spAligned && loop.role() == erExternalPerimeter) + if (loop.role() == erExternalPerimeter) m_seam_history.add_seam(po, polygon.points[idx_min], polygon_bb); diff --git a/src/libslic3r/GCode/SeamPlacer.hpp b/src/libslic3r/GCode/SeamPlacer.hpp index e603b7d57..d72079f2e 100644 --- a/src/libslic3r/GCode/SeamPlacer.hpp +++ b/src/libslic3r/GCode/SeamPlacer.hpp @@ -12,6 +12,7 @@ namespace Slic3r { class PrintObject; class ExtrusionLoop; class Print; +class Layer; namespace EdgeGrid { class Grid; } @@ -39,7 +40,7 @@ class SeamPlacer { public: void init(const Print& print); - Point get_seam(const size_t layer_idx, const SeamPosition seam_position, + Point get_seam(const Layer *layer, const SeamPosition seam_position, const ExtrusionLoop& loop, Point last_pos, coordf_t nozzle_diameter, const PrintObject* po, bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 22d7970ff..5df4aa63c 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -536,7 +536,8 @@ const std::vector& Preset::print_options() "exact_last_layer_height", "perimeter_loop", "perimeter_loop_seam", - "seam_travel", + "seam_angle_cost", + "seam_travel_cost", "infill_connection", "first_layer_infill_speed", "thin_walls_min_width", diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 65c006b71..26ba8b694 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -932,28 +932,28 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ } // Copy content of the ModelObject including its ID, do not change the parent. model_object.assign_copy(model_object_new); - } else if (supports_differ || model_custom_supports_data_changed(model_object, model_object_new)) { + } else if (supports_differ || seam_position_differ || model_custom_supports_data_changed(model_object, model_object_new)) { // First stop background processing before shuffling or deleting the ModelVolumes in the ModelObject's list. if (supports_differ) { - this->call_cancel_callback(); - update_apply_status(false); + this->call_cancel_callback(); + update_apply_status(false); } // Invalidate just the supports step. auto range = print_object_status.equal_range(PrintObjectStatus(model_object.id())); for (auto it = range.first; it != range.second; ++ it) update_apply_status(it->print_object->invalidate_step(posSupportMaterial)); if (supports_differ) { - // Copy just the support volumes. - model_volume_list_update_supports_seams(model_object, model_object_new); - }else if (seam_position_differ) { - // First stop background processing before shuffling or deleting the ModelVolumes in the ModelObject's list. - this->call_cancel_callback(); - update_apply_status(false); - // Invalidate just the gcode step. - invalidate_step(psGCodeExport); - // Copy just the seam volumes. - model_volume_list_update_supports_seams(model_object, model_object_new); - } + // Copy just the support volumes. + model_volume_list_update_supports_seams(model_object, model_object_new); + }else if (seam_position_differ) { + // First stop background processing before shuffling or deleting the ModelVolumes in the ModelObject's list. + this->call_cancel_callback(); + update_apply_status(false); + // Invalidate just the gcode step. + invalidate_step(psGCodeExport); + // Copy just the seam volumes. + model_volume_list_update_supports_seams(model_object, model_object_new); + } } else if (model_custom_seam_data_changed(model_object, model_object_new)) { update_apply_status(this->invalidate_step(psGCodeExport)); } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 8aab6ffe6..f452303da 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2796,31 +2796,38 @@ void PrintConfigDef::init_fff_params() def->label = L("Seam position"); def->category = OptionCategory::perimeter; def->tooltip = L("Position of perimeters starting points." - "\n --- When using Custom seam ---" - "\nYou have to create one or more seam sphere in the context menu of the object." - " When an object has a seam object, this setting is not taken into account nymore for the object." - " Refer to the wiki/help menu for more information."); + "\n "); def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); - def->enum_values.push_back("random"); def->enum_values.push_back("near"); + def->enum_values.push_back("random"); def->enum_values.push_back("aligned"); def->enum_values.push_back("rear"); - def->enum_values.push_back("hidden"); + def->enum_labels.push_back(L("Cost-based")); def->enum_labels.push_back(L("Random")); - def->enum_labels.push_back(L("Nearest")); def->enum_labels.push_back(L("Aligned")); def->enum_labels.push_back(L("Rear")); - def->enum_labels.push_back(L("Corners")); def->mode = comSimple; - def->set_default_value(new ConfigOptionEnum(spHidden)); + def->set_default_value(new ConfigOptionEnum(spNearest)); - def = this->add("seam_travel", coBool); - def->label = L("Travel move reduced"); + def = this->add("seam_angle_cost", coPercent); + def->label = L("Angle cost"); + def->full_label = L("Seam angle cost"); def->category = OptionCategory::perimeter; - def->tooltip = L("Add a big cost to travel paths when possible (when going into a loop), so it will prefer a less optimal seam posistion if it's nearer."); - def->cli = "seam-travel!"; + def->tooltip = L("Cost of placing the seam at a bad angle. The worst angle (max penalty) is when it's flat."); + def->sidetext = L("%"); + def->min = 0; def->mode = comExpert; - def->set_default_value(new ConfigOptionBool(false)); + def->set_default_value(new ConfigOptionPercent(100)); + + def = this->add("seam_travel_cost", coPercent); + def->label = L("Travel cost"); + def->full_label = L("Seam travel cost"); + def->category = OptionCategory::perimeter; + def->tooltip = L("Cost of moving the extruder. The highest penalty is when the point is the farest from the position of the extruder before extruding the external periemter"); + def->sidetext = L("%"); + def->min = 0; + def->mode = comExpert; + def->set_default_value(new ConfigOptionPercent(100)); #if 0 def = this->add("seam_preferred_direction", coFloat); @@ -4769,8 +4776,19 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va value = "notconnected"; else value = "connected"; + } else if (opt_key == "seam_travel") { + if (value == "1") { + opt_key = "seam_travel_cost"; + value = "200%"; + } else { + opt_key = ""; + } + } else if (opt_key == "seam_position") { + if (value == "hidden") { + opt_key = "seam_travel_cost"; + value = "20%"; + } } - // Ignore the following obsolete configuration keys: static std::set ignore = { "duplicate_x", "duplicate_y", "gcode_arcs", "multiply_x", "multiply_y", diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index cda26f0f3..03f54a927 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -100,7 +100,7 @@ enum SupportMaterialPattern { }; enum SeamPosition { - spRandom, spNearest, spAligned, spRear, spHidden, spCustom + spRandom, spNearest, spAligned, spRear, spCustom }; enum SLAMaterial { @@ -272,11 +272,11 @@ template<> inline const t_config_enum_values& ConfigOptionEnum::ge static t_config_enum_values keys_map; if (keys_map.empty()) { keys_map["random"] = spRandom; - keys_map["nearest"] = spHidden; + keys_map["nearest"] = spNearest; keys_map["near"] = spNearest; keys_map["aligned"] = spAligned; keys_map["rear"] = spRear; - keys_map["hidden"] = spHidden; + keys_map["hidden"] = spNearest; keys_map["custom"] = spCustom; } return keys_map; @@ -587,7 +587,8 @@ public: ConfigOptionPercent perimeter_bonding; ConfigOptionInt raft_layers; ConfigOptionEnum seam_position; - ConfigOptionBool seam_travel; + ConfigOptionPercent seam_angle_cost; + ConfigOptionPercent seam_travel_cost; // ConfigOptionFloat seam_preferred_direction; // ConfigOptionFloat seam_preferred_direction_jitter; ConfigOptionFloat slice_closing_radius; @@ -650,7 +651,8 @@ protected: OPT_PTR(perimeter_bonding); OPT_PTR(raft_layers); OPT_PTR(seam_position); - OPT_PTR(seam_travel); + OPT_PTR(seam_angle_cost); + OPT_PTR(seam_travel_cost); OPT_PTR(slice_closing_radius); // OPT_PTR(seam_preferred_direction); // OPT_PTR(seam_preferred_direction_jitter); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index ecc9cae91..e058b3984 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -819,7 +819,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector &layer_height_profile) // slicing in parallel std::vector expolygons_by_layer = this->slice_region(region_id, slice_zs, slicing_mode); //scale for shrinkage - double scale = print()->config().filament_shrink.get_abs_value(this->print()->regions()[region_id]->extruder(FlowRole::frPerimeter) - 1, 1); + std::cout << (&(this->print()->regions())) << " =?= " << (&(this->print()->m_regions)) << "\n"; + const size_t extruder_id = this->print()->regions()[region_id]->extruder(FlowRole::frPerimeter) - 1; + double scale = print()->config().filament_shrink.get_abs_value(extruder_id, 1); if (scale != 1) { scale = 1 / scale; for (ExPolygons &polys : expolygons_by_layer) diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 183d79d38..a2b5b6cbb 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -81,7 +81,7 @@ void PreferencesDialog::build() def.label = L("Check for application updates"); def.type = coBool; def.tooltip = L("If enabled, SuperSlicer will check for the new versions of itself online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done."); - def.set_default_value(new ConfigOptionBool(app_config->get("version_check") == "0")); + def.set_default_value(new ConfigOptionBool(app_config->get("version_check") == "1")); option = Option(def, "version_check"); m_optgroup_general->append_single_option_line(option); @@ -97,7 +97,7 @@ void PreferencesDialog::build() def.label = L("Update built-in Presets automatically"); def.type = coBool; def.tooltip = L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded into a separate temporary location. When a new preset version becomes available it is offered at application startup."); - def.set_default_value(new ConfigOptionBool(app_config->get("preset_update") == "0")); + def.set_default_value(new ConfigOptionBool(app_config->get("preset_update") == "1")); option = Option(def, "preset_update"); m_optgroup_general->append_single_option_line(option); @@ -117,25 +117,12 @@ void PreferencesDialog::build() option = Option(def, "show_incompatible_presets"); m_optgroup_general->append_single_option_line(option); - def.label = L("Main GUI always in expert mode"); - def.type = coBool; - def.tooltip = L("If enabled, the gui will be in expert mode even if the simple or advanced mode is selected (but not the setting tabs)."); - def.set_default_value(new ConfigOptionBool{ app_config->get("objects_always_expert") == "1" }); - option = Option(def, "objects_always_expert"); - m_optgroup_general->append_single_option_line(option); - - m_optgroup_paths = std::make_shared(this, _(L("General"))); - m_optgroup_paths->title_width = 10; - m_optgroup_paths->m_on_change = [this](t_config_option_key opt_key, boost::any value) { - m_values[opt_key] = boost::any_cast(value); - }; - def.label = L("FreeCAD path"); - def.type = coString; - def.tooltip = L("If it point to a valid freecad instance (the bin directory or the python executable), you can use the built-in python script to quickly generate geometry."); - def.set_default_value(new ConfigOptionString{ app_config->get("freecad_path") }); - option = Option(def, "freecad_path"); - option.opt.full_width = true; - m_optgroup_paths->append_single_option_line(option); + def.label = L("Main GUI always in expert mode"); + def.type = coBool; + def.tooltip = L("If enabled, the gui will be in expert mode even if the simple or advanced mode is selected (but not the setting tabs)."); + def.set_default_value(new ConfigOptionBool{ app_config->get("objects_always_expert") == "1" }); + option = Option(def, "objects_always_expert"); + m_optgroup_general->append_single_option_line(option); def.label = L("Single Instance"); def.type = coBool; @@ -195,6 +182,21 @@ void PreferencesDialog::build() m_optgroup_general->activate(); + m_optgroup_paths = std::make_shared(this, _(L("Paths"))); + m_optgroup_paths->title_width = 10; + m_optgroup_paths->m_on_change = [this](t_config_option_key opt_key, boost::any value) { + m_values[opt_key] = boost::any_cast(value); + }; + def.label = L("FreeCAD path"); + def.type = coString; + def.tooltip = L("If it point to a valid freecad instance (the bin directory or the python executable), you can use the built-in python script to quickly generate geometry."); + def.set_default_value(new ConfigOptionString{ app_config->get("freecad_path") }); + option = Option(def, "freecad_path"); + option.opt.full_width = true; + m_optgroup_paths->append_single_option_line(option); + + m_optgroup_paths->activate(); + m_optgroup_camera = std::make_shared(this, _L("Camera")); m_optgroup_camera->label_width = 40; m_optgroup_camera->m_on_change = [this](t_config_option_key opt_key, boost::any value) {