mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-14 10:17:55 -06:00
Support material - Fixed some compilation warnings, added new debbuging
SVG file outputs.
This commit is contained in:
parent
3b5f40710c
commit
ff0412b417
1 changed files with 260 additions and 219 deletions
|
@ -176,7 +176,7 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object
|
||||||
// One of the support extruders is of "don't care" type.
|
// One of the support extruders is of "don't care" type.
|
||||||
auto object_extruders = m_object->print()->object_extruders();
|
auto object_extruders = m_object->print()->object_extruders();
|
||||||
if (object_extruders.size() == 1 &&
|
if (object_extruders.size() == 1 &&
|
||||||
*object_extruders.begin() == std::max(m_object_config->support_material_extruder.value, m_object_config->support_material_interface_extruder.value))
|
*object_extruders.begin() == std::max<unsigned int>(m_object_config->support_material_extruder.value, m_object_config->support_material_interface_extruder.value))
|
||||||
// Object is printed with the same extruder as the support.
|
// Object is printed with the same extruder as the support.
|
||||||
m_can_merge_support_regions = true;
|
m_can_merge_support_regions = true;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
for (int u = i; u < j; ++u) {
|
for (int u = i; u < j; ++u) {
|
||||||
MyLayer &layer = *layers_sorted[u];
|
MyLayer &layer = *layers_sorted[u];
|
||||||
if (!layer.polygons.empty())
|
if (! layer.polygons.empty())
|
||||||
empty = false;
|
empty = false;
|
||||||
layer.print_z = zavg;
|
layer.print_z = zavg;
|
||||||
height_min = std::min(height_min, layer.height);
|
height_min = std::min(height_min, layer.height);
|
||||||
|
@ -399,9 +399,9 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
|
||||||
coordf_t zmax = layers_sorted[i]->print_z + EPSILON;
|
coordf_t zmax = layers_sorted[i]->print_z + EPSILON;
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
for (; j < layers_sorted.size() && layers_sorted[j]->print_z <= zmax; ++j)
|
for (; j < layers_sorted.size() && layers_sorted[j]->print_z <= zmax; ++j)
|
||||||
if (!layers_sorted[j]->polygons.empty())
|
if (! layers_sorted[j]->polygons.empty())
|
||||||
empty = false;
|
empty = false;
|
||||||
if (!empty) {
|
if (! empty) {
|
||||||
export_print_z_polygons_to_svg(
|
export_print_z_polygons_to_svg(
|
||||||
debug_out_path("support-%d-%lf.svg", iRun, layers_sorted[i]->print_z).c_str(),
|
debug_out_path("support-%d-%lf.svg", iRun, layers_sorted[i]->print_z).c_str(),
|
||||||
layers_sorted.data() + i, j - i);
|
layers_sorted.data() + i, j - i);
|
||||||
|
@ -555,6 +555,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SupportGridPattern& operator=(const SupportGridPattern &rhs);
|
||||||
|
|
||||||
// Get some internal point of an expolygon, to be used as a representative
|
// Get some internal point of an expolygon, to be used as a representative
|
||||||
// sample to test, whether this island is inside another island.
|
// sample to test, whether this island is inside another island.
|
||||||
static Point island_sample(const ExPolygon &expoly)
|
static Point island_sample(const ExPolygon &expoly)
|
||||||
|
@ -854,7 +856,6 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
||||||
if (! contact_polygons.empty()) {
|
if (! contact_polygons.empty()) {
|
||||||
// get the average nozzle diameter used on this layer
|
// get the average nozzle diameter used on this layer
|
||||||
MyLayer &new_layer = layer_allocate(layer_storage, layer_storage_mutex, sltTopContact);
|
MyLayer &new_layer = layer_allocate(layer_storage, layer_storage_mutex, sltTopContact);
|
||||||
const Layer *layer_below = (layer_id > 0) ? object.layers[layer_id - 1] : NULL;
|
|
||||||
new_layer.idx_object_layer_above = layer_id;
|
new_layer.idx_object_layer_above = layer_id;
|
||||||
if (m_slicing_params.soluble_interface) {
|
if (m_slicing_params.soluble_interface) {
|
||||||
// Align the contact surface height with a layer immediately below the supported layer.
|
// Align the contact surface height with a layer immediately below the supported layer.
|
||||||
|
@ -865,7 +866,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
||||||
new_layer.bottom_z = m_slicing_params.raft_interface_top_z;
|
new_layer.bottom_z = m_slicing_params.raft_interface_top_z;
|
||||||
} else {
|
} else {
|
||||||
// Interface layer will be synchronized with the object.
|
// Interface layer will be synchronized with the object.
|
||||||
assert(layer_below != nullptr);
|
assert(layer_id > 0);
|
||||||
new_layer.height = object.layers[layer_id - 1]->height;
|
new_layer.height = object.layers[layer_id - 1]->height;
|
||||||
new_layer.bottom_z = new_layer.print_z - new_layer.height;
|
new_layer.bottom_z = new_layer.print_z - new_layer.height;
|
||||||
}
|
}
|
||||||
|
@ -980,7 +981,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||||
#endif
|
#endif
|
||||||
// These are the overhang surfaces. They are touching the object and they are not expanded away from the object.
|
// These are the overhang surfaces. They are touching the object and they are not expanded away from the object.
|
||||||
// Use a slight positive offset to overlap the touching regions.
|
// Use a slight positive offset to overlap the touching regions.
|
||||||
polygons_append(polygons_new, offset(*top_contacts[contact_idx]->overhang_polygons, SCALED_EPSILON));
|
polygons_append(polygons_new, offset(*top_contacts[contact_idx]->overhang_polygons, float(SCALED_EPSILON)));
|
||||||
polygons_append(projection, union_(polygons_new));
|
polygons_append(projection, union_(polygons_new));
|
||||||
}
|
}
|
||||||
if (projection.empty())
|
if (projection.empty())
|
||||||
|
@ -1061,14 +1062,30 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||||
debug_out_path("support-bottom-contacts-%d-%lf.svg", iRun, layer_new.print_z),
|
debug_out_path("support-bottom-contacts-%d-%lf.svg", iRun, layer_new.print_z),
|
||||||
union_ex(layer_new.polygons, false));
|
union_ex(layer_new.polygons, false));
|
||||||
#endif /* SLIC3R_DEBUG */
|
#endif /* SLIC3R_DEBUG */
|
||||||
// Trim the already created base layers above the current layer intersecting with the bottom contacts layer.
|
// Trim the already created base layers above the current layer intersecting with the new bottom contacts layer.
|
||||||
touching = offset(touching, float(SCALED_EPSILON));
|
touching = offset(touching, float(SCALED_EPSILON));
|
||||||
for (int layer_id_above = layer_id + 1; layer_id_above < int(object.total_layer_count()); ++ layer_id_above) {
|
for (int layer_id_above = layer_id + 1; layer_id_above < int(object.total_layer_count()); ++ layer_id_above) {
|
||||||
const Layer &layer_above = *object.layers[layer_id_above];
|
const Layer &layer_above = *object.layers[layer_id_above];
|
||||||
if (layer_above.print_z > layer_new.print_z + EPSILON)
|
if (layer_above.print_z > layer_new.print_z + EPSILON)
|
||||||
break;
|
break;
|
||||||
if (! layer_support_areas[layer_id_above].empty())
|
if (! layer_support_areas[layer_id_above].empty()) {
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
{
|
||||||
|
BoundingBox bbox = get_extents(touching);
|
||||||
|
bbox.merge(get_extents(layer_support_areas[layer_id_above]));
|
||||||
|
::Slic3r::SVG svg(debug_out_path("support-support-areas-raw-before-trimming-%d-with-%f-%lf.svg", iRun, layer.print_z, layer_above.print_z), bbox);
|
||||||
|
svg.draw(union_ex(touching, false), "blue", 0.5f);
|
||||||
|
svg.draw(union_ex(layer_support_areas[layer_id_above], true), "red", 0.5f);
|
||||||
|
svg.draw_outline(union_ex(layer_support_areas[layer_id_above], true), "red", "blue", scale_(0.1f));
|
||||||
|
}
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
layer_support_areas[layer_id_above] = diff(layer_support_areas[layer_id_above], touching);
|
layer_support_areas[layer_id_above] = diff(layer_support_areas[layer_id_above], touching);
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
Slic3r::SVG::export_expolygons(
|
||||||
|
debug_out_path("support-support-areas-raw-after-trimming-%d-with-%f-%lf.svg", iRun, layer.print_z, layer_above.print_z),
|
||||||
|
union_ex(layer_support_areas[layer_id_above], false));
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // ! top.empty()
|
} // ! top.empty()
|
||||||
|
@ -1080,8 +1097,23 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||||
// Polygons trimming = union_(to_polygons(layer.slices.expolygons), touching, true);
|
// Polygons trimming = union_(to_polygons(layer.slices.expolygons), touching, true);
|
||||||
Polygons trimming = offset(layer.slices.expolygons, float(SCALED_EPSILON));
|
Polygons trimming = offset(layer.slices.expolygons, float(SCALED_EPSILON));
|
||||||
projection = diff(projection_raw, trimming, false);
|
projection = diff(projection_raw, trimming, false);
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
{
|
||||||
|
BoundingBox bbox = get_extents(projection_raw);
|
||||||
|
bbox.merge(get_extents(trimming));
|
||||||
|
::Slic3r::SVG svg(debug_out_path("support-support-areas-raw-%d-%lf.svg", iRun, layer.print_z), bbox);
|
||||||
|
svg.draw(union_ex(trimming, false), "blue", 0.5f);
|
||||||
|
svg.draw(union_ex(projection, true), "red", 0.5f);
|
||||||
|
svg.draw_outline(union_ex(projection, true), "red", "blue", scale_(0.1f));
|
||||||
|
}
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
remove_sticks(projection);
|
remove_sticks(projection);
|
||||||
remove_degenerate(projection);
|
remove_degenerate(projection);
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
Slic3r::SVG::export_expolygons(
|
||||||
|
debug_out_path("support-support-areas-raw-cleaned-%d-%lf.svg", iRun, layer.print_z),
|
||||||
|
union_ex(projection, false));
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
SupportGridPattern support_grid_pattern(
|
SupportGridPattern support_grid_pattern(
|
||||||
// Support islands, to be stretched into a grid.
|
// Support islands, to be stretched into a grid.
|
||||||
projection,
|
projection,
|
||||||
|
@ -1092,13 +1124,31 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||||
tbb::task_group task_group_inner;
|
tbb::task_group task_group_inner;
|
||||||
// 1) Cache the slice of a support volume. The support volume is expanded by 1/2 of support material flow spacing
|
// 1) Cache the slice of a support volume. The support volume is expanded by 1/2 of support material flow spacing
|
||||||
// to allow a placement of suppot zig-zag snake along the grid lines.
|
// to allow a placement of suppot zig-zag snake along the grid lines.
|
||||||
task_group_inner.run([this, &support_grid_pattern, &layer_support_area] {
|
task_group_inner.run([this, &support_grid_pattern, &layer_support_area
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
, &layer
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
|
] {
|
||||||
layer_support_area = support_grid_pattern.extract_support(m_support_material_flow.scaled_spacing()/2 + 25);
|
layer_support_area = support_grid_pattern.extract_support(m_support_material_flow.scaled_spacing()/2 + 25);
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
Slic3r::SVG::export_expolygons(
|
||||||
|
debug_out_path("support-layer_support_area-gridded-%d-%lf.svg", iRun, layer.print_z),
|
||||||
|
union_ex(layer_support_area, false));
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
});
|
});
|
||||||
// 2) Support polygons will be projected down. To keep the interface and base layers from growing, return a contour a tiny bit smaller than the grid cells.
|
// 2) Support polygons will be projected down. To keep the interface and base layers from growing, return a contour a tiny bit smaller than the grid cells.
|
||||||
Polygons projection_new;
|
Polygons projection_new;
|
||||||
task_group_inner.run([&projection_new, &support_grid_pattern] {
|
task_group_inner.run([&projection_new, &support_grid_pattern
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
, &layer
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
|
] {
|
||||||
projection_new = support_grid_pattern.extract_support(-5);
|
projection_new = support_grid_pattern.extract_support(-5);
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
Slic3r::SVG::export_expolygons(
|
||||||
|
debug_out_path("support-projection_new-gridded-%d-%lf.svg", iRun, layer.print_z),
|
||||||
|
union_ex(projection_new, false));
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
});
|
});
|
||||||
task_group_inner.wait();
|
task_group_inner.wait();
|
||||||
projection = std::move(projection_new);
|
projection = std::move(projection_new);
|
||||||
|
@ -1692,14 +1742,6 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_int
|
||||||
MyLayersPtr &intermediate_layers,
|
MyLayersPtr &intermediate_layers,
|
||||||
MyLayerStorage &layer_storage) const
|
MyLayerStorage &layer_storage) const
|
||||||
{
|
{
|
||||||
// Old comment:
|
|
||||||
// Compute interface area on this layer as diff of upper contact area
|
|
||||||
// (or upper interface area) and layer slices.
|
|
||||||
// This diff is responsible of the contact between support material and
|
|
||||||
// the top surfaces of the object. We should probably offset the top
|
|
||||||
// surfaces vertically before performing the diff, but this needs
|
|
||||||
// investigation.
|
|
||||||
|
|
||||||
// my $area_threshold = $self->interface_flow->scaled_spacing ** 2;
|
// my $area_threshold = $self->interface_flow->scaled_spacing ** 2;
|
||||||
|
|
||||||
MyLayersPtr interface_layers;
|
MyLayersPtr interface_layers;
|
||||||
|
@ -2240,7 +2282,7 @@ void modulate_extrusion_by_overlapping_layers(
|
||||||
for (int i_overlapping_layer = int(n_overlapping_layers) - 1; i_overlapping_layer >= 0; -- i_overlapping_layer) {
|
for (int i_overlapping_layer = int(n_overlapping_layers) - 1; i_overlapping_layer >= 0; -- i_overlapping_layer) {
|
||||||
const PrintObjectSupportMaterial::MyLayer &overlapping_layer = *overlapping_layers[i_overlapping_layer];
|
const PrintObjectSupportMaterial::MyLayer &overlapping_layer = *overlapping_layers[i_overlapping_layer];
|
||||||
ExtrusionPathFragment &frag = path_fragments[i_overlapping_layer];
|
ExtrusionPathFragment &frag = path_fragments[i_overlapping_layer];
|
||||||
Polygons polygons_trimming = offset(union_ex(overlapping_layer.polygons), scale_(0.5*extrusion_width));
|
Polygons polygons_trimming = offset(union_ex(overlapping_layer.polygons), float(scale_(0.5*extrusion_width)));
|
||||||
frag.polylines = intersection_pl(path_fragments.back().polylines, polygons_trimming, false);
|
frag.polylines = intersection_pl(path_fragments.back().polylines, polygons_trimming, false);
|
||||||
path_fragments.back().polylines = diff_pl(path_fragments.back().polylines, polygons_trimming, false);
|
path_fragments.back().polylines = diff_pl(path_fragments.back().polylines, polygons_trimming, false);
|
||||||
// Adjust the extrusion parameters for a reduced layer height and a non-bridging flow (nozzle_dmr = -1, does not matter).
|
// Adjust the extrusion parameters for a reduced layer height and a non-bridging flow (nozzle_dmr = -1, does not matter).
|
||||||
|
@ -2280,6 +2322,7 @@ void modulate_extrusion_by_overlapping_layers(
|
||||||
(fragment_end.is_start ? &polyline.points.front() : &polyline.points.back());
|
(fragment_end.is_start ? &polyline.points.front() : &polyline.points.back());
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
ExtrusionPathFragmentEndPointAccessor& operator=(const ExtrusionPathFragmentEndPointAccessor&) {}
|
||||||
const std::vector<ExtrusionPathFragment> &m_path_fragments;
|
const std::vector<ExtrusionPathFragment> &m_path_fragments;
|
||||||
};
|
};
|
||||||
const coord_t search_radius = 7;
|
const coord_t search_radius = 7;
|
||||||
|
@ -2290,8 +2333,6 @@ void modulate_extrusion_by_overlapping_layers(
|
||||||
for (size_t i_polyline = 0; i_polyline < polylines.size(); ++ i_polyline) {
|
for (size_t i_polyline = 0; i_polyline < polylines.size(); ++ i_polyline) {
|
||||||
// Map a starting point of a polyline to a pair of <layer, polyline>
|
// Map a starting point of a polyline to a pair of <layer, polyline>
|
||||||
if (polylines[i_polyline].points.size() >= 2) {
|
if (polylines[i_polyline].points.size() >= 2) {
|
||||||
const Point &pt_start = polylines[i_polyline].points.front();
|
|
||||||
const Point &pt_end = polylines[i_polyline].points.back();
|
|
||||||
map_fragment_starts.insert(ExtrusionPathFragmentEnd(i_overlapping_layer, i_polyline, true));
|
map_fragment_starts.insert(ExtrusionPathFragmentEnd(i_overlapping_layer, i_polyline, true));
|
||||||
map_fragment_starts.insert(ExtrusionPathFragmentEnd(i_overlapping_layer, i_polyline, false));
|
map_fragment_starts.insert(ExtrusionPathFragmentEnd(i_overlapping_layer, i_polyline, false));
|
||||||
}
|
}
|
||||||
|
@ -2453,7 +2494,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||||
// Insert the raft base layers.
|
// Insert the raft base layers.
|
||||||
size_t n_raft_layers = size_t(std::max(0, int(m_slicing_params.raft_layers()) - 1));
|
size_t n_raft_layers = size_t(std::max(0, int(m_slicing_params.raft_layers()) - 1));
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, n_raft_layers),
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, n_raft_layers),
|
||||||
[this, &object, &raft_layers, &loop_interface_processor,
|
[this, &object, &raft_layers,
|
||||||
infill_pattern, &bbox_object, support_density, interface_density, raft_angle_1st_layer, raft_angle_base, raft_angle_interface, link_max_length_factor, with_sheath]
|
infill_pattern, &bbox_object, support_density, interface_density, raft_angle_1st_layer, raft_angle_base, raft_angle_interface, link_max_length_factor, with_sheath]
|
||||||
(const tbb::blocked_range<size_t>& range) {
|
(const tbb::blocked_range<size_t>& range) {
|
||||||
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
|
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue