mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-14 10:17:55 -06:00
Supports using the EdgeGrid simplify_contour
This commit is contained in:
parent
1d44e92a6e
commit
946b36bb4d
2 changed files with 198 additions and 77 deletions
|
@ -5,6 +5,7 @@
|
||||||
#include "Print.hpp"
|
#include "Print.hpp"
|
||||||
#include "SupportMaterial.hpp"
|
#include "SupportMaterial.hpp"
|
||||||
#include "Fill/FillBase.hpp"
|
#include "Fill/FillBase.hpp"
|
||||||
|
#include "EdgeGrid.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -242,7 +243,10 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
|
||||||
|
|
||||||
// Determine the bottom contact surfaces of the supports over the top surfaces of the object.
|
// Determine the bottom contact surfaces of the supports over the top surfaces of the object.
|
||||||
// Depending on whether the support is soluble or not, the contact layer thickness is decided.
|
// Depending on whether the support is soluble or not, the contact layer thickness is decided.
|
||||||
MyLayersPtr bottom_contacts = this->bottom_contact_layers(object, top_contacts, layer_storage);
|
std::vector<Polygons> layer_support_areas;
|
||||||
|
MyLayersPtr bottom_contacts = this->bottom_contact_layers_and_layer_support_areas(
|
||||||
|
object, top_contacts, layer_storage,
|
||||||
|
layer_support_areas);
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(info) << "Support generator - Trimming top contacts by bottom contacts";
|
BOOST_LOG_TRIVIAL(info) << "Support generator - Trimming top contacts by bottom contacts";
|
||||||
|
|
||||||
|
@ -263,7 +267,7 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
|
||||||
BOOST_LOG_TRIVIAL(info) << "Support generator - Creating base layers";
|
BOOST_LOG_TRIVIAL(info) << "Support generator - Creating base layers";
|
||||||
|
|
||||||
// Fill in intermediate layers between the top / bottom support contact layers, trimmed by the object.
|
// Fill in intermediate layers between the top / bottom support contact layers, trimmed by the object.
|
||||||
this->generate_base_layers(object, bottom_contacts, top_contacts, intermediate_layers);
|
this->generate_base_layers(object, bottom_contacts, top_contacts, intermediate_layers, layer_support_areas);
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
for (MyLayersPtr::const_iterator it = intermediate_layers.begin(); it != intermediate_layers.end(); ++ it) {
|
for (MyLayersPtr::const_iterator it = intermediate_layers.begin(); it != intermediate_layers.end(); ++ it) {
|
||||||
|
@ -429,7 +433,8 @@ Polygons collect_slices_outer(const Layer &layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the top contact surfaces of the support or the raft.
|
// Find the top contact surfaces of the support or the raft.
|
||||||
PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_layers(const PrintObject &object, MyLayerStorage &layer_storage) const
|
PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_layers(
|
||||||
|
const PrintObject &object, MyLayerStorage &layer_storage) const
|
||||||
{
|
{
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
static int iRun = 0;
|
static int iRun = 0;
|
||||||
|
@ -744,12 +749,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
||||||
return contact_out;
|
return contact_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PointHash {
|
#if 0
|
||||||
size_t operator()(const Point &pt) const {
|
|
||||||
return std::hash<coord_t>()(pt.x) ^ std::hash<coord_t>()(pt.y);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::unordered_set<Point,PointHash> PointHashMap;
|
typedef std::unordered_set<Point,PointHash> PointHashMap;
|
||||||
|
|
||||||
void fillet(Polygon &poly, PointHashMap &new_points_hash_map)
|
void fillet(Polygon &poly, PointHashMap &new_points_hash_map)
|
||||||
|
@ -778,6 +778,35 @@ void fillet(Polygon &poly, PointHashMap &new_points_hash_map)
|
||||||
if (! has_some)
|
if (! has_some)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
static int iRun = 0;
|
||||||
|
++ iRun;
|
||||||
|
{
|
||||||
|
FILE *pfile = ::fopen(debug_out_path("fillet-in-%d.bin", iRun).c_str(), "wb");
|
||||||
|
size_t cnt = poly.points.size();
|
||||||
|
::fwrite(&cnt, 1, sizeof(cnt), pfile);
|
||||||
|
::fwrite(poly.points.data(), cnt, sizeof(Point), pfile);
|
||||||
|
cnt = new_points_hash_map.size();
|
||||||
|
::fwrite(&cnt, 1, sizeof(cnt), pfile);
|
||||||
|
for (PointHashMap::iterator it = new_points_hash_map.begin(); it != new_points_hash_map.end(); ++ it) {
|
||||||
|
const Point &pt = *it;
|
||||||
|
::fwrite(&pt, 1, sizeof(Point), pfile);
|
||||||
|
}
|
||||||
|
::fclose(pfile);
|
||||||
|
}
|
||||||
|
::Slic3r::SVG svg(debug_out_path("fillet-%d.svg", iRun), get_extents(poly));
|
||||||
|
svg.draw(poly, "black", scale_(0.05));
|
||||||
|
for (size_t i = 0; i < poly.points.size(); ++ i) {
|
||||||
|
const Point &pt1 = poly.points[i];
|
||||||
|
const Point &pt2 = poly.points[(i+1)%poly.points.size()];
|
||||||
|
if (new_points_hash_map.find(pt1) != new_points_hash_map.end())
|
||||||
|
svg.draw(Line(pt1, pt2), "red", scale_(0.035));
|
||||||
|
if (new_points_hash_map.find(pt1) != new_points_hash_map.end() &&
|
||||||
|
new_points_hash_map.find(pt2) != new_points_hash_map.end())
|
||||||
|
svg.draw(Line(pt1, pt2), "red", scale_(0.05));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Mark a range of points around the intersection points.
|
// Mark a range of points around the intersection points.
|
||||||
const double rounding_range = scale_(1.5);
|
const double rounding_range = scale_(1.5);
|
||||||
std::vector<Pointf> pts;
|
std::vector<Pointf> pts;
|
||||||
|
@ -795,7 +824,7 @@ void fillet(Polygon &poly, PointHashMap &new_points_hash_map)
|
||||||
if (d > rounding_range)
|
if (d > rounding_range)
|
||||||
break;
|
break;
|
||||||
point_flag[idx] |= 4;
|
point_flag[idx] |= 4;
|
||||||
pt = pt2;
|
//pt = pt2;
|
||||||
}
|
}
|
||||||
for (int j = 1; j < int(poly.points.size()); ++ j) {
|
for (int j = 1; j < int(poly.points.size()); ++ j) {
|
||||||
int idx = (i + int(poly.points.size()) - j) % poly.points.size();
|
int idx = (i + int(poly.points.size()) - j) % poly.points.size();
|
||||||
|
@ -804,7 +833,7 @@ void fillet(Polygon &poly, PointHashMap &new_points_hash_map)
|
||||||
if (d > rounding_range)
|
if (d > rounding_range)
|
||||||
break;
|
break;
|
||||||
point_flag[idx] |= 4;
|
point_flag[idx] |= 4;
|
||||||
pt = pt2;
|
//pt = pt2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pts.push_back(Pointf(poly.points[i].x, poly.points[i].y));
|
pts.push_back(Pointf(poly.points[i].x, poly.points[i].y));
|
||||||
|
@ -850,6 +879,10 @@ void fillet(Polygon &poly, PointHashMap &new_points_hash_map)
|
||||||
}
|
}
|
||||||
if (j < poly.points.size())
|
if (j < poly.points.size())
|
||||||
poly.points.erase(poly.points.begin() + j, poly.points.end());
|
poly.points.erase(poly.points.begin() + j, poly.points.end());
|
||||||
|
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
svg.draw_outline(poly, "blue", scale_(0.025));
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillet(Polygons &polygons, PointHashMap &new_points_hash_map)
|
void fillet(Polygons &polygons, PointHashMap &new_points_hash_map)
|
||||||
|
@ -858,19 +891,46 @@ void fillet(Polygons &polygons, PointHashMap &new_points_hash_map)
|
||||||
fillet(*it, new_points_hash_map);
|
fillet(*it, new_points_hash_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_contact_layers(
|
void union_and_fillet(Polygons &polygons, size_t n_polygons_old)
|
||||||
const PrintObject &object, const MyLayersPtr &top_contacts, MyLayerStorage &layer_storage) const
|
{
|
||||||
|
if (n_polygons_old == polygons.size())
|
||||||
|
// No new polygons.
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Fill in the new_points hash table with points of new contours.
|
||||||
|
PointHashMap new_points;
|
||||||
|
for (size_t i = n_polygons_old; i < polygons.size(); ++ i) {
|
||||||
|
const Polygon &poly = polygons[i];
|
||||||
|
for (size_t j = 0; j < poly.points.size(); ++ j)
|
||||||
|
new_points.insert(poly.points[j]);
|
||||||
|
}
|
||||||
|
// Merge the newly added regions. Don't use the safety offset, the offset has been added already.
|
||||||
|
polygons = union_(polygons, false);
|
||||||
|
// Fillet transition between the old and new points.
|
||||||
|
fillet(polygons, new_points);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Collect
|
||||||
|
PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_contact_layers_and_layer_support_areas(
|
||||||
|
const PrintObject &object, const MyLayersPtr &top_contacts, MyLayerStorage &layer_storage,
|
||||||
|
std::vector<Polygons> &layer_support_areas) const
|
||||||
{
|
{
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
static int iRun = 0;
|
static int iRun = 0;
|
||||||
++ iRun;
|
++ iRun;
|
||||||
#endif /* SLIC3R_DEBUG */
|
#endif /* SLIC3R_DEBUG */
|
||||||
|
|
||||||
|
// Allocate empty surface areas, one per object layer.
|
||||||
|
layer_support_areas.assign(object.total_layer_count(), Polygons());
|
||||||
|
|
||||||
// find object top surfaces
|
// find object top surfaces
|
||||||
// we'll use them to clip our support and detect where does it stick
|
// we'll use them to clip our support and detect where does it stick
|
||||||
MyLayersPtr bottom_contacts;
|
MyLayersPtr bottom_contacts;
|
||||||
if (! m_object_config->support_material_buildplate_only.value && ! top_contacts.empty())
|
|
||||||
|
if (! top_contacts.empty())
|
||||||
{
|
{
|
||||||
|
// There is some support to be built, if there are non-empty top surfaces detected.
|
||||||
// Sum of unsupported contact areas above the current layer.print_z.
|
// Sum of unsupported contact areas above the current layer.print_z.
|
||||||
Polygons projection;
|
Polygons projection;
|
||||||
// Last top contact layer visited when collecting the projection of contact areas.
|
// Last top contact layer visited when collecting the projection of contact areas.
|
||||||
|
@ -878,35 +938,35 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||||
for (int layer_id = int(object.total_layer_count()) - 2; layer_id >= 0; -- layer_id) {
|
for (int layer_id = int(object.total_layer_count()) - 2; layer_id >= 0; -- layer_id) {
|
||||||
BOOST_LOG_TRIVIAL(trace) << "Support generator - bottom_contact_layers - layer " << layer_id;
|
BOOST_LOG_TRIVIAL(trace) << "Support generator - bottom_contact_layers - layer " << layer_id;
|
||||||
const Layer &layer = *object.get_layer(layer_id);
|
const Layer &layer = *object.get_layer(layer_id);
|
||||||
Polygons top = collect_region_slices_by_type(layer, stTop);
|
// Top surfaces of this layer, to be used to stop the surface volume from growing down.
|
||||||
if (top.empty())
|
Polygons top;
|
||||||
continue;
|
if (! m_object_config->support_material_buildplate_only)
|
||||||
|
top = collect_region_slices_by_type(layer, stTop);
|
||||||
size_t projection_size_old = projection.size();
|
size_t projection_size_old = projection.size();
|
||||||
// Collect projections of all contact areas above or at the same level as this top surface.
|
// Collect projections of all contact areas above or at the same level as this top surface.
|
||||||
for (; contact_idx >= 0 && top_contacts[contact_idx]->print_z >= layer.print_z; -- contact_idx) {
|
for (; contact_idx >= 0 && top_contacts[contact_idx]->print_z >= layer.print_z; -- contact_idx) {
|
||||||
|
Polygons polygons_new;
|
||||||
// Contact surfaces are expanded away from the object, trimmed by the object.
|
// Contact surfaces are expanded away from the object, trimmed by the object.
|
||||||
// Use a slight positive offset to overlap the touching regions.
|
// Use a slight positive offset to overlap the touching regions.
|
||||||
polygons_append(projection, offset(top_contacts[contact_idx]->polygons, SCALED_EPSILON));
|
polygons_append(polygons_new, offset(top_contacts[contact_idx]->polygons, SCALED_EPSILON));
|
||||||
|
size_t size1 = polygons_new.size();
|
||||||
// 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(projection, offset(*top_contacts[contact_idx]->aux_polygons, SCALED_EPSILON));
|
polygons_append(polygons_new, offset(*top_contacts[contact_idx]->aux_polygons, SCALED_EPSILON));
|
||||||
|
#if 0
|
||||||
|
union_and_fillet(polygons_new, size1);
|
||||||
|
#else
|
||||||
|
union_(polygons_new);
|
||||||
|
#endif
|
||||||
|
polygons_append(projection, std::move(polygons_new));
|
||||||
}
|
}
|
||||||
if (projection.empty())
|
if (projection.empty())
|
||||||
continue;
|
continue;
|
||||||
if (projection_size_old < projection.size()) {
|
#if 0
|
||||||
// Fill in the new_points hash table with points of new contours.
|
union_and_fillet(projection, projection_size_old);
|
||||||
PointHashMap new_points;
|
#else
|
||||||
for (size_t i = projection_size_old; i < projection.size(); ++ i) {
|
union_(projection);
|
||||||
const Polygon &poly = projection[i];
|
#endif
|
||||||
for (size_t j = 0; j < poly.points.size(); ++ j)
|
|
||||||
new_points.insert(poly.points[j]);
|
|
||||||
}
|
|
||||||
// Merge the newly added regions. Don't use the safety offset, the offset has been added already.
|
|
||||||
projection = union_(projection, false);
|
|
||||||
// Fillet transition between the old and new points.
|
|
||||||
fillet(projection, new_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
{
|
{
|
||||||
BoundingBox bbox = get_extents(projection);
|
BoundingBox bbox = get_extents(projection);
|
||||||
|
@ -922,9 +982,9 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||||
// top surfaces above layer.print_z falls onto this top surface.
|
// top surfaces above layer.print_z falls onto this top surface.
|
||||||
// touching are the contact surfaces supported exclusively by this top surfaaces.
|
// touching are the contact surfaces supported exclusively by this top surfaaces.
|
||||||
// Don't use a safety offset as it has been applied during insertion of polygons.
|
// Don't use a safety offset as it has been applied during insertion of polygons.
|
||||||
|
if (! top.empty()) {
|
||||||
Polygons touching = intersection(top, projection, false);
|
Polygons touching = intersection(top, projection, false);
|
||||||
if (touching.empty())
|
if (! touching.empty()) {
|
||||||
continue;
|
|
||||||
// Allocate a new bottom contact layer.
|
// Allocate a new bottom contact layer.
|
||||||
MyLayer &layer_new = layer_allocate(layer_storage, sltBottomContact);
|
MyLayer &layer_new = layer_allocate(layer_storage, sltBottomContact);
|
||||||
bottom_contacts.push_back(&layer_new);
|
bottom_contacts.push_back(&layer_new);
|
||||||
|
@ -943,10 +1003,6 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||||
layer_new.bridging = ! m_soluble_interface;
|
layer_new.bridging = ! m_soluble_interface;
|
||||||
//FIXME how much to inflate the top surface?
|
//FIXME how much to inflate the top surface?
|
||||||
layer_new.polygons = offset(touching, float(m_support_material_flow.scaled_width()));
|
layer_new.polygons = offset(touching, float(m_support_material_flow.scaled_width()));
|
||||||
// Remove the areas that touched from the projection that will continue on next, lower, top surfaces.
|
|
||||||
// projection = diff(projection, touching);
|
|
||||||
projection = diff(projection, to_polygons(layer.slices.expolygons), true);
|
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
{
|
{
|
||||||
::Slic3r::SVG svg(debug_out_path("support-bottom-contacts-%d-%lf.svg", iRun, layer_new.print_z), get_extents(layer_new.polygons));
|
::Slic3r::SVG svg(debug_out_path("support-bottom-contacts-%d-%lf.svg", iRun, layer_new.print_z), get_extents(layer_new.polygons));
|
||||||
|
@ -955,9 +1011,42 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||||
}
|
}
|
||||||
#endif /* SLIC3R_DEBUG */
|
#endif /* SLIC3R_DEBUG */
|
||||||
}
|
}
|
||||||
|
} // ! top.empty()
|
||||||
|
|
||||||
|
remove_sticks(projection);
|
||||||
|
remove_degenerate(projection);
|
||||||
|
|
||||||
|
// Create an EdgeGrid, initialize it with projection, initialize signed distance field.
|
||||||
|
Slic3r::EdgeGrid::Grid grid;
|
||||||
|
coord_t grid_resolution = scale_(1.5f);
|
||||||
|
BoundingBox bbox = get_extents(projection);
|
||||||
|
bbox.offset(20);
|
||||||
|
bbox.align_to_grid(grid_resolution);
|
||||||
|
grid.set_bbox(bbox);
|
||||||
|
grid.create(projection, grid_resolution);
|
||||||
|
grid.calculate_sdf();
|
||||||
|
|
||||||
|
// Extract a bounding contour from the grid.
|
||||||
|
Polygons projection_simplified = grid.contours_simplified();
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
{
|
||||||
|
BoundingBox bbox = get_extents(projection);
|
||||||
|
bbox.merge(get_extents(projection_simplified));
|
||||||
|
|
||||||
|
::Slic3r::SVG svg(debug_out_path("support-bottom-contacts-simplified-%d-%d.svg", iRun, layer_id), bbox);
|
||||||
|
svg.draw(union_ex(projection, false), "blue", 0.5);
|
||||||
|
svg.draw(union_ex(projection_simplified, false), "red", 0.5);
|
||||||
|
}
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
|
projection = std::move(projection_simplified);
|
||||||
|
|
||||||
|
// Remove the areas that touched from the projection that will continue on next, lower, top surfaces.
|
||||||
|
// projection = diff(projection, touching);
|
||||||
|
projection = diff(projection, to_polygons(layer.slices.expolygons), true);
|
||||||
|
layer_support_areas[layer_id] = projection;
|
||||||
|
}
|
||||||
std::reverse(bottom_contacts.begin(), bottom_contacts.end());
|
std::reverse(bottom_contacts.begin(), bottom_contacts.end());
|
||||||
} // if (! m_object_config->support_material_buildplate_only.value && ! top_contacts.empty())
|
} // ! top_contacts.empty()
|
||||||
|
|
||||||
return bottom_contacts;
|
return bottom_contacts;
|
||||||
}
|
}
|
||||||
|
@ -1093,7 +1182,8 @@ void PrintObjectSupportMaterial::generate_base_layers(
|
||||||
const PrintObject &object,
|
const PrintObject &object,
|
||||||
const MyLayersPtr &bottom_contacts,
|
const MyLayersPtr &bottom_contacts,
|
||||||
const MyLayersPtr &top_contacts,
|
const MyLayersPtr &top_contacts,
|
||||||
MyLayersPtr &intermediate_layers) const
|
MyLayersPtr &intermediate_layers,
|
||||||
|
std::vector<Polygons> &layer_support_areas) const
|
||||||
{
|
{
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
static int iRun = 0;
|
static int iRun = 0;
|
||||||
|
@ -1106,23 +1196,48 @@ void PrintObjectSupportMaterial::generate_base_layers(
|
||||||
// coordf_t fillet_radius_scaled = scale_(m_object_config->support_material_spacing);
|
// coordf_t fillet_radius_scaled = scale_(m_object_config->support_material_spacing);
|
||||||
int idx_top_contact_above = int(top_contacts.size()) - 1;
|
int idx_top_contact_above = int(top_contacts.size()) - 1;
|
||||||
int idx_bottom_contact_overlapping = int(bottom_contacts.size()) - 1;
|
int idx_bottom_contact_overlapping = int(bottom_contacts.size()) - 1;
|
||||||
|
int idx_object_layer_above = int(object.total_layer_count()) - 1;
|
||||||
for (int idx_intermediate = int(intermediate_layers.size()) - 1; idx_intermediate >= 0; -- idx_intermediate)
|
for (int idx_intermediate = int(intermediate_layers.size()) - 1; idx_intermediate >= 0; -- idx_intermediate)
|
||||||
{
|
{
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Support generator - generate_base_layers - creating layer " <<
|
||||||
|
idx_intermediate << " of " << intermediate_layers.size();
|
||||||
MyLayer &layer_intermediate = *intermediate_layers[idx_intermediate];
|
MyLayer &layer_intermediate = *intermediate_layers[idx_intermediate];
|
||||||
|
|
||||||
// New polygons for layer_intermediate.
|
|
||||||
Polygons polygons_new;
|
|
||||||
|
|
||||||
// Find a top_contact layer touching the layer_intermediate from above, if any, and collect its polygons into polygons_new.
|
// Find a top_contact layer touching the layer_intermediate from above, if any, and collect its polygons into polygons_new.
|
||||||
while (idx_top_contact_above >= 0 && top_contacts[idx_top_contact_above]->bottom_z > layer_intermediate.print_z + EPSILON)
|
while (idx_top_contact_above >= 0 && top_contacts[idx_top_contact_above]->bottom_z > layer_intermediate.print_z + EPSILON)
|
||||||
-- idx_top_contact_above;
|
-- idx_top_contact_above;
|
||||||
if (idx_top_contact_above >= 0 && top_contacts[idx_top_contact_above]->print_z > layer_intermediate.print_z)
|
|
||||||
polygons_append(polygons_new, top_contacts[idx_top_contact_above]->polygons);
|
|
||||||
|
|
||||||
|
// New polygons for layer_intermediate.
|
||||||
|
Polygons polygons_new;
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Add polygons projected from the intermediate layer above.
|
// Add polygons projected from the intermediate layer above.
|
||||||
if (idx_intermediate + 1 < int(intermediate_layers.size()))
|
if (idx_intermediate + 1 < int(intermediate_layers.size()))
|
||||||
polygons_append(polygons_new, intermediate_layers[idx_intermediate+1]->polygons);
|
polygons_append(polygons_new, intermediate_layers[idx_intermediate+1]->polygons);
|
||||||
|
|
||||||
|
if (idx_top_contact_above >= 0 && top_contacts[idx_top_contact_above]->print_z > layer_intermediate.print_z) {
|
||||||
|
// Contact surfaces are expanded away from the object, trimmed by the object.
|
||||||
|
// Use a slight positive offset to overlap the touching regions.
|
||||||
|
Polygons polygons_new2;
|
||||||
|
polygons_append(polygons_new2, offset(top_contacts[idx_top_contact_above]->polygons, SCALED_EPSILON));
|
||||||
|
size_t size2 = polygons_new2.size();
|
||||||
|
// 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.
|
||||||
|
polygons_append(polygons_new2, offset(*top_contacts[idx_top_contact_above]->aux_polygons, SCALED_EPSILON));
|
||||||
|
union_and_fillet(polygons_new2, size2);
|
||||||
|
if (! polygons_new2.empty()) {
|
||||||
|
size_t polygons_size_old = polygons_new.size();
|
||||||
|
polygons_append(polygons_new, std::move(polygons_new2));
|
||||||
|
union_and_fillet(polygons_new, polygons_size_old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Use the precomputed layer_support_areas.
|
||||||
|
while (idx_object_layer_above > 0 && object.get_layer(idx_object_layer_above - 1)->print_z > layer_intermediate.print_z - EPSILON)
|
||||||
|
-- idx_object_layer_above;
|
||||||
|
polygons_new = layer_support_areas[idx_object_layer_above];
|
||||||
|
#endif
|
||||||
|
|
||||||
// Polygons to trim polygons_new.
|
// Polygons to trim polygons_new.
|
||||||
Polygons polygons_trimming;
|
Polygons polygons_trimming;
|
||||||
|
|
||||||
|
@ -1145,7 +1260,7 @@ void PrintObjectSupportMaterial::generate_base_layers(
|
||||||
-- idx_bottom_contact_overlapping;
|
-- idx_bottom_contact_overlapping;
|
||||||
// Collect all the top_contact layer intersecting with this layer.
|
// Collect all the top_contact layer intersecting with this layer.
|
||||||
for (int i = idx_bottom_contact_overlapping; i >= 0; -- i) {
|
for (int i = idx_bottom_contact_overlapping; i >= 0; -- i) {
|
||||||
MyLayer &layer_bottom_overlapping = *bottom_contacts[idx_bottom_contact_overlapping];
|
MyLayer &layer_bottom_overlapping = *bottom_contacts[i];
|
||||||
if (layer_bottom_overlapping.print_z < layer_intermediate.print_z - layer_intermediate.height + EPSILON)
|
if (layer_bottom_overlapping.print_z < layer_intermediate.print_z - layer_intermediate.height + EPSILON)
|
||||||
break;
|
break;
|
||||||
polygons_append(polygons_trimming, layer_bottom_overlapping.polygons);
|
polygons_append(polygons_trimming, layer_bottom_overlapping.polygons);
|
||||||
|
@ -1203,6 +1318,9 @@ void PrintObjectSupportMaterial::generate_base_layers(
|
||||||
size_t idx_object_layer_overlapping = 0;
|
size_t idx_object_layer_overlapping = 0;
|
||||||
// For all intermediate support layers:
|
// For all intermediate support layers:
|
||||||
for (MyLayersPtr::iterator it_layer = intermediate_layers.begin(); it_layer != intermediate_layers.end(); ++ it_layer) {
|
for (MyLayersPtr::iterator it_layer = intermediate_layers.begin(); it_layer != intermediate_layers.end(); ++ it_layer) {
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Support generator - generate_base_layers - trimmming layer " <<
|
||||||
|
(it_layer - intermediate_layers.begin()) << " of " << intermediate_layers.size();
|
||||||
|
|
||||||
MyLayer &layer_intermediate = *(*it_layer);
|
MyLayer &layer_intermediate = *(*it_layer);
|
||||||
if (layer_intermediate.polygons.empty())
|
if (layer_intermediate.polygons.empty())
|
||||||
// Empty support layer, nothing to trim.
|
// Empty support layer, nothing to trim.
|
||||||
|
|
|
@ -163,7 +163,9 @@ private:
|
||||||
// Generate bottom contact layers supporting the top contact layers.
|
// Generate bottom contact layers supporting the top contact layers.
|
||||||
// For a soluble interface material synchronize the layer heights with the object,
|
// For a soluble interface material synchronize the layer heights with the object,
|
||||||
// otherwise set the layer height to a bridging flow of a support interface nozzle.
|
// otherwise set the layer height to a bridging flow of a support interface nozzle.
|
||||||
MyLayersPtr bottom_contact_layers(const PrintObject &object, const MyLayersPtr &top_contacts, MyLayerStorage &layer_storage) const;
|
MyLayersPtr bottom_contact_layers_and_layer_support_areas(
|
||||||
|
const PrintObject &object, const MyLayersPtr &top_contacts, MyLayerStorage &layer_storage,
|
||||||
|
std::vector<Polygons> &layer_support_areas) const;
|
||||||
|
|
||||||
// Trim the top_contacts layers with the bottom_contacts layers if they overlap, so there would not be enough vertical space for both of them.
|
// Trim the top_contacts layers with the bottom_contacts layers if they overlap, so there would not be enough vertical space for both of them.
|
||||||
void trim_top_contacts_by_bottom_contacts(const PrintObject &object, const MyLayersPtr &bottom_contacts, MyLayersPtr &top_contacts) const;
|
void trim_top_contacts_by_bottom_contacts(const PrintObject &object, const MyLayersPtr &bottom_contacts, MyLayersPtr &top_contacts) const;
|
||||||
|
@ -180,7 +182,8 @@ private:
|
||||||
const PrintObject &object,
|
const PrintObject &object,
|
||||||
const MyLayersPtr &bottom_contacts,
|
const MyLayersPtr &bottom_contacts,
|
||||||
const MyLayersPtr &top_contacts,
|
const MyLayersPtr &top_contacts,
|
||||||
MyLayersPtr &intermediate_layers) const;
|
MyLayersPtr &intermediate_layers,
|
||||||
|
std::vector<Polygons> &layer_support_areas) const;
|
||||||
|
|
||||||
Polygons generate_raft_base(
|
Polygons generate_raft_base(
|
||||||
const PrintObject &object,
|
const PrintObject &object,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue