ENH: improve tree support

1. add a hook inside tree branches for improved strength
2. fix the issue that interface may fly as a mess (delete the logic
  where gap nodes can skip dropping down)
3. fix the issue that base nodes may fly as a mess (smoothing should
  skip polygon nodes, see Jira:STUDIO-4403)

Change-Id: Ie9f2039813c2ca3127ed8913304cc455fec8e7ee
(cherry picked from commit 83cef5f91d49ff3d275a89ec3df8b5f0fd573f8c)
This commit is contained in:
arthur 2023-09-23 16:31:49 +08:00 committed by Lane.Wei
parent a62bf3b838
commit 76f876a3c6
9 changed files with 476 additions and 330 deletions

View file

@ -665,6 +665,8 @@ Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &c
{ return _clipper(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); } { return _clipper(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
Slic3r::Polygons diff_clipped(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset) Slic3r::Polygons diff_clipped(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return diff(subject, ClipperUtils::clip_clipper_polygons_with_subject_bbox(clip, get_extents(subject).inflated(SCALED_EPSILON)), do_safety_offset); } { return diff(subject, ClipperUtils::clip_clipper_polygons_with_subject_bbox(clip, get_extents(subject).inflated(SCALED_EPSILON)), do_safety_offset); }
Slic3r::ExPolygons diff_clipped(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return diff_ex(subject, ClipperUtils::clip_clipper_polygons_with_subject_bbox(clip, get_extents(subject).inflated(SCALED_EPSILON)), do_safety_offset); }
Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset) Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); } { return _clipper(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset) Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)

View file

@ -430,6 +430,7 @@ Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::ExPolygon
// Optimized version clipping the "clipping" polygon using clip_clipper_polygon_with_subject_bbox(). // Optimized version clipping the "clipping" polygon using clip_clipper_polygon_with_subject_bbox().
// To be used with complex clipping polygons, where majority of the clipping polygons are outside of the source polygon. // To be used with complex clipping polygons, where majority of the clipping polygons are outside of the source polygon.
Slic3r::Polygons diff_clipped(const Slic3r::Polygons &src, const Slic3r::Polygons &clipping, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::Polygons diff_clipped(const Slic3r::Polygons &src, const Slic3r::Polygons &clipping, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::ExPolygons diff_clipped(const Slic3r::ExPolygons &src, const Slic3r::Polygons &clipping, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons diff(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::Polygons diff(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);

View file

@ -306,6 +306,7 @@ protected:
int type; int type;
coordf_t dist_to_top; // mm dist to top coordf_t dist_to_top; // mm dist to top
bool need_infill = false; bool need_infill = false;
bool need_extra_wall = false;
AreaGroup(ExPolygon *a, int t, coordf_t d) : area(a), type(t), dist_to_top(d) {} AreaGroup(ExPolygon *a, int t, coordf_t d) : area(a), type(t), dist_to_top(d) {}
}; };
enum OverhangType { Detected = 0, Enforced }; enum OverhangType { Detected = 0, Enforced };

View file

@ -3246,7 +3246,7 @@ void PrintConfigDef::init_fff_params()
def->category = L("Support"); def->category = L("Support");
def->tooltip = L("This setting specify the count of walls around tree support"); def->tooltip = L("This setting specify the count of walls around tree support");
def->min = 0; def->min = 0;
def->mode = comAdvanced; def->mode = comDevelop;
def->set_default_value(new ConfigOptionInt(1)); def->set_default_value(new ConfigOptionInt(1));
def = this->add("tree_support_brim_width", coFloat); def = this->add("tree_support_brim_width", coFloat);

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,8 @@
#include "Flow.hpp" #include "Flow.hpp"
#include "PrintConfig.hpp" #include "PrintConfig.hpp"
#include "Fill/Lightning/Generator.hpp" #include "Fill/Lightning/Generator.hpp"
#include "TreeModelVolumes.hpp"
#include "TreeSupport3D.hpp"
#ifndef SQ #ifndef SQ
#define SQ(x) ((x)*(x)) #define SQ(x) ((x)*(x))
@ -244,7 +246,6 @@ public:
, position(Point(0, 0)) , position(Point(0, 0))
, obj_layer_nr(0) , obj_layer_nr(0)
, support_roof_layers_below(0) , support_roof_layers_below(0)
, support_floor_layers_above(0)
, to_buildplate(true) , to_buildplate(true)
, parent(nullptr) , parent(nullptr)
, print_z(0.0) , print_z(0.0)
@ -258,7 +259,6 @@ public:
, position(position) , position(position)
, obj_layer_nr(obj_layer_nr) , obj_layer_nr(obj_layer_nr)
, support_roof_layers_below(support_roof_layers_below) , support_roof_layers_below(support_roof_layers_below)
, support_floor_layers_above(0)
, to_buildplate(to_buildplate) , to_buildplate(to_buildplate)
, parent(parent) , parent(parent)
, print_z(print_z_) , print_z(print_z_)
@ -266,13 +266,16 @@ public:
, dist_mm_to_top(dist_mm_to_top_) , dist_mm_to_top(dist_mm_to_top_)
{ {
if (parent) { if (parent) {
parents.push_back(parent);
type = parent->type; type = parent->type;
overhang = parent->overhang; overhang = parent->overhang;
if (dist_mm_to_top==0) if (dist_mm_to_top==0)
dist_mm_to_top = parent->dist_mm_to_top + parent->height; dist_mm_to_top = parent->dist_mm_to_top + parent->height;
parent->child = this; parent->child = this;
for (auto& neighbor : parent->merged_neighbours) for (auto& neighbor : parent->merged_neighbours) {
neighbor->child = this; neighbor->child = this;
parents.push_back(neighbor);
}
} }
} }
@ -299,10 +302,10 @@ public:
mutable double radius = 0.0; mutable double radius = 0.0;
mutable double max_move_dist = 0.0; mutable double max_move_dist = 0.0;
NodeType type = eCircle; NodeType type = eCircle;
bool is_merged = false; // this node is generated by merging upper nodes
bool is_corner = false; bool is_corner = false;
bool is_processed = false; bool is_processed = false;
const ExPolygon *overhang = nullptr; // when type==ePolygon, set this value to get original overhang area bool need_extra_wall = false;
ExPolygon overhang; // when type==ePolygon, set this value to get original overhang area
/*! /*!
* \brief The direction of the skin lines above the tip of the branch. * \brief The direction of the skin lines above the tip of the branch.
@ -321,7 +324,6 @@ public:
* how far we need to extend that support roof downwards. * how far we need to extend that support roof downwards.
*/ */
int support_roof_layers_below; int support_roof_layers_below;
int support_floor_layers_above;
int obj_layer_nr; int obj_layer_nr;
/*! /*!
@ -341,6 +343,7 @@ public:
* the entire branch needs to be known. * the entire branch needs to be known.
*/ */
Node *parent; Node *parent;
std::vector<Node*> parents;
Node *child = nullptr; Node *child = nullptr;
/*! /*!
@ -387,6 +390,7 @@ public:
InfillPattern interface_fill_pattern; InfillPattern interface_fill_pattern;
InfillPattern contact_fill_pattern; InfillPattern contact_fill_pattern;
bool with_sheath; bool with_sheath;
bool independent_layer_height = false;
const double thresh_big_overhang = SQ(scale_(10)); const double thresh_big_overhang = SQ(scale_(10));
}; };
@ -417,6 +421,7 @@ private:
* \warning This class is NOT currently thread-safe and should not be accessed in OpenMP blocks * \warning This class is NOT currently thread-safe and should not be accessed in OpenMP blocks
*/ */
std::shared_ptr<TreeSupportData> m_ts_data; std::shared_ptr<TreeSupportData> m_ts_data;
std::unique_ptr<TreeSupport3D::TreeModelVolumes> m_model_volumes;
PrintObject *m_object; PrintObject *m_object;
const PrintObjectConfig* m_object_config; const PrintObjectConfig* m_object_config;
SlicingParameters m_slicing_params; SlicingParameters m_slicing_params;
@ -431,6 +436,7 @@ private:
coordf_t MAX_BRANCH_RADIUS_FIRST_LAYER = 12.0; coordf_t MAX_BRANCH_RADIUS_FIRST_LAYER = 12.0;
coordf_t MIN_BRANCH_RADIUS = 0.5; coordf_t MIN_BRANCH_RADIUS = 0.5;
float tree_support_branch_diameter_angle = 5.0; float tree_support_branch_diameter_angle = 5.0;
coord_t m_min_radius = scale_(1); // in mm
bool is_strong = false; bool is_strong = false;
bool is_slim = false; bool is_slim = false;
bool with_infill = false; bool with_infill = false;
@ -465,7 +471,7 @@ private:
void smooth_nodes(std::vector<std::vector<Node *>> &contact_nodes); void smooth_nodes(std::vector<std::vector<Node *>> &contact_nodes);
void adjust_layer_heights(std::vector<std::vector<Node*>>& contact_nodes); void smooth_nodes(std::vector<std::vector<Node*>>& contact_nodes, const TreeSupport3D::TreeSupportSettings& config);
/*! BBS: MusangKing: maximum layer height /*! BBS: MusangKing: maximum layer height
* \brief Optimize the generation of tree support by pre-planning the layer_heights * \brief Optimize the generation of tree support by pre-planning the layer_heights
@ -486,7 +492,7 @@ private:
* \return For each layer, a list of points where the tree should connect * \return For each layer, a list of points where the tree should connect
* with the model. * with the model.
*/ */
void generate_contact_points(std::vector<std::vector<Node*>>& contact_nodes); void generate_contact_points(std::vector<std::vector<Node*>>& contact_nodes, const std::vector<TreeSupport3D::SupportElements>& move_bounds);
/*! /*!
* \brief Add a node to the next layer. * \brief Add a node to the next layer.
@ -500,7 +506,11 @@ private:
Polygons contact_nodes_to_polygon(const std::vector<Node*>& contact_nodes, Polygons layer_contours, int layer_nr, std::vector<double>& radiis, std::vector<bool>& is_interface); Polygons contact_nodes_to_polygon(const std::vector<Node*>& contact_nodes, Polygons layer_contours, int layer_nr, std::vector<double>& radiis, std::vector<bool>& is_interface);
void clear_contact_nodes(std::vector<std::vector<Node*>>& contact_nodes); void clear_contact_nodes(std::vector<std::vector<Node*>>& contact_nodes);
coordf_t calc_branch_radius(coordf_t base_radius, size_t layers_to_top, size_t tip_layers, double diameter_angle_scale_factor); coordf_t calc_branch_radius(coordf_t base_radius, size_t layers_to_top, size_t tip_layers, double diameter_angle_scale_factor);
coordf_t calc_branch_radius(coordf_t base_radius, coordf_t mm_to_top, double diameter_angle_scale_factor); coordf_t calc_branch_radius(coordf_t base_radius, coordf_t mm_to_top, double diameter_angle_scale_factor, bool use_min_distance=true);
ExPolygons get_avoidance(coordf_t radius, size_t obj_layer_nr);
ExPolygons get_collision(coordf_t radius, size_t layer_nr);
// get Polygons instead of ExPolygons
Polygons get_collision_polys(coordf_t radius, size_t layer_nr);
// similar to SupportMaterial::trim_support_layers_by_object // similar to SupportMaterial::trim_support_layers_by_object
Polygons get_trim_support_regions( Polygons get_trim_support_regions(

View file

@ -321,9 +321,6 @@ void tree_supports_show_error(std::string_view message, bool critical)
/*! /*!
* \brief Precalculates all avoidances, that could be required. * \brief Precalculates all avoidances, that could be required.
*
* \param storage[in] Background storage to access meshes.
* \param currently_processing_meshes[in] Indexes of all meshes that are processed in this iteration
*/ */
[[nodiscard]] static LayerIndex precalculate(const Print &print, const std::vector<Polygons> &overhangs, const TreeSupportSettings &config, const std::vector<size_t> &object_ids, TreeModelVolumes &volumes, std::function<void()> throw_on_cancel) [[nodiscard]] static LayerIndex precalculate(const Print &print, const std::vector<Polygons> &overhangs, const TreeSupportSettings &config, const std::vector<size_t> &object_ids, TreeModelVolumes &volumes, std::function<void()> throw_on_cancel)
{ {
@ -833,7 +830,7 @@ inline SupportGeneratorLayer& layer_allocate(
* \param move_bounds[out] Storage for the influence areas. * \param move_bounds[out] Storage for the influence areas.
* \param storage[in] Background storage, required for adding roofs. * \param storage[in] Background storage, required for adding roofs.
*/ */
static void generate_initial_areas( void generate_initial_areas(
const PrintObject &print_object, const PrintObject &print_object,
const TreeModelVolumes &volumes, const TreeModelVolumes &volumes,
const TreeSupportSettings &config, const TreeSupportSettings &config,
@ -3438,11 +3435,10 @@ static void extrude_branch(
#ifdef TREE_SUPPORT_ORGANIC_NUDGE_NEW #ifdef TREE_SUPPORT_ORGANIC_NUDGE_NEW
// New version using per layer AABB trees of lines for nudging spheres away from an object. // New version using per layer AABB trees of lines for nudging spheres away from an object.
static void organic_smooth_branches_avoid_collisions( void organic_smooth_branches_avoid_collisions(
const PrintObject &print_object, const PrintObject &print_object,
const TreeModelVolumes &volumes, const TreeModelVolumes &volumes,
const TreeSupportSettings &config, const TreeSupportSettings &config,
std::vector<SupportElements> &move_bounds,
const std::vector<std::pair<SupportElement*, int>> &elements_with_link_down, const std::vector<std::pair<SupportElement*, int>> &elements_with_link_down,
const std::vector<size_t> &linear_data_layers, const std::vector<size_t> &linear_data_layers,
std::function<void()> throw_on_cancel) std::function<void()> throw_on_cancel)
@ -3520,9 +3516,9 @@ static void organic_smooth_branches_avoid_collisions(
link_down, link_down,
// locked // locked
element.parents.empty() || (link_down == -1 && element.state.layer_idx > 0), element.parents.empty() || (link_down == -1 && element.state.layer_idx > 0),
unscaled<float>(config.getRadius(element.state)), element.state.radius<EPSILON? unscaled<float>(config.getRadius(element.state)):float(element.state.radius),
// 3D position // 3D position
to_3d(unscaled<float>(element.state.result_on_layer), float(layer_z(slicing_params, element.state.layer_idx))) to_3d(unscaled<float>(element.state.result_on_layer), element.state.print_z<EPSILON? float(layer_z(slicing_params, element.state.layer_idx)):element.state.print_z)
}); });
// Update min_z coordinate to min_z of the tree below. // Update min_z coordinate to min_z of the tree below.
CollisionSphere &collision_sphere = collision_spheres.back(); CollisionSphere &collision_sphere = collision_spheres.back();
@ -3569,12 +3565,14 @@ static void organic_smooth_branches_avoid_collisions(
collision_sphere.prev_position = collision_sphere.position; collision_sphere.prev_position = collision_sphere.position;
std::atomic<size_t> num_moved{ 0 }; std::atomic<size_t> num_moved{ 0 };
tbb::parallel_for(tbb::blocked_range<size_t>(0, collision_spheres.size()), tbb::parallel_for(tbb::blocked_range<size_t>(0, collision_spheres.size()),
[&collision_spheres, &layer_collision_cache, &slicing_params, &move_bounds, &linear_data_layers, &num_moved, &throw_on_cancel](const tbb::blocked_range<size_t> range) { [&collision_spheres, &layer_collision_cache, &slicing_params, &linear_data_layers, &num_moved, &throw_on_cancel](const tbb::blocked_range<size_t> range) {
for (size_t collision_sphere_id = range.begin(); collision_sphere_id < range.end(); ++ collision_sphere_id) for (size_t collision_sphere_id = range.begin(); collision_sphere_id < range.end(); ++ collision_sphere_id)
if (CollisionSphere &collision_sphere = collision_spheres[collision_sphere_id]; ! collision_sphere.locked) { if (CollisionSphere &collision_sphere = collision_spheres[collision_sphere_id]; ! collision_sphere.locked) {
// Calculate collision of multiple 2D layers against a collision sphere. // Calculate collision of multiple 2D layers against a collision sphere.
collision_sphere.last_collision_depth = - std::numeric_limits<double>::max(); collision_sphere.last_collision_depth = - std::numeric_limits<double>::max();
for (uint32_t layer_id = collision_sphere.layer_begin; layer_id != collision_sphere.layer_end; ++ layer_id) { for (uint32_t layer_id = collision_sphere.layer_begin; layer_id != collision_sphere.layer_end; ++ layer_id) {
if(layer_id>= layer_collision_cache.size())
continue;
double dz = (layer_id - collision_sphere.element.state.layer_idx) * slicing_params.layer_height; double dz = (layer_id - collision_sphere.element.state.layer_idx) * slicing_params.layer_height;
if (double r2 = sqr(collision_sphere.radius) - sqr(dz); r2 > 0) { if (double r2 = sqr(collision_sphere.radius) - sqr(dz); r2 > 0) {
if (const LayerCollisionCache &layer_collision_cache_item = layer_collision_cache[layer_id]; ! layer_collision_cache_item.empty()) { if (const LayerCollisionCache &layer_collision_cache_item = layer_collision_cache[layer_id]; ! layer_collision_cache_item.empty()) {
@ -3605,7 +3603,6 @@ static void organic_smooth_branches_avoid_collisions(
} }
// Laplacian smoothing // Laplacian smoothing
Vec2d avg{ 0, 0 }; Vec2d avg{ 0, 0 };
const SupportElements &above = move_bounds[collision_sphere.element.state.layer_idx + 1];
const size_t offset_above = linear_data_layers[collision_sphere.element.state.layer_idx + 1]; const size_t offset_above = linear_data_layers[collision_sphere.element.state.layer_idx + 1];
double weight = 0.; double weight = 0.;
for (auto iparent : collision_sphere.element.parents) { for (auto iparent : collision_sphere.element.parents) {
@ -3615,7 +3612,7 @@ static void organic_smooth_branches_avoid_collisions(
} }
if (collision_sphere.element_below_id != -1) { if (collision_sphere.element_below_id != -1) {
const size_t offset_below = linear_data_layers[collision_sphere.element.state.layer_idx - 1]; const size_t offset_below = linear_data_layers[collision_sphere.element.state.layer_idx - 1];
const double w = weight; // config.getRadius(move_bounds[element.state.layer_idx - 1][below].state); const double w = weight;
avg += w * to_2d(collision_spheres[offset_below + collision_sphere.element_below_id].prev_position.cast<double>()); avg += w * to_2d(collision_spheres[offset_below + collision_sphere.element_below_id].prev_position.cast<double>());
weight += w; weight += w;
} }
@ -3802,7 +3799,7 @@ indexed_triangle_set draw_branches(
throw_on_cancel(); throw_on_cancel();
organic_smooth_branches_avoid_collisions(print_object, volumes, config, move_bounds, elements_with_link_down, linear_data_layers, throw_on_cancel); organic_smooth_branches_avoid_collisions(print_object, volumes, config, elements_with_link_down, linear_data_layers, throw_on_cancel);
// Unmark all nodes. // Unmark all nodes.
for (SupportElements &elements : move_bounds) for (SupportElements &elements : move_bounds)
@ -4010,13 +4007,17 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
generate_initial_areas(*print.get_object(mesh_idx), volumes, config, overhangs, move_bounds, top_contacts, layer_storage, throw_on_cancel); generate_initial_areas(*print.get_object(mesh_idx), volumes, config, overhangs, move_bounds, top_contacts, layer_storage, throw_on_cancel);
auto t_gen = std::chrono::high_resolution_clock::now(); auto t_gen = std::chrono::high_resolution_clock::now();
// save num of points to log
for (size_t i = 0; i < move_bounds.size(); i++)
BOOST_LOG_TRIVIAL(info) << "Number of points in move_bound: " << move_bounds[i].size() << " in layer " << i;
#ifdef TREESUPPORT_DEBUG_SVG #ifdef TREESUPPORT_DEBUG_SVG
for (size_t layer_idx = 0; layer_idx < move_bounds.size(); ++layer_idx) { for (size_t layer_idx = 0; layer_idx < move_bounds.size(); ++layer_idx) {
Polygons polys; Polygons polys;
for (auto& area : move_bounds[layer_idx]) for (auto& area : move_bounds[layer_idx])
append(polys, area.influence_area); append(polys, area.influence_area);
if (auto begin = move_bounds[layer_idx].begin(); begin != move_bounds[layer_idx].end()) if (auto begin = move_bounds[layer_idx].begin(); begin != move_bounds[layer_idx].end())
SVG::export_expolygons(debug_out_path("treesupport-initial_areas-%d.svg", layer_idx), SVG::export_expolygons(debug_out_path("initial_areas-%d.svg", layer_idx),
{ { { union_ex(volumes.getWallRestriction(config.getCollisionRadius(begin->state), layer_idx, begin->state.use_min_xy_dist)) }, { { { union_ex(volumes.getWallRestriction(config.getCollisionRadius(begin->state), layer_idx, begin->state.use_min_xy_dist)) },
{ "wall_restricrictions", "gray", 0.5f } }, { "wall_restricrictions", "gray", 0.5f } },
{ { union_ex(polys) }, { "parent", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } }); { { union_ex(polys) }, { "parent", "red", "black", "", scaled<coord_t>(0.1f), 0.5f } } });
@ -4076,10 +4077,7 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
support_params.support_density = 0; support_params.support_density = 0;
SupportGeneratorLayersPtr interface_layers, base_interface_layers; SupportGeneratorLayersPtr 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 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 = generate_support_layers(print_object, raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers);
SupportGeneratorLayersPtr layers_sorted =
#endif // SLIC3R_DEBUG
generate_support_layers(print_object, raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers);
// Don't fill in the tree supports, make them hollow with just a single sheath line. // Don't fill in the tree supports, make them hollow with just a single sheath line.
print.set_status(69, _L("Support: generate toolpath")); print.set_status(69, _L("Support: generate toolpath"));

View file

@ -145,7 +145,9 @@ struct SupportElementStateBits {
struct SupportElementState : public SupportElementStateBits struct SupportElementState : public SupportElementStateBits
{ {
int type; int type=0;
coordf_t radius=0;
float print_z=0;
/*! /*!
* \brief The layer this support elements wants reach * \brief The layer this support elements wants reach
@ -586,10 +588,14 @@ void create_layer_pathing(const TreeModelVolumes& volumes, const TreeSupportSett
void create_nodes_from_area(const TreeModelVolumes& volumes, const TreeSupportSettings& config, std::vector<SupportElements>& move_bounds, std::function<void()> throw_on_cancel); void create_nodes_from_area(const TreeModelVolumes& volumes, const TreeSupportSettings& config, std::vector<SupportElements>& move_bounds, std::function<void()> throw_on_cancel);
void organic_smooth_branches_avoid_collisions(const PrintObject& print_object, const TreeModelVolumes& volumes, const TreeSupportSettings& config, const std::vector<std::pair<SupportElement*, int>>& elements_with_link_down, const std::vector<size_t>& linear_data_layers, std::function<void()> throw_on_cancel);
indexed_triangle_set draw_branches(PrintObject& print_object, const TreeModelVolumes& volumes, const TreeSupportSettings& config, std::vector<SupportElements>& move_bounds, std::function<void()> throw_on_cancel); indexed_triangle_set draw_branches(PrintObject& print_object, const TreeModelVolumes& volumes, const TreeSupportSettings& config, std::vector<SupportElements>& move_bounds, std::function<void()> throw_on_cancel);
void slice_branches(PrintObject& print_object, const TreeModelVolumes& volumes, const TreeSupportSettings& config, const std::vector<Polygons>& overhangs, std::vector<SupportElements>& move_bounds, const indexed_triangle_set& cummulative_mesh, SupportGeneratorLayersPtr& bottom_contacts, SupportGeneratorLayersPtr& top_contacts, SupportGeneratorLayersPtr& intermediate_layers, SupportGeneratorLayerStorage& layer_storage, std::function<void()> throw_on_cancel); void slice_branches(PrintObject& print_object, const TreeModelVolumes& volumes, const TreeSupportSettings& config, const std::vector<Polygons>& overhangs, std::vector<SupportElements>& move_bounds, const indexed_triangle_set& cummulative_mesh, SupportGeneratorLayersPtr& bottom_contacts, SupportGeneratorLayersPtr& top_contacts, SupportGeneratorLayersPtr& intermediate_layers, SupportGeneratorLayerStorage& layer_storage, std::function<void()> throw_on_cancel);
void generate_initial_areas(const PrintObject& print_object, const TreeModelVolumes& volumes, const TreeSupportSettings& config, const std::vector<Polygons>& overhangs, std::vector<SupportElements>& move_bounds, SupportGeneratorLayersPtr& top_contacts, SupportGeneratorLayerStorage& layer_storage, std::function<void()> throw_on_cancel);
} // namespace TreeSupport3D } // namespace TreeSupport3D
void generate_tree_support_3D(PrintObject &print_object, TreeSupport* tree_support, std::function<void()> throw_on_cancel = []{}); void generate_tree_support_3D(PrintObject &print_object, TreeSupport* tree_support, std::function<void()> throw_on_cancel = []{});

View file

@ -64,7 +64,7 @@ static constexpr double RESOLUTION = 0.0125;
static constexpr double SPARSE_INFILL_RESOLUTION = 0.04; static constexpr double SPARSE_INFILL_RESOLUTION = 0.04;
#define SCALED_SPARSE_INFILL_RESOLUTION (SPARSE_INFILL_RESOLUTION / SCALING_FACTOR) #define SCALED_SPARSE_INFILL_RESOLUTION (SPARSE_INFILL_RESOLUTION / SCALING_FACTOR)
static constexpr double SUPPORT_RESOLUTION = 0.05; static constexpr double SUPPORT_RESOLUTION = 0.1;
#define SCALED_SUPPORT_RESOLUTION (SUPPORT_RESOLUTION / SCALING_FACTOR) #define SCALED_SUPPORT_RESOLUTION (SUPPORT_RESOLUTION / SCALING_FACTOR)
// Maximum perimeter length for the loop to apply the small perimeter speed. // Maximum perimeter length for the loop to apply the small perimeter speed.
#define SMALL_PERIMETER_LENGTH ((6.5 / SCALING_FACTOR) * 2 * PI) #define SMALL_PERIMETER_LENGTH ((6.5 / SCALING_FACTOR) * 2 * PI)