#697 fix Random seam position when only one perimeter.

fix random for thin wall loops (less than one perimeter)
This commit is contained in:
supermerill 2020-11-21 21:03:19 +01:00
parent 3799d533cc
commit c73e9cf1c9
4 changed files with 30 additions and 12 deletions

View File

@ -88,6 +88,8 @@ enum ExtrusionLoopRole : uint16_t {
elrHole = 1 << 3, // 8 elrHole = 1 << 3, // 8
//it's a modifier that indicate that the loop should be printed as vase //it's a modifier that indicate that the loop should be printed as vase
elrVase = 1 << 4, //16 elrVase = 1 << 4, //16
//it's a modifier that indicate that the loop does not contains an inner loop, used for random seam
elrFirstLoop = 1 << 5, //32
}; };

View File

@ -206,6 +206,8 @@ void SeamPlacer::init(const Print& print)
explgs = Slic3r::offset_ex(explgs, scale_(max_nozzle_dmr)); explgs = Slic3r::offset_ex(explgs, scale_(max_nozzle_dmr));
for (ExPolygons& explgs : m_blockers) for (ExPolygons& explgs : m_blockers)
explgs = Slic3r::offset_ex(explgs, scale_(max_nozzle_dmr)); explgs = Slic3r::offset_ex(explgs, scale_(max_nozzle_dmr));
this->external_perimeters_first = print.default_region_config().external_perimeters_first;
} }
@ -439,22 +441,30 @@ Point SeamPlacer::get_seam(const Layer *layer, SeamPosition seam_position,
return polygon.points[idx_min]; return polygon.points[idx_min];
} else { // spRandom } else { // spRandom
if ( (loop.loop_role() & elrInternal) != 0 && loop.role() != erExternalPerimeter) { if ( (loop.loop_role() & ExtrusionLoopRole::elrInternal) != 0 && loop.role() != erExternalPerimeter) {
// This loop does not contain any other loop. Set a random position. // This loop does not contain any other loop. Set a random position.
// The other loops will get a seam close to the random point chosen // The other loops will get a seam close to the random point chosen
// on the innermost contour. // on the innermost contour.
//FIXME This works correctly for inner contours first only.
last_pos = this->get_random_seam(layer_idx, polygon); last_pos = this->get_random_seam(layer_idx, polygon);
} } else if (loop.role() == erExternalPerimeter) {
if (loop.role() == erExternalPerimeter && is_custom_seam_on_layer(layer_idx)) { if (is_custom_seam_on_layer(layer_idx)) {
// There is a possibility that the loop will be influenced by custom // There is a possibility that the loop will be influenced by custom
// seam enforcer/blocker. In this case do not inherit the seam // seam enforcer/blocker. In this case do not inherit the seam
// from internal loops (which may conflict with the custom selection // from internal loops (which may conflict with the custom selection
// and generate another random one. // and generate another random one.
bool saw_custom = false; bool saw_custom = false;
Point candidate = this->get_random_seam(layer_idx, polygon, &saw_custom); Point candidate = this->get_random_seam(layer_idx, polygon, &saw_custom);
if (saw_custom) if (saw_custom)
last_pos = candidate; last_pos = candidate;
} else if (external_perimeters_first || (loop.loop_role() & ExtrusionLoopRole::elrFirstLoop) != 0) {
// this is if external_perimeters_first
// this is if only space for one externalperimeter.
//in these case, there isn't a seam from the inner loops, so we had to creat our on
last_pos = this->get_random_seam(layer_idx, polygon);
}
} else if (loop.role() == erThinWall) {
//thin wall loop is like an external perimeter, but without anything near it.
last_pos = this->get_random_seam(layer_idx, polygon);
} }
return last_pos; return last_pos;
} }

View File

@ -51,6 +51,9 @@ private:
//std::map<const PrintObject*, Point> m_last_seam_position; //std::map<const PrintObject*, Point> m_last_seam_position;
SeamHistory m_seam_history; SeamHistory m_seam_history;
// if it's expected, we need to randomized at the external periemter.
bool external_perimeters_first;
// Get indices of points inside enforcers and blockers. // Get indices of points inside enforcers and blockers.
void get_enforcers_and_blockers(size_t layer_id, void get_enforcers_and_blockers(size_t layer_id,

View File

@ -1103,6 +1103,9 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
if (!loop.is_contour) { if (!loop.is_contour) {
loop_role = (ExtrusionLoopRole)(loop_role | ExtrusionLoopRole::elrHole); loop_role = (ExtrusionLoopRole)(loop_role | ExtrusionLoopRole::elrHole);
} }
if (loop.children.empty()) {
loop_role = ExtrusionLoopRole(loop_role | ExtrusionLoopRole::elrFirstLoop);
}
if (this->config->external_perimeters_vase.value && this->config->external_perimeters_first.value && is_external) { if (this->config->external_perimeters_vase.value && this->config->external_perimeters_first.value && is_external) {
if ((loop.is_contour && this->config->external_perimeters_nothole.value) || (!loop.is_contour && this->config->external_perimeters_hole.value)) { if ((loop.is_contour && this->config->external_perimeters_nothole.value) || (!loop.is_contour && this->config->external_perimeters_hole.value)) {
loop_role = (ExtrusionLoopRole)(loop_role | ExtrusionLoopRole::elrVase); loop_role = (ExtrusionLoopRole)(loop_role | ExtrusionLoopRole::elrVase);