FIX: auto-arrange ignores wipe tower due to supports
Wipe tower is needed if support base and interface use different materials. Jira: STUDIO-1336 Change-Id: I006ece952aac1a0f0a57721c2cd1b52b2ceee28a (cherry picked from commit 1a387e4b1607dee36f5abe499892f027e244fbeb)
This commit is contained in:
parent
fb4f30a4a4
commit
9f96c8adec
7 changed files with 57 additions and 54 deletions
|
@ -836,7 +836,7 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
|
|||
item.binId(arrpoly.bed_idx);
|
||||
item.priority(arrpoly.priority);
|
||||
item.itemId(arrpoly.itemid);
|
||||
item.extrude_id = arrpoly.extrude_ids.back();
|
||||
item.extrude_id = arrpoly.extrude_ids.front();
|
||||
item.height = arrpoly.height;
|
||||
item.name = arrpoly.name;
|
||||
//BBS: add virtual object logic
|
||||
|
|
|
@ -2923,7 +2923,7 @@ double ModelInstance::get_auto_brim_width() const
|
|||
return get_auto_brim_width(DeltaT, adhcoeff);
|
||||
}
|
||||
|
||||
void ModelInstance::get_arrange_polygon(void* ap) const
|
||||
void ModelInstance::get_arrange_polygon(void *ap, const Slic3r::DynamicPrintConfig &config_global) const
|
||||
{
|
||||
// static const double SIMPLIFY_TOLERANCE_MM = 0.1;
|
||||
|
||||
|
@ -2962,6 +2962,16 @@ void ModelInstance::get_arrange_polygon(void* ap) const
|
|||
ret.extrude_ids = volume->get_extruders();
|
||||
if (ret.extrude_ids.empty()) //the default extruder
|
||||
ret.extrude_ids.push_back(1);
|
||||
|
||||
// get per-object support extruders
|
||||
auto op = object->get_config_value<ConfigOptionBool>(config_global, "enable_support");
|
||||
bool is_support_enabled = op && op->getBool();
|
||||
if (is_support_enabled) {
|
||||
auto op1 = object->get_config_value<ConfigOptionInt>(config_global, "support_filament");
|
||||
auto op2 = object->get_config_value<ConfigOptionInt>(config_global, "support_interface_filament");
|
||||
if (op1) ret.extrude_ids.push_back(op1->getInt());
|
||||
if (op2) ret.extrude_ids.push_back(op2->getInt());
|
||||
}
|
||||
}
|
||||
|
||||
indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, EnforcerBlockerType type) const
|
||||
|
|
|
@ -1111,7 +1111,7 @@ public:
|
|||
|
||||
// Getting the input polygon for arrange
|
||||
// We use void* as input type to avoid including Arrange.hpp in Model.hpp.
|
||||
void get_arrange_polygon(void* arrange_polygon) const;
|
||||
void get_arrange_polygon(void *arrange_polygon, const Slic3r::DynamicPrintConfig &config = Slic3r::DynamicPrintConfig()) const;
|
||||
|
||||
// Apply the arrange result on the ModelInstance
|
||||
void apply_arrange_result(const Vec2d& offs, double rotation)
|
||||
|
|
|
@ -88,9 +88,9 @@ void duplicate_objects(Model &model, size_t copies_num)
|
|||
|
||||
// Set up arrange polygon for a ModelInstance and Wipe tower
|
||||
template<class T>
|
||||
arrangement::ArrangePolygon get_arrange_poly(T obj)
|
||||
arrangement::ArrangePolygon get_arrange_poly(T obj, const Slic3r::DynamicPrintConfig& config)
|
||||
{
|
||||
ArrangePolygon ap = obj.get_arrange_polygon();
|
||||
ArrangePolygon ap = obj.get_arrange_polygon(config);
|
||||
//BBS: always set bed_idx to 0 to use original transforms with no bed_idx
|
||||
//if this object is not arranged, it can keep the original transforms
|
||||
//ap.bed_idx = ap.translation.x() / bed_stride_x(plater);
|
||||
|
@ -110,14 +110,14 @@ arrangement::ArrangePolygon get_arrange_poly(T obj)
|
|||
}
|
||||
|
||||
template<>
|
||||
arrangement::ArrangePolygon get_arrange_poly(ModelInstance* inst)
|
||||
arrangement::ArrangePolygon get_arrange_poly(ModelInstance* inst, const Slic3r::DynamicPrintConfig& config)
|
||||
{
|
||||
return get_arrange_poly(PtrWrapper{ inst });
|
||||
return get_arrange_poly(PtrWrapper{ inst },config);
|
||||
}
|
||||
|
||||
ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r::DynamicPrintConfig& config)
|
||||
{
|
||||
ArrangePolygon ap = get_arrange_poly(PtrWrapper{ instance });
|
||||
ArrangePolygon ap = get_arrange_poly(PtrWrapper{ instance }, config);
|
||||
|
||||
//BBS: add temperature information
|
||||
if (config.has("curr_bed_type")) {
|
||||
|
@ -127,20 +127,20 @@ ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r::
|
|||
|
||||
const ConfigOptionInts* bed_opt = config.option<ConfigOptionInts>(get_bed_temp_key(curr_bed_type));
|
||||
if (bed_opt != nullptr)
|
||||
ap.bed_temp = bed_opt->get_at(ap.extrude_ids.back()-1);
|
||||
ap.bed_temp = bed_opt->get_at(ap.extrude_ids.front()-1);
|
||||
|
||||
const ConfigOptionInts* bed_opt_1st_layer = config.option<ConfigOptionInts>(get_bed_temp_1st_layer_key(curr_bed_type));
|
||||
if (bed_opt_1st_layer != nullptr)
|
||||
ap.first_bed_temp = bed_opt_1st_layer->get_at(ap.extrude_ids.back()-1);
|
||||
ap.first_bed_temp = bed_opt_1st_layer->get_at(ap.extrude_ids.front()-1);
|
||||
}
|
||||
|
||||
if (config.has("nozzle_temperature")) //get the print temperature
|
||||
ap.print_temp = config.opt_int("nozzle_temperature", ap.extrude_ids.back() - 1);
|
||||
ap.print_temp = config.opt_int("nozzle_temperature", ap.extrude_ids.front() - 1);
|
||||
if (config.has("nozzle_temperature_initial_layer")) //get the nozzle_temperature_initial_layer
|
||||
ap.first_print_temp = config.opt_int("nozzle_temperature_initial_layer", ap.extrude_ids.back() - 1);
|
||||
ap.first_print_temp = config.opt_int("nozzle_temperature_initial_layer", ap.extrude_ids.front() - 1);
|
||||
|
||||
if (config.has("temperature_vitrification")) {
|
||||
ap.vitrify_temp = config.opt_int("temperature_vitrification", ap.extrude_ids.back() - 1);
|
||||
ap.vitrify_temp = config.opt_int("temperature_vitrification", ap.extrude_ids.front() - 1);
|
||||
}
|
||||
|
||||
// get brim width
|
||||
|
|
|
@ -71,10 +71,10 @@ template<class T> struct PtrWrapper
|
|||
|
||||
explicit PtrWrapper(T* p) : ptr{ p } {}
|
||||
|
||||
arrangement::ArrangePolygon get_arrange_polygon() const
|
||||
arrangement::ArrangePolygon get_arrange_polygon(const Slic3r::DynamicPrintConfig &config = Slic3r::DynamicPrintConfig()) const
|
||||
{
|
||||
arrangement::ArrangePolygon ap;
|
||||
ptr->get_arrange_polygon(&ap);
|
||||
ptr->get_arrange_polygon(&ap, config);
|
||||
return ap;
|
||||
}
|
||||
|
||||
|
@ -86,12 +86,12 @@ template<class T> struct PtrWrapper
|
|||
};
|
||||
|
||||
template<class T>
|
||||
arrangement::ArrangePolygon get_arrange_poly(T obj);
|
||||
arrangement::ArrangePolygon get_arrange_poly(T obj, const DynamicPrintConfig &config = DynamicPrintConfig());
|
||||
|
||||
template<>
|
||||
arrangement::ArrangePolygon get_arrange_poly(ModelInstance* inst);
|
||||
arrangement::ArrangePolygon get_arrange_poly(ModelInstance* inst, const DynamicPrintConfig& config);
|
||||
|
||||
ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r::DynamicPrintConfig& config);
|
||||
ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const DynamicPrintConfig& config);
|
||||
}
|
||||
|
||||
#endif // MODELARRANGE_HPP
|
||||
|
|
|
@ -237,39 +237,48 @@ void ArrangeJob::prepare_all() {
|
|||
prepare_wipe_tower();
|
||||
}
|
||||
|
||||
// 准备料塔。逻辑如下:
|
||||
// 1. 如果料塔被禁用,或是逐件打印,则不需要料塔
|
||||
// 2. 以下两种情况需要料塔:1)某对象是多色对象;2)打开了支撑,且支撑体与接触面使用的是不同材料
|
||||
// 3. 如果允许不同材料落在相同盘,则以下情况也需要料塔:1)所有选定对象中使用了多种热床温度相同的材料(比如颜色不同的PLA)
|
||||
void ArrangeJob::prepare_wipe_tower()
|
||||
{
|
||||
bool need_wipe_tower = false;
|
||||
|
||||
// if wipe tower is explicitly disabled, no need to estimate
|
||||
auto &print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
||||
if (!print.config().enable_prime_tower) return;
|
||||
DynamicPrintConfig ¤t_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
auto op = current_config.option("enable_prime_tower");
|
||||
if (op && op->getBool() == false || params.is_seq_print) return;
|
||||
|
||||
// estimate if we need wipe tower for all plates:
|
||||
// need wipe tower if some object has multiple extruders (has paint-on colors or support material)
|
||||
for (const auto &item : m_selected) {
|
||||
std::set<int> obj_extruders;
|
||||
for (int id : item.extrude_ids) obj_extruders.insert(id);
|
||||
if (obj_extruders.size() > 1) {
|
||||
need_wipe_tower = true;
|
||||
BOOST_LOG_TRIVIAL(info) << "arrange: need wipe tower because object " << item.name << " has multiple extruders (has paint-on colors)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if multile extruders have same bed temp, we need wipe tower
|
||||
if (!params.is_seq_print) {
|
||||
// need wipe tower if some object has multiple extruders (has paint-on colors)
|
||||
if (!params.allow_multi_materials_on_same_plate) {
|
||||
for (const auto &item : m_selected)
|
||||
if (item.extrude_ids.size() > 1) {
|
||||
need_wipe_tower = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
std::map<int, std::set<int>> bedTemp2extruderIds;
|
||||
for (const auto &item : m_selected)
|
||||
for (auto id : item.extrude_ids) { bedTemp2extruderIds[item.bed_temp].insert(id); }
|
||||
for (const auto &be : bedTemp2extruderIds) {
|
||||
if (be.second.size() > 1) {
|
||||
need_wipe_tower = true;
|
||||
break;
|
||||
}
|
||||
if (params.allow_multi_materials_on_same_plate) {
|
||||
std::map<int, std::set<int>> bedTemp2extruderIds;
|
||||
for (const auto &item : m_selected)
|
||||
for (auto id : item.extrude_ids) { bedTemp2extruderIds[item.bed_temp].insert(id); }
|
||||
for (const auto &be : bedTemp2extruderIds) {
|
||||
if (be.second.size() > 1) {
|
||||
need_wipe_tower = true;
|
||||
BOOST_LOG_TRIVIAL(info) << "arrange: need wipe tower because allow_multi_materials_on_same_plate=true and we have multiple extruders of same type";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "arrange: need_wipe_tower=" << need_wipe_tower;
|
||||
|
||||
if (need_wipe_tower) {
|
||||
// BBS: prepare wipe tower for all possible plates
|
||||
// check all plates to see if wipe tower is already there
|
||||
ArrangePolygon wipe_tower_ap;
|
||||
std::vector<bool> plates_have_wipe_tower(MAX_NUM_PLATES, false);
|
||||
for (int bedid = 0; bedid < MAX_NUM_PLATES; bedid++)
|
||||
|
@ -300,20 +309,6 @@ void ArrangeJob::prepare_wipe_tower()
|
|||
}
|
||||
|
||||
|
||||
arrangement::ArrangePolygon ArrangeJob::get_arrange_poly_(ModelInstance *mi)
|
||||
{
|
||||
arrangement::ArrangePolygon ap = get_arrange_poly(mi);
|
||||
|
||||
auto setter = ap.setter;
|
||||
ap.setter = [this, setter, mi](const arrangement::ArrangePolygon &set_ap) {
|
||||
setter(set_ap);
|
||||
if (!set_ap.is_arranged())
|
||||
m_unarranged.emplace_back(mi);
|
||||
};
|
||||
|
||||
return ap;
|
||||
}
|
||||
|
||||
//BBS: prepare current part plate for arranging
|
||||
void ArrangeJob::prepare_partplate() {
|
||||
clear_input();
|
||||
|
|
|
@ -38,8 +38,6 @@ class ArrangeJob : public PlaterJob
|
|||
void prepare_partplate();
|
||||
void prepare_wipe_tower();
|
||||
|
||||
ArrangePolygon get_arrange_poly_(ModelInstance* mi);
|
||||
|
||||
ArrangePolygon prepare_arrange_polygon(void* instance);
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in a new issue