Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2021-11-18 15:36:23 +0300
committersupermerill <merill@free.fr>2021-11-18 15:36:23 +0300
commit8e14a10b12b14450b7dcbac281f5f24c62769f81 (patch)
treead8ef80d59560c0c25a5310e75b841490b22da01
parenta9a7f1bcf606e027fca8251f1ea8b2093980ab8b (diff)
parent0d25f9b266ebe279a14e1a494bb60262f8ff9f2f (diff)
Merge branch 'stable'2.3.57.6
-rw-r--r--doc/How to build - Windows.md4
-rw-r--r--resources/localization/README.md28
m---------resources/profiles0
-rw-r--r--resources/ui_layout/print.ui5
-rw-r--r--src/libslic3r/ClipperUtils.cpp7
-rw-r--r--src/libslic3r/Config.cpp2
-rw-r--r--src/libslic3r/Fill/Fill.cpp69
-rw-r--r--src/libslic3r/Fill/FillBase.cpp7
-rw-r--r--src/libslic3r/Fill/FillBase.hpp11
-rw-r--r--src/libslic3r/Fill/FillConcentric.cpp2
-rw-r--r--src/libslic3r/Fill/FillConcentric.hpp2
-rw-r--r--src/libslic3r/Fill/FillLine.cpp4
-rw-r--r--src/libslic3r/Fill/FillLine.hpp2
-rw-r--r--src/libslic3r/Fill/FillRectilinear.cpp90
-rw-r--r--src/libslic3r/Fill/FillRectilinear.hpp2
-rw-r--r--src/libslic3r/Fill/FillSmooth.cpp5
-rw-r--r--src/libslic3r/Flow.cpp8
-rw-r--r--src/libslic3r/Flow.hpp3
-rw-r--r--src/libslic3r/GCode.cpp13
-rw-r--r--src/libslic3r/PlaceholderParser.cpp38
-rw-r--r--src/libslic3r/Preset.cpp3
-rw-r--r--src/libslic3r/PrintConfig.cpp30
-rw-r--r--src/libslic3r/PrintConfig.hpp2
-rw-r--r--src/libslic3r/PrintObject.cpp2
-rw-r--r--src/slic3r/GUI/CalibrationBridgeDialog.cpp12
-rw-r--r--src/slic3r/GUI/CalibrationRetractionDialog.cpp14
-rw-r--r--src/slic3r/GUI/ConfigManipulation.cpp1
-rw-r--r--src/slic3r/GUI/Field.cpp180
-rw-r--r--src/slic3r/GUI/Field.hpp4
29 files changed, 343 insertions, 207 deletions
diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md
index a6fad03a1..5a96dcdb7 100644
--- a/doc/How to build - Windows.md
+++ b/doc/How to build - Windows.md
@@ -28,13 +28,13 @@ cmake .. -G "Visual Studio 16 2019" -A x64
msbuild /m ALL_BUILD.vcxproj
```
-and then build Slic3r (in ./build):
+and then build and install Slic3r (in ./build as an elevated Command Prompt - 'Run As Administrator'):
```
cmake .. -G "Visual Studio 16 2019" -A x64 -DCMAKE_PREFIX_PATH="PATH_TO_Slic3r\deps\build\destdir\usr\local"
msbuild /m /P:Configuration=Release INSTALL.vcxproj
```
You can also build it in visual studio, for that open the .sln.
-Note that you need to have `libgmp-10.dll` and `libmpfr-4.dll` next to your built Slic3r. You can get them from any Slic3r release.
+Note that you need to have `libgmp-10.dll` and `libmpfr-4.dll` next to your built Slic3r. You can get them from any Slic3r release: So copy these two dlls from your deps-build dir (default: "\deps\build\destdir\usr\local\bin") into the target installation dir of Slic3r (default: "C:\Program Files (x86)\Slic3r")
If you want to create the zipped release, you can follow this [script](https://github.com/supermerill/Slic3r/blob/master/.github/workflows/ccpp_win.yml).
diff --git a/resources/localization/README.md b/resources/localization/README.md
index 0b22ed33f..ebc9fbd7c 100644
--- a/resources/localization/README.md
+++ b/resources/localization/README.md
@@ -16,25 +16,25 @@ If you found an odd translation and want to change it, go to section B)
Useful tools:
* windows:
- * [python](https://www.python.org/)
- * [gettext](http://gnuwin32.sourceforge.net/downlinks/gettext.php)
+ * [python](https://www.python.org/)
+ * [gettext](http://gnuwin32.sourceforge.net/downlinks/gettext.php)
* linux:
* python: make sure you can execute python3, install it if it isn't here.
* gettext: if you can't execute msgfmt, install the package 'gettext'
* macos: maybe like linux?
### 1) initialisation
-open the settings.ini
-for each file that can contain useful translation, create/edit a "data" line to point to the said file.
-The 'input' property must be the Slic3r.pot path
-The 'output' must be the Slic3r.po
-The 'todo' contains the path of the po file to complete.
+Open the settings.ini
+* For each file that can contain useful translation, create/edit a "data" line to point to the said file.
+* The 'input' property must be the Slic3r.pot path
+* The 'output' must be the Slic3r.po
+* The 'todo' contains the path of the po file to complete.
note that the first data line has the priority over the other ones (the first translation encountered is the one used)
-In this example, we are going to update the Spanish translation.
-We are going to use your old translation file and the current PrusaSlicer one.
-To decompile the .mo of Prusaslicer, use the command `msgunfmt PrusaSlicer.mo -o PrusaSlicer.po`.
+In this example, we are going to update the Spanish translation.
+We are going to use your old translation file and the current PrusaSlicer one.
+To decompile the .mo of Prusaslicer, use the command `msgunfmt PrusaSlicer.mo -o PrusaSlicer.po`.
So the settings.ini contains these lines :
```
@@ -59,13 +59,13 @@ output = es/Slic3r.po
```
Notes:
-* thee 'todo' and 'output' files will be erased, so be sure nothing important has this name (or write another name)
-* the file at 'database_out' will receive all the database created from the data files. That way, it will keep your new & old unused translations just in case the wording revert back to it, or to be used as reference for the helper.
+* the 'todo' and 'output' files will be erased, so be sure you didn't use this file name (or copy it elsewhere). Note that often, Slic3r.po is used as input & output, as it's the "updated" file.
+* the file at 'database_out' will receive all the translations created from the data files. That way, it will keep your new & old unused translations just in case the wording revert back to it, or to be used as reference for the helper.
* ui_dir should be the path to the slic3r/resources/ui_layout directory. If you're in slic3r/resources/localization, this value is good.
* allow_msgctxt is a bool to allow to keep the msgctxt tags. You need a recent version of gettext to use that.
* ignore_case is a bool that will let the tool to ignore the case when comparing msgid if no translation is found.
-* remove_comment is a bool taht will remove all comment in the output file. It's to avoid unecessary changes in the git commit.
-* percent_error_similar is a number between 0 and 1. This will activate the helper that will write help comment in the TODO file. These will present similar string that are already translated, to let you pick chunk that are already translated to avoid redoing all the work. It's the percentage of difference allowed (0 = identical, 1 = everything, 0.5 = not more than half of the string is different), using (levenshtein distance / msgid length).
+* remove_comment is a bool that will remove all comments in the output file. It's to avoid unecessary changes in the git commit. Don't submit pull request for '.po' file with comments. (Note that the translations are ordered by alphabetic order)
+* percent_error_similar is a number between 0 and 1. This will activate the helper that will write help comment in the TODO file. These will present similar string that are already translated, to let you pick chunk that are already translated to avoid redoing all the work. It's the percentage of difference allowed (0 = identical, 1 = everything, 0.5 = not more than half of the string is different), using (levenshtein distance / msgid length). You have to install the levenshtein lib in python to use it.
* max_similar: max number of help translation per item
* language and language_code: text to include in the header.
diff --git a/resources/profiles b/resources/profiles
-Subproject 38cf62ab55e88865c21d8d8b15f8fd1d0b5139a
+Subproject bac080959a79df36f6cfb9f58d1589f54fa60b5
diff --git a/resources/ui_layout/print.ui b/resources/ui_layout/print.ui
index 2eb5ff0d6..b5f893b70 100644
--- a/resources/ui_layout/print.ui
+++ b/resources/ui_layout/print.ui
@@ -321,8 +321,11 @@ group:Overlap
setting:label$External:external_perimeter_overlap
setting:label$Gap Fill:gap_fill_overlap
end_line
+ line:Bridge lines density
+ setting:bridge_overlap_min
+ setting:bridge_overlap
+ end_line
setting:sidetext_width$7:infill_overlap
- setting:bridge_overlap
group:Flow
line:Flow ratio
setting:bridge_flow_ratio
diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp
index cc91ce050..431c4ed0f 100644
--- a/src/libslic3r/ClipperUtils.cpp
+++ b/src/libslic3r/ClipperUtils.cpp
@@ -598,6 +598,10 @@ ClipperLib::PolyTree _clipper_do_pl(const ClipperLib::ClipType clipType, const P
// read input
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
ClipperLib::Paths input_clip = Slic3rMultiPoints_to_ClipperPaths(clip);
+
+ // perform safety offset (before scaling because it scale & unscale)
+ if (safety_offset_) safety_offset(&input_clip);
+
//scale to have some more precision to do some Y-bugfix
scaleClipperPolygons(input_subject);
scaleClipperPolygons(input_clip);
@@ -614,9 +618,6 @@ ClipperLib::PolyTree _clipper_do_pl(const ClipperLib::ClipType clipType, const P
lasty = pt.Y;
}
}
-
- // perform safety offset
- if (safety_offset_) safety_offset(&input_clip);
// init Clipper
ClipperLib::Clipper clipper;
diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp
index 741c1d832..ee3fda467 100644
--- a/src/libslic3r/Config.cpp
+++ b/src/libslic3r/Config.cpp
@@ -710,7 +710,7 @@ double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int ex
//FIXME there are some ratio_over chains, which end with empty ratio_with.
// For example, XXX_extrusion_width parameters are not handled by get_abs_value correctly.
if (!opt_def->ratio_over.empty() && opt_def->ratio_over != "depends")
- return cast_opt->get_abs_value(this->get_computed_value(opt_def->ratio_over));
+ return cast_opt->get_abs_value(this->get_computed_value(opt_def->ratio_over, extruder_id));
std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " has no valid ratio_over to compute of";
throw ConfigurationError(ss.str());
diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index 9f0030fa3..aa1b38d76 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -23,9 +23,9 @@ struct SurfaceFillParams : FillParams
// FillBase
// in unscaled coordinates
- coordf_t spacing = 0.;
+ double spacing = 0.;
// infill / perimeter overlap, in unscaled coordinates
- coordf_t overlap = 0.;
+ double overlap = 0.;
// Angle as provided by the region config, in radians.
float angle = 0.f;
// Non-negative for a bridge.
@@ -435,6 +435,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
store_fill(current_region_id);
}
current_region_id = surface_fill.region_id;
+ const LayerRegion* layerm = this->m_regions[surface_fill.region_id];
// Create the filler object.
std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));
@@ -446,6 +447,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
// calculate flow spacing for infill pattern generation
bool using_internal_flow = ! surface_fill.surface.has_fill_solid() && ! surface_fill.params.flow.bridge;
+ //init spacing, it may also use & modify a bit the surface_fill.params, so most of these should be set before.
+ // note that the bridge overlap is applied here via the rectilinear init_spacing.
f->init_spacing(surface_fill.params.spacing, surface_fill.params);
double link_max_length = 0.;
if (! surface_fill.params.flow.bridge) {
@@ -463,7 +466,6 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
//give the overlap size to let the infill do his overlap
//add overlap if at least one perimeter
- const LayerRegion* layerm = this->m_regions[surface_fill.region_id];
const float perimeter_spacing = layerm->flow(frPerimeter).spacing();
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
@@ -485,10 +487,6 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
surface_fill.params.flow = Flow::new_from_spacing((float)f->get_spacing(), surface_fill.params.flow.nozzle_diameter, (float)surface_fill.params.flow.height, overlap, surface_fill.params.flow.bridge);
}
- //apply bridge_overlap if needed
- if (surface_fill.params.flow.bridge && surface_fill.params.density > 0.99 && layerm->region()->config().bridge_overlap.get_abs_value(1) != 1) {
- surface_fill.params.density *= float(layerm->region()->config().bridge_overlap.get_abs_value(1));
- }
for (ExPolygon &expoly : surface_fill.expolygons) {
//set overlap polygons
@@ -509,6 +507,63 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
if (!expoly.contour.empty()) {
surface_fill.surface.expolygon = std::move(expoly);
+ //adjust the bridge density
+ if (surface_fill.params.flow.bridge && surface_fill.params.density > 0.99 /*&& layerm->region()->config().bridge_overlap.get_abs_value(1) != 1*/) {
+ ////varies the overlap to have teh best coverage for the bridge
+ //surface_fill.params.density *= float(layerm->region()->config().bridge_overlap.get_abs_value(1));
+ double min_spacing = 0.999 * surface_fill.params.spacing / surface_fill.params.config->bridge_overlap.get_abs_value(surface_fill.params.density);
+ double max_spacing = 1.001 * surface_fill.params.spacing / surface_fill.params.config->bridge_overlap_min.get_abs_value(surface_fill.params.density);
+ double factor = 1.00001;
+ if (min_spacing < max_spacing * 1.01) {
+ // create a bouding box of the rotated surface
+ coord_t bounding_box_size_x = 0;
+ Polygon poly = surface_fill.surface.expolygon.contour;
+ coord_t bounding_box_min_x = 0;
+ poly.rotate(PI / 2 - (surface_fill.params.bridge_angle < 0 ? surface_fill.params.angle : surface_fill.params.bridge_angle));
+ ExPolygons expolys;
+ if (surface_fill.params.bridge_angle > 0 && !f->no_overlap_expolygons.empty()) {
+ //take only the no-overlap area
+ expolys = offset_ex(intersection_ex(ExPolygons{ ExPolygon{surface_fill.surface.expolygon.contour} }, f->no_overlap_expolygons), -scale_t(surface_fill.params.spacing) / 2 - 10);
+ } else {
+ expolys = offset_ex(ExPolygon{surface_fill.surface.expolygon.contour}, -scale_t(surface_fill.params.spacing) / 2 - 10);
+ }
+ BoundingBox bb;
+ bool first = true;
+ for (ExPolygon& expoly : expolys) {
+ expoly.holes.clear();
+ expoly.rotate(PI / 2 - (surface_fill.params.bridge_angle < 0 ? surface_fill.params.angle : surface_fill.params.bridge_angle));
+ if (first) {
+ bb = expoly.contour.bounding_box();
+ first = false;
+ } else {
+ bb.merge(expoly.contour.points);
+ }
+ }
+ bounding_box_size_x = bb.size().x();
+ bounding_box_min_x = bb.min.x();
+
+ //compute the dist
+ double new_spacing = unscaled(f->_adjust_solid_spacing(bounding_box_size_x, scale_t(min_spacing), 2));
+ if (new_spacing <= max_spacing) {
+ surface_fill.params.density = factor * surface_fill.params.spacing / new_spacing;
+ } else {
+ double new_spacing2 = unscaled(f->_adjust_solid_spacing(bounding_box_size_x, scale_t(min_spacing * 1.999 - new_spacing), 2));
+ if (new_spacing2 < min_spacing) {
+ if (min_spacing - new_spacing2 < new_spacing - max_spacing) {
+ surface_fill.params.density = surface_fill.params.config->bridge_overlap.get_abs_value(surface_fill.params.density);
+ } else {
+ surface_fill.params.density = surface_fill.params.config->bridge_overlap_min.get_abs_value(surface_fill.params.density);
+ }
+ } else {
+ //use the highest density
+ surface_fill.params.density = surface_fill.params.config->bridge_overlap.get_abs_value(surface_fill.params.density);
+ }
+ }
+ surface_fill.params.dont_adjust = true;
+ surface_fill.params.bridge_offset = std::abs(poly.bounding_box().min.x() - bounding_box_min_x);
+ }
+ }
+
//make fill
while ((size_t)surface_fill.params.priority >= fills_by_priority.size())
fills_by_priority.push_back(new ExtrusionEntityCollection());
diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp
index 08bcc9d9f..b2806c19d 100644
--- a/src/libslic3r/Fill/FillBase.cpp
+++ b/src/libslic3r/Fill/FillBase.cpp
@@ -84,7 +84,7 @@ Polylines Fill::fill_surface(const Surface *surface, const FillParams &params) c
// This function possibly increases the spacing, never decreases,
// and for a narrow width the increase in spacing may become severe,
// therefore the adjustment is limited to 20% increase.
-coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance)
+coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance, const double factor_max)
{
assert(width >= 0);
assert(distance > 0);
@@ -93,10 +93,9 @@ coord_t Fill::_adjust_solid_spacing(const coord_t width, const coord_t distance)
coord_t distance_new = (number_of_intervals == 0) ?
distance :
(coord_t)(((width - EPSILON) / number_of_intervals));
- const coordf_t factor = coordf_t(distance_new) / coordf_t(distance);
+ const double factor = coordf_t(distance_new) / coordf_t(distance);
assert(factor > 1. - 1e-5);
// How much could the extrusion width be increased? By 20%.
- const coordf_t factor_max = 1.2;
if (factor > factor_max)
distance_new = coord_t(floor((coordf_t(distance) * factor_max + 0.5)));
return distance_new;
@@ -228,7 +227,7 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &para
coord_t Fill::_line_spacing_for_density(float density) const
{
- return scale_(this->get_spacing() / density);
+ return scale_t(this->get_spacing() / density);
}
//FIXME: add recent improvmeent from perimetergenerator: avoid thick gapfill
diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp
index bfac2d55b..5c5773b10 100644
--- a/src/libslic3r/Fill/FillBase.hpp
+++ b/src/libslic3r/Fill/FillBase.hpp
@@ -44,6 +44,9 @@ struct FillParams
// Fill density, fraction in <0, 1>
float density { 0.f };
+ // bridge offset from the centerline.
+ coord_t bridge_offset = -1;
+
// Fill extruding flow multiplier, fraction in <0, 1>. Used by "over bridge compensation"
float flow_mult { 1.0f };
@@ -108,7 +111,7 @@ public:
FillAdaptive::Octree* adapt_fill_octree = nullptr;
protected:
// in unscaled coordinates, please use init (after settings all others settings) as some algos want to modify the value
- coordf_t spacing_priv;
+ double spacing_priv;
public:
virtual ~Fill() {}
@@ -118,8 +121,8 @@ public:
static Fill* new_from_type(const std::string &type);
void set_bounding_box(const Slic3r::BoundingBox &bbox) { bounding_box = bbox; }
- virtual void init_spacing(coordf_t spacing, const FillParams &params) { this->spacing_priv = spacing; }
- coordf_t get_spacing() const { return spacing_priv; }
+ virtual void init_spacing(double spacing, const FillParams &params) { this->spacing_priv = spacing; }
+ double get_spacing() const { return spacing_priv; }
// Do not sort the fill lines to optimize the print head path?
virtual bool no_sort() const { return false; }
@@ -181,7 +184,7 @@ public:
//for rectilinear
static void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, const Polygons& polygons_src, Polylines& polylines_out, const double spacing, const FillParams& params);
- static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance);
+ static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance, const double factor_max = 1.2);
// Align a coordinate to a grid. The coordinate may be negative,
// the aligned value will never be bigger than the original one.
diff --git a/src/libslic3r/Fill/FillConcentric.cpp b/src/libslic3r/Fill/FillConcentric.cpp
index 86de14193..6da55e454 100644
--- a/src/libslic3r/Fill/FillConcentric.cpp
+++ b/src/libslic3r/Fill/FillConcentric.cpp
@@ -14,7 +14,7 @@ FillConcentric::init_spacing(coordf_t spacing, const FillParams &params)
{
Fill::init_spacing(spacing, params);
if (params.density > 0.9999f && !params.dont_adjust) {
- this->spacing_priv = unscale<double>(this->_adjust_solid_spacing(bounding_box.size()(0), _line_spacing_for_density(params.density)));
+ this->spacing_priv = unscaled(this->_adjust_solid_spacing(bounding_box.size()(0), _line_spacing_for_density(params.density)));
}
}
diff --git a/src/libslic3r/Fill/FillConcentric.hpp b/src/libslic3r/Fill/FillConcentric.hpp
index b111ed7cf..8a6e97f9e 100644
--- a/src/libslic3r/Fill/FillConcentric.hpp
+++ b/src/libslic3r/Fill/FillConcentric.hpp
@@ -12,7 +12,7 @@ public:
protected:
Fill* clone() const override { return new FillConcentric(*this); };
- void init_spacing(coordf_t spacing, const FillParams &params) override;
+ void init_spacing(double spacing, const FillParams &params) override;
void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
diff --git a/src/libslic3r/Fill/FillLine.cpp b/src/libslic3r/Fill/FillLine.cpp
index eb2a17af5..356528e94 100644
--- a/src/libslic3r/Fill/FillLine.cpp
+++ b/src/libslic3r/Fill/FillLine.cpp
@@ -7,9 +7,9 @@
namespace Slic3r {
-void FillLine::init_spacing(coordf_t spacing, const FillParams& params) {
+void FillLine::init_spacing(double spacing, const FillParams& params) {
- this->_min_spacing = scale_(spacing);
+ this->_min_spacing = scale_t(spacing);
assert(params.density > 0.0001f && params.density <= 1.f);
this->_line_spacing = coord_t(coordf_t(this->_min_spacing) / params.density);
this->_diagonal_distance = this->_line_spacing * 2;
diff --git a/src/libslic3r/Fill/FillLine.hpp b/src/libslic3r/Fill/FillLine.hpp
index f14b9c4bb..771639d4f 100644
--- a/src/libslic3r/Fill/FillLine.hpp
+++ b/src/libslic3r/Fill/FillLine.hpp
@@ -15,7 +15,7 @@ public:
Fill* clone() const override { return new FillLine(*this); };
~FillLine() override = default;
- void init_spacing(coordf_t spacing, const FillParams& params) override;
+ void init_spacing(double spacing, const FillParams& params) override;
protected:
void _fill_surface_single(
const FillParams &params,
diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp
index 3e557956a..ab5418b56 100644
--- a/src/libslic3r/Fill/FillRectilinear.cpp
+++ b/src/libslic3r/Fill/FillRectilinear.cpp
@@ -754,13 +754,13 @@ static inline float measure_outer_contour_slab(
*/
void
-FillRectilinear::init_spacing(coordf_t spacing, const FillParams& params)
+FillRectilinear::init_spacing(double spacing, const FillParams& params)
{
Fill::init_spacing(spacing, params);
//remove this code path becaus it's only really useful for squares at 45° and it override a setting
// define flow spacing according to requested density
//if (params.full_infill() && !params.dont_adjust) {
- // this->spacing = unscale<coordf_t>(this->_adjust_solid_spacing(bounding_box.size()(0), _line_spacing_for_density(params.density)));
+ // this->spacing = unscaled(this->_adjust_solid_spacing(bounding_box.size()(0), _line_spacing_for_density(params.density)));
//}
}
@@ -774,9 +774,11 @@ enum DirectionMask
std::vector<SegmentedIntersectionLine> FillRectilinear::_vert_lines_for_polygon(const ExPolygonWithOffset &poly_with_offset, const BoundingBox &bounding_box, const FillParams &params, coord_t line_spacing) const
{
// n_vlines = ceil(bbox_width / line_spacing)
- size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing;
- coord_t x0 = bounding_box.min(0);
- if (params.full_infill())
+ size_t n_vlines = 1 + (bounding_box.max.x() - bounding_box.min.x() - 10) / line_spacing;
+ coord_t x0 = bounding_box.min.x();
+ if (params.flow.bridge && params.bridge_offset >= 0) {
+ x0 += params.bridge_offset;
+ }else if (params.full_infill())
x0 += (line_spacing + coord_t(SCALED_EPSILON)) / 2;
#ifdef SLIC3R_DEBUG
@@ -1253,7 +1255,7 @@ static void connect_segment_intersections_by_contours(
SegmentIntersection& it2 = il.intersections[it.left_vertical()];
assert(it2.left_vertical() == i_intersection);
it2.prev_on_contour_quality = SegmentIntersection::LinkQuality::Invalid;
- }
+ }
if (it.has_right_vertical() && it.next_on_contour_quality == SegmentIntersection::LinkQuality::Invalid) {
SegmentIntersection& it2 = il.intersections[it.right_vertical()];
assert(it2.right_vertical() == i_intersection);
@@ -1263,7 +1265,7 @@ static void connect_segment_intersections_by_contours(
}
assert(validate_segment_intersection_connectivity(segs));
- }
+}
static void pinch_contours_insert_phony_outer_intersections(std::vector<SegmentedIntersectionLine> &segs)
{
@@ -1277,41 +1279,49 @@ static void pinch_contours_insert_phony_outer_intersections(std::vector<Segmente
for (size_t i_vline = 1; i_vline < segs.size(); ++ i_vline) {
SegmentedIntersectionLine &il = segs[i_vline];
assert(il.intersections.empty() || il.intersections.size() >= 2);
- if (! il.intersections.empty()) {
+ if (il.intersections.size() > 2) {
+ //these can trigger....(2 segments, high then low) but less if I check for il.intersections.size() > 2 instead of !empty()
assert(il.intersections.front().type == SegmentIntersection::OUTER_LOW);
assert(il.intersections.back().type == SegmentIntersection::OUTER_HIGH);
auto end = il.intersections.end() - 1;
insert_after.clear();
- for (auto it = il.intersections.begin() + 1; it != end;) {
- if (it->type == SegmentIntersection::OUTER_HIGH) {
- ++ it;
- assert(it->type == SegmentIntersection::OUTER_LOW);
- ++ it;
+ size_t idx = 1;
+ while(idx < il.intersections.size()) {
+ if (il.intersections[idx].type == SegmentIntersection::OUTER_HIGH) {
+ if (idx + 1 < il.intersections.size()) {
+ assert(il.intersections[idx + 1].type == SegmentIntersection::OUTER_LOW);
+ }
+ idx += 2;
} else {
- auto lo = it;
- assert(lo->type == SegmentIntersection::INNER_LOW);
- auto hi = ++ it;
- assert(hi->type == SegmentIntersection::INNER_HIGH);
- auto lo2 = ++ it;
- if (lo2->type == SegmentIntersection::INNER_LOW) {
- // INNER_HIGH followed by INNER_LOW. The outer contour may have squeezed the inner contour into two separate loops.
- // In that case one shall insert a phony OUTER_HIGH / OUTER_LOW pair.
- int up = hi->vertical_up();
- int dn = lo2->vertical_down();
+ size_t loidx = idx;
+ const SegmentIntersection& lo = il.intersections[loidx];
+ assert(lo.type == SegmentIntersection::INNER_LOW);
+ size_t hiidx = ++idx;
+ const SegmentIntersection& hi = il.intersections[hiidx];
+ assert(hi.type == SegmentIntersection::INNER_HIGH);
+ size_t lo2idx = ++idx;
+ if (lo2idx < il.intersections.size()) {
+ const SegmentIntersection& lo2 = il.intersections[lo2idx];
+ if (lo2.type == SegmentIntersection::INNER_LOW) {
+ // INNER_HIGH followed by INNER_LOW. The outer contour may have squeezed the inner contour into two separate loops.
+ // In that case one shall insert a phony OUTER_HIGH / OUTER_LOW pair.
+ int up = hi.vertical_up();
+ int dn = lo2.vertical_down();
#ifndef _NDEBUG
- assert(up == -1 || up > 0);
- assert(dn == -1 || dn >= 0);
- assert((up == -1 && dn == -1) || (dn + 1 == up));
+ assert(up == -1 || up > 0);
+ assert(dn == -1 || dn >= 0);
+ assert((up == -1 && dn == -1) || (dn + 1 == up));
#endif // _NDEBUG
- bool pinched = dn + 1 != up;
- if (pinched) {
- // hi is not connected with its inner contour to lo2.
- // Insert a phony OUTER_HIGH / OUTER_LOW pair.
+ bool pinched = dn + 1 != up;
+ if (pinched) {
+ // hi is not connected with its inner contour to lo2.
+ // Insert a phony OUTER_HIGH / OUTER_LOW pair.
#if 0
- static int pinch_idx = 0;
- printf("Pinched %d\n", pinch_idx++);
+ static int pinch_idx = 0;
+ printf("Pinched %d\n", pinch_idx++);
#endif
- insert_after.emplace_back(hi - il.intersections.begin());
+ insert_after.emplace_back(hiidx);
+ }
}
}
}
@@ -2805,8 +2815,8 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa
// Shrink the input polygon a bit first to not push the infill lines out of the perimeters.
// const float INFILL_OVERLAP_OVER_SPACING = 0.3f;
- const float INFILL_OVERLAP_OVER_SPACING = 0.45f; //merill: what is this value??? shouldn't it be like flow.width()?
- assert(INFILL_OVERLAP_OVER_SPACING > 0 && INFILL_OVERLAP_OVER_SPACING < 0.5f);
+ //const float INFILL_OVERLAP_OVER_SPACING = 0.45f; //merill: what is this value???
+ //assert(INFILL_OVERLAP_OVER_SPACING > 0 && INFILL_OVERLAP_OVER_SPACING < 0.5f);
// Rotate polygons so that we can work with vertical lines here
std::pair<float, Point> rotate_vector = this->_infill_direction(surface);
@@ -2819,8 +2829,8 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa
ExPolygonWithOffset poly_with_offset(
surface->expolygon,
- rotate_vector.first,
- (scale_t(0 /*this->overlap*/ - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->get_spacing())),
- (scale_t(0 /*this->overlap*/ - 0.5f * this->get_spacing())));
+ (scale_t(0 /*this->overlap*/ - /*(0.5 - INFILL_OVERLAP_OVER_SPACING)*/ 0.05 * this->get_spacing())), // outer offset, have to be > to the inner one (less negative)
+ (scale_t(0 /*this->overlap*/ - 0.48f * this->get_spacing()))); // inner offset (don't put 0.5, as it will cut full-filled area when it's exactly at the right place)
if (poly_with_offset.n_contours_inner == 0) {
// Not a single infill line fits.
//Prusa: maybe one shall trigger the gap fill here?
@@ -2831,15 +2841,15 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa
BoundingBox bounding_box = poly_with_offset.bounding_box_src();
// define flow spacing according to requested density
- if (params.full_infill() && !params.dont_adjust || line_spacing == 0 ) {
+ if ((params.full_infill() && !params.dont_adjust) || line_spacing == 0 ) {
//it's == this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing) because of the init_spacing
line_spacing = scale_(this->get_spacing());
- } else {
+ } else if (!params.full_infill()) {
// extend bounding box so that our pattern will be aligned with other layers
// Transform the reference point to the rotated coordinate system.
Point refpt = rotate_vector.second.rotated(- rotate_vector.first);
// _align_to_grid will not work correctly with positive pattern_shift.
- coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing;
+ coord_t pattern_shift_scaled = scale_t(pattern_shift) % line_spacing;
refpt.x() -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
bounding_box.merge(_align_to_grid(
bounding_box.min,
diff --git a/src/libslic3r/Fill/FillRectilinear.hpp b/src/libslic3r/Fill/FillRectilinear.hpp
index 9e3cc056e..d15abf4e5 100644
--- a/src/libslic3r/Fill/FillRectilinear.hpp
+++ b/src/libslic3r/Fill/FillRectilinear.hpp
@@ -16,7 +16,7 @@ class FillRectilinear : public Fill
public:
Fill* clone() const override { return new FillRectilinear(*this); };
~FillRectilinear() override = default;
- virtual void init_spacing(coordf_t spacing, const FillParams& params) override;
+ virtual void init_spacing(double spacing, const FillParams& params) override;
Polylines fill_surface(const Surface* surface, const FillParams& params) const override;
protected:
diff --git a/src/libslic3r/Fill/FillSmooth.cpp b/src/libslic3r/Fill/FillSmooth.cpp
index 4f6276ee6..3fa43d673 100644
--- a/src/libslic3r/Fill/FillSmooth.cpp
+++ b/src/libslic3r/Fill/FillSmooth.cpp
@@ -61,11 +61,12 @@ namespace Slic3r {
}
void FillSmooth::fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill,
- const FillParams &params, const double volume) const {
+ const FillParams &params_init, const double volume) const {
+ FillParams params = params_init;
std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[idx]));
f2->bounding_box = this->bounding_box;
- f2->init_spacing(this->get_spacing(),params);
+ f2->init_spacing(this->get_spacing(), params);
f2->layer_id = this->layer_id;
f2->z = this->z;
f2->angle = anglePass[idx] + this->angle;
diff --git a/src/libslic3r/Flow.cpp b/src/libslic3r/Flow.cpp
index 274c5af26..9f71af4b7 100644
--- a/src/libslic3r/Flow.cpp
+++ b/src/libslic3r/Flow.cpp
@@ -215,7 +215,7 @@ Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height,
// For normal extrusons, extrusion width is wider than the spacing due to the rounding and squishing of the extrusions.
// For bridge extrusions, the extrusions are placed with a tiny BRIDGE_EXTRA_SPACING gaps between the threads.
float width = float(bridge ?
- (spacing - BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter) :
+ (spacing /*- BRIDGE_EXTRA_SPACING_MULT (0.125) * nozzle_diameter*/) :
#ifdef HAS_PERIMETER_LINE_OVERLAP
(spacing + PERIMETER_LINE_OVERLAP_FACTOR * height * (1. - 0.25 * PI) * spacing_ratio);
#else
@@ -235,7 +235,7 @@ float Flow::spacing() const
float min_flow_spacing = this->width - this->height * (1. - 0.25 * PI) * spacing_ratio;
float res = this->width - PERIMETER_LINE_OVERLAP_FACTOR * (this->width - min_flow_spacing);
#else
- float res = float(this->bridge ? (this->width + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter) : (this->width - this->height * (1. - 0.25 * PI) * spacing_ratio));
+ float res = float(this->bridge ? (this->width /*+ BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter*/) : (this->width - this->height * (1. - 0.25 * PI) * spacing_ratio));
#endif
// assert(res > 0.f);
if (res <= 0.f)
@@ -250,8 +250,8 @@ float Flow::spacing(const Flow &other) const
{
assert(this->height == other.height);
assert(this->bridge == other.bridge);
- float res = float(this->bridge ?
- 0.5 * this->width + 0.5 * other.width + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter :
+ float res = float((this->bridge || other.bridge) ?
+ 0.5 * this->width + 0.5 * other.width :
0.5 * this->spacing() + 0.5 * other.spacing());
// assert(res > 0.f);
if (res <= 0.f)
diff --git a/src/libslic3r/Flow.hpp b/src/libslic3r/Flow.hpp
index 06c4a158f..9d9be77ee 100644
--- a/src/libslic3r/Flow.hpp
+++ b/src/libslic3r/Flow.hpp
@@ -10,9 +10,6 @@ namespace Slic3r {
class PrintObject;
-// Extra spacing of bridge threads, in mult of nozzle_width/extrusion_width. 0.05 for 0.4
-#define BRIDGE_EXTRA_SPACING_MULT 0.125
-
// Overlap factor of perimeter lines. Currently no overlap.
#ifdef HAS_PERIMETER_LINE_OVERLAP
#define PERIMETER_LINE_OVERLAP_FACTOR 1.0
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index b792985d3..e397c198f 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1399,6 +1399,10 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
m_placeholder_parser.set("first_layer_print_max", new ConfigOptionFloats({ bbox.max.x(), bbox.max.y() }));
m_placeholder_parser.set("first_layer_print_size", new ConfigOptionFloats({ bbox.size().x(), bbox.size().y() }));
}
+ //misc
+ if (config().thumbnails_color.value.length() == 7) {
+ m_placeholder_parser.set("thumbnails_color_int", new ConfigOptionInt((int)strtol(config().thumbnails_color.value.substr(1, 6).c_str(), NULL, 16)));
+ }
std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id);
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
@@ -1704,6 +1708,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
_write_format(file, "; total filament cost = %.2lf\n", print.m_print_statistics.total_cost);
if (print.m_print_statistics.total_toolchanges > 0)
_write_format(file, "; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges);
+ _write_format(file, "; total layers count = %i\n", m_layer_count);
_writeln(file, GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag);
// Append full config.
@@ -1742,7 +1747,7 @@ std::string GCode::placeholder_parser_process(const std::string &name, const std
func_add_colour("filament_colour_int", config().filament_colour.values[current_extruder_id]);
func_add_colour("extruder_colour_int", config().extruder_colour.values[current_extruder_id]);
}
- func_add_colour("thumbnails_color_int", config().thumbnails_color);
+ config_override->set_key_value("current_position", new ConfigOptionFloats({ unscaled(m_last_pos.x()), unscaled(m_last_pos.y()) }));
std::string gcode = m_placeholder_parser.process(templ, current_extruder_id, config_override, &m_placeholder_parser_context);
if (!gcode.empty() && (m_config.gcode_comments || m_config.fan_speedup_time.value != 0 || m_config.fan_kickstart.value != 0 )) {
@@ -3768,8 +3773,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string &descri
//we have to remove coeff percentage on path.width length
double coeff = cut_corner_cache[idx_angle-30];
//the length, do half of the work on width/4 and the other half on width/2
- coordf_t length1 = (path.width) / 4;
- coordf_t line_length = unscaled(line.length());
+ double length1 = (path.width) / 4;
+ double line_length = unscaled(line.length());
if (line_length > length1) {
double mult1 = 1 - coeff * 2;
double length2 = (path.width) / 2;
@@ -3785,7 +3790,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string &descri
sum += e_per_mm * (length1) * mult1;
if (line_length - length1 > length2) {
- Point inter_point2 = line.point_at(scale_d(length2));
+ Point inter_point2 = line.point_at(scale_d(length1 + length2));
//extrude reduced
gcode += m_writer.extrude_to_xy(
this->point_to_gcode(inter_point2),
diff --git a/src/libslic3r/PlaceholderParser.cpp b/src/libslic3r/PlaceholderParser.cpp
index 660f45ee4..c077d6cd7 100644
--- a/src/libslic3r/PlaceholderParser.cpp
+++ b/src/libslic3r/PlaceholderParser.cpp
@@ -1496,6 +1496,9 @@ bool PlaceholderParser::evaluate_boolean_expression(const std::string &templ, co
void PlaceholderParser::append_custom_variables(std::map<std::string, std::vector<std::string>> name2var_array, int nb_extruders) {
+
+ bool is_array = nb_extruders > 0;
+ if (!is_array) nb_extruders = 1;
std::regex is_a_name("[a-zA-Z_]+");
for (const auto& entry : name2var_array) {
if (entry.first.empty())
@@ -1575,17 +1578,27 @@ void PlaceholderParser::append_custom_variables(std::map<std::string, std::vecto
log << "Parsing NUM custom variable '" << entry.first << "' : ";
for (auto s : double_values) log << ", " << s;
BOOST_LOG_TRIVIAL(trace) << log.str();
- ConfigOptionFloats* conf = new ConfigOptionFloats(double_values);
- conf->set_is_extruder_size(true);
- this->set(entry.first, conf);
+ if (is_array) {
+ ConfigOptionFloats* conf = new ConfigOptionFloats(double_values);
+ conf->set_is_extruder_size(true);
+ this->set(entry.first, conf);
+ } else {
+ ConfigOptionFloat* conf = new ConfigOptionFloat(double_values[0]);
+ this->set(entry.first, conf);
+ }
} else if (!is_not_bool) {
std::stringstream log;
log << "Parsing BOOL custom variable '" << entry.first << "' : ";
for (auto s : bool_values) log << ", " << s;
BOOST_LOG_TRIVIAL(trace) << log.str();
- ConfigOptionBools* conf = new ConfigOptionBools(bool_values);
- conf->set_is_extruder_size(true);
- this->set(entry.first, conf);
+ if (is_array) {
+ ConfigOptionBools* conf = new ConfigOptionBools(bool_values);
+ conf->set_is_extruder_size(true);
+ this->set(entry.first, conf);
+ } else {
+ ConfigOptionBool* conf = new ConfigOptionBool(bool_values[0]);
+ this->set(entry.first, conf);
+ }
} else {
for (std::string& s : string_values)
boost::replace_all(s, "\\n", "\n");
@@ -1593,9 +1606,14 @@ void PlaceholderParser::append_custom_variables(std::map<std::string, std::vecto
log << "Parsing STR custom variable '" << entry.first << "' : ";
for (auto s : string_values) log << ", " << s;
BOOST_LOG_TRIVIAL(trace) << log.str();
- ConfigOptionStrings* conf = new ConfigOptionStrings(string_values);
- conf->set_is_extruder_size(true);
- this->set(entry.first, conf);
+ if (is_array) {
+ ConfigOptionStrings* conf = new ConfigOptionStrings(string_values);
+ conf->set_is_extruder_size(true);
+ this->set(entry.first, conf);
+ } else {
+ ConfigOptionString* conf = new ConfigOptionString(string_values[0]);
+ this->set(entry.first, conf);
+ }
}
}
@@ -1623,7 +1641,7 @@ void PlaceholderParser::parse_custom_variables(const ConfigOptionString& custom_
}
}
- append_custom_variables(name2var_array, 1);
+ append_custom_variables(name2var_array, 0);
}
void PlaceholderParser::parse_custom_variables(const ConfigOptionStrings& filament_custom_variables)
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index f79542964..d8be8af9e 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -591,6 +591,7 @@ const std::vector<std::string>& Preset::print_options()
"clip_multipart_objects",
"over_bridge_flow_ratio",
"bridge_overlap",
+ "bridge_overlap_min",
"first_layer_flow_ratio",
"clip_multipart_objects", "enforce_full_fill_volume", "external_infill_margin", "bridged_infill_margin",
// compensation
@@ -898,7 +899,7 @@ const std::vector<std::string>& Preset::sla_printer_options()
"min_initial_exposure_time", "max_initial_exposure_time",
//FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset.
"print_host", "printhost_apikey", "printhost_cafile", "printhost_port",
- "printer_custom_variables",
+ "printer_notes",
"inherits",
"thumbnails",
"thumbnails_color",
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 505200986..32c89872e 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -404,16 +404,30 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPercent(100));
+ def = this->add("bridge_overlap_min", coPercent);
+ def->label = L("Min");
+ def->full_label = L("Min bridge density");
+ def->sidetext = L("%");
+ def->category = OptionCategory::width;
+ def->tooltip = L("Minimum density for bridge lines. If Lower than bridge_overlap, then the overlap value can be lowered automatically down to this value."
+ " If the value is higher, this parameter has no effect."
+ "\nDefault to 87.5% to allow a little void between the lines.");
+ def->min = 50;
+ def->max = 200;
+ def->mode = comExpert;
+ def->set_default_value(new ConfigOptionPercent(80));
+
def = this->add("bridge_overlap", coPercent);
- def->label = L("Bridge overlap");
- def->full_label = L("Bridge overlap");
+ def->label = L("Max");
+ def->full_label = L("Max bridge density");
def->sidetext = L("%");
def->category = OptionCategory::width;
- def->tooltip = L("Amount of overlap between lines of the bridge. If want more space between line (or less), you can modify it. Default to 100%. A value of 50% will create two times less lines.");
+ def->tooltip = L("Maximum density for bridge lines. If you want more space between line (or less), you can modify it."
+ " A value of 50% will create two times less lines, and a value of 200% will create two time more lines that overlap each other.");
def->min = 50;
def->max = 200;
def->mode = comExpert;
- def->set_default_value(new ConfigOptionPercent(100));
+ def->set_default_value(new ConfigOptionPercent(90));
def = this->add("bridge_speed", coFloat);
def->label = L("Bridges");
@@ -2406,15 +2420,16 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionBool(false));
def = this->add("infill_overlap", coFloatOrPercent);
- def->label = L("Infill/perimeters overlap");
+ def->label = L("Infill/perimeters encroachment");
def->category = OptionCategory::width;
def->tooltip = L("This setting applies an additional overlap between infill and perimeters for better bonding. "
"Theoretically this shouldn't be needed, but backlash might cause gaps. If expressed "
- "as percentage (example: 15%) it is calculated over perimeter extrusion width.");
+ "as percentage (example: 15%) it is calculated over perimeter extrusion width."
+ "\nDon't put a value higher than 50% (of the perimeter width), as it will fuse with it and follow the perimeter.");
def->sidetext = L("mm or %");
def->ratio_over = "perimeter_extrusion_width";
def->min = 0;
- def->max_literal = { 1, true };
+ def->max_literal = { 0.5, true };
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloatOrPercent(25, true));
@@ -5916,6 +5931,7 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = {
"avoid_crossing_not_first_layer",
"bridge_internal_fan_speed",
"bridge_overlap",
+"bridge_overlap_min",
"bridge_speed_internal",
"bridged_infill_margin",
"brim_ears_detection_length",
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index ce90d35f5..32537c609 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -782,6 +782,7 @@ public:
ConfigOptionPercent bridge_flow_ratio;
ConfigOptionPercent over_bridge_flow_ratio;
ConfigOptionPercent bridge_overlap;
+ ConfigOptionPercent bridge_overlap_min;
ConfigOptionEnum<InfillPattern> bottom_fill_pattern;
ConfigOptionFloatOrPercent bridged_infill_margin;
ConfigOptionFloat bridge_speed;
@@ -900,6 +901,7 @@ protected:
OPT_PTR(bridge_flow_ratio);
OPT_PTR(over_bridge_flow_ratio);
OPT_PTR(bridge_overlap);
+ OPT_PTR(bridge_overlap_min);
OPT_PTR(bottom_fill_pattern);
OPT_PTR(bridged_infill_margin);
OPT_PTR(bridge_speed);
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index cbfa7d5ef..3fbe51b3b 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -2177,8 +2177,6 @@ namespace Slic3r {
ExPolygons not_bridge = diff_ex({ ExPolygon{ poly_to_check_for_thin } }, collapsed);
int try1_count = bridge.size() + not_bridge.size();
if (try1_count > 1) {
- if (layer->id() == 15)
- std::cout << "lol\n";
min_width = float(bridge_flow.scaled_width()) * 1.5f;
collapsed = offset2_ex({ poly_to_check_for_thin }, -min_width, +min_width * 1.5f);
ExPolygons bridge2 = intersection_ex(collapsed, { ExPolygon{ poly_to_check_for_thin } });
diff --git a/src/slic3r/GUI/CalibrationBridgeDialog.cpp b/src/slic3r/GUI/CalibrationBridgeDialog.cpp
index f1e521dc0..302c0c856 100644
--- a/src/slic3r/GUI/CalibrationBridgeDialog.cpp
+++ b/src/slic3r/GUI/CalibrationBridgeDialog.cpp
@@ -80,7 +80,13 @@ void CalibrationBridgeDialog::create_geometry(std::string setting_to_test, bool
assert(objs_idx.size() == nb_items);
const DynamicPrintConfig* print_config = this->gui_app->get_tab(Preset::TYPE_FFF_PRINT)->get_config();
+ const DynamicPrintConfig* filament_config = this->gui_app->get_tab(Preset::TYPE_FFF_FILAMENT)->get_config();
const DynamicPrintConfig* printer_config = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
+ DynamicPrintConfig full_print_config;
+ full_print_config.apply(*print_config);
+ full_print_config.apply(*filament_config);
+ full_print_config.apply(*printer_config);
+ full_print_config.set_key_value("extruder_id", new ConfigOptionInt(0));
/// --- scale ---
// model is created for a 0.4 nozzle, scale xy with nozzle size.
@@ -144,14 +150,14 @@ void CalibrationBridgeDialog::create_geometry(std::string setting_to_test, bool
//model.objects[objs_idx[i]]->config.set_key_value("top_fill_pattern", new ConfigOptionEnum<InfillPattern>(ipSmooth)); /not needed
model.objects[objs_idx[i]]->config.set_key_value("ironing", new ConfigOptionBool(false)); // not needed, and it slow down things.
}
- /// if first ayer height is excatly at the wrong value, the text isn't drawed. Fix that by switching the first layer height just a little bit.
- double first_layer_height = print_config->get_computed_value("first_layer_height", 0);
+ /// if first ayer height is excactly at the wrong value, the text isn't drawed. Fix that by switching the first layer height just a little bit.
+ double first_layer_height = full_print_config.get_computed_value("first_layer_height", 0);
double layer_height = nozzle_diameter * 0.5;
if (layer_height > 0.01 && (int(first_layer_height * 100) % int(layer_height * 100)) == int(layer_height * 50)) {
double z_step = printer_config->option<ConfigOptionFloat>("z_step")->value;
if (z_step == 0)
z_step = 0.1;
- double max_height = printer_config->get_computed_value("max_layer_height",0);
+ double max_height = full_print_config.get_computed_value("max_layer_height",0);
if (max_height > first_layer_height + z_step)
for (size_t i = 0; i < nb_items; i++)
model.objects[objs_idx[i]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(first_layer_height + z_step, false));
diff --git a/src/slic3r/GUI/CalibrationRetractionDialog.cpp b/src/slic3r/GUI/CalibrationRetractionDialog.cpp
index f7ec1a2be..1de3f179c 100644
--- a/src/slic3r/GUI/CalibrationRetractionDialog.cpp
+++ b/src/slic3r/GUI/CalibrationRetractionDialog.cpp
@@ -231,13 +231,15 @@ void CalibrationRetractionDialog::create_geometry(wxCommandEvent& event_args) {
model.objects[objs_idx[i]]->config.set_key_value("print_temperature", new ConfigOptionInt(int(temp - temp_decr * i)));
//set retraction override
size_t num_part = 0;
+ const int mytemp = temp - temp_decr * i;
+ const int extra_vol = (mytemp <= 285 && mytemp >= 180 && mytemp % 5 == 0) ? 2 : 1;
for (ModelObject* part : part_tower[i]) {
- model.objects[objs_idx[i]]->volumes[num_part + 2]->config.set_key_value("print_retract_length", new ConfigOptionFloat(retraction_start + num_part * retraction_steps));
- model.objects[objs_idx[i]]->volumes[num_part + 2]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
- model.objects[objs_idx[i]]->volumes[num_part + 2]->config.set_key_value("perimeter_speed", new ConfigOptionFloat(std::min(external_perimeter_speed, perimeter_speed)));
- model.objects[objs_idx[i]]->volumes[num_part + 2]->config.set_key_value("external_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
- model.objects[objs_idx[i]]->volumes[num_part + 2]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
- //model.objects[objs_idx[i]]->volumes[num_part + 1]->config.set_key_value("infill_speed", new ConfigOptionFloat(std::min(print_config->option<ConfigOptionFloat>("infill_speed")->value, 10.*scale)));
+ model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("print_retract_length", new ConfigOptionFloat(retraction_start + num_part * retraction_steps));
+ model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
+ model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("perimeter_speed", new ConfigOptionFloat(std::min(external_perimeter_speed, perimeter_speed)));
+ model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("external_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
+ model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("small_perimeter_speed", new ConfigOptionFloatOrPercent(external_perimeter_speed, false));
+ //model.objects[objs_idx[i]]->volumes[num_part + extra_vol]->config.set_key_value("infill_speed", new ConfigOptionFloat(std::min(print_config->option<ConfigOptionFloat>("infill_speed")->value, 10.*scale)));
num_part++;
}
}
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
index 3a75e57ae..1aff59ca0 100644
--- a/src/slic3r/GUI/ConfigManipulation.cpp
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -216,6 +216,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
names.push_back("bridge_flow_ratio");
names.push_back("over_bridge_flow_ratio");
names.push_back("bridge_overlap");
+ names.push_back("bridge_overlap_min");
names.push_back("fill_top_flow_ratio");
names.push_back("first_layer_flow_ratio");
for (int i = 0; i < names.size(); i++) {
diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index 793652f26..0bc236e43 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -413,104 +413,120 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
break;
case coFloatsOrPercents:
case coFloatOrPercent: {
- if (!str.IsEmpty() && str.Last() != '%')
- {
- double val = 0.;
- // Replace the first occurence of comma in decimal number.
- str.Replace(",", ".", false);
-
- // remove space and "mm" substring, if any exists
- str.Replace(" ", "", true);
- str.Replace("m", "", true);
-
- if (m_opt.nullable && str == na_value()) {
- val = ConfigOptionFloatsNullable::nil_value();
- str = "nan";
- } else if (!str.ToCDouble(&val)) {
- if (!check_value) {
- m_value.clear();
- break;
+ if (!str.IsEmpty()) {
+ if ("infill_overlap" == m_opt_id && m_last_validated_value != str) {
+ bool bad = false;
+ double val = 0.;
+ if (str.Last() != '%') {
+ if (str.ToCDouble(&val)) {
+ const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
+ const std::vector<double>& nozzle_diameters = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values;
+ double nozzle_diameter = 0;
+ for (double diameter : nozzle_diameters)
+ nozzle_diameter = std::max(nozzle_diameter, diameter);
+ if (val > nozzle_diameter / 2) {
+ bad = true;
+ }
+ }
+ } else {
+ if (str.substr(0, str.size() - 1).ToCDouble(&val)) {
+ if (val >= 50) {
+ bad = true;
+ }
+ }
}
- show_error(m_parent, _(L("Invalid numeric input.")));
- set_value(double_to_string(val, m_opt.precision), true);
- } else {
-
- //at least check min, as we can want a 0 min
- if (m_opt.min > val)
- {
+ if (bad && check_value) {
+ const wxString msg_text = from_u8(_u8L("The infill / perimeter encroachment can't be higher than half of the perimeter width.\n"
+ "Are you sure to use this value?"));
+ wxMessageDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO);
+ auto ret = dialog.ShowModal();
+ if (ret == wxID_NO) {
+ str = from_u8("49%");
+ m_last_validated_value = str;
+ set_value(str, false);
+ str = m_last_validated_value;
+ }
+ m_last_validated_value = str;
+ }
+ }
+ else if (str.Last() != '%') {
+ double val = 0.;
+ // Replace the first occurence of comma in decimal number.
+ str.Replace(",", ".", false);
+
+ // remove space and "mm" substring, if any exists
+ str.Replace(" ", "", true);
+ str.Replace("m", "", true);
+
+ if (m_opt.nullable && str == na_value()) {
+ val = ConfigOptionFloatsNullable::nil_value();
+ str = "nan";
+ } else if (!str.ToCDouble(&val)) {
if (!check_value) {
m_value.clear();
break;
}
- show_error(m_parent, _(L("Input value is out of range")));
- if (m_opt.min > val) val = m_opt.min;
+ show_error(m_parent, _(L("Invalid numeric input.")));
set_value(double_to_string(val, m_opt.precision), true);
- } else if (m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast<std::string>(m_value)) {
- bool not_ok = (m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max);
- if( !not_ok && m_opt.max_literal.value != 0 )
- if (m_opt.max_literal.percent) {
- const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
- const std::vector<double>& nozzle_diameters = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values;
- double nozzle_diameter = 0;
- for (double diameter : nozzle_diameters)
- nozzle_diameter = std::max(nozzle_diameter, diameter);
- if (m_opt.max_literal.value > 0)
- not_ok = val > nozzle_diameter * m_opt.max_literal.value;
- else
- not_ok = val < nozzle_diameter * (-m_opt.max_literal.value);
- }else{
- if(m_opt.max_literal.value > 0)
- not_ok = val > m_opt.max_literal.value;
- else
- not_ok = val < -m_opt.max_literal.value;
- }
- if (not_ok) {
-
- // if (
- // (
- // (m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max)
- // ||
- // (m_opt.sidetext.rfind("mm ") != std::string::npos && val > m_opt.max_literal)
- // )
- // &&
- // (m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast<std::string>(m_value)))
- //{
- // if (m_opt.opt_key.find("extrusion_width") != std::string::npos || m_opt.opt_key.find("extrusion_spacing") != std::string::npos) {
- // const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
- // const std::vector<double>& nozzle_diameters = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values;
- // double nozzle_diameter = 0;
- // for (double diameter : nozzle_diameters)
- // nozzle_diameter = std::max(nozzle_diameter, diameter);
- // if (val < nozzle_diameter * 10) {
- // m_value = std::string(str.ToUTF8().data());
- // break;
- // }
- // }
- //TODO: chack for infill_overlap from diameter% => allow max_literal to be a %
+ } else {
+ //at least check min, as we can want a 0 min
+ if (m_opt.min > val)
+ {
if (!check_value) {
m_value.clear();
break;
}
+ show_error(m_parent, _(L("Input value is out of range")));
+ if (m_opt.min > val) val = m_opt.min;
+ set_value(double_to_string(val, m_opt.precision), true);
+ } else if (m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast<std::string>(m_value)) {
+ bool not_ok = (m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max);
+ if (!not_ok && m_opt.max_literal.value != 0) {
+ if (m_opt.max_literal.percent) {
+ const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
+ const std::vector<double>& nozzle_diameters = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values;
+ double nozzle_diameter = 0;
+ for (double diameter : nozzle_diameters)
+ nozzle_diameter = std::max(nozzle_diameter, diameter);
+ if (m_opt.max_literal.value > 0)
+ not_ok = val > nozzle_diameter * m_opt.max_literal.value;
+ else
+ not_ok = val < nozzle_diameter* (-m_opt.max_literal.value);
+ } else {
+ if (m_opt.max_literal.value > 0)
+ not_ok = val > m_opt.max_literal.value;
+ else
+ not_ok = val < -m_opt.max_literal.value;
+ }
+ }
+ if (not_ok && m_last_validated_value != str) {
+ if (!check_value) {
+ m_value.clear();
+ break;
+ }
- bool infill_anchors = m_opt.opt_key == "infill_anchor" || m_opt.opt_key == "infill_anchor_max";
-
- const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm";
- const wxString stVal = double_to_string(val, m_opt.precision);
- const wxString msg_text = from_u8((boost::format(_utf8(L("Do you mean %s%% instead of %s %s?\n"
- "Select YES if you want to change this value to %s%%, \n"
- "or NO if you are sure that %s %s is a correct value."))) % stVal % stVal % sidetext % stVal % stVal % sidetext).str());
- wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO);
- if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) {
- set_value(from_u8((boost::format("%s%%") % stVal).str()), false/*true*/);
- str += "%%";
- } else
- set_value(stVal, false); // it's no needed but can be helpful, when inputted value contained "," instead of "."
+ bool infill_anchors = m_opt.opt_key == "infill_anchor" || m_opt.opt_key == "infill_anchor_max";
+
+ const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm";
+ const wxString stVal = double_to_string(val, m_opt.precision);
+ const wxString msg_text = from_u8((boost::format(_u8L("Do you mean %s%% instead of %s %s?\n"
+ "Select YES if you want to change this value to %s%%, \n"
+ "or NO if you are sure that %s %s is a correct value.")) % stVal % stVal % sidetext % stVal % stVal % sidetext).str());
+ wxMessageDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO);
+ if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) {
+ str += "%";
+ m_last_validated_value = str;
+ set_value(str, false/*true*/);
+ str = m_last_validated_value;
+ } else
+ set_value(stVal, false); // it's no needed but can be helpful, when inputted value contained "," instead of "."
+ m_last_validated_value = str;
+ }
}
}
}
}
-
m_value = std::string(str.ToUTF8().data());
break;
}
diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp
index 3c361f94b..e48473346 100644
--- a/src/slic3r/GUI/Field.hpp
+++ b/src/slic3r/GUI/Field.hpp
@@ -230,8 +230,10 @@ protected:
// current value
boost::any m_value;
- // last maeningful value
+ // last meaningful value
boost::any m_last_meaningful_value;
+ // last validated value
+ wxString m_last_validated_value;
int m_em_unit;