1084{
1085
1087
1088 if (! print.config().gcode_substitutions.values.empty()) {
1091 }
1092
1093
1098#if ENABLE_GCODE_VIEWER_DATA_CHECKING
1099 m_last_mm3_per_mm = 0.;
1100#endif
1101
1102
1103
1105 if (print.config().complete_objects.value) {
1106
1107 for (auto object : print.objects()) {
1108 std::vector<coordf_t> zs;
1109 zs.reserve(object->layers().size() + object->support_layers().size());
1110 for (
auto layer : object->layers())
1111 zs.push_back(
layer->print_z);
1112 for (
auto layer : object->support_layers())
1113 zs.push_back(
layer->print_z);
1114 std::sort(zs.begin(), zs.end());
1115 m_layer_count += (
unsigned int)(object->instances().size() * (std::unique(zs.begin(), zs.end()) - zs.begin()));
1116 }
1117 }
1118 print.throw_if_canceled();
1119
1122
1124 print.throw_if_canceled();
1125
1126 if (print.config().spiral_vase.value)
1128
1129 if (print.config().max_volumetric_extrusion_rate_slope_positive.value > 0 ||
1130 print.config().max_volumetric_extrusion_rate_slope_negative.value > 0)
1133
1134 if (print.config().avoid_crossing_curled_overhangs){
1136 }
1137
1138
1140
1141
1142
1143 if (const auto [thumbnails, thumbnails_format] = std::make_pair(
1144 print.full_print_config().option<ConfigOptionPoints>("thumbnails"),
1145 print.full_print_config().option<ConfigOptionEnum<GCodeThumbnailsFormat>>("thumbnails_format"));
1146 thumbnails)
1149 [&file](
const char* sz) { file.write(sz); },
1150 [&print]() { print.throw_if_canceled(); });
1151
1152
1153 {
1154 std::list<std::string> lines;
1155 boost::split(lines, print.config().notes.value, boost::is_any_of("\n"), boost::token_compress_off);
1156 for (auto line : lines) {
1157
1158 if (! line.empty() && line.back() == '\r')
1159 line.pop_back();
1160 file.write_format("; %s\n", line.c_str());
1161 }
1162 if (! lines.empty())
1163 file.write("\n");
1164 }
1165 print.throw_if_canceled();
1166
1167
1168 const PrintObject *first_object = print.objects().front();
1169 const double layer_height = first_object->config().layer_height.value;
1170 assert(! print.config().first_layer_height.percent);
1171 const double first_layer_height = print.config().first_layer_height.value;
1172 for (size_t region_id = 0; region_id < print.num_print_regions(); ++ region_id) {
1173 const PrintRegion ®ion = print.get_print_region(region_id);
1175 file.write_format(
"; perimeters extrusion width = %.2fmm\n", region.flow(*first_object,
frPerimeter,
layer_height).width());
1176 file.write_format(
"; infill extrusion width = %.2fmm\n", region.flow(*first_object,
frInfill,
layer_height).width());
1177 file.write_format(
"; solid infill extrusion width = %.2fmm\n", region.flow(*first_object,
frSolidInfill,
layer_height).width());
1179 if (print.has_support_material())
1181 if (print.config().first_layer_extrusion_width.value > 0)
1182 file.write_format(
"; first layer extrusion width = %.2fmm\n", region.flow(*first_object,
frPerimeter, first_layer_height,
true).width());
1183 file.write_format("\n");
1184 }
1185 print.throw_if_canceled();
1186
1187
1188 if (print.config().remaining_times.value)
1190
1191
1192 file.find_replace_enable();
1193
1194
1198
1201
1202
1203
1204 ToolOrdering tool_ordering;
1205 unsigned int initial_extruder_id = (unsigned int)-1;
1206 unsigned int final_extruder_id = (unsigned int)-1;
1207 bool has_wipe_tower = false;
1208 std::vector<const PrintInstance*> print_object_instances_ordering;
1209 std::vector<const PrintInstance*>::const_iterator print_object_instance_sequential_active;
1210 if (print.config().complete_objects.value) {
1211
1213
1214
1215 print_object_instance_sequential_active = print_object_instances_ordering.begin();
1216 for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++ print_object_instance_sequential_active) {
1217 tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id);
1218 if ((initial_extruder_id = tool_ordering.first_extruder()) != static_cast<unsigned int>(-1))
1219 break;
1220 }
1221 if (initial_extruder_id == static_cast<unsigned int>(-1))
1222
1223 throw Slic3r::SlicingError(
_u8L(
"No extrusions were generated for objects."));
1224
1225
1227 } else {
1228
1229
1230 tool_ordering = print.tool_ordering();
1231 tool_ordering.assign_custom_gcodes(print);
1232 if (tool_ordering.all_extruders().empty())
1233
1234 throw Slic3r::SlicingError(
_u8L(
"No extrusions were generated for objects."));
1235 has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower();
1236 initial_extruder_id = (has_wipe_tower && ! print.config().single_extruder_multi_material_priming) ?
1237
1238 tool_ordering.all_extruders().back() :
1239
1240 tool_ordering.first_extruder();
1241
1242
1244
1247 }
1248 if (initial_extruder_id == (unsigned int)-1) {
1249
1250 initial_extruder_id = 0;
1251 final_extruder_id = 0;
1252 } else {
1253 final_extruder_id = tool_ordering.last_extruder();
1254 assert(final_extruder_id != (unsigned int)-1);
1255 }
1256 print.throw_if_canceled();
1257
1260
1261
1263
1264
1266
1270
1272
1274
1276 this->
placeholder_parser().
set(
"has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming);
1277 this->
placeholder_parser().
set(
"total_toolchanges", std::max(0, print.wipe_tower_data().number_of_toolchanges));
1278 {
1279 BoundingBoxf bbox(print.config().bed_shape.values);
1283 }
1284 {
1285
1286
1287
1288
1289
1290 auto pts = std::make_unique<ConfigOptionPoints>();
1291 pts->values.reserve(print.first_layer_convex_hull().size());
1292 for (
const Point &pt : print.first_layer_convex_hull().points)
1293 pts->values.emplace_back(
unscale(pt));
1294 BoundingBoxf bbox(pts->values);
1300
1301
1302
1303
1304 std::vector<unsigned char> is_extruder_used(std::max(size_t(255), print.config().nozzle_diameter.size()), 0);
1305 for (unsigned int extruder_id : tool_ordering.all_extruders())
1306 is_extruder_used[extruder_id] = true;
1308 }
1309
1310
1312
1313 std::string start_gcode = this->
placeholder_parser_process(
"start_gcode", print.config().start_gcode.value, initial_extruder_id);
1314
1316
1318
1319
1321
1322
1323 file.writeln(start_gcode);
1324
1326 print.throw_if_canceled();
1327
1328
1330
1331 print.throw_if_canceled();
1332
1333
1334 std::function<
void(
void)> throw_if_canceled_func = [&print]() { print.throw_if_canceled();};
1336
1337 if (! (has_wipe_tower && print.config().single_extruder_multi_material_priming)) {
1338
1339
1340 file.write(this->
set_extruder(initial_extruder_id, 0.));
1341 }
1342
1343
1344 if (print.config().complete_objects.value) {
1345 size_t finished_objects = 0;
1346 const PrintObject *prev_object = (*print_object_instance_sequential_active)->print_object;
1347 for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++ print_object_instance_sequential_active) {
1348 const PrintObject &object = *(*print_object_instance_sequential_active)->print_object;
1349 if (&object != prev_object || tool_ordering.first_extruder() != final_extruder_id) {
1350 tool_ordering = ToolOrdering(object, final_extruder_id);
1351 unsigned int new_extruder_id = tool_ordering.first_extruder();
1352 if (new_extruder_id == (unsigned int)-1)
1353
1354 continue;
1355 initial_extruder_id = new_extruder_id;
1356 final_extruder_id = tool_ordering.last_extruder();
1357 assert(final_extruder_id != (unsigned int)-1);
1358 }
1359 print.throw_if_canceled();
1361 if (finished_objects > 0) {
1362
1363
1369
1371
1372
1373
1376
1380 }
1381
1384
1385
1386
1388 ++ finished_objects;
1389
1390
1392 prev_object = &object;
1393 }
1394 } else {
1395
1396
1398
1399 if (has_wipe_tower && ! layers_to_print.empty()) {
1400 m_wipe_tower.reset(
new WipeTowerIntegration(print.config(), *print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get()));
1402 if (print.config().single_extruder_multi_material_priming) {
1404
1406 coordf_t twolayers_printz = ((layers_to_print.size() == 1) ? layers_to_print.front() : layers_to_print[1]).first +
EPSILON;
1407 for (const PrintObject *print_object : print.objects())
1411 bbox_prime.offset(0.5f);
1412 bool overlap = bbox_prime.overlap(bbox_print);
1413
1416 file.write("M300 S800 P500\n");
1417 if (overlap) {
1418
1419 file.write("M1 Remove priming towers and click button.\n");
1420 } else {
1421
1422
1423 file.write("M1 S10\n");
1424 }
1425 } else {
1426
1427
1428 if (overlap) {
1430 _u8L(
"Your print is very close to the priming regions. "
1431 "Make sure there is no collision."));
1432 } else {
1433
1434 }
1435
1436 }
1437 }
1438 print.throw_if_canceled();
1439 }
1440
1441
1442
1443 this->
process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file);
1445
1447 }
1448
1449
1452
1453
1455
1456
1457 {
1462 if (print.config().single_extruder_multi_material) {
1463
1465 config.set_key_value(
"filament_extruder_id",
new ConfigOptionInt(extruder_id));
1467 } else {
1468 for (
const std::string &
end_gcode : print.
config().end_filament_gcode.values) {
1469 int extruder_id = (
unsigned int)(&
end_gcode - &print.config().end_filament_gcode.values.front());
1470 config.set_key_value(
"filament_extruder_id",
new ConfigOptionInt(extruder_id));
1472 }
1473 }
1475 }
1478
1479
1480
1481 file.find_replace_supress();
1482
1483
1484 if (print.config().remaining_times.value)
1486
1487 print.throw_if_canceled();
1488
1489
1491
1492 has_wipe_tower, print.wipe_tower_data(),
1493 this->config(),
1495 initial_extruder_id,
1496
1497 print.m_print_statistics));
1498 file.write("\n");
1499 file.write_format("; total filament used [g] = %.2lf\n", print.m_print_statistics.total_weight);
1500 file.write_format("; total filament cost = %.2lf\n", print.m_print_statistics.total_cost);
1501 if (print.m_print_statistics.total_toolchanges > 0)
1502 file.write_format("; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges);
1504
1505
1506
1507 {
1508 file.write("\n; prusaslicer_config = begin\n");
1509 std::string full_config;
1511 if (!full_config.empty())
1512 file.write(full_config);
1513 file.write("; prusaslicer_config = end\n");
1514 }
1515 print.throw_if_canceled();
1516}
#define _u8L(s)
macro used to mark string used at localization, return same string
Definition SLAPrint.cpp:29
void use_external_mp_once()
Definition AvoidCrossingPerimeters.hpp:20
void disable_once()
Definition AvoidCrossingPerimeters.hpp:22
unsigned int id() const
Definition Extruder.hpp:17
std::unique_ptr< WipeTowerIntegration > m_wipe_tower
Definition GCode.hpp:421
void print_machine_envelope(GCodeOutputStream &file, Print &print)
Definition GCode.cpp:1797
GCodeProcessor m_processor
Definition GCode.hpp:435
std::string set_extruder(unsigned int extruder_id, double print_z)
Definition GCode.cpp:3316
std::string preamble()
Definition GCode.cpp:2618
friend class WipeTowerIntegration
Definition GCode.hpp:447
float m_max_layer_z
Definition GCode.hpp:408
GCodeWriter m_writer
Definition GCode.hpp:345
std::unique_ptr< GCodeFindReplace > m_find_replace
Definition GCode.hpp:419
void set_origin(const Vec2d &pointf)
Definition GCode.cpp:2606
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment)
Definition GCode.cpp:3169
static void append_full_config(const Print &print, std::string &str)
Definition GCode.cpp:2572
std::string placeholder_parser_process(const std::string &name, const std::string &templ, unsigned int current_extruder_id, const DynamicConfig *config_override=nullptr)
Definition GCode.cpp:1683
float m_last_height
Definition GCode.hpp:406
void apply_print_config(const PrintConfig &print_config)
Definition GCode.cpp:2565
std::unique_ptr< SpiralVase > m_spiral_vase
Definition GCode.hpp:418
PlaceholderParser & placeholder_parser()
Definition GCode.hpp:176
std::string retract(bool toolchange=false)
Definition GCode.cpp:3290
void set_extruders(const std::vector< unsigned int > &extruder_ids)
Definition GCode.cpp:2593
float m_last_layer_z
Definition GCode.hpp:407
FullPrintConfig m_config
Definition GCode.hpp:342
void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait)
Definition GCode.cpp:1880
struct Slic3r::GCode::PlaceholderParserIntegration m_placeholder_parser_integration
AvoidCrossingPerimeters m_avoid_crossing_perimeters
Definition GCode.hpp:379
GCodeWriter & writer()
Definition GCode.hpp:174
SeamPlacer m_seam_placer
Definition GCode.hpp:334
const FullPrintConfig & config() const
Definition GCode.hpp:172
static ObjectsLayerToPrint collect_layers_to_print(const PrintObject &object)
Definition GCode.cpp:547
OozePrevention m_ooze_prevention
Definition GCode.hpp:377
std::unique_ptr< CoolingBuffer > m_cooling_buffer
Definition GCode.hpp:417
std::unique_ptr< PressureEqualizer > m_pressure_equalizer
Definition GCode.hpp:420
void process_layers(const Print &print, const ToolOrdering &tool_ordering, const std::vector< const PrintInstance * > &print_object_instances_ordering, const std::vector< std::pair< coordf_t, ObjectsLayerToPrint > > &layers_to_print, GCodeOutputStream &output_stream)
Definition GCode.cpp:1521
const Layer * layer() const
Definition GCode.hpp:173
void _print_first_layer_bed_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait)
Definition GCode.cpp:1858
JPSPathFinder m_avoid_crossing_curled_overhangs
Definition GCode.hpp:380
static const std::string & reserved_tag(ETags tag)
Definition GCodeProcessor.hpp:186
@ First_Line_M73_Placeholder
@ Estimated_Printing_Time_Placeholder
@ Last_Line_M73_Placeholder
const std::vector< Extruder > & extruders() const
Definition GCodeWriter.hpp:34
Extruder * extruder()
Definition GCodeWriter.hpp:26
std::string postamble() const
Definition GCodeWriter.cpp:80
static std::string set_fan(const GCodeFlavor gcode_flavor, bool gcode_comments, unsigned int speed)
Definition GCodeWriter.cpp:503
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100=false) const
Definition GCodeWriter.cpp:207
std::string travel_to_z(double z, const std::string &comment=std::string())
Definition GCodeWriter.cpp:305
Vec3d get_position() const
Definition GCodeWriter.hpp:75
void init_bed_shape(const Points &bed_shape)
Definition JumpPointSearch.hpp:29
std::mt19937 rng
Definition PlaceholderParser.hpp:23
void set(const std::string &key, const std::string &value)
Definition PlaceholderParser.hpp:44
DynamicConfig & config_writable()
Definition PlaceholderParser.hpp:53
std::unique_ptr< DynamicConfig > global_config
Definition PlaceholderParser.hpp:26
static void update_timestamp(DynamicConfig &config)
Definition PlaceholderParser.cpp:76
void init(const Print &print, std::function< void(void)> throw_if_canceled_func)
Definition SeamPlacer.cpp:1414
#define const
Definition getopt.c:38
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
static constexpr double EPSILON
Definition libslic3r.h:51
double coordf_t
Definition libslic3r.h:45
static void init_ooze_prevention(const Print &print, OozePrevention &ooze_prevention)
Definition GCode.cpp:966
static std::string update_print_stats_and_format_filament_stats(const bool has_wipe_tower, const WipeTowerData &wipe_tower_data, const FullPrintConfig &config, const std::vector< Extruder > &extruders, unsigned int initial_extruder_id, PrintStatistics &print_statistics)
Definition GCode.cpp:972
static void init_gcode_processor(const PrintConfig &config, GCodeProcessor &processor, bool &silent_time_estimator_enabled)
Definition GCode.cpp:899
static double autospeed_volumetric_limit(const Print &print)
Definition GCode.cpp:909
void export_thumbnails_to_file(ThumbnailsGeneratorCallback &thumbnail_cb, const std::vector< Vec2d > &sizes, GCodeThumbnailsFormat format, WriteToOutput output, ThrowIfCanceledCallback throw_if_canceled)
Definition Thumbnails.hpp:27
coord_t width(const BoundingBox &box)
Definition Arrange.cpp:539
@ gcfMarlinFirmware
Definition PrintConfig.hpp:35
@ gcfMarlinLegacy
Definition PrintConfig.hpp:35
ConfigOptionFloat
Definition PrintConfig.hpp:570
layer_height((ConfigOptionInt, faded_layers))((ConfigOptionFloat
@ frTopSolidInfill
Definition Flow.hpp:21
@ frExternalPerimeter
Definition Flow.hpp:17
@ frPerimeter
Definition Flow.hpp:18
@ frSolidInfill
Definition Flow.hpp:20
@ frInfill
Definition Flow.hpp:19
between_objects_gcode((ConfigOptionFloats, deretract_speed))((ConfigOptionString
BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z)
Definition PrintExtents.cpp:136
BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object, const coordf_t max_print_z)
Definition PrintExtents.cpp:108
std::string header_slic3r_generated()
Definition utils.cpp:914
Flow support_material_flow(const PrintObject *object, float layer_height)
Definition Flow.cpp:218
std::vector< const PrintInstance * > chain_print_object_instances(const Print &print)
Definition ShortestPath.cpp:1984
Points get_bed_shape(const DynamicPrintConfig &config)
Definition PrintConfig.cpp:4936
BoundingBoxf get_print_extrusions_extents(const Print &print)
Definition PrintExtents.cpp:101
std::vector< const PrintInstance * > sort_object_instances_by_model_order(const Print &print)
Definition GCode.cpp:1062
ConfigOptionBoolsTempl< false > ConfigOptionBools
Definition Config.hpp:1491
GCodeThumbnailsFormat
Definition PrintConfig.hpp:137
T unscale(Q v)
Definition libslic3r.h:95
ConfigOptionFloatsTempl< false > ConfigOptionFloats
Definition Config.hpp:716
end_gcode((ConfigOptionStrings, end_filament_gcode))((ConfigOptionString
BoundingBoxf get_wipe_tower_priming_extrusions_extents(const Print &print)
Definition PrintExtents.cpp:165
std::string gcode_extrusion_role_to_string(GCodeExtrusionRole role)
Definition ExtrusionRole.cpp:34
constexpr auto data(C &c) -> decltype(c.data())
Definition span.hpp:195
IGL_INLINE void count(const Eigen::SparseMatrix< XType > &X, const int dim, Eigen::SparseVector< SType > &S)
Definition count.cpp:12
TMultiShape< PolygonImpl > merge(const TMultiShape< PolygonImpl > &shapes)
Definition geometries.hpp:259
TCoord< P > x(const P &p)
Definition geometry_traits.hpp:297
static constexpr const ExtrusionRoleModifiers None
Definition ExtrusionRole.hpp:47
PlaceholderParser parser
Definition GCode.hpp:353
PlaceholderParser::ContextData context
Definition GCode.hpp:355
void init(const GCodeWriter &config)
Definition GCode.cpp:456