mirror of
https://github.com/QIDITECH/QIDIStudio.git
synced 2026-02-07 04:11:50 +03:00
update libslic3r
This commit is contained in:
@@ -328,8 +328,8 @@ SupportGeneratorLayersPtr generate_raft_base(
|
||||
}
|
||||
|
||||
// How much to inflate the support columns to be stable. This also applies to the 1st layer, if no raft layers are to be printed.
|
||||
const float inflate_factor_fine = float(scale_((slicing_params.raft_layers() > 1) ? 0.5 : EPSILON));
|
||||
const float inflate_factor_1st_layer = std::max(0.f, float(scale_(object.config().raft_first_layer_expansion)) - inflate_factor_fine);
|
||||
const float inflate_factor_fine = float(scale_((slicing_params.raft_layers() > 1) ? 0.5 : EPSILON));
|
||||
float inflate_factor_1st_layer = float(scale_(object.config().raft_first_layer_expansion));
|
||||
SupportGeneratorLayer *contacts = top_contacts .empty() ? nullptr : top_contacts .front();
|
||||
SupportGeneratorLayer *interfaces = interface_layers .empty() ? nullptr : interface_layers .front();
|
||||
SupportGeneratorLayer *base_interfaces = base_interface_layers.empty() ? nullptr : base_interface_layers.front();
|
||||
@@ -389,7 +389,11 @@ SupportGeneratorLayersPtr generate_raft_base(
|
||||
new_layer.height = slicing_params.first_print_layer_height;
|
||||
new_layer.bottom_z = 0.;
|
||||
first_layer = union_(std::move(first_layer), base);
|
||||
new_layer.polygons = inflate_factor_1st_layer > 0 ? expand(first_layer, inflate_factor_1st_layer) : first_layer;
|
||||
if (inflate_factor_1st_layer < 0) { //means auto
|
||||
inflate_factor_1st_layer = scale_(2.);
|
||||
new_layer.polygons = expand(first_layer, inflate_factor_1st_layer - inflate_factor_fine);
|
||||
} else
|
||||
new_layer.polygons = inflate_factor_1st_layer > inflate_factor_fine ? expand(first_layer, inflate_factor_1st_layer - inflate_factor_fine) : first_layer;
|
||||
}
|
||||
// Insert the base layers.
|
||||
for (size_t i = 1; i < slicing_params.base_raft_layers; ++ i) {
|
||||
@@ -423,8 +427,17 @@ SupportGeneratorLayersPtr generate_raft_base(
|
||||
//if (object.has_brim())
|
||||
// trimming = offset(object.layers().front()->lslices, (float)scale_(object.config().brim_object_gap.value), SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
//else
|
||||
trimming = offset(object.layers().front()->lslices, (float)scale_(support_params.gap_xy_first_layer), SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
if (inflate_factor_1st_layer > SCALED_EPSILON) {
|
||||
trimming = offset(object.layers().front()->lslices, (float)scale_(support_params.gap_xy_first_layer), SUPPORT_SURFACES_OFFSET_PARAMETERS);
|
||||
if (inflate_factor_1st_layer < 0) { //means auto
|
||||
//for (const auto &expoly : to_expolygons(raft)) {
|
||||
// //TODO: it's hard to get the exact support height here
|
||||
// inflate_factor_1st_layer = std::max(0.,
|
||||
// scale_(expoly.map_moment_to_expansion(max_speed, contacts_with_height.empty() ? 0 : contacts_with_height[0]->print_z)));
|
||||
//}
|
||||
inflate_factor_1st_layer = scale_(2.);
|
||||
}
|
||||
if (inflate_factor_1st_layer > inflate_factor_fine + SCALED_EPSILON) {
|
||||
inflate_factor_1st_layer = inflate_factor_1st_layer - inflate_factor_fine;
|
||||
// Inflate in multiple steps to avoid leaking of the support 1st layer through object walls.
|
||||
auto nsteps = std::max(5, int(ceil(inflate_factor_1st_layer / support_params.first_layer_flow.scaled_width())));
|
||||
float step = inflate_factor_1st_layer / nsteps;
|
||||
@@ -1463,7 +1476,8 @@ void generate_support_toolpaths(
|
||||
const SupportGeneratorLayersPtr &top_contacts,
|
||||
const SupportGeneratorLayersPtr &intermediate_layers,
|
||||
const SupportGeneratorLayersPtr &interface_layers,
|
||||
const SupportGeneratorLayersPtr &base_interface_layers)
|
||||
const SupportGeneratorLayersPtr &base_interface_layers,
|
||||
const std::vector<ExPolygons> &cooldown_areas)
|
||||
{
|
||||
// loop_interface_processor with a given circle radius.
|
||||
LoopInterfaceProcessor loop_interface_processor(1.5 * support_params.support_material_interface_flow.scaled_width());
|
||||
@@ -1595,7 +1609,7 @@ void generate_support_toolpaths(
|
||||
std::vector<LayerCache> layer_caches(support_layers.size());
|
||||
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, support_layers.size()),
|
||||
[&config, &slicing_params, &support_params, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor,
|
||||
[&config, &slicing_params, &support_params, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &cooldown_areas, &layer_caches, &loop_interface_processor,
|
||||
&bbox_object, &angles, &interface_angles, n_raft_layers, link_max_length_factor]
|
||||
(const tbb::blocked_range<size_t>& range) {
|
||||
// Indices of the 1st layer in their respective container at the support layer height.
|
||||
@@ -1810,6 +1824,29 @@ void generate_support_toolpaths(
|
||||
support_params, sheath, no_sort);
|
||||
}
|
||||
|
||||
if (!cooldown_areas.empty() && !cooldown_areas[support_layer_id].empty()) {
|
||||
std::function<void(ExtrusionEntitiesPtr &)> setOverhangDegreeImpl = [&](ExtrusionEntitiesPtr &entities) {
|
||||
for (auto entityPtr : entities) {
|
||||
if (overlaps(to_expolygons(entityPtr->polygons_covered_by_width()), cooldown_areas[support_layer_id])) {
|
||||
if (ExtrusionEntityCollection *collection = dynamic_cast<ExtrusionEntityCollection *>(entityPtr)) {
|
||||
setOverhangDegreeImpl(collection->entities);
|
||||
} else if (ExtrusionPath *path = dynamic_cast<ExtrusionPath *>(entityPtr)) {
|
||||
path->set_overhang_degree(10);
|
||||
} else if (ExtrusionMultiPath *multipath = dynamic_cast<ExtrusionMultiPath *>(entityPtr)) {
|
||||
for (ExtrusionPath &path : multipath->paths) { path.set_overhang_degree(10); }
|
||||
} else if (ExtrusionLoop *loop = dynamic_cast<ExtrusionLoop *>(entityPtr)) {
|
||||
for (ExtrusionPath &path : loop->paths) { path.set_overhang_degree(10); }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
setOverhangDegreeImpl(base_layer.extrusions);
|
||||
setOverhangDegreeImpl(top_contact_layer.extrusions);
|
||||
setOverhangDegreeImpl(bottom_contact_layer.extrusions);
|
||||
setOverhangDegreeImpl(interface_layer.extrusions);
|
||||
setOverhangDegreeImpl(base_interface_layer.extrusions);
|
||||
}
|
||||
|
||||
// Merge base_interface_layers to base_layers to avoid unneccessary retractions
|
||||
if (! base_layer.empty() && ! base_interface_layer.empty() && ! base_layer.polygons_to_extrude().empty() && ! base_interface_layer.polygons_to_extrude().empty() &&
|
||||
base_layer.could_merge(base_interface_layer))
|
||||
@@ -1998,6 +2035,7 @@ sub clip_with_shape {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Unions two Polygons. Ensures that if the input is non empty that the output also will be non empty.
|
||||
* \param first[in] The first Polygon.
|
||||
|
||||
@@ -72,7 +72,8 @@ void generate_support_toolpaths(
|
||||
const SupportGeneratorLayersPtr &top_contacts,
|
||||
const SupportGeneratorLayersPtr &intermediate_layers,
|
||||
const SupportGeneratorLayersPtr &interface_layers,
|
||||
const SupportGeneratorLayersPtr &base_interface_layers);
|
||||
const SupportGeneratorLayersPtr &base_interface_layers,
|
||||
const std::vector<ExPolygons> &cooldown_areas = {});
|
||||
|
||||
// FN_HIGHER_EQUAL: the provided object pointer has a Z value >= of an internal threshold.
|
||||
// Find the first item with Z value >= of an internal threshold of fn_higher_equal.
|
||||
|
||||
@@ -1775,7 +1775,7 @@ static inline std::pair<SupportGeneratorLayer*, SupportGeneratorLayer*> new_cont
|
||||
|
||||
// Contact layer will be printed with a normal flow, but
|
||||
// it will support layers printed with a bridging flow.
|
||||
if (object_config.thick_bridges && SupportMaterialInternal::has_bridging_extrusions(layer) && print_config.independent_support_layer_height) {
|
||||
if (object_config.thick_bridges && SupportMaterialInternal::has_bridging_extrusions(layer)/* && print_config.independent_support_layer_height*/) {
|
||||
coordf_t bridging_height = 0.;
|
||||
for (const LayerRegion* region : layer.regions())
|
||||
bridging_height += region->region().bridging_height_avg(print_config);
|
||||
@@ -2928,7 +2928,7 @@ SupportGeneratorLayersPtr PrintObjectSupportMaterial::raft_and_intermediate_supp
|
||||
for (size_t i = 0; i < top_contacts.size(); ++i)
|
||||
assert(top_contacts[i]->height > 0.);
|
||||
#endif /* _DEBUG */
|
||||
|
||||
|
||||
return intermediate_layers;
|
||||
}
|
||||
|
||||
|
||||
@@ -160,13 +160,13 @@ struct SupportParameters {
|
||||
this->support_density > 0.95 || this->with_sheath ? ipRectilinear :
|
||||
ipSupportBase;
|
||||
this->interface_fill_pattern = (this->interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
||||
this->raft_interface_fill_pattern = this->raft_interface_density > 0.95 ? ipRectilinear : ipSupportBase;
|
||||
this->raft_interface_fill_pattern = this->raft_interface_density > 0.95 ? ipRectilinear : ipSupportBase;
|
||||
if (object_config.support_interface_pattern == smipGrid)
|
||||
this->contact_fill_pattern = ipGrid;
|
||||
else if (object_config.support_interface_pattern == smipRectilinearInterlaced || object_config.support_interface_pattern == smipAuto)
|
||||
this->contact_fill_pattern = ipRectilinear;
|
||||
else
|
||||
this->contact_fill_pattern = object_config.support_interface_pattern == smipConcentric ?
|
||||
this->contact_fill_pattern = object_config.support_interface_pattern == smipConcentric ?
|
||||
ipConcentric :
|
||||
(this->interface_density > 0.95 ? ipRectilinear : ipSupportBase);
|
||||
|
||||
@@ -220,7 +220,7 @@ struct SupportParameters {
|
||||
}
|
||||
}
|
||||
|
||||
if(object_config.tree_support_wall_count.value==0){
|
||||
if(object_config.tree_support_wall_count.value==-1){
|
||||
tree_support_branch_diameter_double_wall = support_filament_strength;
|
||||
this->tree_branch_diameter_double_wall_area_scaled = 0.25*sqr(scaled<double>(tree_support_branch_diameter_double_wall))*M_PI;
|
||||
}else{
|
||||
@@ -258,7 +258,7 @@ struct SupportParameters {
|
||||
Flow support_material_flow;
|
||||
Flow support_material_interface_flow;
|
||||
Flow support_material_bottom_interface_flow;
|
||||
// Flow at raft inteface & contact layers.
|
||||
// Flow at raft inteface & contact layers.
|
||||
Flow raft_interface_flow;
|
||||
coordf_t support_extrusion_width;
|
||||
// Is merging of regions allowed? Could the interface & base support regions be printed with the same extruder?
|
||||
|
||||
@@ -945,7 +945,10 @@ void TreeSupport::detect_overhangs(bool check_support_necessity/* = false*/)
|
||||
blocker = offset_ex(union_(blockers[layer_nr]), scale_(radius_sample_resolution));
|
||||
if (!blocker.empty()) overhangs_all_layers[layer_nr] = diff_ex(overhangs_all_layers[layer_nr], blocker);
|
||||
}
|
||||
if (!enforced_overhangs.empty()) overhangs_all_layers[layer_nr] = union_ex(overhangs_all_layers[layer_nr], enforced_overhangs);
|
||||
if (!enforced_overhangs.empty()) {
|
||||
enforced_overhangs = diff_ex(offset_ex(enforced_overhangs, enforcer_overhang_offset), lower_layer->lslices_extrudable);
|
||||
overhangs_all_layers[layer_nr] = union_ex(overhangs_all_layers[layer_nr], enforced_overhangs);
|
||||
}
|
||||
}
|
||||
else if (layer_nr < enforcers.size() && lower_layer) {
|
||||
if (!enforced_overhangs.empty()) {
|
||||
@@ -1210,7 +1213,7 @@ void TreeSupport::detect_overhangs(bool check_support_necessity/* = false*/)
|
||||
layer->loverhangs_with_type.clear();
|
||||
for (const auto &cantilever : layer->cantilevers) add_overhang(layer, cantilever, OverhangType::Cantilever);
|
||||
} else {
|
||||
ExPolygons enforced_overhangs = to_expolygons(enforcers[layer_nr]);
|
||||
ExPolygons enforced_overhangs = offset_ex(to_expolygons(enforcers[layer_nr]), enforcer_overhang_offset);
|
||||
ExPolygons loverhangs_new;
|
||||
std::vector<std::pair<ExPolygon, int>> loverhangs_with_type_new;
|
||||
ExPolygons bigflat;
|
||||
@@ -1507,7 +1510,7 @@ void TreeSupport::generate_toolpaths()
|
||||
coordf_t support_extrusion_width = m_support_params.support_extrusion_width;
|
||||
coordf_t nozzle_diameter = m_print_config->nozzle_diameter.get_at(object_config.support_filament - 1);
|
||||
coordf_t layer_height = object_config.layer_height.value;
|
||||
const size_t wall_count = object_config.tree_support_wall_count.value;
|
||||
const int wall_count = object_config.tree_support_wall_count.value;
|
||||
|
||||
// coconut: use same intensity settings as SupportMaterial.cpp
|
||||
auto m_support_material_interface_flow = support_material_interface_flow(m_object, float(m_slicing_params.layer_height));
|
||||
@@ -1616,7 +1619,7 @@ void TreeSupport::generate_toolpaths()
|
||||
filler_raft->angle = PI / 2;
|
||||
filler_raft->spacing = support_flow.spacing();
|
||||
for (auto& poly : first_non_raft_base)
|
||||
make_perimeter_and_infill(ts_layer->support_fills.entities, poly, std::min(size_t(1), wall_count), support_flow, erSupportMaterial, filler_raft, interface_density, false);
|
||||
make_perimeter_and_infill(ts_layer->support_fills.entities, poly, std::min(1, wall_count), support_flow, erSupportMaterial, filler_raft, interface_density, false);
|
||||
}
|
||||
|
||||
if (m_object->support_layer_count() <= m_raft_layers)
|
||||
@@ -1747,8 +1750,16 @@ void TreeSupport::generate_toolpaths()
|
||||
filler_interface->layer_id = 0;
|
||||
}
|
||||
|
||||
fill_expolygons_generate_paths(ts_layer->support_fills.entities, polys, filler_interface.get(), fill_params, erSupportMaterialInterface,
|
||||
interface_flow);
|
||||
ExtrusionEntityCollection *temp_support_fills = new ExtrusionEntityCollection();
|
||||
for (auto &single_poly : union_ex(polys))
|
||||
make_perimeter_and_infill(temp_support_fills->entities, single_poly, 1, interface_flow, erSupportMaterialInterface, filler_interface.get(),
|
||||
interface_density, false);
|
||||
temp_support_fills->no_sort = true; // make sure loops are first
|
||||
if (!temp_support_fills->entities.empty())
|
||||
ts_layer->support_fills.entities.push_back(temp_support_fills);
|
||||
else
|
||||
delete temp_support_fills;
|
||||
|
||||
}
|
||||
else {
|
||||
// base_areas
|
||||
@@ -1773,17 +1784,35 @@ void TreeSupport::generate_toolpaths()
|
||||
// allow infill-only mode if support is thick enough (so min_wall_count is 0);
|
||||
// otherwise must draw 1 wall
|
||||
// Don't need extra walls if we have infill. Extra walls may overlap with the infills.
|
||||
size_t min_wall_count = 1;
|
||||
make_perimeter_and_infill(ts_layer->support_fills.entities, poly, std::max(min_wall_count, wall_count), flow,
|
||||
size_t min_wall_count = wall_count == 0 ? 0 : 1;
|
||||
make_perimeter_and_infill(ts_layer->support_fills.entities, poly, std::max(int(min_wall_count), wall_count), flow,
|
||||
erSupportMaterial, filler_support.get(), support_density);
|
||||
}
|
||||
else {
|
||||
SupportParameters support_params = m_support_params;
|
||||
if (area_group.need_extra_wall && object_config.tree_support_wall_count.value == 0)
|
||||
if (area_group.need_extra_wall && object_config.tree_support_wall_count.value == -1)
|
||||
support_params.tree_branch_diameter_double_wall_area_scaled = 0.1;
|
||||
tree_supports_generate_paths(ts_layer->support_fills.entities, loops, flow, support_params);
|
||||
}
|
||||
}
|
||||
|
||||
if (area_group.need_cooling)
|
||||
{
|
||||
std::function<void(ExtrusionEntityCollection *)> setOverhangDegreeImpl = [&](ExtrusionEntityCollection *entity) {
|
||||
for (auto entityPtr : entity->entities) {
|
||||
if (ExtrusionEntityCollection *collection = dynamic_cast<ExtrusionEntityCollection *>(entityPtr)) {
|
||||
setOverhangDegreeImpl(collection);
|
||||
} else if (ExtrusionPath *path = dynamic_cast<ExtrusionPath *>(entityPtr)) {
|
||||
path->set_overhang_degree(10);
|
||||
} else if (ExtrusionMultiPath *multipath = dynamic_cast<ExtrusionMultiPath *>(entityPtr)) {
|
||||
for (ExtrusionPath &path : multipath->paths) { path.set_overhang_degree(10); }
|
||||
} else if (ExtrusionLoop *loop = dynamic_cast<ExtrusionLoop *>(entityPtr)) {
|
||||
for (ExtrusionPath &path : loop->paths) { path.set_overhang_degree(10); }
|
||||
}
|
||||
}
|
||||
};
|
||||
setOverhangDegreeImpl(&ts_layer->support_fills);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_support_params.base_fill_pattern == ipLightning)
|
||||
@@ -2304,6 +2333,7 @@ void TreeSupport::draw_circles()
|
||||
ts_layer->support_islands.reserve(curr_layer_nodes.size());
|
||||
ExPolygons area_poly; // the polygon node area which will be printed as normal support
|
||||
ExPolygons extra_wall_area; //where nodes would have extra walls
|
||||
ExPolygons cooldown_area;
|
||||
for (const SupportNode* p_node : curr_layer_nodes)
|
||||
{
|
||||
if (print->canceled())
|
||||
@@ -2327,7 +2357,6 @@ void TreeSupport::draw_circles()
|
||||
append(area_poly, area);
|
||||
if (node.need_extra_wall) append(extra_wall_area, area);
|
||||
}
|
||||
if (tree_brim_width <= 0) brim_width = node.type == ePolygon ? 1 : 3;
|
||||
}
|
||||
else {
|
||||
Polygon circle(branch_circle);
|
||||
@@ -2352,15 +2381,16 @@ void TreeSupport::draw_circles()
|
||||
circle.points[i] = circle.points[i] * scale + node.position;
|
||||
}
|
||||
}
|
||||
brim_width = tree_brim_width > 0 ?
|
||||
tree_brim_width :
|
||||
std::max(MIN_BRANCH_RADIUS_FIRST_LAYER,
|
||||
std::min(node.radius + node.dist_mm_to_top / (scale * branch_radius) * 0.5, MAX_BRANCH_RADIUS_FIRST_LAYER) - node.radius);
|
||||
// brim_width = tree_brim_width > 0 ?
|
||||
// tree_brim_width :
|
||||
// std::max(MIN_BRANCH_RADIUS_FIRST_LAYER,
|
||||
// std::min(node.radius + node.dist_mm_to_top / (scale * branch_radius) * 0.5, MAX_BRANCH_RADIUS_FIRST_LAYER) - node.radius);
|
||||
area = avoid_object_remove_extra_small_parts(ExPolygon(circle), get_collision(node.is_sharp_tail && node.distance_to_top <= 0));
|
||||
// area = diff_clipped({ ExPolygon(circle) }, get_collision(node.is_sharp_tail && node.distance_to_top <= 0));
|
||||
|
||||
if (!area.empty()) has_circle_node = true;
|
||||
if (node.need_extra_wall) append(extra_wall_area, area);
|
||||
if (node.overhang_degree >= 2) append(cooldown_area, area);
|
||||
|
||||
// merge overhang to get a smoother interface surface
|
||||
// Do not merge when buildplate_only is on, because some underneath nodes may have been deleted.
|
||||
@@ -2374,10 +2404,17 @@ void TreeSupport::draw_circles()
|
||||
}
|
||||
append(area, overhang_expanded);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (layer_nr == 0 && m_raft_layers == 0)
|
||||
if (layer_nr == 0 && m_raft_layers == 0) {
|
||||
if (tree_brim_width >= 0) brim_width = tree_brim_width;
|
||||
else {
|
||||
for (const auto &expoly : area)
|
||||
brim_width = std::max(brim_width, expoly.map_moment_to_expansion(m_object_config->support_speed.values[0], node.dist_mm_to_top));
|
||||
}
|
||||
area = safe_offset_inc(area, scale_(brim_width), get_collision(false), scale_(MIN_BRANCH_RADIUS * 0.5), 0, 1);
|
||||
}
|
||||
if (obj_layer_nr>0 && node.distance_to_top < 0)
|
||||
append(roof_gap_areas, area);
|
||||
else if (m_support_params.num_top_interface_layers > 0 && obj_layer_nr > 0 && (node.support_roof_layers_below == 0 || node.support_roof_layers_below == 1) &&
|
||||
@@ -2461,6 +2498,7 @@ void TreeSupport::draw_circles()
|
||||
area_groups.back().need_infill = overlaps({ expoly }, area_poly);
|
||||
bool need_extra_wall = overlaps({expoly},extra_wall_area);
|
||||
area_groups.back().need_extra_wall = need_extra_wall && !area_groups.back().need_infill;
|
||||
area_groups.back().need_cooling = overlaps({ expoly }, cooldown_area);
|
||||
}
|
||||
for (auto& expoly : ts_layer->roof_areas) {
|
||||
//if (area(expoly) < SQ(scale_(1))) continue;
|
||||
@@ -2880,6 +2918,18 @@ void TreeSupport::drop_nodes()
|
||||
if (!overlap_with_circle.empty() && is_inside_ex(overlap_with_circle, node.position)) {
|
||||
continue;
|
||||
}
|
||||
Polygon circle = make_circle(scale_(node.radius), 0.00789 * scale_(node.radius));
|
||||
circle.translate(node.position);
|
||||
ExPolygons area = avoid_object_remove_extra_small_parts(ExPolygon(circle), get_collision(0, obj_layer_nr));
|
||||
if (!area.empty()) {
|
||||
p_node->overhang = area[0];
|
||||
if (area[0].area() < SQ(scale_(1.)) || (!node.parent->to_buildplate && !overlaps({node.overhang}, {node.parent->overhang}))) {
|
||||
p_node->valid = false;
|
||||
p_node->is_processed = true;
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
if (node.to_buildplate || parts.empty()) //It's outside, so make it go towards the build plate.
|
||||
{
|
||||
@@ -3362,8 +3412,10 @@ void TreeSupport::drop_nodes()
|
||||
}
|
||||
if (i_node->child) {
|
||||
i_node->child->parent = i_node->parent;
|
||||
i_node->child->parents.erase(std::find(i_node->child->parents.begin(), i_node->child->parents.end(), i_node));
|
||||
append(i_node->child->parents, i_node->parents);
|
||||
auto it = std::find(i_node->child->parents.begin(), i_node->child->parents.end(), i_node);
|
||||
if (it != i_node->child->parents.end()) i_node->child->parents.erase(it);
|
||||
if (!i_node->parents.empty())
|
||||
append(i_node->child->parents, i_node->parents);
|
||||
}
|
||||
i_node->is_processed = true; // mark to be deleted later
|
||||
|
||||
@@ -3441,6 +3493,7 @@ void TreeSupport::smooth_nodes()
|
||||
branch[i]->radius = radii1[i];
|
||||
branch[i]->movement = (pts[i + 1] - pts[i - 1]) / 2;
|
||||
branch[i]->is_processed = true;
|
||||
branch[i]->overhang_degree = std::min(10.0, unscale_((branch[i]->movement).cast<double>().norm()) / m_object_config->support_line_width * 10);
|
||||
if (branch[i]->parents.size() > 1 || (branch[i]->movement.x() > max_move || branch[i]->movement.y() > max_move) ||
|
||||
(total_height > thresh_tall_branch && branch[i]->dist_mm_to_top < thresh_dist_to_top))
|
||||
branch[i]->need_extra_wall = true;
|
||||
|
||||
@@ -125,6 +125,7 @@ struct SupportNode
|
||||
bool is_sharp_tail = false;
|
||||
bool valid = true;
|
||||
bool fading = false;
|
||||
double overhang_degree = 0.0; // overhang degree for cooling just like perimeter
|
||||
ExPolygon overhang; // when type==ePolygon, set this value to get original overhang area
|
||||
coordf_t origin_area;
|
||||
|
||||
@@ -432,7 +433,6 @@ private:
|
||||
SlicingParameters m_slicing_params;
|
||||
// Various precomputed support parameters to be shared with external functions.
|
||||
SupportParameters m_support_params;
|
||||
//1.9.5
|
||||
size_t m_raft_layers = 0; // number of raft layers, including raft base, raft interface, raft gap
|
||||
size_t m_highest_overhang_layer = 0;
|
||||
std::vector<std::vector<MinimumSpanningTree>> m_spanning_trees;
|
||||
|
||||
@@ -4140,7 +4140,7 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
|
||||
// Outputs
|
||||
layer_storage, top_contacts, interface_layers, base_interface_layers };
|
||||
|
||||
|
||||
std::vector<ExPolygons> cooldown_areas(num_support_layers);
|
||||
if (has_support) {
|
||||
auto t_precalc = std::chrono::high_resolution_clock::now();
|
||||
// value is the area where support may be placed. As this is calculated in CreateLayerPathing it is saved and reused in draw_areas
|
||||
@@ -4185,7 +4185,7 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
|
||||
// this new function give correct result when raft is also enabled
|
||||
organic_draw_branches(
|
||||
*print.get_object(processing.second.front()), volumes, config, move_bounds,
|
||||
bottom_contacts, top_contacts, interface_placer, intermediate_layers, layer_storage,
|
||||
bottom_contacts, top_contacts, interface_placer, intermediate_layers, layer_storage, cooldown_areas,
|
||||
throw_on_cancel);
|
||||
#endif
|
||||
|
||||
@@ -4232,7 +4232,7 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
|
||||
// Don't fill in the tree supports, make them hollow with just a single sheath line.
|
||||
print.set_status(69, _L("Generating support"));
|
||||
generate_support_toolpaths(print_object.support_layers(), print_object.config(), support_params, print_object.slicing_parameters(),
|
||||
raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers);
|
||||
raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers, cooldown_areas);
|
||||
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
BOOST_LOG_TRIVIAL(info) << "Total time of organic tree support: " << 0.001 * std::chrono::duration_cast<std::chrono::microseconds>(t_end - t_start).count() << " ms";
|
||||
@@ -4287,6 +4287,7 @@ void organic_draw_branches(
|
||||
// Output:
|
||||
SupportGeneratorLayersPtr& intermediate_layers,
|
||||
SupportGeneratorLayerStorage& layer_storage,
|
||||
std::vector<ExPolygons>& cooldown_areas,
|
||||
|
||||
std::function<void()> throw_on_cancel)
|
||||
{
|
||||
@@ -4336,6 +4337,30 @@ void organic_draw_branches(
|
||||
|
||||
organic_smooth_branches_avoid_collisions(print_object, volumes, config, elements_with_link_down, linear_data_layers, throw_on_cancel);
|
||||
|
||||
//save the cooling area
|
||||
for (LayerIndex layer_idx = 0; layer_idx + 1 < LayerIndex(move_bounds.size()); ++layer_idx) {
|
||||
auto &layer_elements = move_bounds[layer_idx];
|
||||
for (auto &elem : layer_elements) {
|
||||
if (!elem.parents.empty()) {
|
||||
SupportElements *layer_above = layer_idx + 1 < LayerIndex(move_bounds.size()) ? &move_bounds[layer_idx + 1] : nullptr;
|
||||
if (!layer_above) break;
|
||||
for (auto &parent_elem : elem.parents) {
|
||||
auto &parent = (*layer_above)[parent_elem];
|
||||
double overhang_degree = std::min(10.0, (parent.state.result_on_layer - elem.state.result_on_layer).cast<double>().norm() /
|
||||
config.support_line_width * 10);
|
||||
|
||||
if (overhang_degree >= 2) {
|
||||
coord_t radius = support_element_radius(config, parent);
|
||||
Polygon circle = make_circle(radius, radius / 100);
|
||||
circle.translate(parent.state.result_on_layer);
|
||||
cooldown_areas[layer_idx + 1].emplace_back(ExPolygon(circle));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reduce memory footprint. After this point only finalize_interface_and_support_areas() will use volumes and from that only collisions with zero radius will be used.
|
||||
volumes.clear_all_but_object_collision();
|
||||
|
||||
|
||||
@@ -318,6 +318,7 @@ void organic_draw_branches(
|
||||
// Output:
|
||||
SupportGeneratorLayersPtr& intermediate_layers,
|
||||
SupportGeneratorLayerStorage& layer_storage,
|
||||
std::vector<ExPolygons>& cooldown_areas,
|
||||
|
||||
std::function<void()> throw_on_cancel);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user