diff options
author | supermerill <merill@free.fr> | 2022-02-14 20:39:25 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2022-02-17 01:46:57 +0300 |
commit | 28cf299df5c0121eda73aad0275076c3fe40f6c6 (patch) | |
tree | 409245e64ffef46ce03dbf0108f8cda39b5f7bc0 /src/libslic3r | |
parent | 3d65b71f0127ccc96bbd129ccb158ddccbec36d2 (diff) |
Add "bridge type" setting.
A bit like the prusa "no thick bridges" but more powerful.
Diffstat (limited to 'src/libslic3r')
-rw-r--r-- | src/libslic3r/Fill/Fill.cpp | 17 | ||||
-rw-r--r-- | src/libslic3r/LayerRegion.cpp | 14 | ||||
-rw-r--r-- | src/libslic3r/Preset.cpp | 4 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.cpp | 16 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.hpp | 2 | ||||
-rw-r--r-- | src/libslic3r/SupportMaterial.cpp | 33 |
6 files changed, 54 insertions, 32 deletions
diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index c601a4342..0aa41de77 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -28,6 +28,7 @@ struct SurfaceFillParams : FillParams float angle = 0.f; // Non-negative for a bridge. float bridge_angle = 0.f; + BridgeType bridge_type = BridgeType::btFromNozzle; // Various print settings? @@ -43,6 +44,7 @@ struct SurfaceFillParams : FillParams if (this->bridge_angle > rhs.bridge_angle) return true; if (this->bridge_angle < rhs.bridge_angle) return false; + RETURN_COMPARE_NON_EQUAL(bridge_type); RETURN_COMPARE_NON_EQUAL(extruder); RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, pattern); RETURN_COMPARE_NON_EQUAL(spacing); @@ -69,6 +71,7 @@ struct SurfaceFillParams : FillParams this->spacing == rhs.spacing && // this->overlap == rhs.overlap && this->angle == rhs.angle && + this->bridge_type == rhs.bridge_type && this->density == rhs.density && this->monotonic == rhs.monotonic && this->connection == rhs.connection && @@ -127,8 +130,10 @@ std::vector<SurfaceFill> group_fills(const Layer &layer) if (surface.has_pos_bottom()) params.connection = region_config.infill_connection_bottom.value; //FIXME for non-thick bridges, shall we allow a bottom surface pattern? - if (is_bridge) + if (is_bridge) { params.connection = InfillConnection::icConnected; + params.bridge_type = region_config.bridge_type.value; + } if (surface.has_pos_external() && !is_bridge) params.pattern = surface.has_pos_top() ? region_config.top_fill_pattern.value : region_config.bottom_fill_pattern.value; else if (!is_bridge) @@ -193,7 +198,15 @@ std::vector<SurfaceFill> group_fills(const Layer &layer) // layerm.flow(extrusion_role, (surface.thickness == -1) ? layer.height : surface.thickness); if (is_bridge) { float nozzle_diameter = layer.object()->print()->config().nozzle_diameter.get_at(layerm.region().extruder(extrusion_role, *layer.object()) - 1); - params.flow = Flow::bridging_flow(nozzle_diameter * std::sqrt(region_config.bridge_flow_ratio.get_abs_value(1)), nozzle_diameter); + if (region_config.bridge_type == BridgeType::btFromFlow) { + Flow reference_flow = layerm.flow(FlowRole::frSolidInfill); + double diameter = sqrt(4 * reference_flow.mm3_per_mm() / PI); + params.flow = Flow::bridging_flow(float(diameter), nozzle_diameter); + } else if (region_config.bridge_type == BridgeType::btFromHeight) { + params.flow = Flow::bridging_flow(float(layerm.layer()->height), nozzle_diameter); + } else /*if (region_config.bridge_type == BridgeType::btFromNozzle)*/ { + params.flow = Flow::bridging_flow(nozzle_diameter * std::sqrt(region_config.bridge_flow_ratio.get_abs_value(1)), nozzle_diameter); + } } else params.flow = layerm.region().flow( *layer.object(), diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 59e54387c..ab561944b 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -31,11 +31,17 @@ Flow LayerRegion::bridging_flow(FlowRole role) const const PrintRegion ®ion = this->region(); const PrintRegionConfig ®ion_config = region.config(); const PrintObject &print_object = *this->layer()->object(); - if (true /*print_object.config().thick_bridges*/) { - // The old Slic3r way (different from all other slicers): Use rounded extrusions. + // Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right. + auto nozzle_diameter = float(print_object.print()->config().nozzle_diameter.get_at(region.extruder(role, *this->layer()->object()) - 1)); + if (region_config.bridge_type == BridgeType::btFromFlow) { + Flow reference_flow = flow(role); + double diameter = sqrt(4 * reference_flow.mm3_per_mm() / PI); + return Flow::bridging_flow(float(diameter), nozzle_diameter); + } else if (region_config.bridge_type == BridgeType::btFromHeight) { + return Flow::bridging_flow(float(m_layer->height), nozzle_diameter); + } else /*if (region_config.bridge_type == BridgeType::btFromNozzle)*/ { + // The good Slic3r way: Use rounded extrusions. // Get the configured nozzle_diameter for the extruder associated to the flow role requested. - // Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right. - auto nozzle_diameter = float(print_object.print()->config().nozzle_diameter.get_at(region.extruder(role, *this->layer()->object()) - 1)); // Applies default bridge spacing. return Flow::bridging_flow(float(sqrt(region_config.bridge_flow_ratio.get_abs_value(1.))) * nozzle_diameter, nozzle_diameter); } diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 7db1c37dc..4fb97b926 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -620,7 +620,9 @@ static std::vector<std::string> s_Preset_print_options { "top_infill_extrusion_width", "support_material_extrusion_width", // overlap, ratios - "infill_overlap", "bridge_flow_ratio", + "infill_overlap", + "bridge_flow_ratio", + "bridge_type", "solid_infill_overlap", "infill_anchor", "infill_anchor_max", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 499d5f4fe..56e1651b8 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -689,13 +689,13 @@ void PrintConfigDef::init_fff_params() def = this->add("bridge_type", coEnum); def->label = L("Bridge flow baseline"); def->category = OptionCategory::width; - def->tooltip = L("A brideg is an extrusion with nothing under it to flatten it, and so it can't have a 'rectangle' shape but a circle one." - "\nThe default way to compute a bridge flow is to use the nozzle diameter as the diameter of the extrusion cross-section. It shouldn't be higher than that to prevent sagging." - "\nA second way to compute a bridge flow is to use the current layer height, so it shouldn't protrude below it. Note that may create too thin extrusions and so a bad bridge quality." - "\nA Third way to compute a bridge flow is to continue to use the current flow. It's what PrusaSlicer call 'not thick bridge'. If there is no current flow, it will use the perimeter one." - " To use if you have some difficulties with the big flow changes from periemter flow to bridge flow and vice-versa." - "\nThis setting allow you to choose the base for the bridge flow compute, the result will be multiplied by the bridge flow to have the final result." - " The preview will display the expected shape of the bridge extrusion (cylinder), don't expect a magical thick and solid air to flatten the extrusion magically."); + def->tooltip = L("This setting allow you to choose the base for the bridge flow compute, the result will be multiplied by the bridge flow to have the final result." + "\nA bridge is an extrusion with nothing under it to flatten it, and so it can't have a 'rectangle' shape but a circle one." + "\n * The default way to compute a bridge flow is to use the nozzle diameter as the diameter of the extrusion cross-section. It shouldn't be higher than that to prevent sagging." + "\n * A second way to compute a bridge flow is to use the current layer height, so it shouldn't protrude below it. Note that may create too thin extrusions and so a bad bridge quality." + "\n * A Third way to compute a bridge flow is to continue to use the current section (mm3 per mm). If there is no current flow, it will use the solid infill one." + " To use if you have some difficulties with the big flow changes from perimeter and infill flow to bridge flow and vice-versa, the bridge flow ratio let you compensate for the change in speed." + " \nThe preview will display the expected shape of the bridge extrusion (cylinder), don't expect a magical thick and solid air to flatten the extrusion magically."); def->sidetext = L("%"); def->enum_keys_map = &ConfigOptionEnum<BridgeType>::get_enum_values(); def->enum_values.push_back("nozzle"); @@ -703,7 +703,7 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("flow"); def->enum_labels.push_back(L("Nozzle diameter")); def->enum_labels.push_back(L("Layer height")); - def->enum_labels.push_back(L("Keep current flow")); + def->enum_labels.push_back(L("Keep current section")); def->min = -1; def->max = 100; def->mode = comAdvanced; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index ea088ae7a..e5f411544 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -653,7 +653,6 @@ protected: \ PRINT_CONFIG_CLASS_DEFINE( PrintObjectConfig, - ((ConfigOptionEnum<BridgeType>, bridge_type)) ((ConfigOptionBool, brim_inside_holes)) ((ConfigOptionFloat, brim_width)) ((ConfigOptionFloat, brim_width_interior)) @@ -741,6 +740,7 @@ PRINT_CONFIG_CLASS_DEFINE( PrintRegionConfig, ((ConfigOptionFloat, bridge_angle)) + ((ConfigOptionEnum<BridgeType>, bridge_type)) ((ConfigOptionInt, bottom_solid_layers)) ((ConfigOptionFloat, bottom_solid_min_thickness)) ((ConfigOptionPercent, bridge_flow_ratio)) diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index d1bfa9a4a..87d99e278 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -4393,24 +4393,25 @@ void PrintObjectSupportMaterial::generate_toolpaths( }); #ifndef NDEBUG - struct Test { - static bool verify_nonempty(const ExtrusionEntityCollection *collection) { - for (const ExtrusionEntity *ee : collection->entities()) { - if (const ExtrusionPath *path = dynamic_cast<const ExtrusionPath*>(ee)) - assert(! path->empty()); - else if (const ExtrusionMultiPath *multipath = dynamic_cast<const ExtrusionMultiPath*>(ee)) - assert(! multipath->empty()); - else if (const ExtrusionEntityCollection *eecol = dynamic_cast<const ExtrusionEntityCollection*>(ee)) { - assert(! eecol->empty()); - return verify_nonempty(eecol); - } else - assert(false); - } - return true; + class verify_nonempty : public ExtrusionVisitorRecursiveConst { + public: + virtual void use(const ExtrusionPath& path) override { assert(!path.empty()); } + virtual void use(const ExtrusionPath3D& path3D) override { assert(!path3D.empty()); } + virtual void use(const ExtrusionMultiPath& truc) override { + ExtrusionVisitorRecursiveConst::use(truc); assert(!truc.empty()); + } + virtual void use(const ExtrusionMultiPath3D& truc) override { + ExtrusionVisitorRecursiveConst::use(truc); assert(!truc.empty()); + } + virtual void use(const ExtrusionLoop& truc) override { + ExtrusionVisitorRecursiveConst::use(truc); assert(!truc.paths.empty()); + } + virtual void use(const ExtrusionEntityCollection& truc) override { + ExtrusionVisitorRecursiveConst::use(truc); assert(!truc.empty()); } }; - for (const SupportLayer *support_layer : support_layers) - assert(Test::verify_nonempty(&support_layer->support_fills)); + for (const SupportLayer* support_layer : support_layers) + support_layer->support_fills.visit(verify_nonempty{}); #endif // NDEBUG } |