mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-27 02:31:10 -06:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_sinking_objects_collision
This commit is contained in:
commit
29340c1560
56 changed files with 673 additions and 361 deletions
|
|
@ -85,9 +85,6 @@ void AppConfig::set_defaults()
|
|||
if (get("associate_stl").empty())
|
||||
set("associate_stl", "0");
|
||||
|
||||
if (get("dark_color_mode").empty())
|
||||
set("dark_color_mode", "0");
|
||||
|
||||
if (get("tabs_as_menu").empty())
|
||||
set("tabs_as_menu", "0");
|
||||
#endif // _WIN32
|
||||
|
|
@ -179,6 +176,9 @@ void AppConfig::set_defaults()
|
|||
#ifdef _WIN32
|
||||
if (get("use_legacy_3DConnexion").empty())
|
||||
set("use_legacy_3DConnexion", "0");
|
||||
|
||||
if (get("dark_color_mode").empty())
|
||||
set("dark_color_mode", "0");
|
||||
#endif // _WIN32
|
||||
|
||||
// Remove legacy window positions/sizes
|
||||
|
|
|
|||
|
|
@ -552,6 +552,22 @@ void Model::convert_from_meters(bool only_small_volumes)
|
|||
}
|
||||
}
|
||||
|
||||
static constexpr const double zero_volume = 0.0000000001;
|
||||
|
||||
int Model::removed_objects_with_zero_volume()
|
||||
{
|
||||
if (objects.size() == 0)
|
||||
return 0;
|
||||
|
||||
int removed = 0;
|
||||
for (int i = int(objects.size()) - 1; i >= 0; i--)
|
||||
if (objects[i]->get_object_stl_stats().volume < zero_volume) {
|
||||
delete_object(size_t(i));
|
||||
removed++;
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
void Model::adjust_min_z()
|
||||
{
|
||||
if (objects.empty())
|
||||
|
|
@ -1701,10 +1717,10 @@ TriangleMeshStats ModelObject::get_object_stl_stats() const
|
|||
return full_stats;
|
||||
}
|
||||
|
||||
int ModelObject::get_mesh_errors_count(const int vol_idx /*= -1*/) const
|
||||
int ModelObject::get_repaired_errors_count(const int vol_idx /*= -1*/) const
|
||||
{
|
||||
if (vol_idx >= 0)
|
||||
return this->volumes[vol_idx]->get_mesh_errors_count();
|
||||
return this->volumes[vol_idx]->get_repaired_errors_count();
|
||||
|
||||
const RepairedMeshErrors& stats = get_object_stl_stats().repaired_errors;
|
||||
|
||||
|
|
@ -1776,7 +1792,7 @@ void ModelVolume::calculate_convex_hull()
|
|||
assert(m_convex_hull.get());
|
||||
}
|
||||
|
||||
int ModelVolume::get_mesh_errors_count() const
|
||||
int ModelVolume::get_repaired_errors_count() const
|
||||
{
|
||||
const RepairedMeshErrors &stats = this->mesh().stats().repaired_errors;
|
||||
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ public:
|
|||
// Get full stl statistics for all object's meshes
|
||||
TriangleMeshStats get_object_stl_stats() const;
|
||||
// Get count of errors in the mesh( or all object's meshes, if volume index isn't defined)
|
||||
int get_mesh_errors_count(const int vol_idx = -1) const;
|
||||
int get_repaired_errors_count(const int vol_idx = -1) const;
|
||||
|
||||
private:
|
||||
friend class Model;
|
||||
|
|
@ -686,7 +686,7 @@ public:
|
|||
const TriangleMesh& get_convex_hull() const;
|
||||
std::shared_ptr<const TriangleMesh> get_convex_hull_shared_ptr() const { return m_convex_hull; }
|
||||
// Get count of errors in the mesh
|
||||
int get_mesh_errors_count() const;
|
||||
int get_repaired_errors_count() const;
|
||||
|
||||
// Helpers for loading / storing into AMF / 3MF files.
|
||||
static ModelVolumeType type_from_string(const std::string &s);
|
||||
|
|
@ -1140,6 +1140,7 @@ public:
|
|||
void convert_from_imperial_units(bool only_small_volumes);
|
||||
bool looks_like_saved_in_meters() const;
|
||||
void convert_from_meters(bool only_small_volumes);
|
||||
int removed_objects_with_zero_volume();
|
||||
|
||||
// Ensures that the min z of the model is not negative
|
||||
void adjust_min_z();
|
||||
|
|
|
|||
|
|
@ -1214,7 +1214,7 @@ static void cut_segmented_layers(const std::vector<ExPolygons>
|
|||
const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - cutting segmented layers in parallel - begin";
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, segmented_regions.size()),[&](const tbb::blocked_range<size_t>& range) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, segmented_regions.size()),[&segmented_regions, &input_expolygons, &cut_width, &throw_on_cancel_callback](const tbb::blocked_range<size_t>& range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
||||
throw_on_cancel_callback();
|
||||
std::vector<std::pair<ExPolygon, size_t>> segmented_regions_cuts;
|
||||
|
|
@ -1366,7 +1366,8 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
|
|||
return out;
|
||||
};
|
||||
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, num_layers, granularity), [&](const tbb::blocked_range<size_t> &range) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, num_layers, granularity), [&granularity, &num_layers, &num_extruders, &layer_color_stat, &top_raw, &triangles_by_color_top,
|
||||
&throw_on_cancel_callback, &input_expolygons, &bottom_raw, &triangles_by_color_bottom](const tbb::blocked_range<size_t> &range) {
|
||||
size_t group_idx = range.begin() / granularity;
|
||||
size_t layer_idx_offset = (group_idx & 1) * num_layers;
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
||||
|
|
@ -1417,7 +1418,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
|
|||
|
||||
std::vector<std::vector<ExPolygons>> triangles_by_color_merged(num_extruders);
|
||||
triangles_by_color_merged.assign(num_extruders, std::vector<ExPolygons>(num_layers));
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, num_layers), [&](const tbb::blocked_range<size_t> &range) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, num_layers), [&triangles_by_color_merged, &triangles_by_color_bottom, &triangles_by_color_top, &num_layers, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
||||
throw_on_cancel_callback();
|
||||
for (size_t color_idx = 0; color_idx < triangles_by_color_merged.size(); ++color_idx) {
|
||||
|
|
@ -1446,7 +1447,7 @@ static std::vector<std::vector<std::pair<ExPolygon, size_t>>> merge_segmented_la
|
|||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged(segmented_regions.size());
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - merging segmented layers in parallel - begin";
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, segmented_regions.size()), [&](const tbb::blocked_range<size_t> &range) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, segmented_regions.size()), [&segmented_regions, &top_and_bottom_layers, &segmented_regions_merged, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
||||
for (const std::pair<ExPolygon, size_t> &colored_expoly : segmented_regions[layer_idx]) {
|
||||
throw_on_cancel_callback();
|
||||
|
|
@ -1526,6 +1527,20 @@ void export_processed_input_expolygons_to_svg(const std::string &path, const Lay
|
|||
}
|
||||
#endif // MMU_SEGMENTATION_DEBUG_INPUT
|
||||
|
||||
// Check if all ColoredLine representing a single layer uses the same color.
|
||||
static bool has_layer_only_one_color(const std::vector<std::vector<ColoredLine>> &colored_polygons)
|
||||
{
|
||||
assert(!colored_polygons.empty());
|
||||
assert(!colored_polygons.front().empty());
|
||||
int first_line_color = colored_polygons.front().front().color;
|
||||
for (const std::vector<ColoredLine> &colored_polygon : colored_polygons)
|
||||
for (const ColoredLine &colored_line : colored_polygon)
|
||||
if (first_line_color != colored_line.color)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions(print_object.layers().size());
|
||||
|
|
@ -1539,7 +1554,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
|
||||
// Merge all regions and remove small holes
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - slices preparation in parallel - begin";
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, layers.size()), [&](const tbb::blocked_range<size_t> &range) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, layers.size()), [&layers, &input_expolygons, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
||||
throw_on_cancel_callback();
|
||||
ExPolygons ex_polygons;
|
||||
|
|
@ -1649,16 +1664,16 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
edge_grids[layer_idx].visit_cells_intersecting_line(line_start, line_end, visitor);
|
||||
}
|
||||
}
|
||||
});
|
||||
}); // end of parallel_for
|
||||
}
|
||||
});
|
||||
}); // end of parallel_for
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - projection of painted triangles - end";
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - painted layers count: "
|
||||
<< std::count_if(painted_lines.begin(), painted_lines.end(), [](const std::vector<PaintedLine> &pl) { return !pl.empty(); });
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - layers segmentation in parallel - begin";
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, print_object.layers().size()), [&](const tbb::blocked_range<size_t> &range) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, print_object.layers().size()), [&edge_grids, &input_expolygons, &painted_lines, &segmented_regions, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
||||
throw_on_cancel_callback();
|
||||
auto comp = [&edge_grids, layer_idx](const PaintedLine &first, const PaintedLine &second) {
|
||||
|
|
@ -1677,20 +1692,28 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
|
||||
if (!painted_lines_single.empty()) {
|
||||
std::vector<std::vector<ColoredLine>> color_poly = colorize_polygons(edge_grids[layer_idx].contours(), 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();
|
||||
assert(!color_poly.empty());
|
||||
assert(!color_poly.front().empty());
|
||||
if (has_layer_only_one_color(color_poly)) {
|
||||
// If the whole layer is painted using the same color, it is not needed to construct a Voronoi diagram for the segmentation of this layer.
|
||||
for (const ExPolygon &ex_polygon : input_expolygons[layer_idx])
|
||||
segmented_regions[layer_idx].emplace_back(ex_polygon, size_t(color_poly.front().front().color));
|
||||
} else {
|
||||
MMU_Graph graph = build_graph(layer_idx, color_poly);
|
||||
remove_multiple_edges_in_vertices(graph, color_poly);
|
||||
graph.remove_nodes_with_one_arc();
|
||||
|
||||
#ifdef MMU_SEGMENTATION_DEBUG_GRAPH
|
||||
{
|
||||
static int iRun = 0;
|
||||
export_graph_to_svg(debug_out_path("mm-graph-final-%d-%d.svg", layer_idx, iRun++), graph, input_expolygons[layer_idx]);
|
||||
}
|
||||
{
|
||||
static int iRun = 0;
|
||||
export_graph_to_svg(debug_out_path("mm-graph-final-%d-%d.svg", layer_idx, iRun++), graph, input_expolygons[layer_idx]);
|
||||
}
|
||||
#endif // MMU_SEGMENTATION_DEBUG_GRAPH
|
||||
|
||||
std::vector<std::pair<Polygon, size_t>> segmentation = extract_colored_segments(graph);
|
||||
for (std::pair<Polygon, size_t> ®ion : segmentation)
|
||||
segmented_regions[layer_idx].emplace_back(std::move(region));
|
||||
std::vector<std::pair<Polygon, size_t>> segmentation = extract_colored_segments(graph);
|
||||
for (std::pair<Polygon, size_t> ®ion : segmentation)
|
||||
segmented_regions[layer_idx].emplace_back(std::move(region));
|
||||
}
|
||||
|
||||
#ifdef MMU_SEGMENTATION_DEBUG_REGIONS
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ TriangleMesh::TriangleMesh(const indexed_triangle_set &its) : its(its)
|
|||
|
||||
TriangleMesh::TriangleMesh(indexed_triangle_set &&its, const RepairedMeshErrors& errors/* = RepairedMeshErrors()*/) : its(std::move(its))
|
||||
{
|
||||
if (errors.repaired())
|
||||
m_stats.repaired_errors = errors;
|
||||
m_stats.repaired_errors = errors;
|
||||
fill_initial_stats(this->its, m_stats);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,14 +33,12 @@ struct RepairedMeshErrors {
|
|||
|
||||
void clear() { *this = RepairedMeshErrors(); }
|
||||
|
||||
RepairedMeshErrors merge(const RepairedMeshErrors& rhs) const {
|
||||
RepairedMeshErrors out;
|
||||
out.edges_fixed = this->edges_fixed + rhs.edges_fixed;
|
||||
out.degenerate_facets = this->degenerate_facets + rhs.degenerate_facets;
|
||||
out.facets_removed = this->facets_removed + rhs.facets_removed;
|
||||
out.facets_reversed = this->facets_reversed + rhs.facets_reversed;
|
||||
out.backwards_edges = this->backwards_edges + rhs.backwards_edges;
|
||||
return out;
|
||||
void merge(const RepairedMeshErrors& rhs) {
|
||||
this->edges_fixed += rhs.edges_fixed;
|
||||
this->degenerate_facets += rhs.degenerate_facets;
|
||||
this->facets_removed += rhs.facets_removed;
|
||||
this->facets_reversed += rhs.facets_reversed;
|
||||
this->backwards_edges += rhs.backwards_edges;
|
||||
}
|
||||
|
||||
bool repaired() const { return degenerate_facets > 0 || edges_fixed > 0 || facets_removed > 0 || facets_reversed > 0 || backwards_edges > 0; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue