mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-15 02:37:51 -06:00
ENH: improve hybrid tree support
1. do not add interface for small overhangs so supports are easier to remove 2. calculate avoidance more accurately using real layer height jira: STUDIO-6285 3. hybrid nodes won't collide with lower layers 4. calculate max move more accurately 5. do not increase radius if next layer has collision jira: STUDIO-2296, STUDIO-7883 6. rewrite plan_layer_heights to prevent support layers overlap. Now the tree support layers are completely independent to object layers. 6. increase collision areas for interface. The top layers may be too close to interface with adaptive layer heights and very small overhang angle Change-Id: I052c3f66e68afb7663e2d70c846dd09ed7086071 (cherry picked from commit aca511caebfdeec270d4fc0ec6bbbadde77cddc9) (cherry picked from commit f2fc996652b3b204b4e554f57afed8519feb0397)
This commit is contained in:
parent
532dcae37a
commit
5054ee8508
5 changed files with 479 additions and 425 deletions
|
@ -845,14 +845,8 @@ void PrintObject::clear_support_layers()
|
||||||
std::shared_ptr<TreeSupportData> PrintObject::alloc_tree_support_preview_cache()
|
std::shared_ptr<TreeSupportData> PrintObject::alloc_tree_support_preview_cache()
|
||||||
{
|
{
|
||||||
if (!m_tree_support_preview_cache) {
|
if (!m_tree_support_preview_cache) {
|
||||||
const coordf_t layer_height = m_config.layer_height.value;
|
|
||||||
const coordf_t xy_distance = m_config.support_object_xy_distance.value;
|
const coordf_t xy_distance = m_config.support_object_xy_distance.value;
|
||||||
const double angle = m_config.tree_support_branch_angle.value * M_PI / 180.;
|
m_tree_support_preview_cache = std::make_shared<TreeSupportData>(*this, xy_distance, g_config_tree_support_collision_resolution);
|
||||||
const coordf_t max_move_distance
|
|
||||||
= (angle < M_PI / 2) ? (coordf_t)(tan(angle) * layer_height) : std::numeric_limits<coordf_t>::max();
|
|
||||||
const coordf_t radius_sample_resolution = g_config_tree_support_collision_resolution;
|
|
||||||
|
|
||||||
m_tree_support_preview_cache = std::make_shared<TreeSupportData>(*this, xy_distance, max_move_distance, radius_sample_resolution);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_tree_support_preview_cache;
|
return m_tree_support_preview_cache;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,9 +28,9 @@ struct LayerHeightData
|
||||||
{
|
{
|
||||||
coordf_t print_z = 0;
|
coordf_t print_z = 0;
|
||||||
coordf_t height = 0;
|
coordf_t height = 0;
|
||||||
size_t next_layer_nr = 0;
|
size_t obj_layer_nr = 0;
|
||||||
LayerHeightData() = default;
|
LayerHeightData() = default;
|
||||||
LayerHeightData(coordf_t z, coordf_t h, size_t next_layer) : print_z(z), height(h), next_layer_nr(next_layer) {}
|
LayerHeightData(coordf_t z, coordf_t h, size_t obj_layer) : print_z(z), height(h), obj_layer_nr(obj_layer) {}
|
||||||
coordf_t bottom_z() {
|
coordf_t bottom_z() {
|
||||||
return print_z - height;
|
return print_z - height;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ public:
|
||||||
* \param radius_sample_resolution Sample size used to round requested node radii.
|
* \param radius_sample_resolution Sample size used to round requested node radii.
|
||||||
* \param collision_resolution
|
* \param collision_resolution
|
||||||
*/
|
*/
|
||||||
TreeSupportData(const PrintObject& object, coordf_t max_move, coordf_t radius_sample_resolution, coordf_t collision_resolution);
|
TreeSupportData(const PrintObject& object, coordf_t radius_sample_resolution, coordf_t collision_resolution);
|
||||||
~TreeSupportData() {
|
~TreeSupportData() {
|
||||||
clear_nodes();
|
clear_nodes();
|
||||||
}
|
}
|
||||||
|
@ -305,11 +305,7 @@ public:
|
||||||
*/
|
*/
|
||||||
coordf_t m_xy_distance;
|
coordf_t m_xy_distance;
|
||||||
|
|
||||||
/*!
|
double branch_scale_factor = 1.0; // tan(45 degrees)
|
||||||
* \brief The maximum distance that the centrepoint of a tree branch may
|
|
||||||
* move in consequtive layers
|
|
||||||
*/
|
|
||||||
coordf_t m_max_move;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sample resolution for radius values.
|
* \brief Sample resolution for radius values.
|
||||||
|
@ -328,6 +324,8 @@ public:
|
||||||
// union contours of all layers below
|
// union contours of all layers below
|
||||||
std::vector<ExPolygons> m_layer_outlines_below;
|
std::vector<ExPolygons> m_layer_outlines_below;
|
||||||
|
|
||||||
|
std::vector<double> m_max_move_distances;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Caches for the collision, avoidance and internal model polygons
|
* \brief Caches for the collision, avoidance and internal model polygons
|
||||||
* at given radius and layer indices.
|
* at given radius and layer indices.
|
||||||
|
@ -366,6 +364,10 @@ public:
|
||||||
*/
|
*/
|
||||||
TreeSupport(PrintObject& object, const SlicingParameters &slicing_params);
|
TreeSupport(PrintObject& object, const SlicingParameters &slicing_params);
|
||||||
|
|
||||||
|
void move_bounds_to_contact_nodes(std::vector<TreeSupport3D::SupportElements> &move_bounds,
|
||||||
|
PrintObject &print_object,
|
||||||
|
const TreeSupport3D::TreeSupportSettings &config);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Create the areas that need support.
|
* \brief Create the areas that need support.
|
||||||
*
|
*
|
||||||
|
@ -377,6 +379,19 @@ public:
|
||||||
|
|
||||||
void detect_overhangs(bool check_support_necessity = false);
|
void detect_overhangs(bool check_support_necessity = false);
|
||||||
|
|
||||||
|
SupportNode* create_node(const Point position,
|
||||||
|
const int distance_to_top,
|
||||||
|
const int obj_layer_nr,
|
||||||
|
const int support_roof_layers_below,
|
||||||
|
const bool to_buildplate,
|
||||||
|
SupportNode* parent,
|
||||||
|
coordf_t print_z_,
|
||||||
|
coordf_t height_,
|
||||||
|
coordf_t dist_mm_to_top_ = 0,
|
||||||
|
coordf_t radius_ = 0)
|
||||||
|
{
|
||||||
|
return m_ts_data->create_node(position, distance_to_top, obj_layer_nr, support_roof_layers_below, to_buildplate, parent, print_z_, height_, dist_mm_to_top_, radius_);
|
||||||
|
}
|
||||||
|
|
||||||
int avg_node_per_layer = 0;
|
int avg_node_per_layer = 0;
|
||||||
float nodes_angle = 0;
|
float nodes_angle = 0;
|
||||||
|
@ -419,12 +434,17 @@ private:
|
||||||
std::vector< std::unordered_map<Line, bool, LineHash>> m_mst_line_x_layer_contour_caches;
|
std::vector< std::unordered_map<Line, bool, LineHash>> m_mst_line_x_layer_contour_caches;
|
||||||
|
|
||||||
float DO_NOT_MOVER_UNDER_MM = 0.0;
|
float DO_NOT_MOVER_UNDER_MM = 0.0;
|
||||||
coordf_t MAX_BRANCH_RADIUS = 10.0;
|
coordf_t base_radius = 0.0;
|
||||||
coordf_t MIN_BRANCH_RADIUS = 0.5;
|
const coordf_t MAX_BRANCH_RADIUS = 10.0;
|
||||||
coordf_t MAX_BRANCH_RADIUS_FIRST_LAYER = 12.0;
|
const coordf_t MIN_BRANCH_RADIUS = 0.4;
|
||||||
coordf_t MIN_BRANCH_RADIUS_FIRST_LAYER = 2.0;
|
const coordf_t MAX_BRANCH_RADIUS_FIRST_LAYER = 12.0;
|
||||||
float tree_support_branch_diameter_angle = 5.0;
|
const coordf_t MIN_BRANCH_RADIUS_FIRST_LAYER = 2.0;
|
||||||
coord_t m_min_radius = scale_(1); // in mm
|
const double tree_support_branch_diameter_angle = 5.0;
|
||||||
|
const double diameter_angle_scale_factor = tan(tree_support_branch_diameter_angle*M_PI/180.0);
|
||||||
|
// minimum roof area (1 mm^2), area smaller than this value will not have interface
|
||||||
|
const double minimum_roof_area{SQ(scaled<double>(1.))};
|
||||||
|
float top_z_distance = 0.0;
|
||||||
|
|
||||||
bool is_strong = false;
|
bool is_strong = false;
|
||||||
bool is_slim = false;
|
bool is_slim = false;
|
||||||
bool with_infill = false;
|
bool with_infill = false;
|
||||||
|
@ -492,8 +512,10 @@ private:
|
||||||
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);
|
||||||
// get unscaled radius(mm) of node based on the distance mm to top
|
// get unscaled radius(mm) of node based on the distance mm to top
|
||||||
coordf_t calc_branch_radius(coordf_t base_radius, coordf_t mm_to_top, double diameter_angle_scale_factor, bool use_min_distance=true);
|
coordf_t calc_branch_radius(coordf_t base_radius, coordf_t mm_to_top, double diameter_angle_scale_factor, bool use_min_distance=true);
|
||||||
coordf_t get_radius(const SupportNode* node, coordf_t base_radius);
|
coordf_t calc_radius(coordf_t mm_to_top);
|
||||||
|
coordf_t get_radius(const SupportNode* node);
|
||||||
ExPolygons get_avoidance(coordf_t radius, size_t obj_layer_nr);
|
ExPolygons get_avoidance(coordf_t radius, size_t obj_layer_nr);
|
||||||
|
// layer's expolygon expanded by radius+m_xy_distance
|
||||||
ExPolygons get_collision(coordf_t radius, size_t layer_nr);
|
ExPolygons get_collision(coordf_t radius, size_t layer_nr);
|
||||||
// get Polygons instead of ExPolygons
|
// get Polygons instead of ExPolygons
|
||||||
Polygons get_collision_polys(coordf_t radius, size_t layer_nr);
|
Polygons get_collision_polys(coordf_t radius, size_t layer_nr);
|
||||||
|
|
|
@ -1201,7 +1201,7 @@ void sample_overhang_area(
|
||||||
if (point_count <= min_support_points) {
|
if (point_count <= min_support_points) {
|
||||||
// add the outer wall (of the overhang) to ensure it is correct supported instead. Try placing the support points in a way that they fully support the outer wall, instead of just the with half of the the support line width.
|
// add the outer wall (of the overhang) to ensure it is correct supported instead. Try placing the support points in a way that they fully support the outer wall, instead of just the with half of the the support line width.
|
||||||
// I assume that even small overhangs are over one line width wide, so lets try to place the support points in a way that the full support area generated from them
|
// I assume that even small overhangs are over one line width wide, so lets try to place the support points in a way that the full support area generated from them
|
||||||
// will support the overhang (if this is not done it may only be half). This WILL NOT be the case when supporting an angle of about < 60<EFBFBD> so there is a fallback,
|
// will support the overhang (if this is not done it may only be half). This WILL NOT be the case when supporting an angle of about < 60 degrees so there is a fallback,
|
||||||
// as some support is better than none.
|
// as some support is better than none.
|
||||||
Polygons reduced_overhang_area = offset(union_ex(overhang_area), -interface_placer.config.support_line_width / 2.2, jtMiter, 1.2);
|
Polygons reduced_overhang_area = offset(union_ex(overhang_area), -interface_placer.config.support_line_width / 2.2, jtMiter, 1.2);
|
||||||
polylines = ensure_maximum_distance_polyline(
|
polylines = ensure_maximum_distance_polyline(
|
||||||
|
@ -1294,6 +1294,8 @@ static void generate_initial_areas(
|
||||||
coord_t max_overhang_insert_lag = 0;
|
coord_t max_overhang_insert_lag = 0;
|
||||||
if (config.z_distance_top_layers > 0) {
|
if (config.z_distance_top_layers > 0) {
|
||||||
max_overhang_insert_lag = 2 * config.z_distance_top_layers;
|
max_overhang_insert_lag = 2 * config.z_distance_top_layers;
|
||||||
|
|
||||||
|
//FIXME
|
||||||
if (mesh_group_settings.support_angle > EPSILON && mesh_group_settings.support_angle < 0.5 * M_PI - EPSILON) {
|
if (mesh_group_settings.support_angle > EPSILON && mesh_group_settings.support_angle < 0.5 * M_PI - EPSILON) {
|
||||||
//FIXME mesh_group_settings.support_angle does not apply to enforcers and also it does not apply to automatic support angle (by half the external perimeter width).
|
//FIXME mesh_group_settings.support_angle does not apply to enforcers and also it does not apply to automatic support angle (by half the external perimeter width).
|
||||||
//used by max_overhang_insert_lag, only if not min_xy_dist.
|
//used by max_overhang_insert_lag, only if not min_xy_dist.
|
||||||
|
@ -1442,6 +1444,7 @@ static void generate_initial_areas(
|
||||||
// or roof is enabled and these are the thin overhangs at object slopes (not horizontal overhangs).
|
// or roof is enabled and these are the thin overhangs at object slopes (not horizontal overhangs).
|
||||||
if (mesh_group_settings.minimum_support_area > 0)
|
if (mesh_group_settings.minimum_support_area > 0)
|
||||||
remove_small(overhang_regular, mesh_group_settings.minimum_support_area);
|
remove_small(overhang_regular, mesh_group_settings.minimum_support_area);
|
||||||
|
|
||||||
for (ExPolygon &support_part : union_ex(overhang_regular)) {
|
for (ExPolygon &support_part : union_ex(overhang_regular)) {
|
||||||
sample_overhang_area(to_polygons(std::move(support_part)),
|
sample_overhang_area(to_polygons(std::move(support_part)),
|
||||||
false, layer_idx, num_support_roof_layers, connect_length,
|
false, layer_idx, num_support_roof_layers, connect_length,
|
||||||
|
@ -2925,10 +2928,6 @@ static std::pair<float, float> extrude_branch(
|
||||||
assert(path.size() >= 2);
|
assert(path.size() >= 2);
|
||||||
static constexpr const float eps = 0.015f;
|
static constexpr const float eps = 0.015f;
|
||||||
std::pair<int, int> prev_strip;
|
std::pair<int, int> prev_strip;
|
||||||
|
|
||||||
// char fname[2048];
|
|
||||||
// static int irun = 0;
|
|
||||||
|
|
||||||
float zmin = 0;
|
float zmin = 0;
|
||||||
float zmax = 0;
|
float zmax = 0;
|
||||||
|
|
||||||
|
@ -3396,8 +3395,7 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
|
||||||
for (size_t i = 0; i < print_object.layer_count(); i++) {
|
for (size_t i = 0; i < print_object.layer_count(); i++) {
|
||||||
for (ExPolygon& expoly : print_object.get_layer(i)->loverhangs) {
|
for (ExPolygon& expoly : print_object.get_layer(i)->loverhangs) {
|
||||||
Polygons polys = to_polygons(expoly);
|
Polygons polys = to_polygons(expoly);
|
||||||
if (tree_support->overhang_types[&expoly] == TreeSupport::SharpTail) {
|
if (tree_support->overhang_types[&expoly] == TreeSupport::SharpTail) { polys = offset(polys, scale_(0.2));
|
||||||
polys = offset(to_polygons(expoly), scale_(0.2));
|
|
||||||
}
|
}
|
||||||
append(overhangs[i + num_raft_layers], polys);
|
append(overhangs[i + num_raft_layers], polys);
|
||||||
}
|
}
|
||||||
|
@ -3492,6 +3490,8 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
|
||||||
bottom_contacts, top_contacts, interface_placer, intermediate_layers, layer_storage,
|
bottom_contacts, top_contacts, interface_placer, intermediate_layers, layer_storage,
|
||||||
throw_on_cancel);
|
throw_on_cancel);
|
||||||
|
|
||||||
|
//tree_support->move_bounds_to_contact_nodes(move_bounds, print_object, config);
|
||||||
|
|
||||||
remove_undefined_layers();
|
remove_undefined_layers();
|
||||||
|
|
||||||
std::tie(interface_layers, base_interface_layers) = generate_interface_layers(print_object.config(), support_params,
|
std::tie(interface_layers, base_interface_layers) = generate_interface_layers(print_object.config(), support_params,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue