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.
This commit is contained in:
supermerill 2020-08-21 22:52:15 +02:00
parent 016b1dc2e0
commit 91491aab48
2 changed files with 30 additions and 14 deletions

View File

@ -3162,19 +3162,39 @@ void GCode::split_at_seam_pos(ExtrusionLoop &loop, std::unique_ptr<EdgeGrid::Gri
// Retrieve the last start position for this object. // Retrieve the last start position for this object.
float last_pos_weight = 1.f; float last_pos_weight = 1.f;
if (seam_position == spCustom) { bool has_seam_custom = false;
for (ModelVolume *v : m_layer->object()->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 // 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(); last_pos = m_layer->object()->bounding_box().center();
// Look for all lambda-seam-modifiers below current z, choose the highest one // Look for all lambda-seam-modifiers below current z, choose the highest one
ModelVolume *v_lambda_seam = nullptr; ModelVolume *v_lambda_seam = nullptr;
Vec3d lambda_pos; Vec3d lambda_pos;
double lambda_dist;
double lambda_radius;
for (ModelVolume *v : m_layer->object()->model_object()->volumes) for (ModelVolume *v : m_layer->object()->model_object()->volumes)
if (v->is_seam_position()) { 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) //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; 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_ptr<EdgeGrid::Gri
// Found, get the center point and apply rotation and scaling of Model instance. Continues to spAligned if not found or Weight set to Zero. // Found, get the center point and apply rotation and scaling of Model instance. Continues to spAligned if not found or Weight set to Zero.
last_pos = Point::new_scale(lambda_pos.x(), lambda_pos.y()); last_pos = Point::new_scale(lambda_pos.x(), lambda_pos.y());
// Weight is set by user and stored in the radius of the sphere // Weight is set by user and stored in the radius of the sphere
double weight_temp = (m_layer->object()->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 * (lambda_radius)));
last_pos_weight = std::max(0.0, std::round(100 * (weight_temp - 0.5))); if (last_pos_weight > 0.0)
if (last_pos_weight <= 0.0) seam_position = spCustom;
seam_position = spHidden;
} }
} }
if (seam_position == spAligned) { if (seam_position == spAligned) {

View File

@ -2578,24 +2578,21 @@ void PrintConfigDef::init_fff_params()
def->label = L("Seam position"); def->label = L("Seam position");
def->category = OptionCategory::perimeter; def->category = OptionCategory::perimeter;
def->tooltip = L("Position of perimeters starting points." 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." "\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," " When an object has a seam object, this setting is not taken into account nymore for the object."
" so you shouldn't have to set it in the global config." " Refer to the wiki/help menu for more information.");
" 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.");
def->enum_keys_map = &ConfigOptionEnum<SeamPosition>::get_enum_values(); def->enum_keys_map = &ConfigOptionEnum<SeamPosition>::get_enum_values();
def->enum_values.push_back("random"); def->enum_values.push_back("random");
def->enum_values.push_back("near"); def->enum_values.push_back("near");
def->enum_values.push_back("aligned"); def->enum_values.push_back("aligned");
def->enum_values.push_back("rear"); def->enum_values.push_back("rear");
def->enum_values.push_back("hidden"); 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("Random"));
def->enum_labels.push_back(L("Nearest")); def->enum_labels.push_back(L("Nearest"));
def->enum_labels.push_back(L("Aligned")); def->enum_labels.push_back(L("Aligned"));
def->enum_labels.push_back(L("Rear")); def->enum_labels.push_back(L("Rear"));
def->enum_labels.push_back(L("Corners")); def->enum_labels.push_back(L("Corners"));
def->enum_labels.push_back(L("Custom"));
def->mode = comSimple; def->mode = comSimple;
def->set_default_value(new ConfigOptionEnum<SeamPosition>(spHidden)); def->set_default_value(new ConfigOptionEnum<SeamPosition>(spHidden));