Some beautification and C++11 adaptation.
This commit is contained in:
parent
640698d28b
commit
9f7a5c7a6f
5 changed files with 69 additions and 116 deletions
|
@ -15,7 +15,7 @@ BridgeDetector::BridgeDetector(
|
||||||
lower_slices(_lower_slices),
|
lower_slices(_lower_slices),
|
||||||
spacing(_spacing)
|
spacing(_spacing)
|
||||||
{
|
{
|
||||||
this->expolygons_owned.push_back(STDMOVE(_expolygon));
|
this->expolygons_owned.push_back(std::move(_expolygon));
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,49 +211,40 @@ Polygons BridgeDetector::coverage(double angle) const
|
||||||
Polygons covered;
|
Polygons covered;
|
||||||
|
|
||||||
if (angle != -1) {
|
if (angle != -1) {
|
||||||
|
|
||||||
// Get anchors, convert them to Polygons and rotate them.
|
// Get anchors, convert them to Polygons and rotate them.
|
||||||
Polygons anchors = to_polygons(this->_anchor_regions);
|
Polygons anchors = to_polygons(this->_anchor_regions);
|
||||||
polygons_rotate(anchors, PI/2.0 - angle);
|
polygons_rotate(anchors, PI/2.0 - angle);
|
||||||
|
|
||||||
for (ExPolygons::const_iterator it_expoly = this->expolygons.begin(); it_expoly != this->expolygons.end(); ++ it_expoly)
|
for (ExPolygon expolygon : this->expolygons) {
|
||||||
{
|
|
||||||
// Clone our expolygon and rotate it so that we work with vertical lines.
|
// Clone our expolygon and rotate it so that we work with vertical lines.
|
||||||
ExPolygon expolygon = *it_expoly;
|
expolygon.rotate(PI/2.0 - angle);
|
||||||
expolygon.rotate(PI/2.0 - angle);
|
// Outset the bridge expolygon by half the amount we used for detecting anchors;
|
||||||
|
// we'll use this one to generate our trapezoids and be sure that their vertices
|
||||||
/* Outset the bridge expolygon by half the amount we used for detecting anchors;
|
// are inside the anchors and not on their contours leading to false negatives.
|
||||||
we'll use this one to generate our trapezoids and be sure that their vertices
|
for (ExPolygon &expoly : offset_ex(expolygon, 0.5f * float(this->spacing))) {
|
||||||
are inside the anchors and not on their contours leading to false negatives. */
|
// Compute trapezoids according to a vertical orientation
|
||||||
ExPolygons grown = offset_ex(expolygon, 0.5f * float(this->spacing));
|
Polygons trapezoids;
|
||||||
|
expoly.get_trapezoids2(&trapezoids, PI/2.0);
|
||||||
// Compute trapezoids according to a vertical orientation
|
for (const Polygon &trapezoid : trapezoids) {
|
||||||
Polygons trapezoids;
|
// not nice, we need a more robust non-numeric check
|
||||||
for (ExPolygons::const_iterator it = grown.begin(); it != grown.end(); ++it)
|
size_t n_supported = 0;
|
||||||
it->get_trapezoids2(&trapezoids, PI/2.0);
|
for (const Line &supported_line : intersection_ln(trapezoid.lines(), anchors))
|
||||||
|
if (supported_line.length() >= this->spacing)
|
||||||
for (Polygons::iterator trapezoid = trapezoids.begin(); trapezoid != trapezoids.end(); ++trapezoid) {
|
++ n_supported;
|
||||||
Lines supported = intersection_ln(trapezoid->lines(), anchors);
|
if (n_supported >= 2)
|
||||||
size_t n_supported = 0;
|
covered.push_back(std::move(trapezoid));
|
||||||
// not nice, we need a more robust non-numeric check
|
}
|
||||||
for (size_t i = 0; i < supported.size(); ++i)
|
|
||||||
if (supported[i].length() >= this->spacing)
|
|
||||||
++ n_supported;
|
|
||||||
if (n_supported >= 2)
|
|
||||||
covered.push_back(STDMOVE(*trapezoid));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unite the trapezoids before rotation, as the rotation creates tiny gaps and intersections between the trapezoids
|
// Unite the trapezoids before rotation, as the rotation creates tiny gaps and intersections between the trapezoids
|
||||||
// instead of exact overlaps.
|
// instead of exact overlaps.
|
||||||
covered = union_(covered);
|
covered = union_(covered);
|
||||||
|
|
||||||
// Intersect trapezoids with actual bridge area to remove extra margins and append it to result.
|
// Intersect trapezoids with actual bridge area to remove extra margins and append it to result.
|
||||||
polygons_rotate(covered, -(PI/2.0 - angle));
|
polygons_rotate(covered, -(PI/2.0 - angle));
|
||||||
covered = intersection(covered, to_polygons(this->expolygons));
|
covered = intersection(covered, to_polygons(this->expolygons));
|
||||||
|
#if 0
|
||||||
/*
|
{
|
||||||
if (0) {
|
|
||||||
my @lines = map @{$_->lines}, @$trapezoids;
|
my @lines = map @{$_->lines}, @$trapezoids;
|
||||||
$_->rotate(-(PI/2 - $angle), [0,0]) for @lines;
|
$_->rotate(-(PI/2 - $angle), [0,0]) for @lines;
|
||||||
|
|
||||||
|
@ -266,7 +257,7 @@ Polygons BridgeDetector::coverage(double angle) const
|
||||||
lines => \@lines,
|
lines => \@lines,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
*/
|
#endif
|
||||||
}
|
}
|
||||||
return covered;
|
return covered;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,15 +45,9 @@ public:
|
||||||
float spacing() const;
|
float spacing() const;
|
||||||
float spacing(const Flow &other) const;
|
float spacing(const Flow &other) const;
|
||||||
double mm3_per_mm() const;
|
double mm3_per_mm() const;
|
||||||
coord_t scaled_width() const {
|
coord_t scaled_width() const { return coord_t(scale_(this->width)); };
|
||||||
return scale_(this->width);
|
coord_t scaled_spacing() const { return coord_t(scale_(this->spacing())); };
|
||||||
};
|
coord_t scaled_spacing(const Flow &other) const { return coord_t(scale_(this->spacing(other))); };
|
||||||
coord_t scaled_spacing() const {
|
|
||||||
return scale_(this->spacing());
|
|
||||||
};
|
|
||||||
coord_t scaled_spacing(const Flow &other) const {
|
|
||||||
return scale_(this->spacing(other));
|
|
||||||
};
|
|
||||||
|
|
||||||
static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio);
|
static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio);
|
||||||
static Flow new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge);
|
static Flow new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge);
|
||||||
|
|
|
@ -53,17 +53,18 @@ class PrintRegion
|
||||||
{
|
{
|
||||||
friend class Print;
|
friend class Print;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PrintRegionConfig config;
|
PrintRegionConfig config;
|
||||||
|
|
||||||
Print* print();
|
Print* print() { return this->_print; }
|
||||||
Flow flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const;
|
Flow flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const;
|
||||||
|
coordf_t nozzle_dmr_avg(const PrintConfig &print_config) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Print* _print;
|
Print* _print;
|
||||||
|
|
||||||
PrintRegion(Print* print);
|
PrintRegion(Print* print) : _print(print) {}
|
||||||
~PrintRegion();
|
~PrintRegion() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -365,17 +365,22 @@ void PrintObject::detect_surfaces_type()
|
||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(info) << "Detecting solid surfaces...";
|
BOOST_LOG_TRIVIAL(info) << "Detecting solid surfaces...";
|
||||||
|
|
||||||
|
// Interface shells: the intersecting parts are treated as self standing objects supporting each other.
|
||||||
|
// Each of the objects will have a full number of top / bottom layers, even if these top / bottom layers
|
||||||
|
// are completely hidden inside a collective body of intersecting parts.
|
||||||
|
// This is useful if one of the parts is to be dissolved, or if it is transparent and the internal shells
|
||||||
|
// should be visible.
|
||||||
bool interface_shells = this->config.interface_shells.value;
|
bool interface_shells = this->config.interface_shells.value;
|
||||||
|
|
||||||
for (int idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
|
for (int idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start";
|
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start";
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
for (int idx_layer = 0; idx_layer < int(this->layer_count()); ++ idx_layer) {
|
for (Layer *layer : this->layers)
|
||||||
LayerRegion *layerm = this->layers[idx_layer]->get_region(idx_region);
|
layer->regions[idx_region]->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial");
|
||||||
layerm->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial");
|
|
||||||
}
|
|
||||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||||
|
|
||||||
|
// If interface shells are allowed, the region->surfaces cannot be overwritten as they may be used by other threads.
|
||||||
|
// Cache the result of the following parallel_loop.
|
||||||
std::vector<Surfaces> surfaces_new;
|
std::vector<Surfaces> surfaces_new;
|
||||||
if (interface_shells)
|
if (interface_shells)
|
||||||
surfaces_new.assign(this->layers.size(), Surfaces());
|
surfaces_new.assign(this->layers.size(), Surfaces());
|
||||||
|
@ -383,14 +388,23 @@ void PrintObject::detect_surfaces_type()
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(
|
||||||
tbb::blocked_range<size_t>(0, this->layers.size()),
|
tbb::blocked_range<size_t>(0, this->layers.size()),
|
||||||
[this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
|
[this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
|
||||||
|
// If we have raft layers, consider bottom layer as a bridge just like any other bottom surface lying on the void.
|
||||||
|
SurfaceType surface_type_bottom_1st =
|
||||||
|
(this->config.raft_layers.value > 0 && this->config.support_material_contact_distance.value > 0) ?
|
||||||
|
stBottomBridge : stBottom;
|
||||||
|
// If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating
|
||||||
|
// the support from the print.
|
||||||
|
SurfaceType surface_type_bottom_other =
|
||||||
|
(this->config.support_material.value && this->config.support_material_contact_distance.value == 0) ?
|
||||||
|
stBottom : stBottomBridge;
|
||||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
||||||
// BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << idx_region << " and layer " << layer->print_z;
|
// BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << idx_region << " and layer " << layer->print_z;
|
||||||
Layer *layer = this->layers[idx_layer];
|
Layer *layer = this->layers[idx_layer];
|
||||||
LayerRegion *layerm = layer->get_region(idx_region);
|
LayerRegion *layerm = layer->get_region(idx_region);
|
||||||
// comparison happens against the *full* slices (considering all regions)
|
// comparison happens against the *full* slices (considering all regions)
|
||||||
// unless internal shells are requested
|
// unless internal shells are requested
|
||||||
Layer *upper_layer = idx_layer + 1 < this->layer_count() ? this->get_layer(idx_layer + 1) : NULL;
|
Layer *upper_layer = idx_layer + 1 < this->layer_count() ? this->get_layer(idx_layer + 1) : nullptr;
|
||||||
Layer *lower_layer = idx_layer > 0 ? this->get_layer(idx_layer - 1) : NULL;
|
Layer *lower_layer = idx_layer > 0 ? this->get_layer(idx_layer - 1) : nullptr;
|
||||||
// collapse very narrow parts (using the safety offset in the diff is not enough)
|
// collapse very narrow parts (using the safety offset in the diff is not enough)
|
||||||
float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f;
|
float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f;
|
||||||
|
|
||||||
|
@ -400,8 +414,6 @@ void PrintObject::detect_surfaces_type()
|
||||||
// of current layer and upper one)
|
// of current layer and upper one)
|
||||||
Surfaces top;
|
Surfaces top;
|
||||||
if (upper_layer) {
|
if (upper_layer) {
|
||||||
// Config value $self->config->interface_shells is true, if a support is separated from the object
|
|
||||||
// by a soluble material (for example a PVA plastic).
|
|
||||||
Polygons upper_slices = interface_shells ?
|
Polygons upper_slices = interface_shells ?
|
||||||
to_polygons(upper_layer->get_region(idx_region)->slices.surfaces) :
|
to_polygons(upper_layer->get_region(idx_region)->slices.surfaces) :
|
||||||
to_polygons(upper_layer->slices);
|
to_polygons(upper_layer->slices);
|
||||||
|
@ -412,54 +424,25 @@ void PrintObject::detect_surfaces_type()
|
||||||
// if no upper layer, all surfaces of this one are solid
|
// if no upper layer, all surfaces of this one are solid
|
||||||
// we clone surfaces because we're going to clear the slices collection
|
// we clone surfaces because we're going to clear the slices collection
|
||||||
top = layerm->slices.surfaces;
|
top = layerm->slices.surfaces;
|
||||||
for (Surfaces::iterator it = top.begin(); it != top.end(); ++ it)
|
for (Surface &surface : top)
|
||||||
it->surface_type = stTop;
|
surface.surface_type = stTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find bottom surfaces (difference between current surfaces
|
// Find bottom surfaces (difference between current surfaces of current layer and lower one).
|
||||||
// of current layer and lower one)
|
|
||||||
Surfaces bottom;
|
Surfaces bottom;
|
||||||
if (lower_layer) {
|
if (lower_layer) {
|
||||||
// If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating
|
Polygons lower_slices = interface_shells ?
|
||||||
// the support from the print.
|
to_polygons(lower_layer->get_region(idx_region)->slices.surfaces) :
|
||||||
SurfaceType surface_type_bottom =
|
to_polygons(lower_layer->slices);
|
||||||
(this->config.support_material.value && this->config.support_material_contact_distance.value == 0) ?
|
surfaces_append(bottom,
|
||||||
stBottom : stBottomBridge;
|
offset2_ex(diff(layerm_slices_surfaces, lower_slices, true), -offset, offset),
|
||||||
// Any surface lying on the void is a true bottom bridge (an overhang)
|
surface_type_bottom_other);
|
||||||
surfaces_append(
|
|
||||||
bottom,
|
|
||||||
offset2_ex(
|
|
||||||
diff(layerm_slices_surfaces, to_polygons(lower_layer->slices), true),
|
|
||||||
-offset, offset),
|
|
||||||
surface_type_bottom);
|
|
||||||
// if user requested internal shells, we need to identify surfaces
|
|
||||||
// lying on other slices not belonging to this region
|
|
||||||
//FIXME Vojtech: config.internal_shells or config.interface_shells? Is it some legacy code?
|
|
||||||
// Why shall multiple regions over soluble support be treated specially?
|
|
||||||
if (interface_shells) {
|
|
||||||
// non-bridging bottom surfaces: any part of this layer lying
|
|
||||||
// on something else, excluding those lying on our own region
|
|
||||||
surfaces_append(
|
|
||||||
bottom,
|
|
||||||
offset2_ex(
|
|
||||||
diff(
|
|
||||||
intersection(layerm_slices_surfaces, to_polygons(lower_layer->slices)), // supported
|
|
||||||
to_polygons(lower_layer->get_region(idx_region)->slices.surfaces),
|
|
||||||
true),
|
|
||||||
-offset, offset),
|
|
||||||
stBottom);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// if no lower layer, all surfaces of this one are solid
|
// if no lower layer, all surfaces of this one are solid
|
||||||
// we clone surfaces because we're going to clear the slices collection
|
// we clone surfaces because we're going to clear the slices collection
|
||||||
bottom = layerm->slices.surfaces;
|
bottom = layerm->slices.surfaces;
|
||||||
// if we have raft layers, consider bottom layer as a bridge
|
for (Surface &surface : bottom)
|
||||||
// just like any other bottom surface lying on the void
|
surface.surface_type = surface_type_bottom_1st;
|
||||||
SurfaceType surface_type_bottom =
|
|
||||||
(this->config.raft_layers.value > 0 && this->config.support_material_contact_distance.value > 0) ?
|
|
||||||
stBottomBridge : stBottom;
|
|
||||||
for (Surfaces::iterator it = bottom.begin(); it != bottom.end(); ++ it)
|
|
||||||
it->surface_type = surface_type_bottom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// now, if the object contained a thin membrane, we could have overlapping bottom
|
// now, if the object contained a thin membrane, we could have overlapping bottom
|
||||||
|
@ -472,11 +455,7 @@ void PrintObject::detect_surfaces_type()
|
||||||
Polygons top_polygons = to_polygons(std::move(top));
|
Polygons top_polygons = to_polygons(std::move(top));
|
||||||
top.clear();
|
top.clear();
|
||||||
surfaces_append(top,
|
surfaces_append(top,
|
||||||
#if 0
|
|
||||||
offset2_ex(diff(top_polygons, to_polygons(bottom), true), -offset, offset),
|
|
||||||
#else
|
|
||||||
diff_ex(top_polygons, to_polygons(bottom), false),
|
diff_ex(top_polygons, to_polygons(bottom), false),
|
||||||
#endif
|
|
||||||
stTop);
|
stTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,11 +479,7 @@ void PrintObject::detect_surfaces_type()
|
||||||
Polygons topbottom = to_polygons(top);
|
Polygons topbottom = to_polygons(top);
|
||||||
polygons_append(topbottom, to_polygons(bottom));
|
polygons_append(topbottom, to_polygons(bottom));
|
||||||
surfaces_append(surfaces_out,
|
surfaces_append(surfaces_out,
|
||||||
#if 0
|
|
||||||
offset2_ex(diff(layerm_slices_surfaces, topbottom, true), -offset, offset),
|
|
||||||
#else
|
|
||||||
diff_ex(layerm_slices_surfaces, topbottom, false),
|
diff_ex(layerm_slices_surfaces, topbottom, false),
|
||||||
#endif
|
|
||||||
stInternal);
|
stInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,21 +2,6 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
PrintRegion::PrintRegion(Print* print)
|
|
||||||
: _print(print)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintRegion::~PrintRegion()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Print*
|
|
||||||
PrintRegion::print()
|
|
||||||
{
|
|
||||||
return this->_print;
|
|
||||||
}
|
|
||||||
|
|
||||||
Flow
|
Flow
|
||||||
PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const
|
PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const
|
||||||
{
|
{
|
||||||
|
@ -65,4 +50,11 @@ PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool first_la
|
||||||
return Flow::new_from_config_width(role, config_width, nozzle_diameter, layer_height, bridge ? (float)this->config.bridge_flow_ratio : 0.0);
|
return Flow::new_from_config_width(role, config_width, nozzle_diameter, layer_height, bridge ? (float)this->config.bridge_flow_ratio : 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const
|
||||||
|
{
|
||||||
|
return (print_config.nozzle_diameter.get_at(this->config.perimeter_extruder.value - 1) +
|
||||||
|
print_config.nozzle_diameter.get_at(this->config.infill_extruder.value - 1) +
|
||||||
|
print_config.nozzle_diameter.get_at(this->config.solid_infill_extruder.value - 1)) / 3.;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue