Prime tower preview fixes

This commit is contained in:
sentientstardust
2026-05-03 14:39:29 +01:00
parent 81b0e61845
commit 988718a091
5 changed files with 109 additions and 10 deletions

View File

@@ -239,7 +239,14 @@ public:
bool empty() const { return m_layer_tools.empty(); }
const std::vector<LayerTools>& layer_tools() const { return m_layer_tools; }
std::vector<LayerTools>& layer_tools() { return m_layer_tools; }
bool has_wipe_tower() const { return ! m_layer_tools.empty() && m_first_printing_extruder != (unsigned int)-1 && m_layer_tools.front().has_wipe_tower; }
bool has_wipe_tower() const {
if (m_layer_tools.empty() || m_first_printing_extruder == (unsigned int)-1)
return false;
for (const LayerTools &layer_tools : m_layer_tools)
if (layer_tools.has_wipe_tower)
return true;
return false;
}
int get_most_used_extruder() const { return most_used_extruder; }
/*

View File

@@ -1569,14 +1569,16 @@ int GLVolumeCollection::load_wipe_tower_preview(
std::vector<ColorRGBA> extruder_colors = GUI::wxGetApp().plater()->get_extruders_colors();
std::vector<ColorRGBA> colors;
GUI::PartPlateList& ppl = GUI::wxGetApp().plater()->get_partplate_list();
std::vector<int> plate_extruders = ppl.get_plate(plate_idx)->get_wipe_tower_extruders(true);
std::vector<int> plate_extruders = ppl.get_plate(plate_idx)->get_extruders(true);
TriangleMesh wipe_tower_shell = make_cube(width, depth, height);
for (int extruder_id : plate_extruders) {
if (extruder_id <= extruder_colors.size())
if (extruder_id > 0 && extruder_id <= extruder_colors.size())
colors.push_back(extruder_colors[extruder_id - 1]);
else
else if (!extruder_colors.empty())
colors.push_back(extruder_colors[0]);
}
if (colors.empty())
colors.emplace_back(ColorRGBA::WHITE());
// Orca: make it transparent
for(auto& color : colors)

View File

@@ -123,7 +123,6 @@ float RetinaHelper::get_scale_factor() { return float(m_window->GetContentScaleF
#undef Convex
#endif
std::string& get_object_limited_text() {
static std::string object_limited_text = _u8L("An object is placed in the left/right nozzle-only area or exceeds the printable height of the left nozzle.\n"
"Please ensure the filaments used by this object are not arranged to other nozzles.");
@@ -2841,10 +2840,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
const Print* print = m_process->fff_print();
const Print* current_print = part_plate->fff_print();
const std::vector<int> wipe_tower_extruders = part_plate->get_wipe_tower_extruders(true);
const size_t texture_mapping_filaments_count =
part_plate->estimate_wipe_tower_filaments_count(&wxGetApp().preset_bundle->project_config);
const size_t wipe_tower_filaments_count = need_wipe_tower ?
std::max<size_t>(1, wipe_tower_extruders.size()) :
wipe_tower_extruders.size();
std::max<size_t>(1, texture_mapping_filaments_count) :
texture_mapping_filaments_count;
if (!need_wipe_tower && wipe_tower_filaments_count < 2) continue;
if (part_plate->get_objects_on_this_plate().empty()) continue;
@@ -2874,8 +2874,28 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
coordf_t plate_bbox_x_min_local_coord = plate_bbox_2d.min(0) - plate_origin(0);
coordf_t plate_bbox_x_max_local_coord = plate_bbox_2d.max(0) - plate_origin(0);
coordf_t plate_bbox_y_min_local_coord = plate_bbox_2d.min(1) - plate_origin(1);
coordf_t plate_bbox_y_max_local_coord = plate_bbox_2d.max(1) - plate_origin(1);
const float old_x = x;
const float old_y = y;
auto clamp_wipe_tower_axis = [](float value, coordf_t min_value, coordf_t max_value, double size, float margin) {
const float axis_min = float(min_value) + margin;
const float axis_max = float(max_value) - margin - float(size);
return axis_max < axis_min ? axis_min : std::min(std::max(value, axis_min), axis_max);
};
x = clamp_wipe_tower_axis(x, plate_bbox_x_min_local_coord, plate_bbox_x_max_local_coord, wipe_tower_size(0), margin);
y = clamp_wipe_tower_axis(y, plate_bbox_y_min_local_coord, plate_bbox_y_max_local_coord, wipe_tower_size(1), margin);
if (std::abs(x - old_x) > EPSILON) {
ConfigOptionFloat x_opt(x);
dynamic_cast<ConfigOptionFloats*>(proj_cfg.option("wipe_tower_x"))->set_at(&x_opt, plate_id, 0);
}
if (std::abs(y - old_y) > EPSILON) {
ConfigOptionFloat y_opt(y);
dynamic_cast<ConfigOptionFloats*>(proj_cfg.option("wipe_tower_y"))->set_at(&y_opt, plate_id, 0);
}
if (!current_print->is_step_done(psWipeTower) || !current_print->wipe_tower_data().wipe_tower_mesh_data) {
// update for wipe tower position
{

View File

@@ -170,6 +170,71 @@ std::vector<int> expand_wipe_tower_extruders(const std::vector<int> &extruders,
return expanded;
}
size_t estimate_wipe_tower_filaments_count_for_texture_mapping(const std::vector<int> &extruders, const DynamicPrintConfig *config)
{
if (extruders.empty())
return 0;
const std::vector<std::string> filament_colours = wipe_tower_filament_colours(config);
const size_t num_physical = filament_colours.size();
if (num_physical == 0)
return 0;
TextureMappingManager texture_mgr;
const std::string texture_mapping_definitions = config != nullptr && config->has("texture_mapping_definitions") ?
config->opt_string("texture_mapping_definitions") :
(wxGetApp().preset_bundle != nullptr && wxGetApp().preset_bundle->project_config.has("texture_mapping_definitions") ?
wxGetApp().preset_bundle->project_config.opt_string("texture_mapping_definitions") :
std::string());
texture_mgr.load_entries(texture_mapping_definitions, filament_colours);
std::vector<unsigned int> physical_ids;
size_t texture_slots = 0;
bool texture_changes_physical_component = false;
for (const int extruder : extruders) {
if (extruder <= 0)
continue;
const unsigned int filament_id = static_cast<unsigned int>(extruder);
if (filament_id <= num_physical) {
physical_ids.emplace_back(filament_id);
continue;
}
const TextureMappingZone *zone = texture_mgr.zone_from_id(filament_id);
if (zone == nullptr || !zone->enabled || zone->deleted)
continue;
std::vector<unsigned int> component_ids = zone->is_image_texture() ?
TextureMappingManager::effective_texture_component_ids(*zone, num_physical, filament_colours) :
TextureMappingManager::selected_component_ids(*zone, num_physical);
component_ids.erase(std::remove_if(component_ids.begin(),
component_ids.end(),
[num_physical](unsigned int id) { return id == 0 || id > num_physical; }),
component_ids.end());
std::sort(component_ids.begin(), component_ids.end());
component_ids.erase(std::unique(component_ids.begin(), component_ids.end()), component_ids.end());
if (component_ids.empty())
continue;
if (component_ids.size() == 1) {
physical_ids.emplace_back(component_ids.front());
} else {
++texture_slots;
texture_changes_physical_component = true;
}
}
std::sort(physical_ids.begin(), physical_ids.end());
physical_ids.erase(std::unique(physical_ids.begin(), physical_ids.end()), physical_ids.end());
size_t count = physical_ids.size() + texture_slots;
if (count < 2 && texture_changes_physical_component)
count = 2;
return count;
}
ColorRGBA PartPlate::SELECT_COLOR = { 0.2666f, 0.2784f, 0.2784f, 1.0f }; //{ 0.4196f, 0.4235f, 0.4235f, 1.0f };
ColorRGBA PartPlate::UNSELECT_COLOR = { 0.82f, 0.82f, 0.82f, 1.0f };
ColorRGBA PartPlate::UNSELECT_DARK_COLOR = { 0.384f, 0.384f, 0.412f, 1.0f };
@@ -1730,6 +1795,11 @@ std::vector<int> PartPlate::get_wipe_tower_extruders(bool conside_custom_gcode)
return expand_wipe_tower_extruders(get_extruders(conside_custom_gcode), config);
}
size_t PartPlate::estimate_wipe_tower_filaments_count(const DynamicPrintConfig *config) const
{
return estimate_wipe_tower_filaments_count_for_texture_mapping(get_extruders(true), config);
}
std::vector<int> PartPlate::get_extruders_under_cli(bool conside_custom_gcode, DynamicPrintConfig& full_config) const
{
std::vector<int> plate_extruders;
@@ -2239,8 +2309,7 @@ Vec3d PartPlate::estimate_wipe_tower_size(const DynamicPrintConfig & config, con
// empty plate
if (plate_extruder_size == 0)
{
std::vector<int> plate_extruders = get_wipe_tower_extruders(true);
plate_extruder_size = plate_extruders.size();
plate_extruder_size = int(estimate_wipe_tower_filaments_count(&config));
}
if (plate_extruder_size == 0)
return wipe_tower_size;

View File

@@ -329,6 +329,7 @@ public:
Vec3d get_origin() { return m_origin; }
//Vec3d calculate_wipe_tower_size(const DynamicPrintConfig &config, const double w, const double wipe_volume, int plate_extruder_size = 0, bool use_global_objects = false) const;
size_t estimate_wipe_tower_filaments_count(const DynamicPrintConfig *config = nullptr) const;
Vec3d estimate_wipe_tower_size(const DynamicPrintConfig & config, const double w, const double wipe_volume, int extruder_count = 1, int plate_extruder_size = 0, bool use_global_objects = false, bool enable_wrapping_detection = false) const;
arrangement::ArrangePolygon estimate_wipe_tower_polygon(const DynamicPrintConfig & config, int plate_index, Vec3d& wt_pos, Vec3d& wt_size, int extruder_count = 1, int plate_extruder_size = 0, bool use_global_objects = false) const;
bool check_objects_empty_and_gcode3mf(std::vector<int> &result) const;