mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Wiping into infill should respect infill_first setting, marking moved to separate function
This commit is contained in:
		
							parent
							
								
									549351bbb4
								
							
						
					
					
						commit
						8bdbe41505
					
				
					 5 changed files with 64 additions and 45 deletions
				
			
		| 
						 | 
				
			
			@ -76,6 +76,7 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
 | 
			
		|||
    this->collect_extruder_statistics(prime_multi_material);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ToolOrdering::LayerTools&  ToolOrdering::tools_for_layer(coordf_t print_z)
 | 
			
		||||
{
 | 
			
		||||
    auto it_layer_tools = std::lower_bound(m_layer_tools.begin(), m_layer_tools.end(), ToolOrdering::LayerTools(print_z - EPSILON));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,7 @@ public:
 | 
			
		|||
            char buf[64];
 | 
			
		||||
            sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width);
 | 
			
		||||
            m_gcode += buf;
 | 
			
		||||
            return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	Writer& 			 set_initial_position(const WipeTower::xy &pos) { 
 | 
			
		||||
| 
						 | 
				
			
			@ -137,7 +138,7 @@ public:
 | 
			
		|||
			width += m_layer_height * float(1. - M_PI / 4.);
 | 
			
		||||
			if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos)
 | 
			
		||||
				m_extrusions.emplace_back(WipeTower::Extrusion(rotated_current_pos, 0, m_current_tool));
 | 
			
		||||
			m_extrusions.emplace_back(WipeTower::Extrusion(WipeTower::xy(rot.x, rot.y), width, m_current_tool));			
 | 
			
		||||
			m_extrusions.emplace_back(WipeTower::Extrusion(WipeTower::xy(rot.x, rot.y), width, m_current_tool));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m_gcode += "G1";
 | 
			
		||||
| 
						 | 
				
			
			@ -483,7 +484,6 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
 | 
			
		|||
	// If false, the last priming are will be large enough to wipe the last extruder sufficiently.
 | 
			
		||||
	bool 						last_wipe_inside_wipe_tower)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	this->set_layer(first_layer_height, first_layer_height, tools.size(), true, false);
 | 
			
		||||
	this->m_current_tool 		= tools.front();
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -1058,7 +1058,7 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer()
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box
 | 
			
		||||
void WipeTowerPrusaMM::plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, bool brim, float wiping_volume_reduction)
 | 
			
		||||
