Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
supermerill committed Oct 13, 2021
2 parents f46c98c + 52e58ff commit 02faf45
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 16 deletions.
33 changes: 32 additions & 1 deletion src/libslic3r/ClipperUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,21 @@ ClipperLib::PolyTree _clipper_do_pl(const ClipperLib::ClipType clipType, const P
// read input
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
ClipperLib::Paths input_clip = Slic3rMultiPoints_to_ClipperPaths(clip);


//perform y safing : if a line is on the same Y, clipper may not pick the good point.
std::set<coord_t> bad_y;
for (ClipperLib::Paths* input : {&input_subject, &input_clip} )
for (ClipperLib::Path& path : *input) {
coord_t lasty = 0;
for (ClipperLib::IntPoint& pt : path) {
if (lasty == pt.Y) {
pt.Y+=1;
bad_y.insert(pt.Y);
}
lasty = pt.Y;
}
}

// perform safety offset
if (safety_offset_) safety_offset(&input_clip);

Expand All @@ -613,6 +627,23 @@ ClipperLib::PolyTree _clipper_do_pl(const ClipperLib::ClipType clipType, const P
// perform operation
ClipperLib::PolyTree retval;
clipper.Execute(clipType, retval, fillType, fillType);

//restore good y
if (!bad_y.empty()) {
std::vector<ClipperLib::PolyNode*> to_check;
to_check.push_back(&retval);
while (!to_check.empty()) {
ClipperLib::PolyNode* node = to_check.back();
to_check.pop_back();
for (ClipperLib::IntPoint& pt : node->Contour) {
if (bad_y.find(pt.Y) != bad_y.end()) {
pt.Y-=1;
}
}
to_check.insert(to_check.end(), node->Childs.begin(), node->Childs.end());
}
}

return retval;
}

Expand Down
22 changes: 22 additions & 0 deletions src/libslic3r/ExtrusionEntity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,28 @@ void ExtrusionLength::use(const ExtrusionEntityCollection& collection) {
}
}


void ExtrusionVisitorRecursiveConst::use(const ExtrusionMultiPath& multipath) {
for (const ExtrusionPath& path: multipath.paths) {
path.visit(*this);
}
}
void ExtrusionVisitorRecursiveConst::use(const ExtrusionMultiPath3D& multipath3D) {
for (const ExtrusionPath3D& path3D : multipath3D.paths) {
path3D.visit(*this);
}
}
void ExtrusionVisitorRecursiveConst::use(const ExtrusionLoop& loop) {
for (const ExtrusionPath& path : loop.paths) {
path.visit(*this);
}
}
void ExtrusionVisitorRecursiveConst::use(const ExtrusionEntityCollection& collection) {
for (const ExtrusionEntity* entity : collection.entities) {
entity->visit(*this);
}
}

//class ExtrusionTreeVisitor : ExtrusionVisitor {
//public:
// //virtual void use(ExtrusionEntity &entity) { assert(false); };
Expand Down
8 changes: 8 additions & 0 deletions src/libslic3r/ExtrusionEntity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,14 @@ class ExtrusionLength : public ExtrusionVisitorConst {
}
};

class ExtrusionVisitorRecursiveConst : public ExtrusionVisitorConst {
public:
virtual void use(const ExtrusionMultiPath& multipath) override;
virtual void use(const ExtrusionMultiPath3D& multipath) override;
virtual void use(const ExtrusionLoop& loop) override;
virtual void use(const ExtrusionEntityCollection& collection) override;
};

}

#endif
15 changes: 14 additions & 1 deletion src/libslic3r/PerimeterGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1852,6 +1852,8 @@ PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, co
for (ExtrusionPath &path : paths) {
direction_polyline.points.insert(direction_polyline.points.end(), path.polyline.points.begin(), path.polyline.points.end());
}
for (int i = 0; i < direction_polyline.points.size() - 1; i++)
assert(direction_polyline.points[i] != direction_polyline.points[i + 1]);
direction_polyline.clip_start(SCALED_RESOLUTION);
direction_polyline.clip_end(SCALED_RESOLUTION);
coord_t dot = direction.dot(Line(direction_polyline.points.back(), direction_polyline.points.front()));
Expand Down Expand Up @@ -1950,11 +1952,12 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop,
//create new node with recursive ask for the inner perimeter & COPY of the points, ready to be cut
my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, my_loop.paths[nearest.idx_polyline_outter]);

// outer_start == outer_end
ExtrusionPath *outer_start = &my_loop.paths[nearest.idx_polyline_outter];
ExtrusionPath *outer_end = &my_loop.paths[nearest.idx_polyline_outter + 1];
Line deletedSection;

//cut our polyline
//cut our polyline, so outer_start has no common point with outer_end
//separate them
size_t nearest_idx_outter = outer_start->polyline.closest_point_index(nearest.outter_best);
if (outer_start->polyline.points[nearest_idx_outter].coincides_with_epsilon(nearest.outter_best)) {
Expand Down Expand Up @@ -2195,6 +2198,16 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop,
my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, travel_path_begin[i]);
}
}
//remove one-point extrusion
//FIXME prevent this instead of patching here?
for (int i = 0; i < my_loop.paths.size(); i++) {
if (my_loop.paths[i].polyline.size() < 2) {
if (my_loop.paths[i].polyline.size() == 1)
std::cout << "erase one-point extrusion : layer " << this->layer->id() << " " << my_loop.paths[i].polyline.points.front().x() << ":" << my_loop.paths[i].polyline.points.front().y() << "\n";
my_loop.paths.erase(my_loop.paths.begin() + i);
i--;
}
}

