Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clip the organic supports outside bed #8195

Merged
merged 4 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions src/libslic3r/Support/TreeModelVolumes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ TreeModelVolumes::TreeModelVolumes(
#endif // SLIC3R_TREESUPPORTS_PROGRESS
m_machine_border{ calculateMachineBorderCollision(build_volume.polygon()) }
{
m_bed_area = build_volume.polygon();
#if 0
std::unordered_map<size_t, size_t> mesh_to_layeroutline_idx;
for (size_t mesh_idx = 0; mesh_idx < storage.meshes.size(); ++ mesh_idx) {
Expand Down Expand Up @@ -180,7 +181,8 @@ void TreeModelVolumes::precalculate(const PrintObject& print_object, const coord
m_ignorable_radii.emplace_back(radius_eval);
}

throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();

// it may seem that the required avoidance can be of a smaller radius when going to model (no initial layer diameter for to model branches)
// but as for every branch going towards the bp, the to model avoidance is required to check for possible merges with to model branches, this assumption is in-fact wrong.
Expand All @@ -203,7 +205,8 @@ void TreeModelVolumes::precalculate(const PrintObject& print_object, const coord
update_radius_until_layer(ceilRadius(config.recommendedMinRadius(current_layer) + m_current_min_xy_dist_delta));
}

throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();

// Copy to deque to use in parallel for later.
std::vector<RadiusLayerPair> relevant_avoidance_radiis{ radius_until_layer.begin(), radius_until_layer.end() };
Expand Down Expand Up @@ -365,8 +368,7 @@ const Polygons& TreeModelVolumes::getPlaceableAreas(const coord_t orig_radius, L
if (orig_radius == 0)
// Placable areas for radius 0 are calculated in the general collision code.
return this->getCollision(0, layer_idx, true);
else
const_cast<TreeModelVolumes*>(this)->calculatePlaceables(radius, layer_idx, throw_on_cancel);
const_cast<TreeModelVolumes*>(this)->calculatePlaceables(radius, layer_idx, throw_on_cancel);
return getPlaceableAreas(orig_radius, layer_idx, throw_on_cancel);
}

Expand Down Expand Up @@ -461,7 +463,8 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
collision_areas_offsetted[layer_idx] = offset_value == 0 ?
union_(collision_areas) :
offset(union_ex(collision_areas), offset_value, ClipperLib::jtMiter, 1.2);
throw_on_cancel();
if(throw_on_cancel)
throw_on_cancel();
}
});

Expand Down Expand Up @@ -524,7 +527,8 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
dst = polygons_simplify(collisions, min_resolution, polygons_strictly_simple);
} else
append(dst, std::move(collisions));
throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();
}
});

Expand All @@ -551,7 +555,8 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
dst = polygons_simplify(placable, min_resolution, polygons_strictly_simple);
} else
append(dst, placable);
throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();
}
});
} else {
Expand All @@ -567,7 +572,8 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
}
}
#endif
throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();
m_collision_cache.insert(std::move(data), radius);
if (calculate_placable)
m_placeable_areas_cache.insert(std::move(data_placeable), radius);
Expand Down Expand Up @@ -597,7 +603,8 @@ void TreeModelVolumes::calculateCollisionHolefree(const std::vector<RadiusLayerP
offset(union_ex(this->getCollision(m_increase_until_radius, layer_idx, false)),
5 - increase_radius_ceil, ClipperLib::jtRound, m_min_resolution),
m_min_resolution, polygons_strictly_simple));
throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();
}
}
m_collision_cache_holefree.insert(std::move(data));
Expand Down Expand Up @@ -640,7 +647,8 @@ void TreeModelVolumes::calculateAvoidance(const std::vector<RadiusLayerPair> &ke
avoidance_tasks.emplace_back(task);
}

throw_on_cancel();
if(throw_on_cancel)
throw_on_cancel();

