1313#include < utils/MixedPolylineStitcher.h>
1414#include < utils/Simplify.h>
1515
16+ #include < range/v3/algorithm/all_of.hpp>
1617#include < range/v3/algorithm/min_element.hpp>
1718#include < range/v3/algorithm/sort.hpp>
1819#include < range/v3/view/map.hpp>
@@ -203,7 +204,7 @@ std::map<ExtruderNumber, Shape> SkirtBrimAppender::generateAllowedAreas(
203204 }
204205
205206 std::map<ExtruderNumber, Shape> allowed_areas_per_extruder;
206- for (ExtruderNumber extruder_nr : used_extruders)
207+ for (const ExtruderNumber extruder_nr : used_extruders)
207208 {
208209 const ExtruderConfig& extruder_config = extruders_configs.at (extruder_nr);
209210
@@ -262,7 +263,7 @@ std::map<ExtruderNumber, Shape> SkirtBrimAppender::generateAllowedAreas(
262263 return allowed_areas_per_extruder;
263264}
264265
265- FeatureExtrusionPtr SkirtBrimAppender::generateOffset (
266+ std::vector<ContinuousExtruderMoveSequencePtr> SkirtBrimAppender::generateOffset (
266267 const ExtruderNumber extruder_nr,
267268 const coord_t total_offset,
268269 Shape& covered_area,
@@ -287,12 +288,12 @@ FeatureExtrusionPtr SkirtBrimAppender::generateOffset(
287288
288289 const GCodePathConfig& config = layer_plan->getConfigsStorage ()->skirt_brim_config_per_extruder .at (extruder_nr);
289290
290- auto feature_extrusion = std::make_shared<FeatureExtrusion>(PrintFeatureType::SkirtBrim, extruder_config. line_width_ ) ;
291+ std::vector<ContinuousExtruderMoveSequencePtr> extrusions ;
291292 for (PolylinePtr &extrusion_line: result)
292293 {
293294 if (extrusion_line->length () >= min_brim_line_length_)
294295 {
295- feature_extrusion-> appendExtruderMoveSequence (ContinuousExtruderMoveSequence::makeFrom (*extrusion_line, extruder_config.line_width_ , config.getSpeed ()));
296+ extrusions. push_back (ContinuousExtruderMoveSequence::makeFrom (*extrusion_line, extruder_config.line_width_ , config.getSpeed ()));
296297 }
297298 }
298299
@@ -303,7 +304,7 @@ FeatureExtrusionPtr SkirtBrimAppender::generateOffset(
303304 allowed_area = allowed_area.difference (covered_area);
304305 }
305306
306- return feature_extrusion ;
307+ return extrusions ;
307308
308309 // FIXME: This should be done globally by a "filter" transformer
309310 // simplify paths to prevent buffer unnerruns in firmware
@@ -331,18 +332,25 @@ void SkirtBrimAppender::generateSkirtBrim(
331332{
332333 struct ExtruderOffsetData
333334 {
335+ ExtruderNumber extruder_nr;
334336 coord_t next_offset;
337+ FeatureExtrusionPtr extrusion;
335338 coord_t extruded_length{0 };
339+ bool done{false };
340+ size_t processed_offsets{0 };
336341 };
337342
338- // Create a map containing the processing data for each extruder to be processed. When an extruder is finished,
339- // it is removed from the map, so when the map is empty, we are done.
340- std::map<ExtruderNumber, ExtruderOffsetData> next_offset;
343+ // Create a map containing the processing data for each extruder to be processed
344+ std::vector<ExtruderOffsetData> extruder_offset_datas;
341345 for (const ExtruderNumber extruder_nr : used_extruders)
342346 {
343347 const ExtruderConfig &extruder_config = extruders_configs.at (extruder_nr);
344348 const coord_t first_offset = extruder_config.gap_ + (extruder_config.line_width_ / 2 );
345- next_offset[extruder_nr] = ExtruderOffsetData{ .next_offset = first_offset };
349+ extruder_offset_datas.push_back (ExtruderOffsetData{
350+ .extruder_nr = extruder_nr,
351+ .next_offset = first_offset,
352+ .extrusion = std::make_shared<FeatureExtrusion>(PrintFeatureType::SkirtBrim, extruder_config.line_width_ )
353+ });
346354 }
347355
348356 // Create a cache containing the extruders processing ordering, we are going to need it extensively
@@ -359,46 +367,47 @@ void SkirtBrimAppender::generateSkirtBrim(
359367
360368 std::map<ExtruderNumber, Shape> covered_areas = starting_outlines;
361369
362- std::map<ExtruderNumber, std::vector<FeatureExtrusionPtr>> extrusions;
363- while (!next_offset.empty ())
370+ while (!ranges::all_of (extruder_offset_datas, [](const ExtruderOffsetData &data) {return data.done ;}))
364371 {
365- auto iterator = ranges::min_element (next_offset , [&extruder_ordering](const auto &offset1, const auto & offset2)
372+ auto iterator = ranges::min_element (extruder_offset_datas , [&extruder_ordering](const auto &offset1, const auto & offset2)
366373 {
367- if (offset1.second . next_offset == offset2. second .next_offset )
374+ if (offset1.next_offset == offset2.next_offset )
368375 {
369- return extruder_ordering.at (offset1.first ) < extruder_ordering.at (offset2.first );
376+ return extruder_ordering.at (offset1.extruder_nr ) < extruder_ordering.at (offset2.extruder_nr );
370377 }
371- return offset1.second . next_offset < offset2. second .next_offset ;
378+ return offset1.next_offset < offset2.next_offset ;
372379 });
373380
374- ExtruderOffsetData &extruder_offset_data = iterator->second ;
375- const ExtruderNumber extruder_nr = iterator->first ;
381+ ExtruderOffsetData &extruder_offset_data = *iterator;
382+ extruder_offset_data.processed_offsets ++;
383+ const ExtruderNumber extruder_nr = extruder_offset_data.extruder_nr ;
376384 const ExtruderConfig &extruder_config = extruders_configs.at (extruder_nr);
377- const FeatureExtrusionPtr offset_extrusion = generateOffset (
385+ const std::vector<ContinuousExtruderMoveSequencePtr> offset_extrusions = generateOffset (
378386 extruder_nr,
379387 extruder_offset_data.next_offset ,
380388 covered_areas.at (extruder_nr),
381389 allowed_areas_per_extruder,
382390 extruders_configs,
383391 print_plan->getOperationsAs <LayerPlan>().front ());
384392
385- extrusions[extruder_nr].push_back (offset_extrusion);
393+ for (const ContinuousExtruderMoveSequencePtr& offset_extrusion : offset_extrusions)
394+ {
395+ extruder_offset_data.extrusion ->appendExtruderMoveSequence (offset_extrusion);
396+ extruder_offset_data.extruded_length += offset_extrusion->calculateLength ();
397+ }
386398
387- extruder_offset_data.extruded_length += offset_extrusion->calculateLength ();
388399 extruder_offset_data.next_offset = extruder_config.line_width_ / 2 ;
389400
390- if (offset_extrusion-> empty () || extruder_offset_data.extruded_length >= extruder_config.skirt_brim_minimal_length_ )
401+ if (offset_extrusions. empty () || ( extruder_offset_data.processed_offsets >= extruder_config. line_count_ && extruder_offset_data. extruded_length >= extruder_config.skirt_brim_minimal_length_ ) )
391402 {
392- next_offset. erase (iterator) ;
403+ extruder_offset_data. done = true ;
393404 }
394405 }
395406
396- for (auto & extrusion : extrusions )
407+ for (auto & extrusion : extruder_offset_datas )
397408 {
398- for (auto &feature : extrusion.second )
399- {
400- print_plan->getOperationsAs <LayerPlan>().front ()->getOperationsAs <ExtruderPlan>().front ()->appendFeatureExtrusion (feature);
401- }
409+ const auto &feature = extrusion.extrusion ;
410+ print_plan->getOperationsAs <LayerPlan>().front ()->getOperationsAs <ExtruderPlan>().front ()->appendFeatureExtrusion (feature);
402411 }
403412}
404413
0 commit comments