mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-10 08:17:51 -06:00
Port PrusaSlicer staggered_inner_seams
This commit is contained in:
parent
b47777e73e
commit
c3c6bbc4e5
7 changed files with 1469 additions and 1255 deletions
File diff suppressed because it is too large
Load diff
|
@ -27,17 +27,6 @@ class Grid;
|
|||
|
||||
namespace SeamPlacerImpl {
|
||||
|
||||
// ************ FOR BACKPORT COMPATIBILITY ONLY ***************
|
||||
// Angle from v1 to v2, returning double atan2(y, x) normalized to <-PI, PI>.
|
||||
template<typename Derived, typename Derived2> inline double angle(const Eigen::MatrixBase<Derived> &v1, const Eigen::MatrixBase<Derived2> &v2)
|
||||
{
|
||||
static_assert(Derived::IsVectorAtCompileTime && int(Derived::SizeAtCompileTime) == 2, "angle(): first parameter is not a 2D vector");
|
||||
static_assert(Derived2::IsVectorAtCompileTime && int(Derived2::SizeAtCompileTime) == 2, "angle(): second parameter is not a 2D vector");
|
||||
auto v1d = v1.template cast<double>();
|
||||
auto v2d = v2.template cast<double>();
|
||||
return atan2(cross2(v1d, v2d), v1d.dot(v2d));
|
||||
}
|
||||
// ***************************
|
||||
|
||||
struct GlobalModelInfo;
|
||||
struct SeamComparator;
|
||||
|
@ -49,8 +38,7 @@ enum class EnforcedBlockedSeamPoint {
|
|||
};
|
||||
|
||||
// struct representing single perimeter loop
|
||||
struct Perimeter
|
||||
{
|
||||
struct Perimeter {
|
||||
size_t start_index{};
|
||||
size_t end_index{}; //inclusive!
|
||||
size_t seam_index{};
|
||||
|
@ -66,11 +54,13 @@ struct Perimeter
|
|||
//Struct over which all processing of perimeters is done. For each perimeter point, its respective candidate is created,
|
||||
// then all the needed attributes are computed and finally, for each perimeter one point is chosen as seam.
|
||||
// This seam position can be then further aligned
|
||||
struct SeamCandidate
|
||||
{
|
||||
SeamCandidate(const Vec3f &pos, Perimeter &perimeter, float local_ccw_angle, EnforcedBlockedSeamPoint type)
|
||||
: position(pos), perimeter(perimeter), visibility(0.0f), overhang(0.0f), embedded_distance(0.0f), local_ccw_angle(local_ccw_angle), type(type), central_enforcer(false)
|
||||
{}
|
||||
struct SeamCandidate {
|
||||
SeamCandidate(const Vec3f &pos, Perimeter &perimeter,
|
||||
float local_ccw_angle,
|
||||
EnforcedBlockedSeamPoint type) :
|
||||
position(pos), perimeter(perimeter), visibility(0.0f), overhang(0.0f), embedded_distance(0.0f), local_ccw_angle(
|
||||
local_ccw_angle), type(type), central_enforcer(false) {
|
||||
}
|
||||
const Vec3f position;
|
||||
// pointer to Perimeter loop of this point. It is shared across all points of the loop
|
||||
Perimeter &perimeter;
|
||||
|
@ -84,11 +74,14 @@ struct SeamCandidate
|
|||
bool central_enforcer; //marks this candidate as central point of enforced segment on the perimeter - important for alignment
|
||||
};
|
||||
|
||||
struct SeamCandidateCoordinateFunctor
|
||||
{
|
||||
SeamCandidateCoordinateFunctor(const std::vector<SeamCandidate> &seam_candidates) : seam_candidates(seam_candidates) {}
|
||||
struct SeamCandidateCoordinateFunctor {
|
||||
SeamCandidateCoordinateFunctor(const std::vector<SeamCandidate> &seam_candidates) :
|
||||
seam_candidates(seam_candidates) {
|
||||
}
|
||||
const std::vector<SeamCandidate> &seam_candidates;
|
||||
float operator()(size_t index, size_t dim) const { return seam_candidates[index].position[dim]; }
|
||||
float operator()(size_t index, size_t dim) const {
|
||||
return seam_candidates[index].position[dim];
|
||||
}
|
||||
};
|
||||
} // namespace SeamPlacerImpl
|
||||
|
||||
|
@ -107,22 +100,24 @@ struct PrintObjectSeamData
|
|||
// Map of PrintObjects (PO) -> vector of layers of PO -> unique_ptr to KD
|
||||
// tree of all points of the given layer
|
||||
|
||||
void clear() { layers.clear(); }
|
||||
void clear()
|
||||
{
|
||||
layers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SeamPlacer
|
||||
{
|
||||
class SeamPlacer {
|
||||
public:
|
||||
// Number of samples generated on the mesh. There are sqr_rays_per_sample_point*sqr_rays_per_sample_point rays casted from each samples
|
||||
static constexpr size_t raycasting_visibility_samples_count = 30000;
|
||||
static constexpr size_t fast_decimation_triangle_count_target = 16000;
|
||||
//square of number of rays per sample point
|
||||
static constexpr size_t sqr_rays_per_sample_point = 5;
|
||||
|
||||
// snapping angle - angles larger than this value will be snapped to during seam painting
|
||||
static constexpr float sharp_angle_snapping_threshold = 55.0f * float(PI) / 180.0f;
|
||||
// overhang angle for seam placement that still yields good results, in degrees, measured from vertical direction
|
||||
//BBS
|
||||
static constexpr float overhang_angle_threshold = 45.0f * float(PI) / 180.0f;
|
||||
static constexpr float overhang_angle_threshold = 50.0f * float(PI) / 180.0f;
|
||||
|
||||
// determines angle importance compared to visibility ( neutral value is 1.0f. )
|
||||
static constexpr float angle_importance_aligned = 0.6f;
|
||||
|
@ -149,15 +144,18 @@ public:
|
|||
void place_seam(const Layer *layer, ExtrusionLoop &loop, bool external_first, const Point &last_pos) const;
|
||||
|
||||
private:
|
||||
void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info, const SeamPosition configured_seam_preference);
|
||||
void calculate_candidates_visibility(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info);
|
||||
void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info);
|
||||
void calculate_candidates_visibility(const PrintObject *po,
|
||||
const SeamPlacerImpl::GlobalModelInfo &global_model_info);
|
||||
void calculate_overhangs_and_layer_embedding(const PrintObject *po);
|
||||
void align_seam_points(const PrintObject *po, const SeamPlacerImpl::SeamComparator &comparator);
|
||||
std::vector<std::pair<size_t, size_t>> find_seam_string(const PrintObject *po, std::pair<size_t, size_t> start_seam, const SeamPlacerImpl::SeamComparator &comparator) const;
|
||||
std::optional<std::pair<size_t, size_t>> find_next_seam_in_layer(const std::vector<PrintObjectSeamData::LayerSeams> &layers,
|
||||
std::vector<std::pair<size_t, size_t>> find_seam_string(const PrintObject *po,
|
||||
std::pair<size_t, size_t> start_seam,
|
||||
const SeamPlacerImpl::SeamComparator &comparator) const;
|
||||
std::optional<std::pair<size_t, size_t>> find_next_seam_in_layer(
|
||||
const std::vector<PrintObjectSeamData::LayerSeams> &layers,
|
||||
const Vec3f& projected_position,
|
||||
const size_t layer_idx,
|
||||
const float max_distance,
|
||||
const size_t layer_idx, const float max_distance,
|
||||
const SeamPlacerImpl::SeamComparator &comparator) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -708,7 +708,7 @@ static std::vector<std::string> s_Preset_print_options {
|
|||
"layer_height", "initial_layer_print_height", "wall_loops", "slice_closing_radius", "spiral_mode", "slicing_mode",
|
||||
"top_shell_layers", "top_shell_thickness", "bottom_shell_layers", "bottom_shell_thickness",
|
||||
"ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall",
|
||||
"seam_position", "wall_infill_order", "sparse_infill_density", "sparse_infill_pattern", "top_surface_pattern", "bottom_surface_pattern",
|
||||
"seam_position", "staggered_inner_seams", "wall_infill_order", "sparse_infill_density", "sparse_infill_pattern", "top_surface_pattern", "bottom_surface_pattern",
|
||||
"infill_direction",
|
||||
"minimum_sparse_infill_area", "reduce_infill_retraction",
|
||||
"ironing_type", "ironing_flow", "ironing_speed", "ironing_spacing",
|
||||
|
|
|
@ -2614,6 +2614,12 @@ void PrintConfigDef::init_fff_params()
|
|||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnum<SeamPosition>(spAligned));
|
||||
|
||||
def = this->add("staggered_inner_seams", coBool);
|
||||
def->label = L("Staggered inner seams");
|
||||
def->tooltip = L("This option causes the inner seams to be shifted backwards based on their depth, forming a zigzag pattern.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("seam_gap", coFloatOrPercent);
|
||||
def->label = L("Seam gap");
|
||||
def->tooltip = L("In order to reduce the visibility of the seam in a closed loop extrusion, the loop is interrupted and shortened by a specified amount.\n"
|
||||
|
|
|
@ -646,6 +646,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||
((ConfigOptionFloat, raft_first_layer_expansion))
|
||||
((ConfigOptionInt, raft_layers))
|
||||
((ConfigOptionEnum<SeamPosition>, seam_position))
|
||||
((ConfigOptionBool, staggered_inner_seams))
|
||||
((ConfigOptionFloat, slice_closing_radius))
|
||||
((ConfigOptionEnum<SlicingMode>, slicing_mode))
|
||||
((ConfigOptionBool, enable_support))
|
||||
|
|
|
@ -540,7 +540,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
|
||||
bool have_perimeters = config->opt_int("wall_loops") > 0;
|
||||
for (auto el : { "ensure_vertical_shell_thickness", "detect_thin_wall", "detect_overhang_wall",
|
||||
"seam_position", "wall_infill_order", "outer_wall_line_width",
|
||||
"seam_position", "staggered_inner_seams", "wall_infill_order", "outer_wall_line_width",
|
||||
"inner_wall_speed", "outer_wall_speed", "small_perimeter_speed", "small_perimeter_threshold" })
|
||||
toggle_field(el, have_perimeters);
|
||||
|
||||
|
|
|
@ -1845,6 +1845,7 @@ void TabPrint::build()
|
|||
|
||||
optgroup = page->new_optgroup(L("Seam"), L"param_seam");
|
||||
optgroup->append_single_option_line("seam_position", "Seam");
|
||||
optgroup->append_single_option_line("staggered_inner_seams", "Seam");
|
||||
optgroup->append_single_option_line("seam_gap","Seam");
|
||||
optgroup->append_single_option_line("role_based_wipe_speed","Seam");
|
||||
optgroup->append_single_option_line("wipe_speed", "Seam");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue