mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
FIX: lightning infill may fail for some cases
Change-Id: Ibc6e4e4262ef9fc0b36a936acc52a3b60dca2cb4 (cherry picked from commit e3b7c5c3404aa200c4b852b3963a7a0aae8837d2)
This commit is contained in:
parent
8375c73ac9
commit
6a644c271c
9 changed files with 34 additions and 36 deletions
|
@ -26,9 +26,9 @@ void GeneratorDeleter::operator()(Generator *p) {
|
|||
delete p;
|
||||
}
|
||||
|
||||
GeneratorPtr build_generator(const PrintObject &print_object)
|
||||
GeneratorPtr build_generator(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
return GeneratorPtr(new Generator(print_object));
|
||||
return GeneratorPtr(new Generator(print_object, throw_on_cancel_callback));
|
||||
}
|
||||
|
||||
} // namespace Slic3r::FillAdaptive
|
||||
|
|
|
@ -3,13 +3,6 @@
|
|||
|
||||
#include "FillBase.hpp"
|
||||
|
||||
/*
|
||||
* A few modifications based on dba1179(2022.06.10) from Prusa, mainly in Generator.hpp and .cpp:
|
||||
* 1. delete the second parameter(a throw back function) of Generator(), since I didnt find corresponding throw back function in BBS code
|
||||
* 2. those codes that call the functions above
|
||||
* 3. add codes of generating lightning in TreeSupport.cpp
|
||||
*/
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintObject;
|
||||
|
@ -21,7 +14,7 @@ class Generator;
|
|||
struct GeneratorDeleter { void operator()(Generator *p); };
|
||||
using GeneratorPtr = std::unique_ptr<Generator, GeneratorDeleter>;
|
||||
|
||||
GeneratorPtr build_generator(const PrintObject &print_object);
|
||||
GeneratorPtr build_generator(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
|
||||
|
||||
class Filler : public Slic3r::Fill
|
||||
{
|
||||
|
|
|
@ -43,7 +43,8 @@ DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outl
|
|||
m_supporting_radius2 = Slic3r::sqr(int64_t(radius));
|
||||
// Sample source polygons with a regular grid sampling pattern.
|
||||
const BoundingBox overhang_bbox = get_extents(current_overhang);
|
||||
for (const ExPolygon &expoly : union_ex(current_overhang)) {
|
||||
ExPolygons expolys = offset2_ex(union_ex(current_overhang), -m_cell_size / 2, m_cell_size / 2); // remove dangling lines which causes sample_grid_pattern crash (fails the OUTER_LOW assertions)
|
||||
for (const ExPolygon &expoly : expolys) {
|
||||
const Points sampled_points = sample_grid_pattern(expoly, m_cell_size, overhang_bbox);
|
||||
const size_t unsupported_points_prev_size = m_unsupported_points.size();
|
||||
m_unsupported_points.resize(unsupported_points_prev_size + sampled_points.size());
|
||||
|
@ -94,10 +95,6 @@ DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outl
|
|||
|
||||
void DistanceField::update(const Point& to_node, const Point& added_leaf)
|
||||
{
|
||||
std::ofstream out1("z:/misc/lightning.txt", std::ios::app);
|
||||
out1 << m_unsupported_points.size() << std::endl;
|
||||
out1.close();
|
||||
|
||||
Vec2d v = (added_leaf - to_node).cast<double>();
|
||||
auto l2 = v.squaredNorm();
|
||||
Vec2d extent = Vec2d(-v.y(), v.x()) * m_supporting_radius / sqrt(l2);
|
||||
|
|
|
@ -63,7 +63,7 @@ Slic3r::SVG draw_two_overhangs_to_svg(size_t ts_layer, const ExPolygons& overhan
|
|||
|
||||
namespace Slic3r::FillLightning {
|
||||
|
||||
Generator::Generator(const PrintObject &print_object)
|
||||
Generator::Generator(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
const PrintConfig &print_config = print_object.print()->config();
|
||||
const PrintObjectConfig &object_config = print_object.config();
|
||||
|
@ -87,11 +87,11 @@ Generator::Generator(const PrintObject &print_object)
|
|||
m_prune_length = coord_t(layer_thickness * std::tan(lightning_infill_prune_angle));
|
||||
m_straightening_max_distance = coord_t(layer_thickness * std::tan(lightning_infill_straightening_angle));
|
||||
|
||||
generateInitialInternalOverhangs(print_object);
|
||||
generateTrees(print_object);
|
||||
generateInitialInternalOverhangs(print_object, throw_on_cancel_callback);
|
||||
generateTrees(print_object, throw_on_cancel_callback);
|
||||
}
|
||||
|
||||
Generator::Generator(PrintObject* m_object, std::vector<Polygons>& contours, std::vector<Polygons>& overhangs, float density)
|
||||
Generator::Generator(PrintObject* m_object, std::vector<Polygons>& contours, std::vector<Polygons>& overhangs, const std::function<void()> &throw_on_cancel_callback, float density)
|
||||
{
|
||||
const PrintConfig &print_config = m_object->print()->config();
|
||||
const PrintObjectConfig &object_config = m_object->config();
|
||||
|
@ -120,7 +120,7 @@ Generator::Generator(PrintObject* m_object, std::vector<Polygons>& contours, std
|
|||
|
||||
m_overhang_per_layer = overhangs;
|
||||
|
||||
generateTreesforSupport(contours);
|
||||
generateTreesforSupport(contours, throw_on_cancel_callback);
|
||||
|
||||
//for (size_t i = 0; i < overhangs.size(); i++)
|
||||
//{
|
||||
|
@ -130,13 +130,14 @@ Generator::Generator(PrintObject* m_object, std::vector<Polygons>& contours, std
|
|||
//}
|
||||
}
|
||||
|
||||
void Generator::generateInitialInternalOverhangs(const PrintObject &print_object)
|
||||
void Generator::generateInitialInternalOverhangs(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
m_overhang_per_layer.resize(print_object.layers().size());
|
||||
|
||||
Polygons infill_area_above;
|
||||
//Iterate from top to bottom, to subtract the overhang areas above from the overhang areas on the layer below, to get only overhang in the top layer where it is overhanging.
|
||||
for (int layer_nr = int(print_object.layers().size()) - 1; layer_nr >= 0; --layer_nr) {
|
||||
throw_on_cancel_callback();
|
||||
Polygons infill_area_here;
|
||||
for (const LayerRegion* layerm : print_object.get_layer(layer_nr)->regions())
|
||||
for (const Surface& surface : layerm->fill_surfaces.surfaces)
|
||||
|
@ -157,7 +158,7 @@ const Layer& Generator::getTreesForLayer(const size_t& layer_id) const
|
|||
return m_lightning_layers[layer_id];
|
||||
}
|
||||
|
||||
void Generator::generateTrees(const PrintObject &print_object)
|
||||
void Generator::generateTrees(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
m_lightning_layers.resize(print_object.layers().size());
|
||||
bboxs.resize(print_object.layers().size());
|
||||
|
@ -165,6 +166,7 @@ void Generator::generateTrees(const PrintObject &print_object)
|
|||
|
||||
// For-each layer from top to bottom:
|
||||
for (int layer_id = int(print_object.layers().size()) - 1; layer_id >= 0; layer_id--) {
|
||||
throw_on_cancel_callback();
|
||||
for (const LayerRegion *layerm : print_object.get_layer(layer_id)->regions())
|
||||
for (const Surface &surface : layerm->fill_surfaces.surfaces)
|
||||
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
|
||||
|
@ -178,6 +180,7 @@ void Generator::generateTrees(const PrintObject &print_object)
|
|||
|
||||
// For-each layer from top to bottom:
|
||||
for (int layer_id = int(top_layer_id); layer_id >= 0; layer_id--) {
|
||||
throw_on_cancel_callback();
|
||||
Layer ¤t_lightning_layer = m_lightning_layers[layer_id];
|
||||
const Polygons ¤t_outlines = infill_outlines[layer_id];
|
||||
const BoundingBox ¤t_outlines_bbox = get_extents(current_outlines);
|
||||
|
@ -187,7 +190,7 @@ void Generator::generateTrees(const PrintObject &print_object)
|
|||
// register all trees propagated from the previous layer as to-be-reconnected
|
||||
std::vector<NodeSPtr> to_be_reconnected_tree_roots = current_lightning_layer.tree_roots;
|
||||
|
||||
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
|
||||
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius, throw_on_cancel_callback);
|
||||
current_lightning_layer.reconnectRoots(to_be_reconnected_tree_roots, current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
|
||||
|
||||
// Initialize trees for next lower layer from the current one.
|
||||
|
@ -211,7 +214,7 @@ void Generator::generateTrees(const PrintObject &print_object)
|
|||
}
|
||||
}
|
||||
|
||||
void Generator::generateTreesforSupport(std::vector<Polygons>& contours)
|
||||
void Generator::generateTreesforSupport(std::vector<Polygons>& contours, const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
if (contours.empty()) return;
|
||||
|
||||
|
@ -225,6 +228,7 @@ void Generator::generateTreesforSupport(std::vector<Polygons>& contours)
|
|||
|
||||
// For-each layer from top to bottom:
|
||||
for (int layer_id = int(top_layer_id); layer_id >= 0; layer_id--) {
|
||||
throw_on_cancel_callback();
|
||||
Layer& current_lightning_layer = m_lightning_layers[layer_id];
|
||||
const Polygons& current_outlines = contours[layer_id];
|
||||
const BoundingBox& current_outlines_bbox = get_extents(current_outlines);
|
||||
|
@ -234,7 +238,7 @@ void Generator::generateTreesforSupport(std::vector<Polygons>& contours)
|
|||
// register all trees propagated from the previous layer as to-be-reconnected
|
||||
std::vector<NodeSPtr> to_be_reconnected_tree_roots = current_lightning_layer.tree_roots;
|
||||
|
||||
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
|
||||
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius, throw_on_cancel_callback);
|
||||
current_lightning_layer.reconnectRoots(to_be_reconnected_tree_roots, current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
|
||||
|
||||
// Initialize trees for next lower layer from the current one.
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
* Lightning Infill for the infill areas in that mesh. The infill areas must
|
||||
* already be calculated at this point.
|
||||
*/
|
||||
explicit Generator(const PrintObject &print_object);
|
||||
explicit Generator(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
|
||||
|
||||
/*!
|
||||
* Get a tree of paths generated for a certain layer of the mesh.
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
float infilll_extrusion_width() const { return m_infill_extrusion_width; }
|
||||
|
||||
Generator(PrintObject* m_object, std::vector<Polygons>& contours, std::vector<Polygons>& overhangs, float density = 0.15);
|
||||
Generator(PrintObject* m_object, std::vector<Polygons>& contours, std::vector<Polygons>& overhangs, const std::function<void()> &throw_on_cancel_callback, float density = 0.15);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
|
@ -72,13 +72,13 @@ protected:
|
|||
* only when support is generated. For this pattern, we also need to
|
||||
* generate overhang areas for the inside of the model.
|
||||
*/
|
||||
void generateInitialInternalOverhangs(const PrintObject &print_object);
|
||||
void generateInitialInternalOverhangs(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
|
||||
|
||||
/*!
|
||||
* Calculate the tree structure of all layers.
|
||||
*/
|
||||
void generateTrees(const PrintObject &print_object);
|
||||
void generateTreesforSupport(std::vector<Polygons>& contours);
|
||||
void generateTrees(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
|
||||
void generateTreesforSupport(std::vector<Polygons>& contours, const std::function<void()> &throw_on_cancel_callback);
|
||||
|
||||
float m_infill_extrusion_width;
|
||||
|
||||
|
|
|
@ -48,10 +48,12 @@ void Layer::generateNewTrees
|
|||
const BoundingBox& current_outlines_bbox,
|
||||
const EdgeGrid::Grid& outlines_locator,
|
||||
const coord_t supporting_radius,
|
||||
const coord_t wall_supporting_radius
|
||||
const coord_t wall_supporting_radius,
|
||||
const std::function<void()> &throw_on_cancel_callback
|
||||
)
|
||||
{
|
||||
DistanceField distance_field(supporting_radius, current_outlines, current_outlines_bbox, current_overhang);
|
||||
throw_on_cancel_callback();
|
||||
|
||||
SparseNodeGrid tree_node_locator;
|
||||
fillLocator(tree_node_locator, current_outlines_bbox);
|
||||
|
@ -61,6 +63,7 @@ void Layer::generateNewTrees
|
|||
size_t unsupported_cell_idx = 0;
|
||||
Point unsupported_location;
|
||||
while (distance_field.tryGetNextPoint(&unsupported_location, &unsupported_cell_idx, unsupported_cell_idx)) {
|
||||
throw_on_cancel_callback();
|
||||
GroundingLocation grounding_loc = getBestGroundingLocation(
|
||||
unsupported_location, current_outlines, current_outlines_bbox, outlines_locator, supporting_radius, wall_supporting_radius, tree_node_locator);
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ public:
|
|||
const BoundingBox& current_outlines_bbox,
|
||||
const EdgeGrid::Grid& outline_locator,
|
||||
coord_t supporting_radius,
|
||||
coord_t wall_supporting_radius
|
||||
coord_t wall_supporting_radius,
|
||||
const std::function<void()> &throw_on_cancel_callback
|
||||
);
|
||||
|
||||
/*! Determine & connect to connection point in tree/outline.
|
||||
|
|
|
@ -546,7 +546,7 @@ FillLightning::GeneratorPtr PrintObject::prepare_lightning_infill_data()
|
|||
break;
|
||||
}
|
||||
|
||||
return has_lightning_infill ? FillLightning::build_generator(std::as_const(*this)) : FillLightning::GeneratorPtr();
|
||||
return has_lightning_infill ? FillLightning::build_generator(std::as_const(*this), [this]() -> void { this->throw_if_canceled(); }) : FillLightning::GeneratorPtr();
|
||||
}
|
||||
|
||||
void PrintObject::clear_layers()
|
||||
|
|
|
@ -1954,7 +1954,8 @@ ExPolygons avoid_object_remove_extra_small_parts(ExPolygons &expolys, const ExPo
|
|||
void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_nodes)
|
||||
{
|
||||
const PrintObjectConfig &config = m_object->config();
|
||||
bool has_brim = m_object->print()->has_brim();
|
||||
const Print* print = m_object->print();
|
||||
bool has_brim = print->has_brim();
|
||||
bool has_infill = config.support_base_pattern.value != smpNone && config.support_base_pattern != smpDefault;
|
||||
int bottom_gap_layers = round(m_slicing_params.gap_object_support / m_slicing_params.layer_height);
|
||||
const coordf_t branch_radius = config.tree_support_branch_diameter.value / 2;
|
||||
|
@ -1979,7 +1980,6 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
|
|||
|
||||
// Performance optimization. Only generate lslices for brim and skirt.
|
||||
size_t brim_skirt_layers = has_brim ? 1 : 0;
|
||||
const Print* print = m_object->print();
|
||||
const PrintConfig& print_config = print->config();
|
||||
for (const PrintObject* object : print->objects())
|
||||
{
|
||||
|
@ -2256,7 +2256,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
|
|||
#endif
|
||||
}
|
||||
|
||||
generator = std::make_unique<FillLightning::Generator>(m_object, contours, overhangs, support_density);
|
||||
generator = std::make_unique<FillLightning::Generator>(m_object, contours, overhangs, []() {}, support_density);
|
||||
}
|
||||
|
||||
else if (!has_infill) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue