FIX: top z distance inaccurate if it's too large
The top z gap should be split if it's too large. Also we use same logic for both synced and independent support layer. jira: STUDIO-7232 github: #4191 Change-Id: Idca792e8fa51a83c2a09441ecac64d40b91d6390
This commit is contained in:
parent
2af6c4f4f4
commit
c262a7ea13
|
@ -3160,71 +3160,72 @@ void TreeSupport::smooth_nodes(std::vector<std::vector<SupportNode*>>& contact_n
|
|||
|
||||
std::vector<LayerHeightData> TreeSupport::plan_layer_heights(std::vector<std::vector<SupportNode *>> &contact_nodes)
|
||||
{
|
||||
const coordf_t max_layer_height = m_slicing_params.max_layer_height;
|
||||
const coordf_t layer_height = m_object_config->layer_height.value;
|
||||
coordf_t z_distance_top = m_slicing_params.gap_support_object;
|
||||
// BBS: add extra distance if thick bridge is enabled
|
||||
// Note: normal support uses print_z, but tree support uses integer layers, so we need to subtract layer_height
|
||||
if (!m_slicing_params.soluble_interface && m_object_config->thick_bridges) {
|
||||
z_distance_top += m_object->layers()[0]->regions()[0]->region().bridging_height_avg(*m_print_config) - layer_height;
|
||||
}
|
||||
const size_t support_roof_layers = m_object_config->support_interface_top_layers.value;
|
||||
const int z_distance_top_layers = round_up_divide(scale_(z_distance_top), scale_(layer_height)) + 1;
|
||||
std::vector<LayerHeightData> layer_heights(contact_nodes.size());
|
||||
std::vector<int> bounds;
|
||||
std::map<int, std::pair<coordf_t,coordf_t>> bounds; // layer_nr:(print_z, height)
|
||||
|
||||
if (layer_height == max_layer_height || !m_support_params.independent_layer_height) {
|
||||
for (int layer_nr = 0; layer_nr < contact_nodes.size(); layer_nr++) {
|
||||
layer_heights[layer_nr] = {m_object->get_layer(layer_nr)->print_z, m_object->get_layer(layer_nr)->height, layer_nr > 0 ? size_t(layer_nr - 1) : 0};
|
||||
}
|
||||
}
|
||||
else {
|
||||
bounds.push_back(0);
|
||||
{
|
||||
// Keep first layer still
|
||||
layer_heights[0] = { m_object->get_layer(0)->print_z, m_object->get_layer(0)->height, 0 };
|
||||
bounds[0] = { m_object->get_layer(0)->print_z, m_object->get_layer(0)->height};
|
||||
// Collect top contact layers
|
||||
for (int layer_nr = 1; layer_nr < contact_nodes.size(); layer_nr++) {
|
||||
if (!contact_nodes[layer_nr].empty()) {
|
||||
bounds.push_back(layer_nr);
|
||||
layer_heights[layer_nr].print_z = contact_nodes[layer_nr].front()->print_z;
|
||||
layer_heights[layer_nr].height = contact_nodes[layer_nr].front()->height;
|
||||
BOOST_LOG_TRIVIAL(trace) << "plan_layer_heights0 print_z, height, layer_nr: " << layer_heights[layer_nr].print_z << " " << layer_heights[layer_nr].height << " "
|
||||
<< layer_nr;
|
||||
coordf_t print_z = contact_nodes[layer_nr].front()->print_z;
|
||||
coordf_t height = contact_nodes[layer_nr].front()->height;
|
||||
if(height>m_slicing_params.max_suport_layer_height){
|
||||
// split this layer into multiple layers if the gap is too big
|
||||
int num_layers=std::ceil(height/m_slicing_params.max_suport_layer_height);
|
||||
coordf_t new_height= height/num_layers;
|
||||
for(auto& node: contact_nodes[layer_nr]) {
|
||||
node->height = new_height;
|
||||
node->distance_to_top = -num_layers;
|
||||
node->support_roof_layers_below+=num_layers-1;
|
||||
}
|
||||
}
|
||||
std::set<int> s(bounds.begin(), bounds.end());
|
||||
bounds.assign(s.begin(), s.end());
|
||||
|
||||
for (size_t idx_extreme = 1; idx_extreme < bounds.size(); idx_extreme++) {
|
||||
int extr2_layer_nr = bounds[idx_extreme];
|
||||
coordf_t extr2z = layer_heights[extr2_layer_nr].bottom_z();
|
||||
int extr1_layer_nr = bounds[idx_extreme - 1];
|
||||
coordf_t extr1z = layer_heights[extr1_layer_nr].print_z;
|
||||
for (int i=0; i<num_layers; ++i) {
|
||||
bounds[layer_nr-i]={print_z, new_height};
|
||||
print_z-=new_height;
|
||||
}
|
||||
}else{
|
||||
bounds[layer_nr]={print_z, height};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto it1 = bounds.begin();
|
||||
auto it2 = bounds.begin();
|
||||
it2++;
|
||||
for (; it2 != bounds.end();it1++, it2++) {
|
||||
int extr2_layer_nr = it2->first;
|
||||
coordf_t extr2z = it2->second.first - it2->second.second; // bottom_z of upper bound
|
||||
int extr1_layer_nr = it1->first; //bounds[idx_extreme - 1];
|
||||
coordf_t extr1z = it1->second.first;// print_z of lower bound
|
||||
coordf_t dist = extr2z - extr1z;
|
||||
|
||||
layer_heights[extr2_layer_nr].print_z = it2->second.first;
|
||||
layer_heights[extr2_layer_nr].height = it2->second.second;
|
||||
BOOST_LOG_TRIVIAL(trace) << "plan_layer_heights0 print_z, height, layer_nr: " << layer_heights[extr2_layer_nr].print_z << " " << layer_heights[extr2_layer_nr].height << " " << extr2_layer_nr;
|
||||
|
||||
// Insert intermediate layers.
|
||||
size_t n_layers_extra = size_t(ceil(dist / (m_slicing_params.max_suport_layer_height + EPSILON)));
|
||||
int actual_internel_layers = extr2_layer_nr - extr1_layer_nr - 1;
|
||||
int extr_layers_left = extr2_layer_nr - extr1_layer_nr - n_layers_extra - 1;
|
||||
size_t n_layers_extra = m_support_params.independent_layer_height ? size_t(ceil(dist / (m_slicing_params.max_suport_layer_height))) :
|
||||
size_t(ceil(dist / (m_slicing_params.min_layer_height)));
|
||||
if (n_layers_extra < 1)
|
||||
continue;
|
||||
|
||||
coordf_t step = dist / coordf_t(n_layers_extra);
|
||||
coordf_t print_z = extr1z + step;
|
||||
//assert(step >= layer_height - EPSILON);
|
||||
coordf_t extr2z_large_steps = extr2z;
|
||||
coordf_t print_z = extr1z;
|
||||
for (int layer_nr = extr1_layer_nr + 1; layer_nr < extr2_layer_nr; layer_nr++) {
|
||||
// if (curr_layer_nodes.empty()) continue;
|
||||
if (std::abs(print_z - m_object->get_layer(layer_nr)->print_z) < step / 2 + EPSILON || extr_layers_left < 1) {
|
||||
Layer* layer = m_object->get_layer(layer_nr);
|
||||
if (!m_support_params.independent_layer_height) step = layer->height;
|
||||
if (std::abs((print_z+step) - layer->print_z) < step / 2 + EPSILON) {
|
||||
print_z += step;
|
||||
layer_heights[layer_nr].print_z = print_z;
|
||||
layer_heights[layer_nr].height = step;
|
||||
print_z += step;
|
||||
}
|
||||
else {
|
||||
// can't clear curr_layer_nodes, or the model will have empty layers
|
||||
layer_heights[layer_nr].print_z = 0.0;
|
||||
layer_heights[layer_nr].height = 0.0;
|
||||
extr_layers_left--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3350,8 +3351,11 @@ void TreeSupport::generate_contact_points(std::vector<std::vector<SupportNode*>>
|
|||
contact_node->is_sharp_tail = is_sharp_tail;
|
||||
if (is_sharp_tail) {
|
||||
int ind = overhang_part.contour.closest_point_index(pt);
|
||||
auto n1 = (overhang_part.contour[ind] - overhang_part.contour[ind - 1]).cast<double>().normalized();
|
||||
auto n2 = (overhang_part.contour[ind] - overhang_part.contour[ind + 1]).cast<double>().normalized();
|
||||
int nSize = overhang_part.contour.points.size();
|
||||
int ind_prev = (ind - 1 + nSize) % nSize;
|
||||
int ind_next = (ind + 1) % nSize;
|
||||
auto n1 = (overhang_part.contour[ind] - overhang_part.contour[ind_prev]).cast<double>().normalized();
|
||||
auto n2 = (overhang_part.contour[ind] - overhang_part.contour[ind_next]).cast<double>().normalized();
|
||||
contact_node->skin_direction = scaled((n1 + n2).normalized());
|
||||
}
|
||||
curr_nodes.emplace_back(contact_node);
|
||||
|
|
Loading…
Reference in New Issue