Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::WipingExtrusions Class Reference

#include <src/libslic3r/GCode/ToolOrdering.hpp>

+ Collaboration diagram for Slic3r::WipingExtrusions:

Public Types

using ExtruderPerCopy = std::vector< int32_t >
 

Public Member Functions

bool is_anything_overridden () const
 
int get_extruder_override (const ExtrusionEntity *entity, uint32_t instance_id) const
 
float mark_wiping_extrusions (const Print &print, const LayerTools &lt, unsigned int old_extruder, unsigned int new_extruder, float volume_to_wipe)
 
void ensure_perimeters_infills_order (const Print &print, const LayerTools &lt)
 
void set_something_overridable ()
 

Private Member Functions

void set_extruder_override (const ExtrusionEntity *entity, size_t copy_id, int extruder, size_t num_of_copies)
 
bool is_entity_overridden (const ExtrusionEntity *entity, size_t copy_id) const
 

Private Attributes

std::map< const ExtrusionEntity *, ExtruderPerCopym_entity_map
 
bool m_something_overridable = false
 
bool m_something_overridden = false
 

Detailed Description

Member Typedef Documentation

◆ ExtruderPerCopy

Member Function Documentation

◆ ensure_perimeters_infills_order()

void Slic3r::WipingExtrusions::ensure_perimeters_infills_order ( const Print print,
const LayerTools lt 
)
779{
781 return;
782
783 unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config(), lt);
784 unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config(), lt);
785
786 for (const PrintObject* object : print.objects()) {
787 // Finds this layer:
788 const Layer* this_layer = object->get_layer_at_printz(lt.print_z, EPSILON);
789 if (this_layer == nullptr)
790 continue;
791 size_t num_of_copies = object->instances().size();
792
793 for (size_t copy = 0; copy < num_of_copies; ++copy) { // iterate through copies first, so that we mark neighbouring infills to minimize travel moves
794 for (const LayerRegion *layerm : this_layer->regions()) {
795 const auto &region = layerm->region();
796 if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
797 continue;
798
799 for (const ExtrusionEntity* ee : layerm->fills()) { // iterate through all infill Collections
800 auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
801 assert(fill);
802
803 if (!is_overriddable(*fill, lt, print.config(), *object, region)
804 || is_entity_overridden(fill, copy) )
805 continue;
806
807 // This infill could have been overridden but was not - unless we do something, it could be
808 // printed before its perimeter, or not be printed at all (in case its original extruder has
809 // not been added to LayerTools
810 // Either way, we will now force-override it with something suitable:
811 if (print.config().infill_first
812 || object->config().wipe_into_objects // in this case the perimeter is overridden, so we can override by the last one safely
813 || lt.is_extruder_order(lt.perimeter_extruder(region), last_nonsoluble_extruder) // !infill_first, but perimeter is already printed when last extruder prints
814 || ! lt.has_extruder(lt.infill_extruder(region))) // we have to force override - this could violate infill_first (FIXME)
815 set_extruder_override(fill, copy, (print.config().infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies);
816 else {
817 // In this case we can (and should) leave it to be printed normally.
818 // Force overriding would mean it gets printed before its perimeter.
819 }
820 }
821
822 // Now the same for perimeters - see comments above for explanation:
823 for (const ExtrusionEntity* ee : layerm->perimeters()) { // iterate through all perimeter Collections
824 auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
825 assert(fill);
826 if (is_overriddable(*fill, lt, print.config(), *object, region) && ! is_entity_overridden(fill, copy))
827 set_extruder_override(fill, copy, (print.config().infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies);
828 }
829 }
830 }
831 }
832}
bool m_something_overridable
Definition ToolOrdering.hpp:67
void set_extruder_override(const ExtrusionEntity *entity, size_t copy_id, int extruder, size_t num_of_copies)
Definition ToolOrdering.cpp:645
bool is_entity_overridden(const ExtrusionEntity *entity, size_t copy_id) const
Definition ToolOrdering.hpp:61
static constexpr double EPSILON
Definition libslic3r.h:51
static int first_nonsoluble_extruder_on_layer(const PrintConfig &print_config, const LayerTools &layer_tools)
Definition ToolOrdering.cpp:661
static bool is_overriddable(const ExtrusionEntityCollection &eec, const LayerTools &lt, const PrintConfig &print_config, const PrintObject &object, const PrintRegion &region)
Definition ToolOrdering.cpp:197
static int last_nonsoluble_extruder_on_layer(const PrintConfig &print_config, const LayerTools &layer_tools)
Definition ToolOrdering.cpp:671

References Slic3r::Print::config(), EPSILON, Slic3r::first_nonsoluble_extruder_on_layer(), Slic3r::LayerTools::has_extruder(), Slic3r::LayerTools::infill_extruder(), is_entity_overridden(), Slic3r::LayerTools::is_extruder_order(), Slic3r::is_overriddable(), Slic3r::last_nonsoluble_extruder_on_layer(), m_something_overridable, Slic3r::Print::objects(), Slic3r::LayerTools::perimeter_extruder(), Slic3r::LayerTools::print_z, Slic3r::Layer::regions(), and set_extruder_override().

+ Here is the call graph for this function:

◆ get_extruder_override()

int Slic3r::WipingExtrusions::get_extruder_override ( const ExtrusionEntity entity,
uint32_t  instance_id 
) const
inline
43 {
44 auto entity_map_it = m_entity_map.find(entity);
45 return entity_map_it == m_entity_map.end() ? -1 : entity_map_it->second[instance_id];
46 }
std::map< const ExtrusionEntity *, ExtruderPerCopy > m_entity_map
Definition ToolOrdering.hpp:66

References m_entity_map.

Referenced by Slic3r::GCode::process_layer_single_object().

+ Here is the caller graph for this function:

◆ is_anything_overridden()

bool Slic3r::WipingExtrusions::is_anything_overridden ( ) const
inline
28 { // if there are no overrides, all the agenda can be skipped - this function can tell us if that's the case
30 }
bool m_something_overridden
Definition ToolOrdering.hpp:68

References m_something_overridden.

Referenced by Slic3r::GCode::process_layer().

+ Here is the caller graph for this function:

◆ is_entity_overridden()

bool Slic3r::WipingExtrusions::is_entity_overridden ( const ExtrusionEntity entity,
size_t  copy_id 
) const
inlineprivate
61 {
62 auto it = m_entity_map.find(entity);
63 return it == m_entity_map.end() ? false : it->second[copy_id] != -1;
64 }

References m_entity_map.

Referenced by ensure_perimeters_infills_order(), and mark_wiping_extrusions().

+ Here is the caller graph for this function:

◆ mark_wiping_extrusions()

float Slic3r::WipingExtrusions::mark_wiping_extrusions ( const Print print,
const LayerTools lt,
unsigned int  old_extruder,
unsigned int  new_extruder,
float  volume_to_wipe 
)
684{
685 const float min_infill_volume = 0.f; // ignore infill with smaller volume than this
686
687 if (! m_something_overridable || volume_to_wipe <= 0. ||
688 // Don't wipe a soluble filament into another object.
689 print.config().filament_soluble.get_at(old_extruder) ||
690 // Don't prime a soluble filament into another object.
691 print.config().filament_soluble.get_at(new_extruder))
692 // Soluble filament cannot be wiped in a random infill, neither the filament after it
693 return std::max(0.f, volume_to_wipe);
694
695 // we will sort objects so that dedicated for wiping are at the beginning:
696 ConstPrintObjectPtrs object_list(print.objects().begin(), print.objects().end());
697 std::sort(object_list.begin(), object_list.end(), [](const PrintObject* a, const PrintObject* b) { return a->config().wipe_into_objects && ! b->config().wipe_into_objects; });
698
699 // We will now iterate through
700 // - first the dedicated objects to mark perimeters or infills (depending on infill_first)
701 // - second through the dedicated ones again to mark infills or perimeters (depending on infill_first)
702 // - then all the others to mark infills (in case that !infill_first, we must also check that the perimeter is finished already
703 // this is controlled by the following variable:
704 bool perimeters_done = false;
705
706 for (int i=0 ; i<(int)object_list.size() + (perimeters_done ? 0 : 1); ++i) {
707 if (!perimeters_done && (i==(int)object_list.size() || !object_list[i]->config().wipe_into_objects)) { // we passed the last dedicated object in list
708 perimeters_done = true;
709 i=-1; // let's go from the start again
710 continue;
711 }
712
713 const PrintObject* object = object_list[i];
714
715 // Finds this layer:
716 const Layer* this_layer = object->get_layer_at_printz(lt.print_z, EPSILON);
717 if (this_layer == nullptr)
718 continue;
719 size_t num_of_copies = object->instances().size();
720
721 // iterate through copies (aka PrintObject instances) first, so that we mark neighbouring infills to minimize travel moves
722 for (unsigned int copy = 0; copy < num_of_copies; ++copy) {
723 for (const LayerRegion *layerm : this_layer->regions()) {
724 const auto &region = layerm->region();
725 if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
726 continue;
727
728 bool wipe_into_infill_only = ! object->config().wipe_into_objects && region.config().wipe_into_infill;
729 if (print.config().infill_first != perimeters_done || wipe_into_infill_only) {
730 for (const ExtrusionEntity* ee : layerm->fills()) { // iterate through all infill Collections
731 auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
732
733 if (!is_overriddable(*fill, lt, print.config(), *object, region))
734 continue;
735
736 if (wipe_into_infill_only && ! print.config().infill_first)
737 // In this case we must check that the original extruder is used on this layer before the one we are overridding
738 // (and the perimeters will be finished before the infill is printed):
739 if (!lt.is_extruder_order(lt.perimeter_extruder(region), new_extruder))
740 continue;
741
742 if ((!is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume)) { // this infill will be used to wipe this extruder
743 set_extruder_override(fill, copy, new_extruder, num_of_copies);
744 if ((volume_to_wipe -= float(fill->total_volume())) <= 0.f)
745 // More material was purged already than asked for.
746 return 0.f;
747 }
748 }
749 }
750
751 // Now the same for perimeters - see comments above for explanation:
752 if (object->config().wipe_into_objects && print.config().infill_first == perimeters_done)
753 {
754 for (const ExtrusionEntity* ee : layerm->perimeters()) {
755 auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
756 if (is_overriddable(*fill, lt, print.config(), *object, region) && !is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume) {
757 set_extruder_override(fill, copy, new_extruder, num_of_copies);
758 if ((volume_to_wipe -= float(fill->total_volume())) <= 0.f)
759 // More material was purged already than asked for.
760 return 0.f;
761 }
762 }
763 }
764 }
765 }
766 }
767 // Some purge remains to be done on the Wipe Tower.
768 assert(volume_to_wipe > 0.);
769 return volume_to_wipe;
770}
std::vector< const PrintObject * > ConstPrintObjectPtrs
Definition Print.hpp:534

References Slic3r::PrintObject::config(), Slic3r::Print::config(), EPSILON, is_entity_overridden(), Slic3r::LayerTools::is_extruder_order(), Slic3r::is_overriddable(), m_something_overridable, Slic3r::Print::objects(), Slic3r::LayerTools::perimeter_extruder(), Slic3r::LayerTools::print_z, Slic3r::Layer::regions(), and set_extruder_override().

+ Here is the call graph for this function:

◆ set_extruder_override()

void Slic3r::WipingExtrusions::set_extruder_override ( const ExtrusionEntity entity,
size_t  copy_id,
int  extruder,
size_t  num_of_copies 
)
private
646{
648
649 auto entity_map_it = (m_entity_map.emplace(entity, ExtruderPerCopy())).first; // (add and) return iterator
650 ExtruderPerCopy& copies_vector = entity_map_it->second;
651 copies_vector.resize(num_of_copies, -1);
652
653 assert(copies_vector[copy_id] == -1);
654 if (copies_vector[copy_id] != -1)
655 BOOST_LOG_TRIVIAL(error) << "ERROR: Entity extruder overriden multiple times!!!";
656
657 copies_vector[copy_id] = extruder;
658}
std::vector< int32_t > ExtruderPerCopy
Definition ToolOrdering.hpp:37
static char error[256]
Definition tga.cpp:50

References error, m_entity_map, and m_something_overridden.

Referenced by ensure_perimeters_infills_order(), and mark_wiping_extrusions().

+ Here is the caller graph for this function:

◆ set_something_overridable()

void Slic3r::WipingExtrusions::set_something_overridable ( )
inline

Member Data Documentation

◆ m_entity_map

std::map<const ExtrusionEntity*, ExtruderPerCopy> Slic3r::WipingExtrusions::m_entity_map
private

◆ m_something_overridable

bool Slic3r::WipingExtrusions::m_something_overridable = false
private

◆ m_something_overridden

bool Slic3r::WipingExtrusions::m_something_overridden = false
private

The documentation for this class was generated from the following files: