Merge branch 'main' into perf/slicing-optimizations

# Conflicts:
#	src/libslic3r/PerimeterGenerator.cpp
#	src/libslic3r/PrintObject.cpp
#	src/libslic3r/Support/TreeSupport.cpp
This commit is contained in:
SoftFever
2026-10-09 19:48:26 +08:00
2078 changed files with 247064 additions and 159572 deletions
+21 -11
View File
@@ -18,16 +18,15 @@
#include "MutablePolygon.hpp"
#include "Utils.hpp"
#include "PrintConfig.hpp"
#include "TriangleSelector.hpp"
#include "TriangleMeshSlicer.hpp"
#include "Surface.hpp"
#include "format.hpp"
#include "libslic3r.h"
#include <numeric>
#include <cmath>
#include <cstddef>
#include <list>
#include <cstdint>
#include <cassert>
#include <algorithm>
#include <cstdlib>
@@ -45,6 +44,9 @@
#include <boost/thread/lock_guard.hpp>
#include <vector>
#include <queue>
#include "SurfaceCollection.hpp"
namespace Slic3r { enum class EnforcerBlockerType : int8_t; }
//#define MM_SEGMENTATION_DEBUG_GRAPH
//#define MM_SEGMENTATION_DEBUG_REGIONS
@@ -62,6 +64,7 @@
namespace Slic3r {
using boost::polygon::voronoi_diagram;
using VD = Geometry::VoronoiDiagram;
static inline Point mk_point(const Voronoi::VD::vertex_type *point) { return {coord_t(point->x()), coord_t(point->y())}; }
@@ -1258,7 +1261,7 @@ static inline std::vector<std::vector<ExPolygons>> segmentation_top_and_bottom_l
// project downards pointing painted triangles over bottom surfaces.
std::vector<std::vector<Polygons>> top_raw(num_facets_states), bottom_raw(num_facets_states);
std::vector<float> zs = zs_from_layers(layers);
Transform3d object_trafo = print_object.trafo_centered();
Transform3d object_trafo = print_object.trafo_sliced();
#ifdef MM_SEGMENTATION_DEBUG_TOP_BOTTOM
static int iRun = 0;
@@ -1287,10 +1290,16 @@ static inline std::vector<std::vector<ExPolygons>> segmentation_top_and_bottom_l
slicing_params.trafo = volume_trafo;
Polygons bottom_slice = slice_mesh(painted, zs[0], slicing_params);
top.erase(top.begin());
bottom.erase(bottom.begin());
bottom[0] = union_(bottom[0], bottom_slice);
// Only the requested projections exist: with
// top_shell_layers = 0 `top` is empty and erasing its begin() was
// undefined (found by fuzzing: a sunk, painted object crashed here).
if (! top.empty())
top.erase(top.begin());
if (! bottom.empty()) {
bottom.erase(bottom.begin());
if (! bottom.empty())
bottom[0] = union_(bottom[0], bottom_slice);
}
} else
slice_mesh_slabs(painted, zs, volume_trafo, max_top_layers > 0 ? &top : nullptr, max_bottom_layers > 0 ? &bottom : nullptr, nullptr, throw_on_cancel_callback);
auto merge = [](std::vector<Polygons> &&src, std::vector<Polygons> &dst) {
@@ -2245,17 +2254,19 @@ std::vector<std::vector<ExPolygons>> segmentation_by_painting(const PrintObject
}
BOOST_LOG_TRIVIAL(debug) << "Print object segmentation - Projection of painted triangles - Begin";
// The layers were sliced in this frame (belt rotation, remap and Z lift included), and it already centers the object.
const Transform3d object_trafo = print_object.trafo_sliced();
for (const ModelVolume *mv : print_object.model_object()->volumes) {
const ModelVolumeFacetsInfo facets_info = extract_facets_info(*mv);
tbb::parallel_for(tbb::blocked_range<size_t>(1, num_facets_states), [&mv, &print_object, &facets_info, &layers, &edge_grids, &painted_lines, &painted_lines_mutex, &input_expolygons, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
tbb::parallel_for(tbb::blocked_range<size_t>(1, num_facets_states), [&mv, &object_trafo, &facets_info, &layers, &edge_grids, &painted_lines, &painted_lines_mutex, &input_expolygons, &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 = facets_info.facets_annotation.get_facets(*mv, 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) {
const Transform3f tr = (object_trafo * mv->get_matrix()).cast<float>();
tbb::parallel_for(tbb::blocked_range<size_t>(0, custom_facets.indices.size()), [&tr, &custom_facets, &layers, &edge_grids, &input_expolygons, &painted_lines, &painted_lines_mutex, &extruder_idx](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();
@@ -2308,7 +2319,6 @@ std::vector<std::vector<ExPolygons>> segmentation_by_painting(const PrintObject
Line line_to_test(Point(scale_(line_start_f.x()), scale_(line_start_f.y())),
Point(scale_(line_end_f.x()), scale_(line_end_f.y())));
line_to_test.translate(-print_object.center_offset());
// BoundingBoxes for EdgeGrids are computed from printable regions. It is possible that the painted line (line_to_test) could
// be outside EdgeGrid's BoundingBox, for example, when the negative volume is used on the painted area (GH #7618).