Merge branch 'master-remote' into SoftFever

This commit is contained in:
SoftFever 2022-10-14 20:40:22 +08:00
commit 834d43af1d
38 changed files with 432 additions and 158 deletions

View file

@ -20,6 +20,50 @@ namespace Slic3r {
const static bool g_wipe_into_objects = false;
void dfs_get_all_sorted_extruders(const std::vector<std::vector<float>> & wipe_volumes,
const std::vector<unsigned int> & all_extruders,
std::vector<unsigned int> & sorted_extruders,
float flush_volume,
std::map<float, std::vector<unsigned int>> &volumes_to_extruder_order)
{
if (sorted_extruders.size() == all_extruders.size()) {
volumes_to_extruder_order.insert(std::pair(flush_volume, sorted_extruders));
return;
}
for (auto extruder_id : all_extruders) {
if (sorted_extruders.empty()) {
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
sorted_extruders.pop_back();
} else {
auto itor = std::find(sorted_extruders.begin(), sorted_extruders.end(), extruder_id);
if (itor == sorted_extruders.end()) {
float delta_flush_volume = wipe_volumes[sorted_extruders.back()][extruder_id];
flush_volume += delta_flush_volume;
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
flush_volume -= delta_flush_volume;
sorted_extruders.pop_back();
}
}
}
}
std::vector<unsigned int> get_extruders_order(const std::vector<std::vector<float>> &wipe_volumes, std::vector<unsigned int> all_extruders, unsigned int start_extruder_id)
{
if (all_extruders.size() > 1) {
std::vector<unsigned int> sorted_extruders;
auto iter = std::find(all_extruders.begin(), all_extruders.end(), start_extruder_id);
if (iter != all_extruders.end()) { sorted_extruders.push_back(start_extruder_id); }
std::map<float, std::vector<unsigned int>> volumes_to_extruder_order;
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, 0, volumes_to_extruder_order);
if (volumes_to_extruder_order.size() > 0) return volumes_to_extruder_order.begin()->second;
}
return all_extruders;
}
// Returns true in case that extruder a comes before b (b does not have to be present). False otherwise.
bool LayerTools::is_extruder_order(unsigned int a, unsigned int b) const
{
@ -471,6 +515,9 @@ void ToolOrdering::reorder_extruders(unsigned int last_extruder_id)
assert(extruder_id > 0);
-- extruder_id;
}
// reorder the extruders for minimum flush volume
reorder_extruders_for_minimum_flush_volume();
}
// BBS
@ -539,6 +586,9 @@ void ToolOrdering::reorder_extruders(std::vector<unsigned int> tool_order_layer0
assert(extruder_id > 0);
--extruder_id;
}
// reorder the extruders for minimum flush volume
reorder_extruders_for_minimum_flush_volume();
}
void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height)
@ -670,6 +720,28 @@ void ToolOrdering::collect_extruder_statistics(bool prime_multi_material)
}
}
void ToolOrdering::reorder_extruders_for_minimum_flush_volume()
{
if (!m_print_config_ptr || m_layer_tools.empty())
return;
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
std::vector<float> flush_matrix(cast<float>(m_print_config_ptr->flush_volumes_matrix.values));
const unsigned int number_of_extruders = (unsigned int) (sqrt(flush_matrix.size()) + EPSILON);
// Extract purging volumes for each extruder pair:
std::vector<std::vector<float>> wipe_volumes;
for (unsigned int i = 0; i < number_of_extruders; ++i)
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders));
unsigned int current_extruder_id = -1;
for (LayerTools& lt : m_layer_tools) {
if (lt.extruders.empty())
continue;
lt.extruders = get_extruders_order(wipe_volumes, lt.extruders, current_extruder_id);
current_extruder_id = lt.extruders.back();
}
}
// Layers are marked for infinite skirt aka draft shield. Not all the layers have to be printed.
void ToolOrdering::mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height)
{

View file

@ -194,6 +194,7 @@ private:
void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height);
void mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height);
void collect_extruder_statistics(bool prime_multi_material);
void reorder_extruders_for_minimum_flush_volume();
// BBS
std::vector<unsigned int> generate_first_layer_tool_order(const Print& print);