void WipeTowerPrusaMM::plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, bool brim, float wipe_volume)
 | 
			
		||||
{
 | 
			
		||||
	assert(m_plan.back().z <= z_par + WT_EPSILON );	// refuses to add a layer below the last one
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1083,7 +1083,6 @@ void WipeTowerPrusaMM::plan_toolchange(float z_par, float layer_height_par, unsi
 | 
			
		|||
    float ramming_depth = depth;
 | 
			
		||||
    length_to_extrude = width*((length_to_extrude / width)-int(length_to_extrude / width)) - width;
 | 
			
		||||
    float first_wipe_line = -length_to_extrude;
 | 
			
		||||
    float wipe_volume = wipe_volumes[old_tool][new_tool] - wiping_volume_reduction;
 | 
			
		||||
    length_to_extrude += volume_to_length(wipe_volume, m_perimeter_width, layer_height_par);
 | 
			
		||||
    length_to_extrude = std::max(length_to_extrude,0.f);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1146,7 +1145,8 @@ void WipeTowerPrusaMM::save_on_last_wipe()
 | 
			
		|||
// Resulting ToolChangeResults are appended into vector "result"
 | 
			
		||||
void WipeTowerPrusaMM::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result)
 | 
			
		||||
{
 | 
			
		||||
	if (m_plan.empty())	return;
 | 
			
		||||
	if (m_plan.empty())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    m_extra_spacing = 1.f;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1161,12 +1161,10 @@ void WipeTowerPrusaMM::generate(std::vector<std::vector<WipeTower::ToolChangeRes
 | 
			
		|||
 | 
			
		||||
    m_layer_info = m_plan.begin();
 | 
			
		||||
 | 
			
		||||
	std::vector<WipeTower::ToolChangeResult> layer_result;
 | 
			
		||||
    std::vector<WipeTower::ToolChangeResult> layer_result;
 | 
			
		||||
	for (auto layer : m_plan)
 | 
			
		||||
	{
 | 
			
		||||
		set_layer(layer.z,layer.height,0,layer.z == m_plan.front().z,layer.z == m_plan.back().z);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		if (m_peters_wipe_tower)
 | 
			
		||||
			m_wipe_tower_rotation_angle += 90.f;
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ public:
 | 
			
		|||
 | 
			
		||||
	// Appends into internal structure m_plan containing info about the future wipe tower
 | 
			
		||||
	// to be used before building begins. The entries must be added ordered in z.
 | 
			
		||||
	void plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, bool brim, float wiping_volume_reduction = 0.f);
 | 
			
		||||
	void plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, bool brim, float wipe_volume = 0.f);
 | 
			
		||||
 | 
			
		||||
	// Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result"
 | 
			
		||||
	void generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1136,43 +1136,12 @@ void Print::_make_wipe_tower()
 | 
			
		|||
            wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id,false);
 | 
			
		||||
            for (const auto extruder_id : layer_tools.extruders) {
 | 
			
		||||
                if ((first_layer && extruder_id == m_tool_ordering.all_extruders().back()) || extruder_id != current_extruder_id) {
 | 
			
		||||
                    float volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id];    // total volume to wipe after this toolchange
 | 
			
		||||
 | 
			
		||||
                    // Toolchange from old_extruder to new_extruder.
 | 
			
		||||
                    // Check how much volume needs to be wiped and keep marking infills until
 | 
			
		||||
                    // we run out of the volume (or infills)
 | 
			
		||||
                    const float min_infill_volume = 0.f;
 | 
			
		||||
                    if (config.wipe_into_infill && !first_layer)
 | 
			
		||||
                        volume_to_wipe = mark_wiping_infill(layer_tools, extruder_id, wipe_volumes[current_extruder_id][extruder_id]);
 | 
			
		||||
 | 
			
		||||
                    float volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id];
 | 
			
		||||
                    float saved_material = 0.f;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    if (!first_layer && !config.filament_soluble.get_at(extruder_id)) {             // soluble filament cannot be wiped in a random infill, first layer is potentionally visible too
 | 
			
		||||
                        for (size_t i = 0; i < objects.size(); ++ i) {                              // Let's iterate through all objects...
 | 
			
		||||
                            for (Layer* lay : objects[i]->layers) {                                 // Find this layer
 | 
			
		||||
                                if (std::abs(layer_tools.print_z - lay->print_z) > EPSILON)
 | 
			
		||||
                                    continue;
 | 
			
		||||
                                for (size_t region_id = 0; region_id < objects[i]->print()->regions.size(); ++ region_id) {
 | 
			
		||||
                                    unsigned int region_extruder = objects[i]->print()->regions[region_id]->config.infill_extruder - 1; // config value is 1-based
 | 
			
		||||
                                    if (config.filament_soluble.get_at(region_extruder)) // if this infill is meant to be soluble, keep it that way
 | 
			
		||||
                                        continue;
 | 
			
		||||
                                    ExtrusionEntityCollection& eec = lay->regions[region_id]->fills;
 | 
			
		||||
                                    for (ExtrusionEntity* ee : eec.entities) {                      // and all infill Collections
 | 
			
		||||
                                            auto* fill = dynamic_cast<ExtrusionEntityCollection*>(ee);
 | 
			
		||||
                                            if (fill->role() == erTopSolidInfill) continue;         // color of TopSolidInfill cannot be changed - it is visible
 | 
			
		||||
                                            if (volume_to_wipe > 0.f && !fill->is_extruder_overridden() && fill->total_volume() > min_infill_volume) {     // this infill will be used to wipe this extruder
 | 
			
		||||
                                                fill->set_extruder_override(extruder_id);
 | 
			
		||||
                                                volume_to_wipe -= fill->total_volume();
 | 
			
		||||
                                            }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    saved_material = wipe_volumes[current_extruder_id][extruder_id] - std::max(0.f, volume_to_wipe);
 | 
			
		||||
                    std::cout << layer_tools.print_z << "\t" << extruder_id << "\t" << wipe_volumes[current_extruder_id][extruder_id] - volume_to_wipe << "\n";
 | 
			
		||||
 | 
			
		||||
                    wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, extruder_id, first_layer && extruder_id == m_tool_ordering.all_extruders().back(), saved_material);
 | 
			
		||||
                    wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, extruder_id, first_layer && extruder_id == m_tool_ordering.all_extruders().back(), volume_to_wipe);
 | 
			
		||||
                    current_extruder_id = extruder_id;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1205,6 +1174,52 @@ void Print::_make_wipe_tower()
 | 
			
		|||
		wipe_tower.tool_change((unsigned int)-1, false));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
float Print::mark_wiping_infill(const ToolOrdering::LayerTools& layer_tools, unsigned int new_extruder, float volume_to_wipe)
 | 
			
		||||
{
 | 
			
		||||
    const float min_infill_volume = 0.f; // ignore infill with smaller volume than this
 | 
			
		||||
 | 
			
		||||
    if (!config.filament_soluble.get_at(new_extruder)) {                            // Soluble filament cannot be wiped in a random infill
 | 
			
		||||
        for (size_t i = 0; i < objects.size(); ++ i) {                              // Let's iterate through all objects...
 | 
			
		||||
            Layer* this_layer = nullptr;
 | 
			
		||||
            for (unsigned int a = 0; a < objects[i]->layers.size(); this_layer = objects[i]->layers[++a]) // Finds this layer
 | 
			
		||||
                if (std::abs(layer_tools.print_z - objects[i]->layers[a]->print_z) < EPSILON)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
            for (size_t region_id = 0; region_id < objects[i]->print()->regions.size(); ++ region_id) {
 | 
			
		||||
                unsigned int region_extruder = objects[i]->print()->regions[region_id]->config.infill_extruder - 1; // config value is 1-based
 | 
			
		||||
                if (config.filament_soluble.get_at(region_extruder)) // if this infill is meant to be soluble, keep it that way
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                if (!config.infill_first) { // in this case we must verify that region_extruder was already used at this layer (and perimeters of the infill are therefore extruded)
 | 
			
		||||
                    bool unused_yet = false;
 | 
			
		||||
                    for (unsigned i = 0; i < layer_tools.extruders.size(); ++i) {
 | 
			
		||||
                        if (layer_tools.extruders[i] == new_extruder)
 | 
			
		||||
                            unused_yet = true;
 | 
			
		||||
                        if (layer_tools.extruders[i] == region_extruder)
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (unused_yet)
 | 
			
		||||
                        continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ExtrusionEntityCollection& eec = this_layer->regions[region_id]->fills;
 | 
			
		||||
                for (ExtrusionEntity* ee : eec.entities) {                      // iterate through all infill Collections
 | 
			
		||||
                    auto* fill = dynamic_cast<ExtrusionEntityCollection*>(ee);
 | 
			
		||||
                    if (fill->role() == erTopSolidInfill) continue;         // color of TopSolidInfill cannot be changed - it is visible
 | 
			
		||||
                    if (volume_to_wipe > 0.f && !fill->is_extruder_overridden() && fill->total_volume() > min_infill_volume) {     // this infill will be used to wipe this extruder
 | 
			
		||||
                        fill->set_extruder_override(new_extruder);
 | 
			
		||||
                        volume_to_wipe -= fill->total_volume();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return std::max(0.f, volume_to_wipe);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
std::string Print::output_filename()
 | 
			
		||||
{
 | 
			
		||||
    this->placeholder_parser.update_timestamp();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -309,11 +309,16 @@ public:
 | 
			
		|||
    void restart() { m_canceled = false; }
 | 
			
		||||
    // Has the calculation been canceled?
 | 
			
		||||
    bool canceled() { return m_canceled; }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
 | 
			
		||||
    PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume);
 | 
			
		||||
 | 
			
		||||
    // This function goes through all infill entities, decides which ones will be used for wiping and
 | 
			
		||||
    // marks them by the extruder id. Returns volume that remains to be wiped on the wipe tower:
 | 
			
		||||
    float mark_wiping_infill(const ToolOrdering::LayerTools& layer_tools, unsigned int new_extruder, float volume_to_wipe);
 | 
			
		||||
 | 
			
		||||
    // Has the calculation been canceled?
 | 
			
		||||
    tbb::atomic<bool>   m_canceled;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue