mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-26 08:54:25 +08:00
cleaning FillSmooth.cpp
This commit is contained in:
parent
c1f3380339
commit
5513c41a20
@ -10,233 +10,210 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
Polylines FillSmooth::fill_surface(const Surface *surface, const FillParams ¶ms)
|
Polylines FillSmooth::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||||
{
|
{
|
||||||
//ERROR: you shouldn't call that. Default to the rectilinear one.
|
//ERROR: you shouldn't call that. Default to the rectilinear one.
|
||||||
printf("FillSmooth::fill_surface() : you call the wrong method (fill_surface instead of fill_surface_extrusion).\n");
|
printf("FillSmooth::fill_surface() : you call the wrong method (fill_surface instead of fill_surface_extrusion).\n");
|
||||||
Polylines polylines_out;
|
Polylines polylines_out;
|
||||||
return polylines_out;
|
return polylines_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out)
|
void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out)
|
||||||
{
|
{
|
||||||
coordf_t init_spacing = this->spacing;
|
coordf_t init_spacing = this->spacing;
|
||||||
|
|
||||||
//printf("FillSmooth::fill_surface() : you call the right method (fill_surface instead of fill_surface_extrusion).\n");
|
//printf("FillSmooth::fill_surface() : you call the right method (fill_surface instead of fill_surface_extrusion).\n");
|
||||||
//second pass with half layer width
|
//second pass with half layer width
|
||||||
FillParams params1 = params;
|
FillParams params1 = params;
|
||||||
FillParams params2 = params;
|
FillParams params2 = params;
|
||||||
FillParams params3 = params;
|
FillParams params3 = params;
|
||||||
params1.density *= percentWidth[0];
|
params1.density *= percentWidth[0];
|
||||||
params2.density *= percentWidth[1];
|
params2.density *= percentWidth[1];
|
||||||
params3.density *= percentWidth[2];
|
params3.density *= percentWidth[2];
|
||||||
|
|
||||||
//a small under-overlap to prevent over-extrudion on thin surfaces (i.e. remove the overlap)
|
//a small under-overlap to prevent over-extrudion on thin surfaces (i.e. remove the overlap)
|
||||||
Surface surfaceNoOverlap(*surface);
|
Surface surfaceNoOverlap(*surface);
|
||||||
//remove the overlap (prevent over-extruding) if possible
|
//remove the overlap (prevent over-extruding) if possible
|
||||||
ExPolygons noOffsetPolys = offset_ex(surfaceNoOverlap.expolygon, -scale_(this->overlap) * (flow.bridge?0:1));
|
ExPolygons noOffsetPolys = offset_ex(surfaceNoOverlap.expolygon, -scale_(this->overlap) * (flow.bridge?0:1));
|
||||||
//printf("FillSmooth::fill_surface() : overlap=%f->%f.\n", overlap, -scale_(this->overlap));
|
//printf("FillSmooth::fill_surface() : overlap=%f->%f.\n", overlap, -scale_(this->overlap));
|
||||||
//printf("FillSmooth::polys : 1->%i.\n", noOffsetPolys.size());
|
//printf("FillSmooth::polys : 1->%i.\n", noOffsetPolys.size());
|
||||||
//printf("FillSmooth::polys : %f %f->%f.\n", surface->expolygon.area(), surfaceNoOverlap.expolygon.area(), noOffsetPolys[0].area());
|
//printf("FillSmooth::polys : %f %f->%f.\n", surface->expolygon.area(), surfaceNoOverlap.expolygon.area(), noOffsetPolys[0].area());
|
||||||
//if (offsetPolys.size() == 1) surfaceNoOverlap.expolygon = offsetPolys[0];
|
//if (offsetPolys.size() == 1) surfaceNoOverlap.expolygon = offsetPolys[0];
|
||||||
|
|
||||||
//TODO: recursive if multiple polys instead of failing
|
//TODO: recursive if multiple polys instead of failing
|
||||||
|
|
||||||
|
|
||||||
//if (polylines_layer1.empty() && polylines_layer2.empty() && polylines_layer3.empty())
|
//if (polylines_layer1.empty() && polylines_layer2.empty() && polylines_layer3.empty())
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
//create root node
|
//create root node
|
||||||
ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
|
ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
|
||||||
//you don't want to sort the extrusions: big infill first, small second
|
//you don't want to sort the extrusions: big infill first, small second
|
||||||
eecroot->no_sort = true;
|
eecroot->no_sort = true;
|
||||||
|
|
||||||
ExtrusionEntityCollection *eec;
|
ExtrusionEntityCollection *eec;
|
||||||
|
|
||||||
double volumeToOccupy = 0;
|
double volumeToOccupy = 0;
|
||||||
|
|
||||||
// first infill
|
// first infill
|
||||||
std::unique_ptr<Fill> f1 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
|
std::unique_ptr<Fill> f1 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
|
||||||
f1->bounding_box = this->bounding_box;
|
f1->bounding_box = this->bounding_box;
|
||||||
f1->spacing = init_spacing;
|
f1->spacing = init_spacing;
|
||||||
f1->layer_id = this->layer_id;
|
f1->layer_id = this->layer_id;
|
||||||
f1->z = this->z;
|
f1->z = this->z;
|
||||||
f1->angle = anglePass[0];
|
f1->angle = anglePass[0];
|
||||||
// Maximum length of the perimeter segment linking two infill lines.
|
// Maximum length of the perimeter segment linking two infill lines.
|
||||||
f1->link_max_length = this->link_max_length;
|
f1->link_max_length = this->link_max_length;
|
||||||
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
||||||
f1->loop_clipping = this->loop_clipping;
|
f1->loop_clipping = this->loop_clipping;
|
||||||
for (auto poly = noOffsetPolys.begin(); poly != noOffsetPolys.end(); ++poly){
|
for (auto poly = noOffsetPolys.begin(); poly != noOffsetPolys.end(); ++poly){
|
||||||
surfaceNoOverlap.expolygon = *poly;
|
surfaceNoOverlap.expolygon = *poly;
|
||||||
Polylines polylines_layer1 = f1->fill_surface(&surfaceNoOverlap, params1);
|
Polylines polylines_layer1 = f1->fill_surface(&surfaceNoOverlap, params1);
|
||||||
if (!polylines_layer1.empty()){
|
if (!polylines_layer1.empty()){
|
||||||
|
|
||||||
double lengthTot = 0;
|
double lengthTot = 0;
|
||||||
int nbLines = 0;
|
int nbLines = 0;
|
||||||
for (auto pline = polylines_layer1.begin(); pline != polylines_layer1.end(); ++pline){
|
for (auto pline = polylines_layer1.begin(); pline != polylines_layer1.end(); ++pline){
|
||||||
Lines lines = pline->lines();
|
Lines lines = pline->lines();
|
||||||
for (auto line = lines.begin(); line != lines.end(); ++line){
|
for (auto line = lines.begin(); line != lines.end(); ++line){
|
||||||
printf("line length = %f, scaled:%f, unscaled:%f \n", line->length(), scale_(line->length()), unscale(line->length()));
|
lengthTot += unscale(line->length());
|
||||||
lengthTot += unscale(line->length());
|
nbLines++;
|
||||||
nbLines++;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// add external "perimeter gap"
|
// add external "perimeter gap"
|
||||||
double poylineVolume = flow.height*unscale(unscale(poly->area()));
|
double poylineVolume = flow.height*unscale(unscale(poly->area()));
|
||||||
double perimeterRoundGap = unscale(poly->contour.length()) * flow.height * (1 - 0.25*PI) * 0.5;
|
double perimeterRoundGap = unscale(poly->contour.length()) * flow.height * (1 - 0.25*PI) * 0.5;
|
||||||
// add holes "perimeter gaps"
|
// add holes "perimeter gaps"
|
||||||
double holesGaps = 0;
|
double holesGaps = 0;
|
||||||
for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole){
|
for (auto hole = poly->holes.begin(); hole != poly->holes.end(); ++hole){
|
||||||
holesGaps += unscale(hole->length()) * flow.height * (1 - 0.25*PI) * 0.5;
|
holesGaps += unscale(hole->length()) * flow.height * (1 - 0.25*PI) * 0.5;
|
||||||
}
|
}
|
||||||
poylineVolume += perimeterRoundGap + holesGaps;
|
poylineVolume += perimeterRoundGap + holesGaps;
|
||||||
|
|
||||||
//extruded volume: see http://manual.slic3r.org/advanced/flow-math, and we need to remove a circle at an end (as the flow continue)
|
//extruded volume: see http://manual.slic3r.org/advanced/flow-math, and we need to remove a circle at an end (as the flow continue)
|
||||||
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
|
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
|
||||||
volumeToOccupy += poylineVolume;
|
volumeToOccupy += poylineVolume;
|
||||||
|
|
||||||
printf("FillSmooth: request extruding of %f length, with mm3_per_mm of %f =volume=> %f / %f (%f) %s\n",
|
eec = new ExtrusionEntityCollection();
|
||||||
lengthTot,
|
eecroot->entities.push_back(eec);
|
||||||
flow.mm3_per_mm(),
|
eec->no_sort = false; //can be sorted inside the pass
|
||||||
flow.mm3_per_mm() * lengthTot,
|
extrusion_entities_append_paths(
|
||||||
flow.height*unscale(unscale(surfaceNoOverlap.area())),
|
eec->entities, STDMOVE(polylines_layer1),
|
||||||
(flow.mm3_per_mm() * lengthTot) / (flow.height*unscale(unscale(surfaceNoOverlap.area()))),
|
flow.bridge ? erBridgeInfill : rolePass[0],
|
||||||
params.fill_exactly ? "ready" : "only for info"
|
//reduced flow height for a better view (it's only a gui thing)
|
||||||
);
|
|
||||||
printf("FillSmooth: extruding flow mult %f vs old: %f\n", percentFlow[0] * poylineVolume / extrudedVolume, percentFlow[0] / percentWidth[0]);
|
|
||||||
|
|
||||||
eec = new ExtrusionEntityCollection();
|
|
||||||
eecroot->entities.push_back(eec);
|
|
||||||
eec->no_sort = false; //can be sorted inside the pass
|
|
||||||
extrusion_entities_append_paths(
|
|
||||||
eec->entities, STDMOVE(polylines_layer1),
|
|
||||||
flow.bridge ? erBridgeInfill : rolePass[0],
|
|
||||||
//reduced flow height for a better view (it's only a gui thing)
|
|
||||||
params.flow_mult * flow.mm3_per_mm() * percentFlow[0] * (params.fill_exactly? poylineVolume / extrudedVolume : 1),
|
params.flow_mult * flow.mm3_per_mm() * percentFlow[0] * (params.fill_exactly? poylineVolume / extrudedVolume : 1),
|
||||||
(float)(flow.width*percentFlow[0] * (params.fill_exactly ? poylineVolume / extrudedVolume : 1)), (float)flow.height*0.8);
|
(float)(flow.width*percentFlow[0] * (params.fill_exactly ? poylineVolume / extrudedVolume : 1)), (float)flow.height*0.8);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//second infill
|
//second infill
|
||||||
if (nbPass > 1){
|
if (nbPass > 1){
|
||||||
|
|
||||||
std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[1]));
|
std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[1]));
|
||||||
f2->bounding_box = this->bounding_box;
|
f2->bounding_box = this->bounding_box;
|
||||||
f2->spacing = init_spacing;
|
f2->spacing = init_spacing;
|
||||||
f2->layer_id = this->layer_id;
|
f2->layer_id = this->layer_id;
|
||||||
f2->z = this->z;
|
f2->z = this->z;
|
||||||
f2->angle = anglePass[1];
|
f2->angle = anglePass[1];
|
||||||
// Maximum length of the perimeter segment linking two infill lines.
|
// Maximum length of the perimeter segment linking two infill lines.
|
||||||
f2->link_max_length = this->link_max_length;
|
f2->link_max_length = this->link_max_length;
|
||||||
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
||||||
f2->loop_clipping = this->loop_clipping;
|
f2->loop_clipping = this->loop_clipping;
|
||||||
Polylines polylines_layer2 = f2->fill_surface(surface, params2);
|
Polylines polylines_layer2 = f2->fill_surface(surface, params2);
|
||||||
|
|
||||||
if (!polylines_layer2.empty()){
|
if (!polylines_layer2.empty()){
|
||||||
if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer2[0].points.size() > 3){
|
if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer2[0].points.size() > 3){
|
||||||
polylines_layer2[0].points.erase(polylines_layer2[0].points.begin());
|
polylines_layer2[0].points.erase(polylines_layer2[0].points.begin());
|
||||||
polylines_layer2[polylines_layer2.size() - 1].points.pop_back();
|
polylines_layer2[polylines_layer2.size() - 1].points.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
//compute the path of the nozzle
|
//compute the path of the nozzle
|
||||||
double lengthTot = 0;
|
double lengthTot = 0;
|
||||||
int nbLines = 0;
|
int nbLines = 0;
|
||||||
for (auto pline = polylines_layer2.begin(); pline != polylines_layer2.end(); ++pline){
|
for (auto pline = polylines_layer2.begin(); pline != polylines_layer2.end(); ++pline){
|
||||||
Lines lines = pline->lines();
|
Lines lines = pline->lines();
|
||||||
for (auto line = lines.begin(); line != lines.end(); ++line){
|
for (auto line = lines.begin(); line != lines.end(); ++line){
|
||||||
//printf("line length = %f, scaled:%f, unscaled:%f \n", line->length(), scale_(line->length()), unscale(line->length()));
|
lengthTot += unscale(line->length());
|
||||||
lengthTot += unscale(line->length());
|
nbLines++;
|
||||||
nbLines++;
|
}
|
||||||
}
|
}
|
||||||
}
|
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
|
||||||
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
|
if (extrudedVolume == 0) extrudedVolume = 1;
|
||||||
if (extrudedVolume != 0){
|
|
||||||
printf("FillSmooth: extruding flow of 2nd layer increased by %f\n", volumeToOccupy / extrudedVolume);
|
|
||||||
printf("FillSmooth: extruding flow of 2nd layer mult %f vs old: %f\n", percentFlow[1] * volumeToOccupy / extrudedVolume, percentFlow[1] / percentWidth[1]);
|
|
||||||
|
|
||||||
}
|
// Save into layer smoothing path.
|
||||||
else{
|
eec = new ExtrusionEntityCollection();
|
||||||
printf("FillSmooth: extruding flow of 2nd layer increased by INFINITE \n");
|
eecroot->entities.push_back(eec);
|
||||||
extrudedVolume = 1;
|
eec->no_sort = false;
|
||||||
}
|
// print thin
|
||||||
|
|
||||||
// Save into layer smoothing path.
|
extrusion_entities_append_paths(
|
||||||
eec = new ExtrusionEntityCollection();
|
eec->entities, STDMOVE(polylines_layer2),
|
||||||
eecroot->entities.push_back(eec);
|
rolePass[1],
|
||||||
eec->no_sort = false;
|
//reduced flow width for a better view (it's only a gui thing)
|
||||||
// print thin
|
|
||||||
|
|
||||||
extrusion_entities_append_paths(
|
|
||||||
eec->entities, STDMOVE(polylines_layer2),
|
|
||||||
rolePass[1],
|
|
||||||
//reduced flow width for a better view (it's only a gui thing)
|
|
||||||
params.flow_mult * flow.mm3_per_mm() * percentFlow[1] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1),
|
params.flow_mult * flow.mm3_per_mm() * percentFlow[1] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1),
|
||||||
(float)(flow.width*(percentFlow[1] < 0.1 ? 0.1 : percentFlow[1])), (float)flow.height);
|
(float)(flow.width*(percentFlow[1] < 0.1 ? 0.1 : percentFlow[1])), (float)flow.height);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// third infill
|
// third infill
|
||||||
if (nbPass > 2){
|
if (nbPass > 2){
|
||||||
std::unique_ptr<Fill> f3 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
|
std::unique_ptr<Fill> f3 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[0]));
|
||||||
f3->bounding_box = this->bounding_box;
|
f3->bounding_box = this->bounding_box;
|
||||||
f3->spacing = init_spacing;
|
f3->spacing = init_spacing;
|
||||||
f3->layer_id = this->layer_id;
|
f3->layer_id = this->layer_id;
|
||||||
f3->z = this->z;
|
f3->z = this->z;
|
||||||
f3->angle = anglePass[2];
|
f3->angle = anglePass[2];
|
||||||
// Maximum length of the perimeter segment linking two infill lines.
|
// Maximum length of the perimeter segment linking two infill lines.
|
||||||
f3->link_max_length = this->link_max_length;
|
f3->link_max_length = this->link_max_length;
|
||||||
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
||||||
f3->loop_clipping = this->loop_clipping;
|
f3->loop_clipping = this->loop_clipping;
|
||||||
Polylines polylines_layer3 = f3->fill_surface(surface, params1);
|
Polylines polylines_layer3 = f3->fill_surface(surface, params1);
|
||||||
|
|
||||||
if (!polylines_layer3.empty()){
|
if (!polylines_layer3.empty()){
|
||||||
|
|
||||||
//remove some points that are not inside the area
|
//remove some points that are not inside the area
|
||||||
if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer3[0].points.size() > 3){
|
if (fillPattern[2] == InfillPattern::ipRectilinear && polylines_layer3[0].points.size() > 3){
|
||||||
polylines_layer3[0].points.erase(polylines_layer3[0].points.begin());
|
polylines_layer3[0].points.erase(polylines_layer3[0].points.begin());
|
||||||
polylines_layer3[polylines_layer3.size() - 1].points.pop_back();
|
polylines_layer3[polylines_layer3.size() - 1].points.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
//compute the path of the nozzle
|
//compute the path of the nozzle
|
||||||
double lengthTot = 0;
|
double lengthTot = 0;
|
||||||
int nbLines = 0;
|
int nbLines = 0;
|
||||||
for (auto pline = polylines_layer3.begin(); pline != polylines_layer3.end(); ++pline){
|
for (auto pline = polylines_layer3.begin(); pline != polylines_layer3.end(); ++pline){
|
||||||
Lines lines = pline->lines();
|
Lines lines = pline->lines();
|
||||||
for (auto line = lines.begin(); line != lines.end(); ++line){
|
for (auto line = lines.begin(); line != lines.end(); ++line){
|
||||||
printf("line length3");
|
lengthTot += unscale(line->length());
|
||||||
//printf("line length = %f, scaled:%f, unscaled:%f \n", line->length(), scale_(line->length()), unscale(line->length()));
|
nbLines++;
|
||||||
lengthTot += unscale(line->length());
|
}
|
||||||
nbLines++;
|
}
|
||||||
}
|
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
|
||||||
}
|
|
||||||
double extrudedVolume = flow.mm3_per_mm() * lengthTot;
|
// Save into layer smoothing path. layer 3
|
||||||
printf("FillSmooth: extruding flow of 3nd layer mult %f vs old: %f\n", percentFlow[2] * volumeToOccupy / extrudedVolume, percentFlow[2] / percentWidth[2]);
|
eec = new ExtrusionEntityCollection();
|
||||||
|
eecroot->entities.push_back(eec);
|
||||||
// Save into layer smoothing path. layer 3
|
eec->no_sort = false;
|
||||||
eec = new ExtrusionEntityCollection();
|
// print thin
|
||||||
eecroot->entities.push_back(eec);
|
extrusion_entities_append_paths(
|
||||||
eec->no_sort = false;
|
eec->entities, STDMOVE(polylines_layer3),
|
||||||
// print thin
|
rolePass[2], //slow (if last)
|
||||||
extrusion_entities_append_paths(
|
//reduced flow width for a better view (it's only a gui thing)
|
||||||
eec->entities, STDMOVE(polylines_layer3),
|
|
||||||
rolePass[2], //slow (if last)
|
|
||||||
//reduced flow width for a better view (it's only a gui thing)
|
|
||||||
params.flow_mult * flow.mm3_per_mm() * percentFlow[2] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1),
|
params.flow_mult * flow.mm3_per_mm() * percentFlow[2] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1),
|
||||||
(float)(flow.width*(percentFlow[2] < 0.1 ? 0.1 : percentFlow[2])), (float)flow.height);
|
(float)(flow.width*(percentFlow[2] < 0.1 ? 0.1 : percentFlow[2])), (float)flow.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eecroot->entities.empty())
|
if (!eecroot->entities.empty())
|
||||||
out.entities.push_back(eecroot);
|
out.entities.push_back(eecroot);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
Loading…
x
Reference in New Issue
Block a user