mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-07 23:17:35 -06:00
ENH: accurate top z distance for tree support
1. accurate top z distance for tree support Also fix a bug that bottom z and top z distances are misused. jira: STUDIO-3000, STUDIO-5990 github: #1827 2. Change interface pattern to interlaced rectilinear when using support material. 2. clean up tree support code Change-Id: Icc8ce1b6844c841a6fbd1d623df707fdc8ed0f7b (cherry picked from commit da7412a48dfb5767918ef125b9d0fb9718c03a61) (cherry picked from commit 39ae64fc53abec794d740e36baaa13fd6fb35849)
This commit is contained in:
parent
de24d0ac2f
commit
d0868d6711
8 changed files with 365 additions and 372 deletions
|
@ -7315,11 +7315,11 @@ msgstr ""
|
|||
msgid ""
|
||||
"When using support material for the support interface, We recommend the "
|
||||
"following settings:\n"
|
||||
"0 top z distance, 0 interface spacing, concentric pattern and disable "
|
||||
"0 top z distance, 0 interface spacing, interlaced rectilinear pattern and disable "
|
||||
"independent support layer height"
|
||||
msgstr ""
|
||||
"当使用支持界面的支持材料时,我们推荐以下设置:\n"
|
||||
"0顶层z距离,0接触层间距,同心图案,并且禁用独立支撑层高"
|
||||
"0顶层z距离,0接触层间距,交叠直线图案,并且禁用独立支撑层高"
|
||||
|
||||
msgid ""
|
||||
"Enabling this option will modify the model's shape. If your print requires "
|
||||
|
|
|
@ -666,6 +666,10 @@ Slic3r::Polygons diff_clipped(const Slic3r::Polygons &subject, const Slic3r::Pol
|
|||
{ 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::ExPolygons diff_clipped(const Slic3r::ExPolygons & subject, const Slic3r::ExPolygons & 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)
|
||||
{ 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)
|
||||
|
|
|
@ -434,6 +434,7 @@ Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::ExPolygon
|
|||
// 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::ExPolygons diff_clipped(const Slic3r::ExPolygons &src, const Slic3r::Polygons &clipping, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
|
||||
Slic3r::ExPolygons diff_clipped(const Slic3r::ExPolygons &src, const Slic3r::ExPolygons &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::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);
|
||||
|
|
|
@ -317,7 +317,7 @@ protected:
|
|||
bool need_extra_wall = false;
|
||||
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, SharpTail };
|
||||
std::vector<AreaGroup> area_groups;
|
||||
std::map<const ExPolygon *, OverhangType> overhang_types;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -31,14 +31,8 @@ struct LayerHeightData
|
|||
size_t next_layer_nr = 0;
|
||||
LayerHeightData() = default;
|
||||
LayerHeightData(coordf_t z, coordf_t h, size_t next_layer) : print_z(z), height(h), next_layer_nr(next_layer) {}
|
||||
};
|
||||
|
||||
struct TreeNode {
|
||||
Vec3f pos;
|
||||
std::vector<int> children; // index of children in the storing vector
|
||||
std::vector<int> parents; // index of parents in the storing vector
|
||||
TreeNode(Point pt, float z) {
|
||||
pos = { float(unscale_(pt.x())),float(unscale_(pt.y())),z };
|
||||
coordf_t bottom_z() {
|
||||
return print_z - height;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -57,40 +51,45 @@ struct SupportNode
|
|||
static constexpr SupportNode* NO_PARENT = nullptr;
|
||||
|
||||
SupportNode()
|
||||
: distance_to_top(0)
|
||||
, position(Point(0, 0))
|
||||
, obj_layer_nr(0)
|
||||
, support_roof_layers_below(0)
|
||||
, to_buildplate(true)
|
||||
, parent(nullptr)
|
||||
, print_z(0.0)
|
||||
, height(0.0)
|
||||
: distance_to_top(0)
|
||||
, position(Point(0, 0))
|
||||
, obj_layer_nr(0)
|
||||
, support_roof_layers_below(0)
|
||||
, to_buildplate(true)
|
||||
, parent(nullptr)
|
||||
, print_z(0.0)
|
||||
, height(0.0)
|
||||
{}
|
||||
|
||||
// when dist_mm_to_top_==0, new node's dist_mm_to_top=parent->dist_mm_to_top + parent->height;
|
||||
SupportNode(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)
|
||||
: distance_to_top(distance_to_top)
|
||||
, position(position)
|
||||
, obj_layer_nr(obj_layer_nr)
|
||||
, support_roof_layers_below(support_roof_layers_below)
|
||||
, to_buildplate(to_buildplate)
|
||||
, parent(parent)
|
||||
, print_z(print_z_)
|
||||
, height(height_)
|
||||
, dist_mm_to_top(dist_mm_to_top_)
|
||||
coordf_t print_z_, coordf_t height_, coordf_t dist_mm_to_top_ = 0, coordf_t radius_ = 0)
|
||||
: distance_to_top(distance_to_top)
|
||||
, position(position)
|
||||
, obj_layer_nr(obj_layer_nr)
|
||||
, support_roof_layers_below(support_roof_layers_below)
|
||||
, to_buildplate(to_buildplate)
|
||||
, parent(parent)
|
||||
, print_z(print_z_)
|
||||
, height(height_)
|
||||
, dist_mm_to_top(dist_mm_to_top_)
|
||||
, radius(radius_)
|
||||
{
|
||||
if (parent) {
|
||||
parents.push_back(parent);
|
||||
type = parent->type;
|
||||
type = parent->type;
|
||||
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;
|
||||
if (radius == 0)
|
||||
radius = parent->radius + (dist_mm_to_top - parent->dist_mm_to_top) * diameter_angle_scale_factor;
|
||||
parent->child = this;
|
||||
for (auto& neighbor : parent->merged_neighbours) {
|
||||
neighbor->child = this;
|
||||
parents.push_back(neighbor);
|
||||
}
|
||||
is_sharp_tail = parent->is_sharp_tail;
|
||||
skin_direction = parent->skin_direction;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,18 +108,23 @@ struct SupportNode
|
|||
int distance_to_top;
|
||||
coordf_t dist_mm_to_top = 0; // dist to bottom contact in mm
|
||||
|
||||
// all nodes will have same diameter_angle_scale_factor because it's defined by user
|
||||
static double diameter_angle_scale_factor;
|
||||
|
||||
/*!
|
||||
* \brief The position of this node on the layer.
|
||||
*/
|
||||
Point position;
|
||||
Point movement; // movement towards neighbor center or outline
|
||||
mutable double radius = 0.0;
|
||||
mutable double max_move_dist = 0.0;
|
||||
TreeNodeType type = eCircle;
|
||||
bool is_corner = false;
|
||||
bool is_processed = false;
|
||||
bool need_extra_wall = false;
|
||||
ExPolygon overhang; // when type==ePolygon, set this value to get original overhang area
|
||||
Point position;
|
||||
Point movement; // movement towards neighbor center or outline
|
||||
mutable double radius = 0.0;
|
||||
mutable double max_move_dist = 0.0;
|
||||
TreeNodeType type = eCircle;
|
||||
bool is_corner = false;
|
||||
bool is_processed = false;
|
||||
bool need_extra_wall = false;
|
||||
bool is_sharp_tail = false;
|
||||
bool valid = true;
|
||||
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.
|
||||
|
@ -128,7 +132,7 @@ struct SupportNode
|
|||
* This determines in which direction we should reduce the width of the
|
||||
* branch.
|
||||
*/
|
||||
bool skin_direction;
|
||||
Point skin_direction;
|
||||
|
||||
/*!
|
||||
* \brief The number of support roof layers below this one.
|
||||
|
@ -199,6 +203,9 @@ public:
|
|||
* \param collision_resolution
|
||||
*/
|
||||
TreeSupportData(const PrintObject& object, coordf_t max_move, coordf_t radius_sample_resolution, coordf_t collision_resolution);
|
||||
~TreeSupportData() {
|
||||
clear_nodes();
|
||||
}
|
||||
|
||||
TreeSupportData(TreeSupportData&&) = default;
|
||||
TreeSupportData& operator=(TreeSupportData&&) = default;
|
||||
|
@ -237,9 +244,13 @@ public:
|
|||
Polygons get_contours(size_t layer_nr) const;
|
||||
Polygons get_contours_with_holes(size_t layer_nr) const;
|
||||
|
||||
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);
|
||||
void clear_nodes();
|
||||
void remove_invalid_nodes();
|
||||
std::vector<LayerHeightData> layer_heights;
|
||||
|
||||
std::vector<TreeNode> tree_nodes;
|
||||
std::vector<SupportNode*> contact_nodes;
|
||||
|
||||
private:
|
||||
/*!
|
||||
|
@ -285,6 +296,7 @@ private:
|
|||
*/
|
||||
const ExPolygons& calculate_avoidance(const RadiusLayerPair& key) const;
|
||||
|
||||
tbb::spin_mutex m_mutex;
|
||||
|
||||
public:
|
||||
bool is_slim = false;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <ctime>
|
||||
#include <cstdarg>
|
||||
#include <stdio.h>
|
||||
#include <filesystem>
|
||||
|
||||
#include "format.hpp"
|
||||
#include "Platform.hpp"
|
||||
|
@ -298,12 +299,13 @@ static std::atomic<bool> debug_out_path_called(false);
|
|||
|
||||
std::string debug_out_path(const char *name, ...)
|
||||
{
|
||||
static constexpr const char *SLIC3R_DEBUG_OUT_PATH_PREFIX = "out/";
|
||||
//static constexpr const char *SLIC3R_DEBUG_OUT_PATH_PREFIX = "out/";
|
||||
auto svg_folder = boost::filesystem::path(g_data_dir) / "SVG/";
|
||||
if (! debug_out_path_called.exchange(true)) {
|
||||
std::string path = boost::filesystem::system_complete(SLIC3R_DEBUG_OUT_PATH_PREFIX).string();
|
||||
if (!boost::filesystem::exists(path)) {
|
||||
boost::filesystem::create_directory(path);
|
||||
if (!boost::filesystem::exists(svg_folder)) {
|
||||
boost::filesystem::create_directory(svg_folder);
|
||||
}
|
||||
std::string path = boost::filesystem::system_complete(svg_folder).string();
|
||||
printf("Debugging output files will be written to %s\n", path.c_str());
|
||||
}
|
||||
char buffer[2048];
|
||||
|
@ -311,7 +313,13 @@ std::string debug_out_path(const char *name, ...)
|
|||
va_start(args, name);
|
||||
std::vsprintf(buffer, name, args);
|
||||
va_end(args);
|
||||
return std::string(SLIC3R_DEBUG_OUT_PATH_PREFIX) + std::string(buffer);
|
||||
|
||||
std::string buf(buffer);
|
||||
if (size_t pos = buf.find_first_of('/'); pos != std::string::npos) {
|
||||
std::string sub_dir = buf.substr(0, pos);
|
||||
std::filesystem::create_directory(svg_folder.string() + sub_dir);
|
||||
}
|
||||
return svg_folder.string() + std::string(buffer);
|
||||
}
|
||||
|
||||
namespace logging = boost::log;
|
||||
|
|
|
@ -1537,9 +1537,9 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
|||
if (opt_key == "support_interface_filament") {
|
||||
int interface_filament_id = m_config->opt_int("support_interface_filament") - 1; // the displayed id is based from 1, while internal id is based from 0
|
||||
if (is_support_filament(interface_filament_id) && !(m_config->opt_float("support_top_z_distance") == 0 && m_config->opt_float("support_interface_spacing") == 0 &&
|
||||
m_config->opt_enum<SupportMaterialInterfacePattern>("support_interface_pattern") == SupportMaterialInterfacePattern::smipConcentric)) {
|
||||
m_config->opt_enum<SupportMaterialInterfacePattern>("support_interface_pattern") == SupportMaterialInterfacePattern::smipRectilinearInterlaced)) {
|
||||
wxString msg_text = _L("When using support material for the support interface, We recommend the following settings:\n"
|
||||
"0 top z distance, 0 interface spacing, concentric pattern and disable independent support layer height");
|
||||
"0 top z distance, 0 interface spacing, interlaced rectilinear pattern and disable independent support layer height");
|
||||
msg_text += "\n\n" + _L("Change these settings automatically? \n"
|
||||
"Yes - Change these settings automatically\n"
|
||||
"No - Do not change these settings for me");
|
||||
|
@ -1548,7 +1548,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
|||
if (dialog.ShowModal() == wxID_YES) {
|
||||
new_conf.set_key_value("support_top_z_distance", new ConfigOptionFloat(0));
|
||||
new_conf.set_key_value("support_interface_spacing", new ConfigOptionFloat(0));
|
||||
new_conf.set_key_value("support_interface_pattern", new ConfigOptionEnum<SupportMaterialInterfacePattern>(SupportMaterialInterfacePattern::smipConcentric));
|
||||
new_conf.set_key_value("support_interface_pattern", new ConfigOptionEnum<SupportMaterialInterfacePattern>(SupportMaterialInterfacePattern::smipRectilinearInterlaced));
|
||||
new_conf.set_key_value("independent_support_layer_height", new ConfigOptionBool(false));
|
||||
m_config_manipulation.apply(m_config, &new_conf);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue