1 #ifndef slic3r_SupportMaterial_hpp_ 2 #define slic3r_SupportMaterial_hpp_ 3 4 #include "Flow.hpp" 5 #include "PrintConfig.hpp" 6 #include "Slicing.hpp" 7 8 namespace Slic3r { 9 10 class PrintObject; 11 class PrintConfig; 12 class PrintObjectConfig; 13 14 // how much we extend support around the actual contact area 15 //FIXME this should be dependent on the nozzle diameter! 16 #define SUPPORT_MATERIAL_MARGIN 1.5 17 18 // This class manages raft and supports for a single PrintObject. 19 // Instantiated by Slic3r::Print::Object->_support_material() 20 // This class is instantiated before the slicing starts as Object.pm will query 21 // the parameters of the raft to determine the 1st layer height and thickness. 22 class PrintObjectSupportMaterial 23 { 24 public: 25 // Support layer type to be used by MyLayer. This type carries a much more detailed information 26 // about the support layer type than the final support layers stored in a PrintObject. 27 enum SupporLayerType { 28 sltUnknown = 0, 29 // Ratft base layer, to be printed with the support material. 30 sltRaftBase, 31 // Raft interface layer, to be printed with the support interface material. 32 sltRaftInterface, 33 // Bottom contact layer placed over a top surface of an object. To be printed with a support interface material. 34 sltBottomContact, 35 // Dense interface layer, to be printed with the support interface material. 36 // This layer is separated from an object by an sltBottomContact layer. 37 sltBottomInterface, 38 // Sparse base support layer, to be printed with a support material. 39 sltBase, 40 // Dense interface layer, to be printed with the support interface material. 41 // This layer is separated from an object with sltTopContact layer. 42 sltTopInterface, 43 // Top contact layer directly supporting an overhang. To be printed with a support interface material. 44 sltTopContact, 45 // Some undecided type yet. It will turn into sltBase first, then it may turn into sltBottomInterface or sltTopInterface. 46 sltIntermediate, 47 }; 48 49 // A support layer type used internally by the SupportMaterial class. This class carries a much more detailed 50 // information about the support layer than the layers stored in the PrintObject, mainly 51 // the MyLayer is aware of the bridging flow and the interface gaps between the object and the support. 52 class MyLayer 53 { 54 public: MyLayer()55 MyLayer() : 56 layer_type(sltUnknown), 57 print_z(0.), 58 bottom_z(0.), 59 height(0.), 60 idx_object_layer_above(size_t(-1)), 61 idx_object_layer_below(size_t(-1)), 62 bridging(false), 63 contact_polygons(nullptr), 64 overhang_polygons(nullptr) 65 {} 66 ~MyLayer()67 ~MyLayer() 68 { 69 delete contact_polygons; 70 contact_polygons = nullptr; 71 delete overhang_polygons; 72 overhang_polygons = nullptr; 73 } 74 reset()75 void reset() { 76 layer_type = sltUnknown; 77 print_z = 0.; 78 bottom_z = 0.; 79 height = 0.; 80 idx_object_layer_above = size_t(-1); 81 idx_object_layer_below = size_t(-1); 82 bridging = false; 83 polygons.clear(); 84 delete contact_polygons; 85 contact_polygons = nullptr; 86 delete overhang_polygons; 87 overhang_polygons = nullptr; 88 } 89 operator ==(const MyLayer & layer2) const90 bool operator==(const MyLayer &layer2) const { 91 return print_z == layer2.print_z && height == layer2.height && bridging == layer2.bridging; 92 } 93 94 // Order the layers by lexicographically by an increasing print_z and a decreasing layer height. operator <(const MyLayer & layer2) const95 bool operator<(const MyLayer &layer2) const { 96 if (print_z < layer2.print_z) { 97 return true; 98 } else if (print_z == layer2.print_z) { 99 if (height > layer2.height) 100 return true; 101 else if (height == layer2.height) { 102 // Bridging layers first. 103 return bridging && ! layer2.bridging; 104 } else 105 return false; 106 } else 107 return false; 108 } 109 110 // For the bridging flow, bottom_print_z will be above bottom_z to account for the vertical separation. 111 // For the non-bridging flow, bottom_print_z will be equal to bottom_z. bottom_print_z() const112 coordf_t bottom_print_z() const { return print_z - height; } 113 114 // To sort the extremes of top / bottom interface layers. extreme_z() const115 coordf_t extreme_z() const { return (this->layer_type == sltTopContact) ? this->bottom_z : this->print_z; } 116 117 SupporLayerType layer_type; 118 // Z used for printing, in unscaled coordinates. 119 coordf_t print_z; 120 // Bottom Z of this layer. For soluble layers, bottom_z + height = print_z, 121 // otherwise bottom_z + gap + height = print_z. 122 coordf_t bottom_z; 123 // Layer height in unscaled coordinates. 124 coordf_t height; 125 // Index of a PrintObject layer_id supported by this layer. This will be set for top contact layers. 126 // If this is not a contact layer, it will be set to size_t(-1). 127 size_t idx_object_layer_above; 128 // Index of a PrintObject layer_id, which supports this layer. This will be set for bottom contact layers. 129 // If this is not a contact layer, it will be set to size_t(-1). 130 size_t idx_object_layer_below; 131 // Use a bridging flow when printing this support layer. 132 bool bridging; 133 134 // Polygons to be filled by the support pattern. 135 Polygons polygons; 136 // Currently for the contact layers only. 137 // MyLayer owns the contact_polygons and overhang_polygons, they are freed by the destructor. 138 Polygons *contact_polygons; 139 Polygons *overhang_polygons; 140 }; 141 142 // Layers are allocated and owned by a deque. Once a layer is allocated, it is maintained 143 // up to the end of a generate() method. The layer storage may be replaced by an allocator class in the future, 144 // which would allocate layers by multiple chunks. 145 typedef std::deque<MyLayer> MyLayerStorage; 146 typedef std::vector<MyLayer*> MyLayersPtr; 147 148 public: 149 PrintObjectSupportMaterial(const PrintObject *object, const SlicingParameters &slicing_params); 150 151 // Is raft enabled? has_raft() const152 bool has_raft() const { return m_slicing_params.has_raft(); } 153 // Has any support? has_support() const154 bool has_support() const { return m_object_config->support_material.value; } build_plate_only() const155 bool build_plate_only() const { return this->has_support() && m_object_config->support_material_buildplate_only.value; } 156 synchronize_layers() const157 bool synchronize_layers() const { return m_slicing_params.soluble_interface && m_object_config->support_material_synchronize_layers.value; } has_contact_loops() const158 bool has_contact_loops() const { return m_object_config->support_material_interface_contact_loops.value; } 159 160 // Generate support material for the object. 161 // New support layers will be added to the object, 162 // with extrusion paths and islands filled in for each support layer. 163 void generate(PrintObject &object); 164 165 private: 166 // Generate top contact layers supporting overhangs. 167 // For a soluble interface material synchronize the layer heights with the object, otherwise leave the layer height undefined. 168 // If supports over bed surface only are requested, don't generate contact layers over an object. 169 MyLayersPtr top_contact_layers(const PrintObject &object, MyLayerStorage &layer_storage) const; 170 171 // Generate bottom contact layers supporting the top contact layers. 172 // For a soluble interface material synchronize the layer heights with the object, 173 // otherwise set the layer height to a bridging flow of a support interface nozzle. 174 MyLayersPtr bottom_contact_layers_and_layer_support_areas( 175 const PrintObject &object, const MyLayersPtr &top_contacts, MyLayerStorage &layer_storage, 176 std::vector<Polygons> &layer_support_areas) const; 177 178 // 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. 179 void trim_top_contacts_by_bottom_contacts(const PrintObject &object, const MyLayersPtr &bottom_contacts, MyLayersPtr &top_contacts) const; 180 181 // Generate raft layers and the intermediate support layers between the bottom contact and top contact surfaces. 182 MyLayersPtr raft_and_intermediate_support_layers( 183 const PrintObject &object, 184 const MyLayersPtr &bottom_contacts, 185 const MyLayersPtr &top_contacts, 186 MyLayerStorage &layer_storage) const; 187 188 // Fill in the base layers with polygons. 189 void generate_base_layers( 190 const PrintObject &object, 191 const MyLayersPtr &bottom_contacts, 192 const MyLayersPtr &top_contacts, 193 MyLayersPtr &intermediate_layers, 194 const std::vector<Polygons> &layer_support_areas) const; 195 196 // Generate raft layers, also expand the 1st support layer 197 // in case there is no raft layer to improve support adhesion. 198 MyLayersPtr generate_raft_base( 199 const MyLayersPtr &top_contacts, 200 const MyLayersPtr &interface_layers, 201 const MyLayersPtr &base_layers, 202 MyLayerStorage &layer_storage) const; 203 204 // Turn some of the base layers into interface layers. 205 MyLayersPtr generate_interface_layers( 206 const MyLayersPtr &bottom_contacts, 207 const MyLayersPtr &top_contacts, 208 MyLayersPtr &intermediate_layers, 209 MyLayerStorage &layer_storage) const; 210 211 // Trim support layers by an object to leave a defined gap between 212 // the support volume and the object. 213 void trim_support_layers_by_object( 214 const PrintObject &object, 215 MyLayersPtr &support_layers, 216 const coordf_t gap_extra_above, 217 const coordf_t gap_extra_below, 218 const coordf_t gap_xy) const; 219 220 /* 221 void generate_pillars_shape(); 222 void clip_with_shape(); 223 */ 224 225 // Produce the actual G-code. 226 void generate_toolpaths( 227 const PrintObject &object, 228 const MyLayersPtr &raft_layers, 229 const MyLayersPtr &bottom_contacts, 230 const MyLayersPtr &top_contacts, 231 const MyLayersPtr &intermediate_layers, 232 const MyLayersPtr &interface_layers) const; 233 234 // Following objects are not owned by SupportMaterial class. 235 const PrintObject *m_object; 236 const PrintConfig *m_print_config; 237 const PrintObjectConfig *m_object_config; 238 // Pre-calculated parameters shared between the object slicer and the support generator, 239 // carrying information on a raft, 1st layer height, 1st object layer height, gap between the raft and object etc. 240 SlicingParameters m_slicing_params; 241 242 Flow m_first_layer_flow; 243 Flow m_support_material_flow; 244 Flow m_support_material_interface_flow; 245 // Is merging of regions allowed? Could the interface & base support regions be printed with the same extruder? 246 bool m_can_merge_support_regions; 247 248 coordf_t m_support_layer_height_min; 249 coordf_t m_support_layer_height_max; 250 251 coordf_t m_gap_xy; 252 }; 253 254 } // namespace Slic3r 255 256 #endif /* slic3r_SupportMaterial_hpp_ */ 257