View file

@ -38,54 +38,6 @@ PrintRegion::PrintRegion(PrintRegionConfig &&config) : PrintRegion(std::move(con
//BBS
float Print::min_skirt_length = 0;
void dfs_get_all_sorted_extruders(const std::vector<std::vector<float>>& wipe_volumes,
const std::vector<unsigned int>& all_extruders,
std::vector<unsigned int> & sorted_extruders,
float flush_volume,
std::map<float, std::vector<unsigned int>> & volumes_to_extruder_order)
{
if (sorted_extruders.size() == all_extruders.size()) {
volumes_to_extruder_order.insert(std::pair(flush_volume, sorted_extruders));
return;
}
for (auto extruder_id : all_extruders) {
if (sorted_extruders.empty()) {
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
sorted_extruders.pop_back();
} else {
auto itor = std::find(sorted_extruders.begin(), sorted_extruders.end(), extruder_id);
if (itor == sorted_extruders.end()) {
float delta_flush_volume = wipe_volumes[sorted_extruders.back()][extruder_id];
flush_volume += delta_flush_volume;
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
flush_volume -= delta_flush_volume;
sorted_extruders.pop_back();
}
}
}
}
std::vector<unsigned int> get_extruders_order(const std::vector<std::vector<float>> &wipe_volumes,
std::vector<unsigned int> all_extruders,
unsigned int start_extruder_id)
{
if (all_extruders.size() > 1) {
std::vector<unsigned int> sorted_extruders;
auto iter = std::find(all_extruders.begin(), all_extruders.end(), start_extruder_id);
if (iter != all_extruders.end()) {
sorted_extruders.push_back(start_extruder_id);
}
std::map<float, std::vector<unsigned int>> volumes_to_extruder_order;
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, 0, volumes_to_extruder_order);
if(volumes_to_extruder_order.size() > 0)
return volumes_to_extruder_order.begin()->second;
}
return all_extruders;
}
void Print::clear()
{
std::scoped_lock<std::mutex> lock(this->state_mutex());
@ -490,11 +442,11 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
//juedge the exclude area
if (!intersection(exclude_polys, convex_hull_no_offset).empty()) {
if (single_object_exception.string.empty()) {
single_object_exception.string = (boost::format(L("%1% is too close to exclusion area, there will be collisions when printing.")) %instance.model_instance->get_object()->name).str();
single_object_exception.string = (boost::format(L("%1% is too close to exclusion area, there may be collisions when printing.")) %instance.model_instance->get_object()->name).str();
single_object_exception.object = instance.model_instance->get_object();
}
else {
single_object_exception.string += (boost::format(L("\n%1% is too close to exclusion area, there will be collisions when printing.")) %instance.model_instance->get_object()->name).str();
single_object_exception.string += (boost::format(L("\n%1% is too close to exclusion area, there may be collisions when printing.")) %instance.model_instance->get_object()->name).str();
single_object_exception.object = nullptr;
}
//if (polygons) {
@ -694,14 +646,14 @@ static StringObjectException layered_print_cleareance_valid(const Print &print,
convex_hulls_temp.push_back(convex_hull);
if (!intersection(convex_hulls_other, convex_hulls_temp).empty()) {
if (warning) {
warning->string = inst->model_instance->get_object()->name + L(" is too close to others, there will be collisions when printing.\n");
warning->string = inst->model_instance->get_object()->name + L(" is too close to others, there may be collisions when printing.\n");
warning->object = inst->model_instance->get_object();
}
}
if (!intersection(exclude_polys, convex_hull).empty()) {
return {inst->model_instance->get_object()->name + L(" is too close to exclusion area, there will be collisions when printing.\n"), inst->model_instance->get_object()};
return {inst->model_instance->get_object()->name + L(" is too close to exclusion area, there may be collisions when printing.\n"), inst->model_instance->get_object()};
/*if (warning) {
warning->string = inst->model_instance->get_object()->name + L(" is too close to exclusion area, there will be collisions when printing.\n");
warning->string = inst->model_instance->get_object()->name + L(" is too close to exclusion area, there may be collisions when printing.\n");
warning->object = inst->model_instance->get_object();
}*/
}
@ -739,7 +691,7 @@ static StringObjectException layered_print_cleareance_valid(const Print &print,
}
if (!intersection(exclude_polys, convex_hulls_temp).empty()) {
/*if (warning) {
warning->string += L("Prime Tower is too close to exclusion area, there will be collisions when printing.\n");
warning->string += L("Prime Tower is too close to exclusion area, there may be collisions when printing.\n");
}*/
return {L("Prime Tower") + L(" is too close to exclusion area, and collisions will be caused.\n")};
}
@ -1903,8 +1855,6 @@ void Print::_make_wipe_tower()
bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id, false);
layer_tools.extruders = get_extruders_order(wipe_volumes, layer_tools.extruders, current_extruder_id);
for (const auto extruder_id : layer_tools.extruders) {
// BBS: priming logic is removed, so no need to do toolchange for first extruder
if (/*(first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || */extruder_id != current_extruder_id) {

View file

@ -2271,11 +2271,9 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
for (Node* p_node : layer_contact_nodes)
{
if (p_node->type == ePolygon) {
Node* next_node = new Node(*p_node);
next_node->distance_to_top++;
next_node->support_roof_layers_below--;
next_node->print_z -= m_object->get_layer(layer_nr)->height;
next_node->to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[layer_nr], next_node->position);
const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[layer_nr], p_node->position);
Node * next_node = new Node(p_node->position, p_node->distance_to_top + 1, p_node->skin_direction, p_node->support_roof_layers_below - 1, to_buildplate, p_node,
m_object->get_layer(layer_nr - 1)->print_z, m_object->get_layer(layer_nr - 1)->height);
contact_nodes[layer_nr - 1].emplace_back(next_node);
}
}
@ -2607,6 +2605,20 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
}
}
// delete nodes with no children (means either it's a single layer nodes, or the branch has been deleted but not completely)
for (size_t layer_nr = contact_nodes.size() - 1; layer_nr > 0; layer_nr--){
auto layer_contact_nodes = contact_nodes[layer_nr];
for (Node *p_node : layer_contact_nodes) {
if (p_node->child==nullptr) {
std::vector<Node *>::iterator to_erase = std::find(contact_nodes[layer_nr].begin(), contact_nodes[layer_nr].end(), p_node);
if (to_erase != contact_nodes[layer_nr].end()) {
to_free_node_set.insert(*to_erase);
contact_nodes[layer_nr].erase(to_erase);
}
}
}
}
BOOST_LOG_TRIVIAL(debug) << "after m_avoidance_cache.size()=" << m_ts_data->m_avoidance_cache.size();
for (Node *node : to_free_node_set)

View file

@ -222,7 +222,7 @@ public:
, height(0.0)
{}
Node(const Point position, const size_t distance_to_top, const bool skin_direction, const int support_roof_layers_below, const bool to_buildplate, Node* const parent,
Node(const Point position, const size_t distance_to_top, const bool skin_direction, const int support_roof_layers_below, const bool to_buildplate, Node* parent,
coordf_t print_z_, coordf_t height_)
: distance_to_top(distance_to_top)
, position(position)
@ -233,7 +233,13 @@ public:
, parent(parent)
, print_z(print_z_)
, height(height_)
{}
{
if (parent) {
type = parent->type;
overhang = parent->overhang;
parent->child = this;
}
}
#ifdef DEBUG // Clear the delete node's data so if there's invalid access after, we may get a clue by inspecting that node.
~Node()
@ -294,6 +300,7 @@ public:
* the entire branch needs to be known.
*/
Node *parent;
Node *child = nullptr;
/*!
* \brief All neighbours (on the same layer) that where merged into this node.