Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@free.fr>2022-09-09 20:52:16 +0300
committersupermerill <merill@free.fr>2022-09-16 17:28:03 +0300
commit098159566be3bb321e96d48ef367b9db3944de56 (patch)
tree51cbf2905054b279fa4f93a8434306ad8ae69e24
parentfe6d2ba62464896102c6a7af9622229ff35b9ee1 (diff)
Fix mmu paint
supermerill/SuperSlicer#2639
-rw-r--r--src/libslic3r/EdgeGrid.hpp5
-rw-r--r--src/libslic3r/Model.cpp4
-rw-r--r--src/libslic3r/Model.hpp1
-rw-r--r--src/libslic3r/MultiMaterialSegmentation.cpp43
4 files changed, 35 insertions, 18 deletions
diff --git a/src/libslic3r/EdgeGrid.hpp b/src/libslic3r/EdgeGrid.hpp
index 44de5a919..e34be36a3 100644
--- a/src/libslic3r/EdgeGrid.hpp
+++ b/src/libslic3r/EdgeGrid.hpp
@@ -179,6 +179,11 @@ public:
assert(m_bbox.contains(p2));
p1 -= m_bbox.min;
p2 -= m_bbox.min;
+ assert(std::abs(p1.x()) < coord_t(int32_t(0x7FFFFFFF)));
+ assert(std::abs(p1.y()) < coord_t(int32_t(0x7FFFFFFF)));
+ assert(std::abs(p2.x()) < coord_t(int32_t(0x7FFFFFFF)));
+ assert(std::abs(p2.y()) < coord_t(int32_t(0x7FFFFFFF)));
+ assert(p1.x() >= 0 && p1.x() < coord_t(m_cols) * m_resolution);
assert(p1.x() >= 0 && p1.x() < coord_t(m_cols) * m_resolution);
assert(p1.y() >= 0 && p1.y() < coord_t(m_rows) * m_resolution);
assert(p2.x() >= 0 && p2.x() < coord_t(m_cols) * m_resolution);
diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp
index bb4e7603b..05f521839 100644
--- a/src/libslic3r/Model.cpp
+++ b/src/libslic3r/Model.cpp
@@ -2093,6 +2093,10 @@ indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, Enforce
selector.deserialize(m_data, false);
return selector.get_facets(type);
}
+void FacetsAnnotation::set_facets_selector(TriangleSelector& selector) const
+{
+ selector.deserialize(m_data, false);
+}
indexed_triangle_set FacetsAnnotation::get_facets_strict(const ModelVolume& mv, EnforcerBlockerType type) const
{
diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp
index efcacb726..335366d23 100644
--- a/src/libslic3r/Model.hpp
+++ b/src/libslic3r/Model.hpp
@@ -553,6 +553,7 @@ public:
const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>>& get_data() const throw() { return m_data; }
bool set(const TriangleSelector& selector);
indexed_triangle_set get_facets(const ModelVolume& mv, EnforcerBlockerType type) const;
+ void set_facets_selector(TriangleSelector& selector) const;
indexed_triangle_set get_facets_strict(const ModelVolume& mv, EnforcerBlockerType type) const;
bool has_facets(const ModelVolume& mv, EnforcerBlockerType type) const;
bool empty() const { return m_data.first.empty(); }
diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp
index 25b5e0f72..dad03aa05 100644
--- a/src/libslic3r/MultiMaterialSegmentation.cpp
+++ b/src/libslic3r/MultiMaterialSegmentation.cpp
@@ -7,6 +7,7 @@
#include "Geometry/VoronoiVisualUtils.hpp"
#include "MutablePolygon.hpp"
#include "format.hpp"
+#include "TriangleSelector.hpp"
#include <utility>
#include <cfloat>
@@ -98,6 +99,7 @@ struct PaintedLineVisitor
const Vec2d v1 = line_to_test.vector().cast<double>();
const double v1_sqr_norm = v1.squaredNorm();
const double heuristic_thr_part = line_to_test.length() + append_threshold;
+ double min_res = std::max(Slic3r::sqr(resolution), append_threshold_sqr);
for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++it_contour_and_segment) {
Line grid_line = grid.line(*it_contour_and_segment);
const Vec2d v2 = grid_line.vector().cast<double>();
@@ -110,15 +112,14 @@ struct PaintedLineVisitor
(grid_line.a - line_to_test.b).cast<double>().squaredNorm() > heuristic_thr_sqr ||
(grid_line.b - line_to_test.b).cast<double>().squaredNorm() > heuristic_thr_sqr)
continue;
-
// When lines have too different length, it is necessary to normalize them
if (Slic3r::sqr(v1.dot(v2)) > cos_threshold2 * v1_sqr_norm * v2.squaredNorm()) {
// The two vectors are nearly collinear (their mutual angle is lower than 30 degrees)
if (painted_lines_set.find(*it_contour_and_segment) == painted_lines_set.end()) {
- if (grid_line.distance_to_squared(line_to_test.a) < append_threshold2 ||
- grid_line.distance_to_squared(line_to_test.b) < append_threshold2 ||
- line_to_test.distance_to_squared(grid_line.a) < append_threshold2 ||
- line_to_test.distance_to_squared(grid_line.b) < append_threshold2) {
+ if (grid_line.distance_to_squared(line_to_test.a) < min_res ||
+ grid_line.distance_to_squared(line_to_test.b) < min_res ||
+ line_to_test.distance_to_squared(grid_line.a) < min_res ||
+ line_to_test.distance_to_squared(grid_line.b) < min_res) {
Line line_to_test_projected;
project_line_on_line(grid_line, line_to_test, &line_to_test_projected);
@@ -144,10 +145,11 @@ struct PaintedLineVisitor
Line line_to_test;
std::unordered_set<std::pair<size_t, size_t>, boost::hash<std::pair<size_t, size_t>>> painted_lines_set;
int color = -1;
+ double resolution = 50 * SCALED_EPSILON;
static inline const double cos_threshold2 = Slic3r::sqr(cos(M_PI * 30. / 180.));
static inline const double append_threshold = 50 * SCALED_EPSILON;
- static inline const double append_threshold2 = Slic3r::sqr(append_threshold);
+ static inline const double append_threshold_sqr = Slic3r::sqr(append_threshold);
};
static Polygon colored_points_to_polygon(const std::vector<ColoredLine> &lines)
@@ -1428,9 +1430,9 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
// Number of regions for a queried color.
int num_regions { 0 };
// Maximum perimeter extrusion width for a queried color.
- float extrusion_width { 0.f };
+ coordf_t extrusion_width { 0.f };
// Minimum radius of a region to be printable. Used to filter regions by morphological opening.
- float small_region_threshold { 0.f };
+ coordf_t small_region_threshold { 0.f };
// Maximum number of top layers for a queried color.
int top_solid_layers { 0 };
// Maximum number of bottom layers for a queried color.
@@ -1444,19 +1446,20 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
// color_idx == 0 means "don't know" extruder aka the underlying extruder.
// As this region may split existing regions, we collect statistics over all regions for color_idx == 0.
color_idx == 0 || config.perimeter_extruder == int(color_idx)) {
- out.extrusion_width = std::max<float>(out.extrusion_width, float(config.perimeter_extrusion_width));
+ double perimeter_extrusion_width = config.get_computed_value("perimeter_extrusion_width");
+ out.extrusion_width = std::max<double>(out.extrusion_width, perimeter_extrusion_width);
out.top_solid_layers = std::max<int>(out.top_solid_layers, config.top_solid_layers);
out.bottom_solid_layers = std::max<int>(out.bottom_solid_layers, config.bottom_solid_layers);
- out.small_region_threshold = config.gap_fill_enabled.value && config.gap_fill_speed.value > 0 ?
+ out.small_region_threshold = config.gap_fill_enabled.value ?
// Gap fill enabled. Enable a single line of 1/2 extrusion width.
- 0.5f * float(config.perimeter_extrusion_width) :
+ 0.5f * (perimeter_extrusion_width) :
// Gap fill disabled. Enable two lines slightly overlapping.
- float(config.perimeter_extrusion_width) + 0.7f * Flow::rounded_rectangle_extrusion_spacing(float(config.perimeter_extrusion_width), float(layer.height));
- out.small_region_threshold = scaled<float>(out.small_region_threshold * 0.5f);
+ (perimeter_extrusion_width) + 0.7f * Flow::rounded_rectangle_extrusion_spacing(perimeter_extrusion_width, float(layer.height), 1.f);
+ out.small_region_threshold = scale_d(out.small_region_threshold * 0.5f);
++ out.num_regions;
}
assert(out.num_regions > 0);
- out.extrusion_width = scaled<float>(out.extrusion_width);
+ out.extrusion_width = scale_d(out.extrusion_width);
return out;
};
@@ -1624,7 +1627,7 @@ void export_processed_input_expolygons_to_svg(const std::string &path, const Lay
::Slic3r::SVG svg(path.c_str(), bbox);
for (LayerRegion *region : regions)
- svg.draw_outline(region->slices.surfaces, "blue", "cyan", stroke_width);
+ svg.draw_outline(region->slices().surfaces, "blue", "cyan", stroke_width);
svg.draw_outline(processed_input_expolygons, "red", "pink", stroke_width);
}
@@ -1688,6 +1691,7 @@ std::vector<std::vector<ExPolygons>> multi_material_segmentation_by_painting(con
std::vector<EdgeGrid::Grid> edge_grids(num_layers);
const ConstLayerPtrsAdaptor layers = print_object.layers();
std::vector<ExPolygons> input_expolygons(num_layers);
+ coord_t resolution = scale_t(print_object.config().option("resolution")->getFloat());
throw_on_cancel_callback();
@@ -1747,15 +1751,18 @@ std::vector<std::vector<ExPolygons>> multi_material_segmentation_by_painting(con
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - projection of painted triangles - begin";
for (const ModelVolume *mv : print_object.model_object()->volumes) {
- tbb::parallel_for(tbb::blocked_range<size_t>(1, num_extruders + 1), [&mv, &print_object, &layers, &edge_grids, &painted_lines, &painted_lines_mutex, &input_expolygons, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
+ //can reuse the TriangleSelector for each extruder_idx
+ TriangleSelector tri_selector(mv->mesh());
+ mv->mmu_segmentation_facets.set_facets_selector(tri_selector);
+ tbb::parallel_for(tbb::blocked_range<size_t>(1, num_extruders + 1), [&mv, &print_object, &layers, &edge_grids, &painted_lines, &painted_lines_mutex, &input_expolygons, &resolution, &tri_selector , &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
for (size_t extruder_idx = range.begin(); extruder_idx < range.end(); ++extruder_idx) {
throw_on_cancel_callback();
- const indexed_triangle_set custom_facets = mv->mmu_segmentation_facets.get_facets(*mv, EnforcerBlockerType(extruder_idx));
+ const indexed_triangle_set custom_facets = tri_selector.get_facets(EnforcerBlockerType(extruder_idx));
if (!mv->is_model_part() || custom_facets.indices.empty())
continue;
const Transform3f tr = print_object.trafo().cast<float>() * mv->get_matrix().cast<float>();
- tbb::parallel_for(tbb::blocked_range<size_t>(0, custom_facets.indices.size()), [&tr, &custom_facets, &print_object, &layers, &edge_grids, &input_expolygons, &painted_lines, &painted_lines_mutex, &extruder_idx](const tbb::blocked_range<size_t> &range) {
+ tbb::parallel_for(tbb::blocked_range<size_t>(0, custom_facets.indices.size()), [&tr, &custom_facets, &print_object, &layers, &edge_grids, &input_expolygons, &painted_lines, &painted_lines_mutex, &extruder_idx, &resolution](const tbb::blocked_range<size_t> &range) {
for (size_t facet_idx = range.begin(); facet_idx < range.end(); ++facet_idx) {
float min_z = std::numeric_limits<float>::max();
float max_z = std::numeric_limits<float>::lowest();