From 91491aab48f6accc0645e4239dbfe5026620000f Mon Sep 17 00:00:00 2001 From: supermerill Date: Fri, 21 Aug 2020 22:52:15 +0200 Subject: [PATCH] custom seam update: - no more setting needed. If an object has a seam-object, it will use the custom seam. - use the nearest sphere in xyz. --- src/libslic3r/GCode.cpp | 35 +++++++++++++++++++++++++++-------- src/libslic3r/PrintConfig.cpp | 9 +++------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 85dfe5f91..ee56c22f1 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3162,19 +3162,39 @@ void GCode::split_at_seam_pos(ExtrusionLoop &loop, std::unique_ptrobject()->model_object()->volumes) + if (v->is_seam_position()) { + has_seam_custom = true; + break; + } + if (has_seam_custom) { // Seam is aligned to be nearest to the position of a "lambda-seam"-named modifier in this or any preceding layer last_pos = m_layer->object()->bounding_box().center(); // Look for all lambda-seam-modifiers below current z, choose the highest one ModelVolume *v_lambda_seam = nullptr; Vec3d lambda_pos; + double lambda_dist; + double lambda_radius; for (ModelVolume *v : m_layer->object()->model_object()->volumes) if (v->is_seam_position()) { - Vec3d test_lambda_pos = m_layer->object()->model_object()->instances.front()->transform_vector(v->get_offset()); + //xy in object coordinates, z in plater coordinates + Vec3d test_lambda_pos = m_layer->object()->model_object()->instances.front()->transform_vector(v->get_offset(), true); + Vec3d test_lambda_pos_plater = m_layer->object()->model_object()->instances.front()->transform_vector(v->get_offset(), false); + Point xy_lambda(scale_(test_lambda_pos.x()), scale_(test_lambda_pos.y())); + Point nearest = polygon.point_projection(xy_lambda); + Vec3d polygon_3dpoint{ unscaled(nearest.x()), unscaled(nearest.y()), (double)m_layer->print_z }; + double test_lambda_dist = (polygon_3dpoint - test_lambda_pos).norm(); + double sphere_radius = m_layer->object()->model_object()->instances.front()->transform_bounding_box(v->mesh().bounding_box(), true).size().x() / 2; + //if (test_lambda_dist > sphere_radius) + // continue; + //use this one if the first or nearer (in z) - if (v_lambda_seam == nullptr || std::abs(m_layer->print_z - test_lambda_pos.z()) < std::abs(m_layer->print_z - lambda_pos.z())) { + if (v_lambda_seam == nullptr || lambda_dist > test_lambda_dist) { v_lambda_seam = v; - lambda_pos = m_layer->object()->model_object()->instances.front()->transform_vector(v_lambda_seam->get_offset()); + lambda_pos = test_lambda_pos; + lambda_radius = sphere_radius; + lambda_dist = test_lambda_dist; } } @@ -3183,10 +3203,9 @@ void GCode::split_at_seam_pos(ExtrusionLoop &loop, std::unique_ptrobject()->model_object()->instances.front()->transform_bounding_box(v_lambda_seam->mesh().bounding_box(), true).size().x() / 2.0); - last_pos_weight = std::max(0.0, std::round(100 * (weight_temp - 0.5))); - if (last_pos_weight <= 0.0) - seam_position = spHidden; + last_pos_weight = std::max(0.0, std::round(100 * (lambda_radius))); + if (last_pos_weight > 0.0) + seam_position = spCustom; } } if (seam_position == spAligned) { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 8e46a0804..1911b9100 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2578,24 +2578,21 @@ void PrintConfigDef::init_fff_params() def->label = L("Seam position"); def->category = OptionCategory::perimeter; def->tooltip = L("Position of perimeters starting points." - "\n --- When using Custom ---" + "\n --- When using Custom seam ---" "\nYou have to create one or more seam sphere in the context menu of the object." - " Note that the custom setting is automatically added to the object when creating a seam object," - " so you shouldn't have to set it in the global config." - " The center of the seam sphere is used to position the seam. If you set multiple spheres, the nearest in z is chosen for a given layer."); + " When an object has a seam object, this setting is not taken into account nymore for the object." + " Refer to the wiki/help menu for more information."); def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("random"); def->enum_values.push_back("near"); def->enum_values.push_back("aligned"); def->enum_values.push_back("rear"); def->enum_values.push_back("hidden"); - def->enum_values.push_back("custom"); def->enum_labels.push_back(L("Random")); def->enum_labels.push_back(L("Nearest")); def->enum_labels.push_back(L("Aligned")); def->enum_labels.push_back(L("Rear")); def->enum_labels.push_back(L("Corners")); - def->enum_labels.push_back(L("Custom")); def->mode = comSimple; def->set_default_value(new ConfigOptionEnum(spHidden));