Bugfix: an error in porting caused bad perimeter ordering. Includes regression test and more unit tests for PerimeterGenerator

This commit is contained in:
Alessandro Ranellucci 2015-12-01 20:40:00 +01:00
parent fbc67d9078
commit 48f1fab49f
2 changed files with 64 additions and 21 deletions

View file

@ -185,7 +185,7 @@ PerimeterGenerator::process()
}
}
}
// if no hole contains this hole, find the contour loop that contains it
for (signed short t = loop_number; t >= 0; --t) {
for (signed short j = 0; j < contours[t].size(); ++j) {
@ -237,7 +237,7 @@ PerimeterGenerator::process()
if (this->config->external_perimeters_first
|| (this->layer_id == 0 && this->print_config->brim_width.value > 0))
entities.reverse();
// append perimeters for this slice as a collection
if (!entities.empty())
this->loops->append(entities);
@ -400,34 +400,35 @@ PerimeterGenerator::_traverse_loops(const PerimeterGeneratorLoops &loops,
}
// append thin walls to the nearest-neighbor search (only for first iteration)
if (!thin_walls.empty()) {
for (Polylines::const_iterator polyline = thin_walls.begin(); polyline != thin_walls.end(); ++polyline) {
ExtrusionPath path(erExternalPerimeter);
path.polyline = *polyline;
path.mm3_per_mm = this->_mm3_per_mm;
path.width = this->perimeter_flow.width;
path.height = this->layer_height;
coll.append(path);
}
thin_walls.clear();
for (Polylines::const_iterator polyline = thin_walls.begin(); polyline != thin_walls.end(); ++polyline) {
ExtrusionPath path(erExternalPerimeter);
path.polyline = *polyline;
path.mm3_per_mm = this->_mm3_per_mm;
path.width = this->perimeter_flow.width;
path.height = this->layer_height;
coll.append(path);
}
thin_walls.clear();
// sort entities
// sort entities into a new collection using a nearest-neighbor search,
// preserving the original indices which are useful for detecting thin walls
ExtrusionEntityCollection sorted_coll;
coll.chained_path(&sorted_coll, false, &sorted_coll.orig_indices);
// traverse children
// traverse children and build the final collection
ExtrusionEntityCollection entities;
for (unsigned short i = 0; i < sorted_coll.orig_indices.size(); ++i) {
size_t idx = sorted_coll.orig_indices[i];
if (idx >= loops.size()) {
for (std::vector<size_t>::const_iterator idx = sorted_coll.orig_indices.begin();
idx != sorted_coll.orig_indices.end();
++idx) {
if (*idx >= loops.size()) {
// this is a thin wall
// let's get it from the sorted collection as it might have been reversed
size_t i = idx - sorted_coll.orig_indices.begin();
entities.append(*sorted_coll.entities[i]);
} else {
const PerimeterGeneratorLoop &loop = loops[i];
ExtrusionLoop eloop = *dynamic_cast<ExtrusionLoop*>(coll.entities[idx]);
const PerimeterGeneratorLoop &loop = loops[*idx];
ExtrusionLoop eloop = *dynamic_cast<ExtrusionLoop*>(coll.entities[*idx]);
ExtrusionEntityCollection children = this->_traverse_loops(loop.children, thin_walls);
if (loop.is_contour) {