Fix of "Supports not generating interface layers" #1306
Fix of "Spurious support interfaces" #1309
This commit is contained in:
parent
b8c2566c44
commit
eb59568368
@ -9,7 +9,9 @@
|
|||||||
#endif /* SLIC3R_GUI */
|
#endif /* SLIC3R_GUI */
|
||||||
|
|
||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
|
#include "ClipperUtils.hpp"
|
||||||
#include "EdgeGrid.hpp"
|
#include "EdgeGrid.hpp"
|
||||||
|
#include "SVG.hpp"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Enable debugging and assert in this file.
|
// Enable debugging and assert in this file.
|
||||||
@ -756,8 +758,8 @@ void EdgeGrid::Grid::calculate_sdf()
|
|||||||
float search_radius = float(m_resolution<<1);
|
float search_radius = float(m_resolution<<1);
|
||||||
m_signed_distance_field.assign(nrows * ncols, search_radius);
|
m_signed_distance_field.assign(nrows * ncols, search_radius);
|
||||||
// For each cell:
|
// For each cell:
|
||||||
for (size_t r = 0; r < m_rows; ++ r) {
|
for (int r = 0; r < (int)m_rows; ++ r) {
|
||||||
for (size_t c = 0; c < m_cols; ++ c) {
|
for (int c = 0; c < (int)m_cols; ++ c) {
|
||||||
const Cell &cell = m_cells[r * m_cols + c];
|
const Cell &cell = m_cells[r * m_cols + c];
|
||||||
// For each segment in the cell:
|
// For each segment in the cell:
|
||||||
for (size_t i = cell.begin; i != cell.end; ++ i) {
|
for (size_t i = cell.begin; i != cell.end; ++ i) {
|
||||||
@ -842,6 +844,8 @@ void EdgeGrid::Grid::calculate_sdf()
|
|||||||
#if 0
|
#if 0
|
||||||
static int iRun = 0;
|
static int iRun = 0;
|
||||||
++ iRun;
|
++ iRun;
|
||||||
|
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
|
||||||
|
wxImage::AddHandler(new wxPNGHandler);
|
||||||
//#ifdef SLIC3R_GUI
|
//#ifdef SLIC3R_GUI
|
||||||
{
|
{
|
||||||
wxImage img(ncols, nrows);
|
wxImage img(ncols, nrows);
|
||||||
@ -1356,9 +1360,101 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset, bool fill_holes) co
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int segments_could_intersect(
|
||||||
|
const Slic3r::Point &ip1, const Slic3r::Point &ip2,
|
||||||
|
const Slic3r::Point &jp1, const Slic3r::Point &jp2)
|
||||||
|
{
|
||||||
|
Slic3r::Point iv = ip1.vector_to(ip2);
|
||||||
|
Slic3r::Point vij1 = ip1.vector_to(jp1);
|
||||||
|
Slic3r::Point vij2 = ip1.vector_to(jp2);
|
||||||
|
int64_t tij1 = int64_t(iv.x) * int64_t(vij1.y) - int64_t(iv.y) * int64_t(vij1.x); // cross(iv, vij1)
|
||||||
|
int64_t tij2 = int64_t(iv.x) * int64_t(vij2.y) - int64_t(iv.y) * int64_t(vij2.x); // cross(iv, vij2)
|
||||||
|
int sij1 = (tij1 > 0) ? 1 : ((tij1 < 0) ? -1 : 0); // signum
|
||||||
|
int sij2 = (tij2 > 0) ? 1 : ((tij2 < 0) ? -1 : 0);
|
||||||
|
return sij1 * sij2;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool segments_intersect(
|
||||||
|
const Slic3r::Point &ip1, const Slic3r::Point &ip2,
|
||||||
|
const Slic3r::Point &jp1, const Slic3r::Point &jp2)
|
||||||
|
{
|
||||||
|
return segments_could_intersect(ip1, ip2, jp1, jp2) <= 0 &&
|
||||||
|
segments_could_intersect(jp1, jp2, ip1, ip2) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>> EdgeGrid::Grid::intersecting_edges() const
|
||||||
|
{
|
||||||
|
std::vector<std::pair<ContourEdge, ContourEdge>> out;
|
||||||
|
// For each cell:
|
||||||
|
for (int r = 0; r < (int)m_rows; ++ r) {
|
||||||
|
for (int c = 0; c < (int)m_cols; ++ c) {
|
||||||
|
const Cell &cell = m_cells[r * m_cols + c];
|
||||||
|
// For each pair of segments in the cell:
|
||||||
|
for (size_t i = cell.begin; i != cell.end; ++ i) {
|
||||||
|
const Slic3r::Points &ipts = *m_contours[m_cell_data[i].first];
|
||||||
|
size_t ipt = m_cell_data[i].second;
|
||||||
|
// End points of the line segment and their vector.
|
||||||
|
const Slic3r::Point &ip1 = ipts[ipt];
|
||||||
|
const Slic3r::Point &ip2 = ipts[(ipt + 1 == ipts.size()) ? 0 : ipt + 1];
|
||||||
|
for (size_t j = i + 1; j != cell.end; ++ j) {
|
||||||
|
const Slic3r::Points &jpts = *m_contours[m_cell_data[j].first];
|
||||||
|
size_t jpt = m_cell_data[j].second;
|
||||||
|
// End points of the line segment and their vector.
|
||||||
|
const Slic3r::Point &jp1 = jpts[jpt];
|
||||||
|
const Slic3r::Point &jp2 = jpts[(jpt + 1 == jpts.size()) ? 0 : jpt + 1];
|
||||||
|
if (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2))
|
||||||
|
// Segments of the same contour share a common vertex.
|
||||||
|
continue;
|
||||||
|
if (segments_intersect(ip1, ip2, jp1, jp2)) {
|
||||||
|
// The two segments intersect. Add them to the output.
|
||||||
|
int jfirst = (&jpts < &ipts) || (&jpts == &ipts && jpt < ipt);
|
||||||
|
out.emplace_back(jfirst ?
|
||||||
|
std::make_pair(std::make_pair(&ipts, ipt), std::make_pair(&jpts, jpt)) :
|
||||||
|
std::make_pair(std::make_pair(&ipts, ipt), std::make_pair(&jpts, jpt)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Slic3r::sort_remove_duplicates(out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EdgeGrid::Grid::has_intersecting_edges() const
|
||||||
|
{
|
||||||
|
// For each cell:
|
||||||
|
for (int r = 0; r < (int)m_rows; ++ r) {
|
||||||
|
for (int c = 0; c < (int)m_cols; ++ c) {
|
||||||
|
const Cell &cell = m_cells[r * m_cols + c];
|
||||||
|
// For each pair of segments in the cell:
|
||||||
|
for (size_t i = cell.begin; i != cell.end; ++ i) {
|
||||||
|
const Slic3r::Points &ipts = *m_contours[m_cell_data[i].first];
|
||||||
|
size_t ipt = m_cell_data[i].second;
|
||||||
|
// End points of the line segment and their vector.
|
||||||
|
const Slic3r::Point &ip1 = ipts[ipt];
|
||||||
|
const Slic3r::Point &ip2 = ipts[(ipt + 1 == ipts.size()) ? 0 : ipt + 1];
|
||||||
|
for (size_t j = i + 1; j != cell.end; ++ j) {
|
||||||
|
const Slic3r::Points &jpts = *m_contours[m_cell_data[j].first];
|
||||||
|
size_t jpt = m_cell_data[j].second;
|
||||||
|
// End points of the line segment and their vector.
|
||||||
|
const Slic3r::Point &jp1 = jpts[jpt];
|
||||||
|
const Slic3r::Point &jp2 = jpts[(jpt + 1 == jpts.size()) ? 0 : jpt + 1];
|
||||||
|
if (! (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2)) &&
|
||||||
|
segments_intersect(ip1, ip2, jp1, jp2))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coord_t resolution, const char *path)
|
void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coord_t resolution, const char *path)
|
||||||
{
|
{
|
||||||
|
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
|
||||||
|
wxImage::AddHandler(new wxPNGHandler);
|
||||||
|
|
||||||
unsigned int w = (bbox.max.x - bbox.min.x + resolution - 1) / resolution;
|
unsigned int w = (bbox.max.x - bbox.min.x + resolution - 1) / resolution;
|
||||||
unsigned int h = (bbox.max.y - bbox.min.y + resolution - 1) / resolution;
|
unsigned int h = (bbox.max.y - bbox.min.y + resolution - 1) / resolution;
|
||||||
wxImage img(w, h);
|
wxImage img(w, h);
|
||||||
@ -1450,4 +1546,59 @@ void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coo
|
|||||||
}
|
}
|
||||||
#endif /* SLIC3R_GUI */
|
#endif /* SLIC3R_GUI */
|
||||||
|
|
||||||
|
// Find all pairs of intersectiong edges from the set of polygons.
|
||||||
|
std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>> intersecting_edges(const Polygons &polygons)
|
||||||
|
{
|
||||||
|
double len = 0;
|
||||||
|
size_t cnt = 0;
|
||||||
|
BoundingBox bbox;
|
||||||
|
for (const Polygon &poly : polygons) {
|
||||||
|
if (poly.points.size() < 2)
|
||||||
|
continue;
|
||||||
|
for (size_t i = 0; i < poly.points.size(); ++ i) {
|
||||||
|
bbox.merge(poly.points[i]);
|
||||||
|
size_t j = (i == 0) ? (poly.points.size() - 1) : i - 1;
|
||||||
|
len += poly.points[i].distance_to(poly.points[j]);
|
||||||
|
++ cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
len /= double(cnt);
|
||||||
|
bbox.offset(20);
|
||||||
|
EdgeGrid::Grid grid;
|
||||||
|
grid.set_bbox(bbox);
|
||||||
|
grid.create(polygons, len);
|
||||||
|
return grid.intersecting_edges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all pairs of intersectiong edges from the set of polygons, highlight them in an SVG.
|
||||||
|
void export_intersections_to_svg(const std::string &filename, const Polygons &polygons)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>> intersections = intersecting_edges(polygons);
|
||||||
|
BoundingBox bbox = get_extents(polygons);
|
||||||
|
SVG svg(filename.c_str(), bbox);
|
||||||
|
svg.draw(union_ex(polygons), "gray", 0.25f);
|
||||||
|
svg.draw_outline(polygons, "black");
|
||||||
|
std::set<const Points*> intersecting_contours;
|
||||||
|
for (const std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge> &ie : intersections) {
|
||||||
|
intersecting_contours.insert(ie.first.first);
|
||||||
|
intersecting_contours.insert(ie.second.first);
|
||||||
|
}
|
||||||
|
// Highlight the contours with intersections.
|
||||||
|
coord_t line_width = coord_t(scale_(0.01));
|
||||||
|
for (const Points *ic : intersecting_contours) {
|
||||||
|
svg.draw_outline(Polygon(*ic), "green");
|
||||||
|
svg.draw_outline(Polygon(*ic), "black", line_width);
|
||||||
|
}
|
||||||
|
// Paint the intersections.
|
||||||
|
for (const std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge> &intersecting_edges : intersections) {
|
||||||
|
auto edge = [](const EdgeGrid::Grid::ContourEdge &e) {
|
||||||
|
return Line(e.first->at(e.second),
|
||||||
|
e.first->at((e.second + 1 == e.first->size()) ? 0 : e.second + 1));
|
||||||
|
};
|
||||||
|
svg.draw(edge(intersecting_edges.first), "red", line_width);
|
||||||
|
svg.draw(edge(intersecting_edges.second), "red", line_width);
|
||||||
|
}
|
||||||
|
svg.Close();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -60,6 +60,11 @@ public:
|
|||||||
// For supports: Contours enclosing the rasterized edges.
|
// For supports: Contours enclosing the rasterized edges.
|
||||||
Polygons contours_simplified(coord_t offset, bool fill_holes) const;
|
Polygons contours_simplified(coord_t offset, bool fill_holes) const;
|
||||||
|
|
||||||
|
typedef std::pair<const Slic3r::Points*, size_t> ContourPoint;
|
||||||
|
typedef std::pair<const Slic3r::Points*, size_t> ContourEdge;
|
||||||
|
std::vector<std::pair<ContourEdge, ContourEdge>> intersecting_edges() const;
|
||||||
|
bool has_intersecting_edges() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Cell {
|
struct Cell {
|
||||||
Cell() : begin(0), end(0) {}
|
Cell() : begin(0), end(0) {}
|
||||||
@ -113,6 +118,13 @@ extern void save_png(const Grid &grid, const BoundingBox &bbox, coord_t resoluti
|
|||||||
#endif /* SLIC3R_GUI */
|
#endif /* SLIC3R_GUI */
|
||||||
|
|
||||||
} // namespace EdgeGrid
|
} // namespace EdgeGrid
|
||||||
|
|
||||||
|
// Find all pairs of intersectiong edges from the set of polygons.
|
||||||
|
extern std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>> intersecting_edges(const Polygons &polygons);
|
||||||
|
|
||||||
|
// Find all pairs of intersectiong edges from the set of polygons, highlight them in an SVG.
|
||||||
|
extern void export_intersections_to_svg(const std::string &filename, const Polygons &polygons);
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif /* slic3r_EdgeGrid_hpp_ */
|
#endif /* slic3r_EdgeGrid_hpp_ */
|
||||||
|
@ -458,6 +458,8 @@ Polygons collect_slices_outer(const Layer &layer)
|
|||||||
class SupportGridPattern
|
class SupportGridPattern
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Achtung! The support_polygons need to be trimmed by trimming_polygons, otherwise
|
||||||
|
// the selection by island_samples (see the island_samples() method) will not work!
|
||||||
SupportGridPattern(
|
SupportGridPattern(
|
||||||
// Support islands, to be stretched into a grid. Already trimmed with min(lower_layer_offset, m_gap_xy)
|
// Support islands, to be stretched into a grid. Already trimmed with min(lower_layer_offset, m_gap_xy)
|
||||||
const Polygons &support_polygons,
|
const Polygons &support_polygons,
|
||||||
@ -485,6 +487,18 @@ public:
|
|||||||
bbox.align_to_grid(grid_resolution);
|
bbox.align_to_grid(grid_resolution);
|
||||||
m_grid.set_bbox(bbox);
|
m_grid.set_bbox(bbox);
|
||||||
m_grid.create(*m_support_polygons, grid_resolution);
|
m_grid.create(*m_support_polygons, grid_resolution);
|
||||||
|
#if 0
|
||||||
|
if (m_grid.has_intersecting_edges()) {
|
||||||
|
// EdgeGrid fails to produce valid signed distance function for self-intersecting polygons.
|
||||||
|
m_support_polygons_rotated = simplify_polygons(*m_support_polygons);
|
||||||
|
m_support_polygons = &m_support_polygons_rotated;
|
||||||
|
m_grid.set_bbox(bbox);
|
||||||
|
m_grid.create(*m_support_polygons, grid_resolution);
|
||||||
|
// assert(! m_grid.has_intersecting_edges());
|
||||||
|
printf("SupportGridPattern: fixing polygons with intersection %s\n",
|
||||||
|
m_grid.has_intersecting_edges() ? "FAILED" : "SUCCEEDED");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
m_grid.calculate_sdf();
|
m_grid.calculate_sdf();
|
||||||
// Sample a single point per input support polygon, keep it as a reference to maintain corresponding
|
// Sample a single point per input support polygon, keep it as a reference to maintain corresponding
|
||||||
// polygons if ever these polygons get split into parts by the trimming polygons.
|
// polygons if ever these polygons get split into parts by the trimming polygons.
|
||||||
@ -499,9 +513,12 @@ public:
|
|||||||
{
|
{
|
||||||
// Generate islands, so each island may be tested for overlap with m_island_samples.
|
// Generate islands, so each island may be tested for overlap with m_island_samples.
|
||||||
assert(std::abs(2 * offset_in_grid) < m_grid.resolution());
|
assert(std::abs(2 * offset_in_grid) < m_grid.resolution());
|
||||||
ExPolygons islands = diff_ex(
|
#ifdef SLIC3R_DEBUG
|
||||||
m_grid.contours_simplified(offset_in_grid, fill_holes),
|
Polygons support_polygons_simplified = m_grid.contours_simplified(offset_in_grid, fill_holes);
|
||||||
*m_trimming_polygons, false);
|
ExPolygons islands = diff_ex(support_polygons_simplified, *m_trimming_polygons, false);
|
||||||
|
#else
|
||||||
|
ExPolygons islands = diff_ex(m_grid.contours_simplified(offset_in_grid, fill_holes), *m_trimming_polygons, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Extract polygons, which contain some of the m_island_samples.
|
// Extract polygons, which contain some of the m_island_samples.
|
||||||
Polygons out;
|
Polygons out;
|
||||||
@ -551,7 +568,10 @@ public:
|
|||||||
bbox.merge(get_extents(islands));
|
bbox.merge(get_extents(islands));
|
||||||
if (!out.empty())
|
if (!out.empty())
|
||||||
bbox.merge(get_extents(out));
|
bbox.merge(get_extents(out));
|
||||||
|
if (!support_polygons_simplified.empty())
|
||||||
|
bbox.merge(get_extents(support_polygons_simplified));
|
||||||
SVG svg(debug_out_path("extract_support_from_grid_trimmed-%d.svg", iRun).c_str(), bbox);
|
SVG svg(debug_out_path("extract_support_from_grid_trimmed-%d.svg", iRun).c_str(), bbox);
|
||||||
|
svg.draw(union_ex(support_polygons_simplified), "gray", 0.25f);
|
||||||
svg.draw(islands, "red", 0.5f);
|
svg.draw(islands, "red", 0.5f);
|
||||||
svg.draw(union_ex(out), "green", 0.5f);
|
svg.draw(union_ex(out), "green", 0.5f);
|
||||||
svg.draw(union_ex(*m_support_polygons), "blue", 0.5f);
|
svg.draw(union_ex(*m_support_polygons), "blue", 0.5f);
|
||||||
@ -568,7 +588,121 @@ public:
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
void serialize(const std::string &path)
|
||||||
|
{
|
||||||
|
FILE *file = ::fopen(path.c_str(), "wb");
|
||||||
|
::fwrite(&m_support_spacing, 8, 1, file);
|
||||||
|
::fwrite(&m_support_angle, 8, 1, file);
|
||||||
|
uint32_t n_polygons = m_support_polygons->size();
|
||||||
|
::fwrite(&n_polygons, 4, 1, file);
|
||||||
|
for (uint32_t i = 0; i < n_polygons; ++ i) {
|
||||||
|
const Polygon &poly = (*m_support_polygons)[i];
|
||||||
|
uint32_t n_points = poly.size();
|
||||||
|
::fwrite(&n_points, 4, 1, file);
|
||||||
|
for (uint32_t j = 0; j < n_points; ++ j) {
|
||||||
|
const Point &pt = poly.points[j];
|
||||||
|
::fwrite(&pt.x, sizeof(coord_t), 1, file);
|
||||||
|
::fwrite(&pt.y, sizeof(coord_t), 1, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n_polygons = m_trimming_polygons->size();
|
||||||
|
::fwrite(&n_polygons, 4, 1, file);
|
||||||
|
for (uint32_t i = 0; i < n_polygons; ++ i) {
|
||||||
|
const Polygon &poly = (*m_trimming_polygons)[i];
|
||||||
|
uint32_t n_points = poly.size();
|
||||||
|
::fwrite(&n_points, 4, 1, file);
|
||||||
|
for (uint32_t j = 0; j < n_points; ++ j) {
|
||||||
|
const Point &pt = poly.points[j];
|
||||||
|
::fwrite(&pt.x, sizeof(coord_t), 1, file);
|
||||||
|
::fwrite(&pt.y, sizeof(coord_t), 1, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SupportGridPattern deserialize(const std::string &path, int which = -1)
|
||||||
|
{
|
||||||
|
SupportGridPattern out;
|
||||||
|
out.deserialize_(path, which);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialization constructor
|
||||||
|
bool deserialize_(const std::string &path, int which = -1)
|
||||||
|
{
|
||||||
|
FILE *file = ::fopen(path.c_str(), "rb");
|
||||||
|
if (file == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_support_polygons = &m_support_polygons_deserialized;
|
||||||
|
m_trimming_polygons = &m_trimming_polygons_deserialized;
|
||||||
|
|
||||||
|
::fread(&m_support_spacing, 8, 1, file);
|
||||||
|
::fread(&m_support_angle, 8, 1, file);
|
||||||
|
//FIXME
|
||||||
|
//m_support_spacing *= 0.01 / 2;
|
||||||
|
uint32_t n_polygons;
|
||||||
|
::fread(&n_polygons, 4, 1, file);
|
||||||
|
m_support_polygons_deserialized.reserve(n_polygons);
|
||||||
|
int32_t scale = 1;
|
||||||
|
for (uint32_t i = 0; i < n_polygons; ++ i) {
|
||||||
|
Polygon poly;
|
||||||
|
uint32_t n_points;
|
||||||
|
::fread(&n_points, 4, 1, file);
|
||||||
|
poly.points.reserve(n_points);
|
||||||
|
for (uint32_t j = 0; j < n_points; ++ j) {
|
||||||
|
coord_t x, y;
|
||||||
|
::fread(&x, sizeof(coord_t), 1, file);
|
||||||
|
::fread(&y, sizeof(coord_t), 1, file);
|
||||||
|
poly.points.emplace_back(Point(x * scale, y * scale));
|
||||||
|
}
|
||||||
|
if (which == -1 || which == i)
|
||||||
|
m_support_polygons_deserialized.emplace_back(std::move(poly));
|
||||||
|
printf("Polygon %d, area: %lf\n", i, area(poly.points));
|
||||||
|
}
|
||||||
|
::fread(&n_polygons, 4, 1, file);
|
||||||
|
m_trimming_polygons_deserialized.reserve(n_polygons);
|
||||||
|
for (uint32_t i = 0; i < n_polygons; ++ i) {
|
||||||
|
Polygon poly;
|
||||||
|
uint32_t n_points;
|
||||||
|
::fread(&n_points, 4, 1, file);
|
||||||
|
poly.points.reserve(n_points);
|
||||||
|
for (uint32_t j = 0; j < n_points; ++ j) {
|
||||||
|
coord_t x, y;
|
||||||
|
::fread(&x, sizeof(coord_t), 1, file);
|
||||||
|
::fread(&y, sizeof(coord_t), 1, file);
|
||||||
|
poly.points.emplace_back(Point(x * scale, y * scale));
|
||||||
|
}
|
||||||
|
m_trimming_polygons_deserialized.emplace_back(std::move(poly));
|
||||||
|
}
|
||||||
|
::fclose(file);
|
||||||
|
|
||||||
|
m_support_polygons_deserialized = simplify_polygons(m_support_polygons_deserialized, false);
|
||||||
|
//m_support_polygons_deserialized = to_polygons(union_ex(m_support_polygons_deserialized, false));
|
||||||
|
|
||||||
|
// Create an EdgeGrid, initialize it with projection, initialize signed distance field.
|
||||||
|
coord_t grid_resolution = coord_t(scale_(m_support_spacing));
|
||||||
|
BoundingBox bbox = get_extents(*m_support_polygons);
|
||||||
|
bbox.offset(20);
|
||||||
|
bbox.align_to_grid(grid_resolution);
|
||||||
|
m_grid.set_bbox(bbox);
|
||||||
|
m_grid.create(*m_support_polygons, grid_resolution);
|
||||||
|
m_grid.calculate_sdf();
|
||||||
|
// Sample a single point per input support polygon, keep it as a reference to maintain corresponding
|
||||||
|
// polygons if ever these polygons get split into parts by the trimming polygons.
|
||||||
|
m_island_samples = island_samples(*m_support_polygons);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Polygons& support_polygons() const { return *m_support_polygons; }
|
||||||
|
const Polygons& trimming_polygons() const { return *m_trimming_polygons; }
|
||||||
|
const EdgeGrid::Grid& grid() const { return m_grid; }
|
||||||
|
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SupportGridPattern() {}
|
||||||
SupportGridPattern& operator=(const SupportGridPattern &rhs);
|
SupportGridPattern& operator=(const SupportGridPattern &rhs);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -639,6 +773,12 @@ private:
|
|||||||
// Internal sample points of supporting expolygons. These internal points are used to pick regions corresponding
|
// Internal sample points of supporting expolygons. These internal points are used to pick regions corresponding
|
||||||
// to the initial supporting regions, after these regions werre grown and possibly split to many by the trimming polygons.
|
// to the initial supporting regions, after these regions werre grown and possibly split to many by the trimming polygons.
|
||||||
Points m_island_samples;
|
Points m_island_samples;
|
||||||
|
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
// support for deserialization of m_support_polygons, m_trimming_polygons
|
||||||
|
Polygons m_support_polygons_deserialized;
|
||||||
|
Polygons m_trimming_polygons_deserialized;
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace SupportMaterialInternal {
|
namespace SupportMaterialInternal {
|
||||||
@ -793,6 +933,30 @@ namespace SupportMaterialInternal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
static int Test()
|
||||||
|
{
|
||||||
|
// for (int i = 0; i < 30; ++ i)
|
||||||
|
{
|
||||||
|
int i = -1;
|
||||||
|
// SupportGridPattern grid("d:\\temp\\support-top-contacts-final-run1-layer460-z70.300000-prev.bin", i);
|
||||||
|
// SupportGridPattern grid("d:\\temp\\support-top-contacts-final-run1-layer460-z70.300000.bin", i);
|
||||||
|
auto grid = SupportGridPattern::deserialize("d:\\temp\\support-top-contacts-final-run1-layer27-z5.650000.bin", i);
|
||||||
|
std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>> intersections = grid.grid().intersecting_edges();
|
||||||
|
if (! intersections.empty())
|
||||||
|
printf("Intersections between contours!\n");
|
||||||
|
Slic3r::export_intersections_to_svg("d:\\temp\\support_polygon_intersections.svg", grid.support_polygons());
|
||||||
|
Slic3r::SVG::export_expolygons("d:\\temp\\support_polygons.svg", union_ex(grid.support_polygons(), false));
|
||||||
|
Slic3r::SVG::export_expolygons("d:\\temp\\trimming_polygons.svg", union_ex(grid.trimming_polygons(), false));
|
||||||
|
Polygons extracted = grid.extract_support(scale_(0.21 / 2), true);
|
||||||
|
Slic3r::SVG::export_expolygons("d:\\temp\\extracted.svg", union_ex(extracted, false));
|
||||||
|
printf("hu!");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int run_support_test = Test();
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
|
|
||||||
// Generate top contact layers supporting overhangs.
|
// Generate top contact layers supporting overhangs.
|
||||||
// For a soluble interface material synchronize the layer heights with the object, otherwise leave the layer height undefined.
|
// For a soluble interface material synchronize the layer heights with the object, otherwise leave the layer height undefined.
|
||||||
// If supports over bed surface only are requested, don't generate contact layers over an object.
|
// If supports over bed surface only are requested, don't generate contact layers over an object.
|
||||||
@ -1095,6 +1259,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Achtung! The contact_polygons need to be trimmed by slices_margin_cached, otherwise
|
||||||
|
// the selection by island_samples (see the SupportGridPattern::island_samples() method) will not work!
|
||||||
SupportGridPattern support_grid_pattern(
|
SupportGridPattern support_grid_pattern(
|
||||||
// Support islands, to be stretched into a grid.
|
// Support islands, to be stretched into a grid.
|
||||||
contact_polygons,
|
contact_polygons,
|
||||||
@ -1113,9 +1279,14 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
|||||||
// Reduce the amount of dense interfaces: Do not generate dense interfaces below overhangs with 60% overhang of the extrusions.
|
// Reduce the amount of dense interfaces: Do not generate dense interfaces below overhangs with 60% overhang of the extrusions.
|
||||||
Polygons dense_interface_polygons = diff(overhang_polygons,
|
Polygons dense_interface_polygons = diff(overhang_polygons,
|
||||||
offset2(lower_layer_polygons, - no_interface_offset * 0.5f, no_interface_offset * (0.6f + 0.5f), SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
offset2(lower_layer_polygons, - no_interface_offset * 0.5f, no_interface_offset * (0.6f + 0.5f), SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||||
// offset(lower_layer_polygons, no_interface_offset * 0.6f, SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
|
||||||
if (! dense_interface_polygons.empty()) {
|
if (! dense_interface_polygons.empty()) {
|
||||||
//FIXME do it for the bridges only?
|
dense_interface_polygons =
|
||||||
|
// Achtung! The dense_interface_polygons need to be trimmed by slices_margin_cached, otherwise
|
||||||
|
// the selection by island_samples (see the SupportGridPattern::island_samples() method) will not work!
|
||||||
|
diff(
|
||||||
|
// Regularize the contour.
|
||||||
|
offset(dense_interface_polygons, no_interface_offset * 0.1f),
|
||||||
|
slices_margin_cached);
|
||||||
SupportGridPattern support_grid_pattern(
|
SupportGridPattern support_grid_pattern(
|
||||||
// Support islands, to be stretched into a grid.
|
// Support islands, to be stretched into a grid.
|
||||||
dense_interface_polygons,
|
dense_interface_polygons,
|
||||||
@ -1125,8 +1296,34 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
|||||||
m_object_config->support_material_spacing.value + m_support_material_flow.spacing(),
|
m_object_config->support_material_spacing.value + m_support_material_flow.spacing(),
|
||||||
Geometry::deg2rad(m_object_config->support_material_angle.value));
|
Geometry::deg2rad(m_object_config->support_material_angle.value));
|
||||||
new_layer.polygons = support_grid_pattern.extract_support(m_support_material_flow.scaled_spacing()/2 + 5, false);
|
new_layer.polygons = support_grid_pattern.extract_support(m_support_material_flow.scaled_spacing()/2 + 5, false);
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
{
|
||||||
|
support_grid_pattern.serialize(debug_out_path("support-top-contacts-final-run%d-layer%d-z%f.bin", iRun, layer_id, layer.print_z));
|
||||||
|
|
||||||
|
BoundingBox bbox = get_extents(contact_polygons);
|
||||||
|
bbox.merge(get_extents(new_layer.polygons));
|
||||||
|
::Slic3r::SVG svg(debug_out_path("support-top-contacts-final0-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z));
|
||||||
|
svg.draw(union_ex(*new_layer.contact_polygons, false), "gray", 0.5f);
|
||||||
|
svg.draw(union_ex(contact_polygons, false), "blue", 0.5f);
|
||||||
|
svg.draw(union_ex(dense_interface_polygons, false), "green", 0.5f);
|
||||||
|
svg.draw(union_ex(new_layer.polygons, true), "red", 0.5f);
|
||||||
|
svg.draw_outline(union_ex(new_layer.polygons, true), "black", "black", scale_(0.1f));
|
||||||
|
}
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
{
|
||||||
|
BoundingBox bbox = get_extents(contact_polygons);
|
||||||
|
bbox.merge(get_extents(new_layer.polygons));
|
||||||
|
::Slic3r::SVG svg(debug_out_path("support-top-contacts-final-run%d-layer%d-z%f.svg", iRun, layer_id, layer.print_z));
|
||||||
|
svg.draw(union_ex(*new_layer.contact_polygons, false), "gray", 0.5f);
|
||||||
|
svg.draw(union_ex(contact_polygons, false), "blue", 0.5f);
|
||||||
|
svg.draw(union_ex(overhang_polygons, false), "green", 0.5f);
|
||||||
|
svg.draw(union_ex(new_layer.polygons, true), "red", 0.5f);
|
||||||
|
svg.draw_outline(union_ex(new_layer.polygons, true), "black", "black", scale_(0.1f));
|
||||||
|
}
|
||||||
|
#endif /* SLIC3R_DEBUG */
|
||||||
|
|
||||||
// Even after the contact layer was expanded into a grid, some of the contact islands may be too tiny to be extruded.
|
// Even after the contact layer was expanded into a grid, some of the contact islands may be too tiny to be extruded.
|
||||||
// Remove those tiny islands from new_layer.polygons and new_layer.contact_polygons.
|
// Remove those tiny islands from new_layer.polygons and new_layer.contact_polygons.
|
||||||
|
Loading…
Reference in New Issue
Block a user