WIP Extending the expressivity of ExtrusionRole
Co-authored-by: supermerill <merill@free.fr> Based on the unfinished idea of @supermerill, defining ExtrusionRole as a bit mask of ExtrusionRoleModifier. Because the ExtrusionRole was used for both ExtrusionEntity and G-code export / G-code viewer, the original ExtrusionRole had to be split to ExtrusionRole and GCodeExtrusionRole to support bitmask attributes for the former while keeing a low number of ordinary values for the latter.
This commit is contained in:
parent
661463645b
commit
5991850db1
@ -490,7 +490,7 @@ static void make_inner_brim(const Print &print,
|
|||||||
|
|
||||||
loops = union_pt_chained_outside_in(loops);
|
loops = union_pt_chained_outside_in(loops);
|
||||||
std::reverse(loops.begin(), loops.end());
|
std::reverse(loops.begin(), loops.end());
|
||||||
extrusion_entities_append_loops(brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()),
|
extrusion_entities_append_loops(brim.entities, std::move(loops), ExtrusionRole::Skirt, float(flow.mm3_per_mm()),
|
||||||
float(flow.width()), float(print.skirt_first_layer_height()));
|
float(flow.width()), float(print.skirt_first_layer_height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,7 +672,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
|||||||
if (i + 1 == j && first_path.size() > 3 && first_path.front().x() == first_path.back().x() && first_path.front().y() == first_path.back().y()) {
|
if (i + 1 == j && first_path.size() > 3 && first_path.front().x() == first_path.back().x() && first_path.front().y() == first_path.back().y()) {
|
||||||
auto *loop = new ExtrusionLoop();
|
auto *loop = new ExtrusionLoop();
|
||||||
brim.entities.emplace_back(loop);
|
brim.entities.emplace_back(loop);
|
||||||
loop->paths.emplace_back(erSkirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height()));
|
loop->paths.emplace_back(ExtrusionRole::Skirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height()));
|
||||||
Points &points = loop->paths.front().polyline.points;
|
Points &points = loop->paths.front().polyline.points;
|
||||||
points.reserve(first_path.size());
|
points.reserve(first_path.size());
|
||||||
for (const ClipperLib_Z::IntPoint &pt : first_path)
|
for (const ClipperLib_Z::IntPoint &pt : first_path)
|
||||||
@ -683,7 +683,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
|||||||
ExtrusionEntityCollection this_loop_trimmed;
|
ExtrusionEntityCollection this_loop_trimmed;
|
||||||
this_loop_trimmed.entities.reserve(j - i);
|
this_loop_trimmed.entities.reserve(j - i);
|
||||||
for (; i < j; ++ i) {
|
for (; i < j; ++ i) {
|
||||||
this_loop_trimmed.entities.emplace_back(new ExtrusionPath(erSkirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height())));
|
this_loop_trimmed.entities.emplace_back(new ExtrusionPath(ExtrusionRole::Skirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height())));
|
||||||
const ClipperLib_Z::Path &path = *loops_trimmed_order[i].first;
|
const ClipperLib_Z::Path &path = *loops_trimmed_order[i].first;
|
||||||
Points &points = dynamic_cast<ExtrusionPath*>(this_loop_trimmed.entities.back())->polyline.points;
|
Points &points = dynamic_cast<ExtrusionPath*>(this_loop_trimmed.entities.back())->polyline.points;
|
||||||
points.reserve(path.size());
|
points.reserve(path.size());
|
||||||
@ -699,7 +699,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
extrusion_entities_append_loops_and_paths(brim.entities, std::move(all_loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height()));
|
extrusion_entities_append_loops_and_paths(brim.entities, std::move(all_loops), ExtrusionRole::Skirt, float(flow.mm3_per_mm()), float(flow.width()), float(print.skirt_first_layer_height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
make_inner_brim(print, top_level_objects_with_brim, bottom_layers_expolygons, brim);
|
make_inner_brim(print, top_level_objects_with_brim, bottom_layers_expolygons, brim);
|
||||||
|
@ -322,8 +322,29 @@ double ExtrusionLoop::min_mm3_per_mm() const
|
|||||||
return min_mm3_per_mm;
|
return min_mm3_per_mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert a rich bitmask based ExtrusionRole to a less expressive ordinal GCodeExtrusionRole.
|
||||||
|
// GCodeExtrusionRole is to be serialized into G-code and deserialized by G-code viewer,
|
||||||
|
GCodeExtrusionRole extrusion_role_to_gcode_extrusion_role(ExtrusionRole role)
|
||||||
|
{
|
||||||
|
if (role == ExtrusionRole::None) return erNone;
|
||||||
|
if (role == ExtrusionRole::Perimeter) return erPerimeter;
|
||||||
|
if (role == ExtrusionRole::ExternalPerimeter) return erExternalPerimeter;
|
||||||
|
if (role == ExtrusionRole::OverhangPerimeter) return erOverhangPerimeter;
|
||||||
|
if (role == ExtrusionRole::InternalInfill) return erInternalInfill;
|
||||||
|
if (role == ExtrusionRole::SolidInfill) return erSolidInfill;
|
||||||
|
if (role == ExtrusionRole::TopSolidInfill) return erTopSolidInfill;
|
||||||
|
if (role == ExtrusionRole::Ironing) return erIroning;
|
||||||
|
if (role == ExtrusionRole::BridgeInfill) return erBridgeInfill;
|
||||||
|
if (role == ExtrusionRole::GapFill) return erGapFill;
|
||||||
|
if (role == ExtrusionRole::Skirt) return erSkirt;
|
||||||
|
if (role == ExtrusionRole::SupportMaterial) return erSupportMaterial;
|
||||||
|
if (role == ExtrusionRole::SupportMaterialInterface) return erSupportMaterialInterface;
|
||||||
|
if (role == ExtrusionRole::WipeTower) return erWipeTower;
|
||||||
|
assert(false);
|
||||||
|
return erNone;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
|
std::string gcode_extrusion_role_to_string(GCodeExtrusionRole role)
|
||||||
{
|
{
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case erNone : return L("Unknown");
|
case erNone : return L("Unknown");
|
||||||
@ -341,13 +362,12 @@ std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
|
|||||||
case erSupportMaterialInterface : return L("Support material interface");
|
case erSupportMaterialInterface : return L("Support material interface");
|
||||||
case erWipeTower : return L("Wipe tower");
|
case erWipeTower : return L("Wipe tower");
|
||||||
case erCustom : return L("Custom");
|
case erCustom : return L("Custom");
|
||||||
case erMixed : return L("Mixed");
|
|
||||||
default : assert(false);
|
default : assert(false);
|
||||||
}
|
}
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtrusionRole ExtrusionEntity::string_to_role(const std::string_view role)
|
GCodeExtrusionRole string_to_gcode_extrusion_role(const std::string_view role)
|
||||||
{
|
{
|
||||||
if (role == L("Perimeter"))
|
if (role == L("Perimeter"))
|
||||||
return erPerimeter;
|
return erPerimeter;
|
||||||
@ -377,8 +397,6 @@ ExtrusionRole ExtrusionEntity::string_to_role(const std::string_view role)
|
|||||||
return erWipeTower;
|
return erWipeTower;
|
||||||
else if (role == L("Custom"))
|
else if (role == L("Custom"))
|
||||||
return erCustom;
|
return erCustom;
|
||||||
else if (role == L("Mixed"))
|
|
||||||
return erMixed;
|
|
||||||
else
|
else
|
||||||
return erNone;
|
return erNone;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
#include "Polygon.hpp"
|
#include "Polygon.hpp"
|
||||||
#include "Polyline.hpp"
|
#include "Polyline.hpp"
|
||||||
|
#include "enum_bitmask.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@ -16,8 +17,113 @@ using ExPolygons = std::vector<ExPolygon>;
|
|||||||
class ExtrusionEntityCollection;
|
class ExtrusionEntityCollection;
|
||||||
class Extruder;
|
class Extruder;
|
||||||
|
|
||||||
// Each ExtrusionRole value identifies a distinct set of { extruder, speed }
|
enum class ExtrusionRoleModifier : uint16_t {
|
||||||
enum ExtrusionRole : uint8_t {
|
// 1) Extrusion types
|
||||||
|
// Perimeter (external, inner, ...)
|
||||||
|
Perimeter,
|
||||||
|
// Infill (top / bottom / solid inner / sparse inner / bridging inner ...)
|
||||||
|
Infill,
|
||||||
|
// Variable width extrusion
|
||||||
|
Thin,
|
||||||
|
// Support material extrusion
|
||||||
|
Support,
|
||||||
|
Skirt,
|
||||||
|
Wipe,
|
||||||
|
// 2) Extrusion modifiers
|
||||||
|
External,
|
||||||
|
Solid,
|
||||||
|
Ironing,
|
||||||
|
Bridge,
|
||||||
|
// 3) Special types
|
||||||
|
// Indicator that the extrusion role was mixed from multiple differing extrusion roles,
|
||||||
|
// for example from Support and SupportInterface.
|
||||||
|
Mixed,
|
||||||
|
// Stopper, there should be maximum 16 modifiers defined for uint16_t bit mask.
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
// There should be maximum 16 modifiers defined for uint16_t bit mask.
|
||||||
|
static_assert(int(ExtrusionRoleModifier::Count) <= 16, "ExtrusionRoleModifier: there must be maximum 16 modifiers defined to fit a 16 bit bitmask");
|
||||||
|
|
||||||
|
using ExtrusionRoleModifiers = enum_bitmask<ExtrusionRoleModifier>;
|
||||||
|
ENABLE_ENUM_BITMASK_OPERATORS(ExtrusionRoleModifier);
|
||||||
|
|
||||||
|
struct ExtrusionRole : public ExtrusionRoleModifiers
|
||||||
|
{
|
||||||
|
constexpr ExtrusionRole(const ExtrusionRoleModifier bit) : ExtrusionRoleModifiers(bit) {}
|
||||||
|
constexpr ExtrusionRole(const ExtrusionRoleModifiers bits) : ExtrusionRoleModifiers(bits) {}
|
||||||
|
|
||||||
|
static constexpr const ExtrusionRoleModifiers None{};
|
||||||
|
// Internal perimeter, not bridging.
|
||||||
|
static constexpr const ExtrusionRoleModifiers Perimeter{ ExtrusionRoleModifier::Perimeter };
|
||||||
|
// External perimeter, not bridging.
|
||||||
|
static constexpr const ExtrusionRoleModifiers ExternalPerimeter{ ExtrusionRoleModifier::Perimeter | ExtrusionRoleModifier::External };
|
||||||
|
// Perimeter, bridging. To be or'ed with ExtrusionRoleModifier::External for external bridging perimeter.
|
||||||
|
static constexpr const ExtrusionRoleModifiers OverhangPerimeter{ ExtrusionRoleModifier::Perimeter | ExtrusionRoleModifier::Bridge };
|
||||||
|
// Sparse internal infill.
|
||||||
|
static constexpr const ExtrusionRoleModifiers InternalInfill{ ExtrusionRoleModifier::Infill };
|
||||||
|
// Solid internal infill.
|
||||||
|
static constexpr const ExtrusionRoleModifiers SolidInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid };
|
||||||
|
// Top solid infill (visible).
|
||||||
|
//FIXME why there is no bottom solid infill type?
|
||||||
|
static constexpr const ExtrusionRoleModifiers TopSolidInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::External };
|
||||||
|
// Ironing infill at the top surfaces.
|
||||||
|
static constexpr const ExtrusionRoleModifiers Ironing{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Ironing | ExtrusionRoleModifier::External };
|
||||||
|
// Visible bridging infill at the bottom of an object.
|
||||||
|
static constexpr const ExtrusionRoleModifiers BridgeInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::Bridge | ExtrusionRoleModifier::External };
|
||||||
|
// static constexpr const ExtrusionRoleModifiers InternalBridgeInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::Bridge };
|
||||||
|
// Gap fill extrusion, currently used for any variable width extrusion: Thin walls outside of the outer extrusion,
|
||||||
|
// gap fill in between perimeters, gap fill between the inner perimeter and infill.
|
||||||
|
//FIXME revise GapFill and ThinWall types, split Gap Fill to Gap Fill and ThinWall.
|
||||||
|
static constexpr const ExtrusionRoleModifiers GapFill{ ExtrusionRoleModifier::Thin }; // | ExtrusionRoleModifier::External };
|
||||||
|
// static constexpr const ExtrusionRoleModifiers ThinWall{ ExtrusionRoleModifier::Thin };
|
||||||
|
static constexpr const ExtrusionRoleModifiers Skirt{ ExtrusionRoleModifier::Skirt };
|
||||||
|
// Support base material, printed with non-soluble plastic.
|
||||||
|
static constexpr const ExtrusionRoleModifiers SupportMaterial{ ExtrusionRoleModifier::Support };
|
||||||
|
// Support interface material, printed with soluble plastic.
|
||||||
|
static constexpr const ExtrusionRoleModifiers SupportMaterialInterface{ ExtrusionRoleModifier::Support | ExtrusionRoleModifier::External };
|
||||||
|
// Wipe tower material.
|
||||||
|
static constexpr const ExtrusionRoleModifiers WipeTower{ ExtrusionRoleModifier::Wipe };
|
||||||
|
// Extrusion role for a collection with multiple extrusion roles.
|
||||||
|
static constexpr const ExtrusionRoleModifiers Mixed{ ExtrusionRoleModifier::Mixed };
|
||||||
|
};
|
||||||
|
|
||||||
|
// Special flags describing loop
|
||||||
|
enum ExtrusionLoopRole {
|
||||||
|
elrDefault,
|
||||||
|
elrContourInternalPerimeter,
|
||||||
|
elrSkirt,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool is_perimeter(ExtrusionRole role)
|
||||||
|
{
|
||||||
|
return role == ExtrusionRole::Perimeter
|
||||||
|
|| role == ExtrusionRole::ExternalPerimeter
|
||||||
|
|| role == ExtrusionRole::OverhangPerimeter;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_infill(ExtrusionRole role)
|
||||||
|
{
|
||||||
|
return role == ExtrusionRole::BridgeInfill
|
||||||
|
|| role == ExtrusionRole::InternalInfill
|
||||||
|
|| role == ExtrusionRole::SolidInfill
|
||||||
|
|| role == ExtrusionRole::TopSolidInfill
|
||||||
|
|| role == ExtrusionRole::Ironing;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_solid_infill(ExtrusionRole role)
|
||||||
|
{
|
||||||
|
return role == ExtrusionRole::BridgeInfill
|
||||||
|
|| role == ExtrusionRole::SolidInfill
|
||||||
|
|| role == ExtrusionRole::TopSolidInfill
|
||||||
|
|| role == ExtrusionRole::Ironing;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_bridge(ExtrusionRole role) {
|
||||||
|
return role == ExtrusionRole::BridgeInfill
|
||||||
|
|| role == ExtrusionRole::OverhangPerimeter;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum GCodeExtrusionRole : uint8_t {
|
||||||
erNone,
|
erNone,
|
||||||
erPerimeter,
|
erPerimeter,
|
||||||
erExternalPerimeter,
|
erExternalPerimeter,
|
||||||
@ -32,49 +138,12 @@ enum ExtrusionRole : uint8_t {
|
|||||||
erSupportMaterial,
|
erSupportMaterial,
|
||||||
erSupportMaterialInterface,
|
erSupportMaterialInterface,
|
||||||
erWipeTower,
|
erWipeTower,
|
||||||
|
// Custom (user defined) G-code block, for example start / end G-code.
|
||||||
erCustom,
|
erCustom,
|
||||||
// Extrusion role for a collection with multiple extrusion roles.
|
// Stopper to count number of enums.
|
||||||
erMixed,
|
|
||||||
erCount
|
erCount
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special flags describing loop
|
|
||||||
enum ExtrusionLoopRole {
|
|
||||||
elrDefault,
|
|
||||||
elrContourInternalPerimeter,
|
|
||||||
elrSkirt,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline bool is_perimeter(ExtrusionRole role)
|
|
||||||
{
|
|
||||||
return role == erPerimeter
|
|
||||||
|| role == erExternalPerimeter
|
|
||||||
|| role == erOverhangPerimeter;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool is_infill(ExtrusionRole role)
|
|
||||||
{
|
|
||||||
return role == erBridgeInfill
|
|
||||||
|| role == erInternalInfill
|
|
||||||
|| role == erSolidInfill
|
|
||||||
|| role == erTopSolidInfill
|
|
||||||
|| role == erIroning;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool is_solid_infill(ExtrusionRole role)
|
|
||||||
{
|
|
||||||
return role == erBridgeInfill
|
|
||||||
|| role == erSolidInfill
|
|
||||||
|| role == erTopSolidInfill
|
|
||||||
|| role == erIroning;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool is_bridge(ExtrusionRole role) {
|
|
||||||
return role == erBridgeInfill
|
|
||||||
|| role == erOverhangPerimeter;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ExtrusionEntity
|
class ExtrusionEntity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -108,11 +177,15 @@ public:
|
|||||||
virtual Polylines as_polylines() const { Polylines dst; this->collect_polylines(dst); return dst; }
|
virtual Polylines as_polylines() const { Polylines dst; this->collect_polylines(dst); return dst; }
|
||||||
virtual double length() const = 0;
|
virtual double length() const = 0;
|
||||||
virtual double total_volume() const = 0;
|
virtual double total_volume() const = 0;
|
||||||
|
|
||||||
static std::string role_to_string(ExtrusionRole role);
|
|
||||||
static ExtrusionRole string_to_role(const std::string_view role);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Convert a rich bitmask based ExtrusionRole to a less expressive ordinal GCodeExtrusionRole.
|
||||||
|
// GCodeExtrusionRole is to be serialized into G-code and deserialized by G-code viewer,
|
||||||
|
GCodeExtrusionRole extrusion_role_to_gcode_extrusion_role(ExtrusionRole role);
|
||||||
|
|
||||||
|
std::string gcode_extrusion_role_to_string(GCodeExtrusionRole role);
|
||||||
|
GCodeExtrusionRole string_to_gcode_extrusion_role(const std::string_view role);
|
||||||
|
|
||||||
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
|
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
|
||||||
|
|
||||||
class ExtrusionPath : public ExtrusionEntity
|
class ExtrusionPath : public ExtrusionEntity
|
||||||
@ -217,7 +290,7 @@ public:
|
|||||||
size_t size() const { return this->paths.size(); }
|
size_t size() const { return this->paths.size(); }
|
||||||
bool empty() const { return this->paths.empty(); }
|
bool empty() const { return this->paths.empty(); }
|
||||||
double length() const override;
|
double length() const override;
|
||||||
ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); }
|
ExtrusionRole role() const override { return this->paths.empty() ? ExtrusionRole::None : this->paths.front().role(); }
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
|
||||||
@ -279,7 +352,7 @@ public:
|
|||||||
// Test, whether the point is extruded by a bridging flow.
|
// Test, whether the point is extruded by a bridging flow.
|
||||||
// This used to be used to avoid placing seams on overhangs, but now the EdgeGrid is used instead.
|
// This used to be used to avoid placing seams on overhangs, but now the EdgeGrid is used instead.
|
||||||
bool has_overhang_point(const Point &point) const;
|
bool has_overhang_point(const Point &point) const;
|
||||||
ExtrusionRole role() const override { return this->paths.empty() ? erNone : this->paths.front().role(); }
|
ExtrusionRole role() const override { return this->paths.empty() ? ExtrusionRole::None : this->paths.front().role(); }
|
||||||
ExtrusionLoopRole loop_role() const { return m_loop_role; }
|
ExtrusionLoopRole loop_role() const { return m_loop_role; }
|
||||||
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
|
||||||
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
|
||||||
@ -304,8 +377,6 @@ public:
|
|||||||
}
|
}
|
||||||
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
||||||
|
|
||||||
//static inline std::string role_to_string(ExtrusionLoopRole role);
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
bool validate() const {
|
bool validate() const {
|
||||||
assert(this->first_point() == this->paths.back().polyline.points.back());
|
assert(this->first_point() == this->paths.back().polyline.points.back());
|
||||||
|
@ -8,7 +8,7 @@ namespace Slic3r {
|
|||||||
|
|
||||||
void filter_by_extrusion_role_in_place(ExtrusionEntitiesPtr &extrusion_entities, ExtrusionRole role)
|
void filter_by_extrusion_role_in_place(ExtrusionEntitiesPtr &extrusion_entities, ExtrusionRole role)
|
||||||
{
|
{
|
||||||
if (role != erMixed) {
|
if (role != ExtrusionRole::Mixed) {
|
||||||
auto first = extrusion_entities.begin();
|
auto first = extrusion_entities.begin();
|
||||||
auto last = extrusion_entities.end();
|
auto last = extrusion_entities.end();
|
||||||
extrusion_entities.erase(
|
extrusion_entities.erase(
|
||||||
|
@ -54,10 +54,10 @@ public:
|
|||||||
|
|
||||||
bool is_collection() const override { return true; }
|
bool is_collection() const override { return true; }
|
||||||
ExtrusionRole role() const override {
|
ExtrusionRole role() const override {
|
||||||
ExtrusionRole out = erNone;
|
ExtrusionRole out{ ExtrusionRole::None };
|
||||||
for (const ExtrusionEntity *ee : entities) {
|
for (const ExtrusionEntity *ee : entities) {
|
||||||
ExtrusionRole er = ee->role();
|
ExtrusionRole er = ee->role();
|
||||||
out = (out == erNone || out == er) ? er : erMixed;
|
out = (out == ExtrusionRole::None || out == er) ? er : ExtrusionRole::Mixed;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -96,8 +96,8 @@ public:
|
|||||||
}
|
}
|
||||||
void replace(size_t i, const ExtrusionEntity &entity);
|
void replace(size_t i, const ExtrusionEntity &entity);
|
||||||
void remove(size_t i);
|
void remove(size_t i);
|
||||||
static ExtrusionEntityCollection chained_path_from(const ExtrusionEntitiesPtr &extrusion_entities, const Point &start_near, ExtrusionRole role = erMixed);
|
static ExtrusionEntityCollection chained_path_from(const ExtrusionEntitiesPtr &extrusion_entities, const Point &start_near, ExtrusionRole role = ExtrusionRole::Mixed);
|
||||||
ExtrusionEntityCollection chained_path_from(const Point &start_near, ExtrusionRole role = erMixed) const
|
ExtrusionEntityCollection chained_path_from(const Point &start_near, ExtrusionRole role = ExtrusionRole::Mixed) const
|
||||||
{ return this->no_sort ? *this : chained_path_from(this->entities, start_near, role); }
|
{ return this->no_sort ? *this : chained_path_from(this->entities, start_near, role); }
|
||||||
void reverse() override;
|
void reverse() override;
|
||||||
const Point& first_point() const override { return this->entities.front()->first_point(); }
|
const Point& first_point() const override { return this->entities.front()->first_point(); }
|
||||||
|
@ -52,7 +52,7 @@ struct SurfaceFillParams
|
|||||||
Flow flow;
|
Flow flow;
|
||||||
|
|
||||||
// For the output
|
// For the output
|
||||||
ExtrusionRole extrusion_role = ExtrusionRole(0);
|
ExtrusionRole extrusion_role{ ExtrusionRole::None };
|
||||||
|
|
||||||
// Various print settings?
|
// Various print settings?
|
||||||
|
|
||||||
@ -81,8 +81,7 @@ struct SurfaceFillParams
|
|||||||
RETURN_COMPARE_NON_EQUAL(flow.height());
|
RETURN_COMPARE_NON_EQUAL(flow.height());
|
||||||
RETURN_COMPARE_NON_EQUAL(flow.nozzle_diameter());
|
RETURN_COMPARE_NON_EQUAL(flow.nozzle_diameter());
|
||||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, bridge);
|
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, bridge);
|
||||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, extrusion_role);
|
return this->extrusion_role.lower(rhs.extrusion_role);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const SurfaceFillParams &rhs) const {
|
bool operator==(const SurfaceFillParams &rhs) const {
|
||||||
@ -145,10 +144,10 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||||||
|
|
||||||
params.extrusion_role =
|
params.extrusion_role =
|
||||||
is_bridge ?
|
is_bridge ?
|
||||||
erBridgeInfill :
|
ExtrusionRole::BridgeInfill :
|
||||||
(surface.is_solid() ?
|
(surface.is_solid() ?
|
||||||
(surface.is_top() ? erTopSolidInfill : erSolidInfill) :
|
(surface.is_top() ? ExtrusionRole::TopSolidInfill : ExtrusionRole::SolidInfill) :
|
||||||
erInternalInfill);
|
ExtrusionRole::InternalInfill);
|
||||||
params.bridge_angle = float(surface.bridge_angle);
|
params.bridge_angle = float(surface.bridge_angle);
|
||||||
params.angle = float(Geometry::deg2rad(region_config.fill_angle.value));
|
params.angle = float(Geometry::deg2rad(region_config.fill_angle.value));
|
||||||
|
|
||||||
@ -282,7 +281,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||||||
params.extruder = layerm.region().extruder(frSolidInfill);
|
params.extruder = layerm.region().extruder(frSolidInfill);
|
||||||
params.pattern = layerm.region().config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
|
params.pattern = layerm.region().config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
|
||||||
params.density = 100.f;
|
params.density = 100.f;
|
||||||
params.extrusion_role = erInternalInfill;
|
params.extrusion_role = ExtrusionRole::InternalInfill;
|
||||||
params.angle = float(Geometry::deg2rad(layerm.region().config().fill_angle.value));
|
params.angle = float(Geometry::deg2rad(layerm.region().config().fill_angle.value));
|
||||||
// calculate the actual flow we'll be using for this infill
|
// calculate the actual flow we'll be using for this infill
|
||||||
params.flow = layerm.flow(frSolidInfill);
|
params.flow = layerm.flow(frSolidInfill);
|
||||||
@ -785,7 +784,7 @@ void Layer::make_ironing()
|
|||||||
eec->no_sort = true;
|
eec->no_sort = true;
|
||||||
extrusion_entities_append_paths(
|
extrusion_entities_append_paths(
|
||||||
eec->entities, std::move(polylines),
|
eec->entities, std::move(polylines),
|
||||||
erIroning,
|
ExtrusionRole::Ironing,
|
||||||
flow_mm3_per_mm, extrusion_width, float(extrusion_height));
|
flow_mm3_per_mm, extrusion_width, float(extrusion_height));
|
||||||
insert_fills_into_islands(*this, ironing_params.region_id, fill_begin, uint32_t(ironing_params.layerm->fills().size()));
|
insert_fills_into_islands(*this, ironing_params.region_id, fill_begin, uint32_t(ironing_params.layerm->fills().size()));
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ namespace Slic3r {
|
|||||||
int
|
int
|
||||||
OozePrevention::_get_temp(GCode& gcodegen)
|
OozePrevention::_get_temp(GCode& gcodegen)
|
||||||
{
|
{
|
||||||
return (gcodegen.layer() != NULL && gcodegen.layer()->id() == 0)
|
return (gcodegen.layer() != nullptr && gcodegen.layer()->id() == 0)
|
||||||
? gcodegen.config().first_layer_temperature.get_at(gcodegen.writer().extruder()->id())
|
? gcodegen.config().first_layer_temperature.get_at(gcodegen.writer().extruder()->id())
|
||||||
: gcodegen.config().temperature.get_at(gcodegen.writer().extruder()->id());
|
: gcodegen.config().temperature.get_at(gcodegen.writer().extruder()->id());
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ namespace Slic3r {
|
|||||||
gcodegen.m_avoid_crossing_perimeters.use_external_mp_once();
|
gcodegen.m_avoid_crossing_perimeters.use_external_mp_once();
|
||||||
gcode += gcodegen.travel_to(
|
gcode += gcodegen.travel_to(
|
||||||
wipe_tower_point_to_object_point(gcodegen, start_pos),
|
wipe_tower_point_to_object_point(gcodegen, start_pos),
|
||||||
erMixed,
|
ExtrusionRole::Mixed,
|
||||||
"Travel to a Wipe Tower");
|
"Travel to a Wipe Tower");
|
||||||
gcode += gcodegen.unretract();
|
gcode += gcodegen.unretract();
|
||||||
}
|
}
|
||||||
@ -864,7 +864,7 @@ namespace DoExport {
|
|||||||
auto min_mm3_per_mm_no_ironing = [](const ExtrusionEntityCollection& eec) -> double {
|
auto min_mm3_per_mm_no_ironing = [](const ExtrusionEntityCollection& eec) -> double {
|
||||||
double min = std::numeric_limits<double>::max();
|
double min = std::numeric_limits<double>::max();
|
||||||
for (const ExtrusionEntity* ee : eec.entities)
|
for (const ExtrusionEntity* ee : eec.entities)
|
||||||
if (ee->role() != erIroning)
|
if (ee->role() != ExtrusionRole::Ironing)
|
||||||
min = std::min(min, ee->min_mm3_per_mm());
|
min = std::min(min, ee->min_mm3_per_mm());
|
||||||
return min;
|
return min;
|
||||||
};
|
};
|
||||||
@ -1271,7 +1271,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||||||
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false);
|
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false);
|
||||||
|
|
||||||
// adds tag for processor
|
// adds tag for processor
|
||||||
file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str());
|
file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), gcode_extrusion_role_to_string(erCustom).c_str());
|
||||||
|
|
||||||
// Write the custom start G-code
|
// Write the custom start G-code
|
||||||
file.writeln(start_gcode);
|
file.writeln(start_gcode);
|
||||||
@ -1320,7 +1320,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||||||
m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer
|
m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer
|
||||||
m_avoid_crossing_perimeters.use_external_mp_once();
|
m_avoid_crossing_perimeters.use_external_mp_once();
|
||||||
file.write(this->retract());
|
file.write(this->retract());
|
||||||
file.write(this->travel_to(Point(0, 0), erNone, "move to origin position for next object"));
|
file.write(this->travel_to(Point(0, 0), ExtrusionRole::None, "move to origin position for next object"));
|
||||||
m_enable_cooling_markers = true;
|
m_enable_cooling_markers = true;
|
||||||
// Disable motion planner when traveling to first object point.
|
// Disable motion planner when traveling to first object point.
|
||||||
m_avoid_crossing_perimeters.disable_once();
|
m_avoid_crossing_perimeters.disable_once();
|
||||||
@ -1407,7 +1407,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
|||||||
file.write(m_writer.set_fan(0));
|
file.write(m_writer.set_fan(0));
|
||||||
|
|
||||||
// adds tag for processor
|
// adds tag for processor
|
||||||
file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str());
|
file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), gcode_extrusion_role_to_string(erCustom).c_str());
|
||||||
|
|
||||||
// Process filament-specific gcode in extruder order.
|
// Process filament-specific gcode in extruder order.
|
||||||
{
|
{
|
||||||
@ -2305,8 +2305,8 @@ void GCode::process_layer_single_object(
|
|||||||
if (! print_wipe_extrusions && layer_to_print.support_layer != nullptr)
|
if (! print_wipe_extrusions && layer_to_print.support_layer != nullptr)
|
||||||
if (const SupportLayer &support_layer = *layer_to_print.support_layer; ! support_layer.support_fills.entities.empty()) {
|
if (const SupportLayer &support_layer = *layer_to_print.support_layer; ! support_layer.support_fills.entities.empty()) {
|
||||||
ExtrusionRole role = support_layer.support_fills.role();
|
ExtrusionRole role = support_layer.support_fills.role();
|
||||||
bool has_support = role == erMixed || role == erSupportMaterial;
|
bool has_support = role == ExtrusionRole::Mixed || role == ExtrusionRole::SupportMaterial;
|
||||||
bool has_interface = role == erMixed || role == erSupportMaterialInterface;
|
bool has_interface = role == ExtrusionRole::Mixed || role == ExtrusionRole::SupportMaterialInterface;
|
||||||
// Extruder ID of the support base. -1 if "don't care".
|
// Extruder ID of the support base. -1 if "don't care".
|
||||||
unsigned int support_extruder = print_object.config().support_material_extruder.value - 1;
|
unsigned int support_extruder = print_object.config().support_material_extruder.value - 1;
|
||||||
// Shall the support be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
|
// Shall the support be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
|
||||||
@ -2340,8 +2340,8 @@ void GCode::process_layer_single_object(
|
|||||||
m_layer = layer_to_print.support_layer;
|
m_layer = layer_to_print.support_layer;
|
||||||
m_object_layer_over_raft = false;
|
m_object_layer_over_raft = false;
|
||||||
gcode += this->extrude_support(
|
gcode += this->extrude_support(
|
||||||
// support_extrusion_role is erSupportMaterial, erSupportMaterialInterface or erMixed for all extrusion paths.
|
// support_extrusion_role is ExtrusionRole::SupportMaterial, ExtrusionRole::SupportMaterialInterface or ExtrusionRole::Mixed for all extrusion paths.
|
||||||
support_layer.support_fills.chained_path_from(m_last_pos, has_support ? (has_interface ? erMixed : erSupportMaterial) : erSupportMaterialInterface));
|
support_layer.support_fills.chained_path_from(m_last_pos, has_support ? (has_interface ? ExtrusionRole::Mixed : ExtrusionRole::SupportMaterial) : ExtrusionRole::SupportMaterialInterface));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2385,7 +2385,7 @@ void GCode::process_layer_single_object(
|
|||||||
for (uint32_t fill_id : *it_fill_range) {
|
for (uint32_t fill_id : *it_fill_range) {
|
||||||
assert(dynamic_cast<ExtrusionEntityCollection*>(fills.entities[fill_id]));
|
assert(dynamic_cast<ExtrusionEntityCollection*>(fills.entities[fill_id]));
|
||||||
if (auto *eec = static_cast<ExtrusionEntityCollection*>(fills.entities[fill_id]);
|
if (auto *eec = static_cast<ExtrusionEntityCollection*>(fills.entities[fill_id]);
|
||||||
(eec->role() == erIroning) == ironing && shall_print_this_extrusion_collection(eec, region)) {
|
(eec->role() == ExtrusionRole::Ironing) == ironing && shall_print_this_extrusion_collection(eec, region)) {
|
||||||
if (eec->can_reverse())
|
if (eec->can_reverse())
|
||||||
// Flatten the infill collection for better path planning.
|
// Flatten the infill collection for better path planning.
|
||||||
for (auto *ee : eec->entities)
|
for (auto *ee : eec->entities)
|
||||||
@ -2631,7 +2631,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, const std::string_view descr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make a little move inwards before leaving loop
|
// make a little move inwards before leaving loop
|
||||||
if (paths.back().role() == erExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 3) {
|
if (paths.back().role() == ExtrusionRole::ExternalPerimeter && m_layer != NULL && m_config.perimeters.value > 1 && paths.front().size() >= 2 && paths.back().polyline.points.size() >= 3) {
|
||||||
// detect angle between last and first segment
|
// detect angle between last and first segment
|
||||||
// the side depends on the original winding order of the polygon (left for contours, right for holes)
|
// the side depends on the original winding order of the polygon (left for contours, right for holes)
|
||||||
//FIXME improve the algorithm in case the loop is tiny.
|
//FIXME improve the algorithm in case the loop is tiny.
|
||||||
@ -2739,9 +2739,9 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
|
|||||||
const double support_interface_speed = m_config.support_material_interface_speed.get_abs_value(support_speed);
|
const double support_interface_speed = m_config.support_material_interface_speed.get_abs_value(support_speed);
|
||||||
for (const ExtrusionEntity *ee : support_fills.entities) {
|
for (const ExtrusionEntity *ee : support_fills.entities) {
|
||||||
ExtrusionRole role = ee->role();
|
ExtrusionRole role = ee->role();
|
||||||
assert(role == erSupportMaterial || role == erSupportMaterialInterface);
|
assert(role == ExtrusionRole::SupportMaterial || role == ExtrusionRole::SupportMaterialInterface);
|
||||||
const auto label = (role == erSupportMaterial) ? support_label : support_interface_label;
|
const auto label = (role == ExtrusionRole::SupportMaterial) ? support_label : support_interface_label;
|
||||||
const double speed = (role == erSupportMaterial) ? support_speed : support_interface_speed;
|
const double speed = (role == ExtrusionRole::SupportMaterial) ? support_speed : support_interface_speed;
|
||||||
const ExtrusionPath *path = dynamic_cast<const ExtrusionPath*>(ee);
|
const ExtrusionPath *path = dynamic_cast<const ExtrusionPath*>(ee);
|
||||||
if (path)
|
if (path)
|
||||||
gcode += this->extrude_path(*path, label, speed);
|
gcode += this->extrude_path(*path, label, speed);
|
||||||
@ -2872,21 +2872,21 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
|
|
||||||
// set speed
|
// set speed
|
||||||
if (speed == -1) {
|
if (speed == -1) {
|
||||||
if (path.role() == erPerimeter) {
|
if (path.role() == ExtrusionRole::Perimeter) {
|
||||||
speed = m_config.get_abs_value("perimeter_speed");
|
speed = m_config.get_abs_value("perimeter_speed");
|
||||||
} else if (path.role() == erExternalPerimeter) {
|
} else if (path.role() == ExtrusionRole::ExternalPerimeter) {
|
||||||
speed = m_config.get_abs_value("external_perimeter_speed");
|
speed = m_config.get_abs_value("external_perimeter_speed");
|
||||||
} else if (path.role() == erOverhangPerimeter || path.role() == erBridgeInfill) {
|
} else if (path.role() == ExtrusionRole::OverhangPerimeter || path.role() == ExtrusionRole::BridgeInfill) {
|
||||||
speed = m_config.get_abs_value("bridge_speed");
|
speed = m_config.get_abs_value("bridge_speed");
|
||||||
} else if (path.role() == erInternalInfill) {
|
} else if (path.role() == ExtrusionRole::InternalInfill) {
|
||||||
speed = m_config.get_abs_value("infill_speed");
|
speed = m_config.get_abs_value("infill_speed");
|
||||||
} else if (path.role() == erSolidInfill) {
|
} else if (path.role() == ExtrusionRole::SolidInfill) {
|
||||||
speed = m_config.get_abs_value("solid_infill_speed");
|
speed = m_config.get_abs_value("solid_infill_speed");
|
||||||
} else if (path.role() == erTopSolidInfill) {
|
} else if (path.role() == ExtrusionRole::TopSolidInfill) {
|
||||||
speed = m_config.get_abs_value("top_solid_infill_speed");
|
speed = m_config.get_abs_value("top_solid_infill_speed");
|
||||||
} else if (path.role() == erIroning) {
|
} else if (path.role() == ExtrusionRole::Ironing) {
|
||||||
speed = m_config.get_abs_value("ironing_speed");
|
speed = m_config.get_abs_value("ironing_speed");
|
||||||
} else if (path.role() == erGapFill) {
|
} else if (path.role() == ExtrusionRole::GapFill) {
|
||||||
speed = m_config.get_abs_value("gap_fill_speed");
|
speed = m_config.get_abs_value("gap_fill_speed");
|
||||||
} else {
|
} else {
|
||||||
throw Slic3r::InvalidArgument("Invalid speed");
|
throw Slic3r::InvalidArgument("Invalid speed");
|
||||||
@ -2927,9 +2927,9 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
// extrude arc or line
|
// extrude arc or line
|
||||||
if (m_enable_extrusion_role_markers)
|
if (m_enable_extrusion_role_markers)
|
||||||
{
|
{
|
||||||
if (path.role() != m_last_extrusion_role)
|
if (GCodeExtrusionRole role = extrusion_role_to_gcode_extrusion_role(path.role()); role != m_last_extrusion_role)
|
||||||
{
|
{
|
||||||
m_last_extrusion_role = path.role();
|
m_last_extrusion_role = role;
|
||||||
if (m_enable_extrusion_role_markers)
|
if (m_enable_extrusion_role_markers)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
@ -2945,10 +2945,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
bool last_was_wipe_tower = (m_last_processor_extrusion_role == erWipeTower);
|
bool last_was_wipe_tower = (m_last_processor_extrusion_role == erWipeTower);
|
||||||
assert(is_decimal_separator_point());
|
assert(is_decimal_separator_point());
|
||||||
|
|
||||||
if (path.role() != m_last_processor_extrusion_role) {
|
if (GCodeExtrusionRole role = extrusion_role_to_gcode_extrusion_role(path.role()); role != m_last_processor_extrusion_role) {
|
||||||
m_last_processor_extrusion_role = path.role();
|
m_last_processor_extrusion_role = role;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
sprintf(buf, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(m_last_processor_extrusion_role).c_str());
|
sprintf(buf, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), gcode_extrusion_role_to_string(m_last_processor_extrusion_role).c_str());
|
||||||
gcode += buf;
|
gcode += buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2979,7 +2979,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
gcode += ";_BRIDGE_FAN_START\n";
|
gcode += ";_BRIDGE_FAN_START\n";
|
||||||
else
|
else
|
||||||
comment = ";_EXTRUDE_SET_SPEED";
|
comment = ";_EXTRUDE_SET_SPEED";
|
||||||
if (path.role() == erExternalPerimeter)
|
if (path.role() == ExtrusionRole::ExternalPerimeter)
|
||||||
comment += ";_EXTERNAL_PERIMETER";
|
comment += ";_EXTERNAL_PERIMETER";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3112,7 +3112,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == erSupportMaterial)
|
if (role == ExtrusionRole::SupportMaterial)
|
||||||
if (const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(m_layer);
|
if (const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(m_layer);
|
||||||
support_layer != nullptr && ! support_layer->support_islands_bboxes.empty()) {
|
support_layer != nullptr && ! support_layer->support_islands_bboxes.empty()) {
|
||||||
BoundingBox bbox_travel = get_extents(travel);
|
BoundingBox bbox_travel = get_extents(travel);
|
||||||
|
@ -326,7 +326,7 @@ private:
|
|||||||
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
|
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
|
||||||
|
|
||||||
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
|
||||||
bool needs_retraction(const Polyline &travel, ExtrusionRole role = erNone);
|
bool needs_retraction(const Polyline &travel, ExtrusionRole role = ExtrusionRole::None);
|
||||||
std::string retract(bool toolchange = false);
|
std::string retract(bool toolchange = false);
|
||||||
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
|
||||||
std::string set_extruder(unsigned int extruder_id, double print_z);
|
std::string set_extruder(unsigned int extruder_id, double print_z);
|
||||||
@ -363,7 +363,7 @@ private:
|
|||||||
// The Pressure Equalizer removes the markers from the final G-code.
|
// The Pressure Equalizer removes the markers from the final G-code.
|
||||||
bool m_enable_extrusion_role_markers;
|
bool m_enable_extrusion_role_markers;
|
||||||
// Keeps track of the last extrusion role passed to the processor
|
// Keeps track of the last extrusion role passed to the processor
|
||||||
ExtrusionRole m_last_processor_extrusion_role;
|
GCodeExtrusionRole m_last_processor_extrusion_role;
|
||||||
// How many times will change_layer() be called?
|
// How many times will change_layer() be called?
|
||||||
// change_layer() will update the progress bar.
|
// change_layer() will update the progress bar.
|
||||||
unsigned int m_layer_count;
|
unsigned int m_layer_count;
|
||||||
@ -376,7 +376,7 @@ private:
|
|||||||
bool m_object_layer_over_raft;
|
bool m_object_layer_over_raft;
|
||||||
double m_volumetric_speed;
|
double m_volumetric_speed;
|
||||||
// Support for the extrusion role markers. Which marker is active?
|
// Support for the extrusion role markers. Which marker is active?
|
||||||
ExtrusionRole m_last_extrusion_role;
|
GCodeExtrusionRole m_last_extrusion_role;
|
||||||
// Support for G-Code Processor
|
// Support for G-Code Processor
|
||||||
float m_last_height{ 0.0f };
|
float m_last_height{ 0.0f };
|
||||||
float m_last_layer_z{ 0.0f };
|
float m_last_layer_z{ 0.0f };
|
||||||
|
@ -415,7 +415,7 @@ void GCodeProcessor::UsedFilaments::process_role_cache(const GCodeProcessor* pro
|
|||||||
filament.first = role_cache / s * 0.001;
|
filament.first = role_cache / s * 0.001;
|
||||||
filament.second = role_cache * processor->m_result.filament_densities[processor->m_extruder_id] * 0.001;
|
filament.second = role_cache * processor->m_result.filament_densities[processor->m_extruder_id] * 0.001;
|
||||||
|
|
||||||
ExtrusionRole active_role = processor->m_extrusion_role;
|
GCodeExtrusionRole active_role = processor->m_extrusion_role;
|
||||||
if (filaments_per_role.find(active_role) != filaments_per_role.end()) {
|
if (filaments_per_role.find(active_role) != filaments_per_role.end()) {
|
||||||
filaments_per_role[active_role].first += filament.first;
|
filaments_per_role[active_role].first += filament.first;
|
||||||
filaments_per_role[active_role].second += filament.second;
|
filaments_per_role[active_role].second += filament.second;
|
||||||
@ -1170,14 +1170,14 @@ std::vector<std::pair<EMoveType, float>> GCodeProcessor::get_moves_time(PrintEst
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<ExtrusionRole, float>> GCodeProcessor::get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const
|
std::vector<std::pair<GCodeExtrusionRole, float>> GCodeProcessor::get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const
|
||||||
{
|
{
|
||||||
std::vector<std::pair<ExtrusionRole, float>> ret;
|
std::vector<std::pair<GCodeExtrusionRole, float>> ret;
|
||||||
if (mode < PrintEstimatedStatistics::ETimeMode::Count) {
|
if (mode < PrintEstimatedStatistics::ETimeMode::Count) {
|
||||||
for (size_t i = 0; i < m_time_processor.machines[static_cast<size_t>(mode)].roles_time.size(); ++i) {
|
for (size_t i = 0; i < m_time_processor.machines[static_cast<size_t>(mode)].roles_time.size(); ++i) {
|
||||||
float time = m_time_processor.machines[static_cast<size_t>(mode)].roles_time[i];
|
float time = m_time_processor.machines[static_cast<size_t>(mode)].roles_time[i];
|
||||||
if (time > 0.0f)
|
if (time > 0.0f)
|
||||||
ret.push_back({ static_cast<ExtrusionRole>(i), time });
|
ret.push_back({ static_cast<GCodeExtrusionRole>(i), time });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -1645,7 +1645,7 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
|
|||||||
|
|
||||||
// extrusion role tag
|
// extrusion role tag
|
||||||
if (boost::starts_with(comment, reserved_tag(ETags::Role))) {
|
if (boost::starts_with(comment, reserved_tag(ETags::Role))) {
|
||||||
set_extrusion_role(ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length())));
|
set_extrusion_role(string_to_gcode_extrusion_role(comment.substr(reserved_tag(ETags::Role).length())));
|
||||||
if (m_extrusion_role == erExternalPerimeter)
|
if (m_extrusion_role == erExternalPerimeter)
|
||||||
m_seams_detector.activate(true);
|
m_seams_detector.activate(true);
|
||||||
return;
|
return;
|
||||||
@ -3771,7 +3771,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type, bool internal_only)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeProcessor::set_extrusion_role(ExtrusionRole role)
|
void GCodeProcessor::set_extrusion_role(GCodeExtrusionRole role)
|
||||||
{
|
{
|
||||||
m_used_filaments.process_role_cache(this);
|
m_used_filaments.process_role_cache(this);
|
||||||
m_extrusion_role = role;
|
m_extrusion_role = role;
|
||||||
|
@ -47,7 +47,7 @@ namespace Slic3r {
|
|||||||
float travel_time;
|
float travel_time;
|
||||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> custom_gcode_times;
|
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> custom_gcode_times;
|
||||||
std::vector<std::pair<EMoveType, float>> moves_times;
|
std::vector<std::pair<EMoveType, float>> moves_times;
|
||||||
std::vector<std::pair<ExtrusionRole, float>> roles_times;
|
std::vector<std::pair<GCodeExtrusionRole, float>> roles_times;
|
||||||
std::vector<float> layers_times;
|
std::vector<float> layers_times;
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
@ -62,7 +62,7 @@ namespace Slic3r {
|
|||||||
|
|
||||||
std::vector<double> volumes_per_color_change;
|
std::vector<double> volumes_per_color_change;
|
||||||
std::map<size_t, double> volumes_per_extruder;
|
std::map<size_t, double> volumes_per_extruder;
|
||||||
std::map<ExtrusionRole, std::pair<double, double>> used_filaments_per_role;
|
std::map<GCodeExtrusionRole, std::pair<double, double>> used_filaments_per_role;
|
||||||
std::map<size_t, double> cost_per_extruder;
|
std::map<size_t, double> cost_per_extruder;
|
||||||
|
|
||||||
std::array<Mode, static_cast<size_t>(ETimeMode::Count)> modes;
|
std::array<Mode, static_cast<size_t>(ETimeMode::Count)> modes;
|
||||||
@ -99,7 +99,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
unsigned int gcode_id{ 0 };
|
unsigned int gcode_id{ 0 };
|
||||||
EMoveType type{ EMoveType::Noop };
|
EMoveType type{ EMoveType::Noop };
|
||||||
ExtrusionRole extrusion_role{ erNone };
|
GCodeExtrusionRole extrusion_role{ erNone };
|
||||||
unsigned char extruder_id{ 0 };
|
unsigned char extruder_id{ 0 };
|
||||||
unsigned char cp_color_id{ 0 };
|
unsigned char cp_color_id{ 0 };
|
||||||
Vec3f position{ Vec3f::Zero() }; // mm
|
Vec3f position{ Vec3f::Zero() }; // mm
|
||||||
@ -238,7 +238,7 @@ namespace Slic3r {
|
|||||||
};
|
};
|
||||||
|
|
||||||
EMoveType move_type{ EMoveType::Noop };
|
EMoveType move_type{ EMoveType::Noop };
|
||||||
ExtrusionRole role{ erNone };
|
GCodeExtrusionRole role{ erNone };
|
||||||
unsigned int g1_line_id{ 0 };
|
unsigned int g1_line_id{ 0 };
|
||||||
unsigned int layer_id{ 0 };
|
unsigned int layer_id{ 0 };
|
||||||
float distance{ 0.0f }; // mm
|
float distance{ 0.0f }; // mm
|
||||||
@ -310,7 +310,7 @@ namespace Slic3r {
|
|||||||
std::vector<TimeBlock> blocks;
|
std::vector<TimeBlock> blocks;
|
||||||
std::vector<G1LinesCacheItem> g1_times_cache;
|
std::vector<G1LinesCacheItem> g1_times_cache;
|
||||||
std::array<float, static_cast<size_t>(EMoveType::Count)> moves_time;
|
std::array<float, static_cast<size_t>(EMoveType::Count)> moves_time;
|
||||||
std::array<float, static_cast<size_t>(ExtrusionRole::erCount)> roles_time;
|
std::array<float, static_cast<size_t>(GCodeExtrusionRole::erCount)> roles_time;
|
||||||
std::vector<float> layers_time;
|
std::vector<float> layers_time;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
@ -360,7 +360,7 @@ namespace Slic3r {
|
|||||||
std::map<size_t, double> volumes_per_extruder;
|
std::map<size_t, double> volumes_per_extruder;
|
||||||
|
|
||||||
double role_cache;
|
double role_cache;
|
||||||
std::map<ExtrusionRole, std::pair<double, double>> filaments_per_role; // ExtrusionRole -> (m, g)
|
std::map<GCodeExtrusionRole, std::pair<double, double>> filaments_per_role; // ExtrusionRole -> (m, g)
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
@ -441,7 +441,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
float value;
|
float value;
|
||||||
float tag_value;
|
float tag_value;
|
||||||
ExtrusionRole role;
|
GCodeExtrusionRole role;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string type;
|
std::string type;
|
||||||
@ -454,7 +454,7 @@ namespace Slic3r {
|
|||||||
: type(type), threshold(threshold)
|
: type(type), threshold(threshold)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void update(float value, ExtrusionRole role) {
|
void update(float value, GCodeExtrusionRole role) {
|
||||||
if (role != erCustom) {
|
if (role != erCustom) {
|
||||||
++count;
|
++count;
|
||||||
if (last_tag_value != 0.0f) {
|
if (last_tag_value != 0.0f) {
|
||||||
@ -539,7 +539,7 @@ namespace Slic3r {
|
|||||||
float m_mm3_per_mm;
|
float m_mm3_per_mm;
|
||||||
float m_fan_speed; // percentage
|
float m_fan_speed; // percentage
|
||||||
float m_z_offset; // mm
|
float m_z_offset; // mm
|
||||||
ExtrusionRole m_extrusion_role;
|
GCodeExtrusionRole m_extrusion_role;
|
||||||
unsigned char m_extruder_id;
|
unsigned char m_extruder_id;
|
||||||
ExtruderColors m_extruder_colors;
|
ExtruderColors m_extruder_colors;
|
||||||
ExtruderTemps m_extruder_temps;
|
ExtruderTemps m_extruder_temps;
|
||||||
@ -620,7 +620,7 @@ namespace Slic3r {
|
|||||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const;
|
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const;
|
||||||
|
|
||||||
std::vector<std::pair<EMoveType, float>> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::vector<std::pair<EMoveType, float>> get_moves_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
std::vector<std::pair<ExtrusionRole, float>> get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::vector<std::pair<GCodeExtrusionRole, float>> get_roles_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
std::vector<float> get_layers_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::vector<float> get_layers_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -757,7 +757,7 @@ namespace Slic3r {
|
|||||||
|
|
||||||
void store_move_vertex(EMoveType type, bool internal_only = false);
|
void store_move_vertex(EMoveType type, bool internal_only = false);
|
||||||
|
|
||||||
void set_extrusion_role(ExtrusionRole role);
|
void set_extrusion_role(GCodeExtrusionRole role);
|
||||||
|
|
||||||
float minimum_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const;
|
float minimum_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const;
|
||||||
float minimum_travel_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const;
|
float minimum_travel_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const;
|
||||||
|
@ -60,7 +60,7 @@ PressureEqualizer::PressureEqualizer(const Slic3r::GCodeConfig &config) : m_use_
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't regulate the pressure before and after gap-fill and ironing.
|
// Don't regulate the pressure before and after gap-fill and ironing.
|
||||||
for (const ExtrusionRole er : {erGapFill, erIroning}) {
|
for (const GCodeExtrusionRole er : {erGapFill, erIroning}) {
|
||||||
m_max_volumetric_extrusion_rate_slopes[er].negative = 0;
|
m_max_volumetric_extrusion_rate_slopes[er].negative = 0;
|
||||||
m_max_volumetric_extrusion_rate_slopes[er].positive = 0;
|
m_max_volumetric_extrusion_rate_slopes[er].positive = 0;
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ bool PressureEqualizer::process_line(const char *line, const char *line_end, GCo
|
|||||||
if (strncmp(line, EXTRUSION_ROLE_TAG.data(), EXTRUSION_ROLE_TAG.length()) == 0) {
|
if (strncmp(line, EXTRUSION_ROLE_TAG.data(), EXTRUSION_ROLE_TAG.length()) == 0) {
|
||||||
line += EXTRUSION_ROLE_TAG.length();
|
line += EXTRUSION_ROLE_TAG.length();
|
||||||
int role = atoi(line);
|
int role = atoi(line);
|
||||||
m_current_extrusion_role = ExtrusionRole(role);
|
m_current_extrusion_role = GCodeExtrusionRole(role);
|
||||||
#ifdef PRESSURE_EQUALIZER_DEBUG
|
#ifdef PRESSURE_EQUALIZER_DEBUG
|
||||||
++line_idx;
|
++line_idx;
|
||||||
#endif
|
#endif
|
||||||
@ -542,7 +542,7 @@ void PressureEqualizer::adjust_volumetric_rate()
|
|||||||
for (size_t iRole = 1; iRole < erCount; ++ iRole) {
|
for (size_t iRole = 1; iRole < erCount; ++ iRole) {
|
||||||
const float &rate_slope = m_max_volumetric_extrusion_rate_slopes[iRole].negative;
|
const float &rate_slope = m_max_volumetric_extrusion_rate_slopes[iRole].negative;
|
||||||
if (rate_slope == 0 || feedrate_per_extrusion_role[iRole] == std::numeric_limits<float>::max())
|
if (rate_slope == 0 || feedrate_per_extrusion_role[iRole] == std::numeric_limits<float>::max())
|
||||||
continue; // The negative rate is unlimited or the rate for ExtrusionRole iRole is unlimited.
|
continue; // The negative rate is unlimited or the rate for GCodeExtrusionRole iRole is unlimited.
|
||||||
|
|
||||||
float rate_end = feedrate_per_extrusion_role[iRole];
|
float rate_end = feedrate_per_extrusion_role[iRole];
|
||||||
if (iRole == line.extrusion_role && rate_succ < rate_end)
|
if (iRole == line.extrusion_role && rate_succ < rate_end)
|
||||||
@ -600,7 +600,7 @@ void PressureEqualizer::adjust_volumetric_rate()
|
|||||||
for (size_t iRole = 1; iRole < erCount; ++ iRole) {
|
for (size_t iRole = 1; iRole < erCount; ++ iRole) {
|
||||||
const float &rate_slope = m_max_volumetric_extrusion_rate_slopes[iRole].positive;
|
const float &rate_slope = m_max_volumetric_extrusion_rate_slopes[iRole].positive;
|
||||||
if (rate_slope == 0 || feedrate_per_extrusion_role[iRole] == std::numeric_limits<float>::max())
|
if (rate_slope == 0 || feedrate_per_extrusion_role[iRole] == std::numeric_limits<float>::max())
|
||||||
continue; // The positive rate is unlimited or the rate for ExtrusionRole iRole is unlimited.
|
continue; // The positive rate is unlimited or the rate for GCodeExtrusionRole iRole is unlimited.
|
||||||
|
|
||||||
float rate_start = feedrate_per_extrusion_role[iRole];
|
float rate_start = feedrate_per_extrusion_role[iRole];
|
||||||
if (!line.adjustable_flow || line.extrusion_role == erExternalPerimeter || line.extrusion_role == erGapFill || line.extrusion_role == erBridgeInfill || line.extrusion_role == erIroning) {
|
if (!line.adjustable_flow || line.extrusion_role == erExternalPerimeter || line.extrusion_role == erGapFill || line.extrusion_role == erBridgeInfill || line.extrusion_role == erIroning) {
|
||||||
|
@ -77,7 +77,7 @@ private:
|
|||||||
// X,Y,Z,E,F
|
// X,Y,Z,E,F
|
||||||
float m_current_pos[5];
|
float m_current_pos[5];
|
||||||
size_t m_current_extruder;
|
size_t m_current_extruder;
|
||||||
ExtrusionRole m_current_extrusion_role;
|
GCodeExtrusionRole m_current_extrusion_role;
|
||||||
bool m_retracted;
|
bool m_retracted;
|
||||||
bool m_use_relative_e_distances;
|
bool m_use_relative_e_distances;
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ private:
|
|||||||
// Index of the active extruder.
|
// Index of the active extruder.
|
||||||
size_t extruder_id;
|
size_t extruder_id;
|
||||||
// Extrusion role of this segment.
|
// Extrusion role of this segment.
|
||||||
ExtrusionRole extrusion_role;
|
GCodeExtrusionRole extrusion_role;
|
||||||
|
|
||||||
// Current volumetric extrusion rate.
|
// Current volumetric extrusion rate.
|
||||||
float volumetric_extrusion_rate;
|
float volumetric_extrusion_rate;
|
||||||
|
@ -407,13 +407,13 @@ Polygons extract_perimeter_polygons(const Layer *layer, std::vector<const LayerR
|
|||||||
ExtrusionRole role = perimeter->role();
|
ExtrusionRole role = perimeter->role();
|
||||||
if (perimeter->is_loop()) {
|
if (perimeter->is_loop()) {
|
||||||
for (const ExtrusionPath &path : static_cast<const ExtrusionLoop*>(perimeter)->paths) {
|
for (const ExtrusionPath &path : static_cast<const ExtrusionLoop*>(perimeter)->paths) {
|
||||||
if (path.role() == ExtrusionRole::erExternalPerimeter) {
|
if (path.role() == ExtrusionRole::ExternalPerimeter) {
|
||||||
role = ExtrusionRole::erExternalPerimeter;
|
role = ExtrusionRole::ExternalPerimeter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == ExtrusionRole::erExternalPerimeter) {
|
if (role == ExtrusionRole::ExternalPerimeter) {
|
||||||
Points p;
|
Points p;
|
||||||
perimeter->collect_points(p);
|
perimeter->collect_points(p);
|
||||||
polygons.emplace_back(std::move(p));
|
polygons.emplace_back(std::move(p));
|
||||||
@ -1548,7 +1548,7 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
|
|||||||
|
|
||||||
Point seam_point = Point::new_scale(seam_position.x(), seam_position.y());
|
Point seam_point = Point::new_scale(seam_position.x(), seam_position.y());
|
||||||
|
|
||||||
if (loop.role() == ExtrusionRole::erPerimeter) { //Hopefully inner perimeter
|
if (loop.role() == ExtrusionRole::Perimeter) { //Hopefully inner perimeter
|
||||||
const SeamCandidate &perimeter_point = layer_perimeters.points[seam_index];
|
const SeamCandidate &perimeter_point = layer_perimeters.points[seam_index];
|
||||||
ExtrusionLoop::ClosestPathPoint projected_point = loop.get_closest_path_and_point(seam_point, false);
|
ExtrusionLoop::ClosestPathPoint projected_point = loop.get_closest_path_and_point(seam_point, false);
|
||||||
// determine depth of the seam point.
|
// determine depth of the seam point.
|
||||||
|
@ -197,7 +197,7 @@ void ToolOrdering::initialize_layers(std::vector<coordf_t> &zs)
|
|||||||
if (object.config().wipe_into_objects)
|
if (object.config().wipe_into_objects)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!region.config().wipe_into_infill || eec.role() != erInternalInfill)
|
if (!region.config().wipe_into_infill || eec.role() != ExtrusionRole::InternalInfill)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -210,8 +210,8 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
|||||||
for (auto support_layer : object.support_layers()) {
|
for (auto support_layer : object.support_layers()) {
|
||||||
LayerTools &layer_tools = this->tools_for_layer(support_layer->print_z);
|
LayerTools &layer_tools = this->tools_for_layer(support_layer->print_z);
|
||||||
ExtrusionRole role = support_layer->support_fills.role();
|
ExtrusionRole role = support_layer->support_fills.role();
|
||||||
bool has_support = role == erMixed || role == erSupportMaterial;
|
bool has_support = role == ExtrusionRole::Mixed || role == ExtrusionRole::SupportMaterial;
|
||||||
bool has_interface = role == erMixed || role == erSupportMaterialInterface;
|
bool has_interface = role == ExtrusionRole::Mixed || role == ExtrusionRole::SupportMaterialInterface;
|
||||||
unsigned int extruder_support = object.config().support_material_extruder.value;
|
unsigned int extruder_support = object.config().support_material_extruder.value;
|
||||||
unsigned int extruder_interface = object.config().support_material_interface_extruder.value;
|
unsigned int extruder_interface = object.config().support_material_interface_extruder.value;
|
||||||
if (has_support)
|
if (has_support)
|
||||||
@ -266,10 +266,10 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
|||||||
for (const ExtrusionEntity *ee : layerm->fills()) {
|
for (const ExtrusionEntity *ee : layerm->fills()) {
|
||||||
// fill represents infill extrusions of a single island.
|
// fill represents infill extrusions of a single island.
|
||||||
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
|
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
|
||||||
ExtrusionRole role = fill->entities.empty() ? erNone : fill->entities.front()->role();
|
ExtrusionRole role = fill->entities.empty() ? ExtrusionRole::None : fill->entities.front()->role();
|
||||||
if (is_solid_infill(role))
|
if (is_solid_infill(role))
|
||||||
has_solid_infill = true;
|
has_solid_infill = true;
|
||||||
else if (role != erNone)
|
else if (role != ExtrusionRole::None)
|
||||||
has_infill = true;
|
has_infill = true;
|
||||||
|
|
||||||
if (m_print_config_ptr) {
|
if (m_print_config_ptr) {
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
// adds tag for analyzer:
|
// adds tag for analyzer:
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
str << ";" << GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) << m_layer_height << "\n"; // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming
|
str << ";" << GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) << m_layer_height << "\n"; // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming
|
||||||
str << ";" << GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role) << ExtrusionEntity::role_to_string(erWipeTower) << "\n";
|
str << ";" << GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role) << gcode_extrusion_role_to_string(erWipeTower) << "\n";
|
||||||
m_gcode += str.str();
|
m_gcode += str.str();
|
||||||
change_analyzer_line_width(line_width);
|
change_analyzer_line_width(line_width);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ ExtrusionMultiPath PerimeterGenerator::thick_polyline_to_multi_path(const ThickP
|
|||||||
}
|
}
|
||||||
|
|
||||||
const double w = fmax(line.a_width, line.b_width);
|
const double w = fmax(line.a_width, line.b_width);
|
||||||
const Flow new_flow = (role == erOverhangPerimeter && flow.bridge()) ? flow : flow.with_width(unscale<float>(w) + flow.height() * float(1. - 0.25 * PI));
|
const Flow new_flow = (role == ExtrusionRole::OverhangPerimeter && flow.bridge()) ? flow : flow.with_width(unscale<float>(w) + flow.height() * float(1. - 0.25 * PI));
|
||||||
if (path.polyline.points.empty()) {
|
if (path.polyline.points.empty()) {
|
||||||
path.polyline.append(line.a);
|
path.polyline.append(line.a);
|
||||||
path.polyline.append(line.b);
|
path.polyline.append(line.b);
|
||||||
@ -292,9 +292,9 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
|||||||
for (const PerimeterGeneratorLoop &loop : loops) {
|
for (const PerimeterGeneratorLoop &loop : loops) {
|
||||||
bool is_external = loop.is_external();
|
bool is_external = loop.is_external();
|
||||||
|
|
||||||
ExtrusionRole role;
|
ExtrusionRole role = ExtrusionRole::None;
|
||||||
ExtrusionLoopRole loop_role;
|
ExtrusionLoopRole loop_role;
|
||||||
role = is_external ? erExternalPerimeter : erPerimeter;
|
role = is_external ? ExtrusionRole::ExternalPerimeter : ExtrusionRole::Perimeter;
|
||||||
if (loop.is_internal_contour()) {
|
if (loop.is_internal_contour()) {
|
||||||
// Note that we set loop role to ContourInternalPerimeter
|
// Note that we set loop role to ContourInternalPerimeter
|
||||||
// also when loop is both internal and external (i.e.
|
// also when loop is both internal and external (i.e.
|
||||||
@ -332,7 +332,7 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
|||||||
extrusion_paths_append(
|
extrusion_paths_append(
|
||||||
paths,
|
paths,
|
||||||
diff_pl({ polygon }, lower_slices_polygons_clipped),
|
diff_pl({ polygon }, lower_slices_polygons_clipped),
|
||||||
erOverhangPerimeter,
|
ExtrusionRole::OverhangPerimeter,
|
||||||
params.mm3_per_mm_overhang,
|
params.mm3_per_mm_overhang,
|
||||||
params.overhang_flow.width(),
|
params.overhang_flow.width(),
|
||||||
params.overhang_flow.height());
|
params.overhang_flow.height());
|
||||||
@ -354,7 +354,7 @@ static ExtrusionEntityCollection traverse_loops_classic(const PerimeterGenerator
|
|||||||
|
|
||||||
// Append thin walls to the nearest-neighbor search (only for first iteration)
|
// Append thin walls to the nearest-neighbor search (only for first iteration)
|
||||||
if (! thin_walls.empty()) {
|
if (! thin_walls.empty()) {
|
||||||
variable_width_classic(thin_walls, erExternalPerimeter, params.ext_perimeter_flow, coll.entities);
|
variable_width_classic(thin_walls, ExtrusionRole::ExternalPerimeter, params.ext_perimeter_flow, coll.entities);
|
||||||
thin_walls.clear();
|
thin_walls.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,7 +503,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const bool is_external = extrusion->inset_idx == 0;
|
const bool is_external = extrusion->inset_idx == 0;
|
||||||
ExtrusionRole role = is_external ? erExternalPerimeter : erPerimeter;
|
ExtrusionRole role = is_external ? ExtrusionRole::ExternalPerimeter : ExtrusionRole::Perimeter;
|
||||||
|
|
||||||
if (pg_extrusion.fuzzify)
|
if (pg_extrusion.fuzzify)
|
||||||
fuzzy_extrusion_line(*extrusion, scaled<float>(params.config.fuzzy_skin_thickness.value), scaled<float>(params.config.fuzzy_skin_point_dist.value));
|
fuzzy_extrusion_line(*extrusion, scaled<float>(params.config.fuzzy_skin_thickness.value), scaled<float>(params.config.fuzzy_skin_point_dist.value));
|
||||||
@ -547,7 +547,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
|||||||
// get overhang paths by checking what parts of this loop fall
|
// get overhang paths by checking what parts of this loop fall
|
||||||
// outside the grown lower slices (thus where the distance between
|
// outside the grown lower slices (thus where the distance between
|
||||||
// the loop centerline and original lower slices is >= half nozzle diameter
|
// the loop centerline and original lower slices is >= half nozzle diameter
|
||||||
extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctDifference), erOverhangPerimeter,
|
extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctDifference), ExtrusionRole::OverhangPerimeter,
|
||||||
params.overhang_flow);
|
params.overhang_flow);
|
||||||
|
|
||||||
// Reapply the nearest point search for starting point.
|
// Reapply the nearest point search for starting point.
|
||||||
@ -568,7 +568,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
|
|||||||
for (const ExtrusionPath &path : paths) {
|
for (const ExtrusionPath &path : paths) {
|
||||||
++point_occurrence[path.polyline.first_point()].occurrence;
|
++point_occurrence[path.polyline.first_point()].occurrence;
|
||||||
++point_occurrence[path.polyline.last_point()].occurrence;
|
++point_occurrence[path.polyline.last_point()].occurrence;
|
||||||
if (path.role() == erOverhangPerimeter) {
|
if (path.role() == ExtrusionRole::OverhangPerimeter) {
|
||||||
point_occurrence[path.polyline.first_point()].is_overhang = true;
|
point_occurrence[path.polyline.first_point()].is_overhang = true;
|
||||||
point_occurrence[path.polyline.last_point()].is_overhang = true;
|
point_occurrence[path.polyline.last_point()].is_overhang = true;
|
||||||
}
|
}
|
||||||
@ -938,7 +938,7 @@ std::tuple<std::vector<ExtrusionPaths>, Polygons> generate_extra_perimeters_over
|
|||||||
Polygons shrinked = offset(prev, -0.4 * overhang_flow.scaled_spacing());
|
Polygons shrinked = offset(prev, -0.4 * overhang_flow.scaled_spacing());
|
||||||
if (!shrinked.empty()) {
|
if (!shrinked.empty()) {
|
||||||
overhang_region.emplace_back();
|
overhang_region.emplace_back();
|
||||||
extrusion_paths_append(overhang_region.back(), perimeter, erOverhangPerimeter, overhang_flow.mm3_per_mm(),
|
extrusion_paths_append(overhang_region.back(), perimeter, ExtrusionRole::OverhangPerimeter, overhang_flow.mm3_per_mm(),
|
||||||
overhang_flow.width(), overhang_flow.height());
|
overhang_flow.width(), overhang_flow.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,13 +953,13 @@ std::tuple<std::vector<ExtrusionPaths>, Polygons> generate_extra_perimeters_over
|
|||||||
if (!fills.empty()) {
|
if (!fills.empty()) {
|
||||||
fills = intersection_pl(fills, inset_overhang_area);
|
fills = intersection_pl(fills, inset_overhang_area);
|
||||||
overhang_region.emplace_back();
|
overhang_region.emplace_back();
|
||||||
extrusion_paths_append(overhang_region.back(), fills, erOverhangPerimeter, overhang_flow.mm3_per_mm(),
|
extrusion_paths_append(overhang_region.back(), fills, ExtrusionRole::OverhangPerimeter, overhang_flow.mm3_per_mm(),
|
||||||
overhang_flow.width(), overhang_flow.height());
|
overhang_flow.width(), overhang_flow.height());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
overhang_region.emplace_back();
|
overhang_region.emplace_back();
|
||||||
extrusion_paths_append(overhang_region.back(), perimeter, erOverhangPerimeter, overhang_flow.mm3_per_mm(),
|
extrusion_paths_append(overhang_region.back(), perimeter, ExtrusionRole::OverhangPerimeter, overhang_flow.mm3_per_mm(),
|
||||||
overhang_flow.width(), overhang_flow.height());
|
overhang_flow.width(), overhang_flow.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,7 +981,7 @@ std::tuple<std::vector<ExtrusionPaths>, Polygons> generate_extra_perimeters_over
|
|||||||
}
|
}
|
||||||
Polylines perimeter = intersection_pl(to_polylines(perimeter_polygon), shrinked_overhang_to_cover);
|
Polylines perimeter = intersection_pl(to_polylines(perimeter_polygon), shrinked_overhang_to_cover);
|
||||||
overhang_region.emplace_back();
|
overhang_region.emplace_back();
|
||||||
extrusion_paths_append(overhang_region.back(), perimeter, erOverhangPerimeter, overhang_flow.mm3_per_mm(),
|
extrusion_paths_append(overhang_region.back(), perimeter, ExtrusionRole::OverhangPerimeter, overhang_flow.mm3_per_mm(),
|
||||||
overhang_flow.width(), overhang_flow.height());
|
overhang_flow.width(), overhang_flow.height());
|
||||||
|
|
||||||
perimeter_polygon = expand(perimeter_polygon, 0.5 * overhang_flow.scaled_spacing());
|
perimeter_polygon = expand(perimeter_polygon, 0.5 * overhang_flow.scaled_spacing());
|
||||||
@ -1502,7 +1502,7 @@ void PerimeterGenerator::process_classic(
|
|||||||
ex.medial_axis(min, max, &polylines);
|
ex.medial_axis(min, max, &polylines);
|
||||||
if (! polylines.empty()) {
|
if (! polylines.empty()) {
|
||||||
ExtrusionEntityCollection gap_fill;
|
ExtrusionEntityCollection gap_fill;
|
||||||
variable_width_classic(polylines, erGapFill, params.solid_infill_flow, gap_fill.entities);
|
variable_width_classic(polylines, ExtrusionRole::GapFill, params.solid_infill_flow, gap_fill.entities);
|
||||||
/* Make sure we don't infill narrow parts that are already gap-filled
|
/* Make sure we don't infill narrow parts that are already gap-filled
|
||||||
(we only consider this surface's gaps to reduce the diff() complexity).
|
(we only consider this surface's gaps to reduce the diff() complexity).
|
||||||
Growing actual extrusions ensures that gaps not filled by medial axis
|
Growing actual extrusions ensures that gaps not filled by medial axis
|
||||||
|
@ -1029,7 +1029,7 @@ void Print::_make_skirt()
|
|||||||
ExtrusionLoop eloop(elrSkirt);
|
ExtrusionLoop eloop(elrSkirt);
|
||||||
eloop.paths.emplace_back(ExtrusionPath(
|
eloop.paths.emplace_back(ExtrusionPath(
|
||||||
ExtrusionPath(
|
ExtrusionPath(
|
||||||
erSkirt,
|
ExtrusionRole::Skirt,
|
||||||
(float)mm3_per_mm, // this will be overridden at G-code export time
|
(float)mm3_per_mm, // this will be overridden at G-code export time
|
||||||
flow.width(),
|
flow.width(),
|
||||||
(float)first_layer_height // this will be overridden at G-code export time
|
(float)first_layer_height // this will be overridden at G-code export time
|
||||||
|
@ -1178,7 +1178,7 @@ namespace SupportMaterialInternal {
|
|||||||
static inline bool has_bridging_perimeters(const ExtrusionLoop &loop)
|
static inline bool has_bridging_perimeters(const ExtrusionLoop &loop)
|
||||||
{
|
{
|
||||||
for (const ExtrusionPath &ep : loop.paths)
|
for (const ExtrusionPath &ep : loop.paths)
|
||||||
if (ep.role() == erOverhangPerimeter && ! ep.polyline.empty())
|
if (ep.role() == ExtrusionRole::OverhangPerimeter && ! ep.polyline.empty())
|
||||||
return int(ep.size()) >= (ep.is_closed() ? 3 : 2);
|
return int(ep.size()) >= (ep.is_closed() ? 3 : 2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1204,7 +1204,7 @@ namespace SupportMaterialInternal {
|
|||||||
for (const ExtrusionEntity *ee2 : static_cast<const ExtrusionEntityCollection*>(ee)->entities) {
|
for (const ExtrusionEntity *ee2 : static_cast<const ExtrusionEntityCollection*>(ee)->entities) {
|
||||||
assert(! ee2->is_collection());
|
assert(! ee2->is_collection());
|
||||||
assert(! ee2->is_loop());
|
assert(! ee2->is_loop());
|
||||||
if (ee2->role() == erBridgeInfill)
|
if (ee2->role() == ExtrusionRole::BridgeInfill)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1225,7 +1225,7 @@ namespace SupportMaterialInternal {
|
|||||||
{
|
{
|
||||||
assert(expansion_scaled >= 0.f);
|
assert(expansion_scaled >= 0.f);
|
||||||
for (const ExtrusionPath &ep : loop.paths)
|
for (const ExtrusionPath &ep : loop.paths)
|
||||||
if (ep.role() == erOverhangPerimeter && ! ep.polyline.empty()) {
|
if (ep.role() == ExtrusionRole::OverhangPerimeter && ! ep.polyline.empty()) {
|
||||||
float exp = 0.5f * (float)scale_(ep.width) + expansion_scaled;
|
float exp = 0.5f * (float)scale_(ep.width) + expansion_scaled;
|
||||||
if (ep.is_closed()) {
|
if (ep.is_closed()) {
|
||||||
if (ep.size() >= 3) {
|
if (ep.size() >= 3) {
|
||||||
@ -3357,7 +3357,7 @@ static inline void tree_supports_generate_paths(
|
|||||||
ExPolygons level2 = offset2_ex({ expoly }, -1.5 * flow.scaled_width(), 0.5 * flow.scaled_width());
|
ExPolygons level2 = offset2_ex({ expoly }, -1.5 * flow.scaled_width(), 0.5 * flow.scaled_width());
|
||||||
if (level2.size() == 1) {
|
if (level2.size() == 1) {
|
||||||
Polylines polylines;
|
Polylines polylines;
|
||||||
extrusion_entities_append_paths(dst, draw_perimeters(expoly, clip_length), erSupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
|
extrusion_entities_append_paths(dst, draw_perimeters(expoly, clip_length), ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
|
||||||
// Disable reversal of the path, always start with the anchor, always print CCW.
|
// Disable reversal of the path, always start with the anchor, always print CCW.
|
||||||
false);
|
false);
|
||||||
expoly = level2.front();
|
expoly = level2.front();
|
||||||
@ -3460,7 +3460,7 @@ static inline void tree_supports_generate_paths(
|
|||||||
pl.reverse();
|
pl.reverse();
|
||||||
polylines.emplace_back(std::move(pl));
|
polylines.emplace_back(std::move(pl));
|
||||||
}
|
}
|
||||||
extrusion_entities_append_paths(dst, polylines, erSupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
|
extrusion_entities_append_paths(dst, polylines, ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height(),
|
||||||
// Disable reversal of the path, always start with the anchor, always print CCW.
|
// Disable reversal of the path, always start with the anchor, always print CCW.
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
@ -3505,7 +3505,7 @@ static inline void fill_expolygons_with_sheath_generate_paths(
|
|||||||
eec->no_sort = true;
|
eec->no_sort = true;
|
||||||
}
|
}
|
||||||
ExtrusionEntitiesPtr &out = no_sort ? eec->entities : dst;
|
ExtrusionEntitiesPtr &out = no_sort ? eec->entities : dst;
|
||||||
extrusion_entities_append_paths(out, draw_perimeters(expoly, clip_length), erSupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height());
|
extrusion_entities_append_paths(out, draw_perimeters(expoly, clip_length), ExtrusionRole::SupportMaterial, flow.mm3_per_mm(), flow.width(), flow.height());
|
||||||
// Fill in the rest.
|
// Fill in the rest.
|
||||||
fill_expolygons_generate_paths(out, offset_ex(expoly, float(-0.4 * spacing)), filler, fill_params, density, role, flow);
|
fill_expolygons_generate_paths(out, offset_ex(expoly, float(-0.4 * spacing)), filler, fill_params, density, role, flow);
|
||||||
if (no_sort && ! eec->empty())
|
if (no_sort && ! eec->empty())
|
||||||
@ -3817,7 +3817,7 @@ void LoopInterfaceProcessor::generate(SupportGeneratorLayerExtruded &top_contact
|
|||||||
extrusion_entities_append_paths(
|
extrusion_entities_append_paths(
|
||||||
top_contact_layer.extrusions,
|
top_contact_layer.extrusions,
|
||||||
std::move(loop_lines),
|
std::move(loop_lines),
|
||||||
erSupportMaterialInterface, flow.mm3_per_mm(), flow.width(), flow.height());
|
ExtrusionRole::SupportMaterialInterface, flow.mm3_per_mm(), flow.width(), flow.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
@ -4252,7 +4252,7 @@ void generate_support_toolpaths(
|
|||||||
// Filler and its parameters
|
// Filler and its parameters
|
||||||
filler, float(support_params.support_density),
|
filler, float(support_params.support_density),
|
||||||
// Extrusion parameters
|
// Extrusion parameters
|
||||||
erSupportMaterial, flow,
|
ExtrusionRole::SupportMaterial, flow,
|
||||||
support_params.with_sheath, false);
|
support_params.with_sheath, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4284,7 +4284,7 @@ void generate_support_toolpaths(
|
|||||||
// Filler and its parameters
|
// Filler and its parameters
|
||||||
filler, density,
|
filler, density,
|
||||||
// Extrusion parameters
|
// Extrusion parameters
|
||||||
(support_layer_id < slicing_params.base_raft_layers) ? erSupportMaterial : erSupportMaterialInterface, flow,
|
(support_layer_id < slicing_params.base_raft_layers) ? ExtrusionRole::SupportMaterial : ExtrusionRole::SupportMaterialInterface, flow,
|
||||||
// sheath at first layer
|
// sheath at first layer
|
||||||
support_layer_id == 0, support_layer_id == 0);
|
support_layer_id == 0, support_layer_id == 0);
|
||||||
}
|
}
|
||||||
@ -4440,7 +4440,7 @@ void generate_support_toolpaths(
|
|||||||
// Filler and its parameters
|
// Filler and its parameters
|
||||||
filler_interface.get(), float(density),
|
filler_interface.get(), float(density),
|
||||||
// Extrusion parameters
|
// Extrusion parameters
|
||||||
erSupportMaterialInterface, interface_flow);
|
ExtrusionRole::SupportMaterialInterface, interface_flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base interface layers under soluble interfaces
|
// Base interface layers under soluble interfaces
|
||||||
@ -4462,7 +4462,7 @@ void generate_support_toolpaths(
|
|||||||
// Filler and its parameters
|
// Filler and its parameters
|
||||||
filler, float(support_params.interface_density),
|
filler, float(support_params.interface_density),
|
||||||
// Extrusion parameters
|
// Extrusion parameters
|
||||||
erSupportMaterial, interface_flow);
|
ExtrusionRole::SupportMaterial, interface_flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base support or flange.
|
// Base support or flange.
|
||||||
@ -4500,7 +4500,7 @@ void generate_support_toolpaths(
|
|||||||
// Filler and its parameters
|
// Filler and its parameters
|
||||||
filler, density,
|
filler, density,
|
||||||
// Extrusion parameters
|
// Extrusion parameters
|
||||||
erSupportMaterial, flow,
|
ExtrusionRole::SupportMaterial, flow,
|
||||||
sheath, no_sort);
|
sheath, no_sort);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
bool is_external_perimeter() const
|
bool is_external_perimeter() const
|
||||||
{
|
{
|
||||||
assert(origin_entity != nullptr);
|
assert(origin_entity != nullptr);
|
||||||
return origin_entity->role() == erExternalPerimeter || origin_entity->role() == erOverhangPerimeter;
|
return origin_entity->role() == ExtrusionRole::ExternalPerimeter || origin_entity->role() == ExtrusionRole::OverhangPerimeter;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2f a;
|
Vec2f a;
|
||||||
@ -170,16 +170,15 @@ struct SliceConnection
|
|||||||
|
|
||||||
float get_flow_width(const LayerRegion *region, ExtrusionRole role)
|
float get_flow_width(const LayerRegion *region, ExtrusionRole role)
|
||||||
{
|
{
|
||||||
switch (role) {
|
if (role == ExtrusionRole::BridgeInfill) return region->flow(FlowRole::frExternalPerimeter).width();
|
||||||
case ExtrusionRole::erBridgeInfill: return region->flow(FlowRole::frExternalPerimeter).width();
|
if (role == ExtrusionRole::ExternalPerimeter) return region->flow(FlowRole::frExternalPerimeter).width();
|
||||||
case ExtrusionRole::erExternalPerimeter: return region->flow(FlowRole::frExternalPerimeter).width();
|
if (role == ExtrusionRole::GapFill) return region->flow(FlowRole::frInfill).width();
|
||||||
case ExtrusionRole::erGapFill: return region->flow(FlowRole::frInfill).width();
|
if (role == ExtrusionRole::Perimeter) return region->flow(FlowRole::frPerimeter).width();
|
||||||
case ExtrusionRole::erPerimeter: return region->flow(FlowRole::frPerimeter).width();
|
if (role == ExtrusionRole::SolidInfill) return region->flow(FlowRole::frSolidInfill).width();
|
||||||
case ExtrusionRole::erSolidInfill: return region->flow(FlowRole::frSolidInfill).width();
|
if (role == ExtrusionRole::InternalInfill) return region->flow(FlowRole::frInfill).width();
|
||||||
case ExtrusionRole::erInternalInfill: return region->flow(FlowRole::frInfill).width();
|
if (role == ExtrusionRole::TopSolidInfill) return region->flow(FlowRole::frTopSolidInfill).width();
|
||||||
case ExtrusionRole::erTopSolidInfill: return region->flow(FlowRole::frTopSolidInfill).width();
|
// default
|
||||||
default: return region->flow(FlowRole::frPerimeter).width();
|
return region->flow(FlowRole::frPerimeter).width();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ExtrusionLine> to_short_lines(const ExtrusionEntity *e, float length_limit)
|
std::vector<ExtrusionLine> to_short_lines(const ExtrusionEntity *e, float length_limit)
|
||||||
@ -800,7 +799,7 @@ SupportPoints check_stability(const PrintObject *po, const PrintTryCancel& cance
|
|||||||
const LayerRegion *fill_region = layer->get_region(fill_range.region());
|
const LayerRegion *fill_region = layer->get_region(fill_range.region());
|
||||||
for (const auto &fill_idx : fill_range) {
|
for (const auto &fill_idx : fill_range) {
|
||||||
const ExtrusionEntity *entity = fill_region->fills().entities[fill_idx];
|
const ExtrusionEntity *entity = fill_region->fills().entities[fill_idx];
|
||||||
if (entity->role() == erBridgeInfill) {
|
if (entity->role() == ExtrusionRole::BridgeInfill) {
|
||||||
for (const ExtrusionLine &bridge :
|
for (const ExtrusionLine &bridge :
|
||||||
check_extrusion_entity_stability(entity, fill_region, prev_layer_ext_perim_lines,prev_layer_boundary, params)) {
|
check_extrusion_entity_stability(entity, fill_region, prev_layer_ext_perim_lines,prev_layer_boundary, params)) {
|
||||||
if (bridge.support_point_generated) {
|
if (bridge.support_point_generated) {
|
||||||
|
@ -40,13 +40,18 @@ public:
|
|||||||
constexpr bool operator&(option_type t) { return m_bits & mask_value(t); }
|
constexpr bool operator&(option_type t) { return m_bits & mask_value(t); }
|
||||||
constexpr bool has(option_type t) { return m_bits & mask_value(t); }
|
constexpr bool has(option_type t) { return m_bits & mask_value(t); }
|
||||||
|
|
||||||
|
constexpr bool operator==(const enum_bitmask r) const { return m_bits == r.m_bits; }
|
||||||
|
constexpr bool operator!=(const enum_bitmask r) const { return m_bits != r.m_bits; }
|
||||||
|
// For sorting by the enum values.
|
||||||
|
constexpr bool lower(const enum_bitmask r) const { return m_bits < r.m_bits; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
underlying_type m_bits = 0;
|
underlying_type m_bits = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// For enabling free functions producing enum_bitmask<> type from bit operations on enums.
|
// For enabling free functions producing enum_bitmask<> type from bit operations on enums.
|
||||||
template<typename Enum> struct is_enum_bitmask_type { static const bool enable = false; };
|
template<typename Enum> struct is_enum_bitmask_type { static constexpr const bool enable = false; };
|
||||||
#define ENABLE_ENUM_BITMASK_OPERATORS(x) template<> struct is_enum_bitmask_type<x> { static const bool enable = true; };
|
#define ENABLE_ENUM_BITMASK_OPERATORS(x) template<> struct is_enum_bitmask_type<x> { static constexpr const bool enable = true; };
|
||||||
template<class Enum> inline constexpr bool is_enum_bitmask_type_v = is_enum_bitmask_type<Enum>::enable;
|
template<class Enum> inline constexpr bool is_enum_bitmask_type_v = is_enum_bitmask_type<Enum>::enable;
|
||||||
|
|
||||||
// Creates an enum_bitmask from two options, convenient for passing of options to a function:
|
// Creates an enum_bitmask from two options, convenient for passing of options to a function:
|
||||||
|
@ -899,7 +899,7 @@ void GCodeViewer::reset()
|
|||||||
m_shells.volumes.clear();
|
m_shells.volumes.clear();
|
||||||
m_layers.reset();
|
m_layers.reset();
|
||||||
m_layers_z_range = { 0, 0 };
|
m_layers_z_range = { 0, 0 };
|
||||||
m_roles = std::vector<ExtrusionRole>();
|
m_roles = std::vector<GCodeExtrusionRole>();
|
||||||
m_print_statistics.reset();
|
m_print_statistics.reset();
|
||||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||||
m_layers_times[i] = std::vector<float>();
|
m_layers_times[i] = std::vector<float>();
|
||||||
@ -1607,8 +1607,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
|||||||
curr.extrusion_role != erSupportMaterial &&
|
curr.extrusion_role != erSupportMaterial &&
|
||||||
curr.extrusion_role != erSupportMaterialInterface &&
|
curr.extrusion_role != erSupportMaterialInterface &&
|
||||||
curr.extrusion_role != erWipeTower &&
|
curr.extrusion_role != erWipeTower &&
|
||||||
curr.extrusion_role != erCustom &&
|
curr.extrusion_role != erCustom) {
|
||||||
curr.extrusion_role != erMixed) {
|
|
||||||
const Vec3d curr_pos = curr.position.cast<double>();
|
const Vec3d curr_pos = curr.position.cast<double>();
|
||||||
const Vec3d prev_pos = prev.position.cast<double>();
|
const Vec3d prev_pos = prev.position.cast<double>();
|
||||||
m_cog.add_segment(curr_pos, prev_pos, curr.mm3_per_mm * (curr_pos - prev_pos).norm());
|
m_cog.add_segment(curr_pos, prev_pos, curr.mm3_per_mm * (curr_pos - prev_pos).norm());
|
||||||
@ -3469,12 +3468,12 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm");
|
return _u8L("from") + " " + std::string(buf1) + " " + _u8L("to") + " " + std::string(buf2) + " " + _u8L("mm");
|
||||||
};
|
};
|
||||||
|
|
||||||
auto role_time_and_percent = [time_mode](ExtrusionRole role) {
|
auto role_time_and_percent = [time_mode](GCodeExtrusionRole role) {
|
||||||
auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair<ExtrusionRole, float>& item) { return role == item.first; });
|
auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair<GCodeExtrusionRole, float>& item) { return role == item.first; });
|
||||||
return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f);
|
return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto used_filament_per_role = [this, imperial_units](ExtrusionRole role) {
|
auto used_filament_per_role = [this, imperial_units](GCodeExtrusionRole role) {
|
||||||
auto it = m_print_statistics.used_filaments_per_role.find(role);
|
auto it = m_print_statistics.used_filaments_per_role.find(role);
|
||||||
if (it == m_print_statistics.used_filaments_per_role.end())
|
if (it == m_print_statistics.used_filaments_per_role.end())
|
||||||
return std::make_pair(0.0, 0.0);
|
return std::make_pair(0.0, 0.0);
|
||||||
@ -3494,10 +3493,10 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
|
|
||||||
if (m_view_type == EViewType::FeatureType) {
|
if (m_view_type == EViewType::FeatureType) {
|
||||||
// calculate offsets to align time/percentage data
|
// calculate offsets to align time/percentage data
|
||||||
for (size_t i = 0; i < m_roles.size(); ++i) {
|
for (GCodeExtrusionRole role : m_roles) {
|
||||||
ExtrusionRole role = m_roles[i];
|
assert(role < erCount);
|
||||||
if (role < erCount) {
|
if (role < erCount) {
|
||||||
labels.push_back(_u8L(ExtrusionEntity::role_to_string(role)));
|
labels.push_back(_u8L(gcode_extrusion_role_to_string(role)));
|
||||||
auto [time, percent] = role_time_and_percent(role);
|
auto [time, percent] = role_time_and_percent(role);
|
||||||
times.push_back((time > 0.0f) ? short_time(get_time_dhms(time)) : "");
|
times.push_back((time > 0.0f) ? short_time(get_time_dhms(time)) : "");
|
||||||
percents.push_back(percent);
|
percents.push_back(percent);
|
||||||
@ -3610,7 +3609,7 @@ void GCodeViewer::render_legend(float& legend_height)
|
|||||||
max_time_percent = std::max(max_time_percent, time_mode.travel_time / time_mode.time);
|
max_time_percent = std::max(max_time_percent, time_mode.travel_time / time_mode.time);
|
||||||
|
|
||||||
for (size_t i = 0; i < m_roles.size(); ++i) {
|
for (size_t i = 0; i < m_roles.size(); ++i) {
|
||||||
ExtrusionRole role = m_roles[i];
|
GCodeExtrusionRole role = m_roles[i];
|
||||||
if (role >= erCount)
|
if (role >= erCount)
|
||||||
continue;
|
continue;
|
||||||
const bool visible = is_visible(role);
|
const bool visible = is_visible(role);
|
||||||
|
@ -208,7 +208,7 @@ class GCodeViewer
|
|||||||
};
|
};
|
||||||
|
|
||||||
EMoveType type{ EMoveType::Noop };
|
EMoveType type{ EMoveType::Noop };
|
||||||
ExtrusionRole role{ erNone };
|
GCodeExtrusionRole role{ erNone };
|
||||||
float delta_extruder{ 0.0f };
|
float delta_extruder{ 0.0f };
|
||||||
float height{ 0.0f };
|
float height{ 0.0f };
|
||||||
float width{ 0.0f };
|
float width{ 0.0f };
|
||||||
@ -753,7 +753,7 @@ private:
|
|||||||
std::vector<ColorRGBA> m_tool_colors;
|
std::vector<ColorRGBA> m_tool_colors;
|
||||||
Layers m_layers;
|
Layers m_layers;
|
||||||
std::array<unsigned int, 2> m_layers_z_range;
|
std::array<unsigned int, 2> m_layers_z_range;
|
||||||
std::vector<ExtrusionRole> m_roles;
|
std::vector<GCodeExtrusionRole> m_roles;
|
||||||
size_t m_extruders_count;
|
size_t m_extruders_count;
|
||||||
std::vector<unsigned char> m_extruder_ids;
|
std::vector<unsigned char> m_extruder_ids;
|
||||||
std::vector<float> m_filament_diameters;
|
std::vector<float> m_filament_diameters;
|
||||||
@ -849,7 +849,7 @@ private:
|
|||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
void render_statistics();
|
void render_statistics();
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
bool is_visible(ExtrusionRole role) const {
|
bool is_visible(GCodeExtrusionRole role) const {
|
||||||
return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0;
|
return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0;
|
||||||
}
|
}
|
||||||
bool is_visible(const Path& path) const { return is_visible(path.role); }
|
bool is_visible(const Path& path) const { return is_visible(path.role); }
|
||||||
|
@ -6567,7 +6567,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||||||
if (support_layer) {
|
if (support_layer) {
|
||||||
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
|
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
|
||||||
_3DScene::extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
|
_3DScene::extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
|
||||||
select_geometry(idx_layer, (extrusion_entity->role() == erSupportMaterial) ?
|
select_geometry(idx_layer, (extrusion_entity->role() == ExtrusionRole::SupportMaterial) ?
|
||||||
support_layer->object()->config().support_material_extruder :
|
support_layer->object()->config().support_material_extruder :
|
||||||
support_layer->object()->config().support_material_interface_extruder, 2));
|
support_layer->object()->config().support_material_interface_extruder, 2));
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ static inline Slic3r::Point random_point(float LO=-50, float HI=50)
|
|||||||
// build a sample extrusion entity collection with random start and end points.
|
// build a sample extrusion entity collection with random start and end points.
|
||||||
static Slic3r::ExtrusionPath random_path(size_t length = 20, float LO = -50, float HI = 50)
|
static Slic3r::ExtrusionPath random_path(size_t length = 20, float LO = -50, float HI = 50)
|
||||||
{
|
{
|
||||||
ExtrusionPath t {erPerimeter, 1.0, 1.0, 1.0};
|
ExtrusionPath t { ExtrusionRole::Perimeter, 1.0, 1.0, 1.0 };
|
||||||
for (size_t j = 0; j < length; ++ j)
|
for (size_t j = 0; j < length; ++ j)
|
||||||
t.polyline.append(random_point(LO, HI));
|
t.polyline.append(random_point(LO, HI));
|
||||||
return t;
|
return t;
|
||||||
@ -37,7 +37,7 @@ static Slic3r::ExtrusionPaths random_paths(size_t count = 10, size_t length = 20
|
|||||||
|
|
||||||
SCENARIO("ExtrusionPath", "[ExtrusionEntity]") {
|
SCENARIO("ExtrusionPath", "[ExtrusionEntity]") {
|
||||||
GIVEN("Simple path") {
|
GIVEN("Simple path") {
|
||||||
Slic3r::ExtrusionPath path{ erExternalPerimeter };
|
Slic3r::ExtrusionPath path{ ExtrusionRole::ExternalPerimeter };
|
||||||
path.polyline = { { 100, 100 }, { 200, 100 }, { 200, 200 } };
|
path.polyline = { { 100, 100 }, { 200, 100 }, { 200, 200 } };
|
||||||
path.mm3_per_mm = 1.;
|
path.mm3_per_mm = 1.;
|
||||||
THEN("first point") {
|
THEN("first point") {
|
||||||
@ -64,7 +64,7 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
Polygon square { { 100, 100 }, { 200, 100 }, { 200, 200 }, { 100, 200 } };
|
Polygon square { { 100, 100 }, { 200, 100 }, { 200, 200 }, { 100, 200 } };
|
||||||
|
|
||||||
ExtrusionLoop loop;
|
ExtrusionLoop loop;
|
||||||
loop.paths.emplace_back(new_extrusion_path(square.split_at_first_point(), erExternalPerimeter, 1.));
|
loop.paths.emplace_back(new_extrusion_path(square.split_at_first_point(), ExtrusionRole::ExternalPerimeter, 1.));
|
||||||
THEN("polygon area") {
|
THEN("polygon area") {
|
||||||
REQUIRE(loop.polygon().area() == Approx(square.area()));
|
REQUIRE(loop.polygon().area() == Approx(square.area()));
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
REQUIRE(loop2->paths.size() == 1);
|
REQUIRE(loop2->paths.size() == 1);
|
||||||
}
|
}
|
||||||
THEN("cloned role") {
|
THEN("cloned role") {
|
||||||
REQUIRE(loop2->paths.front().role() == erExternalPerimeter);
|
REQUIRE(loop2->paths.front().role() == ExtrusionRole::ExternalPerimeter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WHEN("cloned and split") {
|
WHEN("cloned and split") {
|
||||||
@ -107,8 +107,8 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
Polyline polyline1 { { 100, 100 }, { 200, 100 }, { 200, 200 } };
|
Polyline polyline1 { { 100, 100 }, { 200, 100 }, { 200, 200 } };
|
||||||
Polyline polyline2 { { 200, 200 }, { 100, 200 }, { 100, 100 } };
|
Polyline polyline2 { { 200, 200 }, { 100, 200 }, { 100, 100 } };
|
||||||
ExtrusionLoop loop;
|
ExtrusionLoop loop;
|
||||||
loop.paths.emplace_back(new_extrusion_path(polyline1, erExternalPerimeter, 1.));
|
loop.paths.emplace_back(new_extrusion_path(polyline1, ExtrusionRole::ExternalPerimeter, 1.));
|
||||||
loop.paths.emplace_back(new_extrusion_path(polyline2, erOverhangPerimeter, 1.));
|
loop.paths.emplace_back(new_extrusion_path(polyline2, ExtrusionRole::OverhangPerimeter, 1.));
|
||||||
|
|
||||||
double tot_len = polyline1.length() + polyline2.length();
|
double tot_len = polyline1.length() + polyline2.length();
|
||||||
THEN("length") {
|
THEN("length") {
|
||||||
@ -135,9 +135,9 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
REQUIRE(loop2->paths[1].polyline.back() == loop2->paths[2].polyline.front());
|
REQUIRE(loop2->paths[1].polyline.back() == loop2->paths[2].polyline.front());
|
||||||
}
|
}
|
||||||
THEN("expected order after splitting") {
|
THEN("expected order after splitting") {
|
||||||
REQUIRE(loop2->paths.front().role() == erExternalPerimeter);
|
REQUIRE(loop2->paths.front().role() == ExtrusionRole::ExternalPerimeter);
|
||||||
REQUIRE(loop2->paths[1].role() == erOverhangPerimeter);
|
REQUIRE(loop2->paths[1].role() == ExtrusionRole::OverhangPerimeter);
|
||||||
REQUIRE(loop2->paths[2].role() == erExternalPerimeter);
|
REQUIRE(loop2->paths[2].role() == ExtrusionRole::ExternalPerimeter);
|
||||||
}
|
}
|
||||||
THEN("path has correct number of points") {
|
THEN("path has correct number of points") {
|
||||||
REQUIRE(loop2->paths.front().polyline.size() == 2);
|
REQUIRE(loop2->paths.front().polyline.size() == 2);
|
||||||
@ -175,8 +175,8 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
REQUIRE(loop2->paths[1].polyline.back() == loop2->paths.front().polyline.front());
|
REQUIRE(loop2->paths[1].polyline.back() == loop2->paths.front().polyline.front());
|
||||||
}
|
}
|
||||||
THEN("expected order after splitting") {
|
THEN("expected order after splitting") {
|
||||||
REQUIRE(loop2->paths.front().role() == erOverhangPerimeter);
|
REQUIRE(loop2->paths.front().role() == ExtrusionRole::OverhangPerimeter);
|
||||||
REQUIRE(loop2->paths[1].role() == erExternalPerimeter);
|
REQUIRE(loop2->paths[1].role() == ExtrusionRole::ExternalPerimeter);
|
||||||
}
|
}
|
||||||
THEN("path has correct number of points") {
|
THEN("path has correct number of points") {
|
||||||
REQUIRE(loop2->paths.front().polyline.size() == 3);
|
REQUIRE(loop2->paths.front().polyline.size() == 3);
|
||||||
@ -207,10 +207,10 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
Polyline polyline3 { { 9829401, 9321068 }, { 4821067, 9321068 }, { 4821067, 4821067 }, { 9829401, 4821067 } };
|
Polyline polyline3 { { 9829401, 9321068 }, { 4821067, 9321068 }, { 4821067, 4821067 }, { 9829401, 4821067 } };
|
||||||
Polyline polyline4 { { 9829401, 4821067 }, { 59312736,4821067 } };
|
Polyline polyline4 { { 9829401, 4821067 }, { 59312736,4821067 } };
|
||||||
ExtrusionLoop loop;
|
ExtrusionLoop loop;
|
||||||
loop.paths.emplace_back(new_extrusion_path(polyline1, erExternalPerimeter, 1.));
|
loop.paths.emplace_back(new_extrusion_path(polyline1, ExtrusionRole::ExternalPerimeter, 1.));
|
||||||
loop.paths.emplace_back(new_extrusion_path(polyline2, erOverhangPerimeter, 1.));
|
loop.paths.emplace_back(new_extrusion_path(polyline2, ExtrusionRole::OverhangPerimeter, 1.));
|
||||||
loop.paths.emplace_back(new_extrusion_path(polyline3, erExternalPerimeter, 1.));
|
loop.paths.emplace_back(new_extrusion_path(polyline3, ExtrusionRole::ExternalPerimeter, 1.));
|
||||||
loop.paths.emplace_back(new_extrusion_path(polyline4, erOverhangPerimeter, 1.));
|
loop.paths.emplace_back(new_extrusion_path(polyline4, ExtrusionRole::OverhangPerimeter, 1.));
|
||||||
double len = loop.length();
|
double len = loop.length();
|
||||||
WHEN("splitting at vertex") {
|
WHEN("splitting at vertex") {
|
||||||
Point point(4821067, 9321068);
|
Point point(4821067, 9321068);
|
||||||
@ -220,10 +220,10 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
REQUIRE(loop.length() == Approx(len));
|
REQUIRE(loop.length() == Approx(len));
|
||||||
}
|
}
|
||||||
THEN("order is correctly preserved after splitting") {
|
THEN("order is correctly preserved after splitting") {
|
||||||
REQUIRE(loop.paths.front().role() == erExternalPerimeter);
|
REQUIRE(loop.paths.front().role() == ExtrusionRole::ExternalPerimeter);
|
||||||
REQUIRE(loop.paths[1].role() == erOverhangPerimeter);
|
REQUIRE(loop.paths[1].role() == ExtrusionRole::OverhangPerimeter);
|
||||||
REQUIRE(loop.paths[2].role() == erExternalPerimeter);
|
REQUIRE(loop.paths[2].role() == ExtrusionRole::ExternalPerimeter);
|
||||||
REQUIRE(loop.paths[3].role() == erOverhangPerimeter);
|
REQUIRE(loop.paths[3].role() == ExtrusionRole::OverhangPerimeter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
loop.paths.emplace_back(new_extrusion_path(
|
loop.paths.emplace_back(new_extrusion_path(
|
||||||
Polyline { { 15896783, 15868739 }, { 24842049, 12117558 }, { 33853238, 15801279 }, { 37591780, 24780128 }, { 37591780, 24844970 },
|
Polyline { { 15896783, 15868739 }, { 24842049, 12117558 }, { 33853238, 15801279 }, { 37591780, 24780128 }, { 37591780, 24844970 },
|
||||||
{ 33853231, 33825297 }, { 24842049, 37509013 }, { 15896798, 33757841 }, { 12211841, 24812544 }, { 15896783, 15868739 } },
|
{ 33853231, 33825297 }, { 24842049, 37509013 }, { 15896798, 33757841 }, { 12211841, 24812544 }, { 15896783, 15868739 } },
|
||||||
erExternalPerimeter, 1.));
|
ExtrusionRole::ExternalPerimeter, 1.));
|
||||||
double len = loop.length();
|
double len = loop.length();
|
||||||
THEN("split_at() preserves total length") {
|
THEN("split_at() preserves total length") {
|
||||||
loop.split_at({ 15896783, 15868739 }, false, 0);
|
loop.split_at({ 15896783, 15868739 }, false, 0);
|
||||||
@ -245,9 +245,9 @@ SCENARIO("ExtrusionLoop", "[ExtrusionEntity]")
|
|||||||
SCENARIO("ExtrusionEntityCollection: Basics", "[ExtrusionEntity]")
|
SCENARIO("ExtrusionEntityCollection: Basics", "[ExtrusionEntity]")
|
||||||
{
|
{
|
||||||
Polyline polyline { { 100, 100 }, { 200, 100 }, { 200, 200 } };
|
Polyline polyline { { 100, 100 }, { 200, 100 }, { 200, 200 } };
|
||||||
ExtrusionPath path = new_extrusion_path(polyline, erExternalPerimeter, 1.);
|
ExtrusionPath path = new_extrusion_path(polyline, ExtrusionRole::ExternalPerimeter, 1.);
|
||||||
ExtrusionLoop loop;
|
ExtrusionLoop loop;
|
||||||
loop.paths.emplace_back(new_extrusion_path(Polygon(polyline.points).split_at_first_point(), erInternalInfill, 1.));
|
loop.paths.emplace_back(new_extrusion_path(Polygon(polyline.points).split_at_first_point(), ExtrusionRole::InternalInfill, 1.));
|
||||||
ExtrusionEntityCollection collection;
|
ExtrusionEntityCollection collection;
|
||||||
collection.append(path);
|
collection.append(path);
|
||||||
THEN("no_sort is false by default") {
|
THEN("no_sort is false by default") {
|
||||||
@ -378,7 +378,7 @@ TEST_CASE("ExtrusionEntityCollection: Chained path", "[ExtrusionEntity]") {
|
|||||||
REQUIRE(chained == test.chained);
|
REQUIRE(chained == test.chained);
|
||||||
ExtrusionEntityCollection unchained_extrusions;
|
ExtrusionEntityCollection unchained_extrusions;
|
||||||
extrusion_entities_append_paths(unchained_extrusions.entities, test.unchained,
|
extrusion_entities_append_paths(unchained_extrusions.entities, test.unchained,
|
||||||
erInternalInfill, 0., 0.4f, 0.3f);
|
ExtrusionRole::InternalInfill, 0., 0.4f, 0.3f);
|
||||||
THEN("Chaining works") {
|
THEN("Chaining works") {
|
||||||
ExtrusionEntityCollection chained_extrusions = unchained_extrusions.chained_path_from(test.initial_point);
|
ExtrusionEntityCollection chained_extrusions = unchained_extrusions.chained_path_from(test.initial_point);
|
||||||
REQUIRE(chained_extrusions.entities.size() == test.chained.size());
|
REQUIRE(chained_extrusions.entities.size() == test.chained.size());
|
||||||
|
@ -80,13 +80,13 @@ SCENARIO("Perimeter nesting", "[Perimeters]")
|
|||||||
}
|
}
|
||||||
THEN("expected number of external loops") {
|
THEN("expected number of external loops") {
|
||||||
size_t num_external = std::count_if(loops.entities.begin(), loops.entities.end(),
|
size_t num_external = std::count_if(loops.entities.begin(), loops.entities.end(),
|
||||||
[](const ExtrusionEntity *ee){ return ee->role() == erExternalPerimeter; });
|
[](const ExtrusionEntity *ee){ return ee->role() == ExtrusionRole::ExternalPerimeter; });
|
||||||
REQUIRE(num_external == data.external);
|
REQUIRE(num_external == data.external);
|
||||||
}
|
}
|
||||||
THEN("expected external order") {
|
THEN("expected external order") {
|
||||||
std::vector<bool> ext_order;
|
std::vector<bool> ext_order;
|
||||||
for (auto *ee : loops.entities)
|
for (auto *ee : loops.entities)
|
||||||
ext_order.emplace_back(ee->role() == erExternalPerimeter);
|
ext_order.emplace_back(ee->role() == ExtrusionRole::ExternalPerimeter);
|
||||||
REQUIRE(ext_order == data.ext_order);
|
REQUIRE(ext_order == data.ext_order);
|
||||||
}
|
}
|
||||||
THEN("expected number of internal contour loops") {
|
THEN("expected number of internal contour loops") {
|
||||||
|
Loading…
Reference in New Issue
Block a user