Refactor loop building code to make_loops()

This commit is contained in:
Alessandro Ranellucci 2014-01-16 11:38:17 +01:00
parent 86f91bb3c4
commit a831f5b176
2 changed files with 71 additions and 54 deletions

View File

@ -411,6 +411,22 @@ TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<Polygons>* la
} }
} }
void
TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<ExPolygons>* layers)
{
std::vector<Polygons> layers_p;
this->slice(z, &layers_p);
layers->resize(z.size());
for (std::vector<Polygons>::const_iterator loops = layers_p.begin(); loops != layers_p.end(); ++loops) {
#ifdef SLIC3R_DEBUG
printf("Layer %zu (slice_z = %.2f): ", layer_id, z[layer_id]);
#endif
this->make_expolygons(*loops, &(*layers)[ loops - layers_p.begin() ]);
}
}
void void
TriangleMeshSlicer::slice_facet(float slice_z, const stl_facet &facet, const int &facet_idx, const float &min_z, const float &max_z, std::vector<IntersectionLine>* lines) const TriangleMeshSlicer::slice_facet(float slice_z, const stl_facet &facet, const int &facet_idx, const float &min_z, const float &max_z, std::vector<IntersectionLine>* lines) const
{ {
@ -664,11 +680,8 @@ class _area_comp {
}; };
void void
TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<ExPolygons>* layers) TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slices)
{ {
std::vector<Polygons> layers_p;
this->slice(z, &layers_p);
/* /*
Input loops are not suitable for evenodd nor nonzero fill types, as we might get Input loops are not suitable for evenodd nor nonzero fill types, as we might get
two consecutive concentric loops having the same winding order - and we have to two consecutive concentric loops having the same winding order - and we have to
@ -685,55 +698,57 @@ TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<ExPolygons>*
the previous sorting method, based on $b->contains_point($a->[0]), failed to nest the previous sorting method, based on $b->contains_point($a->[0]), failed to nest
loops correctly in some edge cases when original model had overlapping facets loops correctly in some edge cases when original model had overlapping facets
*/ */
layers->resize(z.size()); std::vector<double> area;
std::vector<double> abs_area;
for (std::vector<Polygons>::const_iterator loops = layers_p.begin(); loops != layers_p.end(); ++loops) { std::vector<size_t> sorted_area; // vector of indices
size_t layer_id = loops - layers_p.begin(); for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++loop) {
double a = loop->area();
std::vector<double> area; area.push_back(a);
std::vector<double> abs_area; abs_area.push_back(std::fabs(a));
std::vector<size_t> sorted_area; // vector of indices sorted_area.push_back(loop - loops.begin());
for (Polygons::const_iterator loop = loops->begin(); loop != loops->end(); ++loop) {
double a = loop->area();
area.push_back(a);
abs_area.push_back(std::fabs(a));
sorted_area.push_back(loop - loops->begin());
}
std::sort(sorted_area.begin(), sorted_area.end(), _area_comp(&abs_area)); // outer first
// we don't perform a safety offset now because it might reverse cw loops
Polygons slices;
for (std::vector<size_t>::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++loop_idx) {
/* we rely on the already computed area to determine the winding order
of the loops, since the Orientation() function provided by Clipper
would do the same, thus repeating the calculation */
Polygons::const_iterator loop = loops->begin() + *loop_idx;
if (area[*loop_idx] >= 0) {
slices.push_back(*loop);
} else {
diff(slices, *loop, slices);
}
}
// perform a safety offset to merge very close facets (TODO: find test case for this)
double safety_offset = scale_(0.0499);
ExPolygons ex_slices;
offset2_ex(slices, ex_slices, +safety_offset, -safety_offset);
#ifdef SLIC3R_DEBUG
size_t holes_count = 0;
for (ExPolygons::const_iterator e = ex_slices.begin(); e != ex_slices.end(); ++e) {
holes_count += e->holes.size();
}
printf("Layer %zu (slice_z = %.2f): %zu surface(s) having %zu holes detected from %zu polylines\n",
layer_id, z[layer_id], ex_slices.size(), holes_count, loops->size());
#endif
ExPolygons* layer = &(*layers)[layer_id];
layer->insert(layer->end(), ex_slices.begin(), ex_slices.end());
} }
std::sort(sorted_area.begin(), sorted_area.end(), _area_comp(&abs_area)); // outer first
// we don't perform a safety offset now because it might reverse cw loops
Polygons p_slices;
for (std::vector<size_t>::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++loop_idx) {
/* we rely on the already computed area to determine the winding order
of the loops, since the Orientation() function provided by Clipper
would do the same, thus repeating the calculation */
Polygons::const_iterator loop = loops.begin() + *loop_idx;
if (area[*loop_idx] >= 0) {
p_slices.push_back(*loop);
} else {
diff(p_slices, *loop, p_slices);
}
}
// perform a safety offset to merge very close facets (TODO: find test case for this)
double safety_offset = scale_(0.0499);
ExPolygons ex_slices;
offset2_ex(p_slices, ex_slices, +safety_offset, -safety_offset);
#ifdef SLIC3R_DEBUG
size_t holes_count = 0;
for (ExPolygons::const_iterator e = ex_slices.begin(); e != ex_slices.end(); ++e) {
holes_count += e->holes.size();
}
printf("%zu surface(s) having %zu holes detected from %zu polylines\n",
ex_slices.size(), holes_count, loops.size());
#endif
// append to the supplied collection
slices->insert(slices->end(), ex_slices.begin(), ex_slices.end());
}
void
TriangleMeshSlicer::make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices)
{
Polygons pp;
this->make_loops(lines, &pp);
this->make_expolygons(pp, slices);
} }
void void
@ -817,8 +832,8 @@ TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
} }
// compute shape of section // compute shape of section
Polygons section; ExPolygons section;
this->make_loops(lines, &section); this->make_expolygons(lines, &section);
/* /*
stl_get_size(&(upper->stl)); stl_get_size(&(upper->stl));

View File

@ -91,6 +91,8 @@ class TriangleMeshSlicer
t_facets_edges facets_edges; t_facets_edges facets_edges;
stl_vertex* v_scaled_shared; stl_vertex* v_scaled_shared;
void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops); void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops);
void make_expolygons(const Polygons &loops, ExPolygons* slices);
void make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices);
}; };
} }