diff --git a/src/libslic3r/ExPolygon.cpp b/src/libslic3r/ExPolygon.cpp index 489023041..506ba8cb6 100644 --- a/src/libslic3r/ExPolygon.cpp +++ b/src/libslic3r/ExPolygon.cpp @@ -372,6 +372,27 @@ bool remove_sticks(ExPolygon &poly) return remove_sticks(poly.contour) || remove_sticks(poly.holes); } +bool remove_small_and_small_holes(ExPolygons &expolygons, double min_area) +{ + bool modified = false; + size_t free_idx = 0; + for (size_t expoly_idx = 0; expoly_idx < expolygons.size(); ++expoly_idx) { + if (std::abs(expolygons[expoly_idx].area()) >= min_area) { + // Expolygon is big enough, so also check all its holes + modified |= remove_small(expolygons[expoly_idx].holes, min_area); + if (free_idx < expoly_idx) { + std::swap(expolygons[expoly_idx].contour, expolygons[free_idx].contour); + std::swap(expolygons[expoly_idx].holes, expolygons[free_idx].holes); + } + ++free_idx; + } else + modified = true; + } + if (free_idx < expolygons.size()) + expolygons.erase(expolygons.begin() + free_idx, expolygons.end()); + return modified; +} + void keep_largest_contour_only(ExPolygons &polygons) { if (polygons.size() > 1) { diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index 73770bb18..89ba2e006 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -360,6 +360,9 @@ extern std::vector get_extents_vector(const ExPolygons &polygons); extern bool remove_sticks(ExPolygon &poly); extern void keep_largest_contour_only(ExPolygons &polygons); +// Removes all expolygons smaller than min_area and also removes all holes smaller than min_area +extern bool remove_small_and_small_holes(ExPolygons &expolygons, double min_area); + inline double area(const ExPolygons &polys) { double s = 0.; diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp index aa2536108..1ed08ef4b 100644 --- a/src/libslic3r/MultiMaterialSegmentation.cpp +++ b/src/libslic3r/MultiMaterialSegmentation.cpp @@ -1357,13 +1357,27 @@ std::vector>> multi_material_segmentati std::vector> painted_lines(print_object.layers().size()); std::vector edge_grids(print_object.layers().size()); const ConstLayerPtrsAdaptor layers = print_object.layers(); + std::vector input_polygons(layers.size()); + + // Merge all regions and remove small holes + for(size_t layer_idx = 0; layer_idx < layers.size(); layer_idx += 1) { + ExPolygons ex_polygons; + for (LayerRegion *region : layers[layer_idx]->regions()) + for (const Surface &surface : region->slices.surfaces) + Slic3r::append(ex_polygons, offset_ex(surface.expolygon, SCALED_EPSILON)); + // All expolygons are expanded by SCALED_EPSILON, merged, and then shrunk again by SCALED_EPSILON + // to ensure that very close polygons will be merged. + ex_polygons = union_ex(ex_polygons); + // Remove all expolygons and holes with an area less than 0.01mm^2 + remove_small_and_small_holes(ex_polygons, Slic3r::sqr(scale_(0.1f))); + input_polygons[layer_idx] = to_polygons(union_ex(offset_ex(ex_polygons, -SCALED_EPSILON))); + } for (size_t layer_idx = 0; layer_idx < layers.size(); ++layer_idx) { - const Layer *layer = layers[layer_idx]; - BoundingBox bbox(get_extents(layer->lslices)); + BoundingBox bbox(get_extents(input_polygons[layer_idx])); bbox.offset(SCALED_EPSILON); edge_grids[layer_idx].set_bbox(bbox); - edge_grids[layer_idx].create(layer->lslices, coord_t(scale_(10.))); + edge_grids[layer_idx].create(input_polygons[layer_idx], coord_t(scale_(10.))); } for (const ModelVolume *mv : print_object.model_object()->volumes) { @@ -1453,11 +1467,7 @@ std::vector>> multi_material_segmentati std::vector &painted_lines_single = painted_lines[layer_idx]; if (!painted_lines_single.empty()) { - Polygons original_polygons; - for (const Slic3r::EdgeGrid::Contour &contour : edge_grids[layer_idx].contours()) - original_polygons.emplace_back(Points(contour.begin(), contour.end())); - - std::vector> color_poly = colorize_polygons(original_polygons, painted_lines_single); + std::vector> color_poly = colorize_polygons(input_polygons[layer_idx], painted_lines_single); MMU_Graph graph = build_graph(layer_idx, color_poly); remove_multiple_edges_in_vertices(graph, color_poly); graph.remove_nodes_with_one_arc(); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 1c5c4f021..688b7d360 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1906,15 +1906,6 @@ void PrintObject::_slice(const std::vector &layer_height_profile) // --------------------MMU_SEGMENTATION_BEGIN---------------------- - // Temporary fix for not assigned lslices - for(size_t layer_idx = 0; layer_idx < m_layers.size(); layer_idx += 1) { - ExPolygons ex_polygons; - for (LayerRegion *region : this->m_layers[layer_idx]->regions()) - for (const Surface &surface : region->slices.surfaces) - ex_polygons.emplace_back(surface.expolygon); - this->m_layers[layer_idx]->lslices = union_ex(ex_polygons); - } - size_t region_count_before_change = this->num_regions(); std::vector>> segmented_regions = multi_material_segmentation_by_painting(*this); // Skip region with default extruder