WIP Tree Supports: Refactored the classic FDM support generator

for modularity, so that the rasterization of support layers
is accessible from tree supports.
This commit is contained in:
Vojtech Bubnik 2022-07-27 08:50:59 +02:00
parent 23099c83dc
commit 075bf675fa
2 changed files with 490 additions and 474 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,53 +11,46 @@ class PrintObject;
class PrintConfig; class PrintConfig;
class PrintObjectConfig; class PrintObjectConfig;
// This class manages raft and supports for a single PrintObject. // Support layer type to be used by SupportGeneratorLayer. This type carries a much more detailed information
// Instantiated by Slic3r::Print::Object->_support_material() // about the support layer type than the final support layers stored in a PrintObject.
// This class is instantiated before the slicing starts as Object.pm will query enum SupporLayerType {
// the parameters of the raft to determine the 1st layer height and thickness. Unknown = 0,
class PrintObjectSupportMaterial // Ratft base layer, to be printed with the support material.
RaftBase,
// Raft interface layer, to be printed with the support interface material.
RaftInterface,
// Bottom contact layer placed over a top surface of an object. To be printed with a support interface material.
BottomContact,
// Dense interface layer, to be printed with the support interface material.
// This layer is separated from an object by an BottomContact layer.
BottomInterface,
// Sparse base support layer, to be printed with a support material.
Base,
// Dense interface layer, to be printed with the support interface material.
// This layer is separated from an object with TopContact layer.
TopInterface,
// Top contact layer directly supporting an overhang. To be printed with a support interface material.
TopContact,
// Some undecided type yet. It will turn into Base first, then it may turn into BottomInterface or TopInterface.
Intermediate,
};
// A support layer type used internally by the SupportMaterial class. This class carries a much more detailed
// information about the support layer than the layers stored in the PrintObject, mainly
// the SupportGeneratorLayer is aware of the bridging flow and the interface gaps between the object and the support.
class SupportGeneratorLayer
{ {
public: public:
// Support layer type to be used by MyLayer. This type carries a much more detailed information
// about the support layer type than the final support layers stored in a PrintObject.
enum SupporLayerType {
sltUnknown = 0,
// Ratft base layer, to be printed with the support material.
sltRaftBase,
// Raft interface layer, to be printed with the support interface material.
sltRaftInterface,
// Bottom contact layer placed over a top surface of an object. To be printed with a support interface material.
sltBottomContact,
// Dense interface layer, to be printed with the support interface material.
// This layer is separated from an object by an sltBottomContact layer.
sltBottomInterface,
// Sparse base support layer, to be printed with a support material.
sltBase,
// Dense interface layer, to be printed with the support interface material.
// This layer is separated from an object with sltTopContact layer.
sltTopInterface,
// Top contact layer directly supporting an overhang. To be printed with a support interface material.
sltTopContact,
// Some undecided type yet. It will turn into sltBase first, then it may turn into sltBottomInterface or sltTopInterface.
sltIntermediate,
};
// A support layer type used internally by the SupportMaterial class. This class carries a much more detailed
// information about the support layer than the layers stored in the PrintObject, mainly
// the MyLayer is aware of the bridging flow and the interface gaps between the object and the support.
class MyLayer
{
public:
void reset() { void reset() {
*this = MyLayer(); *this = SupportGeneratorLayer();
} }
bool operator==(const MyLayer &layer2) const { bool operator==(const SupportGeneratorLayer &layer2) const {
return print_z == layer2.print_z && height == layer2.height && bridging == layer2.bridging; return print_z == layer2.print_z && height == layer2.height && bridging == layer2.bridging;
} }
// Order the layers by lexicographically by an increasing print_z and a decreasing layer height. // Order the layers by lexicographically by an increasing print_z and a decreasing layer height.
bool operator<(const MyLayer &layer2) const { bool operator<(const SupportGeneratorLayer &layer2) const {
if (print_z < layer2.print_z) { if (print_z < layer2.print_z) {
return true; return true;
} else if (print_z == layer2.print_z) { } else if (print_z == layer2.print_z) {
@ -72,7 +65,7 @@ public:
return false; return false;
} }
void merge(MyLayer &&rhs) { void merge(SupportGeneratorLayer &&rhs) {
// The union_() does not support move semantic yet, but maybe one day it will. // The union_() does not support move semantic yet, but maybe one day it will.
this->polygons = union_(this->polygons, std::move(rhs.polygons)); this->polygons = union_(this->polygons, std::move(rhs.polygons));
auto merge = [](std::unique_ptr<Polygons> &dst, std::unique_ptr<Polygons> &src) { auto merge = [](std::unique_ptr<Polygons> &dst, std::unique_ptr<Polygons> &src) {
@ -92,9 +85,9 @@ public:
coordf_t bottom_print_z() const { return print_z - height; } coordf_t bottom_print_z() const { return print_z - height; }
// To sort the extremes of top / bottom interface layers. // To sort the extremes of top / bottom interface layers.
coordf_t extreme_z() const { return (this->layer_type == sltTopContact) ? this->bottom_z : this->print_z; } coordf_t extreme_z() const { return (this->layer_type == SupporLayerType::TopContact) ? this->bottom_z : this->print_z; }
SupporLayerType layer_type { sltUnknown }; SupporLayerType layer_type { SupporLayerType::Unknown };
// Z used for printing, in unscaled coordinates. // Z used for printing, in unscaled coordinates.
coordf_t print_z { 0 }; coordf_t print_z { 0 };
// Bottom Z of this layer. For soluble layers, bottom_z + height = print_z, // Bottom Z of this layer. For soluble layers, bottom_z + height = print_z,
@ -118,9 +111,17 @@ public:
std::unique_ptr<Polygons> overhang_polygons; std::unique_ptr<Polygons> overhang_polygons;
// Enforcers need to be propagated independently in case the "support on build plate only" option is enabled. // Enforcers need to be propagated independently in case the "support on build plate only" option is enabled.
std::unique_ptr<Polygons> enforcer_polygons; std::unique_ptr<Polygons> enforcer_polygons;
}; };
// Layers are allocated and owned by a deque. Once a layer is allocated, it is maintained
// up to the end of a generate() method. The layer storage may be replaced by an allocator class in the future,
// which would allocate layers by multiple chunks.
using SupportGeneratorLayerStorage = std::deque<SupportGeneratorLayer>;
using SupportGeneratorLayersPtr = std::vector<SupportGeneratorLayer*>;
struct SupportParameters {
SupportParameters(const PrintObject &object);
struct SupportParams {
Flow first_layer_flow; Flow first_layer_flow;
Flow support_material_flow; Flow support_material_flow;
Flow support_material_interface_flow; Flow support_material_interface_flow;
@ -129,7 +130,7 @@ public:
bool can_merge_support_regions; bool can_merge_support_regions;
coordf_t support_layer_height_min; coordf_t support_layer_height_min;
// coordf_t support_layer_height_max; // coordf_t support_layer_height_max;
coordf_t gap_xy; coordf_t gap_xy;
@ -144,14 +145,28 @@ public:
InfillPattern interface_fill_pattern; InfillPattern interface_fill_pattern;
InfillPattern contact_fill_pattern; InfillPattern contact_fill_pattern;
bool with_sheath; bool with_sheath;
}; };
// Layers are allocated and owned by a deque. Once a layer is allocated, it is maintained // Produce the support G-code.
// up to the end of a generate() method. The layer storage may be replaced by an allocator class in the future, // Used by both classic and tree supports.
// which would allocate layers by multiple chunks. static void generate_support_toolpaths(
typedef std::deque<MyLayer> MyLayerStorage; SupportLayerPtrs &support_layers,
typedef std::vector<MyLayer*> MyLayersPtr; const PrintObjectConfig &config,
const SupportParameters &support_params,
const SlicingParameters &slicing_params,
const SupportGeneratorLayersPtr &raft_layers,
const SupportGeneratorLayersPtr &bottom_contacts,
const SupportGeneratorLayersPtr &top_contacts,
const SupportGeneratorLayersPtr &intermediate_layers,
const SupportGeneratorLayersPtr &interface_layers,
const SupportGeneratorLayersPtr &base_interface_layers);
// This class manages raft and supports for a single PrintObject.
// Instantiated by Slic3r::Print::Object->_support_material()
// This class is instantiated before the slicing starts as Object.pm will query
// the parameters of the raft to determine the 1st layer height and thickness.
class PrintObjectSupportMaterial
{
public: public:
PrintObjectSupportMaterial(const PrintObject *object, const SlicingParameters &slicing_params); PrintObjectSupportMaterial(const PrintObject *object, const SlicingParameters &slicing_params);
@ -175,58 +190,58 @@ private:
// Generate top contact layers supporting overhangs. // Generate top contact layers supporting overhangs.
// For a soluble interface material synchronize the layer heights with the object, otherwise leave the layer height undefined. // For a soluble interface material synchronize the layer heights with the object, otherwise leave the layer height undefined.
// If supports over bed surface only are requested, don't generate contact layers over an object. // If supports over bed surface only are requested, don't generate contact layers over an object.
MyLayersPtr top_contact_layers(const PrintObject &object, const std::vector<Polygons> &buildplate_covered, MyLayerStorage &layer_storage) const; SupportGeneratorLayersPtr top_contact_layers(const PrintObject &object, const std::vector<Polygons> &buildplate_covered, SupportGeneratorLayerStorage &layer_storage) const;
// Generate bottom contact layers supporting the top contact layers. // Generate bottom contact layers supporting the top contact layers.
// For a soluble interface material synchronize the layer heights with the object, // For a soluble interface material synchronize the layer heights with the object,
// otherwise set the layer height to a bridging flow of a support interface nozzle. // otherwise set the layer height to a bridging flow of a support interface nozzle.
MyLayersPtr bottom_contact_layers_and_layer_support_areas( SupportGeneratorLayersPtr bottom_contact_layers_and_layer_support_areas(
const PrintObject &object, const MyLayersPtr &top_contacts, std::vector<Polygons> &buildplate_covered, const PrintObject &object, const SupportGeneratorLayersPtr &top_contacts, std::vector<Polygons> &buildplate_covered,
MyLayerStorage &layer_storage, std::vector<Polygons> &layer_support_areas) const; SupportGeneratorLayerStorage &layer_storage, std::vector<Polygons> &layer_support_areas) const;
// Trim the top_contacts layers with the bottom_contacts layers if they overlap, so there would not be enough vertical space for both of them. // Trim the top_contacts layers with the bottom_contacts layers if they overlap, so there would not be enough vertical space for both of them.
void trim_top_contacts_by_bottom_contacts(const PrintObject &object, const MyLayersPtr &bottom_contacts, MyLayersPtr &top_contacts) const; void trim_top_contacts_by_bottom_contacts(const PrintObject &object, const SupportGeneratorLayersPtr &bottom_contacts, SupportGeneratorLayersPtr &top_contacts) const;
// Generate raft layers and the intermediate support layers between the bottom contact and top contact surfaces. // Generate raft layers and the intermediate support layers between the bottom contact and top contact surfaces.
MyLayersPtr raft_and_intermediate_support_layers( SupportGeneratorLayersPtr raft_and_intermediate_support_layers(
const PrintObject &object, const PrintObject &object,
const MyLayersPtr &bottom_contacts, const SupportGeneratorLayersPtr &bottom_contacts,
const MyLayersPtr &top_contacts, const SupportGeneratorLayersPtr &top_contacts,
MyLayerStorage &layer_storage) const; SupportGeneratorLayerStorage &layer_storage) const;
// Fill in the base layers with polygons. // Fill in the base layers with polygons.
void generate_base_layers( void generate_base_layers(
const PrintObject &object, const PrintObject &object,
const MyLayersPtr &bottom_contacts, const SupportGeneratorLayersPtr &bottom_contacts,
const MyLayersPtr &top_contacts, const SupportGeneratorLayersPtr &top_contacts,
MyLayersPtr &intermediate_layers, SupportGeneratorLayersPtr &intermediate_layers,
const std::vector<Polygons> &layer_support_areas) const; const std::vector<Polygons> &layer_support_areas) const;
// Generate raft layers, also expand the 1st support layer // Generate raft layers, also expand the 1st support layer
// in case there is no raft layer to improve support adhesion. // in case there is no raft layer to improve support adhesion.
MyLayersPtr generate_raft_base( SupportGeneratorLayersPtr generate_raft_base(
const PrintObject &object, const PrintObject &object,
const MyLayersPtr &top_contacts, const SupportGeneratorLayersPtr &top_contacts,
const MyLayersPtr &interface_layers, const SupportGeneratorLayersPtr &interface_layers,
const MyLayersPtr &base_interface_layers, const SupportGeneratorLayersPtr &base_interface_layers,
const MyLayersPtr &base_layers, const SupportGeneratorLayersPtr &base_layers,
MyLayerStorage &layer_storage) const; SupportGeneratorLayerStorage &layer_storage) const;
// Turn some of the base layers into base interface layers. // Turn some of the base layers into base interface layers.
// For soluble interfaces with non-soluble bases, print maximum two first interface layers with the base // For soluble interfaces with non-soluble bases, print maximum two first interface layers with the base
// extruder to improve adhesion of the soluble filament to the base. // extruder to improve adhesion of the soluble filament to the base.
std::pair<MyLayersPtr, MyLayersPtr> generate_interface_layers( std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interface_layers(
const MyLayersPtr &bottom_contacts, const SupportGeneratorLayersPtr &bottom_contacts,
const MyLayersPtr &top_contacts, const SupportGeneratorLayersPtr &top_contacts,
MyLayersPtr &intermediate_layers, SupportGeneratorLayersPtr &intermediate_layers,
MyLayerStorage &layer_storage) const; SupportGeneratorLayerStorage &layer_storage) const;
// Trim support layers by an object to leave a defined gap between // Trim support layers by an object to leave a defined gap between
// the support volume and the object. // the support volume and the object.
void trim_support_layers_by_object( void trim_support_layers_by_object(
const PrintObject &object, const PrintObject &object,
MyLayersPtr &support_layers, SupportGeneratorLayersPtr &support_layers,
const coordf_t gap_extra_above, const coordf_t gap_extra_above,
const coordf_t gap_extra_below, const coordf_t gap_extra_below,
const coordf_t gap_xy) const; const coordf_t gap_xy) const;
@ -236,16 +251,6 @@ private:
void clip_with_shape(); void clip_with_shape();
*/ */
// Produce the actual G-code.
void generate_toolpaths(
SupportLayerPtrs &support_layers,
const MyLayersPtr &raft_layers,
const MyLayersPtr &bottom_contacts,
const MyLayersPtr &top_contacts,
const MyLayersPtr &intermediate_layers,
const MyLayersPtr &interface_layers,
const MyLayersPtr &base_interface_layers) const;
// Following objects are not owned by SupportMaterial class. // Following objects are not owned by SupportMaterial class.
const PrintObject *m_object; const PrintObject *m_object;
const PrintConfig *m_print_config; const PrintConfig *m_print_config;
@ -254,7 +259,7 @@ private:
// carrying information on a raft, 1st layer height, 1st object layer height, gap between the raft and object etc. // carrying information on a raft, 1st layer height, 1st object layer height, gap between the raft and object etc.
SlicingParameters m_slicing_params; SlicingParameters m_slicing_params;
// Various precomputed support parameters to be shared with external functions. // Various precomputed support parameters to be shared with external functions.
SupportParams m_support_params; SupportParameters m_support_params;
}; };
} // namespace Slic3r } // namespace Slic3r