mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-14 21:22:03 +08:00
#697 fix Random seam position when only one perimeter.
fix random for thin wall loops (less than one perimeter)
This commit is contained in:
parent
3799d533cc
commit
c73e9cf1c9
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,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,
|
||||||
const Polygon& polygon,
|
const Polygon& polygon,
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user