Extending the expressivity of ExtrusionRole
Moved is_xx() test functions to ExtrusionRole enum class, changed the tests to use the new ExtrusionRole bitmask. Follow-up to5991850db1
e50e96bb26
c64dbacf88
This commit is contained in:
parent
c64dbacf88
commit
d1f610d957
@ -50,7 +50,7 @@ void ExtrusionPath::polygons_covered_by_spacing(Polygons &out, const float scale
|
|||||||
{
|
{
|
||||||
// Instantiating the Flow class to get the line spacing.
|
// Instantiating the Flow class to get the line spacing.
|
||||||
// Don't know the nozzle diameter, setting to zero. It shall not matter it shall be optimized out by the compiler.
|
// Don't know the nozzle diameter, setting to zero. It shall not matter it shall be optimized out by the compiler.
|
||||||
bool bridge = is_bridge(this->role());
|
bool bridge = this->role().is_bridge();
|
||||||
assert(! bridge || this->width == this->height);
|
assert(! bridge || this->width == this->height);
|
||||||
auto flow = bridge ? Flow::bridging_flow(this->width, 0.f) : Flow(this->width, this->height, 0.f);
|
auto flow = bridge ? Flow::bridging_flow(this->width, 0.f) : Flow(this->width, this->height, 0.f);
|
||||||
polygons_append(out, offset(this->polyline, 0.5f * float(flow.scaled_spacing()) + scaled_epsilon));
|
polygons_append(out, offset(this->polyline, 0.5f * float(flow.scaled_spacing()) + scaled_epsilon));
|
||||||
@ -208,7 +208,7 @@ ExtrusionLoop::ClosestPathPoint ExtrusionLoop::get_closest_path_and_point(const
|
|||||||
out.segment_idx = foot_pt_.first;
|
out.segment_idx = foot_pt_.first;
|
||||||
min2 = d2;
|
min2 = d2;
|
||||||
}
|
}
|
||||||
if (prefer_non_overhang && !is_bridge(path.role()) && d2 < min2_non_overhang) {
|
if (prefer_non_overhang && ! path.role().is_bridge() && d2 < min2_non_overhang) {
|
||||||
best_non_overhang.foot_pt = foot_pt_.second;
|
best_non_overhang.foot_pt = foot_pt_.second;
|
||||||
best_non_overhang.path_idx = &path - &this->paths.front();
|
best_non_overhang.path_idx = &path - &this->paths.front();
|
||||||
best_non_overhang.segment_idx = foot_pt_.first;
|
best_non_overhang.segment_idx = foot_pt_.first;
|
||||||
@ -294,7 +294,7 @@ bool ExtrusionLoop::has_overhang_point(const Point &point) const
|
|||||||
if (pos != -1) {
|
if (pos != -1) {
|
||||||
// point belongs to this path
|
// point belongs to this path
|
||||||
// we consider it overhang only if it's not an endpoint
|
// we consider it overhang only if it's not an endpoint
|
||||||
return (is_bridge(path.role()) && pos > 0 && pos != (int)(path.polyline.points.size())-1);
|
return (path.role().is_bridge() && pos > 0 && pos != int(path.polyline.points.size())-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -58,7 +58,7 @@ struct ExtrusionRole : public ExtrusionRoleModifiers
|
|||||||
//FIXME why there is no bottom solid infill type?
|
//FIXME why there is no bottom solid infill type?
|
||||||
static constexpr const ExtrusionRoleModifiers TopSolidInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::External };
|
static constexpr const ExtrusionRoleModifiers TopSolidInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::External };
|
||||||
// Ironing infill at the top surfaces.
|
// Ironing infill at the top surfaces.
|
||||||
static constexpr const ExtrusionRoleModifiers Ironing{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Ironing | ExtrusionRoleModifier::External };
|
static constexpr const ExtrusionRoleModifiers Ironing{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::Ironing | ExtrusionRoleModifier::External };
|
||||||
// Visible bridging infill at the bottom of an object.
|
// 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 BridgeInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::Bridge | ExtrusionRoleModifier::External };
|
||||||
// static constexpr const ExtrusionRoleModifiers InternalBridgeInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::Bridge };
|
// static constexpr const ExtrusionRoleModifiers InternalBridgeInfill{ ExtrusionRoleModifier::Infill | ExtrusionRoleModifier::Solid | ExtrusionRoleModifier::Bridge };
|
||||||
@ -76,6 +76,13 @@ struct ExtrusionRole : public ExtrusionRoleModifiers
|
|||||||
static constexpr const ExtrusionRoleModifiers WipeTower{ ExtrusionRoleModifier::Wipe };
|
static constexpr const ExtrusionRoleModifiers WipeTower{ ExtrusionRoleModifier::Wipe };
|
||||||
// Extrusion role for a collection with multiple extrusion roles.
|
// Extrusion role for a collection with multiple extrusion roles.
|
||||||
static constexpr const ExtrusionRoleModifiers Mixed{ ExtrusionRoleModifier::Mixed };
|
static constexpr const ExtrusionRoleModifiers Mixed{ ExtrusionRoleModifier::Mixed };
|
||||||
|
|
||||||
|
bool is_perimeter() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Perimeter); }
|
||||||
|
bool is_external_perimeter() const { return this->is_perimeter() && this->is_external(); }
|
||||||
|
bool is_infill() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Infill); }
|
||||||
|
bool is_solid_infill() const { return this->is_infill() && this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Solid); }
|
||||||
|
bool is_external() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::External); }
|
||||||
|
bool is_bridge() const { return this->ExtrusionRoleModifiers::has(ExtrusionRoleModifier::Bridge); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special flags describing loop
|
// Special flags describing loop
|
||||||
@ -85,35 +92,6 @@ enum ExtrusionLoopRole {
|
|||||||
elrSkirt,
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Be careful when editing this list as many parts of the code depend
|
// Be careful when editing this list as many parts of the code depend
|
||||||
// on the values of these ordinars, for example
|
// on the values of these ordinars, for example
|
||||||
// GCodeViewer::Extrusion_Role_Colors
|
// GCodeViewer::Extrusion_Role_Colors
|
||||||
|
@ -2601,7 +2601,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, const std::string_view descr
|
|||||||
if (paths.empty()) return "";
|
if (paths.empty()) return "";
|
||||||
|
|
||||||
// apply the small perimeter speed
|
// apply the small perimeter speed
|
||||||
if (is_perimeter(paths.front().role()) && loop.length() <= SMALL_PERIMETER_LENGTH && speed == -1)
|
if (paths.front().role().is_perimeter() && loop.length() <= SMALL_PERIMETER_LENGTH && speed == -1)
|
||||||
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
|
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
|
||||||
|
|
||||||
// extrude along the path
|
// extrude along the path
|
||||||
@ -2618,7 +2618,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, const std::string_view descr
|
|||||||
m_wipe.path = paths.front().polyline;
|
m_wipe.path = paths.front().polyline;
|
||||||
|
|
||||||
for (auto it = std::next(paths.begin()); it != paths.end(); ++it) {
|
for (auto it = std::next(paths.begin()); it != paths.end(); ++it) {
|
||||||
if (is_bridge(it->role()))
|
if (it->role().is_bridge())
|
||||||
break; // Don't perform a wipe on bridges.
|
break; // Don't perform a wipe on bridges.
|
||||||
|
|
||||||
assert(it->polyline.points.size() >= 2);
|
assert(it->polyline.points.size() >= 2);
|
||||||
@ -2686,7 +2686,7 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, const std::s
|
|||||||
m_wipe.path.reverse();
|
m_wipe.path.reverse();
|
||||||
|
|
||||||
for (auto it = std::next(multipath.paths.rbegin()); it != multipath.paths.rend(); ++it) {
|
for (auto it = std::next(multipath.paths.rbegin()); it != multipath.paths.rend(); ++it) {
|
||||||
if (is_bridge(it->role()))
|
if (it->role().is_bridge())
|
||||||
break; // Do not perform a wipe on bridges.
|
break; // Do not perform a wipe on bridges.
|
||||||
|
|
||||||
assert(it->polyline.points.size() >= 2);
|
assert(it->polyline.points.size() >= 2);
|
||||||
@ -2831,7 +2831,7 @@ void GCode::GCodeOutputStream::write_format(const char* format, ...)
|
|||||||
std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view description, double speed)
|
std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view description, double speed)
|
||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
const std::string_view description_bridge = is_bridge(path.role()) ? " (bridge)"sv : ""sv;
|
const std::string_view description_bridge = path.role().is_bridge() ? " (bridge)"sv : ""sv;
|
||||||
|
|
||||||
// go to first point of extrusion path
|
// go to first point of extrusion path
|
||||||
if (!m_last_pos_defined || m_last_pos != path.first_point()) {
|
if (!m_last_pos_defined || m_last_pos != path.first_point()) {
|
||||||
@ -2852,11 +2852,11 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
acceleration = m_config.first_layer_acceleration.value;
|
acceleration = m_config.first_layer_acceleration.value;
|
||||||
} else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) {
|
} else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) {
|
||||||
acceleration = m_config.first_layer_acceleration_over_raft.value;
|
acceleration = m_config.first_layer_acceleration_over_raft.value;
|
||||||
} else if (m_config.bridge_acceleration.value > 0 && is_bridge(path.role())) {
|
} else if (m_config.bridge_acceleration.value > 0 && path.role().is_bridge()) {
|
||||||
acceleration = m_config.bridge_acceleration.value;
|
acceleration = m_config.bridge_acceleration.value;
|
||||||
} else if (m_config.infill_acceleration.value > 0 && is_infill(path.role())) {
|
} else if (m_config.infill_acceleration.value > 0 && path.role().is_infill()) {
|
||||||
acceleration = m_config.infill_acceleration.value;
|
acceleration = m_config.infill_acceleration.value;
|
||||||
} else if (m_config.perimeter_acceleration.value > 0 && is_perimeter(path.role())) {
|
} else if (m_config.perimeter_acceleration.value > 0 && path.role().is_perimeter()) {
|
||||||
acceleration = m_config.perimeter_acceleration.value;
|
acceleration = m_config.perimeter_acceleration.value;
|
||||||
} else {
|
} else {
|
||||||
acceleration = m_config.default_acceleration.value;
|
acceleration = m_config.default_acceleration.value;
|
||||||
@ -2876,7 +2876,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
speed = m_config.get_abs_value("perimeter_speed");
|
speed = m_config.get_abs_value("perimeter_speed");
|
||||||
} else if (path.role() == ExtrusionRole::ExternalPerimeter) {
|
} 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() == ExtrusionRole::OverhangPerimeter || path.role() == ExtrusionRole::BridgeInfill) {
|
} else if (path.role().is_bridge()) {
|
||||||
|
assert(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() == ExtrusionRole::InternalInfill) {
|
} else if (path.role() == ExtrusionRole::InternalInfill) {
|
||||||
speed = m_config.get_abs_value("infill_speed");
|
speed = m_config.get_abs_value("infill_speed");
|
||||||
@ -2915,7 +2916,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
|
|
||||||
bool variable_speed = false;
|
bool variable_speed = false;
|
||||||
std::vector<ProcessedPoint> new_points{};
|
std::vector<ProcessedPoint> new_points{};
|
||||||
if (this->m_config.enable_dynamic_overhang_speeds && !this->on_first_layer() && is_perimeter(path.role())) {
|
if (this->m_config.enable_dynamic_overhang_speeds && !this->on_first_layer() && path.role().is_perimeter()) {
|
||||||
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, m_config.overhang_overlap_levels,
|
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, m_config.overhang_overlap_levels,
|
||||||
m_config.dynamic_overhang_speeds,
|
m_config.dynamic_overhang_speeds,
|
||||||
m_config.get_abs_value("external_perimeter_speed"), speed);
|
m_config.get_abs_value("external_perimeter_speed"), speed);
|
||||||
@ -2975,7 +2976,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
|
|
||||||
std::string comment;
|
std::string comment;
|
||||||
if (m_enable_cooling_markers) {
|
if (m_enable_cooling_markers) {
|
||||||
if (is_bridge(path.role()))
|
if (path.role().is_bridge())
|
||||||
gcode += ";_BRIDGE_FAN_START\n";
|
gcode += ";_BRIDGE_FAN_START\n";
|
||||||
else
|
else
|
||||||
comment = ";_EXTRUDE_SET_SPEED";
|
comment = ";_EXTRUDE_SET_SPEED";
|
||||||
@ -3026,7 +3027,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, const std::string_view de
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_enable_cooling_markers)
|
if (m_enable_cooling_markers)
|
||||||
gcode += is_bridge(path.role()) ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n";
|
gcode += path.role().is_bridge() ? ";_BRIDGE_FAN_END\n" : ";_EXTRUDE_END\n";
|
||||||
|
|
||||||
this->set_last_pos(path.last_point());
|
this->set_last_pos(path.last_point());
|
||||||
return gcode;
|
return gcode;
|
||||||
|
@ -63,11 +63,11 @@ unsigned int LayerTools::extruder(const ExtrusionEntityCollection &extrusions, c
|
|||||||
assert(region.config().infill_extruder.value > 0);
|
assert(region.config().infill_extruder.value > 0);
|
||||||
assert(region.config().solid_infill_extruder.value > 0);
|
assert(region.config().solid_infill_extruder.value > 0);
|
||||||
// 1 based extruder ID.
|
// 1 based extruder ID.
|
||||||
unsigned int extruder = ((this->extruder_override == 0) ?
|
unsigned int extruder = this->extruder_override == 0 ?
|
||||||
(is_infill(extrusions.role()) ?
|
(extrusions.role().is_infill() ?
|
||||||
(is_solid_infill(extrusions.entities.front()->role()) ? region.config().solid_infill_extruder : region.config().infill_extruder) :
|
(extrusions.entities.front()->role().is_solid_infill() ? region.config().solid_infill_extruder : region.config().infill_extruder) :
|
||||||
region.config().perimeter_extruder.value) :
|
region.config().perimeter_extruder.value) :
|
||||||
this->extruder_override);
|
this->extruder_override;
|
||||||
return (extruder == 0) ? 0 : extruder - 1;
|
return (extruder == 0) ? 0 : extruder - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
|||||||
// 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() ? ExtrusionRole::None : fill->entities.front()->role();
|
ExtrusionRole role = fill->entities.empty() ? ExtrusionRole::None : fill->entities.front()->role();
|
||||||
if (is_solid_infill(role))
|
if (role.is_solid_infill())
|
||||||
has_solid_infill = true;
|
has_solid_infill = true;
|
||||||
else if (role != ExtrusionRole::None)
|
else if (role != ExtrusionRole::None)
|
||||||
has_infill = true;
|
has_infill = true;
|
||||||
|
@ -58,6 +58,8 @@ public:
|
|||||||
bool is_external_perimeter() const
|
bool is_external_perimeter() const
|
||||||
{
|
{
|
||||||
assert(origin_entity != nullptr);
|
assert(origin_entity != nullptr);
|
||||||
|
//FIXME origin_entity->role() == ExtrusionRole::OverhangPerimeter is not quite right.
|
||||||
|
// rather use origin_entity->role().is_external_perimeter()
|
||||||
return origin_entity->role() == ExtrusionRole::ExternalPerimeter || origin_entity->role() == ExtrusionRole::OverhangPerimeter;
|
return origin_entity->role() == ExtrusionRole::ExternalPerimeter || origin_entity->role() == ExtrusionRole::OverhangPerimeter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,14 +31,14 @@ public:
|
|||||||
constexpr enum_bitmask(option_type o) : m_bits(mask_value(o)) {}
|
constexpr enum_bitmask(option_type o) : m_bits(mask_value(o)) {}
|
||||||
|
|
||||||
// Set the bit corresponding to the given option.
|
// Set the bit corresponding to the given option.
|
||||||
constexpr enum_bitmask operator|(option_type t) { return enum_bitmask(m_bits | mask_value(t)); }
|
constexpr enum_bitmask operator|(option_type t) const { return enum_bitmask(m_bits | mask_value(t)); }
|
||||||
|
|
||||||
// Combine with another enum_bitmask of the same type.
|
// Combine with another enum_bitmask of the same type.
|
||||||
constexpr enum_bitmask operator|(enum_bitmask<option_type> t) { return enum_bitmask(m_bits | t.m_bits); }
|
constexpr enum_bitmask operator|(enum_bitmask<option_type> t) const { return enum_bitmask(m_bits | t.m_bits); }
|
||||||
|
|
||||||
// Get the value of the bit corresponding to the given option.
|
// Get the value of the bit corresponding to the given option.
|
||||||
constexpr bool operator&(option_type t) { return m_bits & mask_value(t); }
|
constexpr bool operator&(option_type t) const { return m_bits & mask_value(t); }
|
||||||
constexpr bool has(option_type t) { return m_bits & mask_value(t); }
|
constexpr bool has(option_type t) const { 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; }
|
||||||
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; }
|
||||||
|
@ -6556,7 +6556,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||||||
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
|
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
|
||||||
if (! fill->entities.empty())
|
if (! fill->entities.empty())
|
||||||
_3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
|
_3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
|
||||||
select_geometry(idx_layer, is_solid_infill(fill->entities.front()->role()) ?
|
select_geometry(idx_layer, fill->entities.front()->role().is_solid_infill() ?
|
||||||
layerm->region().config().solid_infill_extruder :
|
layerm->region().config().solid_infill_extruder :
|
||||||
layerm->region().config().infill_extruder, 1));
|
layerm->region().config().infill_extruder, 1));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user