Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2022-08-29 02:03:26 +0300
committersupermerill <merill@free.fr>2022-09-16 17:11:25 +0300
commit695e959cb67babc0f093b7372a806a42aad787ee (patch)
treef3a1de0e88fcdd21977ee890e0b76e356050ba04
parentcfc7c8d2f1fd940d37dfdb22180e96de30af98aa (diff)
contiguous: allow paint & Seam sphere for the base position.
supermerill/SuperSlicer#3058
-rw-r--r--src/libslic3r/GCode/SeamPlacer.cpp139
-rw-r--r--src/slic3r/GUI/GUI_ObjectList.cpp3
2 files changed, 89 insertions, 53 deletions
diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp
index fa8146900..8847bc40f 100644
--- a/src/libslic3r/GCode/SeamPlacer.cpp
+++ b/src/libslic3r/GCode/SeamPlacer.cpp
@@ -509,7 +509,9 @@ Point SeamPlacer::calculate_seam(const Layer& layer, SeamPosition seam_position,
Polygon polygon = loop.polygon();
bool was_clockwise = polygon.make_counter_clockwise();
const coord_t nozzle_r = coord_t(scale_(0.5 * nozzle_dmr) + 0.5);
- float last_pos_weight = 1.f;
+ Point seam_mod_pos;
+ float last_pos_weight = 2.f;
+ float seam_mod_weight = 0.f;
float angle_weight = 1.f;
if (seam_position == spCustom)
seam_position = spCost;
@@ -538,27 +540,28 @@ Point SeamPlacer::calculate_seam(const Layer& layer, SeamPosition seam_position,
assert(layer_idx < po->layer_count());
const bool custom_seam = loop.role() == erExternalPerimeter && this->is_custom_seam_on_layer(layer_idx, po_idx);
+ bool has_custom_seam_modifier = false;
+ if (print_object_instance_idx < po->instances().size())
+ for (ModelVolume* v : po->model_object()->volumes)
+ if (v->is_seam_position()) {
+ has_custom_seam_modifier = true;
+ break;
+ }
- if (custom_seam) {
+ if (custom_seam || has_custom_seam_modifier) {
// Seam enf/blockers can begin and end in between the original vertices.
// Let add extra points in between and update the leghths.
polygon.densify(MINIMAL_POLYGON_SIDE);
}
- bool has_seam_custom = false;
- if(print_object_instance_idx < po->instances().size())
- for (ModelVolume* v : po->model_object()->volumes)
- if (v->is_seam_position()) {
- has_seam_custom = true;
- break;
- }
- if (has_seam_custom) {
+ if (has_custom_seam_modifier) {
// Look for all lambda-seam-modifiers below current z, choose the highest one
ModelVolume* v_lambda_seam = nullptr;
Vec3d lambda_pos;
double lambda_z = 0;
double lambda_dist = 0;
double lambda_radius = 0;
+ double max_lambda_radius = 0;
//get model_instance (like from po->model_object()->instances, but we don't have the index for that array)
const ModelInstance* model_instance = po->instances()[print_object_instance_idx].model_instance;
for (ModelVolume* v : po->model_object()->volumes) {
@@ -576,7 +579,7 @@ Point SeamPlacer::calculate_seam(const Layer& layer, SeamPosition seam_position,
Vec3d polygon_3dpoint{ unscaled(nearest.x()), unscaled(nearest.y()), (double)layer.print_z };
double test_lambda_dist = (polygon_3dpoint - test_lambda_pos).norm();
double sphere_radius = po->model_object()->instance_bounding_box(0, true).size().x() / 2;
-
+ max_lambda_radius = std::max(max_lambda_radius, sphere_radius);
//use this one if the first or nearer (in z, or in xy if same z)
if (v_lambda_seam == nullptr
@@ -593,11 +596,24 @@ Point SeamPlacer::calculate_seam(const Layer& layer, SeamPosition seam_position,
if (v_lambda_seam != nullptr) {
// 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());
+ seam_mod_pos = Point::new_scale(lambda_pos.x(), lambda_pos.y());
// Weight is set by user and stored in the radius of the sphere
- last_pos_weight = std::max(0.0, std::round(100 * (lambda_radius)));
- if (last_pos_weight > 0.0)
- seam_position = spCustom;
+ seam_mod_weight = 1.f + 100 * (lambda_radius/max_lambda_radius);
+ if (seam_mod_weight > 0.0) {
+ seam_mod_weight += 1.;
+ if (seam_position == spAligned) {
+ last_pos_weight = 0;
+ angle_weight = 0;
+ } else if(seam_position == spExtremlyAligned) {
+ last_pos_weight = 1.f;
+ angle_weight = 0;
+ } else {
+ seam_position = spCustom;
+ last_pos_weight = 0;
+ }
+ }
+ } else {
+ has_custom_seam_modifier = false;
}
}
@@ -607,13 +623,29 @@ Point SeamPlacer::calculate_seam(const Layer& layer, SeamPosition seam_position,
double travel_cost = 1;
if (seam_position == spAligned || seam_position == spExtremlyAligned) {
// Seam is aligned to the seam at the preceding layer.
+ bool has_last_layer_pos = false;
if (po != nullptr) {
std::optional<Point> pos = m_seam_history.get_last_seam(m_po_list[po_idx], layer_po->print_z, loop.polygon().bounding_box());
if (pos.has_value()) {
last_pos = *pos;
+ has_last_layer_pos = true;
+ }
+ // deactivate if activated and spAligned and is_custom_enforcer_on_layer
+ if (last_pos_weight > 0 && seam_position == spAligned && is_custom_enforcer_on_layer(layer_idx, po_idx)) {
+ last_pos_weight = 0.f;
+ }
+ }
+ // even with spExtremlyAligned, still use the custom enforcer at the start
+ if (seam_position == spExtremlyAligned) {
+ if (custom_seam) {
+ seam_position = spAligned;
+ } else if (has_custom_seam_modifier && !has_last_layer_pos) {
+ seam_position = spAligned;
}
- // TODO: check why i put it out of the if
- last_pos_weight = is_custom_enforcer_on_layer(layer_idx, po_idx) ? 0.f : 1.f;
+ }
+ if (has_custom_seam_modifier && !has_last_layer_pos) {
+ //if seam modifier and no previous data, don't use last pos
+ last_pos_weight = 0;
}
} else if (seam_position == spRear) {
// Object is centered around (0,0) in its current coordinate system.
@@ -639,12 +671,18 @@ Point SeamPlacer::calculate_seam(const Layer& layer, SeamPosition seam_position,
// Insert a projection of last_pos into the polygon.
- size_t last_pos_proj_idx;
- {
+ size_t last_pos_proj_idx = 0;
+ if(last_pos_weight > 0){
Points::const_iterator it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r);
last_pos_proj_idx = it - polygon.points.begin();
}
Point last_pos_proj = polygon.points[last_pos_proj_idx];
+ size_t seam_mod_pos_proj_idx = 0;
+ if (seam_mod_weight > 0) {
+ Points::const_iterator it = project_point_to_polygon_and_insert(polygon, seam_mod_pos, 0.1 * nozzle_r);
+ seam_mod_pos_proj_idx = it - polygon.points.begin();
+ }
+ Point seam_mod_pos_proj = polygon.points[seam_mod_pos_proj_idx];
if (seam_position != spExtremlyAligned) {
@@ -675,40 +713,41 @@ Point SeamPlacer::calculate_seam(const Layer& layer, SeamPosition seam_position,
if (was_clockwise)
ccwAngle = -ccwAngle;
float penalty = 0;
- //if (ccwAngle < -float(0.6 * PI))
- // penalty = 0.f;
- //else if (ccwAngle > float(0.6 * PI))
- //
- // penalty = penaltyConvexVertex;
//else
- if (ccwAngle < 0.f) {
- // We love Sharp reflex vertex (high negative ccwAngle). It hides the seam perfectly.
- // Interpolate penalty between maximum and zero.
- penalty = penaltyFlatSurface * bspline_kernel(ccwAngle);
- } else if (ccwAngle > float(0.67 * PI)) {
- //penalize too sharp convex angle, it's best to be nearer to ~100°
- penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel((PI - ccwAngle) * 1.5);
- } else {
- // Interpolate penalty between maximum and the penalty for a convex vertex.
- penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle);
+ if (angle_weight > 0) {
+ if (ccwAngle < 0.f) {
+ // We love Sharp reflex vertex (high negative ccwAngle). It hides the seam perfectly.
+ // Interpolate penalty between maximum and zero.
+ penalty = penaltyFlatSurface * bspline_kernel(ccwAngle);
+ } else if (ccwAngle > float(0.67 * PI)) {
+ //penalize too sharp convex angle, it's best to be nearer to ~100°
+ penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel((PI - ccwAngle) * 1.5);
+ } else {
+ // Interpolate penalty between maximum and the penalty for a convex vertex.
+ penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle);
+ }
+ penalty *= angle_weight;
}
- penalty *= angle_weight;
- if (po != nullptr && travel_cost >= 1) {
- //TODO maybe delete this code path, it's not used in prusa and may not be optimal. At least, document why it's here.
- penalty += last_pos_weight * polygon.points[i].distance_to(last_pos_proj) / dist_max;
- penalties[i] = std::max(0.f, penalty);
- } else {
- // Give a negative penalty for points close to the last point or the prefered seam location.
- float dist_to_last_pos_proj = (i < last_pos_proj_idx) ?
- std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) :
- std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
- penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max);
- penalties[i] = std::max(0.f, penalty);
- if (prefer_nearest) {
- // This hack limits the search around the nearest position projection.
- penalties[i] += dist_to_last_pos_proj > 6.f * nozzle_r ? 100.f : 0.f;
+ if (last_pos_weight > 0) {
+ if (po != nullptr && travel_cost >= 1) {
+ //TODO maybe delete this code path, it's not used in prusa and may not be optimal. At least, document why it's here.
+ penalty += last_pos_weight * polygon.points[i].distance_to(last_pos_proj) / dist_max;
+ } else {
+ // Give a negative penalty for points close to the last point or the prefered seam location.
+ float dist_to_last_pos_proj = (i < last_pos_proj_idx) ?
+ std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) :
+ std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]);
+ penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max);
+ if (prefer_nearest) {
+ // This hack limits the search around the nearest position projection.
+ penalty += dist_to_last_pos_proj > 6.f * nozzle_r ? 100.f : 0.f;
+ }
}
}
+ if (seam_mod_weight > 0) {
+ penalty += seam_mod_weight * polygon.points[i].distance_to(seam_mod_pos_proj) / dist_max;
+ }
+ penalties[i] = std::max(0.f, penalty);
}
// Penalty for overhangs.
@@ -1114,7 +1153,7 @@ std::optional<Point> SeamHistory::get_last_seam(const PrintObject* po, double la
return out;
// Get seam was called for different layer than last time.
- std::map<const PrintObject*, std::vector<SeamPoint>>* data_last_layer = nullptr;
+ std::map<const PrintObject*, std::vector<SeamPoint>>* data_last_layer = layer_z > m_data.begin()->first * 1.01 ? &m_data.begin()->second : nullptr;
for (auto it = m_data.begin() + 1; it != m_data.end(); ++it) {
if (it->first == layer_z) {
data_last_layer = &std::prev(it)->second;
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 41e931434..7b98ef99e 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -1651,9 +1651,6 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
// Bounding box of the selected instance in world coordinate system including the translation, without modifiers.
BoundingBoxf3 instance_bb = model_object.instance_bounding_box(instance_idx);
- if(type == ModelVolumeType::SEAM_POSITION)
- model_object.config.set_key_value("seam_position", new ConfigOptionEnum<SeamPosition>(spCustom));
-
TriangleMesh mesh = create_mesh(type_name, instance_bb);
// Mesh will be centered when loading.