-
-
Notifications
You must be signed in to change notification settings - Fork 890
/
Copy pathlayerPart.cpp
110 lines (95 loc) · 3.9 KB
/
layerPart.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (c) 2023 UltiMaker
// CuraEngine is released under the terms of the AGPLv3 or higher.
#include "layerPart.h"
#include "geometry/OpenPolyline.h"
#include "progress/Progress.h"
#include "settings/EnumSettings.h" //For ESurfaceMode.
#include "settings/Settings.h"
#include "sliceDataStorage.h"
#include "slicer.h"
#include "utils/OpenPolylineStitcher.h"
#include "utils/Simplify.h" //Simplifying the layers after creating them.
#include "utils/ThreadPool.h"
/*
The layer-part creation step is the first step in creating actual useful data for 3D printing.
It takes the result of the Slice step, which is an unordered list of polygons_, and makes groups of polygons_,
each of these groups is called a "part", which sometimes are also known as "islands". These parts represent
isolated areas in the 2D layer with possible holes.
Creating "parts" is an important step, as all elements in a single part should be printed before going to another part.
And all every bit inside a single part can be printed without the nozzle leaving the boundary of this part.
It's also the first step that stores the result in the "data storage" so all other steps can access it.
*/
namespace cura
{
void createLayerWithParts(const Settings& settings, SliceLayer& storageLayer, SlicerLayer* layer)
{
OpenPolylineStitcher::stitch(layer->open_polylines_, storageLayer.open_polylines, layer->polygons_, settings.get<coord_t>("wall_line_width_0"));
storageLayer.open_polylines = Simplify(settings).polyline(storageLayer.open_polylines);
const bool union_all_remove_holes = settings.get<bool>("meshfix_union_all_remove_holes");
if (union_all_remove_holes)
{
for (unsigned int i = 0; i < layer->polygons_.size(); i++)
{
if (layer->polygons_[i].orientation())
layer->polygons_[i].reverse();
}
}
std::vector<SingleShape> result;
const bool union_layers = settings.get<bool>("meshfix_union_all");
const ESurfaceMode surface_only = settings.get<ESurfaceMode>("magic_mesh_surface_mode");
if (surface_only == ESurfaceMode::SURFACE && ! union_layers)
{ // Don't do anything with overlapping areas; no union nor xor
result.reserve(layer->polygons_.size());
for (const Polygon& poly : layer->polygons_)
{
if (poly.empty())
{
continue;
}
result.emplace_back();
result.back().push_back(poly);
}
}
else
{
result = layer->polygons_.splitIntoParts(union_layers || union_all_remove_holes);
}
for (auto& part : result)
{
storageLayer.parts.emplace_back();
if (part.empty())
{
continue;
}
storageLayer.parts.back().outline = part;
storageLayer.parts.back().boundaryBox.calculate(storageLayer.parts.back().outline);
if (storageLayer.parts.back().outline.empty())
{
storageLayer.parts.pop_back();
}
}
}
void createLayerParts(SliceMeshStorage& mesh, Slicer* slicer)
{
const auto total_layers = slicer->layers.size();
assert(mesh.layers.size() == total_layers);
cura::parallel_for<size_t>(
0,
total_layers,
[slicer, &mesh](size_t layer_nr)
{
SliceLayer& layer_storage = mesh.layers[layer_nr];
SlicerLayer& slice_layer = slicer->layers[layer_nr];
createLayerWithParts(mesh.settings, layer_storage, &slice_layer);
});
for (LayerIndex layer_nr = total_layers - 1; layer_nr >= 0; layer_nr--)
{
SliceLayer& layer_storage = mesh.layers[layer_nr];
if (layer_storage.parts.size() > 0 || (mesh.settings.get<ESurfaceMode>("magic_mesh_surface_mode") != ESurfaceMode::NORMAL && layer_storage.open_polylines.size() > 0))
{
mesh.layer_nr_max_filled_layer = layer_nr; // last set by the highest non-empty layer
break;
}
}
}
} // namespace cura