diff --git a/resources/calibration/filament_pressure/0.3mf b/resources/calibration/filament_pressure/0.3mf
new file mode 100644
index 00000000000..138817b8e9c
Binary files /dev/null and b/resources/calibration/filament_pressure/0.3mf differ
diff --git a/resources/calibration/filament_pressure/1.3mf b/resources/calibration/filament_pressure/1.3mf
new file mode 100644
index 00000000000..7cd89f71099
Binary files /dev/null and b/resources/calibration/filament_pressure/1.3mf differ
diff --git a/resources/calibration/filament_pressure/2.3mf b/resources/calibration/filament_pressure/2.3mf
new file mode 100644
index 00000000000..8c571135148
Binary files /dev/null and b/resources/calibration/filament_pressure/2.3mf differ
diff --git a/resources/calibration/filament_pressure/3.3mf b/resources/calibration/filament_pressure/3.3mf
new file mode 100644
index 00000000000..151e2b5a553
Binary files /dev/null and b/resources/calibration/filament_pressure/3.3mf differ
diff --git a/resources/calibration/filament_pressure/4.3mf b/resources/calibration/filament_pressure/4.3mf
new file mode 100644
index 00000000000..8e1fb62d84c
Binary files /dev/null and b/resources/calibration/filament_pressure/4.3mf differ
diff --git a/resources/calibration/filament_pressure/5.3mf b/resources/calibration/filament_pressure/5.3mf
new file mode 100644
index 00000000000..f72fc6a5aac
Binary files /dev/null and b/resources/calibration/filament_pressure/5.3mf differ
diff --git a/resources/calibration/filament_pressure/6.3mf b/resources/calibration/filament_pressure/6.3mf
new file mode 100644
index 00000000000..44f3f6815d0
Binary files /dev/null and b/resources/calibration/filament_pressure/6.3mf differ
diff --git a/resources/calibration/filament_pressure/7.3mf b/resources/calibration/filament_pressure/7.3mf
new file mode 100644
index 00000000000..ba5a44e6cd7
Binary files /dev/null and b/resources/calibration/filament_pressure/7.3mf differ
diff --git a/resources/calibration/filament_pressure/8.3mf b/resources/calibration/filament_pressure/8.3mf
new file mode 100644
index 00000000000..ee03a573ab6
Binary files /dev/null and b/resources/calibration/filament_pressure/8.3mf differ
diff --git a/resources/calibration/filament_pressure/9.3mf b/resources/calibration/filament_pressure/9.3mf
new file mode 100644
index 00000000000..da0c9a1dcc2
Binary files /dev/null and b/resources/calibration/filament_pressure/9.3mf differ
diff --git a/resources/calibration/filament_pressure/base_plate.3mf b/resources/calibration/filament_pressure/base_plate.3mf
new file mode 100644
index 00000000000..4815007b066
Binary files /dev/null and b/resources/calibration/filament_pressure/base_plate.3mf differ
diff --git a/resources/calibration/filament_pressure/filament_pressure.html b/resources/calibration/filament_pressure/filament_pressure.html
new file mode 100644
index 00000000000..9cee3d2e0ff
--- /dev/null
+++ b/resources/calibration/filament_pressure/filament_pressure.html
@@ -0,0 +1,108 @@
+
+
+
+
+ Pressure Advance Calibration
+
+
+
+
+
+
+
+
+Pressure Advance Calibration
+ |
+
+
+
+
+ Requirements: |
+ Perfect Bed Leveling and Layer Squish |
+
+
+ |
+
+
+
+This test is still in development. The beta version should work well, but your current print settings need to be saved before clicking "Generate" since they are used to create the model.
+
+Note: This test will automatically pull all your currently saved configuration parameters and generate a model for you to print. For optimal results, depending if you're chasing speed/quality or a mix of both, it is recommended to keep similar speeds for most extrusion roles, (although this is not mandatory).
+
+How to Tune Your Printer for Pressure/Linear Advance
+To get started:
+
+- Select the number of tests to create, the max is 10.
+- Each row represents the config parameters for the selected extrusion role (e.g., first row = ExternalPerimeter, second row = FirstLayer).
+- Select the start/end and increment values, you can manually edit these values if you want larger or smaller values.
+- Since each model will have its own config, one test model might print faster or slower than others. This is expected and normal.
+- This is the first calibration tool that supports Arachne! so leave it enabled if you use Arachne.
+- Helpful tip: If you are running multiple tests on a single plate, take a screenshot of the main configuration page (or leave it open and drag the window out of the way) to match the row number to the ID label on the bottom right of the loaded model. (counting starts at '0' ☺)
+You can also inspect each 'base model' and view the object modifiers for each 90° bend model, the 'region_gcode' will have a comment for the extrusion role.
+
+
+if you use PA/LA commands in your feature_gcode it will be auto commented
+
+Currently unsupported roles:
+
+- BridgeInfill, InternalBridgeInfill, ThinWall, GapFill, Ironing
+
+What is the "Verify" option?
+The "Verify" option is an experimental feature. It aims to create a 90° model for each extrusion role, applying specific settings related to that extrusion role.
+You need to manually add the pressure advance values into the "per region g-code" box.
+However, it currently doesn't work perfectly. Occasionally the models get 'gap fill' and that will produce inaccurate results. Select the "verify" option to identify which extrusion roles need Pressure Advance tuning.
+
+Known Bugs
+
+- Setting the first layer's PA value for multiple tests only applies the last row's value to (before_layer_gcode).
+- The first layer may receive gap fill on the 90° bend models; it is recommended to disable gap fill in the object modifiers if this occurs.
+- Occasionally some numbers might get scaled wrong so they won't show up on the G-code preview, this has primarily been for number '1'. If this happens, adjust main config 'thin_perimeters' to '-1'.
+- Other minor bugs may be present.
+
+
+Advice
+Before calibrating Pressure/Linear Advance, it is recommended to tune everything else first!
+
You may need to disable or adjust your part cooling config for this test, including the features that slow down layer times. Note: Large variances in ER speeds can reduce print quality and dimensional accuracy.
+It's recommended to set 'first_layer_min_speed' and 'first_layer_speed' to the same values, since the variance in speeds will mess with the first layer's pressure advance adjustments.
+
+Notes
+TODO: add pictures
+
+
+
+
+
diff --git a/resources/calibration/filament_pressure/pa_border.3mf b/resources/calibration/filament_pressure/pa_border.3mf
new file mode 100644
index 00000000000..d38fe7ed0d3
Binary files /dev/null and b/resources/calibration/filament_pressure/pa_border.3mf differ
diff --git a/resources/calibration/filament_pressure/point.3mf b/resources/calibration/filament_pressure/point.3mf
new file mode 100644
index 00000000000..96eba02d41d
Binary files /dev/null and b/resources/calibration/filament_pressure/point.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.10.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.10.3mf
new file mode 100644
index 00000000000..2a28103bfe4
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.10.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.20.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.20.3mf
new file mode 100644
index 00000000000..b417e1e81eb
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.20.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.30.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.30.3mf
new file mode 100644
index 00000000000..5ce2a8b8c2d
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.30.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.40.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.40.3mf
new file mode 100644
index 00000000000..99128146de6
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.40.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.50.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.50.3mf
new file mode 100644
index 00000000000..d9ceffd6e6a
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.50.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.60.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.60.3mf
new file mode 100644
index 00000000000..2c708f1e37d
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.60.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.70.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.70.3mf
new file mode 100644
index 00000000000..40b4a4cb134
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.70.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.80.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.80.3mf
new file mode 100644
index 00000000000..ce1acea65de
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.80.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.90.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.90.3mf
new file mode 100644
index 00000000000..663dcc2aa89
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_0.90.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.00.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.00.3mf
new file mode 100644
index 00000000000..5c67869f28d
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.00.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.10.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.10.3mf
new file mode 100644
index 00000000000..2352622f843
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.10.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.20.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.20.3mf
new file mode 100644
index 00000000000..b63d795cd9a
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.20.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.30.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.30.3mf
new file mode 100644
index 00000000000..ff37348ab57
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.30.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.40.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.40.3mf
new file mode 100644
index 00000000000..074fc9f59dd
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.40.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.50.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.50.3mf
new file mode 100644
index 00000000000..ddf766e80c1
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.50.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.60.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.60.3mf
new file mode 100644
index 00000000000..3b62dbbac3e
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.60.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.70.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.70.3mf
new file mode 100644
index 00000000000..f40288b18db
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.70.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.80.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.80.3mf
new file mode 100644
index 00000000000..2e79e018a7e
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.80.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.90.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.90.3mf
new file mode 100644
index 00000000000..58c03e13c6d
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_1.90.3mf differ
diff --git a/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_2.00.3mf b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_2.00.3mf
new file mode 100644
index 00000000000..fdddb7999df
Binary files /dev/null and b/resources/calibration/filament_pressure/scaled_with_nozzle_size/90_bend_2.00.3mf differ
diff --git a/resources/localization/list.txt b/resources/localization/list.txt
index 8eb97365b74..39cb74d0df2 100644
--- a/resources/localization/list.txt
+++ b/resources/localization/list.txt
@@ -12,6 +12,7 @@ src/slic3r/GUI/CalibrationCubeDialog.cpp
src/slic3r/GUI/CalibrationFlowDialog.cpp
src/slic3r/GUI/CalibrationOverBridgeDialog.cpp
src/slic3r/GUI/CalibrationRetractionDialog.cpp
+src/slic3r/GUI/CalibrationPressureAdvDialog.cpp
src/slic3r/GUI/CalibrationTempDialog.cpp
src/slic3r/GUI/ConfigManipulation.cpp
src/slic3r/GUI/ConfigSnapshotDialog.cpp
diff --git a/resources/ui_layout/default/filament.ui b/resources/ui_layout/default/filament.ui
index 7aa065d2ba5..8e6c9624d66 100644
--- a/resources/ui_layout/default/filament.ui
+++ b/resources/ui_layout/default/filament.ui
@@ -43,7 +43,7 @@ group:Fan speed - default
setting:id$0:label_width$12:label$Interface:support_material_interface_fan_speed
line:Bridges fan speed
setting:id$0:label_width$12:label$Bridges:bridge_fan_speed
- setting:id$0:label_width$12:label$Internal bridges:bridge_internal_fan_speed
+ setting:id$0:label_width$12:label$Internal bridges:internal_bridge_fan_speed
line:Overhangs Perimeter fan speed
setting:id$0:label_width$12:label$Overhangs:overhangs_fan_speed
line:Gap fill fan speed
diff --git a/resources/ui_layout/default/print.ui b/resources/ui_layout/default/print.ui
index 8db71216cd6..bfdffa645c0 100644
--- a/resources/ui_layout/default/print.ui
+++ b/resources/ui_layout/default/print.ui
@@ -334,7 +334,7 @@ group:label_width$8:sidetext_width$7:Speed for print moves
setting:width$4:brim_speed
line:Bridge speed
setting:width$4:bridge_speed
- setting:width$4:bridge_speed_internal
+ setting:width$4:internal_bridge_speed
setting:width$4:overhangs_speed
line:Gap fill speed
setting:width$4:label$Maximum speed:gap_fill_speed
@@ -384,7 +384,7 @@ group:label_width$9:sidetext_width$8:Acceleration control (advanced)
setting:width$4:brim_acceleration
line:Bridge acceleration
setting:width$4:bridge_acceleration
- setting:width$4:bridge_internal_acceleration
+ setting:width$4:internal_bridge_acceleration
setting:width$4:overhangs_acceleration
line:Other extrusions acceleration
setting:width$4:gap_fill_acceleration
@@ -507,6 +507,7 @@ group:Output file
setting:full_width:output_filename_format
group:Other
gcode_substitutions
+ setting:per_objects_gcode
group:Post-processing script
setting:full_width:height$5:post_process
post_process_explanation
diff --git a/resources/ui_layout/example/filament.ui b/resources/ui_layout/example/filament.ui
index 7aefcd3fbd8..fdf3c8fca99 100644
--- a/resources/ui_layout/example/filament.ui
+++ b/resources/ui_layout/example/filament.ui
@@ -48,7 +48,7 @@ group:Fan speed - default
setting:id$0:label_width$12:label$Interface:support_material_interface_fan_speed
line:Bridges fan speed
setting:id$0:label_width$12:label$Bridges:bridge_fan_speed
- setting:id$0:label_width$12:label$Internal bridges:bridge_internal_fan_speed
+ setting:id$0:label_width$12:label$Internal bridges:internal_bridge_fan_speed
line:Overhangs Perimeter fan speed
setting:id$0:label_width$12:label$Overhangs:overhangs_fan_speed
line:Gap fill fan speed
diff --git a/resources/ui_layout/example/print.ui b/resources/ui_layout/example/print.ui
index 5d90c54bdaf..f16a2d96c9a 100644
--- a/resources/ui_layout/example/print.ui
+++ b/resources/ui_layout/example/print.ui
@@ -322,7 +322,7 @@ group:label_width$8:sidetext_width$7:Speed for print moves
setting:width$4:brim_speed
line:Bridge speed
setting:width$4:bridge_speed
- setting:width$4:bridge_speed_internal
+ setting:width$4:internal_bridge_speed
setting:width$4:overhangs_speed
line:Gap fill speed
setting:width$4:label$maximum speed:gap_fill_speed
@@ -366,7 +366,7 @@ group:label_width$9:sidetext_width$8:Acceleration control (advanced)
setting:width$4:brim_acceleration
line:Bridge acceleration
setting:width$4:bridge_acceleration
- setting:width$4:bridge_internal_acceleration
+ setting:width$4:internal_bridge_acceleration
setting:width$4:overhangs_acceleration
line:Other extrusions acceleration
setting:width$4:gap_fill_acceleration
@@ -489,6 +489,7 @@ group:Output file
setting:full_width:output_filename_format
group:Other
gcode_substitutions
+ setting:per_objects_gcode
group:Post-processing script
setting:full_width:height$5:post_process
post_process_explanation
diff --git a/src/libslic3r/AppConfig.hpp b/src/libslic3r/AppConfig.hpp
index 6da1f7353ba..a7fe8ccb226 100644
--- a/src/libslic3r/AppConfig.hpp
+++ b/src/libslic3r/AppConfig.hpp
@@ -119,6 +119,10 @@ class AppConfig
}
std::string get(const std::string §ion, const std::string &key) const
{ std::string value; this->get(section, key, value); return value; }
+ bool get_bool(const std::string §ion, const std::string &key) const
+ { return this->get(section, key) == "1"; }
+ bool get_bool(const std::string &key) const
+ { return this->get(key) == "1"; }
std::string get(const std::string &key) const
{ std::string value; this->get("", key, value); return value; }
void set(const std::string §ion, const std::string &key, const std::string &value)
diff --git a/src/libslic3r/BuildVolume.cpp b/src/libslic3r/BuildVolume.cpp
index c580e6f876e..31e853cdb79 100644
--- a/src/libslic3r/BuildVolume.cpp
+++ b/src/libslic3r/BuildVolume.cpp
@@ -238,7 +238,8 @@ BuildVolume::ObjectState object_state_templ(const indexed_triangle_set &its, con
const stl_vertex p2 = trafo * its.vertices[tri(iedge)];
assert(sign(p1) == s[iprev]);
assert(sign(p2) == s[iedge]);
- assert(p1.z() * p2.z() < 0);
+ assert(p1.z() * p2.z() <= 0);
+ assert(std::abs(p2.z() - p1.z()) > EPSILON);
// Edge crosses the z plane. Calculate intersection point with the plane.
const float t = (world_min_z - p1.z()) / (p2.z() - p1.z());
(is_inside(Vec3f(p1.x() + (p2.x() - p1.x()) * t, p1.y() + (p2.y() - p1.y()) * t, world_min_z)) ? inside : outside) = true;
diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index 118a8370bb9..ff0cec93c73 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -57,6 +57,7 @@ struct SurfaceFillParams : FillParams
RETURN_COMPARE_NON_EQUAL(can_angle_cross);
RETURN_COMPARE_NON_EQUAL(density);
RETURN_COMPARE_NON_EQUAL(monotonic);
+ RETURN_COMPARE_NON_EQUAL(max_sparse_infill_spacing);
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, connection);
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust);
@@ -70,16 +71,22 @@ struct SurfaceFillParams : FillParams
assert(this->config != nullptr);
assert(rhs.config != nullptr);
if (config != nullptr && rhs.config != nullptr) {
+ RETURN_COMPARE_NON_EQUAL(config->infill_acceleration);
RETURN_COMPARE_NON_EQUAL(config->infill_speed);
+ RETURN_COMPARE_NON_EQUAL(config->solid_infill_acceleration);
RETURN_COMPARE_NON_EQUAL(config->solid_infill_speed);
+ RETURN_COMPARE_NON_EQUAL(config->top_solid_infill_acceleration);
RETURN_COMPARE_NON_EQUAL(config->top_solid_infill_speed);
- RETURN_COMPARE_NON_EQUAL(config->ironing_speed);
+ RETURN_COMPARE_NON_EQUAL(config->default_acceleration);
RETURN_COMPARE_NON_EQUAL(config->default_speed);
+ RETURN_COMPARE_NON_EQUAL(config->bridge_acceleration);
RETURN_COMPARE_NON_EQUAL(config->bridge_speed);
- RETURN_COMPARE_NON_EQUAL(config->bridge_speed_internal);
+ RETURN_COMPARE_NON_EQUAL(config->internal_bridge_acceleration);
+ RETURN_COMPARE_NON_EQUAL(config->internal_bridge_speed);
+ RETURN_COMPARE_NON_EQUAL(config->gap_fill_acceleration);
RETURN_COMPARE_NON_EQUAL(config->gap_fill_speed);
RETURN_COMPARE_NON_EQUAL(config->print_extrusion_multiplier);
- RETURN_COMPARE_NON_EQUAL(max_sparse_infill_spacing);
+ RETURN_COMPARE_NON_EQUAL(config->region_gcode.value);
}
if (config == nullptr || rhs.config == nullptr || max_sparse_infill_spacing == 0)
RETURN_COMPARE_NON_EQUAL(flow.width());
@@ -92,14 +99,23 @@ struct SurfaceFillParams : FillParams
if ((config != nullptr) != (rhs.config != nullptr))
return false;
if(config != nullptr && (
- config->infill_speed != rhs.config->infill_speed
+ config->infill_acceleration != rhs.config->infill_acceleration
+ || config->infill_speed != rhs.config->infill_speed
+ || config->solid_infill_acceleration != rhs.config->solid_infill_acceleration
|| config->solid_infill_speed != rhs.config->solid_infill_speed
+ || config->top_solid_infill_acceleration != rhs.config->top_solid_infill_acceleration
|| config->top_solid_infill_speed != rhs.config->top_solid_infill_speed
- || config->ironing_speed != rhs.config->ironing_speed
+ || config->default_acceleration != rhs.config->default_acceleration
|| config->default_speed != rhs.config->default_speed
+ || config->bridge_acceleration != rhs.config->bridge_acceleration
|| config->bridge_speed != rhs.config->bridge_speed
- || config->bridge_speed_internal != rhs.config->bridge_speed_internal
- || config->gap_fill_speed != rhs.config->gap_fill_speed))
+ || config->internal_bridge_acceleration != rhs.config->internal_bridge_acceleration
+ || config->internal_bridge_speed != rhs.config->internal_bridge_speed
+ || config->gap_fill_acceleration != rhs.config->gap_fill_acceleration
+ || config->gap_fill_speed != rhs.config->gap_fill_speed
+ || config->print_extrusion_multiplier != rhs.config->print_extrusion_multiplier
+ || config->region_gcode != rhs.config->region_gcode
+ ))
return false;
// then check params
return this->extruder == rhs.extruder &&
@@ -765,6 +781,7 @@ void Layer::make_ironing()
double line_spacing;
// Height of the extrusion, to calculate the extrusion flow from.
double height;
+ double acceleration;
double speed;
double angle;
IroningType type;
@@ -786,6 +803,10 @@ void Layer::make_ironing()
return true;
if (this->height > rhs.height)
return false;
+ if (this->acceleration < rhs.acceleration)
+ return true;
+ if (this->acceleration > rhs.acceleration)
+ return false;
if (this->speed < rhs.speed)
return true;
if (this->speed > rhs.speed)
@@ -797,11 +818,12 @@ void Layer::make_ironing()
return false;
}
- bool operator==(const IroningParams &rhs) const {
+ bool operator==(const IroningParams &rhs) const
+ {
return this->extruder == rhs.extruder && this->just_infill == rhs.just_infill &&
- this->line_spacing == rhs.line_spacing && this->height == rhs.height && this->speed == rhs.speed &&
- this->angle == rhs.angle &&
- this->type == rhs.type;
+ this->line_spacing == rhs.line_spacing && this->height == rhs.height &&
+ this->acceleration == rhs.acceleration && this->speed == rhs.speed &&
+ this->angle == rhs.angle && this->type == rhs.type;
}
LayerRegion *layerm = nullptr;
@@ -847,11 +869,16 @@ void Layer::make_ironing()
ironing_params.type = config.ironing_type;
ironing_params.just_infill = false;
ironing_params.line_spacing = config.ironing_spacing;
- ironing_params.height = default_layer_height * 0.01 * config.ironing_flowrate;
- ironing_params.speed = config.ironing_speed;
- ironing_params.angle = config.ironing_angle <0 ?
- compute_fill_angle(config, layerm->layer()->id()) :
- float(Geometry::deg2rad(config.ironing_angle.value));
+ ironing_params.height = default_layer_height * 0.01 * config.ironing_flowrate;
+ ironing_params.acceleration = config.ironing_acceleration;
+ ironing_params.speed = config.ironing_speed;
+ if (config.ironing_angle.value >= 0) {
+ ironing_params.angle = float(Geometry::deg2rad(config.ironing_angle.value));
+ } else {
+ ironing_params.angle = compute_fill_angle(config, layerm->layer()->id());
+ if (config.ironing_angle.value < -1)
+ ironing_params.angle += float(Geometry::deg2rad(-config.ironing_angle.value));
+ }
ironing_params.layerm = layerm;
by_extruder.emplace_back(ironing_params);
}
diff --git a/src/libslic3r/Flow.cpp b/src/libslic3r/Flow.cpp
index 3c34b71aecd..ca689ac239b 100644
--- a/src/libslic3r/Flow.cpp
+++ b/src/libslic3r/Flow.cpp
@@ -524,7 +524,7 @@ float Flow::rounded_rectangle_extrusion_spacing(float width, float height, float
#else
if (width == height && width == 0)
return 0.f;
- float out = width - height * float(1. - 0.25 * PI) * m_spacing_ratio;
+ float out = width - height * float(1. - 0.25 * PI) * m_spacing_ratio;//this calculates the real spacing for widths. i need this one.
if (out <= 0.f)
throw FlowErrorNegativeSpacing();
return out;
diff --git a/src/libslic3r/Format/BBConfig.cpp b/src/libslic3r/Format/BBConfig.cpp
index ffb22ab40e2..78e81ae23a8 100644
--- a/src/libslic3r/Format/BBConfig.cpp
+++ b/src/libslic3r/Format/BBConfig.cpp
@@ -96,7 +96,7 @@ void init()
//key_translation_map["bridge_angle"] = "bridge_angle";
key_translation_map["bridge_density"] = "bridge_overlap_min";
key_translation_map["bridge_no_support"] = "dont_support_bridges";
- key_translation_map["internal_bridge_speed"] = "bridge_speed_internal";
+ //key_translation_map["internal_bridge_speed"] = "internal_bridge_speed";
//key_translation_map["brim_ears"] = "brim_ears";
//key_translation_map["brim_ears_detection_length"] = "brim_ears_detection_length";
//key_translation_map["brim_ears_max_angle"] = "brim_ears_max_angle";
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 840fcd16c38..77250f9ec85 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -870,6 +870,7 @@ namespace DoExport {
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Color Change G-code")), GCodeWriter::get_default_color_change_gcode(config));
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Pause Print G-code")), GCodeWriter::get_default_pause_gcode(config));
if (ret.size() < MAX_TAGS_COUNT) check(_(L("Template Custom G-code")), config.template_custom_gcode.value);
+ //if (ret.size() < MAX_TAGS_COUNT) check(_(L("Per object G-code")), config.per_objects_gcode.value); //not needed yet ?
if (ret.size() < MAX_TAGS_COUNT) {
for (const std::string& value : config.start_filament_gcode.values) {
check(_(L("Filament Start G-code")), value);
@@ -906,6 +907,16 @@ namespace DoExport {
break;
}
}
+ if (ret.size() < MAX_TAGS_COUNT) {
+ std::set per_object_gcodes;
+ for (const PrintObject *obj : print.objects())
+ per_object_gcodes.insert(obj->config().object_gcode.value);
+ for (const std::string &gcode : per_object_gcodes) {
+ check(_(L("Per object G-code")), gcode);
+ if (ret.size() == MAX_TAGS_COUNT)
+ break;
+ }
+ }
return ret;
}
@@ -1083,7 +1094,7 @@ namespace DoExport {
excluded.insert(erTopSolidInfill);
if (config->option("bridge_speed") != nullptr && config->get_computed_value("bridge_speed") != 0)
excluded.insert(erBridgeInfill);
- if (config->option("bridge_speed_internal") != nullptr && config->get_computed_value("bridge_speed_internal") != 0)
+ if (config->option("internal_bridge_speed") != nullptr && config->get_computed_value("internal_bridge_speed") != 0)
excluded.insert(erInternalBridgeInfill);
if (config->option("support_material_speed") != nullptr && config->get_computed_value("support_material_speed") != 0)
excluded.insert(erSupportMaterial);
@@ -1542,6 +1553,55 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene
file.write_format("; first layer extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, first_layer_height, 0).width());
file.write_format("\n");
}
+
+ /*size_t nb_parts_per_object = 0;
+ size_t nb_parts_per_target_volume = 0;
+ std::string volume_config_per_object_gcode = "";
+
+ if (print.default_region_config().per_objects_gcode.value != "") {// mabye add check for project name/ base object name ? user doesn't normally add models inside another model.
+
+ std::string per_object_target_name = print.default_region_config().per_objects_gcode.value;// pull main config object names to apply modifer gcode to
+ std::istringstream iss(per_object_target_name);
+ std::vector target_objects;
+
+ file.write("; target object name: " + per_object_target_name + "\n");
+ if (!per_object_target_name.empty() && per_object_target_name.back() != ',') {
+ throw Slic3r::SlicingError(_(L("no ending comma found, fix per object in main print settings config! each object you want to apply settings to much be seperated by a comma!")));
+ }
+ std::string search_for_comma;
+ while (std::getline(iss, search_for_comma, ',')) {
+ target_objects.push_back(search_for_comma);
+ }
+
+ for (PrintObject* print_object : print.objects()) { //loop though main objects
+ std::string volume_name = "";
+ auto part_details = print_object->model_object()->volumes;
+
+ for (const auto& volume : part_details) {//loop though object volumes - object parts
+ volume_name = volume->name;
+ file.writeln(volume_name);//write file name at start/end of next loop
+
+ for (const auto& target_object : target_objects) {//loop though each volume
+ if (volume_name == target_object) {
+ nb_parts_per_target_volume++;
+ auto volume_config = volume->config.option("per_objects_gcode");//pull per volume config
+ if (volume_config) {//failsafe check, maybe user forgot to add the manipulator in
+ volume_config_per_object_gcode = volume->config.opt_serialize("per_objects_gcode");
+ file.writeln(volume_config_per_object_gcode);
+ m_writer.set_per_object_gcode(volume_config_per_object_gcode);//need to check if "per_objects_gcode" contains '\n' split string and write it the write new line and write remaining of string till next "\n"
+ }
+ break;
+ }
+ }
+ file.writeln(volume_name);
+ nb_parts_per_object++;
+ }
+ }
+ }
+
+ file.write("; Total parts per object: " + std::to_string(nb_parts_per_object) + "\n");
+ file.write("; Total parts per target volume: " + std::to_string(nb_parts_per_target_volume) + "\n");*/
+
BoundingBoxf3 global_bounding_box;
size_t nb_items = 0;
std::wregex pattern(L"[^\\w]+", std::regex_constants::ECMAScript);
@@ -1614,6 +1674,7 @@ void GCode::_do_export(Print& print_mod, GCodeOutputStream &file, ThumbnailsGene
file.write("M486 T" + std::to_string(nb_items) + "\n");
}
if (this->config().gcode_label_objects) {
+ file.write("; Total objects to print: " + std::to_string(nb_items) + "\n");
file.write_format( "; plater:{\"center\":[%f,%f,%f],\"boundingbox_center\":[%f,%f,%f],\"boundingbox_size\":[%f,%f,%f]}\n",
global_bounding_box.center().x(), global_bounding_box.center().y(), 0.,
global_bounding_box.center().x(), global_bounding_box.center().y(), global_bounding_box.center().z(),
@@ -3477,8 +3538,9 @@ LayerResult GCode::process_layer(
if (m_config.avoid_crossing_perimeters)
m_avoid_crossing_perimeters.init_layer(*m_layer);
//print object label to help the printer firmware know where it is (for removing the objects)
+ m_gcode_label_objects_start = "";
if (this->config().gcode_label_objects) {
- m_gcode_label_objects_start =
+ m_gcode_label_objects_start +=
std::string("; printing object ") +
instance_to_print.print_object.model_object()->name +
" id:" + instance_id + " copy " + instance_copy +
@@ -3511,6 +3573,14 @@ LayerResult GCode::process_layer(
"\n";
}
}
+ if (!instance_to_print.print_object.config().object_gcode.value.empty()) {
+ DynamicConfig config;
+ config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index));
+ config.set_key_value("layer_z", new ConfigOptionFloat(print_z));
+ m_gcode_label_objects_start += this->placeholder_parser_process("object_gcode",
+ instance_to_print.print_object.config().object_gcode.value, m_writer.tool()->id(), &config)
+ + "\n";
+ }
// ask for a bigger lift for travel to object when moving to another object
if (single_object_instance_idx == size_t(-1) && !first_object)
set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, extruder_id);
@@ -3588,7 +3658,7 @@ LayerResult GCode::process_layer(
}
}
// Don't set m_gcode_label_objects_end if you don't had to write the m_gcode_label_objects_start.
- if (m_gcode_label_objects_start != "") {
+ if (!m_gcode_label_objects_start.empty()) {
m_gcode_label_objects_start = "";
} else if (this->config().gcode_label_objects) {
m_gcode_label_objects_end = std::string("; stop printing object ") + instance_to_print.print_object.model_object()->name
@@ -5203,7 +5273,7 @@ std::string GCode::extrude_path(const ExtrusionPath &path, const std::string &de
const double max_gcode_per_second = this->config().max_gcode_per_second.value;
double current_scaled_min_length = scaled_min_length;
if (max_gcode_per_second > 0) {
- current_scaled_min_length = std::max(current_scaled_min_length, scale_(_compute_speed_mm_per_sec(path, speed_mm_per_sec)) / max_gcode_per_second);
+ current_scaled_min_length = std::max(current_scaled_min_length, scale_(_compute_speed_mm_per_sec(path, speed_mm_per_sec,nullptr)) / max_gcode_per_second);
}
simplifed_path.polyline.ensure_fitting_result_valid();
if (current_scaled_min_length > 0 && !m_last_too_small.empty()) {
@@ -5286,6 +5356,41 @@ std::string GCode::extrude_path_3D(const ExtrusionPath3D &path, const std::strin
return gcode;
}
+// Apply region-specific settings
+void GCode::apply_region_config(std::string &gcode) {
+ // modify our fullprintconfig with it. (works as all items avaialable in the regionconfig are present in this config, ie: it write everything region-defined)
+ m_config.apply(m_region->config());
+ // pass our region config to the gcode writer
+ m_writer.apply_print_region_config(m_region->config());
+ // perimeter-only (but won't break anything if done also in infill & ironing): pass needed settings to seam placer.
+ m_seam_placer.external_perimeters_first = m_region->config().external_perimeters_first.value;
+ // temperature override from region
+ if (m_config.print_temperature > 0) {
+ if (m_layer != nullptr && m_layer->bottom_z() < EPSILON && m_config.print_first_layer_temperature.value > 0) {
+ gcode += m_writer.set_temperature(m_config.print_first_layer_temperature.value, false, m_writer.tool()->id());
+ } else {
+ gcode += m_writer.set_temperature(m_config.print_temperature.value, false, m_writer.tool()->id());
+ }
+ } else if (m_layer != nullptr && m_layer->bottom_z() < EPSILON && m_config.first_layer_temperature.get_at(m_writer.tool()->id()) > 0) {
+ gcode += m_writer.set_temperature(m_config.first_layer_temperature.get_at(m_writer.tool()->id()), false,
+ m_writer.tool()->id());
+ } else if (m_config.temperature.get_at(m_writer.tool()->id()) > 0) { // don't set it if disabled
+ gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false,
+ m_writer.tool()->id());
+ }
+ // apply region_gcode
+ if (!m_region->config().region_gcode.value.empty()) {//here
+ DynamicConfig config;
+ config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index));
+ config.set_key_value("layer_z", new ConfigOptionFloat(m_layer == nullptr ? m_last_height : m_layer->print_z));
+ m_gcode_label_objects_start += this->placeholder_parser_process("region_gcode",
+ m_region->config().region_gcode.value,
+ m_writer.tool()->id(), &config) +
+ "\n";
+ }
+
+}
+
// Extrude perimeters: Decide where to put seams (hide or align seams).
std::string GCode::extrude_perimeters(const Print &print, const std::vector &by_region)
{
@@ -5295,17 +5400,7 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vectorconfig());
- m_writer.apply_print_region_config(m_region->config());
- m_seam_placer.external_perimeters_first = m_region->config().external_perimeters_first.value;
- if (m_config.print_temperature > 0)
- gcode += m_writer.set_temperature(m_config.print_temperature.value, false, m_writer.tool()->id());
- else if (m_layer != nullptr && m_layer->bottom_z() < EPSILON && m_config.first_layer_temperature.get_at(m_writer.tool()->id()) > 0)
- gcode += m_writer.set_temperature(m_config.first_layer_temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id());
- else if (m_config.temperature.get_at(m_writer.tool()->id()) > 0) { // don't set it if disabled
- gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false,
- m_writer.tool()->id());
- }
+ apply_region_config(gcode);
ExtrusionEntitiesPtr extrusions{region.perimeters};
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
for (const ExtrusionEntity *ee : extrusions) {
@@ -5324,14 +5419,7 @@ std::string GCode::extrude_infill(const Print& print, const std::vectorconfig().infill_first == is_infill_first)) {
- m_config.apply(m_region->config());
- m_writer.apply_print_region_config(m_region->config());
- if (m_config.print_temperature > 0)
- gcode += m_writer.set_temperature(m_config.print_temperature.value, false, m_writer.tool()->id());
- else if (m_layer != nullptr && m_layer->bottom_z() < EPSILON && m_config.first_layer_temperature.get_at(m_writer.tool()->id()) > 0)
- gcode += m_writer.set_temperature(m_config.first_layer_temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id());
- else if (m_config.temperature.get_at(m_writer.tool()->id()) > 0) // don't set it if disabled
- gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id());
+ apply_region_config(gcode);
ExtrusionEntitiesPtr extrusions{ region.infills };
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
for (const ExtrusionEntity* fill : extrusions) {
@@ -5350,14 +5438,7 @@ std::string GCode::extrude_ironing(const Print& print, const std::vectorconfig());
- m_writer.apply_print_region_config(m_region->config());
- if (m_config.print_temperature > 0)
- gcode += m_writer.set_temperature(m_config.print_temperature.value, false, m_writer.tool()->id());
- else if (m_layer != nullptr && m_layer->bottom_z() < EPSILON && m_config.first_layer_temperature.get_at(m_writer.tool()->id()) > 0)
- gcode += m_writer.set_temperature(m_config.first_layer_temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id());
- else if (m_config.temperature.get_at(m_writer.tool()->id()) > 0)
- gcode += m_writer.set_temperature(m_config.temperature.get_at(m_writer.tool()->id()), false, m_writer.tool()->id());
+ apply_region_config(gcode);
ExtrusionEntitiesPtr extrusions{ region.ironings };
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
for (const ExtrusionEntity* fill : extrusions) {
@@ -5674,7 +5755,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string &descri
return gcode;
}
-double_t GCode::_compute_speed_mm_per_sec(const ExtrusionPath& path, double speed) {
+double_t GCode::_compute_speed_mm_per_sec(const ExtrusionPath& path, double speed, std::string *comment) {
float factor = 1;
// set speed
@@ -5686,24 +5767,34 @@ double_t GCode::_compute_speed_mm_per_sec(const ExtrusionPath& path, double spee
//it's a bit hacky, so if you want to rework it, help yourself.
if (path.role() == erPerimeter) {
speed = m_config.get_computed_value("perimeter_speed");
+ if(comment) *comment = "perimeter_speed";
} else if (path.role() == erExternalPerimeter) {
speed = m_config.get_computed_value("external_perimeter_speed");
+ if(comment) *comment = "external_perimeter_speed";
} else if (path.role() == erBridgeInfill) {
speed = m_config.get_computed_value("bridge_speed");
+ if(comment) *comment = "bridge_speed";
} else if (path.role() == erInternalBridgeInfill) {
- speed = m_config.get_computed_value("bridge_speed_internal");
+ speed = m_config.get_computed_value("internal_bridge_speed");
+ if(comment) *comment = "internal_bridge_speed";
} else if (path.role() == erOverhangPerimeter) {
speed = m_config.get_computed_value("overhangs_speed");
+ if(comment) *comment = "overhangs_speed";
} else if (path.role() == erInternalInfill) {
speed = m_config.get_computed_value("infill_speed");
+ if(comment) *comment = "infill_speed";
} else if (path.role() == erSolidInfill) {
speed = m_config.get_computed_value("solid_infill_speed");
+ if(comment) *comment = "solid_infill_speed";
} else if (path.role() == erTopSolidInfill) {
speed = m_config.get_computed_value("top_solid_infill_speed");
+ if(comment) *comment = "top_solid_infill_speed";
} else if (path.role() == erThinWall) {
speed = m_config.get_computed_value("thin_walls_speed");
+ if(comment) *comment = "thin_walls_speed";
} else if (path.role() == erGapFill) {
speed = m_config.get_computed_value("gap_fill_speed");
+ if(comment) *comment = "gap_fill_speed";
double max_ratio = m_config.gap_fill_flow_match_perimeter.get_abs_value(1.);
if (max_ratio > 0 && m_region) {
//compute intended perimeter flow
@@ -5745,7 +5836,8 @@ double_t GCode::_compute_speed_mm_per_sec(const ExtrusionPath& path, double spee
} else if (path.role() == erBridgeInfill) {
speed = m_config.bridge_speed.get_abs_value(vol_speed);
} else if (path.role() == erInternalBridgeInfill) {
- speed = m_config.bridge_speed_internal.get_abs_value(vol_speed);
+ speed = m_config.internal_bridge_speed.get_abs_value(vol_speed);
+ if(comment) *comment = std::string("internal_bridge_speed ") + *comment;
} else if (path.role() == erOverhangPerimeter) {
speed = m_config.overhangs_speed.get_abs_value(vol_speed);
} else if (path.role() == erInternalInfill) {
@@ -5956,10 +6048,10 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
}
break;
case erInternalBridgeInfill:
- if (m_config.bridge_internal_acceleration.value > 0) {
- double bridge_internal_acceleration = m_config.get_computed_value("bridge_internal_acceleration");
- if (bridge_internal_acceleration > 0) {
- acceleration = bridge_internal_acceleration;
+ if (m_config.internal_bridge_acceleration.value > 0) {
+ double internal_bridge_acceleration = m_config.get_computed_value("internal_bridge_acceleration");
+ if (internal_bridge_acceleration > 0) {
+ acceleration = internal_bridge_acceleration;
break;
}
}
@@ -6014,7 +6106,8 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
}
// compute speed here to be able to know it for travel_deceleration_use_target
- speed = _compute_speed_mm_per_sec(path, speed);
+ std::string speed_comment = "";
+ speed = _compute_speed_mm_per_sec(path, speed, m_config.gcode_comments ? &speed_comment : nullptr);
if (m_config.travel_deceleration_use_target){
if (travel_acceleration <= acceleration || travel_acceleration == 0 || acceleration == 0) {
@@ -6140,17 +6233,57 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
}
gcode += m_writer.unretract();
- // extrude arc or line
+ // process custom extrusion role change gcode.
if (path.role() != m_last_extrusion_role && !m_config.feature_gcode.value.empty()) {
DynamicConfig config;
config.set_key_value("extrusion_role", new ConfigOptionString(extrusion_role_to_string_for_parser(path.role())));
config.set_key_value("last_extrusion_role", new ConfigOptionString(extrusion_role_to_string_for_parser(m_last_extrusion_role)));
config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index + 1));
config.set_key_value("layer_z", new ConfigOptionFloat(m_layer == nullptr ? m_last_height : m_layer->print_z));
- gcode += this->placeholder_parser_process("feature_gcode",
- m_config.feature_gcode.value, m_writer.tool()->id(), &config)
- + "\n";
- }
+
+ if (m_config.print_custom_variables.value == "calibration_print" && !m_region->config().region_gcode.value.empty()) {
+
+ GCodeFlavor flavor = m_config.gcode_flavor.value;
+ std::string keyword = (gcfKlipper == flavor) ? "SET_PRESSURE_ADVANCE" :
+ (gcfMarlinFirmware == flavor) ? "M900" :
+ (gcfRepRap == flavor) ? "M572 S" : "";
+
+ //std::string keyword = "SET_PRESSURE_ADVANCE";
+ std::string feature_gcode_full = m_config.feature_gcode.value;
+ std::string feature_gcode_modified;//if "feature_gcode_full" is a single line and doesn't have a new line at the end fix it.
+ if (feature_gcode_full.back() != '\n') {
+ feature_gcode_full += '\n';
+ }
+
+ size_t pos = 0;
+
+ // Loop until all occurrences of SET_PRESSURE_ADVANCE are found
+ while ((pos = feature_gcode_full.find(keyword, pos)) != std::string::npos) {
+ // Step 1: Get everything before the keyword
+ feature_gcode_modified = feature_gcode_full.substr(0, pos);
+ size_t newline_pos = feature_gcode_full.find('\n', pos + keyword.length());
+ std::string substring_to_replace = feature_gcode_full.substr(pos, newline_pos - pos);
+ size_t first_non_space = substring_to_replace.find_first_not_of(" ", keyword.length());
+ substring_to_replace = substring_to_replace.substr(0, first_non_space) + substring_to_replace.substr(first_non_space);
+ std::replace(substring_to_replace.begin(), substring_to_replace.end(), ';', ' '); // Replace ';' with a space
+ substring_to_replace = "\n;" + substring_to_replace;
+ feature_gcode_modified += substring_to_replace;
+ feature_gcode_modified += feature_gcode_full.substr(newline_pos);
+ feature_gcode_full = feature_gcode_modified;
+ pos = newline_pos + 1;
+ }
+
+ // Pass the modified G-code to be processed
+ gcode += this->placeholder_parser_process("feature_gcode", feature_gcode_full, m_writer.tool()->id(), &config) + "\n";
+ } else {
+ gcode += this->placeholder_parser_process("feature_gcode", m_config.feature_gcode.value, m_writer.tool()->id(), &config) + "\n";
+ }
+
+
+
+
+
+ }//gcode += this->placeholder_parser_process("feature_gcode", m_config.feature_gcode.value, m_writer.tool()->id(), &config) + "\n";
if (m_enable_extrusion_role_markers) {
if (path.role() != m_last_extrusion_role) {
char buf[32];
diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp
index 607f6470db3..633197220d9 100644
--- a/src/libslic3r/GCode.hpp
+++ b/src/libslic3r/GCode.hpp
@@ -390,6 +390,7 @@ class GCode : ExtrusionVisitorConst {
// For sequential print, the instance of the object to be printing has to be defined.
const size_t single_object_instance_idx);
+ void apply_region_config(std::string &gcode);
std::string extrude_perimeters(const Print &print, const std::vector &by_region);
std::string extrude_infill(const Print& print, const std::vector& by_region, bool is_infill_first);
std::string extrude_ironing(const Print& print, const std::vector& by_region);
@@ -518,7 +519,7 @@ class GCode : ExtrusionVisitorConst {
void _extrude_line(std::string& gcode_str, const Line& line, const double e_per_mm, const std::string& comment);
void _extrude_line_cut_corner(std::string& gcode_str, const Line& line, const double e_per_mm, const std::string& comment, Point& last_pos, const double path_width);
std::string _before_extrude(const ExtrusionPath &path, const std::string &description, double speed = -1);
- double_t _compute_speed_mm_per_sec(const ExtrusionPath& path, double speed = -1);
+ double_t _compute_speed_mm_per_sec(const ExtrusionPath &path, double speed, std::string *comment);
std::string _after_extrude(const ExtrusionPath &path);
void print_machine_envelope(GCodeOutputStream &file, const Print &print);
void _print_first_layer_bed_temperature(std::string &out, const Print &print, const std::string &gcode, uint16_t first_printing_extruder_id, bool wait);
diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp
index 2003c845f3d..5ea2ecb13b4 100644
--- a/src/libslic3r/GCode/CoolingBuffer.cpp
+++ b/src/libslic3r/GCode/CoolingBuffer.cpp
@@ -902,7 +902,7 @@ std::string CoolingBuffer::apply_layer_cooldown(
}
//set the fan controls
default_fan_speed[ExtrusionRole::erBridgeInfill] = EXTRUDER_CONFIG(bridge_fan_speed);
- default_fan_speed[ExtrusionRole::erInternalBridgeInfill] = EXTRUDER_CONFIG(bridge_internal_fan_speed);
+ default_fan_speed[ExtrusionRole::erInternalBridgeInfill] = EXTRUDER_CONFIG(internal_bridge_fan_speed);
default_fan_speed[ExtrusionRole::erTopSolidInfill] = EXTRUDER_CONFIG(top_fan_speed);
default_fan_speed[ExtrusionRole::erIroning] = default_fan_speed[ExtrusionRole::erTopSolidInfill];
default_fan_speed[ExtrusionRole::erSupportMaterialInterface] = EXTRUDER_CONFIG(support_material_interface_fan_speed);
@@ -982,7 +982,7 @@ std::string CoolingBuffer::apply_layer_cooldown(
fan_speeds[ExtrusionRole::erBridgeInfill] = fan_speeds[0];
}
- // if bridge_internal_fan is disabled, it takes the value of bridge_fan
+ // if internal_bridge_fan is disabled, it takes the value of bridge_fan
if (!fan_control[ExtrusionRole::erInternalBridgeInfill] && fan_control[ExtrusionRole::erBridgeInfill]) {
fan_control[ExtrusionRole::erInternalBridgeInfill] = true;
fan_speeds[ExtrusionRole::erInternalBridgeInfill] = fan_speeds[ExtrusionRole::erBridgeInfill];
diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp
index a5ab786a570..504797f7ee3 100644
--- a/src/libslic3r/GCode/WipeTower.cpp
+++ b/src/libslic3r/GCode/WipeTower.cpp
@@ -654,7 +654,7 @@ WipeTower::WipeTower(const PrintConfig& config, const PrintObjectConfig& default
}
// Read absolute value of first layer speed, if given as percentage,
// it is taken over wipe_tower_speed.
- m_first_layer_speed = config.first_layer_speed.get_abs_value(m_speed);
+ m_first_layer_speed = default_object_config.first_layer_speed.get_abs_value(m_speed);
if (m_first_layer_speed == 0.f) { // just to make sure autospeed doesn't break it.
m_first_layer_speed = m_speed;
}
diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp
index 76fc83ee814..658b1c059ee 100644
--- a/src/libslic3r/GCodeWriter.cpp
+++ b/src/libslic3r/GCodeWriter.cpp
@@ -279,6 +279,32 @@ void GCodeWriter::set_acceleration(uint32_t acceleration)
m_current_acceleration = acceleration;
}
+
+void GCodeWriter::set_per_object_gcode(std::string per_object)
+{
+ if (per_object == m_current_per_object_gcode)
+ return;
+
+ m_current_per_object_gcode = per_object;
+}
+
+std::string GCodeWriter::write_per_object_gcode(){
+ if (m_current_per_object_gcode == m_last_per_object_gcode || m_current_per_object_gcode == "")
+ return "";
+
+ m_last_per_object_gcode = m_current_per_object_gcode;
+
+ std::ostringstream gcode;
+
+
+ gcode << m_current_per_object_gcode;
+ if (this->config.gcode_comments) gcode << " ; added per_object_gcode";
+ gcode << "\n";
+
+ return gcode.str();
+}
+
+
void GCodeWriter::set_travel_acceleration(uint32_t acceleration)
{
//only gcfMarlinFirmware and gcfRepRap can use the travel accel
diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp
index 72f04152831..e0fef5a132a 100644
--- a/src/libslic3r/GCodeWriter.hpp
+++ b/src/libslic3r/GCodeWriter.hpp
@@ -44,6 +44,8 @@ class GCodeWriter {
void set_travel_acceleration(uint32_t acceleration);
uint32_t get_acceleration() const;
std::string write_acceleration();
+ void set_per_object_gcode(std::string per_object);
+ std::string write_per_object_gcode();
std::string reset_e(bool force = false);
std::string update_progress(uint32_t num, uint32_t tot, bool allow_100 = false) const;
// return false if this extruder was already selected
@@ -91,6 +93,8 @@ class GCodeWriter {
std::vector m_extruders;
std::vector m_millers;
std::string m_extrusion_axis = "E";
+ std::string m_current_per_object_gcode;
+ std::string m_last_per_object_gcode;
bool m_single_extruder_multi_material = false;
Tool* m_tool = nullptr;
uint32_t m_last_acceleration = 0;
@@ -103,6 +107,7 @@ class GCodeWriter {
int16_t m_last_temperature_with_offset = 0;
int16_t m_last_bed_temperature = 0;
bool m_last_bed_temperature_reached = true;
+
// if positive, it's set, and the next lift wil have this extra lift
double m_extra_lift = 0;
// current lift, to remove from m_pos to have the current height.
diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp
index 5e5eaec9b49..a23dbe925d9 100644
--- a/src/libslic3r/Layer.cpp
+++ b/src/libslic3r/Layer.cpp
@@ -171,6 +171,7 @@ void Layer::make_perimeters()
/// if you don't do that, objects will share the same region, and the same settings.
if (config.perimeter_extruder == other_config.perimeter_extruder
&& config.perimeters == other_config.perimeters
+ && config.external_perimeter_acceleration == other_config.external_perimeter_acceleration
&& config.external_perimeter_extrusion_width == other_config.external_perimeter_extrusion_width
&& config.external_perimeter_overlap == other_config.external_perimeter_overlap
&& config.external_perimeter_speed == other_config.external_perimeter_speed // it os mandatory? can't this be set at gcode.cpp?
@@ -182,6 +183,7 @@ void Layer::make_perimeters()
&& config.extra_perimeters_overhangs == other_config.extra_perimeters_overhangs
&& config.gap_fill_enabled == other_config.gap_fill_enabled
&& ((config.gap_fill_speed == other_config.gap_fill_speed) || !config.gap_fill_enabled)
+ && config.gap_fill_acceleration == other_config.gap_fill_acceleration
&& config.gap_fill_last == other_config.gap_fill_last
&& config.gap_fill_flow_match_perimeter == other_config.gap_fill_flow_match_perimeter
&& config.gap_fill_extension == other_config.gap_fill_extension
@@ -196,10 +198,12 @@ void Layer::make_perimeters()
&& (this->id() == 0 || config.only_one_perimeter_first_layer == other_config.only_one_perimeter_first_layer)
&& config.only_one_perimeter_top == other_config.only_one_perimeter_top
&& config.only_one_perimeter_top_other_algo == other_config.only_one_perimeter_top_other_algo
+ && config.overhangs_acceleration == other_config.overhangs_acceleration
&& config.overhangs_width_speed == other_config.overhangs_width_speed
&& config.overhangs_width == other_config.overhangs_width
&& config.overhangs_reverse == other_config.overhangs_reverse
&& config.overhangs_reverse_threshold == other_config.overhangs_reverse_threshold
+ && config.perimeter_acceleration == other_config.perimeter_acceleration
&& config.perimeter_extrusion_width == other_config.perimeter_extrusion_width
&& config.perimeter_loop == other_config.perimeter_loop
&& config.perimeter_loop_seam == other_config.perimeter_loop_seam
@@ -211,17 +215,43 @@ void Layer::make_perimeters()
&& config.small_perimeter_min_length == other_config.small_perimeter_min_length
&& config.small_perimeter_max_length == other_config.small_perimeter_max_length
&& config.thin_walls == other_config.thin_walls
+ && config.thin_walls_acceleration == other_config.thin_walls_acceleration
&& config.thin_walls_min_width == other_config.thin_walls_min_width
&& config.thin_walls_overlap == other_config.thin_walls_overlap
+ && config.thin_walls_speed == other_config.thin_walls_speed
&& config.thin_perimeters == other_config.thin_perimeters
&& config.thin_perimeters_all == other_config.thin_perimeters_all
- && config.thin_walls_speed == other_config.thin_walls_speed
&& config.infill_overlap == other_config.infill_overlap
&& config.perimeter_loop == other_config.perimeter_loop
+ && config.region_gcode == other_config.region_gcode
&& config.fuzzy_skin == other_config.fuzzy_skin
&& config.fuzzy_skin_thickness == other_config.fuzzy_skin_thickness
&& config.fuzzy_skin_point_dist == other_config.fuzzy_skin_point_dist
+
+ /*&& config.bridge_acceleration == other_config.bridge_acceleration
+ && config.internal_bridge_acceleration == other_config.internal_bridge_acceleration
+ && config.brim_acceleration == other_config.brim_acceleration
+ && config.default_acceleration == other_config.default_acceleration
+ && config.external_perimeter_acceleration == other_config.external_perimeter_acceleration
+ && config.first_layer_acceleration == other_config.first_layer_acceleration
+ && config.gap_fill_acceleration == other_config.gap_fill_acceleration
+ && config.infill_acceleration == other_config.infill_acceleration
+ && config.ironing_acceleration == other_config.ironing_acceleration
+ && config.overhangs_acceleration == other_config.overhangs_acceleration
+ && config.perimeter_acceleration == other_config.perimeter_acceleration
+ && config.solid_infill_acceleration == other_config.solid_infill_acceleration
+ && config.support_material_acceleration == other_config.support_material_acceleration
+ && config.support_material_interface_acceleration == other_config.support_material_interface_acceleration
+ && config.thin_walls_acceleration == other_config.thin_walls_acceleration
+ && config.top_solid_infill_acceleration == other_config.top_solid_infill_acceleration//compiles fine with moving them here, how to properly test this ?
+ && config.per_objects_gcode == other_config.per_objects_gcode */
+ //&& config.external_perimeter_extrusion_spacing == other_config.external_perimeter_extrusion_spacing
+ //&& config.perimeter_extrusion_spacing == other_config.perimeter_extrusion_spacing
+ //&& config.first_layer_size_compensation == other_config.first_layer_size_compensation
+ && config.first_layer_extrusion_width == other_config.first_layer_extrusion_width
+ && config.first_layer_extrusion_spacing == other_config.first_layer_extrusion_spacing
+
) {
layerms.push_back(other_layerm);
done[it - m_regions.begin()] = true;
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index ca667080cfa..cda6bb76b00 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -523,7 +523,7 @@ static std::vector s_Preset_print_options {
// speeds
"default_speed",
"bridge_speed",
- "bridge_speed_internal",
+ "internal_bridge_speed",
"brim_speed",
"external_perimeter_speed",
"first_layer_speed",
@@ -559,7 +559,6 @@ static std::vector s_Preset_print_options {
"fuzzy_skin_thickness",
// acceleration
"bridge_acceleration",
- "bridge_internal_acceleration",
"brim_acceleration",
"default_acceleration",
"external_perimeter_acceleration",
@@ -567,6 +566,7 @@ static std::vector s_Preset_print_options {
"first_layer_acceleration_over_raft",
"gap_fill_acceleration",
"infill_acceleration",
+ "internal_bridge_acceleration",
"ironing_acceleration",
"overhangs_acceleration",
"perimeter_acceleration",
@@ -632,7 +632,9 @@ static std::vector s_Preset_print_options {
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder",
"gcode_substitutions",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",
- "ooze_prevention", "standby_temperature_delta", "interface_shells",
+ "ooze_prevention", "standby_temperature_delta", "interface_shells",
+ "object_gcode",
+ "region_gcode",
// width & spacing
"extrusion_spacing",
"extrusion_width",
@@ -709,6 +711,7 @@ static std::vector s_Preset_print_options {
"curve_smoothing_angle_convex",
"curve_smoothing_angle_concave",
"print_extrusion_multiplier",
+ "print_first_layer_temperature",
"print_retract_length",
"print_temperature",
"print_retract_lift",
@@ -756,10 +759,10 @@ static std::vector s_Preset_filament_options {
"default_fan_speed",
"max_fan_speed",
"bridge_fan_speed",
- "bridge_internal_fan_speed",
"external_perimeter_fan_speed",
"gap_fill_fan_speed",
"infill_fan_speed",
+ "internal_bridge_fan_speed",
"overhangs_fan_speed",
"perimeter_fan_speed",
"solid_infill_fan_speed",
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 06b81731c73..50ad5619930 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -61,27 +61,25 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
if (opt_keys.empty())
return false;
+
// Cache the plenty of parameters, which influence the G-code generator only,
// or they are only notes not influencing the generated G-code.
static std::unordered_set steps_gcode = {
+ "allow_empty_layers",
"avoid_crossing_perimeters",
"avoid_crossing_perimeters_max_detour",
"avoid_crossing_not_first_layer",
- "avoid_crossing_top",
"bed_shape",
"bed_temperature",
"before_layer_gcode",
"between_objects_gcode",
- "bridge_acceleration",
- "bridge_internal_acceleration",
"bridge_fan_speed",
- "bridge_internal_fan_speed",
- "brim_acceleration",
"chamber_temperature",
+ "color_change_gcode",
"colorprint_heights",
"complete_objects_sort",
- "cooling",
- "default_acceleration",
+ "complete_objects_one_brim",
+ //"cooling",
"default_fan_speed",
"deretract_speed",
"disable_fan_first_layers",
@@ -89,8 +87,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
"enforce_retract_first_layer",
"end_gcode",
"end_filament_gcode",
- "external_perimeter_acceleration",
- "external_perimeter_cut_corners",
"external_perimeter_fan_speed",
"extrusion_axis",
"extruder_clearance_height",
@@ -104,62 +100,59 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
"fan_kickstart",
"fan_speedup_overhangs",
"fan_speedup_time",
+ "feature_gcode",
"fan_percentage",
"fan_printer_min_speed",
"filament_colour",
"filament_custom_variables",
"filament_diameter",
"filament_density",
+ "filament_load_time",
"filament_notes",
"filament_cost",
"filament_spool_weight",
- "first_layer_acceleration",
- "first_layer_acceleration_over_raft",
+ "filament_unload_time",
+ "filament_wipe_advanced_pigment",
"first_layer_bed_temperature",
- "first_layer_flow_ratio",
- "first_layer_speed", // ? delete y prusa here in 2.4
- "first_layer_speed_over_raft",
- "first_layer_infill_speed",
- "first_layer_min_speed",
"full_fan_speed_layer",
- "gap_fill_acceleration",
"gap_fill_fan_speed",
- "gap_fill_flow_match_perimeter",
- "gap_fill_speed",
"gcode_ascii",
"gcode_comments",
"gcode_filename_illegal_char",
"gcode_label_objects",
"gcode_precision_xyz",
"gcode_precision_e",
- "infill_acceleration",
+ "gcode_substitutions",
"infill_fan_speed",
- "ironing_acceleration",
+ "internal_bridge_fan_speed",
"layer_gcode",
+ "lift_min",
"max_fan_speed",
"max_gcode_per_second",
"max_print_height",
"max_print_speed",
+ "max_speed_reduction",
"max_volumetric_speed",
"min_length",
"min_print_speed",
+ "milling_diameter",
"milling_toolchange_end_gcode",
"milling_toolchange_start_gcode",
- "milling_offset",
- "milling_z_offset",
- "milling_z_lift",
"max_volumetric_extrusion_rate_slope_positive",
"max_volumetric_extrusion_rate_slope_negative",
"notes",
"only_retract_when_crossing_perimeters",
"output_filename_format",
- "overhangs_acceleration",
"overhangs_fan_speed",
- "perimeter_acceleration",
+ "parallel_objects_step",
+ "pause_print_gcode",
"post_process",
- "gcode_substitutions",
+ "print_custom_variables",
+ "printer_custom_variables",
"perimeter_fan_speed",
"printer_notes",
+ "remaining_times",
+ "remaining_times_type",
"retract_before_travel",
"retract_before_wipe",
"retract_layer_change",
@@ -174,9 +167,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
"retract_restart_extra",
"retract_restart_extra_toolchange",
"retract_speed",
+ "silent_mode",
"single_extruder_multi_material_priming",
"slowdown_below_layer_time",
- "solid_infill_acceleration",
"solid_infill_fan_speed",
"support_material_acceleration",
"support_material_fan_speed",
@@ -186,8 +179,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
"start_gcode",
"start_gcode_manual",
"start_filament_gcode",
- "thin_walls_acceleration",
- "thin_walls_speed",
+ "template_custom_gcode",
"thumbnails",
"thumbnails_color",
"thumbnails_custom_color",
@@ -202,17 +194,16 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
"tool_name",
"toolchange_gcode",
"top_fan_speed",
- "top_solid_infill_acceleration",
"threads",
- "travel_acceleration",
- "travel_deceleration_use_target",
- "travel_speed",
- "travel_speed_z",
"use_firmware_retraction",
"use_relative_e_distances",
"use_volumetric_e",
"variable_layer_height",
"wipe",
+ "wipe_advanced",
+ "wipe_advanced_algo",
+ "wipe_advanced_multiplier",
+ "wipe_advanced_nozzle_melted_volume",
"wipe_extra_perimeter",
"wipe_inside_depth",
"wipe_inside_end",
@@ -228,6 +219,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
bool invalidated = false;
for (const t_config_option_key &opt_key : opt_keys) {
+ //this one isn't even use in slicing, only for import.
+ if (opt_key == "init_z_rotate")
+ continue;
if (steps_gcode.find(opt_key) != steps_gcode.end()) {
// These options only affect G-code export or they are just notes without influence on the generated G-code,
// so there is nothing to invalidate.
@@ -240,23 +234,22 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
|| opt_key == "min_skirt_length"
|| opt_key == "ooze_prevention"
|| opt_key == "skirts"
- || opt_key == "skirt_height"
|| opt_key == "skirt_brim"
|| opt_key == "skirt_distance"
|| opt_key == "skirt_distance_from_brim"
+ || opt_key == "skirt_extrusion_width"
+ || opt_key == "skirt_height"
|| opt_key == "wipe_tower_x"
|| opt_key == "wipe_tower_y"
|| opt_key == "wipe_tower_rotation_angle"
) {
steps.emplace_back(psSkirtBrim);
} else if (
- opt_key == "filament_shrink"
- || opt_key == "first_layer_height"
+ opt_key == "bridge_precision"
+ || opt_key == "filament_shrink"
|| opt_key == "nozzle_diameter"
- || opt_key == "model_precision"
|| opt_key == "resolution"
|| opt_key == "resolution_internal"
- || opt_key == "slice_closing_radius"
// Spiral Vase forces different kind of slicing than the normal model:
// In Spiral Vase mode, holes are closed and only the largest area contour is kept at each layer.
// Therefore toggling the Spiral Vase on / off requires complete reslicing.
@@ -266,14 +259,13 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
} else if (
opt_key == "complete_objects"
|| opt_key == "filament_type"
- || opt_key == "filament_soluble"
- || opt_key == "first_layer_temperature"
|| opt_key == "filament_loading_speed"
|| opt_key == "filament_loading_speed_start"
|| opt_key == "filament_unloading_speed"
|| opt_key == "filament_unloading_speed_start"
|| opt_key == "filament_toolchange_delay"
|| opt_key == "filament_cooling_moves"
+ || opt_key == "filament_max_wipe_tower_speed"
|| opt_key == "filament_minimal_purge_on_wipe_tower"
|| opt_key == "filament_cooling_initial_speed"
|| opt_key == "filament_cooling_final_speed"
@@ -291,9 +283,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
|| opt_key == "filament_toolchange_part_fan_speed"
|| opt_key == "filament_dip_insertion_speed"
|| opt_key == "filament_dip_extraction_speed" //skinnydip params end
+ || opt_key == "first_layer_temperature"
|| opt_key == "gcode_flavor"
|| opt_key == "high_current_on_filament_swap"
- || opt_key == "infill_first"
|| opt_key == "single_extruder_multi_material"
|| opt_key == "temperature"
|| opt_key == "wipe_tower"
@@ -301,8 +293,10 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
|| opt_key == "wipe_tower_brim_width"
|| opt_key == "wipe_tower_bridging"
|| opt_key == "wipe_tower_no_sparse_layers"
+ || opt_key == "wipe_tower_per_color_wipe"
|| opt_key == "wipe_tower_speed"
|| opt_key == "wipe_tower_wipe_starting_speed"
+ || opt_key == "wiping_volumes_extruders"
|| opt_key == "wiping_volumes_matrix"
|| opt_key == "parking_pos_retraction"
|| opt_key == "cooling_tube_retraction"
@@ -310,7 +304,6 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
|| opt_key == "extra_loading_move"
|| opt_key == "travel_speed"
|| opt_key == "travel_speed_z"
- || opt_key == "first_layer_speed"
|| opt_key == "z_offset") {
steps.emplace_back(psWipeTower);
steps.emplace_back(psSkirtBrim);
@@ -321,8 +314,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
//FIXME Killing supports on any change of "filament_soluble" is rough. We should check for each object whether that is necessary.
osteps.emplace_back(posSupportMaterial);
} else if (
- opt_key == "first_layer_extrusion_width"
- || opt_key == "arc_fitting"
+ opt_key == "arc_fitting"
|| opt_key == "arc_fitting_tolerance"
|| opt_key == "min_layer_height"
|| opt_key == "max_layer_height"
@@ -333,6 +325,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver& /* ne
osteps.emplace_back(posSimplifyPath);
osteps.emplace_back(posSupportMaterial);
steps.emplace_back(psSkirtBrim);
+ } else if (opt_key == "seam_gap" || opt_key == "seam_gap_external") {
+ osteps.emplace_back(posInfill);
}
else if (opt_key == "posSlice")
osteps.emplace_back(posSlice);
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index f72bfcfe2e7..0f8d4211f17 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -46,6 +46,7 @@ namespace FillLightning {
using GeneratorPtr = std::unique_ptr;
}; // namespace FillLightning
+
// Print step IDs for keeping track of the print state.
// The Print steps are applied in this order.
enum PrintStep {
@@ -59,6 +60,7 @@ enum PrintStep {
// should be refreshed.
psSlicingFinished = psSkirtBrim,
psGCodeExport,
+ //TODO: psGCodeLoader (for params that are only used for time display and such)
psCount,
};
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index fe2ba37e9cb..e18866b0138 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -590,7 +590,8 @@ void PrintConfigDef::init_fff_params()
def->label = L("Arc fitting");
def->category = OptionCategory::firmware;
def->tooltip = L("Enable this to get a G-code file which has G2 and G3 moves. "
- "And the fitting tolerance is same with resolution");
+ "And the fitting tolerance is same with resolution\n"
+ "Please make sure your firmware is configured for GCode Arcs support");
def->mode = comAdvancedE | comSuSi;
def->set_default_value(new ConfigOptionBool(false));
@@ -676,6 +677,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert | comPrusa;
def->set_default_value(new ConfigOptionString(""));
+ def = this->add("per_objects_gcode", coString);
+ def->label = L("Per object G-code");
+ def->category = OptionCategory::customgcode;
+ def->tooltip = L("This code is inserted at the start of every object. it's main advantage is when you use it as a object modifer(right click on a model to add it there)"
+ "\nadd here the model names you want to insert the gocde for eg:'90_bend.3mf' if you have several seperate them with ',' no spaces in any target file name!"
+ "\nthe code will search for that object name and insert the custom gcode per that object only.");
+ def->multiline = true;
+ def->full_width = true;
+ def->height = 10;
+ def->mode = comExpert | comPrusa;
+ def->set_default_value(new ConfigOptionString(""));
+
def = this->add("bottom_solid_layers", coInt);
//TRN To be shown in Print Settings "Bottom solid layers"
def->label = L("Bottom");
@@ -712,20 +725,6 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvancedE | comPrusa;
def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
- def = this->add("bridge_internal_acceleration", coFloatOrPercent);
- def->label = L("Internal bridges ");
- def->full_label = L("Internal bridges acceleration");
- def->category = OptionCategory::speed;
- def->tooltip = L("This is the acceleration your printer will use for internal bridges. "
- "\nCan be a % of the default acceleration"
- "\nSet zero to use bridge acceleration for internal bridges.");
- def->sidetext = L("mm/s² or %");
- def->ratio_over = "bridge_acceleration";
- def->min = 0;
- def->max_literal = { -200, false };
- def->mode = comExpert | comSuSi;
- def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
-
def = this->add("bridge_angle", coFloat);
def->label = L("Bridging");
def->full_label = L("Bridging angle");
@@ -751,19 +750,6 @@ void PrintConfigDef::init_fff_params()
def->is_vector_extruder = true;
def->set_default_value(new ConfigOptionInts{ 100 });
- def = this->add("bridge_internal_fan_speed", coInts);
- def->label = L("Infill bridges fan speed");
- def->category = OptionCategory::cooling;
- def->tooltip = L("This fan speed is enforced during all infill bridges. It won't slow down the fan if it's currently running at a higher speed."
- "\nSet to -1 to disable this override (Internal bridges will use Bridges fan speed)."
- "\nCan be disabled by disable_fan_first_layers and increased by low layer time.");
- def->sidetext = L("%");
- def->min = -1;
- def->max = 100;
- def->mode = comAdvancedE | comSuSi;
- def->is_vector_extruder = true;
- def->set_default_value(new ConfigOptionInts{ -1 });
-
def = this->add("bridge_type", coEnum);
def->label = L("Bridge flow baseline");
def->category = OptionCategory::width;
@@ -855,17 +841,6 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvancedE | comPrusa;
def->set_default_value(new ConfigOptionFloatOrPercent(60, true));
- def = this->add("bridge_speed_internal", coFloatOrPercent);
- def->label = L("Internal bridges");
- def->full_label = L("Internal bridge speed");
- def->category = OptionCategory::speed;
- def->tooltip = L("Speed for printing the bridges that support the top layer.\nCan be a % of the bridge speed.");
- def->sidetext = L("mm/s or %");
- def->ratio_over = "bridge_speed";
- def->min = 0;
- def->mode = comExpert | comSuSi;
- def->set_default_value(new ConfigOptionFloatOrPercent(150,true));
-
def = this->add("brim_inside_holes", coBool);
def->label = L("Brim inside holes");
def->category = OptionCategory::skirtBrim;
@@ -1443,7 +1418,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Fill pattern for bridges and internal bridge infill.");
def->enum_keys_map = &ConfigOptionEnum::get_enum_values();
def->enum_values.push_back("rectilinear");
- def->enum_values.push_back("monotonic");
+ def->enum_values.push_back("monotonic");
def->enum_labels.push_back(L("Rectilinear"));
def->enum_labels.push_back(L("Monotonic"));
def->mode = comExpert | comSuSi;
@@ -2765,7 +2740,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("gap_fill_flow_match_perimeter", coPercent);
def->label = L("Cap with perimeter flow");
def->full_label = L("Gapfill: cap speed with perimeter flow");
- def->category = OptionCategory::output;
+ def->category = OptionCategory::speed;
def->tooltip = L("A percentage of the perimeter flow (mm3/s) is used as a limit for the gap fill flow, and so the gapfill may reduce its speed when the gap fill extrusions became too thick."
" This allow you to use a high gapfill speed, to print the thin gapfill quickly and reduce the difference in flow rate for the gapfill."
"\nSet zero to deactivate.");
@@ -2922,7 +2897,8 @@ void PrintConfigDef::init_fff_params()
def->category = OptionCategory::output;
def->tooltip = L("Enable this to add comments into the G-Code labeling print moves with what object they belong to,"
" which is useful for the Octoprint CancelObject plugin. This settings is NOT compatible with "
- "Single Extruder Multi Material setup and Wipe into Object / Wipe into Infill.");
+ "Single Extruder Multi Material setup and Wipe into Object / Wipe into Infill."
+ "Please make sure your firmware is configured for label objects support");
def->aliases = { "label_printed_objects" };
def->mode = comAdvancedE | comPrusa;
def->set_default_value(new ConfigOptionBool(1));
@@ -2974,10 +2950,15 @@ void PrintConfigDef::init_fff_params()
def->label = L("Combine infill every");
def->category = OptionCategory::infill;
def->tooltip = L("This feature allows you to combine infill and speed up your print by extruding thicker "
- "infill layers while preserving thin perimeters, thus accuracy.");
+ "infill layers while preserving thin perimeters, thus accuracy."
+ "\nthis will not make your combined layerheights larger than nozzle_diameter");
def->sidetext = L("layers");
def->full_label = L("Combine infill every n layers");
def->min = 1;
+ //def->ratio_over = "nozzle_diameter";
+ //FIXME need to validate this max value based on nozzle_diameter and base_layer_height, ratio_over ?
+ //if base_layer_height 0.2 with 0.4mm nozzle it allows higher numbers to be set that might confuse some users.
+ //def->max = nozzle_diameter;
def->mode = comAdvancedE | comPrusa;
def->set_default_value(new ConfigOptionInt(1));
@@ -3287,6 +3268,47 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert | comPrusa;
def->set_default_value(new ConfigOptionBool(false));
+ def = this->add("internal_bridge_acceleration", coFloatOrPercent);
+ def->label = L("Internal bridges ");
+ def->full_label = L("Internal bridges acceleration");
+ def->category = OptionCategory::speed;
+ def->tooltip = L("This is the acceleration your printer will use for internal bridges. "
+ "\nCan be a % of the default acceleration"
+ "\nSet zero to use bridge acceleration for internal bridges.");
+ def->sidetext = L("mm/s² or %");
+ def->ratio_over = "bridge_acceleration";
+ def->min = 0;
+ def->max_literal = { -200, false };
+ def->mode = comExpert | comSuSi;
+ def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
+ def->aliases = { "bridge_internal_acceleration" };
+
+ def = this->add("internal_bridge_fan_speed", coInts);
+ def->label = L("Infill bridges fan speed");
+ def->category = OptionCategory::cooling;
+ def->tooltip = L("This fan speed is enforced during all infill bridges. It won't slow down the fan if it's currently running at a higher speed."
+ "\nSet to -1 to disable this override (Internal bridges will use Bridges fan speed)."
+ "\nCan be disabled by disable_fan_first_layers and increased by low layer time.");
+ def->sidetext = L("%");
+ def->min = -1;
+ def->max = 100;
+ def->mode = comAdvancedE | comSuSi;
+ def->is_vector_extruder = true;
+ def->set_default_value(new ConfigOptionInts{ -1 });
+ def->aliases = { "bridge_internal_fan_speed" };
+
+ def = this->add("internal_bridge_speed", coFloatOrPercent);
+ def->label = L("Internal bridges");
+ def->full_label = L("Internal bridge speed");
+ def->category = OptionCategory::speed;
+ def->tooltip = L("Speed for printing the bridges that support the top layer.\nCan be a % of the bridge speed.");
+ def->sidetext = L("mm/s or %");
+ def->ratio_over = "bridge_speed";
+ def->min = 0;
+ def->mode = comExpert | comSuSi;
+ def->set_default_value(new ConfigOptionFloatOrPercent(150,true));
+ def->aliases = { "bridge_speed_internal" };
+
def = this->add("mmu_segmented_region_max_width", coFloat);
def->label = L("Maximum width of a segmented region");
def->tooltip = L("Maximum width of a segmented region. Zero disables this feature.");
@@ -3306,7 +3328,7 @@ void PrintConfigDef::init_fff_params()
def = this->add("ironing_acceleration", coFloatOrPercent);
def->label = L("Ironing");
def->full_label = L("Ironing acceleration");
- def->category = OptionCategory::speed;
+ def->category = OptionCategory::ironing;
def->tooltip = L("This is the acceleration your printer will use for ironing. "
"\nCan be a % of the top solid infill acceleration"
"\nSet zero to use top solid infill acceleration for ironing.");
@@ -3901,6 +3923,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvancedE | comSuSi;
def->set_default_value(new ConfigOptionString{ "" });
+ def = this->add("object_gcode", coString);
+ def->label = L("Per object G-code");
+ def->category = OptionCategory::advanced;
+ def->tooltip = L("This code is inserted each layer, when the object began to print (just after the label if any)."
+ " It's main advantage is when you use it as a object modifer (right click on a model)."
+ "\nSpecial variables: 'layer_num','layer_z'");
+ def->multiline = true;
+ def->full_width = true;
+ def->height = 10;
+ def->mode = comExpert | comSuSi;
+ def->set_default_value(new ConfigOptionString(""));
+
def = this->add("only_one_perimeter_first_layer", coBool);
def->label = L("Only one perimeter on First layer");
def->category = OptionCategory::perimeter;
@@ -4445,6 +4479,18 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvancedE | comSuSi;
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
+ def = this->add("region_gcode", coString);
+ def->label = L("Per region G-code");
+ def->category = OptionCategory::output;
+ def->tooltip = L("This code is inserted when a region is starting to print something (infill, perimeter, ironing)."
+ " It's main advantage is when you use it as a object modifer(right click on a model to add it there)"
+ "\nSpecial variables: 'layer_num','layer_z'");
+ def->multiline = true;
+ def->full_width = true;
+ def->height = 10;
+ def->mode = comExpert | comSuSi;
+ def->set_default_value(new ConfigOptionString(""));
+
def = this->add("resolution", coFloat);
def->label = L("Slice resolution");
def->category = OptionCategory::slicing;
@@ -5706,6 +5752,14 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert | comSuSi;
def->set_default_value(new ConfigOptionInt(0));
+ def = this->add("print_first_layer_temperature", coInt);
+ def->label = L("Temperature");
+ def->category = OptionCategory::filament;
+ def->tooltip = L("Override the temperature of the extruder (for the first layer). Avoid making too many changes, it won't stop for cooling/heating. 0 to disable (using print_temperature if defined). May only work on Height range modifiers.");
+ def->mode = comExpert | comSuSi;
+ def->min = 0;
+ def->set_default_value(new ConfigOptionInt(0));
+
def = this->add("print_retract_lift", coFloat);
def->label = L("Z-lift override");
def->category = OptionCategory::filament;
@@ -8070,11 +8124,9 @@ std::unordered_set prusa_export_to_remove_keys = {
"avoid_crossing_not_first_layer",
"avoid_crossing_top",
"bridge_fill_pattern",
-"bridge_internal_acceleration",
-"bridge_internal_fan_speed",
+"bridge_precision",
"bridge_overlap",
"bridge_overlap_min",
-"bridge_speed_internal",
"bridge_type",
"bridged_infill_margin",
"brim_acceleration",
@@ -8178,6 +8230,9 @@ std::unordered_set prusa_export_to_remove_keys = {
"infill_extrusion_spacing",
"infill_fan_speed",
"init_z_rotate",
+"internal_bridge_acceleration",
+"internal_bridge_fan_speed",
+"internal_bridge_speed",
"ironing_acceleration",
"ironing_angle",
"lift_min",
@@ -8199,6 +8254,7 @@ std::unordered_set prusa_export_to_remove_keys = {
"min_width_top_surface",
"model_precision",
"no_perimeter_unsupported_algo",
+"object_gcode",
"only_one_perimeter_top_other_algo",
"only_one_perimeter_top",
"only_one_perimeter_first_layer",
@@ -8220,6 +8276,7 @@ std::unordered_set prusa_export_to_remove_keys = {
"perimeter_reverse",
"perimeter_round_corners",
"print_extrusion_multiplier",
+"print_first_layer_temperature"
"print_custom_variables",
"print_retract_length",
"print_retract_lift",
@@ -8229,6 +8286,7 @@ std::unordered_set prusa_export_to_remove_keys = {
"printhost_client_cert_password",
"raft_layer_height",
"raft_interface_layer_height",
+"region_gcode",
"remaining_times_type",
"resolution_internal",
"retract_lift_first_layer",
@@ -9085,7 +9143,7 @@ std::set DynamicPrintConfig::value_changed(const t_co
something_changed = true;
}
}
- if (opt_key == "first_layer_extrusion_width") {
+ if (opt_key == "first_layer_extrusion_width") { //here
spacing_option = this->option("first_layer_extrusion_spacing");
if (width_option) {
width_option->set_phony(false);
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index d08278c77e1..f976b580046 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -22,7 +22,7 @@
// class DynamicConfig : public virtual ConfigBase
// class DynamicPrintConfig : public DynamicConfig
// class DynamicPrintAndCLIConfig : public DynamicPrintConfig
-//
+// my repo
//
#ifndef slic3r_PrintConfig_hpp_
@@ -706,6 +706,7 @@ protected: \
PRINT_CONFIG_CLASS_DEFINE(
PrintObjectConfig,
+ ((ConfigOptionFloatOrPercent, brim_acceleration))
((ConfigOptionBool, brim_inside_holes))
((ConfigOptionFloat, brim_width))
((ConfigOptionFloat, brim_width_interior))
@@ -718,17 +719,23 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloatOrPercent, brim_speed))
//((ConfigOptionEnum, brim_type))
((ConfigOptionBool, clip_multipart_objects))
+ ((ConfigOptionString, object_gcode))
((ConfigOptionBool, dont_support_bridges))
((ConfigOptionPercent, external_perimeter_cut_corners))
//((ConfigOptionBool, exact_last_layer_height))
((ConfigOptionFloatOrPercent, extrusion_width))
((ConfigOptionFloatOrPercent, extrusion_spacing))
+ ((ConfigOptionBool, fill_angle_follow_model))
+ ((ConfigOptionFloatOrPercent, first_layer_acceleration))
((ConfigOptionFloatOrPercent, first_layer_acceleration_over_raft))
((ConfigOptionFloatOrPercent, first_layer_height))
((ConfigOptionFloatOrPercent, first_layer_extrusion_width))
((ConfigOptionFloatOrPercent, first_layer_extrusion_spacing))
+ ((ConfigOptionFloatOrPercent, first_layer_infill_speed))
+ ((ConfigOptionFloat, first_layer_min_speed))
((ConfigOptionFloat, first_layer_size_compensation)) /* elefant_foot_compensation */
((ConfigOptionInt, first_layer_size_compensation_layers))
+ ((ConfigOptionFloatOrPercent, first_layer_speed))
((ConfigOptionFloatOrPercent, first_layer_speed_over_raft))
((ConfigOptionFloat, hole_size_compensation))
((ConfigOptionFloat, hole_size_threshold))
@@ -815,6 +822,7 @@ PRINT_CONFIG_CLASS_DEFINE(
PrintRegionConfig,
((ConfigOptionBool, avoid_crossing_top))
+ ((ConfigOptionFloatOrPercent, bridge_acceleration))
((ConfigOptionFloat, bridge_angle))
((ConfigOptionEnum, bridge_fill_pattern))
((ConfigOptionEnum, bridge_type))
@@ -827,15 +835,16 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionEnum, bottom_fill_pattern))
((ConfigOptionFloatOrPercent, bridged_infill_margin))
((ConfigOptionFloatOrPercent, bridge_speed))
- ((ConfigOptionFloatOrPercent, bridge_speed_internal))
((ConfigOptionFloat, curve_smoothing_precision))
((ConfigOptionFloat, curve_smoothing_cutoff_dist))
((ConfigOptionFloat, curve_smoothing_angle_convex))
((ConfigOptionFloat, curve_smoothing_angle_concave))
+ ((ConfigOptionFloatOrPercent, default_acceleration))
((ConfigOptionFloatOrPercent, default_speed))
((ConfigOptionBool, ensure_vertical_shell_thickness))
((ConfigOptionBool, enforce_full_fill_volume))
((ConfigOptionFloatOrPercent, external_infill_margin))
+ ((ConfigOptionFloatOrPercent, external_perimeter_acceleration))
((ConfigOptionFloatOrPercent, external_perimeter_extrusion_width))
((ConfigOptionFloatOrPercent, external_perimeter_extrusion_spacing))
((ConfigOptionFloatOrPercent, external_perimeter_extrusion_change_odd_layers))
@@ -859,12 +868,15 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionPercent, fill_density))
((ConfigOptionEnum, fill_pattern))
((ConfigOptionPercent, first_layer_flow_ratio))
+ ((ConfigOptionFloatOrPercent, first_layer_extrusion_width))//here?
+ ((ConfigOptionFloatOrPercent, first_layer_extrusion_spacing))
((ConfigOptionEnum, fuzzy_skin))
((ConfigOptionFloatOrPercent, fuzzy_skin_thickness))
((ConfigOptionFloatOrPercent, fuzzy_skin_point_dist))
((ConfigOptionPercent, fill_top_flow_ratio))
((ConfigOptionPercent, fill_smooth_distribution))
((ConfigOptionFloatOrPercent, fill_smooth_width))
+ ((ConfigOptionFloatOrPercent, gap_fill_acceleration))
((ConfigOptionBool, gap_fill_enabled))
((ConfigOptionFloatOrPercent, gap_fill_extension))
((ConfigOptionPercent, gap_fill_flow_match_perimeter))
@@ -880,6 +892,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionBool, hole_to_polyhole))
((ConfigOptionFloatOrPercent, hole_to_polyhole_threshold))
((ConfigOptionBool, hole_to_polyhole_twisted))
+ ((ConfigOptionFloatOrPercent, infill_acceleration))
((ConfigOptionInt, infill_extruder))
((ConfigOptionFloatOrPercent, infill_extrusion_width))
((ConfigOptionFloatOrPercent, infill_extrusion_spacing))
@@ -895,8 +908,11 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionBool, infill_dense))
((ConfigOptionEnum, infill_dense_algo))
((ConfigOptionBool, infill_first))
+ ((ConfigOptionFloatOrPercent, internal_bridge_acceleration))
+ ((ConfigOptionFloatOrPercent, internal_bridge_speed))
// Ironing options
((ConfigOptionBool, ironing))
+ ((ConfigOptionFloatOrPercent, ironing_acceleration))
((ConfigOptionFloat, ironing_angle))
((ConfigOptionEnum, ironing_type))
((ConfigOptionPercent, ironing_flowrate))
@@ -909,6 +925,10 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, milling_speed))
((ConfigOptionFloatOrPercent, min_width_top_surface))
// Detect bridging perimeters
+ ((ConfigOptionFloatOrPercent, overhangs_acceleration))
+ ((ConfigOptionFloatOrPercent, overhangs_max_slope))
+ ((ConfigOptionFloat, overhangs_bridge_threshold))
+ ((ConfigOptionInt, overhangs_bridge_upper_layers))
((ConfigOptionFloatOrPercent, overhangs_speed))
((ConfigOptionInt, overhangs_speed_enforce))
((ConfigOptionFloatOrPercent, overhangs_width))
@@ -916,6 +936,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionBool, overhangs_reverse))
((ConfigOptionFloatOrPercent, overhangs_reverse_threshold))
((ConfigOptionEnum, no_perimeter_unsupported_algo))
+ ((ConfigOptionFloatOrPercent, perimeter_acceleration))
((ConfigOptionBool, perimeter_round_corners))
((ConfigOptionInt, perimeter_extruder))
((ConfigOptionFloatOrPercent, perimeter_extrusion_width))
@@ -931,10 +952,12 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionPercent, print_extrusion_multiplier))
((ConfigOptionFloat, print_retract_length))
((ConfigOptionFloat, print_retract_lift))
+ ((ConfigOptionString, region_gcode))
((ConfigOptionFloatOrPercent, small_perimeter_speed))
((ConfigOptionFloatOrPercent, small_perimeter_min_length))
((ConfigOptionFloatOrPercent, small_perimeter_max_length))
((ConfigOptionEnum, solid_fill_pattern))
+ ((ConfigOptionFloatOrPercent, solid_infill_acceleration))
((ConfigOptionFloat, solid_infill_below_area))
((ConfigOptionInt, solid_infill_extruder))
((ConfigOptionFloatOrPercent, solid_infill_extrusion_width))
@@ -944,10 +967,12 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloatOrPercent, solid_infill_speed))
((ConfigOptionPercent, solid_infill_overlap))
((ConfigOptionInt, solid_over_perimeters))
+ ((ConfigOptionInt, print_first_layer_temperature))
((ConfigOptionInt, print_temperature))
((ConfigOptionPercent, thin_perimeters))
((ConfigOptionPercent, thin_perimeters_all))
((ConfigOptionBool, thin_walls))
+ ((ConfigOptionFloatOrPercent, thin_walls_acceleration))
((ConfigOptionFloatOrPercent, thin_walls_min_width))
((ConfigOptionFloatOrPercent, thin_walls_overlap))
((ConfigOptionFloatOrPercent, thin_walls_speed))
@@ -956,9 +981,12 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloatOrPercent, top_infill_extrusion_spacing))
((ConfigOptionInt, top_solid_layers))
((ConfigOptionFloat, top_solid_min_thickness))
+ ((ConfigOptionFloatOrPercent, top_solid_infill_acceleration))
+ ((ConfigOptionPercent, top_solid_infill_overlap))
((ConfigOptionFloatOrPercent, top_solid_infill_speed))
+ ((ConfigOptionFloatOrPercent, travel_acceleration))
+ ((ConfigOptionBool, travel_deceleration_use_target))
((ConfigOptionBool, wipe_into_infill))
-
)
PRINT_CONFIG_CLASS_DEFINE(
@@ -1162,11 +1190,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloatOrPercent, avoid_crossing_perimeters_max_detour))
((ConfigOptionPoints, bed_shape))
((ConfigOptionInts, bed_temperature))
- ((ConfigOptionFloatOrPercent, bridge_acceleration))
- ((ConfigOptionFloatOrPercent, bridge_internal_acceleration))
((ConfigOptionInts, bridge_fan_speed))
- ((ConfigOptionInts, bridge_internal_fan_speed))
- ((ConfigOptionFloatOrPercent, brim_acceleration))
+ ((ConfigOptionFloatOrPercent, bridge_precision))
((ConfigOptionInts, chamber_temperature))
((ConfigOptionBool, complete_objects))
((ConfigOptionFloat, parallel_objects_step))
@@ -1175,13 +1200,11 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionEnum, complete_objects_sort))
((ConfigOptionFloats, colorprint_heights))
//((ConfigOptionBools, cooling))
- ((ConfigOptionFloatOrPercent, default_acceleration))
((ConfigOptionInts, disable_fan_first_layers))
((ConfigOptionInts, default_fan_speed))
((ConfigOptionEnum, draft_shield))
((ConfigOptionFloat, duplicate_distance))
((ConfigOptionBool, enforce_retract_first_layer))
- ((ConfigOptionFloatOrPercent, external_perimeter_acceleration))
((ConfigOptionInts, external_perimeter_fan_speed))
((ConfigOptionFloat, extruder_clearance_height))
((ConfigOptionFloat, extruder_clearance_radius))
@@ -1194,18 +1217,13 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionStrings, filament_notes))
((ConfigOptionPercents, filament_max_overlap))
((ConfigOptionPercents, filament_shrink))
- ((ConfigOptionFloatOrPercent, first_layer_acceleration))
((ConfigOptionInts, first_layer_bed_temperature))
- ((ConfigOptionFloatOrPercent, first_layer_speed))
- ((ConfigOptionFloatOrPercent, first_layer_infill_speed))
- ((ConfigOptionFloat, first_layer_min_speed))
((ConfigOptionInts, first_layer_temperature))
+ //((ConfigOptionFloatOrPercent, first_layer_speed))
((ConfigOptionInts, full_fan_speed_layer))
- ((ConfigOptionFloatOrPercent, gap_fill_acceleration))
((ConfigOptionInts, gap_fill_fan_speed))
- ((ConfigOptionFloatOrPercent, infill_acceleration))
((ConfigOptionInts, infill_fan_speed))
- ((ConfigOptionFloatOrPercent, ironing_acceleration))
+ ((ConfigOptionInts, internal_bridge_fan_speed))
((ConfigOptionFloat, lift_min))
((ConfigOptionInts, max_fan_speed))
((ConfigOptionFloatsOrPercents, max_layer_height))
@@ -1214,8 +1232,6 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloats, milling_diameter))
((ConfigOptionStrings, milling_toolchange_end_gcode))
((ConfigOptionStrings, milling_toolchange_start_gcode))
- //((ConfigOptionPoints, milling_offset))
- //((ConfigOptionFloats, milling_z_offset))
//((ConfigOptionInts, min_fan_speed)) // now fan_printer_min_speed
((ConfigOptionFloatsOrPercents, min_layer_height))
((ConfigOptionFloats, min_print_speed))
@@ -1225,9 +1241,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionBool, only_retract_when_crossing_perimeters))
((ConfigOptionBool, ooze_prevention))
((ConfigOptionString, output_filename_format))
- ((ConfigOptionFloatOrPercent, overhangs_acceleration))
((ConfigOptionInts, overhangs_fan_speed))
- ((ConfigOptionFloatOrPercent, perimeter_acceleration))
((ConfigOptionInts, perimeter_fan_speed))
((ConfigOptionStrings, post_process))
((ConfigOptionString, print_custom_variables))
@@ -1249,7 +1263,6 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionInt, skirts))
((ConfigOptionFloats, slowdown_below_layer_time))
((ConfigOptionBool, spiral_vase))
- ((ConfigOptionFloatOrPercent, solid_infill_acceleration))
((ConfigOptionInts, solid_infill_fan_speed))
((ConfigOptionInt, standby_temperature_delta))
((ConfigOptionFloatOrPercent, support_material_acceleration))
@@ -1257,7 +1270,6 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloatOrPercent, support_material_interface_acceleration))
((ConfigOptionInts, support_material_interface_fan_speed))
((ConfigOptionInts, temperature))
- ((ConfigOptionFloatOrPercent, thin_walls_acceleration))
((ConfigOptionInt, threads))
((ConfigOptionPoints, thumbnails))
((ConfigOptionString, thumbnails_color))
@@ -1271,9 +1283,6 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
((ConfigOptionFloat, time_start_gcode))
((ConfigOptionFloat, time_toolchange))
((ConfigOptionInts, top_fan_speed))
- ((ConfigOptionFloatOrPercent, top_solid_infill_acceleration))
- ((ConfigOptionFloatOrPercent, travel_acceleration))
- ((ConfigOptionBool, travel_deceleration_use_target))
((ConfigOptionBools, wipe))
((ConfigOptionBool, wipe_tower))
((ConfigOptionFloatOrPercent, wipe_tower_brim_width))
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index 18d68c51f4a..b3b1edc9b97 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -821,7 +821,7 @@ FillLightning::GeneratorPtr PrintObject::prepare_lightning_infill_data()
// Called by Print::apply().
// This method only accepts PrintObjectConfig and PrintRegionConfig option keys.
-bool PrintObject::invalidate_state_by_config_options(
+ bool PrintObject::invalidate_state_by_config_options(
const ConfigOptionResolver &old_config, const ConfigOptionResolver &new_config, const std::vector &opt_keys)
{
if (opt_keys.empty())
@@ -831,13 +831,13 @@ bool PrintObject::invalidate_state_by_config_options(
bool invalidated = false;
for (const t_config_option_key& opt_key : opt_keys) {
if (
- opt_key == "gap_fill_enabled"
- || opt_key == "gap_fill_extension"
+ opt_key == "gap_fill_extension"
|| opt_key == "gap_fill_last"
|| opt_key == "gap_fill_max_width"
|| opt_key == "gap_fill_min_area"
|| opt_key == "gap_fill_min_length"
|| opt_key == "gap_fill_min_width"
+ || opt_key == "min_width_top_surface"
|| opt_key == "only_one_perimeter_first_layer"
|| opt_key == "only_one_perimeter_top"
|| opt_key == "only_one_perimeter_top_other_algo"
@@ -846,23 +846,23 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "overhangs_reverse"
|| opt_key == "overhangs_reverse_threshold"
|| opt_key == "overhangs_speed_enforce"
+ || opt_key == "perimeter_bonding"
|| opt_key == "perimeter_extrusion_change_odd_layers"
|| opt_key == "perimeter_extrusion_spacing"
|| opt_key == "perimeter_extrusion_width"
|| opt_key == "perimeter_reverse"
- || opt_key == "infill_overlap"
+ || opt_key == "perimeter_round_corners"
|| opt_key == "thin_perimeters"
|| opt_key == "thin_perimeters_all"
- || opt_key == "thin_walls"
+ || opt_key == "thin_walls_merge"
|| opt_key == "thin_walls_min_width"
|| opt_key == "thin_walls_overlap"
|| opt_key == "external_perimeters_first"
|| opt_key == "external_perimeters_hole"
|| opt_key == "external_perimeters_nothole"
|| opt_key == "external_perimeter_extrusion_change_odd_layers"
- || opt_key == "external_perimeter_extrusion_spacing"
- || opt_key == "external_perimeter_extrusion_width"
|| opt_key == "external_perimeters_vase"
+ || opt_key == "first_layer_extrusion_width"
|| opt_key == "perimeter_loop"
|| opt_key == "perimeter_loop_seam") {
steps.emplace_back(posPerimeters);
@@ -888,32 +888,49 @@ bool PrintObject::invalidate_state_by_config_options(
steps.emplace_back(posSlice);
steps.emplace_back(posPerimeters);
} else if (
- opt_key == "layer_height"
+ // || opt_key == "exact_last_layer_height"
+ opt_key == "bridge_type"
+ || opt_key == "clip_multipart_objects"
+ || opt_key == "curve_smoothing_angle_concave"
+ || opt_key == "curve_smoothing_angle_convex"
+ || opt_key == "curve_smoothing_cutoff_dist"
+ || opt_key == "curve_smoothing_precision"
+ || opt_key == "dont_support_bridges"
+ || opt_key == "elephant_foot_min_width" //sla ?
+ || opt_key == "first_layer_size_compensation"
+ || opt_key == "first_layer_size_compensation_layers"
|| opt_key == "first_layer_height"
+ || opt_key == "hole_size_compensation"
+ || opt_key == "hole_size_threshold"
+ || opt_key == "hole_to_polyhole"
+ || opt_key == "hole_to_polyhole_threshold"
+ || opt_key == "hole_to_polyhole_twisted"
+ || opt_key == "layer_height"
+ || opt_key == "min_bead_width"
+ || opt_key == "min_feature_size"
|| opt_key == "mmu_segmented_region_max_width"
- // || opt_key == "exact_last_layer_height"
+ || opt_key == "model_precision"
+ || opt_key == "overhangs_max_slope"
+ || opt_key == "overhangs_bridge_threshold"
+ || opt_key == "overhangs_bridge_upper_layers"
|| opt_key == "raft_contact_distance"
|| opt_key == "raft_interface_layer_height"
|| opt_key == "raft_layers"
|| opt_key == "raft_layer_height"
- || opt_key == "slice_closing_radius"
- || opt_key == "clip_multipart_objects"
- || opt_key == "first_layer_size_compensation"
- || opt_key == "first_layer_size_compensation_layers"
- || opt_key == "elephant_foot_min_width"
- || opt_key == "dont_support_bridges"
+ || opt_key == "perimeter_generator"
|| opt_key == "slice_closing_radius"
|| opt_key == "slicing_mode"
|| opt_key == "support_material_contact_distance_type"
- || opt_key == "support_material_contact_distance_top"
- || opt_key == "support_material_contact_distance_bottom"
+ || opt_key == "support_material_contact_distance"
+ || opt_key == "support_material_bottom_contact_distance"
|| opt_key == "support_material_interface_layer_height"
|| opt_key == "support_material_layer_height"
- || opt_key == "xy_size_compensation"
- || opt_key == "hole_size_compensation"
- || opt_key == "hole_size_threshold"
- || opt_key == "hole_to_polyhole"
- || opt_key == "hole_to_polyhole_threshold") {
+ || opt_key == "wall_transition_length"
+ || opt_key == "wall_transition_filter_deviation"
+ || opt_key == "wall_transition_angle"
+ || opt_key == "wall_distribution_count"
+ || opt_key == "xy_inner_size_compensation"
+ || opt_key == "xy_size_compensation") {
steps.emplace_back(posSlice);
} else if (opt_key == "support_material") {
steps.emplace_back(posSupportMaterial);
@@ -935,17 +952,15 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "support_material_enforce_layers"
|| opt_key == "support_material_extruder"
|| opt_key == "support_material_extrusion_width"
- || opt_key == "support_material_bottom_contact_distance"
|| opt_key == "support_material_interface_layers"
|| opt_key == "support_material_bottom_interface_layers"
|| opt_key == "support_material_interface_angle"
|| opt_key == "support_material_interface_angle_increment"
- || opt_key == "support_material_interface_pattern"
|| opt_key == "support_material_interface_contact_loops"
|| opt_key == "support_material_interface_extruder"
+ || opt_key == "support_material_interface_pattern"
|| opt_key == "support_material_interface_spacing"
|| opt_key == "support_material_pattern"
- || opt_key == "support_material_interface_pattern"
|| opt_key == "support_material_style"
|| opt_key == "support_material_xy_spacing"
|| opt_key == "support_material_spacing"
@@ -956,8 +971,7 @@ bool PrintObject::invalidate_state_by_config_options(
steps.emplace_back(posSupportMaterial);
} else if (opt_key == "bottom_solid_layers") {
steps.emplace_back(posPrepareInfill);
- if (m_print->config().spiral_vase
- || opt_key == "z_step") {
+ if (m_print->config().spiral_vase) {
// Changing the number of bottom layers when a spiral vase is enabled requires re-slicing the object again.
// Otherwise, holes in the bottom layers could be filled, as is reported in GH #5528.
steps.emplace_back(posSlice);
@@ -973,9 +987,10 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "infill_every_layers"
|| opt_key == "infill_dense"
|| opt_key == "infill_dense_algo"
- || opt_key == "infill_not_connected"
|| opt_key == "infill_only_where_needed"
+ || opt_key == "ironing"
|| opt_key == "ironing_type"
+ || opt_key == "over_bridge_flow_ratio"
|| opt_key == "solid_infill_below_area"
|| opt_key == "solid_infill_extruder"
|| opt_key == "solid_infill_every_layers"
@@ -984,10 +999,10 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "top_solid_min_thickness") {
steps.emplace_back(posPrepareInfill);
} else if (
- opt_key == "top_fill_pattern"
- || opt_key == "bottom_fill_pattern"
+ opt_key == "bottom_fill_pattern"
|| opt_key == "bridge_fill_pattern"
- || opt_key == "solid_fill_pattern"
+ || opt_key == "bridge_overlap"
+ || opt_key == "bridge_overlap_min"
|| opt_key == "enforce_full_fill_volume"
|| opt_key == "fill_aligned_z"
|| opt_key == "fill_angle"
@@ -1004,17 +1019,20 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "infill_connection_bridge"
|| opt_key == "infill_connection_solid"
|| opt_key == "infill_connection_top"
- || opt_key == "seam_gap"
- || opt_key == "seam_gap_external"
+ || opt_key == "ironing_angle"
+ || opt_key == "ironing_flowrate"
+ || opt_key == "ironing_spacing"
+ || opt_key == "solid_fill_pattern"
+ || opt_key == "top_fill_pattern"
|| opt_key == "top_infill_extrusion_spacing"
|| opt_key == "top_infill_extrusion_width" ) {
steps.emplace_back(posInfill);
- } else if (opt_key == "fill_pattern") {
- steps.emplace_back(posInfill);
+ } else if (opt_key == "fill_pattern") {
+ steps.emplace_back(posInfill);
- const auto *old_fill_pattern = old_config.option>(opt_key);
- const auto *new_fill_pattern = new_config.option>(opt_key);
- assert(old_fill_pattern && new_fill_pattern);
+ const auto *old_fill_pattern = old_config.option>(opt_key);
+ const auto *new_fill_pattern = new_config.option>(opt_key);
+ assert(old_fill_pattern && new_fill_pattern);
// We need to recalculate infill surfaces when infill_only_where_needed is enabled, and we are switching from
// the Lightning infill to another infill or vice versa.
if (m_config.infill_only_where_needed && (new_fill_pattern->value == ipLightning || old_fill_pattern->value == ipLightning))
@@ -1036,36 +1054,34 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "bridged_infill_margin"
|| opt_key == "extra_perimeters"
|| opt_key == "extra_perimeters_odd_layers"
+ || opt_key == "extra_perimeters_overhangs"
|| opt_key == "external_infill_margin"
|| opt_key == "external_perimeter_overlap"
|| opt_key == "gap_fill_overlap"
+ || opt_key == "infill_overlap"
|| opt_key == "no_perimeter_unsupported_algo"
- || opt_key == "filament_max_overlap"
|| opt_key == "perimeters"
|| opt_key == "perimeter_overlap"
|| opt_key == "solid_infill_extrusion_change_odd_layers"
|| opt_key == "solid_infill_extrusion_spacing"
- || opt_key == "solid_infill_extrusion_width") {
+ || opt_key == "solid_infill_extrusion_width"
+ || opt_key == "solid_infill_overlap"
+ || opt_key == "top_solid_infill_overlap") {
steps.emplace_back(posPerimeters);
steps.emplace_back(posPrepareInfill);
- } else if (opt_key == "solid_infill_extrusion_change_odd_layers"
- || opt_key == "solid_infill_extrusion_spacing"
- || opt_key == "solid_infill_extrusion_width") {
- // This value is used for calculating perimeter - infill overlap, thus perimeters need to be recalculated.
- steps.emplace_back(posPerimeters);
- steps.emplace_back(posPrepareInfill);
} else if (
- opt_key == "external_perimeter_extrusion_width"
- || opt_key == "perimeter_extruder"
- || opt_key == "fuzzy_skin"
- || opt_key == "fuzzy_skin_thickness"
- || opt_key == "fuzzy_skin_point_dist"
- || opt_key == "overhangs"
- || opt_key == "thin_walls"
- || opt_key == "thick_bridges") {
+ opt_key == "external_perimeter_extrusion_width"
+ || opt_key == "external_perimeter_extrusion_spacing"
+ || opt_key == "perimeter_extruder"
+ || opt_key == "fuzzy_skin"
+ || opt_key == "fuzzy_skin_thickness"
+ || opt_key == "fuzzy_skin_point_dist"
+ || opt_key == "thin_walls") {
steps.emplace_back(posPerimeters);
steps.emplace_back(posSupportMaterial);
} else if (opt_key == "bridge_flow_ratio"
+ || opt_key == "extrusion_spacing"
+ || opt_key == "extrusion_width"
|| opt_key == "first_layer_extrusion_spacing"
|| opt_key == "first_layer_extrusion_width") {
//if (m_config.support_material_contact_distance > 0.) {
@@ -1075,28 +1091,53 @@ bool PrintObject::invalidate_state_by_config_options(
steps.emplace_back(posInfill);
steps.emplace_back(posSupportMaterial);
//}
- } else if (
- opt_key == "perimeter_generator"
- || opt_key == "wall_transition_length"
- || opt_key == "wall_transition_filter_deviation"
- || opt_key == "wall_transition_angle"
- || opt_key == "wall_distribution_count"
- || opt_key == "min_feature_size"
- || opt_key == "min_bead_width") {
- steps.emplace_back(posSlice);
} else if (
opt_key == "avoid_crossing_top"
+ || opt_key == "bridge_acceleration"
|| opt_key == "bridge_speed"
- || opt_key == "bridge_speed_internal"
+ || opt_key == "brim_acceleration"
+ || opt_key == "brim_speed"
|| opt_key == "external_perimeter_speed"
- || opt_key == "external_perimeters_vase"
+ || opt_key == "default_acceleration"
+ || opt_key == "default_speed"
+ || opt_key == "external_perimeter_acceleration"
+ || opt_key == "external_perimeter_cut_corners"
+ || opt_key == "first_layer_acceleration"
+ || opt_key == "first_layer_acceleration_over_raft"
+ || opt_key == "first_layer_extrusion_width"
+ || opt_key == "first_layer_extrusion_spacing"//missing from here ?
+ || opt_key == "first_layer_flow_ratio"
+ || opt_key == "first_layer_infill_speed"
+ || opt_key == "first_layer_min_speed"
+ || opt_key == "first_layer_speed"
+ || opt_key == "first_layer_speed_over_raft"
+ || opt_key == "gap_fill_acceleration"
+ || opt_key == "gap_fill_flow_match_perimeter"
|| opt_key == "gap_fill_speed"
+ || opt_key == "infill_acceleration"
|| opt_key == "infill_speed"
+ || opt_key == "internal_bridge_acceleration"
+ || opt_key == "internal_bridge_speed"
+ || opt_key == "ironing_acceleration"
+ || opt_key == "ironing_speed"
+ || opt_key == "milling_after_z"
+ || opt_key == "milling_extra_size"
+ || opt_key == "milling_post_process"
+ || opt_key == "milling_speed"
+ || opt_key == "object_gcode"
+ || opt_key == "overhangs_acceleration"
|| opt_key == "overhangs_speed"
+ || opt_key == "perimeter_acceleration"
|| opt_key == "perimeter_speed"
+ || opt_key == "print_extrusion_multiplier"
+ || opt_key == "print_first_layer_temperature"
+ || opt_key == "print_retract_length"
+ || opt_key == "print_retract_lift"
+ || opt_key == "print_temperature"
+ || opt_key == "region_gcode"
|| opt_key == "seam_position"
- || opt_key == "seam_preferred_direction"
- || opt_key == "seam_preferred_direction_jitter"
+ //|| opt_key == "seam_preferred_direction"
+ //|| opt_key == "seam_preferred_direction_jitter"
|| opt_key == "seam_angle_cost"
|| opt_key == "seam_notch_all"
|| opt_key == "seam_notch_angle"
@@ -1107,14 +1148,20 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "small_perimeter_speed"
|| opt_key == "small_perimeter_min_length"
|| opt_key == "small_perimeter_max_length"
+ || opt_key == "solid_infill_acceleration"
|| opt_key == "solid_infill_speed"
|| opt_key == "support_material_interface_speed"
|| opt_key == "support_material_speed"
+ || opt_key == "thin_walls_acceleration"
|| opt_key == "thin_walls_speed"
- || opt_key == "top_solid_infill_speed") {
+ || opt_key == "top_solid_infill_acceleration"
+ || opt_key == "top_solid_infill_speed"
+ || opt_key == "travel_acceleration"
+ || opt_key == "travel_deceleration_use_target") {
invalidated |= m_print->invalidate_step(psGCodeExport);
} else if (
- opt_key == "wipe_into_infill"
+ opt_key == "infill_first"
+ || opt_key == "wipe_into_infill"
|| opt_key == "wipe_into_objects") {
invalidated |= m_print->invalidate_step(psWipeTower);
invalidated |= m_print->invalidate_step(psGCodeExport);
@@ -1125,7 +1172,8 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "brim_ears_max_angle"
|| opt_key == "brim_ears_pattern"
|| opt_key == "brim_per_object"
- || opt_key == "brim_separation") {
+ || opt_key == "brim_separation"
+ || opt_key == "brim_type") {
invalidated |= m_print->invalidate_step(psSkirtBrim);
// Brim is printed below supports, support invalidates brim and skirt.
steps.emplace_back(posSupportMaterial);
diff --git a/src/libslic3r/PrintRegion.cpp b/src/libslic3r/PrintRegion.cpp
index 03fd40de5f8..6a213a07bfe 100644
--- a/src/libslic3r/PrintRegion.cpp
+++ b/src/libslic3r/PrintRegion.cpp
@@ -79,9 +79,14 @@ Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_he
} else {
throw Slic3r::InvalidArgument("Unknown role");
}
- if (first_layer && object.config().first_layer_extrusion_width.value > 0) {
+ /*if (first_layer && object.config().first_layer_extrusion_width.value > 0) {
config_width = object.config().first_layer_extrusion_width;
config_spacing = object.config().first_layer_extrusion_spacing;
+ }*/
+
+ if (first_layer && m_config.first_layer_extrusion_width.value > 0) {
+ config_width = m_config.first_layer_extrusion_width;
+ config_spacing = m_config.first_layer_extrusion_spacing;
}
if (config_width.value == 0) {
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index c11f860c59b..97a4520446d 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -38,6 +38,8 @@ set(SLIC3R_GUI_SOURCES
GUI/CalibrationTempDialog.hpp
GUI/CalibrationRetractionDialog.cpp
GUI/CalibrationRetractionDialog.hpp
+ GUI/CalibrationPressureAdvDialog.cpp
+ GUI/CalibrationPressureAdvDialog.hpp
GUI/ConfigSnapshotDialog.cpp
GUI/ConfigSnapshotDialog.hpp
GUI/CreateMMUTiledCanvas.cpp
diff --git a/src/slic3r/GUI/CalibrationAbstractDialog.cpp b/src/slic3r/GUI/CalibrationAbstractDialog.cpp
index f3eaebbb664..8af84ce85ab 100644
--- a/src/slic3r/GUI/CalibrationAbstractDialog.cpp
+++ b/src/slic3r/GUI/CalibrationAbstractDialog.cpp
@@ -26,13 +26,14 @@ static wxSize get_screen_size(wxWindow* window)
namespace Slic3r {
namespace GUI {
- CalibrationAbstractDialog::CalibrationAbstractDialog(GUI_App* app, MainFrame* mainframe, std::string name)
+CalibrationAbstractDialog::CalibrationAbstractDialog(GUI_App* app, MainFrame* mainframe, std::string name)
: DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L(name)),
#if ENABLE_SCROLLABLE
- wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
+ wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
#else
- wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
+ wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
#endif // ENABLE_SCROLLABLE
+ , "calibration")
{
this->gui_app = app;
this->main_frame = mainframe;
@@ -45,10 +46,24 @@ namespace GUI {
}
-void CalibrationAbstractDialog::create(boost::filesystem::path html_path, std::string html_name, wxSize dialog_size){
+void CalibrationAbstractDialog::create(boost::filesystem::path html_path, std::string html_name, wxSize dialog_size, bool include_close_button){
- auto main_sizer = new wxBoxSizer(wxVERTICAL);
+ const AppConfig* app_config = get_app_config();
+ bool dark_mode = app_config->get_bool("dark_color_mode");// i guss these can be set as global variables?
+ std::string user_color_text = app_config->get("color_dark");
+ wxColour text_color("#" + user_color_text);
+ std::string color_background = dark_mode ? "333233" : "ffffff";//dark grey and white. whats the offical dark mode color ?
+ wxColour background_color("#" + color_background);
+
+ // Create a panel for the entire content
+ wxPanel* main_panel = new wxPanel(this, wxID_ANY);
+ main_panel->SetBackgroundColour(background_color);
+
+ // Create the sizer for the panel's content
+ wxBoxSizer* panel_sizer = new wxBoxSizer(wxVERTICAL);
+ gui_app->app_config->set("autocenter", "1");
+
//language
wxString language = wxGetApp().current_language_code();
boost::filesystem::path full_file_path = (boost::filesystem::path(Slic3r::resources_dir()) / html_path/ (into_u8(language) + "_"+ html_name));
@@ -66,35 +81,48 @@ void CalibrationAbstractDialog::create(boost::filesystem::path html_path, std::s
}
}
- //html
- html_viewer = new wxHtmlWindow(this, wxID_ANY,
+ // Create the HTML viewer and load the page
+ html_viewer = new wxHtmlWindow(main_panel, wxID_ANY,
wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
html_viewer->LoadPage(GUI::from_u8(full_file_path.string()));
// when using hyperlink, open the browser.
html_viewer->Bind(wxEVT_HTML_LINK_CLICKED, [this](wxHtmlLinkEvent& evt) {
wxLaunchDefaultBrowser(evt.GetLinkInfo().GetHref());
});
- main_sizer->Add(html_viewer, 1, wxEXPAND | wxALL, 5);
+ panel_sizer->Add(html_viewer, 1, wxEXPAND | wxALL, 5);
+ // Adjust the dialog size
wxDisplay display(wxDisplay::GetFromWindow(main_frame));
wxRect screen = display.GetClientArea();
dialog_size.x = std::min(int(dialog_size.x * this->scale_factor()), screen.width - 50);
dialog_size.y = std::min(int(dialog_size.y * this->scale_factor()), screen.height - 50);
+ // Create the button sizer and configure the "Close" button
wxStdDialogButtonSizer* buttons = new wxStdDialogButtonSizer();
create_buttons(buttons);
- wxButton* close = new wxButton(this, wxID_CLOSE, _L("Close"));
- close->Bind(wxEVT_BUTTON, &CalibrationAbstractDialog::close_me, this);
- buttons->AddButton(close);
- close->SetDefault();
- close->SetFocus();
- SetAffirmativeId(wxID_CLOSE);
+ if (!include_close_button) {//if you want to define a custom location for the close button
+ wxButton* close = new wxButton(main_panel, wxID_CLOSE, _L("Close"));
+ close->Bind(wxEVT_BUTTON, &CalibrationAbstractDialog::close_me, this);
+ buttons->AddButton(close);
+ close->SetDefault();
+ close->SetFocus();
+ SetAffirmativeId(wxID_CLOSE);
+ }
+
buttons->Realize();
- main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5);
+ panel_sizer->Add(buttons, 0, wxEXPAND | wxALL, 5);
+
+ // Set the panel's sizer and add the panel to the dialog
+ main_panel->SetSizer(panel_sizer);
+ wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
+ main_sizer->Add(main_panel, 1, wxEXPAND | wxALL, 0);
SetSizer(main_sizer);
this->SetSize(dialog_size.x, dialog_size.y);
+ gui_app->app_config->set("autocenter", "0");
+ main_panel->Lower();// this may break some calibration windows... willl have to call Raise() on other calibration windows that have a panel
+
}
void CalibrationAbstractDialog::close_me(wxCommandEvent& event_args) {
diff --git a/src/slic3r/GUI/CalibrationAbstractDialog.hpp b/src/slic3r/GUI/CalibrationAbstractDialog.hpp
index a54fa6d72b3..ae8f0f5ff63 100644
--- a/src/slic3r/GUI/CalibrationAbstractDialog.hpp
+++ b/src/slic3r/GUI/CalibrationAbstractDialog.hpp
@@ -25,7 +25,7 @@ class CalibrationAbstractDialog : public DPIDialog
private:
wxPanel* create_header(wxWindow* parent, const wxFont& bold_font);
protected:
- void create(boost::filesystem::path html_path, std::string html_name, wxSize dialogsize = wxSize(850, 550));
+ void create(boost::filesystem::path html_path, std::string html_name, wxSize dialogsize = wxSize(850, 550), bool include_close_button = false);
virtual void create_buttons(wxStdDialogButtonSizer*) = 0;
void on_dpi_changed(const wxRect& suggested_rect) override;
void close_me(wxCommandEvent& event_args);
diff --git a/src/slic3r/GUI/CalibrationPressureAdvDialog.cpp b/src/slic3r/GUI/CalibrationPressureAdvDialog.cpp
new file mode 100644
index 00000000000..4ac11bcc79a
--- /dev/null
+++ b/src/slic3r/GUI/CalibrationPressureAdvDialog.cpp
@@ -0,0 +1,1322 @@
+#include "CalibrationPressureAdvDialog.hpp"
+#include "I18N.hpp"
+#include "libslic3r/Utils.hpp"
+#include "libslic3r/CustomGCode.hpp"
+#include "libslic3r/Model.hpp"
+#include "libslic3r/AppConfig.hpp"
+#include "GLCanvas3D.hpp"
+#include "GUI.hpp"
+#include "GUI_ObjectList.hpp"
+#include "Plater.hpp"
+#include "Tab.hpp"
+#include
+#include
+#include
+#include "wxExtensions.hpp"
+#include "Jobs/ArrangeJob.hpp"
+//#include "Jobs/job.hpp" 2.7 requirement?
+#include
+
+#pragma optimize("", off)
+
+#undef NDEBUG
+#include
+
+#if ENABLE_SCROLLABLE
+static wxSize get_screen_size(wxWindow* window)
+{
+ const auto idx = wxDisplay::GetFromWindow(window);
+ wxDisplay display(idx != wxNOT_FOUND ? idx : 0u);
+ return display.GetClientArea().GetSize();
+}
+#endif // ENABLE_SCROLLABLE
+
+namespace Slic3r {
+namespace GUI {
+
+//BUG: custom gcode ' between extrusion role changes' should that be before or after region gcode?
+// BUG: output error if first layer height is lower than base layer height
+// this can cause the numbers to not "show up" on the preview because the z scale is calculated wrong.
+// ie; first_layer_height=0.1 and base_layer_height =0.20
+//BUG: if first/base layer height are both .02 numbers don't show up when sliced. doesn't happen with windows, it did for linux ?
+//BUG: first_layer_height and base_layer_height both the same wil mess with numbers scale in z ?
+//TODO: does marlin/reprap need other values for this?
+//improvement if users have milti toolheads/swapping create a custom command for setting PA, add in welcome page for them to add this custom command for PA into filament notes-custom variables
+// since they will most likely have a klipper macro for chaning toolheads/doing other stuff.
+//BUG: some localization issues results in broken PA calculations since ',' and '.' get swapped. this is because of manual text entry as strings.
+
+/*FlowRole string_to_flow_role(const std::string& role_str) {
+ static std::unordered_map role_map = {
+ {"InternalInfill", FlowRole::frInfill},
+ {"BridgeInfill", FlowRole::frSupportMaterialInterface}, // special calc required
+ {"ExternalPerimeter", FlowRole::frExternalPerimeter},
+ {"GapFill", FlowRole::frSupportMaterialInterface}, // special calc required
+ {"InternalBridgeInfill", FlowRole::frSupportMaterialInterface}, // special calc required
+ {"Ironing", FlowRole::frSupportMaterialInterface}, // special calc required
+ {"OverhangPerimeter", FlowRole::frExternalPerimeter}, //overhangs use the same flow config as external perimeter TODO: confirm this.
+ {"Perimeter", FlowRole::frPerimeter},
+ {"SolidInfill", FlowRole::frSolidInfill},
+ {"SupportMaterial", FlowRole::frSupportMaterial},
+ {"SupportMaterialInterface", FlowRole::frSupportMaterialInterface},
+ {"ThinWall", FlowRole::frSupportMaterialInterface}, // special calc required
+ {"TopSolidInfill", FlowRole::frTopSolidInfill},
+ {"FirstLayer", FlowRole::frSupportMaterialInterface} // special calc required
+ };
+
+ return role_map[role_str];
+}
+
+ExtrusionRole string_to_er_role(const std::string& role_str) {
+ static std::unordered_map role_map = {
+ {"InternalInfill", ExtrusionRole::erInternalInfill},
+ {"BridgeInfill", ExtrusionRole::erBridgeInfill},
+ {"ExternalPerimeter", ExtrusionRole::erExternalPerimeter},
+ {"GapFill", ExtrusionRole::erGapFill},
+ {"InternalBridgeInfill", ExtrusionRole::erInternalBridgeInfill},
+ {"Ironing", ExtrusionRole::erIroning},
+ {"OverhangPerimeter", ExtrusionRole::erOverhangPerimeter},
+ {"Perimeter", ExtrusionRole::erPerimeter},
+ {"SolidInfill", ExtrusionRole::erSolidInfill},
+ {"SupportMaterial", ExtrusionRole::erSupportMaterial},
+ {"SupportMaterialInterface", ExtrusionRole::erSupportMaterialInterface},
+ {"ThinWall", ExtrusionRole::erThinWall},
+ {"TopSolidInfill", ExtrusionRole::erTopSolidInfill},
+ {"FirstLayer", ExtrusionRole::erCustom}
+ };
+
+ return role_map[role_str];
+}*/
+
+void CalibrationPressureAdvDialog::create_geometry(wxCommandEvent& event_args) {
+
+ std::string choice_extrusion_role[] = {
+ "InternalInfill",
+ "BridgeInfill",
+ "ExternalPerimeter",
+ "GapFill",
+ "InternalBridgeInfill",
+ "Ironing",
+ "OverhangPerimeter",
+ "Perimeter",
+ "SolidInfill",
+ "SupportMaterial",
+ "SupportMaterialInterface",
+ "ThinWall",
+ "TopSolidInfill",
+ "FirstLayer"//i've got added them all right?
+ };
+
+ std::unordered_map er_width_ToOptionKey = {
+ {"InternalInfill", "infill_extrusion_width"},
+ //{"BridgeInfill", "placeholder"},//special calc required
+ {"ExternalPerimeter", "external_perimeter_extrusion_width"},
+ //{"GapFill", "placeholder"},//special calc required
+ //{"InternalBridgeInfill", "placeholder"},//special calc required, TODO:find out where/how this is calculated
+ //{"Ironing", "top_infill_extrusion_width"},//not fully suported
+ {"OverhangPerimeter", "overhangs_width"},//special calc required, TODO:find out where/how this is calculated 'overhangs_width' is not the same width config as others, it considers this value when calculating flow
+ {"Perimeter", "perimeter_extrusion_width"},
+ {"SolidInfill", "solid_infill_extrusion_width"},
+ {"SupportMaterial", "support_material_extrusion_width"},// support material layer_height can go up/down depending on config.
+ {"SupportMaterialInterface", "support_material_extrusion_width"},//SupportMaterialInterface and SupportMaterialInterface shares same width calculations?
+ {"ThinWall", "thin_walls_min_width"},//not fully suported
+ {"TopSolidInfill", "top_infill_extrusion_width"},
+ {"FirstLayer", "first_layer_extrusion_width"}
+
+ };
+
+ std::unordered_map er_accel_ToOptionKey = {
+ {"InternalInfill", "infill_acceleration"},
+ {"BridgeInfill", "bridge_acceleration"},
+ {"ExternalPerimeter", "external_perimeter_acceleration"},
+ {"GapFill", "gap_fill_acceleration"},
+ {"InternalBridgeInfill", "internal_bridge_acceleration"},
+ {"Ironing", "ironing_acceleration"},
+ {"OverhangPerimeter", "overhangs_acceleration"},
+ {"Perimeter", "perimeter_acceleration"},
+ {"SolidInfill", "solid_infill_acceleration"},
+ {"SupportMaterial", "support_material_acceleration"},
+ {"SupportMaterialInterface", "support_material_interface_acceleration"},
+ {"ThinWall", "thin_walls_acceleration"},
+ {"TopSolidInfill", "top_solid_infill_acceleration"},
+ {"FirstLayer", "first_layer_acceleration"}
+ };
+
+ std::unordered_map er_spacing_ToOptionKey = {
+ {"InternalInfill", "infill_extrusion_spacing"},
+ //{"BridgeInfill", "placeholder"},
+ {"ExternalPerimeter", "external_perimeter_extrusion_spacing"},
+ //{"GapFill", "placeholder"},//special calc required for commented ones
+ //{"InternalBridgeInfill", "placeholder"},
+ //{"Ironing", "ironing_spacing"}, TOFIX? TYPE: coFloat
+ {"Ironing", "top_infill_extrusion_spacing"},
+ {"OverhangPerimeter", "external_perimeter_extrusion_spacing"},
+ {"Perimeter", "perimeter_extrusion_spacing"},
+ {"SolidInfill", "solid_infill_extrusion_spacing"},
+ {"SupportMaterial", "external_perimeter_extrusion_spacing"}, //TOFIX? TYPE: coFloat
+ {"SupportMaterialInterface", "external_perimeter_extrusion_spacing"}, //TOFIX? TYPE: coFloat
+ {"ThinWall", "external_perimeter_extrusion_spacing"}, //TOFIX?
+ {"TopSolidInfill", "top_infill_extrusion_spacing"},
+ {"FirstLayer", "first_layer_extrusion_spacing"}
+ };
+
+ std::unordered_map er_speed_ToOptionKey = {
+ {"InternalInfill", "infill_speed"},
+ {"BridgeInfill", "bridge_speed"},
+ {"ExternalPerimeter", "external_perimeter_speed"},
+ {"GapFill", "gap_fill_speed"},
+ {"InternalBridgeInfill", "internal_bridge_speed"},
+ {"Ironing", "ironing_speed"},
+ {"OverhangPerimeter", "overhangs_speed"},
+ {"Perimeter", "perimeter_speed"},
+ {"SolidInfill", "solid_infill_speed"},
+ {"SupportMaterial", "support_material_speed"},
+ {"SupportMaterialInterface", "support_material_interface_speed"},
+ {"ThinWall", "thin_walls_speed"},
+ {"TopSolidInfill", "top_solid_infill_speed"},
+ {"FirstLayer", "first_layer_speed"}
+ };
+
+
+ Plater* plat = this->main_frame->plater();
+ Model& model = plat->model();
+ if (!plat->new_project(L("Pressure calibration")))
+ return;
+
+ bool autocenter = gui_app->app_config->get("autocenter") == "1";
+ if (autocenter) {
+ //disable auto-center for this calibration.
+ gui_app->app_config->set("autocenter", "0");
+ }
+
+ std::vector items;
+ for (int i = 0; i < currentTestCount; i++) {
+ items.emplace_back((boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / "base_plate.3mf").string());
+ }
+ std::vector objs_idx = plat->load_files(items, true, false, false, false);
+ assert(objs_idx.size() == currentTestCount);
+ 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(*printer_config);
+ full_print_config.apply(*filament_config);
+
+ GCodeFlavor flavor = printer_config->option>("gcode_flavor")->value;
+ const ConfigOptionFloats* nozzle_diameter_config = printer_config->option("nozzle_diameter");
+ assert(nozzle_diameter_config->size() > 0);
+ double nozzle_diameter = nozzle_diameter_config->get_at(0);//get extruderID too?
+
+
+ double first_layer_height = full_print_config.get_computed_value("first_layer_height");
+ double first_layer_width = full_print_config.get_abs_value("first_layer_extrusion_width", nozzle_diameter);
+ double first_layer_spacing = full_print_config.get_abs_value("first_layer_extrusion_spacing", nozzle_diameter);
+ double first_layer_flow_ratio = full_print_config.get_computed_value("first_layer_flow_ratio");
+ double first_layer_size_compensation = full_print_config.get_computed_value("first_layer_size_compensation");
+ double infill_every_layers = full_print_config.get_computed_value("infill_every_layers");
+ double support_material_layer_height = full_print_config.get_computed_value("support_material_layer_height");
+
+ double base_layer_height = full_print_config.get_computed_value("layer_height");
+ double er_width = full_print_config.get_abs_value("solid_infill_extrusion_width", nozzle_diameter);
+ double er_accel = full_print_config.get_computed_value("solid_infill_acceleration");
+ double er_speed = full_print_config.get_computed_value("solid_infill_speed");
+ double er_spacing = full_print_config.get_abs_value("external_perimeter_extrusion_spacing",nozzle_diameter);
+ double thin_walls_min_width = full_print_config.get_abs_value("thin_walls_min_width", nozzle_diameter);
+
+ double default_er_width = full_print_config.get_abs_value("extrusion_width", nozzle_diameter);
+ double default_er_speed = full_print_config.get_computed_value("default_speed");
+ double default_er_accel = full_print_config.get_computed_value("default_acceleration");
+ double default_er_spacing = full_print_config.get_abs_value("extrusion_spacing", nozzle_diameter);
+ double spacing_ratio = full_print_config.get_computed_value("perimeter_overlap");
+ double spacing_ratio_external = full_print_config.get_computed_value("external_perimeter_overlap");
+ double filament_max_overlap = full_print_config.get_computed_value("filament_max_overlap",0);//maybe check for extruderID ?
+ const int extruder_count = wxGetApp().extruders_edited_cnt();
+ double combined_layer_height = infill_every_layers * base_layer_height;
+ double min_layer_height = full_print_config.get_computed_value("min_layer_height", extruder_count);
+ double max_layer_height = full_print_config.get_computed_value("max_layer_height", extruder_count);
+
+ bool infill_dense = full_print_config.get_bool("infill_dense");
+ if (combined_layer_height > nozzle_diameter){
+ combined_layer_height = nozzle_diameter;
+ }
+ Flow first_layer_flow = Flow::new_from_config(FlowRole::frPerimeter, *print_config, nozzle_diameter, first_layer_height, 1.f, true);
+ Flow base_flow = Flow::new_from_config(FlowRole::frExternalPerimeter, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);// used for switch statement, not fully coded yet.
+ double default_first_layer_width = first_layer_flow.width();
+ double default_first_layer_spacing = first_layer_flow.spacing();
+
+ bool defaults_broken = false;
+ if(default_er_width == 0 || default_er_spacing == 0){//if their default value config is broken fix it :)
+ Flow broken_config_flow = Flow::new_from_config(FlowRole::frExternalPerimeter, *print_config, nozzle_diameter, base_layer_height, spacing_ratio_external, false);
+ //default_er_width = broken_config_flow.width()
+ //default_er_spacing = broken_config_flow.spacing();// might work? or is it better to use nozzle diameter if config is broken?
+
+ default_er_width = nozzle_diameter;
+ default_er_spacing = default_er_width - base_layer_height * float(1. - 0.25 * PI) * spacing_ratio_external; //rounded_rectangle_extrusion_spacing
+ defaults_broken = true;
+ }
+ //what if defaults broken/not set for speed/accell too??
+
+
+ // --- translate ---
+ //bool autocenter = gui_app->app_config->get("autocenter") == "1";
+ bool has_to_arrange = plat->config()->opt_float("init_z_rotate") != 0;
+ has_to_arrange = true;
+
+
+ /*if (!autocenter) {
+ const ConfigOptionPoints* bed_shape = printer_config->option("bed_shape");
+ Vec2d bed_size = BoundingBoxf(bed_shape->values).size();
+ Vec2d bed_min = BoundingBoxf(bed_shape->values).min;
+ model.objects[objs_idx[0]]->translate({ bed_min.x() + bed_size.x() / 2, bed_min.y() + bed_size.y() / 2, 5 * xyzScale - 5 });
+ }*/
+
+
+ std::vector < std::vector> pressure_tower;
+ bool smooth_time = false;
+
+ std::string nozzle_diameter_str = std::to_string(nozzle_diameter);
+ nozzle_diameter_str.erase(nozzle_diameter_str.find_last_not_of('0') + 2, std::string::npos);
+
+
+ if (nozzle_diameter_str.back() == '.') {//if nozzle_diameter_str broke fix it by adding '0' to end, prob not needed?
+ nozzle_diameter_str += '0';
+ }
+
+ /*size_t decimal_pos = nozzle_diameter_str.find('.');
+ // some users might have 0.0x nozzle size. if that's the case then they should just need to create the file and it should load. ie; 90_bend_0.450.3mf
+ if (decimal_pos != std::string::npos) {
+ size_t non_zero_pos = nozzle_diameter_str.find_first_not_of('0', decimal_pos + 2);
+ nozzle_diameter_str.erase(non_zero_pos, std::string::npos);
+ }*/
+
+ std::string bend_90_nozzle_size_3mf = "90_bend_" + nozzle_diameter_str + ".3mf";
+ std::string extrusion_role = dynamicExtrusionRole[0]->GetValue().ToStdString();
+ double initial_model_height = 0.2;
+ //models is created per nozzles size 0.1-2mm walls are nozzle_size*4 thick
+ //exported origin point is center of the model in xyz
+ double initial_90_bend_x = 42.00; //size in x= 42.0 mm, model half x=21.0
+ double initial_90_bend_y = 21.0; //size in y= 21.0 mm, model half y=10.5
+ double initial_number_x = 2.0; //size in x= 2.0 mm , model half x=1.0
+ double initial_number_y = 4.0; //size in y= 4.0 mm , model half y=2.0
+ double initial_border_x = 1.6; //size in x= 1.6 mm , model half x=0.8
+ double initial_border_y = 21.0; //size in y= 21.0 mm, model half y=10.5
+ double initial_point_xy = 0.60; //size in xy= 0.6mm , model half xy=0.3 'point' model origin is bottom right offset x=0.7 y= -1.7(center of model +x1,y2 for bottom right edges)
+ double x_offset_90_bend = 1.2; //apex of 90° bend is offset from origin
+
+
+ int count_numbers = 0;
+ int count_borders = 0;
+ std::vector bend_90_positions;
+ std::vector number_positions;
+
+ for (int id_item = 0; id_item < currentTestCount; id_item++) {
+
+ count_numbers = 0;
+ count_borders = 0;
+ bend_90_positions.clear();
+ number_positions.clear();
+
+ auto pa_result = calc_PA_values(id_item);
+ std::vector pa_values = pa_result.first;
+ int count_increments = pa_result.second;
+ extrusion_role = dynamicExtrusionRole[id_item]->GetValue().ToStdString();
+ if (extrusion_role == "SupportMaterial" && support_material_layer_height != 0){
+ combined_layer_height = support_material_layer_height;
+ }
+ else if (extrusion_role == "InternalInfill" && infill_dense == false && infill_every_layers > 1){
+ combined_layer_height = infill_every_layers * base_layer_height;
+ }
+
+ /*
+ double first_pa = wxAtof(firstPaValue);
+ */
+
+ if (extrusion_role == "Verify") {
+ //count_increments = 13;
+ count_increments = sizeof(choice_extrusion_role) / sizeof(choice_extrusion_role[0]);
+ er_width = default_er_width;
+ er_spacing = default_er_spacing;
+ er_width = er_width * 100 / nozzle_diameter;
+ er_width = std::round(er_width * 100.0) / 100.0;
+
+ }
+ else{
+ /*bool enable_switch = false;
+ if(enable_switch == true){//still needs work :)
+ for (const std::string& role_str : choice_extrusion_role) {
+ ExtrusionRole extrusion_role = string_to_er_role(role_str);
+ FlowRole flow_role = string_to_flow_role(role_str);
+ double modified_layer_height = base_layer_height;
+ if (infill_every_layers > 1 && role_str == "InternalInfill" && infill_dense == false){
+ modified_layer_height = combined_layer_height;
+ }
+ else if (role_str == "SupportMaterial"){//this one might be tricky to do, since supports layerheight can go up/down based on config. maybe load 3 90_bend models for supports with low,high, middle layer heights
+ if (support_material_layer_height == 0){
+ double average_layer_height = (min_layer_height + max_layer_height) / 2;
+ modified_layer_height = average_layer_height;
+ }
+ else{
+ modified_layer_height = support_material_layer_height;
+ }
+ }
+ else if (role_str == "FirstLayer"){
+ modified_layer_height = first_layer_height;
+ }
+
+ switch (extrusion_role) {
+ case ExtrusionRole::erInternalInfill:
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, modified_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erBridgeInfill:// this will be tricky because bridges don't get any "layersquish" so the 90_bend model will have to have "empty" layers to help simulate a bridge
+ base_flow = Flow::new_from_width(float width, float nozzle_diameter, float height, float spacing_ratio, bool bridge = false);
+ //base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erExternalPerimeter:
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erGapFill:// i don't think i can adjust width/spacing for this one. only speed related config. unless i scale the 90_bend model wrong so it DOES get gap fill ? won't work for arachne, or will it ?
+ //base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erInternalBridgeInfill:
+ //base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, modified_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erIroning:
+ //base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, modified_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erOverhangPerimeter:
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erPerimeter:
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erSolidInfill:
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erSupportMaterial:
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, modified_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erSupportMaterialInterface:
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erThinWall://maybe scale the 90_bend models down so they get detected as thin_walls_min_width config ? this will result in a "single wall" 90_bend model hmmm..
+ //base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erTopSolidInfill:
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);
+ break;
+ case ExtrusionRole::erCustom://first_layer
+ base_flow = Flow::new_from_config(flow_role, *print_config, nozzle_diameter, modified_layer_height, 1.f, true);
+ break;
+ default:
+ base_flow = Flow::new_from_config(FlowRole::frExternalPerimeter, *print_config, nozzle_diameter, base_layer_height, filament_max_overlap, false);//unsupported roles.
+ continue;
+ }
+ break;
+ }
+ }*/
+
+ for (int i = 0; i < sizeof(choice_extrusion_role) / sizeof(choice_extrusion_role[0]); i++) {
+
+ if (er_width_ToOptionKey.find(extrusion_role) != er_width_ToOptionKey.end()) {
+
+ //look at maps to match speed/width ect to the selected ER role
+ er_width = print_config->get_abs_value(er_width_ToOptionKey[extrusion_role].c_str(), nozzle_diameter);
+ er_speed = full_print_config.get_computed_value(er_speed_ToOptionKey[extrusion_role].c_str());
+ er_accel = full_print_config.get_computed_value(er_accel_ToOptionKey[extrusion_role].c_str());
+ er_spacing = print_config->get_abs_value(er_spacing_ToOptionKey[extrusion_role].c_str(), nozzle_diameter);
+ first_layer_flow = Flow::new_from_config(FlowRole::frPerimeter, *print_config, nozzle_diameter, first_layer_height, 1.f, true);
+ first_layer_width = first_layer_flow.width();
+ first_layer_spacing = first_layer_flow.spacing();
+
+ //potential BUG if any of the values are 0 everything else would fail, pull the default value too and assign that
+ er_width = (er_width != 0) ? er_width : default_er_width;
+ er_speed = (er_speed != 0) ? er_speed : default_er_speed;
+ er_accel = (er_accel != 0) ? er_accel : default_er_accel;
+ er_spacing = (er_spacing != 0) ? er_spacing : default_er_spacing;
+ first_layer_width = (first_layer_width != 0) ? first_layer_width : first_layer_flow.width();
+ first_layer_spacing = (first_layer_spacing != 0) ? first_layer_spacing : first_layer_flow.spacing();
+
+ er_width = std::round((er_width * 100 / nozzle_diameter) * 100.0) / 100.0;
+ first_layer_width = std::round((first_layer_width * 100 / nozzle_diameter) * 100.0) / 100.0;
+
+ } else {
+ er_width = print_config->get_abs_value("solid_infill_extrusion_width", nozzle_diameter); //used for gapfill_width/bridges selection. TODO: add the bits for this here since gapfill/bridges need special calculations
+ er_width = std::round((er_width * 100 / nozzle_diameter) * 100.0) / 100.0;
+ first_layer_width = default_first_layer_width;
+ first_layer_spacing = default_first_layer_spacing;
+ //er_width = er_width * 100 / nozzle_diameter;
+ //er_width = std::round(er_width * 100.0) / 100.0;
+
+ }
+ }
+ if(defaults_broken == true){//if their config is broken fix it :)
+ default_er_width = nozzle_diameter;
+ default_er_spacing = default_er_width - base_layer_height * float(1. - 0.25 * PI) * spacing_ratio_external; //rounded_rectangle_extrusion_spacing
+ }
+ }
+
+
+ //-- magical scaling is done here :)
+ //the 90_bend models need to be scaled correctly so there is no 'gapfill' since gapfill will effect results.
+ double adjustment_factor = first_layer_flow.width() - first_layer_flow.spacing();
+
+ double xyzScale = nozzle_diameter / 0.4;
+ double er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, base_layer_height, er_spacing);
+ //double er_width_to_scale_first_layer = magical_scaling(nozzle_diameter, first_layer_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, first_layer_height, first_layer_spacing);//prob not needed?
+ double er_width_to_scale_first_layer_border = first_layer_flow.width() + 3 * first_layer_flow.spacing() + adjustment_factor;//total_width_with_overlap
+
+ if (infill_every_layers > 1 && extrusion_role == "InternalInfill" && infill_dense == false){
+ er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, combined_layer_height, er_spacing);
+ }
+ if (extrusion_role == "SupportMaterial" && support_material_layer_height != 0){
+ er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, combined_layer_height, er_spacing);
+ }
+
+ //-- magical scaling
+ pressure_tower.emplace_back();
+
+ double z_scaled_model_height = initial_model_height * (first_layer_height / initial_model_height); //mm
+ double xy_scaled_90_bend_x = initial_90_bend_x * er_width_to_scale; // mm
+ double xy_scaled_90_bend_y = initial_90_bend_y * er_width_to_scale; // mm
+ //double first_layer_xy_scaled_90_bend_x = initial_90_bend_x * er_width_to_scale_first_layer; // mm for 90_bend width scaled for first_layer prob not needed?
+ //double first_layer_xy_scaled_90_bend_y = initial_90_bend_y * er_width_to_scale_first_layer; // mm for 90_bend width scaled for first_layer prob not needed?
+ double xy_scaled_border_x = er_width_to_scale_first_layer_border; // mm
+ double xy_scaled_border_y = er_width_to_scale_first_layer_border; // mm
+ double xy_scaled_number_x = initial_number_x * xyzScale * er_width_to_scale; // mm
+ double xy_scaled_number_y = initial_number_y * xyzScale * er_width_to_scale; // mm
+ double xy_scaled_point_xy = initial_point_xy * xyzScale * er_width_to_scale; // mm
+
+
+ double thickness_offset = 0.0;
+ double bend_90_y_pos = 0.0;
+ double z_scale_90_bend = (first_layer_height + (base_layer_height * 4)) / initial_model_height;//force constant 5 layer height for model
+ double z_90_bend_pos = (first_layer_height + (base_layer_height * 4)) / 2;
+ double z_scale_others = first_layer_height / initial_model_height;
+ double z_others_pos = first_layer_height / 2;
+ std::set added_roles;
+
+ for (int nb_90_bends = 0; nb_90_bends < count_increments; nb_90_bends++) {
+ std::string er_role = extrusion_role;
+ double y_offset = 0.0;
+ bool role_found = false;
+
+ if (extrusion_role == "Verify") {
+ y_offset = 10.0 /* * nozzle_diameter*/;
+ for (size_t i = 0; i < sizeof(choice_extrusion_role) / sizeof(choice_extrusion_role[0]); i++) {
+ er_role = choice_extrusion_role[i];
+ if (er_width_ToOptionKey.find(er_role) != er_width_ToOptionKey.end() && added_roles.find(er_role) == added_roles.end()) {
+ added_roles.insert(er_role);
+ role_found = true;
+ break;
+ }
+ else{role_found = false;}//role not found and not currently supported by calibration tool.
+ }
+ } else {
+ role_found = (er_width_ToOptionKey.find(er_role) != er_width_ToOptionKey.end());
+ }
+
+ if (role_found == true) {
+ er_width = print_config->get_abs_value(er_width_ToOptionKey[er_role].c_str(), nozzle_diameter);
+ er_spacing = print_config->get_abs_value(er_spacing_ToOptionKey[er_role].c_str(), nozzle_diameter);
+
+ er_width = (er_width != 0) ? er_width : default_er_width;//found supported role but it has 0 value, need to give it defaults.
+ er_spacing = (er_spacing != 0) ? er_spacing : default_er_spacing;
+
+ } else {
+ er_width = default_er_width;
+ er_spacing = default_er_spacing;
+ }
+
+ er_width = std::round((er_width * 100 / nozzle_diameter) * 100.0) / 100.0;
+ er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, base_layer_height, er_spacing);
+
+ if (infill_every_layers > 1 && extrusion_role == "InternalInfill" && infill_dense == false){
+ er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, combined_layer_height, er_spacing);
+ z_90_bend_pos = (first_layer_height + (combined_layer_height * 5)) / 2;
+ z_scale_90_bend = (first_layer_height + (combined_layer_height * 5)) / initial_model_height;//force constant 6 layer height for model even if combing layers, needed for infill selected role
+ }
+ if (extrusion_role == "SupportMaterial" && support_material_layer_height != 0 ){
+ er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, combined_layer_height, er_spacing);
+ z_90_bend_pos = (first_layer_height + (combined_layer_height * 5)) / 2;
+ z_scale_90_bend = (first_layer_height + (combined_layer_height * 5)) / initial_model_height;//TOFIX: support material layer heights can change if its set to "0"
+ }
+
+
+ add_part(model.objects[objs_idx[id_item]],
+ (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / "scaled_with_nozzle_size" / bend_90_nozzle_size_3mf).string(),
+ Vec3d{ x_offset_90_bend, bend_90_y_pos , z_90_bend_pos },
+ /*scale*/Vec3d{ er_width_to_scale, er_width_to_scale, z_scale_90_bend }, false);
+
+ pressure_tower.back().push_back(model.objects[objs_idx[id_item]]);
+ Eigen::Vector3d modelPosition( x_offset_90_bend, bend_90_y_pos + y_offset , z_90_bend_pos );
+
+ // thickness offset that moves each '90_bend' model in Y
+ //thickness_offset = ((er_width / 100) * nozzle_diameter) * 4 + (nozzle_diameter * 2);// pretty tight gap
+ //thickness_offset = ((er_width / 100) * nozzle_diameter) * 4 + (nozzle_diameter * 2.5);
+ thickness_offset = ((er_width / 100) * nozzle_diameter) * 4 + (nozzle_diameter * 4);// larger gap
+
+ //thickness_offset = ((er_width / 100.0) * nozzle_diameter * xy_scaled_90_bend_y * 4) + (nozzle_diameter * 4);
+ //double scaled_thickness_offset = ((xy_scaled_90_bend_x - initial_90_bend_x) + (xy_scaled_90_bend_y - initial_90_bend_y));
+ //double real_offset = thickness_offset + scaled_thickness_offset;
+
+ /*thickness_offset = ((er_width / 100.0) * nozzle_diameter * 4) + (nozzle_diameter * 4);
+
+ double scaled_thickness_offset = thickness_offset * (((xy_scaled_90_bend_x / initial_90_bend_x) + (xy_scaled_90_bend_y / initial_90_bend_y)) / 2.0 - 1);
+ double real_offset = thickness_offset + scaled_thickness_offset;*/
+
+ bend_90_positions.push_back(modelPosition);
+ bend_90_y_pos = modelPosition.y() + thickness_offset;
+ //bend_90_y_pos = modelPosition.y() + real_offset;
+
+
+ }
+
+ for (int nb_bends = 0; nb_bends < count_increments;nb_bends++){
+
+ if(nb_bends == 1 && extrusion_role != "Verify") {//only load once. this only determines when the borders get loaded, keeping at top of list makes it easier to scroll down to. it can't be '0' since it needs the numbers positions!
+
+ Eigen::Vector3d bend_pos_first = bend_90_positions[0];
+ Eigen::Vector3d bend_pos_mid = bend_90_positions[count_increments/2];
+ Eigen::Vector3d bend_pos_last = bend_90_positions[count_increments-1];
+
+ Eigen::Vector3d number_pos_first = number_positions[0];
+ Eigen::Vector3d number_pos_mid = number_positions[0];
+ Eigen::Vector3d number_pos_last = number_positions[0];
+
+
+ if (!number_positions.empty()) {
+
+ for (size_t j = 0; j < number_positions.size(); j++) {
+ if (j == number_positions.size() / 2) {
+ number_pos_mid = number_positions[j];
+ }
+ number_pos_last = number_positions[j];
+ count_numbers++;
+ }
+ }
+
+ //TOFIX: on odd/uneven PA_values array results in the boreders being a little too short. this is mainly because i force load in the final end_pa value, cascades into loading extra 90_bend model.
+
+ double numbers_total_width = (number_pos_last.x() + (xy_scaled_number_x / 2)) - (number_pos_first.x() - (xy_scaled_number_x / 2));// scaled to include gap between end of 90_bend and first number,perfection
+ double total_height = (bend_pos_last.y() + (xy_scaled_90_bend_y / 2)) - (bend_pos_first.y() - (xy_scaled_90_bend_y / 2));
+ double scalred_r_border_x_mm = numbers_total_width + (nozzle_diameter * 2);
+ double left_border_x_offset = (bend_pos_mid.x() - (xy_scaled_90_bend_x/2) - nozzle_diameter + ( xy_scaled_border_x / 2) ) - (bend_pos_mid.x() - (xy_scaled_90_bend_x/2));//left border is positioned slightly inside the 90_bend model this is that distance.
+ double tb_total_width_mm = (xy_scaled_border_x - left_border_x_offset) + xy_scaled_90_bend_x + scalred_r_border_x_mm;
+
+ double scaled_l_border_x_percentage = xy_scaled_border_x / initial_border_x;
+ double scaled_r_border_x_percentage = (numbers_total_width + (nozzle_diameter * 2)) / initial_border_x ;
+ double scaled_lr_border_y_percentage = (total_height + xy_scaled_border_y) / initial_90_bend_y;
+ double scaled_tb_border_x_percentage = tb_total_width_mm / initial_border_x;
+ double scaled_tb_border_y_percentage = xy_scaled_border_y / initial_border_y;
+
+ double left_border_x_pos = bend_pos_mid.x() - (xy_scaled_90_bend_x/2) - nozzle_diameter;
+ double right_border_x_pos = bend_pos_mid.x() + (xy_scaled_90_bend_x / 2) + (scalred_r_border_x_mm / 2);
+
+ double left_edge_pos = bend_pos_mid.x() - (xy_scaled_90_bend_x / 2) - xy_scaled_border_x + left_border_x_offset;
+ double right_edge_pos = (xy_scaled_90_bend_x / 2) + scalred_r_border_x_mm + bend_pos_mid.x();
+ double center = (left_edge_pos + right_edge_pos) / 2;
+ double tb_border_x_pos = center;
+
+
+ add_part(model.objects[objs_idx[id_item]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / "pa_border.3mf").string(),
+ Vec3d{ left_border_x_pos , bend_pos_mid.y(), z_others_pos },
+ /*scale*/Vec3d{ scaled_l_border_x_percentage, scaled_lr_border_y_percentage, z_scale_others }, false);count_borders++; //Left border
+
+ add_part(model.objects[objs_idx[id_item]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / "pa_border.3mf").string(),
+ Vec3d{ right_border_x_pos , bend_pos_mid.y(), z_others_pos },
+ /*scale*/Vec3d{ scaled_r_border_x_percentage , scaled_lr_border_y_percentage , z_scale_others}, false);count_borders++; //right border
+
+
+ add_part(model.objects[objs_idx[id_item]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / "pa_border.3mf").string(),//on odd number of count_increments the bottom border is not joined to the side borders. fixing this bug will require
+ Vec3d{ tb_border_x_pos , bend_pos_first.y() - (xy_scaled_90_bend_y / 2) - (xy_scaled_border_y / 2) - nozzle_diameter, z_others_pos }, // adding more if/else statements to add the extra offset and apply this to all other calculations for the border scale and position.
+ /*scale*/Vec3d{ scaled_tb_border_x_percentage , scaled_tb_border_y_percentage, z_scale_others }, false);count_borders++; //bottom border
+ //----------
+ add_part(model.objects[objs_idx[id_item]], (boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / "pa_border.3mf").string(),
+ Vec3d{ tb_border_x_pos , bend_pos_last.y() + (xy_scaled_90_bend_y / 2) + (xy_scaled_border_y / 2) + nozzle_diameter, z_others_pos },
+ /*scale*/Vec3d{ scaled_tb_border_x_percentage, scaled_tb_border_y_percentage, z_scale_others}, false);count_borders++; //top border
+ // scale model in percentage from original models xy values!
+
+
+ if (id_item < 10){ //will break if max test count goes higher. ie currentTestCount
+ add_part(model.objects[objs_idx[id_item]],(boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / (std::to_string(id_item) + std::string(".3mf"))).string(),
+ Vec3d{ number_pos_mid.x(), bend_pos_first.y() - (xy_scaled_90_bend_y / 2) + (xy_scaled_number_y / 2), z_scaled_model_height },
+ /*scale*/Vec3d{ xyzScale * er_width_to_scale, xyzScale * er_width_to_scale, z_scale_others * 2 }, false);count_borders++; // currentTestCount identifer
+ }
+ }
+
+
+ if (extrusion_role != "Verify") {// possible to load the words for each ER role and slice the Er role next to it's 90_bend ?
+
+ if (nb_bends % 2 == 1){
+ continue;// Skip generating every second number
+ }
+
+ Eigen::Vector3d bend_90_pos = bend_90_positions[nb_bends];
+ std::string pa_values_string = std::to_string(pa_values[nb_bends]);
+
+ double xpos = bend_90_pos.x() + (xy_scaled_90_bend_x / 2) + (xy_scaled_number_x / 2) + nozzle_diameter;
+ //double ypos = bend_90_pos.y() + (xy_scaled_90_bend_y / 2) - (xy_scaled_number_y / 2)
+ double ypos = bend_90_pos.y() + (xy_scaled_90_bend_y / 2) - (xy_scaled_number_y / 2) + (nozzle_diameter * 3);
+ //double ypos = bend_90_pos.y() + (xy_scaled_90_bend_y / 2) - (xy_scaled_number_y / 2) + (er_width / 100 * 2);//TODO: perfect this position so it's centered with the notch on the 90_bend
+ // will need to calculate that number sizing/positioning to offset it by.
+
+ for (size_t j = 0; j < pa_values_string.length(); ++j) {//not sure how the code will respond with a positive array list? ie ; 100.2 this moves decimal point thus breaking the code from loading model since "..3mf" not a real file
+
+ if (pa_values_string[j] == '.') {
+ add_part(model.objects[objs_idx[id_item]],(boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / "point.3mf").string(),
+ Vec3d{ xpos - (xy_scaled_number_x / 2), ypos /* - xy_scaled_point_xy - xyzScale*/, z_scaled_model_height },// point gets moved to wrong position on all nozzle_sizes, guessing it's exported offset position doesn't get scaled with the model.
+ /*scale*/Vec3d{ xyzScale * er_width_to_scale, xyzScale + (xyzScale / 2), z_scale_others * 2 }, false);;
+ xpos -= (xy_scaled_number_x / 2);
+
+ } else if (std::isdigit(pa_values_string[j])) {
+ add_part(model.objects[objs_idx[id_item]],(boost::filesystem::path(Slic3r::resources_dir()) / "calibration" / "filament_pressure" / (pa_values_string[j] + std::string(".3mf"))).string(),
+ Vec3d{ xpos, ypos, z_scaled_model_height },// might need to re size the numbers a touch. they get marked as "thin walls"
+ /*scale*/Vec3d{ xyzScale * er_width_to_scale, xyzScale * er_width_to_scale, z_scale_others * 2 }, false);;//TOCHECK: if any numbers get gapfill
+ }
+
+ Eigen::Vector3d modelPosition(xpos + (xy_scaled_number_x / 2) + nozzle_diameter + (xy_scaled_number_x / 2), ypos, z_scaled_model_height);
+ number_positions.push_back(modelPosition);
+ xpos = modelPosition.x();
+ }
+ }
+ }
+ }
+
+ /// --- main config ---
+ // => settings that are for object or region should be added to the model (see below, in the for loop), not here
+ DynamicPrintConfig new_print_config = *print_config;
+ DynamicPrintConfig new_printer_config = *printer_config;
+ //check if setting any config values to 45° breaks it. or it might be the default value for rotation adding part?
+ new_print_config.set_key_value("avoid_crossing_perimeters", new ConfigOptionBool(false));
+ new_print_config.set_key_value("complete_objects", new ConfigOptionBool(false)); //true is required for multi tests on single plate?
+ new_print_config.set_key_value("first_layer_flow_ratio", new ConfigOptionPercent(100));
+ new_print_config.set_key_value("first_layer_size_compensation", new ConfigOptionFloat(0));
+ new_print_config.set_key_value("xy_inner_size_compensation", new ConfigOptionFloat(0));
+ new_print_config.set_key_value("xy_outer_size_compensation", new ConfigOptionFloat(0));
+ new_print_config.set_key_value("print_custom_variables", new ConfigOptionString("calibration_print"));//created this as an extra check for when generating gcode to not include "feature_gcode"
+ // unless i disable the "generate" button if the keywords are detected in the custom gcode ?
+
+
+ //assert(filament_temp_item_name.size() == nb_runs);
+ //assert(model.objects.size() == nb_runs);
+ assert(objs_idx.size() == currentTestCount);
+ for (int id_item = 0; id_item < currentTestCount; id_item++) {
+
+ auto pa_result = calc_PA_values(id_item);
+ std::vector pa_values = pa_result.first;
+ int count_increments = pa_result.second;
+
+ wxString firstPaValue = dynamicFirstPa[id_item]->GetValue();
+ double first_pa = wxAtof(firstPaValue);
+ smooth_time = dynamicEnableST[id_item]->GetValue();
+ extrusion_role = dynamicExtrusionRole[id_item]->GetValue().ToStdString();
+
+ if (extrusion_role == "Verify") {// have to keep it in range
+ count_increments = sizeof(choice_extrusion_role) / sizeof(choice_extrusion_role[0]);
+ }
+ if (extrusion_role == "SupportMaterial" && support_material_layer_height != 0){
+ combined_layer_height = support_material_layer_height;
+ }
+ else if (extrusion_role == "InternalInfill" && infill_dense == false && infill_every_layers > 1){
+ combined_layer_height = infill_every_layers * base_layer_height;
+ }
+
+ auto last_90_bend_scale = model.objects[objs_idx[id_item]]->volumes[count_increments]->get_scaling_factor();
+ Eigen::Vector3d bend_90_mesh = model.objects[objs_idx[id_item]]->volumes[count_increments]->mesh().size();
+ double model_height = bend_90_mesh.z() * last_90_bend_scale.z();
+
+ std::string set_first_layer_prefix = (gcfKlipper == flavor) ? "SET_PRESSURE_ADVANCE ADVANCE=" :
+ (gcfMarlinFirmware == flavor) ? "M900 K" :
+ (gcfRepRap == flavor) ? "M572 S" : "";
+ std::string region_prefix = "{if layer_z <= " + std::to_string(first_layer_height) + "}" + set_first_layer_prefix + std::to_string(first_pa) + "; first layer [layer_z] {endif}";
+
+ /*
+ gcfRepRap,
+ gcfSprinter,
+ gcfRepetier,
+ gcfTeacup,
+ gcfMakerWare,
+ gcfMarlinLegacy,
+ gcfMarlinFirmware,
+ gcfLerdge,
+ gcfKlipper,
+ gcfSailfish,
+ gcfMach3,
+ gcfMachinekit,
+ gcfSmoothie,
+ gcfNoExtrusion*/
+
+ // config modifers for the base model
+ model.objects[objs_idx[id_item]]->config.set_key_value("bottom_fill_pattern", new ConfigOptionEnum(ipMonotonicWGapFill));// ipConcentric or ipConcentricGapFill ?
+ model.objects[objs_idx[id_item]]->config.set_key_value("thin_walls", new ConfigOptionBool(true));
+ model.objects[objs_idx[id_item]]->config.set_key_value("bottom_solid_layers", new ConfigOptionInt(1));
+ model.objects[objs_idx[id_item]]->config.set_key_value("brim_width", new ConfigOptionFloat(0));
+ model.objects[objs_idx[id_item]]->config.set_key_value("external_perimeter_overlap", new ConfigOptionPercent(100));
+ model.objects[objs_idx[id_item]]->config.set_key_value("fill_density", new ConfigOptionPercent(0));
+ model.objects[objs_idx[id_item]]->config.set_key_value("gap_fill_enabled", new ConfigOptionBool(true)); //should be false?, enabled for testing
+ model.objects[objs_idx[id_item]]->config.set_key_value("min_width_top_surface", new ConfigOptionFloatOrPercent(0.0,false));
+ model.objects[objs_idx[id_item]]->config.set_key_value("only_one_perimeter_top", new ConfigOptionBool(false));
+ model.objects[objs_idx[id_item]]->config.set_key_value("only_one_perimeter_first_layer", new ConfigOptionBool(false));//, if borderers - right are scaled correctly there shouldn't be any gap fill in them. it would be nice to keep the *4 extrusion lines for the borders only.
+ model.objects[objs_idx[id_item]]->config.set_key_value("perimeter_overlap", new ConfigOptionPercent(100));
+ model.objects[objs_idx[id_item]]->config.set_key_value("seam_position", new ConfigOptionEnum(spRear)); //spRear or spCost //BUG: should be fixed in 2.7 merge/SS 2.5.59.7, when this is changed the "perimeters & shell" doesn't turn red indicating a change.
+ model.objects[objs_idx[id_item]]->config.set_key_value("top_solid_layers", new ConfigOptionInt(0));
+ model.objects[objs_idx[id_item]]->config.set_key_value("region_gcode", new ConfigOptionString(region_prefix + " \n" ));
+
+ int style = 2;
+ if (extrusion_role != "Verify") {//don't apply layer ranges to the main object for verify mode.
+ if(style == 1){//BUG:using this one "works" untill you clear the plate, and it gets stuck in a infinite loop trying to delete nodes, see line 781 of objectDataViewModel.cpp
+
+ if (infill_every_layers > 1 && extrusion_role == "InternalInfill" && infill_dense == false) {
+ ModelConfig range_conf;
+
+ range_conf.set_key_value("layer_height", new ConfigOptionFloatOrPercent(combined_layer_height, false));
+ model.objects[objs_idx[id_item]]->layer_config_ranges[std::pair(first_layer_height, 8)] = range_conf;
+
+ wxGetApp().obj_list()->layers_editing();
+ }
+ }
+ if(style == 2){
+ if (infill_every_layers > 1 && extrusion_role == "InternalInfill" && infill_dense == false) {
+
+ wxGetApp().obj_list()->layers_editing(id_item);//could prob use this same thing for the unsupported roles since they need a different layer_height/width
+ auto existing_range = model.objects[objs_idx[id_item]]->layer_config_ranges.find(std::pair(0.0f, 2.0f));// Find the default existing range {0.0f, 2.0f}
+
+ if (existing_range != model.objects[objs_idx[id_item]]->layer_config_ranges.end()) {
+ ModelConfig new_range_conf = existing_range->second;
+
+ new_range_conf.set_key_value("layer_height", new ConfigOptionFloatOrPercent(combined_layer_height, false));
+ model.objects[objs_idx[id_item]]->layer_config_ranges.erase(existing_range);
+ model.objects[objs_idx[id_item]]->layer_config_ranges[std::pair(first_layer_height, model_height + first_layer_height)] = new_range_conf;
+ }
+ }
+ if (extrusion_role == "SupportMaterial" && support_material_layer_height != 0 ){
+
+ wxGetApp().obj_list()->layers_editing(id_item);//could prob use this same thing for the unsupported roles since they need a different layer_height/width
+ auto existing_range = model.objects[objs_idx[id_item]]->layer_config_ranges.find(std::pair(0.0f, 2.0f));// Find the default existing range {0.0f, 2.0f}
+
+ if (existing_range != model.objects[objs_idx[id_item]]->layer_config_ranges.end()) {
+ ModelConfig new_range_conf = existing_range->second;
+
+ new_range_conf.set_key_value("layer_height", new ConfigOptionFloatOrPercent(combined_layer_height, false));
+ model.objects[objs_idx[id_item]]->layer_config_ranges.erase(existing_range);
+ model.objects[objs_idx[id_item]]->layer_config_ranges[std::pair(first_layer_height, model_height + first_layer_height)] = new_range_conf;
+ }
+ }
+ }
+ }
+ size_t num_part = 0;
+ const int extra_vol = 1;
+ std::set added_roles;
+ for (ModelObject* part : pressure_tower[id_item]) {//loop though each part/volume and assign the modifers for the 90_bend model.
+
+ std::string er_role = extrusion_role;
+ bool role_found = false;
+ if (extrusion_role == "Verify") {
+ for (size_t i = 0; i < sizeof(choice_extrusion_role) / sizeof(choice_extrusion_role[0]); i++) {
+ er_role = choice_extrusion_role[num_part];
+ if (er_width_ToOptionKey.find(er_role) != er_width_ToOptionKey.end() && added_roles.find(er_role) == added_roles.end()) {
+ //er_role = er_role;
+ added_roles.insert(er_role);
+ role_found = true;
+ break;
+ }
+ else{role_found = false;}//role not found and not currently supported by calibration tool.
+ }
+ } else {
+ role_found = (er_width_ToOptionKey.find(er_role) != er_width_ToOptionKey.end());
+ }
+
+ if (role_found == true /*&& defaults_broken == false*/) {
+ er_width = print_config->get_abs_value(er_width_ToOptionKey[er_role].c_str(), nozzle_diameter);
+ er_speed = full_print_config.get_computed_value(er_speed_ToOptionKey[er_role].c_str(), nozzle_diameter);
+ er_accel = full_print_config.get_computed_value(er_accel_ToOptionKey[er_role].c_str(), nozzle_diameter);
+ er_spacing = print_config->get_abs_value(er_spacing_ToOptionKey[er_role].c_str(), nozzle_diameter);
+
+ er_width = (er_width != 0) ? er_width : default_er_width;
+ er_speed = (er_speed != 0) ? er_speed : default_er_speed;
+ er_accel = (er_accel != 0) ? er_accel : default_er_accel;
+ er_spacing = (er_spacing != 0) ? er_spacing : default_er_spacing;
+
+
+ } else {
+ //instead of loading defaults for everything only load defaults for broken/unsupported values.
+ er_width = default_er_width;
+ er_speed = default_er_speed;
+ er_accel = default_er_accel;
+ er_spacing = default_er_spacing;
+
+ //er_width = print_config->get_abs_value(er_width_ToOptionKey[er_role].c_str(), nozzle_diameter);
+ er_speed = full_print_config.get_computed_value(er_speed_ToOptionKey[er_role].c_str(), nozzle_diameter);
+ er_accel = full_print_config.get_computed_value(er_accel_ToOptionKey[er_role].c_str(), nozzle_diameter);
+ //er_spacing = print_config->get_abs_value(er_spacing_ToOptionKey[er_role].c_str(), nozzle_diameter);
+
+ //er_width = (er_width != 0) ? er_width : default_er_width;
+ er_speed = (er_speed != 0) ? er_speed : default_er_speed;
+ er_accel = (er_accel != 0) ? er_accel : default_er_accel;
+ //er_spacing = (er_spacing != 0) ? er_spacing : default_er_spacing;
+
+ er_role = "defaults for " + er_role + " width spacing";
+ }
+ er_width = std::round((er_width * 100 / nozzle_diameter) * 100.0) / 100.0;
+
+ double er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, base_layer_height, er_spacing);
+ if (infill_every_layers > 1 && extrusion_role == "InternalInfill" && infill_dense == false) {
+ er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, combined_layer_height, er_spacing);
+ }
+ if (extrusion_role == "SupportMaterial" && support_material_layer_height != 0 ){
+ er_width_to_scale = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, combined_layer_height, er_spacing);
+ }
+ double er_width_to_scale_first_layer_match_base2 = magical_scaling(nozzle_diameter, er_width, filament_max_overlap, spacing_ratio, spacing_ratio_external, first_layer_height, first_layer_spacing);
+
+ double xy_scaled_90_bend_x = initial_90_bend_x * er_width_to_scale; // mm
+ double xy_scaled_90_bend_y = initial_90_bend_y * er_width_to_scale; // mm
+ double first_layer_xy_scaled_90_bend_x_match = initial_90_bend_x * er_width_to_scale_first_layer_match_base2; // mm for 90_bend width scaled for first_layer to match er role width
+ double first_layer_xy_scaled_90_bend_y_match = initial_90_bend_y * er_width_to_scale_first_layer_match_base2; // mm for 90_bend width scaled for first_layer to match er role width
+
+
+
+ /*double size_diff_x = xy_scaled_90_bend_x - first_layer_xy_scaled_90_bend_x_match;
+ double size_diff_y = xy_scaled_90_bend_y - first_layer_xy_scaled_90_bend_y_match;
+ double scaling_factor_x = size_diff_x / xy_scaled_90_bend_x;
+ double scaling_factor_y = size_diff_y / xy_scaled_90_bend_y;
+
+ double adjusted_first_layer_width_x2 = er_width * (1 + scaling_factor_x);
+ double adjusted_first_layer_width_y2 = er_width * (1 + scaling_factor_y);*/ //check if below is good before deleteing
+
+
+ double adjusted_first_layer_width_x = er_width * (1 + (xy_scaled_90_bend_x - first_layer_xy_scaled_90_bend_x_match) / xy_scaled_90_bend_x);
+ double adjusted_first_layer_width_y = er_width * (1 + (xy_scaled_90_bend_y - first_layer_xy_scaled_90_bend_y_match) / xy_scaled_90_bend_y);
+ double adjusted_first_average = (adjusted_first_layer_width_x + adjusted_first_layer_width_y) / 2;
+
+ std::string set_advance_prefix =
+ (gcfKlipper == flavor) ? (smooth_time ? "SET_PRESSURE_ADVANCE SMOOTH_TIME=" : "SET_PRESSURE_ADVANCE ADVANCE=") :
+ (gcfMarlinFirmware == flavor) ? "M900 K" :
+ (gcfRepRap == flavor) ? "M572 S" : "";
+
+
+ /// --- custom config ---
+ // config for the 90_bend model
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("first_layer_extrusion_width", new ConfigOptionFloatOrPercent(adjusted_first_average, true));//TODO: check if this is now perfect
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("perimeter_extrusion_width", new ConfigOptionFloatOrPercent(er_width, true));
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("external_perimeter_extrusion_width", new ConfigOptionFloatOrPercent(er_width, true));//TODO: check widths and ect breaks if any values are in mm/percentage
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("perimeter_speed", new ConfigOptionFloatOrPercent(er_speed, false));
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("external_perimeter_speed", new ConfigOptionFloatOrPercent(er_speed, false));
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("gap_fill_speed", new ConfigOptionFloatOrPercent(er_speed, false));
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("perimeter_acceleration", new ConfigOptionFloatOrPercent(er_accel, false));
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("external_perimeter_acceleration", new ConfigOptionFloatOrPercent(er_accel, false));
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("gap_fill_acceleration", new ConfigOptionFloatOrPercent(er_accel, false));
+
+ if (extrusion_role == "Verify") {
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("region_gcode", new ConfigOptionString(set_advance_prefix + " ; " + er_role ));//user manual type in values
+ //will need to adjust layerheight for infill,support, other er roles that needs a different layerheight for verify mode.
+
+ /*ModelConfig range_conf;
+ range_conf.set_key_value("layer_height", new ConfigOptionFloatOrPercent(combined_layer_height, false));
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->layer_config_ranges[std::pair(first_layer_height, 8)] = range_conf;
+
+ wxGetApp().obj_list()->layers_editing();
+ auto list = wxGetApp().obj_list();*/
+
+ /*if (infill_every_layers > 1 && extrusion_role == "InternalInfill" && infill_dense == false) {
+
+ wxGetApp().obj_list()->layers_editing(id_item);//could prob use this same thing for the unsupported roles since they need a different layer_height
+ auto existing_range = model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->layer_config_ranges.find(std::pair(0.0f, 2.0f));// Find the default existing range {0.0f, 2.0f}
+
+ if (existing_range != model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->layer_config_ranges.end()) {
+ ModelConfig new_range_conf = existing_range->second;
+
+ new_range_conf.set_key_value("layer_height", new ConfigOptionFloatOrPercent(combined_layer_height, false));
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->layer_config_ranges.erase(existing_range);
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->layer_config_ranges[std::pair(first_layer_height, model_height + first_layer_height)] = new_range_conf;
+ }
+ }
+ else if (extrusion_role == supports /ect){
+ }*/
+ }
+ else{
+ model.objects[objs_idx[id_item]]->volumes[num_part + extra_vol]->config.set_key_value("region_gcode", new ConfigOptionString(set_advance_prefix + std::to_string(pa_values[num_part]) + " ; " + er_role + "\n"));
+ }
+ num_part++;
+ //model.objects[objs_idx[id_item]]->ensure_on_bed(); // put at the correct z (kind of arrange-z)) shouldn't be needed though.
+ //model.objects[objs_idx[id_item]]->center_around_origin();
+ }
+
+
+ bool enable_region_gcode_for_numbers = false;// this still needa a bit of work, the first layer ends up getting messed up surfaces. might be a config thing?
+ // unless i need to change the numbers height and z position?
+ if (enable_region_gcode_for_numbers == true){
+ std::string set_advance_prefix = (gcfKlipper == flavor) ? (smooth_time ? "SET_PRESSURE_ADVANCE SMOOTH_TIME=" : "SET_PRESSURE_ADVANCE ADVANCE=") :
+ (gcfMarlinFirmware == flavor) ? "M900 K" :
+ (gcfRepRap == flavor) ? "M572 S" : "";
+
+ int pa_index = 0;
+ int nb_number = 0;
+
+ while (nb_number < number_positions.size()) {
+
+ // Skip borders or out-of-bounds or odd pa_index
+ if ((nb_number >= count_numbers && nb_number < count_numbers + count_borders) ||
+ num_part >= model.objects[objs_idx[id_item]]->volumes.size() ||
+ pa_index % 2 == 1) {
+ if (pa_index % 2 == 1) pa_index++; // increment pa_index to match how numbers are loaded
+ else {
+ num_part++;
+ nb_number++;
+ }
+ continue; // Skip to the next iteration same way numbers get loaded.
+ }
+
+ // Apply the PA value to the number set stays inline with 90_bend models
+ for (int number_set = 0; number_set < count_numbers; number_set++){
+ model.objects[objs_idx[id_item]]->volumes[number_set + num_part + extra_vol]->config.set_key_value(
+ "region_gcode",
+ new ConfigOptionString(set_advance_prefix + std::to_string(pa_values[pa_index]) + " ; "));
+
+ nb_number++;
+ }
+ pa_index++;
+ num_part += count_numbers;
+ }
+ }
+ }
+
+ //update plater
+ this->gui_app->get_tab(Preset::TYPE_FFF_PRINT)->load_config(new_print_config);
+ plat->on_config_change(new_print_config);
+ this->gui_app->get_tab(Preset::TYPE_PRINTER)->load_config(new_printer_config);
+ plat->on_config_change(new_printer_config);
+ //enable it later as a safeguard?, shouldn't be needed though.
+ //for (size_t obj_idx : objs_idx) { model.objects[obj_idx]->ensure_on_bed(); } // put at the correct z (kind of arrange-z))
+ //for (size_t obj_idx : objs_idx) { model.objects[obj_idx]->center_around_origin();}
+ plat->changed_objects(objs_idx);
+ this->gui_app->get_tab(Preset::TYPE_FFF_PRINT)->update_dirty();
+ this->gui_app->get_tab(Preset::TYPE_PRINTER)->update_dirty();
+ plat->is_preview_shown();
+ //update everything, easier to code.
+ ObjectList* obj = this->gui_app->obj_list();
+ obj->update_after_undo_redo();
+
+ // arrange if needed, after new settings, to take them into account
+ // BUG:(borders don't slice. with 2+ generated models.) after updating to 2.5.59.11 the generating 2+ models they have "sinking label" have to click "drop to bed" to resolve, clicking "arrange" doesn't fix issue. -fixed
+ if (has_to_arrange) {
+ //update print config (done at reslice but we need it here)
+ if (plat->printer_technology() == ptFFF)
+ plat->fff_print().apply(plat->model(), *plat->config());
+ std::shared_ptr fake_statusbar = std::make_shared();
+ ArrangeJob arranger(std::dynamic_pointer_cast(fake_statusbar), plat);
+ arranger.prepare_all();
+ arranger.process();
+ arranger.finalize();
+
+ /*ArrangeJob arranger(ArrangeJob::Full);
+ //Ctl ctl;
+ bool canceled = false; // Example value; adjust as necessary based on user input
+ std::exception_ptr e; // Exception handling
+
+ arranger.prepare_all();
+ //arranger.process(ctl);
+ arranger.finalize(canceled, e);
+ ArrangeJob();*/
+
+ }
+
+ if (extrusion_role != "Verify") {//don't auto slice so user can manual add PA values
+ plat->reslice(); //forces a slice of plater.
+ }
+
+ if (autocenter) {
+ //re-enable auto-center after this calibration.
+ gui_app->app_config->set("autocenter", "1");
+ }
+}
+
+double CalibrationPressureAdvDialog::magical_scaling(double nozzle_diameter, double er_width, double filament_max_overlap, double spacing_ratio, double spacing_ratio_external, double base_layer_height, double er_spacing) {
+
+ //assert(er_width > 1.0 && "er_width should be above 1.0 as it's a percentage value");
+ double xyzScale = nozzle_diameter / 0.4;
+ double er_width_decimal = er_width * nozzle_diameter / 100.0;//models are generated to be default width of x4 lines for the walls ie; 0.4mm nozzle is 1.6mm thick walls + extra for ER role widths
+ double er_width_to_scale = 1.0;
+ double overlap_ratio = 1;
+ if (filament_max_overlap) {
+ overlap_ratio = filament_max_overlap;
+ }
+
+ spacing_ratio = std::min(overlap_ratio * 0.5f, spacing_ratio_external / 2.0);
+ double new_scale_spacing = er_width_decimal - base_layer_height * float(1.0 - 0.25 * PI) * spacing_ratio;
+ double spacing_value = std::round((new_scale_spacing / nozzle_diameter) * 100); //spacing_value = Round((Spacing / Max Nozzle Diameter) * 100)
+ er_spacing = (std::round(spacing_value * 10000) / 10000) * 0.01;
+
+
+ if (xyzScale > 4) {
+ er_width_to_scale = 1.0;
+ } else {
+ er_width_to_scale = er_spacing - (nozzle_diameter / 2 * 0.01);//need to scale slightly under to help with models being correct TODO: test more configurations of nozzle sizes/layer heights
+ //if use has the 'wrong' min layer height for a nozzle size, the model will get filled with "gapfill" not a normal extrusion, need to test more for what variables 'break' it
+ }
+
+ return er_width_to_scale;
+}
+
+void CalibrationPressureAdvDialog::create_buttons(wxStdDialogButtonSizer* buttons) {
+
+ const DynamicPrintConfig* printer_config = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
+ GCodeFlavor flavor = printer_config->option>("gcode_flavor")->value;
+ const AppConfig* app_config = get_app_config();
+
+ bool dark_mode = app_config->get_bool("dark_color_mode");// i guss these can be set as global variables?
+ std::string user_color = app_config->get("color_dark");
+ wxColour text_color("#" + user_color);
+
+ std::string color_background = dark_mode ? "333233" : "ffffff";//dark grey and white. whats the offical dark mode color ?
+ wxColour background_color("#" + color_background);
+
+ std::string prefix = (gcfMarlinFirmware == flavor) ? " LA " : ((gcfKlipper == flavor || gcfRepRap == flavor) ? " PA " : "unsupported firmware type");
+
+
+
+ if (prefix != "unsupported firmware type") {
+
+ wxPanel* mainPanel = new wxPanel(this, wxID_ANY);
+ mainPanel->SetBackgroundColour(background_color);
+ mainPanel->Raise();
+
+ // Create a vertical sizer for the panel
+ wxBoxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);
+ mainPanel->SetSizer(panelSizer);
+
+ // Create the common controls sizer
+ wxBoxSizer* commonSizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxString number_of_runs[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };//setting this any higher will break loading the model for the ID
+ nbRuns = new wxComboBox(mainPanel, wxID_ANY, wxString{ "1" }, wxDefaultPosition, wxDefaultSize, 10, number_of_runs, wxCB_READONLY);
+ nbRuns->SetToolTip(_L("Select the number of tests to generate, max 6 is recommended due to bed size limits"));
+ nbRuns->SetSelection(0);
+ nbRuns->Bind(wxEVT_COMBOBOX, &CalibrationPressureAdvDialog::on_row_change, this);
+
+ wxStaticText* text_generate_count = new wxStaticText(mainPanel, wxID_ANY, _L("Number of" + prefix + "tests: "));
+ text_generate_count->SetForegroundColour(text_color);
+ commonSizer->Add(text_generate_count, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+ commonSizer->Add(nbRuns, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+
+ // Create a button for generating models
+ wxButton* generateButton = new wxButton(mainPanel, wxID_FILE1, _L("Generate"));
+ generateButton->Bind(wxEVT_BUTTON, &CalibrationPressureAdvDialog::create_geometry, this);
+ commonSizer->Add(generateButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+
+ commonSizer->AddSpacer(50);// move the close button to the right a little, or align it on the far right side?
+
+ wxButton* closeButton = new wxButton(mainPanel, wxID_CLOSE, _L("Close"));
+ closeButton->Bind(wxEVT_BUTTON, &CalibrationPressureAdvDialog::close_me_wrapper, this);
+ commonSizer->Add(closeButton, 0, wxALL, 5);
+
+ panelSizer->Add(commonSizer, 0, wxALL, 10);
+ dynamicSizer = new wxBoxSizer(wxVERTICAL);
+ panelSizer->Add(dynamicSizer, 1, wxEXPAND | wxALL, 5);
+ buttons->Add(mainPanel, 1, wxEXPAND | wxALL, 10);
+
+ currentTestCount = wxAtoi(nbRuns->GetValue());
+ create_row_controls(dynamicSizer, currentTestCount);
+ } else {
+
+ wxStaticText* incompatiable_text = new wxStaticText(this, wxID_ANY, _L(prefix));
+ incompatiable_text->SetForegroundColour(*wxRED); // Set the text color to red for the incompatiable firmware tpe
+ buttons->Add(incompatiable_text);
+ }
+}
+
+void CalibrationPressureAdvDialog::create_row_controls(wxBoxSizer* parentSizer, int row_count) {
+
+ const AppConfig* app_config = get_app_config();
+ bool dark_mode = app_config->get_bool("dark_color_mode");
+
+ std::string user_color_text = app_config->get("color_dark");
+ wxColour text_color("#" + user_color_text);
+
+ //
+ //wxArrayInt
+ //wxArrayDouble
+ //wxArrayDouble choices_first_layerPA[] = { 0.025, 0.030, 0.035, 0.040, 0.045, 0.050 };
+ wxString choices_first_layerPA[] = { "0.025", "0.030", "0.035", "0.040", "0.045", "0.050" };
+ wxString choices_start_PA[] = { "0.0", "0.010", "0.020", "0.030", "0.040", "0.050" };
+ wxString choices_end_PA[] = { "0.10", "0.20", "0.30", "0.40", "0.50", "0.60", "0.70", "0.80", "0.90", "1.00" };
+ wxString choices_increment_PA[] = { "0.0010", "0.0025", "0.0035", "0.005", "0.006", "0.007", "0.01", "0.1" };
+ wxString choices_extrusion_role[] = {
+ "InternalInfill", "BridgeInfill", "ExternalPerimeter", "GapFill", "InternalBridgeInfill",
+ "Ironing", "OverhangPerimeter", "Perimeter", "SolidInfill", "SupportMaterial",
+ "SupportMaterialInterface", "ThinWall", "TopSolidInfill", "FirstLayer", "Verify"
+ };
+ const DynamicPrintConfig* printer_config = this->gui_app->get_tab(Preset::TYPE_PRINTER)->get_config();
+ GCodeFlavor flavor = printer_config->option>("gcode_flavor")->value;
+ std::string prefix = (gcfMarlinFirmware == flavor) ? " LA " : ((gcfKlipper == flavor || gcfRepRap == flavor) ? " PA " : "unsupported firmware type");
+ //improvements: pull retraction value and auto select a better suited start/end value?
+ //
+ int current_selection = 2;//start selection at ExternalPerimeter
+
+ if (!dynamicExtrusionRole.empty()) {// If there's a previous selection, find the index of the last selected role
+ std::string last_selected_er_role = dynamicExtrusionRole[currentTestCount-1]->GetValue().ToStdString();
+ for (int j = 0; j < sizeof(choices_extrusion_role) / sizeof(choices_extrusion_role[0]); j++) {
+ if (choices_extrusion_role[j] == wxString(last_selected_er_role)) {
+ current_selection = j + 1;
+ break;
+ }
+ }
+ }
+ current_selection = std::min(current_selection, static_cast(sizeof(choices_extrusion_role) / sizeof(choices_extrusion_role[0]) - 1));
+
+ for (int i = 0; i < row_count; i++) {
+ wxBoxSizer* rowSizer = new wxBoxSizer(wxHORIZONTAL);
+
+ wxComboBox* firstPaCombo = new wxComboBox(parentSizer->GetContainingWindow(), wxID_ANY, wxString{ choices_first_layerPA[3] }, wxDefaultPosition, wxSize(80, -1), 6, choices_first_layerPA);
+ wxStaticText* text_first_l_prefix = new wxStaticText(parentSizer->GetContainingWindow(), wxID_ANY, _L("First Layers" + prefix + "value: "));
+ text_first_l_prefix->SetForegroundColour(text_color);
+ rowSizer->Add(text_first_l_prefix, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+ firstPaCombo->SetToolTip(_L("Select the" + prefix + "value to be used for the first layer only.\n(this gets added to 'before_layer_gcode' area)"));
+ rowSizer->Add(firstPaCombo, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+ dynamicFirstPa.push_back(firstPaCombo);
+
+ rowSizer->AddSpacer(15);
+
+ wxComboBox* startPaCombo = new wxComboBox(parentSizer->GetContainingWindow(), wxID_ANY, wxString{ choices_start_PA[0]}, wxDefaultPosition, wxSize(80, -1), 6, choices_start_PA);
+ wxStaticText* text_start_value = new wxStaticText(parentSizer->GetContainingWindow(), wxID_ANY, _L("Start value: "));
+ text_start_value->SetForegroundColour(text_color);
+ rowSizer->Add(text_start_value, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+ startPaCombo->SetToolTip(_L("Select the starting" + prefix + "value to be used.\n (you can manually type in values!)"));
+ startPaCombo->SetSelection(0);
+ rowSizer->Add(startPaCombo, 0, wxALIGN_CENTER_VERTICAL);
+ dynamicStartPa.push_back(startPaCombo);
+
+ rowSizer->AddSpacer(15);
+
+ wxComboBox* endPaCombo = new wxComboBox(parentSizer->GetContainingWindow(), wxID_ANY, wxString{ choices_end_PA[0] }, wxDefaultPosition, wxSize(80, -1), 10, choices_end_PA);
+ wxStaticText* text_end_value = new wxStaticText(parentSizer->GetContainingWindow(), wxID_ANY, _L("End value: "));
+ text_end_value->SetForegroundColour(text_color);
+ rowSizer->Add(text_end_value, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+ endPaCombo->SetToolTip(_L("Select the ending" + prefix + "value to be used.\n (you can manually type in values!)"));
+ endPaCombo->SetSelection(0);
+ rowSizer->Add(endPaCombo, 0, wxALIGN_CENTER_VERTICAL);
+ dynamicEndPa.push_back(endPaCombo);
+
+ rowSizer->AddSpacer(15);
+
+ wxComboBox* paIncrementCombo = new wxComboBox(parentSizer->GetContainingWindow(), wxID_ANY, wxString{ choices_increment_PA[3] }, wxDefaultPosition, wxSize(80, -1), 8, choices_increment_PA);
+ wxStaticText* text_increment = new wxStaticText(parentSizer->GetContainingWindow(), wxID_ANY, _L("Increment by: "));
+ text_increment->SetForegroundColour(text_color);
+ rowSizer->Add(text_increment, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+ paIncrementCombo->SetToolTip(_L("Select the incremental value.\n (you can manually type in values!)"));
+ paIncrementCombo->SetSelection(3);
+ rowSizer->Add(paIncrementCombo, 0, wxALIGN_CENTER_VERTICAL);
+ dynamicPaIncrement.push_back(paIncrementCombo);
+
+ rowSizer->AddSpacer(15);
+
+ wxComboBox* erPaCombo = new wxComboBox(parentSizer->GetContainingWindow(), wxID_ANY, wxString{ choices_extrusion_role[current_selection] }, wxDefaultPosition, wxSize(200, -1), 15, choices_extrusion_role, wxCB_READONLY);//disable user edit this one :)
+ wxStaticText* text_extrusion_role = new wxStaticText(parentSizer->GetContainingWindow(), wxID_ANY, _L("Extrusion role: "));
+ text_extrusion_role->SetForegroundColour(text_color);
+ rowSizer->Add(text_extrusion_role, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+ erPaCombo->SetToolTip(_L("Select the extrusion role you want to generate a calibration for"));
+ erPaCombo->SetSelection(current_selection);
+ rowSizer->Add(erPaCombo, 0, wxALIGN_CENTER_VERTICAL);
+ dynamicExtrusionRole.push_back(erPaCombo);
+
+ // Increment selection for the next row
+ current_selection++;
+ if (current_selection >= sizeof(choices_extrusion_role) / sizeof(choices_extrusion_role[0])) {
+ current_selection = 0; // Wrap around: SetSelection does it's own memory access checks so this shouldn't be needed. but it's a nice safe guard to have.
+ }
+
+ if (prefix == " PA ") {//klipper only feature ?
+ rowSizer->AddSpacer(15);
+ wxCheckBox* enableST = new wxCheckBox(parentSizer->GetContainingWindow(), wxID_ANY, _L(""), wxDefaultPosition, wxDefaultSize);
+ wxStaticText* text_smooth_time = new wxStaticText(parentSizer->GetContainingWindow(), wxID_ANY, _L("Smooth time: "));
+ text_smooth_time->SetForegroundColour(text_color);
+ rowSizer->Add(text_smooth_time, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
+ //enableST->SetToolTip(_L("Generate smooth time values"));
+ enableST->SetToolTip(_L("This parameter defines the duration over which extruder velocity changes are averaged, helping to smooth out rapid changes in extrusion pressure. Shorter times (e.g., 0.01 seconds) are beneficial for fast printing, while longer times (e.g., 0.4 seconds) are better for slower printing. The default value is 0.04 seconds."));
+ enableST->SetValue(false);
+ rowSizer->Add(enableST, 1, wxALIGN_CENTER_VERTICAL);
+ dynamicEnableST.push_back(enableST);
+ }
+
+ parentSizer->Add(rowSizer, 0, wxALL, 2);// change this to make each row have a larger/smaller 'gap' between them
+ dynamicRowcount.push_back(rowSizer);
+ }
+}
+
+void CalibrationPressureAdvDialog::on_row_change(wxCommandEvent& event) {
+ int new_test_count = wxAtoi(nbRuns->GetValue());
+
+ wxSize auto_size = GetSize();
+ //wxSize auto_size = DoGetBestSize();
+
+ if (new_test_count > currentTestCount) {
+ create_row_controls(dynamicSizer, new_test_count - currentTestCount);
+ } else if (new_test_count < currentTestCount) {
+ for (int i = currentTestCount - 1; i >= new_test_count; --i) {
+ wxBoxSizer* row = dynamicRowcount.back();
+ dynamicSizer->Detach(row);
+ row->Clear(true);
+ delete row;
+ dynamicRowcount.pop_back();
+ dynamicFirstPa.pop_back();
+ dynamicStartPa.pop_back();
+ dynamicEndPa.pop_back();
+ dynamicPaIncrement.pop_back();
+ dynamicExtrusionRole.pop_back();
+ dynamicEnableST.pop_back();
+ }
+ }
+
+ currentTestCount = new_test_count;
+ dynamicSizer->Layout();
+ this->Fit();
+
+ //this->SetSize(1600,600);
+ this->SetSize(auto_size); //makes GUI flash on updating
+
+}
+
+std::pair, int> CalibrationPressureAdvDialog::calc_PA_values(int id_item) {
+ wxString firstPaValue = dynamicFirstPa[id_item]->GetValue();
+ wxString startPaValue = dynamicStartPa[id_item]->GetValue();
+ wxString endPaValue = dynamicEndPa[id_item]->GetValue();
+ wxString paIncrementValue = dynamicPaIncrement[id_item]->GetValue();
+ wxString erPaValue = dynamicExtrusionRole[id_item]->GetValue();
+
+ double first_pa;
+ firstPaValue.ToDouble(&first_pa);
+
+ double start_pa;
+ startPaValue.ToDouble(&start_pa);
+ double end_pa;
+ endPaValue.ToDouble(&end_pa);
+ double pa_increment;
+ paIncrementValue.ToDouble(&pa_increment);
+
+ int countincrements = 0;
+ int sizeofarray = static_cast((end_pa - start_pa) / pa_increment) + 2;//'+2' needed for odd/even numbers
+ std::vector pa_values(sizeofarray);
+
+ double incremented_pa_value = start_pa;
+ while (incremented_pa_value <= end_pa + pa_increment / 2) {
+ if (incremented_pa_value <= end_pa) {
+ double rounded_pa = std::round(incremented_pa_value * 1000000.0) / 1000000.0;
+ pa_values[countincrements] = rounded_pa;
+ countincrements++;
+ incremented_pa_value += pa_increment;
+ } else {
+ pa_values[countincrements] = end_pa;
+ countincrements++;//failsafe if werid input numbers are provided that can't add the "ending pa" number to the array.
+ break;
+ }
+ }// is there a limit of how many models SS can load ? might be good to set a failsafe just so it won't load 10k+ models...
+
+ return std::make_pair(pa_values, countincrements);
+}
+
+void CalibrationPressureAdvDialog::close_me_wrapper(wxCommandEvent& event) {
+ this->close_me(event);
+}
+} // namespace GUI
+} // namespace Slic3r
+#pragma optimize("", on)
\ No newline at end of file
diff --git a/src/slic3r/GUI/CalibrationPressureAdvDialog.hpp b/src/slic3r/GUI/CalibrationPressureAdvDialog.hpp
new file mode 100644
index 00000000000..65f8b8ab0d6
--- /dev/null
+++ b/src/slic3r/GUI/CalibrationPressureAdvDialog.hpp
@@ -0,0 +1,46 @@
+#ifndef slic3r_GUI_CalibrationPressureAdvDialog_hpp_
+#define slic3r_GUI_CalibrationPressureAdvDialog_hpp_
+
+#include "CalibrationAbstractDialog.hpp"
+//pressure advance PressureAdv
+namespace Slic3r {
+namespace GUI {
+
+class CalibrationPressureAdvDialog : public CalibrationAbstractDialog
+{
+
+public:
+ CalibrationPressureAdvDialog(GUI_App* app, MainFrame* mainframe) : CalibrationAbstractDialog(app, mainframe, "Pressure calibration")
+ { create(boost::filesystem::path("calibration") / "filament_pressure", "filament_pressure.html", wxSize(1600, 600), true); Centre(wxBOTH); currentTestCount = 1; } //include_close_button = true
+ virtual ~CalibrationPressureAdvDialog(){ }
+
+ void close_me_wrapper(wxCommandEvent& event);
+
+
+protected:
+ void create_buttons(wxStdDialogButtonSizer* sizer) override;
+ void create_row_controls(wxBoxSizer* parent_sizer, int row_count);
+ void create_geometry(wxCommandEvent& event_args);
+ void on_row_change(wxCommandEvent& event);
+ std::pair, int> calc_PA_values(int id_item);
+ double magical_scaling(double, double, double, double, double, double, double );
+
+ //i've set choice boxes for now just to save me typing numbers in when i want to test it :)
+ wxComboBox* nbRuns;
+
+ std::vector dynamicFirstPa; //first layer PA -user manual entry
+ std::vector dynamicStartPa; //starting PA value -user manual entry
+ std::vector dynamicEndPa; //ending PA value -user manual entry
+ std::vector dynamicPaIncrement; //increment PA by this value -user manual entry~~ or have drop down box ?
+ std::vector dynamicExtrusionRole;//extrusion role Pressure/Linear Advance -user choice select
+ std::vector dynamicEnableST; // checkbox for "smooth_time" - klipper only feature?
+ std::vector dynamicRowcount; // To keep track of dynamically created rows
+
+ wxBoxSizer* dynamicSizer;
+ int currentTestCount;
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif
diff --git a/src/slic3r/GUI/CalibrationRetractionDialog.cpp b/src/slic3r/GUI/CalibrationRetractionDialog.cpp
index 44ea22a2d20..d4ed5b2f792 100644
--- a/src/slic3r/GUI/CalibrationRetractionDialog.cpp
+++ b/src/slic3r/GUI/CalibrationRetractionDialog.cpp
@@ -146,6 +146,7 @@ void CalibrationRetractionDialog::create_geometry(wxCommandEvent& event_args) {
double retraction_start = 0;
std::string str = temp_start->GetValue().ToStdString();
int temp = int((2 + filament_config->option("temperature")->get_at(0)) / 5) * 5;
+ int first_layer_temp = filament_config->option("first_layer_temperature")->get_at(0);
if (str.find_first_not_of("0123456789") == std::string::npos)
temp = std::atoi(str.c_str());
@@ -239,6 +240,7 @@ void CalibrationRetractionDialog::create_geometry(wxCommandEvent& event_args) {
current_obj->config.set_key_value("layer_height", new ConfigOptionFloat(nozzle_diameter / 2.));
//temp
current_obj->config.set_key_value("print_temperature", new ConfigOptionInt(int(temp - temp_decr * i)));
+ current_obj->config.set_key_value("print_first_layer_temperature", new ConfigOptionInt(first_layer_temp));
//set retraction override
const int mytemp = temp - temp_decr * i;
diff --git a/src/slic3r/GUI/CalibrationTempDialog.cpp b/src/slic3r/GUI/CalibrationTempDialog.cpp
index b76abb26ac9..49ec3c35c40 100644
--- a/src/slic3r/GUI/CalibrationTempDialog.cpp
+++ b/src/slic3r/GUI/CalibrationTempDialog.cpp
@@ -71,6 +71,7 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
// -- get temps
const ConfigOptionInts* temperature_config = filament_config->option("temperature");
+ const int first_layer_temperature = filament_config->option("temperature")->get_at(0);
assert(temperature_config->values.size() >= 1);
long nb_items_up = 1;
if (!nb_up->GetValue().ToLong(&nb_items_up)) {
@@ -160,6 +161,7 @@ void CalibrationTempDialog::create_geometry(wxCommandEvent& event_args) {
double firstChangeHeight = print_config->get_abs_value("first_layer_height", nozzle_diameter);
//model.custom_gcode_per_print_z.gcodes.emplace_back(CustomGCode::Item{ firstChangeHeight + nozzle_diameter/2, CustomGCode::Type::Custom, -1, "", "M104 S" + std::to_string(temperature) + " ; ground floor temp tower set" });
model.objects[objs_idx[0]]->config.set_key_value("print_temperature", new ConfigOptionInt(temperature));
+ model.objects[objs_idx[0]]->config.set_key_value("print_first_layer_temperature", new ConfigOptionInt(first_layer_temperature));
for (int16_t i = 1; i < nb_items; i++) {
model.custom_gcode_per_print_z.gcodes.emplace_back(CustomGCode::Item{ (i * 10 * xyzScale), CustomGCode::Type::Custom , -1, "", "M104 S" + std::to_string(temperature - i * step_temp) + " ; floor " + std::to_string(i) + " of the temp tower set" });
//str_layer_gcode += "\n{ elsif layer_z >= " + std::to_string(i * 10 * xyzScale) + " and layer_z <= " + std::to_string((1 + i * 10) * xyzScale) + " }\nM104 S" + std::to_string(temperature - (int8_t)nb_delta * 5 + i * 5);
diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp
index 62d3402a4bb..094cbf222d0 100644
--- a/src/slic3r/GUI/ConfigManipulation.cpp
+++ b/src/slic3r/GUI/ConfigManipulation.cpp
@@ -513,10 +513,11 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
"raft_layer_height", "raft_interface_layer_height"})
toggle_field(el, have_raft);
- //for default_extrusion_width/spacing, you need to ahve at least an extrusion_width with 0
+ //for default_extrusion_width/spacing, you need to have at least an extrusion_width with 0
bool have_default_width = config->option("first_layer_extrusion_width")->get_float() == 0 ||
(config->option("perimeter_extrusion_width")->get_float() == 0 && (have_perimeters || have_brim)) ||
(config->option("external_perimeter_extrusion_width")->get_float() == 0 && have_perimeters) ||
+ (config->option("first_layer_extrusion_width")->get_float() == 0 && have_perimeters) ||
(config->option("infill_extrusion_width")->get_float() == 0 && (have_infill || has_solid_infill)) ||
(config->option("solid_infill_extrusion_width")->get_float() == 0 && has_solid_infill) ||
(config->option("top_infill_extrusion_width")->get_float() == 0 && has_top_solid_infill) ||
@@ -524,6 +525,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
(config->option("skirt_extrusion_width")->get_float() == 0 && have_skirt);
toggle_field("extrusion_width", have_default_width);
toggle_field("extrusion_spacing", have_default_width);
+ toggle_field("first_layer_extrusion_width", have_perimeters);
+ toggle_field("first_layer_extrusion_spacing", have_perimeters);
bool has_PP_ironing = has_top_solid_infill && config->opt_bool("ironing");
for (auto el : { "ironing_type", "ironing_flowrate", "ironing_spacing", "ironing_angle" })
@@ -577,7 +580,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
toggle_field("support_material_acceleration", have_default_acceleration && (have_support_material || have_brim || have_skirt));
toggle_field("support_material_interface_acceleration", have_default_acceleration && have_support_material && have_support_interface);
toggle_field("brim_acceleration", have_default_acceleration && (have_brim || have_skirt));
- for (auto el : { "bridge_acceleration", "bridge_internal_acceleration", "overhangs_acceleration", "gap_fill_acceleration", "travel_acceleration", "travel_deceleration_use_target", "first_layer_acceleration" })
+ for (auto el : { "bridge_acceleration", "internal_bridge_acceleration", "overhangs_acceleration", "gap_fill_acceleration", "travel_acceleration", "travel_deceleration_use_target", "first_layer_acceleration" })
toggle_field(el, have_default_acceleration);
// for default speed, it needs at least a dependent field with a %
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 3af8dd5bea2..66f6881c74a 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -66,6 +66,7 @@
#include "CalibrationOverBridgeDialog.hpp"
#include "CalibrationTempDialog.hpp"
#include "CalibrationRetractionDialog.hpp"
+#include "CalibrationPressureAdvDialog.hpp"
#include "ConfigSnapshotDialog.hpp"
#include "CreateMMUTiledCanvas.hpp"
#include "FreeCADDialog.hpp"
@@ -1981,6 +1982,10 @@ void GUI_App::calibration_retraction_dialog()
{
change_calibration_dialog(nullptr, new CalibrationRetractionDialog(this, mainframe));
}
+void GUI_App::calibration_pressureadv_dialog()
+{
+ change_calibration_dialog(nullptr, new CalibrationPressureAdvDialog(this, mainframe));
+}
void GUI_App::freecad_script_dialog()
{
change_calibration_dialog(nullptr, new FreeCADDialog(this, mainframe));
diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp
index 3dc7f0c9081..25654af8e90 100644
--- a/src/slic3r/GUI/GUI_App.hpp
+++ b/src/slic3r/GUI/GUI_App.hpp
@@ -253,6 +253,7 @@ class GUI_App : public wxApp
void over_bridge_dialog();
void calibration_cube_dialog();
void calibration_retraction_dialog();
+ void calibration_pressureadv_dialog();
void freecad_script_dialog();
void tiled_canvas_dialog();
//void support_tuning(); //have to do multiple, in a submenu
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 2e0ff17f978..068d16b2f44 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -2282,7 +2282,7 @@ void ObjectList::layers_editing()
// set some default value
if (ranges.empty()) {
take_snapshot(_(L("Add Layers")));
- ranges[{ 0.0f, 2.0f }].assign_config(get_default_layer_config(obj_idx));
+ ranges[{ 0.0f, 2.0f }].assign_config(get_default_layer_config(obj_idx));//defaults here
}
// create layer root item
@@ -2300,6 +2300,39 @@ void ObjectList::layers_editing()
Expand(layers_item);
}
+void ObjectList::layers_editing(int obj_idx)
+{
+ wxDataViewItem item = m_objects_model->GetItemById(obj_idx);
+
+ if (!item)
+ return;
+
+ const wxDataViewItem obj_item = m_objects_model->GetTopParent(item);
+ wxDataViewItem layers_item = m_objects_model->GetLayerRootItem(obj_item);
+
+ if (!layers_item.IsOk())
+ {
+ t_layer_config_ranges& ranges = object(obj_idx)->layer_config_ranges;
+
+ if (ranges.empty()) {
+ take_snapshot(_(L("Add Layers")));
+ ranges[{ 0.0f, 2.0f }].assign_config(get_default_layer_config(obj_idx));
+ }
+
+ layers_item = add_layer_root_item(obj_item);
+ }
+
+ if (!layers_item.IsOk())
+ return;
+
+ wxGetApp().obj_layers()->reset_selection();
+ wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false);
+
+ select_item(layers_item);
+ Expand(layers_item);
+}
+
+
wxDataViewItem ObjectList::add_layer_root_item(const wxDataViewItem obj_item)
{
const int obj_idx = m_objects_model->GetIdByItem(obj_item);
diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp
index 51d69eaee52..24dd084fb34 100644
--- a/src/slic3r/GUI/GUI_ObjectList.hpp
+++ b/src/slic3r/GUI/GUI_ObjectList.hpp
@@ -268,6 +268,7 @@ class ObjectList : public wxDataViewCtrl
void split();
void merge(bool to_multipart_object);
void layers_editing();
+ void layers_editing(int obj_idx);
wxDataViewItem add_layer_root_item(const wxDataViewItem obj_item);
wxDataViewItem add_settings_item(wxDataViewItem parent_item, const DynamicPrintConfig* config);
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index ebe5517b58c..17fcc4312aa 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -1960,6 +1960,8 @@ void MainFrame::init_menubar_as_editor()
[this](wxCommandEvent&) { wxGetApp().filament_temperature_dialog(); });
append_menu_item(m_calibration_menu, wxID_ANY, _(L("Extruder retraction calibration")), _(L("Create a test print to help you to set your retraction length.")),
[this](wxCommandEvent&) { wxGetApp().calibration_retraction_dialog(); });
+ append_menu_item(m_calibration_menu, wxID_ANY, _(L("Pressure calibration")), _(L("Create a model for tuning Pressure Linear advance.")),
+ [this](wxCommandEvent&) { wxGetApp().calibration_pressureadv_dialog(); });
m_calibration_menu->AppendSeparator();
append_menu_item(m_calibration_menu, wxID_ANY, _(L("Bridge flow calibration")), _(L("Create a test print to help you to set your bridge flow ratio.")),
[this](wxCommandEvent&) { wxGetApp().bridge_tuning_dialog(); });
diff --git a/src/slic3r/GUI/ObjectDataViewModel.cpp b/src/slic3r/GUI/ObjectDataViewModel.cpp
index 6c126a5aee3..c072c1aa774 100644
--- a/src/slic3r/GUI/ObjectDataViewModel.cpp
+++ b/src/slic3r/GUI/ObjectDataViewModel.cpp
@@ -778,10 +778,17 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item)
// Delete all sub-items
int i = m_objects[id]->GetChildCount() - 1;
while (i >= 0) {
- Delete(wxDataViewItem(m_objects[id]->GetNthChild(i)));
+ Delete(wxDataViewItem(m_objects[id]->GetNthChild(i)));//gets stuck if 'layer_config_ranges' was called directly without it having the parent node.
i = m_objects[id]->GetChildCount() - 1;
}
m_objects.erase(it);
+
+ /*int i = m_objects[id]->GetChildCount() - 1;
+ while (i >= 0) {
+ Delete(wxDataViewItem(m_objects[id]->GetNthChild(i)));
+ --i; // Decrement manually after each delete
+ }
+ m_objects.erase(it);*/
}
if (id > 0) {
if(id == m_objects.size()) id--;
diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp
index 305e7b642a5..2b2937bbf90 100644
--- a/src/slic3r/GUI/PresetHints.cpp
+++ b/src/slic3r/GUI/PresetHints.cpp
@@ -108,7 +108,7 @@ std::string PresetHints::cooling_description(const Preset &preset_fil, const Pre
const int support_fan_speed = preset_fil.config.opt_int("support_material_fan_speed", 0) == 1 ? 0 : preset_fil.config.get_int("support_material_fan_speed");
const int supp_inter_fan_speed = preset_fil.config.opt_int("support_material_interface_fan_speed", 0) == 1 ? 0 : preset_fil.config.get_int("support_material_interface_fan_speed");
const int bridge_fan_speed = preset_fil.config.opt_int("bridge_fan_speed", 0) == 1 ? 0 : preset_fil.config.get_int("bridge_fan_speed");
- const int bridge_internal_fan_speed = preset_fil.config.opt_int("bridge_internal_fan_speed", 0) == 1 ? 0 : preset_fil.config.get_int("bridge_internal_fan_speed");
+ const int internal_bridge_fan_speed = preset_fil.config.opt_int("internal_bridge_fan_speed", 0) == 1 ? 0 : preset_fil.config.get_int("internal_bridge_fan_speed");
const int overhangs_fan_speed = preset_fil.config.opt_int("overhangs_fan_speed", 0) == 1 ? 0 : preset_fil.config.get_int("overhangs_fan_speed");
const int gap_fill_fan_speed = preset_fil.config.opt_int("gap_fill_fan_speed", 0) == 1 ? 0 : preset_fil.config.get_int("gap_fill_fan_speed");
const int disable_fan_first_layers = preset_fil.config.opt_int("disable_fan_first_layers", 0);
@@ -133,7 +133,7 @@ std::string PresetHints::cooling_description(const Preset &preset_fil, const Pre
format_simple_fan_min_speed(out, min_fan_speed, default_fan_speed, _L("Solid surfaces"), solid_fan_speed);
format_simple_fan_speed(out, min_fan_speed, default_fan_speed, _L("Top surfaces"), top_fan_speed);
format_double_fan_min_speed(out, min_fan_speed, default_fan_speed, _L("Supports"), support_fan_speed, _L("Support interfaces"), supp_inter_fan_speed);
- format_double_fan_speed(out, min_fan_speed, default_fan_speed, _L("Bridges"), bridge_fan_speed, _L("Internal bridges"), bridge_internal_fan_speed);
+ format_double_fan_speed(out, min_fan_speed, default_fan_speed, _L("Bridges"), bridge_fan_speed, _L("Internal bridges"), internal_bridge_fan_speed);
format_simple_fan_min_speed(out, min_fan_speed, default_fan_speed, _L("Perimeter overhangs"), overhangs_fan_speed);
format_simple_fan_min_speed(out, min_fan_speed, default_fan_speed, _L("Gap fills"), gap_fill_fan_speed);
@@ -160,7 +160,7 @@ std::string PresetHints::cooling_description(const Preset &preset_fil, const Pre
surface_list += ",";
surface_list += _L("Bridges");
}
- if (bridge_internal_fan_speed > 0) {
+ if (internal_bridge_fan_speed > 0) {
surface_list += ",";
surface_list += _L("Internal bridges");
}
@@ -243,7 +243,7 @@ std::string PresetHints::cooling_description(const Preset &preset_fil, const Pre
out += "\n\n" + _L("! 1 for the External perimeters fan speed is Deprecated, please set it to 0 to stop the fan!");
if (preset_fil.config.opt_int("bridge_fan_speed", 0) == 1)
out += "\n\n" + _L("! 1 for the Bridge fan speed is Deprecated, please set it to 0 to stop the fan!");
- if (preset_fil.config.opt_int("bridge_internal_fan_speed", 0) == 1)
+ if (preset_fil.config.opt_int("internal_bridge_fan_speed", 0) == 1)
out += "\n\n" + _L("! 1 for the Infill bridge fan speed is Deprecated, please set it to 0 to stop the fan!");
return out.ToStdString();