tbb::parallel_for(tbb::blocked_range<size_t>(0, avoidance_tasks.size(), 1),
[this, &avoidance_tasks, &throw_on_cancel](const tbb::blocked_range<size_t> &range) {
Expand Down Expand Up @@ -685,7 +693,8 @@ void TreeModelVolumes::calculateAvoidance(const std::vector<RadiusLayerPair> &ke
latest_avoidance = diff(latest_avoidance, getPlaceableAreas(task.radius, layer_idx, throw_on_cancel));
latest_avoidance = polygons_simplify(latest_avoidance, m_min_resolution, polygons_strictly_simple);
data.emplace_back(RadiusLayerPair{task.radius, layer_idx}, latest_avoidance);
throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();
}
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
{
Expand Down Expand Up @@ -736,7 +745,8 @@ void TreeModelVolumes::calculatePlaceables(const coord_t radius, const LayerInde
// xy_distance that cant support it. Making the area smaller by xy_distance fixes this.
- (radius + m_current_min_xy_dist + m_current_min_xy_dist_delta),
jtMiter, 1.2);
throw_on_cancel();
if(throw_on_cancel)
throw_on_cancel();
}
});
#ifdef SLIC3R_TREESUPPORTS_PROGRESS
Expand Down Expand Up @@ -810,7 +820,8 @@ void TreeModelVolumes::calculateWallRestrictions(const std::vector<RadiusLayerPa
polygons_simplify(
intersection(getCollision(0, layer_idx, true), getCollision(radius, layer_idx - 1, true)),
m_min_resolution, polygons_strictly_simple);
throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();
}
});
m_wall_restrictions_cache.insert(std::move(data), min_layer_bottom, radius);
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/Support/TreeModelVolumes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ class TreeModelVolumes
this->ceilRadius(radius + m_current_min_xy_dist_delta) - m_current_min_xy_dist_delta;
}

Polygon m_bed_area;

