Make sure prime tower uses correct line width and filament for outer wall
This commit is contained in:
@@ -269,6 +269,14 @@ void ToolOrdering::handle_dontcare_extruder(const std::vector<unsigned int>& too
|
||||
assert(extruder_id > 0);
|
||||
--extruder_id;
|
||||
}
|
||||
for (unsigned int &extruder_id : lt.texture_mapping_extruders) {
|
||||
assert(extruder_id > 0);
|
||||
--extruder_id;
|
||||
}
|
||||
for (unsigned int &extruder_id : lt.texture_mapping_component_extruders) {
|
||||
assert(extruder_id > 0);
|
||||
--extruder_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,6 +347,14 @@ void ToolOrdering::handle_dontcare_extruder(unsigned int last_extruder_id)
|
||||
assert(extruder_id > 0);
|
||||
-- extruder_id;
|
||||
}
|
||||
for (unsigned int &extruder_id : lt.texture_mapping_extruders) {
|
||||
assert(extruder_id > 0);
|
||||
-- extruder_id;
|
||||
}
|
||||
for (unsigned int &extruder_id : lt.texture_mapping_component_extruders) {
|
||||
assert(extruder_id > 0);
|
||||
-- extruder_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,10 +736,35 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
||||
|
||||
// Store the current extruder override (set to zero if no overriden), so that layer_tools.wiping_extrusions().is_overridable_and_mark() will use it.
|
||||
layer_tools.extruder_override = extruder_override;
|
||||
auto append_layer_filament = [&layer_tools](unsigned int filament_id) {
|
||||
if (layer_tools.texture_mapping_manager != nullptr && layer_tools.texture_mapping_manager->is_texture_mapping_zone_id(filament_id))
|
||||
auto append_layer_filament = [&layer_tools, &object](unsigned int filament_id) {
|
||||
const bool is_texture_mapping_zone = layer_tools.texture_mapping_manager != nullptr &&
|
||||
layer_tools.texture_mapping_manager->is_texture_mapping_zone_id(filament_id);
|
||||
const unsigned int resolved_filament_id = layer_tools.resolve_filament_id(filament_id);
|
||||
if (is_texture_mapping_zone) {
|
||||
layer_tools.has_texture_mapping_zone = true;
|
||||
layer_tools.extruders.emplace_back(layer_tools.resolve_filament_id(filament_id));
|
||||
if (resolved_filament_id > 0)
|
||||
layer_tools.texture_mapping_extruders.emplace_back(resolved_filament_id);
|
||||
const TextureMappingZone *zone = layer_tools.texture_mapping_manager->zone_from_id(filament_id);
|
||||
bool added_texture_component = false;
|
||||
if (zone != nullptr && zone->enabled && !zone->deleted) {
|
||||
std::vector<std::string> filament_colours = object.print()->config().filament_colour.values;
|
||||
filament_colours.resize(layer_tools.num_physical_filaments, "#FFFFFF");
|
||||
std::vector<unsigned int> component_ids =
|
||||
zone->is_image_texture() ?
|
||||
TextureMappingManager::effective_texture_component_ids(*zone,
|
||||
layer_tools.num_physical_filaments,
|
||||
filament_colours) :
|
||||
TextureMappingManager::selected_component_ids(*zone, layer_tools.num_physical_filaments);
|
||||
for (const unsigned int component_id : component_ids)
|
||||
if (component_id >= 1 && component_id <= layer_tools.num_physical_filaments) {
|
||||
layer_tools.texture_mapping_component_extruders.emplace_back(component_id);
|
||||
added_texture_component = true;
|
||||
}
|
||||
}
|
||||
if (!added_texture_component && resolved_filament_id > 0)
|
||||
layer_tools.texture_mapping_component_extruders.emplace_back(resolved_filament_id);
|
||||
}
|
||||
layer_tools.extruders.emplace_back(resolved_filament_id);
|
||||
};
|
||||
|
||||
// What extruders are required to print this object layer?
|
||||
@@ -841,6 +882,8 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
||||
for (auto& layer : m_layer_tools) {
|
||||
// Sort and remove duplicates
|
||||
sort_remove_duplicates(layer.extruders);
|
||||
sort_remove_duplicates(layer.texture_mapping_extruders);
|
||||
sort_remove_duplicates(layer.texture_mapping_component_extruders);
|
||||
|
||||
// make sure that there are some tools for each object layer (e.g. tall wiping object will result in empty extruders vector)
|
||||
if (layer.extruders.empty() && layer.has_object)
|
||||
|
||||
@@ -156,6 +156,8 @@ public:
|
||||
bool has_support = false;
|
||||
// Zero based extruder IDs, ordered to minimize tool switches.
|
||||
std::vector<unsigned int> extruders;
|
||||
std::vector<unsigned int> texture_mapping_extruders;
|
||||
std::vector<unsigned int> texture_mapping_component_extruders;
|
||||
// If per layer extruder switches are inserted by the G-code preview slider, this value contains the new (1 based) extruder, with which the whole object layer is being printed with.
|
||||
// If not overriden, it is set to 0.
|
||||
unsigned int extruder_override = 0;
|
||||
|
||||
@@ -630,7 +630,7 @@ public:
|
||||
if (! m_preview_suppressed && e > 0.f && len > 0.f) {
|
||||
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
|
||||
// This is left zero if it is a travel move.
|
||||
float width = e * m_filpar[0].filament_area / (len * m_layer_height);
|
||||
float width = e * m_filpar[m_current_tool].filament_area / (len * m_layer_height);
|
||||
// Correct for the roundings of a squished extrusion.
|
||||
width += m_layer_height * float(1. - M_PI / 4.);
|
||||
if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos)
|
||||
@@ -688,7 +688,7 @@ public:
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
|
||||
// This is left zero if it is a travel move.
|
||||
float width = e * m_filpar[0].filament_area / (len * m_layer_height);
|
||||
float width = e * m_filpar[m_current_tool].filament_area / (len * m_layer_height);
|
||||
// Correct for the roundings of a squished extrusion.
|
||||
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));
|
||||
@@ -1447,7 +1447,8 @@ static void prime_tower_textured_path(WipeTowerWriter &writer,
|
||||
float width_range = (base_width - min_width) * std::clamp(texture.global_strength, 0.f, 1.f);
|
||||
if (texture.sagging_ratio > EPSILON)
|
||||
width_range = std::min(width_range, layer_height * texture.sagging_ratio);
|
||||
const float sample_step = std::max(0.35f, reference_width);
|
||||
const float base_extrusion_flow = extrusion_flow * prime_tower_flow_scale_for_width(reference_width, base_width, layer_height);
|
||||
const float sample_step = std::max(0.35f, base_width);
|
||||
|
||||
float travelled = 0.f;
|
||||
bool have_shifted_pos = false;
|
||||
@@ -1476,7 +1477,7 @@ static void prime_tower_textured_path(WipeTowerWriter &writer,
|
||||
const float u = (mid_distance - texture_path.anchor_distance) / total_length;
|
||||
const float visibility = texture.sample_tool_visibility(current_tool, u, v, normalization_tools);
|
||||
const float target_width = base_width - (1.f - visibility) * width_range;
|
||||
const float flow_scale = prime_tower_flow_scale_for_width(reference_width, target_width, layer_height);
|
||||
const float flow_scale = prime_tower_flow_scale_for_width(base_width, target_width, layer_height);
|
||||
const float centerline_shift = 0.5f * (base_width - reference_width) + 0.5f * (base_width - target_width);
|
||||
const Vec2f p0 = a + delta * t0 - outward * centerline_shift;
|
||||
const Vec2f p1 = a + delta * t1 - outward * centerline_shift;
|
||||
@@ -1485,12 +1486,11 @@ static void prime_tower_textured_path(WipeTowerWriter &writer,
|
||||
shifted_pos = p0;
|
||||
have_shifted_pos = true;
|
||||
}
|
||||
writer.extrude_explicit(p1, (p1 - p0).norm() * extrusion_flow * flow_scale, feedrate, true);
|
||||
writer.extrude_explicit(p1, (p1 - p0).norm() * base_extrusion_flow * flow_scale, feedrate, true);
|
||||
shifted_pos = p1;
|
||||
}
|
||||
travelled += sample_len;
|
||||
}
|
||||
writer.change_analyzer_line_width(reference_width);
|
||||
}
|
||||
|
||||
static void prime_tower_textured_closed_path(WipeTowerWriter &writer,
|
||||
@@ -2748,12 +2748,17 @@ WipeTower::ToolChangeResult WipeTower::finish_layer(bool extrude_perimeter, bool
|
||||
std::vector<size_t> texture_normalization_tools;
|
||||
if (m_prime_tower_texture.valid()) {
|
||||
const size_t texture_tool_count = m_prime_tower_texture.filament_colours.size();
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
if (m_layer_info != m_plan.end()) {
|
||||
if (m_layer_info != m_plan.end() && !m_layer_info->texture_mapping_layer_tools.empty()) {
|
||||
for (const size_t tool : m_layer_info->texture_mapping_layer_tools)
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool, texture_tool_count);
|
||||
} else if (m_layer_info != m_plan.end()) {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
for (const WipeTowerInfo::ToolChange &tool_change : m_layer_info->tool_changes) {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool_change.old_tool, texture_tool_count);
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool_change.new_tool, texture_tool_count);
|
||||
}
|
||||
} else {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
}
|
||||
}
|
||||
if (extrude_perimeter) {
|
||||
@@ -2835,13 +2840,23 @@ void WipeTower::plan_toolchange(float z_par,
|
||||
unsigned int new_tool,
|
||||
float wipe_volume,
|
||||
float purge_volume,
|
||||
bool texture_mapping_single_component_layer)
|
||||
bool texture_mapping_single_component_layer,
|
||||
const std::vector<unsigned int> &texture_mapping_layer_tools,
|
||||
int texture_mapping_wall_tool)
|
||||
{
|
||||
assert(m_plan.empty() || m_plan.back().z <= z_par + WT_EPSILON); // refuses to add a layer below the last one
|
||||
|
||||
if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) // if we moved to a new layer, we'll add it to m_plan first
|
||||
m_plan.push_back(WipeTowerInfo(z_par, layer_height_par));
|
||||
m_plan.back().texture_mapping_single_component_layer |= texture_mapping_single_component_layer;
|
||||
if (texture_mapping_wall_tool >= 0)
|
||||
m_plan.back().texture_mapping_wall_tool = size_t(texture_mapping_wall_tool);
|
||||
std::vector<size_t> &layer_texture_tools = m_plan.back().texture_mapping_layer_tools;
|
||||
for (const unsigned int tool : texture_mapping_layer_tools) {
|
||||
const size_t tool_id = size_t(tool);
|
||||
if (std::find(layer_texture_tools.begin(), layer_texture_tools.end(), tool_id) == layer_texture_tools.end())
|
||||
layer_texture_tools.emplace_back(tool_id);
|
||||
}
|
||||
|
||||
if (m_first_layer_idx == size_t(-1) && (! m_no_sparse_layers || old_tool != new_tool))
|
||||
m_first_layer_idx = m_plan.size() - 1;
|
||||
@@ -4299,10 +4314,28 @@ void WipeTower::generate_new(std::vector<std::vector<WipeTower::ToolChangeResult
|
||||
ToolChangeResult timelapse_wall;
|
||||
|
||||
auto get_wall_filament_for_this_layer = [this, &layer, &wall_filament]() -> int {
|
||||
if (layer.tool_changes.size() == 0)
|
||||
auto texture_wall_tool_for_this_layer = [this, &layer]() -> int {
|
||||
if (!m_prime_tower_texture.valid() || layer.texture_mapping_wall_tool == size_t(-1))
|
||||
return -1;
|
||||
const int texture_wall_tool = int(layer.texture_mapping_wall_tool);
|
||||
if (layer.tool_changes.empty())
|
||||
return texture_wall_tool == int(m_current_tool) ? texture_wall_tool : -1;
|
||||
if (int(layer.tool_changes.front().old_tool) == texture_wall_tool)
|
||||
return texture_wall_tool;
|
||||
for (const WipeTowerInfo::ToolChange &tool_change : layer.tool_changes)
|
||||
if (int(tool_change.new_tool) == texture_wall_tool)
|
||||
return texture_wall_tool;
|
||||
return -1;
|
||||
if (m_prime_tower_texture.valid() && layer.texture_mapping_single_component_layer && layer.tool_changes.size() == 1)
|
||||
return layer.tool_changes.front().new_tool;
|
||||
};
|
||||
if (const int texture_wall_tool = texture_wall_tool_for_this_layer(); texture_wall_tool != -1)
|
||||
return texture_wall_tool;
|
||||
if (layer.tool_changes.size() == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (m_prime_tower_texture.valid()) {
|
||||
if (layer.texture_mapping_single_component_layer && layer.tool_changes.size() == 1)
|
||||
return layer.tool_changes.front().new_tool;
|
||||
}
|
||||
|
||||
int candidate_id = -1;
|
||||
for (size_t idx = 0; idx < layer.tool_changes.size(); ++idx) {
|
||||
@@ -4713,12 +4746,17 @@ Polygon WipeTower::generate_support_wall_new(WipeTowerWriter &writer, const box_
|
||||
if (m_prime_tower_texture.valid() && result_wall.size() == 1 && !result_wall.front().points.empty()) {
|
||||
std::vector<size_t> texture_normalization_tools;
|
||||
const size_t texture_tool_count = m_prime_tower_texture.filament_colours.size();
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
if (m_layer_info != m_plan.end()) {
|
||||
if (m_layer_info != m_plan.end() && !m_layer_info->texture_mapping_layer_tools.empty()) {
|
||||
for (const size_t tool : m_layer_info->texture_mapping_layer_tools)
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool, texture_tool_count);
|
||||
} else if (m_layer_info != m_plan.end()) {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
for (const WipeTowerInfo::ToolChange &tool_change : m_layer_info->tool_changes) {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool_change.old_tool, texture_tool_count);
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool_change.new_tool, texture_tool_count);
|
||||
}
|
||||
} else {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
}
|
||||
const bool closed_texture_path = !rib_wall && !skip_points;
|
||||
std::vector<Vec2f> points;
|
||||
|
||||
@@ -76,8 +76,8 @@ struct PrimeTowerTextureRenderSettings
|
||||
float sample_tool_visibility(size_t tool, float u, float v) const
|
||||
{
|
||||
const float raw_visibility = sample_tool_visibility_raw(tool, u, v);
|
||||
if (settings_zone_enabled || !compact_offset_mode)
|
||||
return raw_visibility;
|
||||
if (!compact_offset_mode)
|
||||
return adjusted_tool_visibility(tool, raw_visibility);
|
||||
|
||||
float max_visibility = std::clamp(raw_visibility, 0.f, 1.f);
|
||||
if (!tool_indices.empty()) {
|
||||
@@ -91,27 +91,126 @@ struct PrimeTowerTextureRenderSettings
|
||||
max_visibility = std::max(max_visibility, std::clamp(sample_tool_visibility_raw(candidate_tool, u, v), 0.f, 1.f));
|
||||
}
|
||||
}
|
||||
return max_visibility > 1e-6f ?
|
||||
std::clamp(raw_visibility / max_visibility, 0.f, 1.f) :
|
||||
std::clamp(raw_visibility, 0.f, 1.f);
|
||||
return max_visibility > 1e-6f ? adjusted_tool_visibility(tool, raw_visibility / max_visibility) :
|
||||
adjusted_tool_visibility(tool, raw_visibility);
|
||||
}
|
||||
|
||||
float sample_tool_visibility(size_t tool, float u, float v, const std::vector<size_t> &normalization_tools) const
|
||||
{
|
||||
const float raw_visibility = sample_tool_visibility_raw(tool, u, v);
|
||||
if (settings_zone_enabled || !compact_offset_mode || normalization_tools.empty())
|
||||
return raw_visibility;
|
||||
if (!compact_offset_mode || normalization_tools.empty())
|
||||
return adjusted_tool_visibility(tool, raw_visibility);
|
||||
|
||||
float max_visibility = std::clamp(raw_visibility, 0.f, 1.f);
|
||||
for (const size_t normalization_tool : normalization_tools)
|
||||
max_visibility = std::max(max_visibility, std::clamp(sample_tool_visibility_raw(normalization_tool, u, v), 0.f, 1.f));
|
||||
|
||||
return max_visibility > 1e-6f ?
|
||||
std::clamp(raw_visibility / max_visibility, 0.f, 1.f) :
|
||||
std::clamp(raw_visibility, 0.f, 1.f);
|
||||
return max_visibility > 1e-6f ? adjusted_tool_visibility(tool, raw_visibility / max_visibility) :
|
||||
adjusted_tool_visibility(tool, raw_visibility);
|
||||
}
|
||||
|
||||
std::vector<size_t> component_tools_for_layer_sequence() const
|
||||
{
|
||||
std::vector<size_t> tools;
|
||||
if (!valid())
|
||||
return tools;
|
||||
|
||||
if (settings_zone_enabled && !component_ids.empty()) {
|
||||
tools.reserve(component_ids.size());
|
||||
for (const unsigned int physical_id : component_ids) {
|
||||
if (physical_id >= 1 && physical_id <= filament_colours.size()) {
|
||||
const size_t tool = size_t(physical_id - 1);
|
||||
if (std::find(tools.begin(), tools.end(), tool) == tools.end())
|
||||
tools.emplace_back(tool);
|
||||
}
|
||||
}
|
||||
if (!tools.empty())
|
||||
return tools;
|
||||
}
|
||||
|
||||
const std::vector<std::array<float, 3>> ideals = color_mode_ideals(color_mode);
|
||||
if (ideals.empty())
|
||||
return tools;
|
||||
|
||||
std::vector<size_t> candidates;
|
||||
if (!tool_indices.empty()) {
|
||||
for (const size_t tool : tool_indices)
|
||||
if (tool < filament_colours.size() && std::find(candidates.begin(), candidates.end(), tool) == candidates.end())
|
||||
candidates.emplace_back(tool);
|
||||
} else {
|
||||
candidates.reserve(filament_colours.size());
|
||||
for (size_t tool = 0; tool < filament_colours.size(); ++tool)
|
||||
candidates.emplace_back(tool);
|
||||
}
|
||||
if (candidates.empty())
|
||||
return tools;
|
||||
|
||||
std::vector<char> used(filament_colours.size(), 0);
|
||||
tools.reserve(ideals.size());
|
||||
for (const std::array<float, 3> &ideal : ideals) {
|
||||
size_t best_tool = size_t(-1);
|
||||
float best_distance = std::numeric_limits<float>::max();
|
||||
for (const size_t candidate : candidates) {
|
||||
if (candidate >= used.size() || used[candidate])
|
||||
continue;
|
||||
const float distance = color_distance2(tool_color(candidate), ideal);
|
||||
if (distance < best_distance) {
|
||||
best_distance = distance;
|
||||
best_tool = candidate;
|
||||
}
|
||||
}
|
||||
if (best_tool != size_t(-1)) {
|
||||
used[best_tool] = 1;
|
||||
tools.emplace_back(best_tool);
|
||||
}
|
||||
}
|
||||
return tools;
|
||||
}
|
||||
|
||||
size_t tool_for_layer_sequence(int layer_index) const
|
||||
{
|
||||
const std::vector<size_t> tools = component_tools_for_layer_sequence();
|
||||
if (tools.empty())
|
||||
return size_t(-1);
|
||||
const int tool_count = int(tools.size());
|
||||
const int index = ((layer_index % tool_count) + tool_count) % tool_count;
|
||||
return tools[size_t(index)];
|
||||
}
|
||||
|
||||
private:
|
||||
static std::vector<std::array<float, 3>> color_mode_ideals(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case CMY:
|
||||
return {std::array<float, 3>{0.f, 1.f, 1.f}, std::array<float, 3>{1.f, 0.f, 1.f}, std::array<float, 3>{1.f, 1.f, 0.f}};
|
||||
case CMYK:
|
||||
return {std::array<float, 3>{0.f, 1.f, 1.f},
|
||||
std::array<float, 3>{1.f, 0.f, 1.f},
|
||||
std::array<float, 3>{1.f, 1.f, 0.f},
|
||||
std::array<float, 3>{0.f, 0.f, 0.f}};
|
||||
case CMYW:
|
||||
return {std::array<float, 3>{0.f, 1.f, 1.f},
|
||||
std::array<float, 3>{1.f, 0.f, 1.f},
|
||||
std::array<float, 3>{1.f, 1.f, 0.f},
|
||||
std::array<float, 3>{1.f, 1.f, 1.f}};
|
||||
case RGB:
|
||||
return {std::array<float, 3>{1.f, 0.f, 0.f}, std::array<float, 3>{0.f, 1.f, 0.f}, std::array<float, 3>{0.f, 0.f, 1.f}};
|
||||
case RGBK:
|
||||
return {std::array<float, 3>{1.f, 0.f, 0.f},
|
||||
std::array<float, 3>{0.f, 1.f, 0.f},
|
||||
std::array<float, 3>{0.f, 0.f, 1.f},
|
||||
std::array<float, 3>{0.f, 0.f, 0.f}};
|
||||
case RGBW:
|
||||
return {std::array<float, 3>{1.f, 0.f, 0.f},
|
||||
std::array<float, 3>{0.f, 1.f, 0.f},
|
||||
std::array<float, 3>{0.f, 0.f, 1.f},
|
||||
std::array<float, 3>{1.f, 1.f, 1.f}};
|
||||
case BW:
|
||||
return {std::array<float, 3>{0.f, 0.f, 0.f}, std::array<float, 3>{1.f, 1.f, 1.f}};
|
||||
default: return {};
|
||||
}
|
||||
}
|
||||
|
||||
float sample_tool_visibility_raw(size_t tool, float u, float v) const
|
||||
{
|
||||
if (!valid())
|
||||
@@ -321,6 +420,14 @@ private:
|
||||
return std::clamp(minimum + std::clamp(value, 0.f, 1.f) * strength * (1.f - minimum), 0.f, 1.f);
|
||||
}
|
||||
|
||||
float adjusted_tool_visibility(size_t tool, float value) const
|
||||
{
|
||||
const unsigned int physical_id = unsigned(tool + 1);
|
||||
return settings_zone_enabled && std::find(component_ids.begin(), component_ids.end(), physical_id) != component_ids.end() ?
|
||||
adjusted_visibility_factor(physical_id, value) :
|
||||
std::clamp(value, 0.f, 1.f);
|
||||
}
|
||||
|
||||
float sample_settings_zone_tool_visibility(size_t tool, float u, float v, bool back) const
|
||||
{
|
||||
const unsigned int physical_id = unsigned(tool + 1);
|
||||
@@ -350,15 +457,7 @@ private:
|
||||
return sample_image_tool_visibility(tool, u, v, back);
|
||||
|
||||
apply_contrast(weights, std::clamp(contrast_pct, 25.f, 300.f) / 100.f, mapped_count);
|
||||
if (compact_offset_mode) {
|
||||
float max_weight = 0.f;
|
||||
for (const float weight : weights)
|
||||
max_weight = std::max(max_weight, std::clamp(weight, 0.f, 1.f));
|
||||
if (max_weight > 1e-6f)
|
||||
for (float &weight : weights)
|
||||
weight = std::clamp(weight / max_weight, 0.f, 1.f);
|
||||
}
|
||||
return adjusted_visibility_factor(physical_id, weights[component_idx]);
|
||||
return std::clamp(weights[component_idx], 0.f, 1.f);
|
||||
}
|
||||
|
||||
float fixed_mode_visibility(size_t tool, float r, float g, float b) const
|
||||
@@ -626,7 +725,9 @@ public:
|
||||
unsigned int new_tool,
|
||||
float wipe_volume = 0.f,
|
||||
float prime_volume = 0.f,
|
||||
bool texture_mapping_single_component_layer = false);
|
||||
bool texture_mapping_single_component_layer = false,
|
||||
const std::vector<unsigned int> &texture_mapping_layer_tools = {},
|
||||
int texture_mapping_wall_tool = -1);
|
||||
|
||||
// Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result"
|
||||
void generate(std::vector<std::vector<ToolChangeResult>> &result);
|
||||
@@ -986,9 +1087,11 @@ private:
|
||||
float z; // z position of the layer
|
||||
float height; // layer height
|
||||
float depth; // depth of the layer based on all layers above
|
||||
float extra_spacing;
|
||||
float extra_spacing;
|
||||
bool extruder_fill{true};
|
||||
bool texture_mapping_single_component_layer{false};
|
||||
std::vector<size_t> texture_mapping_layer_tools;
|
||||
size_t texture_mapping_wall_tool{size_t(-1)};
|
||||
float toolchanges_depth() const { float sum = 0.f; for (const auto &a : tool_changes) sum += a.required_depth; return sum; }
|
||||
|
||||
std::vector<ToolChange> tool_changes;
|
||||
|
||||
@@ -683,7 +683,7 @@ public:
|
||||
if (! m_preview_suppressed && e > 0.f && len > 0.f) {
|
||||
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
|
||||
// This is left zero if it is a travel move.
|
||||
float width = e * m_filpar[0].filament_area / (len * m_layer_height);
|
||||
float width = e * m_filpar[m_current_tool].filament_area / (len * m_layer_height);
|
||||
// Correct for the roundings of a squished extrusion.
|
||||
width += m_layer_height * float(1. - M_PI / 4.);
|
||||
if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos)
|
||||
@@ -1019,7 +1019,7 @@ public:
|
||||
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
|
||||
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
|
||||
// This is left zero if it is a travel move.
|
||||
float width = e * m_filpar[0].filament_area / (len * m_layer_height);
|
||||
float width = e * m_filpar[m_current_tool].filament_area / (len * m_layer_height);
|
||||
// Correct for the roundings of a squished extrusion.
|
||||
width += m_layer_height * float(1. - M_PI / 4.);
|
||||
if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos)
|
||||
@@ -1426,7 +1426,8 @@ static void prime_tower_textured_path(WipeTowerWriter2& writer,
|
||||
float width_range = (base_width - min_width) * std::clamp(texture.global_strength, 0.f, 1.f);
|
||||
if (texture.sagging_ratio > EPSILON)
|
||||
width_range = std::min(width_range, layer_height * texture.sagging_ratio);
|
||||
const float sample_step = std::max(0.35f, reference_width);
|
||||
const float base_extrusion_flow = extrusion_flow * prime_tower_flow_scale_for_width(reference_width, base_width, layer_height);
|
||||
const float sample_step = std::max(0.35f, base_width);
|
||||
|
||||
float travelled = 0.f;
|
||||
bool have_shifted_pos = false;
|
||||
@@ -1455,7 +1456,7 @@ static void prime_tower_textured_path(WipeTowerWriter2& writer,
|
||||
const float u = (mid_distance - texture_path.anchor_distance) / total_length;
|
||||
const float visibility = texture.sample_tool_visibility(current_tool, u, v, normalization_tools);
|
||||
const float target_width = base_width - (1.f - visibility) * width_range;
|
||||
const float flow_scale = prime_tower_flow_scale_for_width(reference_width, target_width, layer_height);
|
||||
const float flow_scale = prime_tower_flow_scale_for_width(base_width, target_width, layer_height);
|
||||
const float centerline_shift = 0.5f * (base_width - reference_width) + 0.5f * (base_width - target_width);
|
||||
const Vec2f p0 = a + delta * t0 - outward * centerline_shift;
|
||||
const Vec2f p1 = a + delta * t1 - outward * centerline_shift;
|
||||
@@ -1464,12 +1465,11 @@ static void prime_tower_textured_path(WipeTowerWriter2& writer,
|
||||
shifted_pos = p0;
|
||||
have_shifted_pos = true;
|
||||
}
|
||||
writer.extrude_explicit(p1, (p1 - p0).norm() * extrusion_flow * flow_scale, feedrate, true);
|
||||
writer.extrude_explicit(p1, (p1 - p0).norm() * base_extrusion_flow * flow_scale, feedrate, true);
|
||||
shifted_pos = p1;
|
||||
}
|
||||
travelled += sample_len;
|
||||
}
|
||||
writer.change_analyzer_line_width(reference_width);
|
||||
}
|
||||
|
||||
static void prime_tower_textured_closed_path(WipeTowerWriter2& writer,
|
||||
@@ -2521,13 +2521,26 @@ static float get_wipe_depth(float volume, float layer_height, float perimeter_wi
|
||||
}
|
||||
|
||||
// Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box
|
||||
void WipeTower2::plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool,
|
||||
unsigned int new_tool, float wipe_volume)
|
||||
void WipeTower2::plan_toolchange(float z_par,
|
||||
float layer_height_par,
|
||||
unsigned int old_tool,
|
||||
unsigned int new_tool,
|
||||
float wipe_volume,
|
||||
const std::vector<unsigned int> &texture_mapping_layer_tools,
|
||||
int texture_mapping_wall_tool)
|
||||
{
|
||||
assert(m_plan.empty() || m_plan.back().z <= z_par + WT_EPSILON); // refuses to add a layer below the last one
|
||||
|
||||
if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) // if we moved to a new layer, we'll add it to m_plan first
|
||||
m_plan.push_back(WipeTowerInfo(z_par, layer_height_par));
|
||||
if (texture_mapping_wall_tool >= 0)
|
||||
m_plan.back().texture_mapping_wall_tool = size_t(texture_mapping_wall_tool);
|
||||
std::vector<size_t> &layer_texture_tools = m_plan.back().texture_mapping_layer_tools;
|
||||
for (const unsigned int tool : texture_mapping_layer_tools) {
|
||||
const size_t tool_id = size_t(tool);
|
||||
if (std::find(layer_texture_tools.begin(), layer_texture_tools.end(), tool_id) == layer_texture_tools.end())
|
||||
layer_texture_tools.emplace_back(tool_id);
|
||||
}
|
||||
|
||||
if (m_first_layer_idx == size_t(-1) && (! m_no_sparse_layers || old_tool != new_tool || m_plan.size() == 1))
|
||||
m_first_layer_idx = m_plan.size() - 1;
|
||||
@@ -2719,6 +2732,21 @@ void WipeTower2::generate(std::vector<std::vector<WipeTower::ToolChangeResult>>
|
||||
m_y_shift = (m_wipe_tower_depth-m_layer_info->depth-m_perimeter_width)/2.f;
|
||||
|
||||
int idx = first_toolchange_to_nonsoluble(layer.tool_changes);
|
||||
auto texture_wall_finish_idx = [this, &layer]() -> int {
|
||||
if (!m_prime_tower_texture.valid() || layer.texture_mapping_wall_tool == size_t(-1))
|
||||
return std::numeric_limits<int>::min();
|
||||
const int texture_wall_tool = int(layer.texture_mapping_wall_tool);
|
||||
if (layer.tool_changes.empty())
|
||||
return texture_wall_tool == int(m_current_tool) ? -1 : std::numeric_limits<int>::min();
|
||||
if (int(layer.tool_changes.front().old_tool) == texture_wall_tool)
|
||||
return -1;
|
||||
for (int i = 0; i < int(layer.tool_changes.size()); ++i)
|
||||
if (int(layer.tool_changes[i].new_tool) == texture_wall_tool)
|
||||
return i;
|
||||
return std::numeric_limits<int>::min();
|
||||
};
|
||||
if (const int texture_idx = texture_wall_finish_idx(); texture_idx != std::numeric_limits<int>::min())
|
||||
idx = texture_idx;
|
||||
WipeTower::ToolChangeResult finish_layer_tcr;
|
||||
|
||||
if (idx == -1) {
|
||||
@@ -2843,12 +2871,17 @@ Polygon WipeTower2::generate_support_rib_wall(WipeTowerWriter2&
|
||||
if (m_prime_tower_texture.valid() && result_wall.size() == 1 && !result_wall.front().points.empty()) {
|
||||
std::vector<size_t> texture_normalization_tools;
|
||||
const size_t texture_tool_count = m_prime_tower_texture.filament_colours.size();
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
if (m_layer_info != m_plan.end()) {
|
||||
if (m_layer_info != m_plan.end() && !m_layer_info->texture_mapping_layer_tools.empty()) {
|
||||
for (const size_t tool : m_layer_info->texture_mapping_layer_tools)
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool, texture_tool_count);
|
||||
} else if (m_layer_info != m_plan.end()) {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
for (const WipeTowerInfo::ToolChange &tool_change : m_layer_info->tool_changes) {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool_change.old_tool, texture_tool_count);
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool_change.new_tool, texture_tool_count);
|
||||
}
|
||||
} else {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
}
|
||||
const bool closed_texture_path = !rib_wall && !skip_points;
|
||||
std::vector<Vec2f> points;
|
||||
@@ -2983,12 +3016,17 @@ Polygon WipeTower2::generate_support_cone_wall(
|
||||
if (m_prime_tower_texture.valid() && polylines.empty()) {
|
||||
std::vector<size_t> texture_normalization_tools;
|
||||
const size_t texture_tool_count = m_prime_tower_texture.filament_colours.size();
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
if (m_layer_info != m_plan.end()) {
|
||||
if (m_layer_info != m_plan.end() && !m_layer_info->texture_mapping_layer_tools.empty()) {
|
||||
for (const size_t tool : m_layer_info->texture_mapping_layer_tools)
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool, texture_tool_count);
|
||||
} else if (m_layer_info != m_plan.end()) {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
for (const WipeTowerInfo::ToolChange &tool_change : m_layer_info->tool_changes) {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool_change.old_tool, texture_tool_count);
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, tool_change.new_tool, texture_tool_count);
|
||||
}
|
||||
} else {
|
||||
prime_tower_append_texture_tool(texture_normalization_tools, m_current_tool, texture_tool_count);
|
||||
}
|
||||
std::vector<Vec2f> ordered;
|
||||
ordered.reserve(pts.size());
|
||||
|
||||
@@ -50,7 +50,13 @@ 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, float wipe_volume = 0.f);
|
||||
void plan_toolchange(float z_par,
|
||||
float layer_height_par,
|
||||
unsigned int old_tool,
|
||||
unsigned int new_tool,
|
||||
float wipe_volume = 0.f,
|
||||
const std::vector<unsigned int> &texture_mapping_layer_tools = {},
|
||||
int texture_mapping_wall_tool = -1);
|
||||
|
||||
// Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result"
|
||||
void generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result);
|
||||
@@ -310,6 +316,8 @@ private:
|
||||
float z; // z position of the layer
|
||||
float height; // layer height
|
||||
float depth; // depth of the layer based on all layers above
|
||||
std::vector<size_t> texture_mapping_layer_tools;
|
||||
size_t texture_mapping_wall_tool{size_t(-1)};
|
||||
float toolchanges_depth() const { float sum = 0.f; for (const auto &a : tool_changes) sum += a.required_depth; return sum; }
|
||||
|
||||
std::vector<ToolChange> tool_changes;
|
||||
|
||||
@@ -3538,6 +3538,43 @@ void Print::_make_wipe_tower()
|
||||
return texture;
|
||||
};
|
||||
const PrimeTowerTextureRenderSettings prime_tower_texture = build_prime_tower_texture();
|
||||
const std::vector<size_t> prime_tower_texture_component_tools = prime_tower_texture.component_tools_for_layer_sequence();
|
||||
auto prime_tower_texture_layer_tools = [&prime_tower_texture, &prime_tower_texture_component_tools](const LayerTools &layer_tools) {
|
||||
std::vector<unsigned int> tools;
|
||||
if (!prime_tower_texture.valid())
|
||||
return tools;
|
||||
if (layer_tools.has_texture_mapping_zone && !layer_tools.texture_mapping_component_extruders.empty()) {
|
||||
tools = layer_tools.texture_mapping_component_extruders;
|
||||
return tools;
|
||||
}
|
||||
if (layer_tools.has_texture_mapping_zone && !layer_tools.texture_mapping_extruders.empty()) {
|
||||
tools = layer_tools.texture_mapping_extruders;
|
||||
return tools;
|
||||
}
|
||||
if (!prime_tower_texture_component_tools.empty()) {
|
||||
tools.reserve(prime_tower_texture_component_tools.size());
|
||||
for (const size_t tool : prime_tower_texture_component_tools)
|
||||
tools.emplace_back(unsigned(tool));
|
||||
return tools;
|
||||
}
|
||||
return tools;
|
||||
};
|
||||
auto prime_tower_texture_wall_tool = [&prime_tower_texture](const LayerTools &layer_tools) -> int {
|
||||
if (!prime_tower_texture.valid())
|
||||
return -1;
|
||||
if (layer_tools.has_texture_mapping_zone && !layer_tools.texture_mapping_extruders.empty()) {
|
||||
const size_t sequence_tool = prime_tower_texture.tool_for_layer_sequence(layer_tools.layer_index);
|
||||
if (sequence_tool != size_t(-1) && std::find(layer_tools.texture_mapping_extruders.begin(),
|
||||
layer_tools.texture_mapping_extruders.end(),
|
||||
unsigned(sequence_tool)) != layer_tools.texture_mapping_extruders.end())
|
||||
return int(sequence_tool);
|
||||
return int(layer_tools.texture_mapping_extruders.front());
|
||||
}
|
||||
const size_t tool = prime_tower_texture.tool_for_layer_sequence(layer_tools.layer_index);
|
||||
if (tool != size_t(-1))
|
||||
return int(tool);
|
||||
return -1;
|
||||
};
|
||||
|
||||
if (!is_wipe_tower_type2) {
|
||||
// in BBL machine, wipe tower is only use to prime extruder. So just use a global wipe volume.
|
||||
@@ -3584,13 +3621,17 @@ void Print::_make_wipe_tower()
|
||||
for (auto& layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
|
||||
if (!layer_tools.has_wipe_tower) continue;
|
||||
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
|
||||
std::vector<unsigned int> texture_mapping_layer_tools = prime_tower_texture_layer_tools(layer_tools);
|
||||
const int texture_mapping_wall_tool = prime_tower_texture_wall_tool(layer_tools);
|
||||
wipe_tower.plan_toolchange((float) layer_tools.print_z,
|
||||
(float) layer_tools.wipe_tower_layer_height,
|
||||
current_filament_id,
|
||||
current_filament_id,
|
||||
0.f,
|
||||
0.f,
|
||||
layer_tools.has_texture_mapping_zone && layer_tools.extruders.size() == 1);
|
||||
layer_tools.has_texture_mapping_zone && layer_tools.extruders.size() == 1,
|
||||
texture_mapping_layer_tools,
|
||||
texture_mapping_wall_tool);
|
||||
|
||||
used_filament_ids.insert(layer_tools.extruders.begin(), layer_tools.extruders.end());
|
||||
|
||||
@@ -3718,8 +3759,10 @@ void Print::_make_wipe_tower()
|
||||
if (!layer_tools.has_wipe_tower)
|
||||
continue;
|
||||
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
|
||||
std::vector<unsigned int> texture_mapping_layer_tools = prime_tower_texture_layer_tools(layer_tools);
|
||||
const int texture_mapping_wall_tool = prime_tower_texture_wall_tool(layer_tools);
|
||||
wipe_tower.plan_toolchange((float) layer_tools.print_z, (float) layer_tools.wipe_tower_layer_height, current_extruder_id,
|
||||
current_extruder_id, false);
|
||||
current_extruder_id, false, texture_mapping_layer_tools, texture_mapping_wall_tool);
|
||||
for (const auto extruder_id : layer_tools.extruders) {
|
||||
if ((first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || extruder_id !=
|
||||
current_extruder_id) {
|
||||
|
||||
Reference in New Issue
Block a user