//update for next loop
childs.erase(childs.begin() + nearest.idx_children);
Expand Down
13 changes: 6 additions & 7 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3849,7 +3849,10 @@ void PrintConfigDef::init_fff_params()
def->set_default_value(new ConfigOptionBool(false));

def = this->add("solid_over_perimeters", coInt);
def->label = L("Max perimeters layer for solid infill");
def->label = L("No solid infill over");
def->full_label = L("No solid infill over perimeters");
def->sidetext = L("perimeters");
def->sidetext_width = 20;
def->category = OptionCategory::perimeter;
def->tooltip = L("When you have a medium/hight number of top/bottom solid layers, and a low/medium of perimeters,"
" then it have to put some solid infill inside the part to have enough solid layers."
Expand Down Expand Up @@ -6482,6 +6485,7 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co
}

//FIXME localize this function.
//note: seems only called for config export & command line. Most of the validation work for the gui is done elsewhere... So this function may be a bit out-of-sync
std::string FullPrintConfig::validate()
{
// --layer-height
Expand Down Expand Up @@ -6558,7 +6562,7 @@ std::string FullPrintConfig::validate()
// --fill-density
if (fabs(this->fill_density.value - 100.) < EPSILON &&
(! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
|| ! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
&& ! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
))
return "The selected fill pattern is not supposed to work at 100% density";

Expand All @@ -6581,11 +6585,6 @@ std::string FullPrintConfig::validate()
if (em <= 0)
return "Invalid value for --extrusion-multiplier";

// --default-acceleration
if ((this->perimeter_acceleration.value != 0. || this->infill_acceleration.value != 0. || this->bridge_acceleration.value != 0. || this->first_layer_acceleration.value != 0.) &&
this->default_acceleration.value == 0.)
return "Invalid zero value for --default-acceleration when using other acceleration settings";

// --spiral-vase
if (this->spiral_vase) {
// Note that we might want to have more than one perimeter on the bottom
Expand Down
7 changes: 4 additions & 3 deletions src/libslic3r/PrintObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1672,7 +1672,7 @@ namespace Slic3r {
size_t grain_size = std::max(num_layers / 16, size_t(1));

//solid_over_perimeters value, to remove solid fill where there's only perimeters on multiple layers
int nb_perimeter_layers_for_solid_fill = region.config().solid_over_perimeters.value;
const int nb_perimeter_layers_for_solid_fill = region.config().solid_over_perimeters.value;

if (!top_bottom_surfaces_all_regions) {
// This is either a single material print, or a multi-material print and interface_shells are enabled, meaning that the vertical shell thickness
Expand Down Expand Up @@ -1899,8 +1899,9 @@ namespace Slic3r {
//check if a polygon is only over perimeter, in this case evict it (depends from nb_perimeter_layers_for_solid_fill value)
if (nb_perimeter_layers_for_solid_fill != 0) {
for (int i = 0; i < shell.size(); i++) {
if (nb_perimeter_layers_for_solid_fill < 2 || intersection({ shell[i] }, max_perimeter_shell, false).empty()) {
toadd = intersection_ex({ shell[i] }, fill_shell);
if (nb_perimeter_layers_for_solid_fill < 2 || intersection_ex({ shell[i] }, max_perimeter_shell, false).empty()) {
ExPolygons expoly = intersection_ex({ shell[i] }, fill_shell);
toadd.insert(toadd.end(), expoly.begin(), expoly.end());
shell.erase(shell.begin() + i);
i--;
}
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/ConfigManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
toggle_field(el, have_infill_dense);

bool has_spiral_vase = have_perimeters && config->opt_bool("spiral_vase");
bool has_top_solid_infill = config->opt_int("top_solid_layers") > 0;
bool has_top_solid_infill = config->opt_int("top_solid_layers") > 0 || has_spiral_vase;
bool has_bottom_solid_infill = config->opt_int("bottom_solid_layers") > 0;
bool has_solid_infill = has_top_solid_infill || has_bottom_solid_infill || (have_infill && (config->opt_int("solid_infill_every_layers") > 0 || config->opt_float("solid_infill_below_area") > 0));
// solid_infill_extruder uses the same logic as in Print::extruders()
Expand Down
8 changes: 5 additions & 3 deletions src/slic3r/GUI/Field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,10 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
str.Replace(" ", "", true);
str.Replace("m", "", true);

if (!str.ToCDouble(&val))
{
if (m_opt.nullable && str == na_value()) {
val = ConfigOptionFloatsNullable::nil_value();
str = "nan";
} else if (!str.ToCDouble(&val)) {
if (!check_value) {
m_value.clear();
break;
Expand Down Expand Up @@ -480,7 +482,6 @@ void TextCtrl::BUILD() {
m_opt.default_value->getFloat() :
m_opt.get_default_value<ConfigOptionPercents>()->get_at(m_opt_idx);
text_value = double_to_string(val, m_opt.precision);
m_last_meaningful_value = text_value;
break;
}
case coFloatsOrPercents:
Expand All @@ -507,6 +508,7 @@ void TextCtrl::BUILD() {
default:
break;
}
m_last_meaningful_value = text_value;

const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/;
auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style);
Expand Down

0 comments on commit 02faf45

Please sign in to comment.