private:
// Caching polygons for a range of layers.
class LayerPolygonCache {
Expand Down
9 changes: 4 additions & 5 deletions src/libslic3r/Support/TreeSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ static Point bounding_box_middle(const BoundingBox &bbox)
TreeSupport::TreeSupport(PrintObject& object, const SlicingParameters &slicing_params)
: m_object(&object), m_slicing_params(slicing_params), m_object_config(&object.config())
{
m_print_config = &m_object->print()->config();
m_raft_layers = slicing_params.base_raft_layers + slicing_params.interface_raft_layers;
support_type = m_object_config->support_type;
support_style = m_object_config->support_style;
Expand Down Expand Up @@ -705,8 +706,7 @@ TreeSupport::TreeSupport(PrintObject& object, const SlicingParameters &slicing_p
tree_support_branch_diameter_angle = 5.0;//is_slim ? 10.0 : 5.0;
// by default tree support needs no infill, unless it's tree hybrid which contains normal nodes.
with_infill = support_pattern != smpNone && support_pattern != smpDefault;
const PrintConfig& print_config = m_object->print()->config();
m_machine_border.contour = get_bed_shape_with_excluded_area(print_config);
m_machine_border.contour = get_bed_shape_with_excluded_area(*m_print_config);
Vec3d plate_offset = m_object->print()->get_plate_origin();
// align with the centered object in current plate (may not be the 1st plate, so need to add the plate offset)
m_machine_border.translate(Point(scale_(plate_offset(0)), scale_(plate_offset(1))) - m_object->instances().front().shift);
Expand Down Expand Up @@ -1404,10 +1404,9 @@ static void make_perimeter_and_infill(ExtrusionEntitiesPtr& dst, const Print& pr

void TreeSupport::generate_toolpaths()
{
const PrintConfig &print_config = m_object->print()->config();
const PrintObjectConfig &object_config = m_object->config();
coordf_t support_extrusion_width = m_support_params.support_extrusion_width;
coordf_t nozzle_diameter = print_config.nozzle_diameter.get_at(object_config.support_filament - 1);
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;

Expand Down Expand Up @@ -1882,7 +1881,7 @@ Polygons TreeSupport::contact_nodes_to_polygon(const std::vector<Node*>& contact
void TreeSupport::generate()
{
if (support_style == smsOrganic) {
generate_tree_support_3D(*m_object, this->throw_on_cancel);
generate_tree_support_3D(*m_object, this, this->throw_on_cancel);
return;
}

Expand Down
12 changes: 7 additions & 5 deletions src/libslic3r/Support/TreeSupport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,13 @@ class TreeSupport
std::unordered_map<double, size_t> printZ_to_lightninglayer;

std::function<void()> throw_on_cancel;
const PrintConfig* m_print_config;
/*!
* \brief Polygons representing the limits of the printable area of the
* machine
*/
ExPolygon m_machine_border;

private:
/*!
* \brief Generator for model collision, avoidance and internal guide volumes
Expand All @@ -429,11 +436,6 @@ class TreeSupport
bool with_infill = false;


/*!
* \brief Polygons representing the limits of the printable area of the
* machine
*/
ExPolygon m_machine_border;

/*!
* \brief Draws circles around each node of the tree into the final support.
Expand Down
40 changes: 24 additions & 16 deletions src/libslic3r/Support/TreeSupport3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
// CuraEngine is released under the terms of the AGPLv3 or higher.

#include "TreeSupport3D.hpp"
#include "TreeSupportCommon.hpp"
#include "SupportCommon.hpp"

#include "../AABBTreeIndirect.hpp"
#include "../BuildVolume.hpp"
Expand All @@ -21,6 +19,9 @@
#include "../Polygon.hpp"
#include "../Polyline.hpp"
#include "../MutablePolygon.hpp"
#include "TreeSupportCommon.hpp"
#include "SupportCommon.hpp"
#include "TreeSupport.hpp"
#include "libslic3r.h"

#include <cassert>
Expand All @@ -34,6 +35,7 @@
#include <boost/log/trivial.hpp>

#include <tbb/parallel_for.h>
#include <tbb/parallel_for_each.h>

#if defined(TREE_SUPPORT_SHOW_ERRORS) && defined(_WIN32)
#define TREE_SUPPORT_SHOW_ERRORS_WIN32
Expand Down Expand Up @@ -4106,13 +4108,14 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume
continue;

// Produce the support G-code.
// Used by both classic and tree supports.
SupportGeneratorLayersPtr raft_layers = generate_raft_base(print_object, support_params, print_object.slicing_parameters(),
top_contacts, interface_layers, base_interface_layers, intermediate_layers, layer_storage);
#if 1 //#ifdef SLIC3R_DEBUG
SupportGeneratorLayersPtr layers_sorted =
#endif // SLIC3R_DEBUG
generate_support_layers(print_object, raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers);
SupportGeneratorLayersPtr raft_layers = generate_raft_base(print_object, support_params, print_object.slicing_parameters(), top_contacts, interface_layers, base_interface_layers, intermediate_layers, layer_storage);
SupportGeneratorLayersPtr layers_sorted = generate_support_layers(print_object, raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers);

// BBS: This is a hack to avoid the support being generated outside the bed area. See #4769.
tbb::parallel_for_each(layers_sorted.begin(), layers_sorted.end(), [&](SupportGeneratorLayer *layer) {
if (layer) layer->polygons = intersection(layer->polygons, volumes.m_bed_area);
});

// Don't fill in the tree supports, make them hollow with just a single sheath line.
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);
Expand Down Expand Up @@ -4363,9 +4366,10 @@ void organic_draw_branches(
std::vector<Polygons> slices = slice_mesh(partial_mesh, slice_z, mesh_slicing_params, throw_on_cancel);
bottom_contacts.clear();
//FIXME parallelize?
for (LayerIndex i = 0; i < LayerIndex(slices.size()); ++ i)
slices[i] = diff_clipped(slices[i], volumes.getCollision(0, layer_begin + i, true)); //FIXME parent_uses_min || draw_area.element->state.use_min_xy_dist);

for (LayerIndex i = 0; i < LayerIndex(slices.size()); ++i) {
slices[i] = diff_clipped(slices[i], volumes.getCollision(0, layer_begin + i, true)); // FIXME parent_uses_min || draw_area.element->state.use_min_xy_dist);
slices[i] = intersection(slices[i], volumes.m_bed_area);
}
size_t num_empty = 0;
if (slices.front().empty()) {
// Some of the initial layers are empty.
Expand Down Expand Up @@ -4568,17 +4572,21 @@ void organic_draw_branches(

} // namespace TreeSupport3D

void generate_tree_support_3D(PrintObject &print_object, std::function<void()> throw_on_cancel)
void generate_tree_support_3D(PrintObject &print_object, TreeSupport* tree_support, std::function<void()> throw_on_cancel)
{
size_t idx = 0;
for (const PrintObject *po : print_object.print()->objects()) {
if (po == &print_object)
break;
++idx;
}
TreeSupport3D::generate_support_areas(*print_object.print(),
BuildVolume(Pointfs{ Vec2d{ -300., -300. }, Vec2d{ -300., +300. }, Vec2d{ +300., +300. }, Vec2d{ +300., -300. } }, 0.), { idx },
throw_on_cancel);

Points bedpts = tree_support->m_machine_border.contour.points;
Pointfs bedptsf;
std::transform(bedpts.begin(), bedpts.end(), std::back_inserter(bedptsf), [](const Point &p) { return unscale(p); });
BuildVolume build_volume{ bedptsf, tree_support->m_print_config->printable_height };

TreeSupport3D::generate_support_areas(*print_object.print(), build_volume, { idx }, throw_on_cancel);
}

} // namespace Slic3r
2 changes: 1 addition & 1 deletion src/libslic3r/Support/TreeSupport3D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ void organic_draw_branches(

} // namespace TreeSupport3D

void generate_tree_support_3D(PrintObject &print_object, std::function<void()> throw_on_cancel = []{});
void generate_tree_support_3D(PrintObject &print_object, TreeSupport* tree_support, std::function<void()> throw_on_cancel = []{});

} // namespace Slic3r

Expand Down