diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp index c859f5eb1..b32eaea12 100644 --- a/xs/src/libslic3r/SupportMaterial.cpp +++ b/xs/src/libslic3r/SupportMaterial.cpp @@ -2,75 +2,6 @@ namespace Slic3r { -Polygon -SupportMaterial::create_circle(coordf_t radius) -{ - Points points; - coordf_t positions[] = {5 * PI / 3, - 4 * PI / 3, - PI, - 2 * PI / 3, - PI / 3, - 0}; - for (auto pos : positions) { - points.emplace_back(radius * cos(pos), (radius * sin(pos))); - } - - return Polygon(points); -} - -Polygons -SupportMaterial::p(SurfacesPtr &surfaces) -{ - Polygons ret; - for (auto surface : surfaces) { - ret.push_back(surface->expolygon.contour); - for (const auto &hole_polygon : surface->expolygon.holes) { - ret.push_back(hole_polygon); - } - } - return ret; -} - -void -SupportMaterial::append_polygons(Polygons &dst, Polygons &src) -{ - for (const auto polygon : src) { - dst.push_back(polygon); - } -} - -coordf_t -SupportMaterial::contact_distance(coordf_t layer_height, coordf_t nozzle_diameter) -{ - coordf_t extra = static_cast(object_config->support_material_contact_distance.value); - if (extra == 0) { - return layer_height; - } - else { - return nozzle_diameter + extra; - } -} - -vector -SupportMaterial::get_keys_sorted(map _map) -{ - vector ret; - for (auto el : _map) - ret.push_back(el.first); - sort(ret.begin(), ret.end()); - return ret; -} - -coordf_t -SupportMaterial::get_max_layer_height(PrintObject *object) -{ - coordf_t ret = -1; - for (auto layer : object->layers) - ret = max(ret, layer->height); - return ret; -} - void SupportMaterial::generate_toolpaths(PrintObject *object, map overhang, @@ -638,6 +569,93 @@ SupportMaterial::object_top(PrintObject *object, map *contac return top; } +void +SupportMaterial::generate_pillars_shape(const map &contact, + const vector &support_z, + map &shape) +{ + // This prevents supplying an empty point set to BoundingBox constructor. + if (contact.empty()) return; + + coord_t pillar_size = scale_(object_config->support_material_pillar_size.value); + coord_t pillar_spacing = scale_(object_config->support_material_pillar_spacing.value); + + Polygons grid; + { + auto pillar = Polygon({ + Point(0, 0), + Point(pillar_size, coord_t(0)), + Point(pillar_size, pillar_size), + Point(coord_t(0), pillar_size) + }); + + Polygons pillars; + BoundingBox bb; + { + Points bb_points; + for (auto contact_el : contact) { + append_to(bb_points, to_points(contact_el.second)); + } + bb = BoundingBox(bb_points); + } + + for (auto x = bb.min.x; x <= bb.max.x - pillar_size; x += pillar_spacing) { + for (auto y = bb.min.y; y <= bb.max.y - pillar_size; y += pillar_spacing) { + pillars.push_back(pillar); + pillar.translate(x, y); + } + } + + grid = union_(pillars); + } + + // Add pillars to every layer. + for (auto i = 0; i < support_z.size(); i++) { + shape[i] = grid; + } + + // Build capitals. + for (auto i = 0; i < support_z.size(); i++) { + coordf_t z = support_z[i]; + + auto capitals = intersection( + grid, + contact.at(z) + ); + + // Work on one pillar at time (if any) to prevent the capitals from being merged + // but store the contact area supported by the capital because we need to make + // sure nothing is left. + Polygons contact_supported_by_capitals; + for (auto capital : capitals) { + // Enlarge capital tops. + auto capital_polygons = offset(Polygons({capital}), +(pillar_spacing - pillar_size) / 2); + append_to(contact_supported_by_capitals, capital_polygons); + + for (int j = i - 1; j >= 0; j--) { + auto jz = support_z[j]; + capital_polygons = offset(Polygons{capital}, -interface_flow->scaled_width() / 2); + if (capitals.empty()) break; + append_to(shape[i], capital_polygons); + } + } + + // Work on one pillar at time (if any) to prevent the capitals from being merged + // but store the contact area supported by the capital because we need to make + // sure nothing is left. + auto contact_not_supported_by_capitals = diff( + contact.at(z), + contact_supported_by_capitals + ); + + if (!contact_not_supported_by_capitals.empty()) { + for (int j = i - 1; j >= 0; j--) { + append_to(shape[j], contact_not_supported_by_capitals); + } + } + } +} + map SupportMaterial::generate_base_layers(vector support_z, map contact, @@ -794,6 +812,18 @@ SupportMaterial::generate_bottom_interface_layers(const vector &suppor } } +coordf_t +SupportMaterial::contact_distance(coordf_t layer_height, coordf_t nozzle_diameter) +{ + coordf_t extra = static_cast(object_config->support_material_contact_distance.value); + if (extra == 0) { + return layer_height; + } + else { + return nozzle_diameter + extra; + } +} + vector SupportMaterial::overlapping_layers(int layer_idx, const vector &support_z) { @@ -868,4 +898,61 @@ SupportMaterial::clip_with_object(map &support, vector */ } +Polygons +SupportMaterial::p(SurfacesPtr &surfaces) +{ + Polygons ret; + for (auto surface : surfaces) { + ret.push_back(surface->expolygon.contour); + for (const auto &hole_polygon : surface->expolygon.holes) { + ret.push_back(hole_polygon); + } + } + return ret; +} + +void +SupportMaterial::append_polygons(Polygons &dst, Polygons &src) +{ + for (const auto polygon : src) { + dst.push_back(polygon); + } +} + +vector +SupportMaterial::get_keys_sorted(map _map) +{ + vector ret; + for (auto el : _map) + ret.push_back(el.first); + sort(ret.begin(), ret.end()); + return ret; +} + +coordf_t +SupportMaterial::get_max_layer_height(PrintObject *object) +{ + coordf_t ret = -1; + for (auto layer : object->layers) + ret = max(ret, layer->height); + return ret; +} + +Polygon +SupportMaterial::create_circle(coordf_t radius) +{ + Points points; + coordf_t positions[] = {5 * PI / 3, + 4 * PI / 3, + PI, + 2 * PI / 3, + PI / 3, + 0}; + for (auto pos : positions) { + points.emplace_back(radius * cos(pos), (radius * sin(pos))); + } + + return Polygon(points); +} + } diff --git a/xs/src/libslic3r/SupportMaterial.hpp b/xs/src/libslic3r/SupportMaterial.hpp index 9d855bedd..2a7c52ed6 100644 --- a/xs/src/libslic3r/SupportMaterial.hpp +++ b/xs/src/libslic3r/SupportMaterial.hpp @@ -50,145 +50,6 @@ public: object(nullptr) {} - void generate_pillars_shape(const map &contact, - const vector &support_z, - map &shape) - { - // This prevents supplying an empty point set to BoundingBox constructor. - if (contact.empty()) return; - - coord_t pillar_size = scale_(object_config->support_material_pillar_size.value); - coord_t pillar_spacing = scale_(object_config->support_material_pillar_spacing.value); - - Polygons grid; - { - auto pillar = Polygon({ - Point(0, 0), - Point(pillar_size, coord_t(0)), - Point(pillar_size, pillar_size), - Point(coord_t(0), pillar_size) - }); - - Polygons pillars; - BoundingBox bb; - { - Points bb_points; - for (auto contact_el : contact) { - append_to(bb_points, to_points(contact_el.second)); - } - bb = BoundingBox(bb_points); - } - - for (auto x = bb.min.x; x <= bb.max.x - pillar_size; x += pillar_spacing) { - for (auto y = bb.min.y; y <= bb.max.y - pillar_size; y += pillar_spacing) { - pillars.push_back(pillar); - pillar.translate(x, y); - } - } - - grid = union_(pillars); - } - - // Add pillars to every layer. - for (auto i = 0; i < support_z.size(); i++) { - shape[i] = grid; - } - - // Build capitals. - for (auto i = 0; i < support_z.size(); i++) { - coordf_t z = support_z[i]; - - auto capitals = intersection( - grid, - contact.at(z) - ); - - // Work on one pillar at time (if any) to prevent the capitals from being merged - // but store the contact area supported by the capital because we need to make - // sure nothing is left. - Polygons contact_supported_by_capitals; - for (auto capital : capitals) { - // Enlarge capital tops. - auto capital_polygons = offset(Polygons({capital}), +(pillar_spacing - pillar_size) / 2); - append_to(contact_supported_by_capitals, capital_polygons); - - for (int j = i - 1; j >= 0; j--) { - auto jz = support_z[j]; - capital_polygons = offset(Polygons{capital}, -interface_flow->scaled_width() / 2); - if (capitals.empty()) break; - append_to(shape[i], capital_polygons); - } - } - - // Work on one pillar at time (if any) to prevent the capitals from being merged - // but store the contact area supported by the capital because we need to make - // sure nothing is left. - auto contact_not_supported_by_capitals = diff( - contact.at(z), - contact_supported_by_capitals - ); - - if (!contact_not_supported_by_capitals.empty()) { - for (int j = i - 1; j >= 0; j--) { - append_to(shape[j], contact_not_supported_by_capitals); - } - } - } - } - - void generate_bottom_interface_layers(const vector &support_z, - map &base, - map &top, - map &interface); - - map generate_base_layers(vector support_z, - map contact, - map interface, - map top); - - map generate_interface_layers(vector support_z, - map contact, - map top); - - pair, map> contact_area(PrintObject *object); - - void generate(PrintObject *object); - - void generate_toolpaths(PrintObject *object, - map overhang, - map contact, - map interface, - map base); - - // Is this expolygons or polygons? - map object_top(PrintObject *object, map *contact); - - // This method removes object silhouette from support material - // (it's used with interface and base only). It removes a bit more, - // leaving a thin gap between object and support in the XY plane. - void clip_with_object(map &support, vector support_z, PrintObject &object); - - void clip_with_shape(map &support, map &shape); - - /// This method returns the indices of the layers overlapping with the given one. - vector overlapping_layers(int layer_idx, const vector &support_z); - - vector support_layers_z(vector contact_z, - vector top_z, - coordf_t max_object_layer_height); - - coordf_t contact_distance(coordf_t layer_height, coordf_t nozzle_diameter); - - Polygons p(SurfacesPtr &surfaces); - - Polygon create_circle(coordf_t radius); - - void append_polygons(Polygons &dst, Polygons &src); - - vector get_keys_sorted(map _map); - - coordf_t get_max_layer_height(PrintObject *object); - void process_layer(int layer_id) { SupportLayer *layer = this->object->support_layers[layer_id]; @@ -212,7 +73,64 @@ public: } + void generate_toolpaths(PrintObject *object, + map overhang, + map contact, + map interface, + map base); + + void generate(PrintObject *object); + + vector support_layers_z(vector contact_z, + vector top_z, + coordf_t max_object_layer_height); + + pair, map> contact_area(PrintObject *object); + + // Is this expolygons or polygons? + map object_top(PrintObject *object, map *contact); + + void generate_pillars_shape(const map &contact, + const vector &support_z, + map &shape); + + map generate_base_layers(vector support_z, + map contact, + map interface, + map top); + + map generate_interface_layers(vector support_z, + map contact, + map top); + + void generate_bottom_interface_layers(const vector &support_z, + map &base, + map &top, + map &interface); + + coordf_t contact_distance(coordf_t layer_height, coordf_t nozzle_diameter); + + /// This method returns the indices of the layers overlapping with the given one. + vector overlapping_layers(int layer_idx, const vector &support_z); + + void clip_with_shape(map &support, map &shape); + + // This method removes object silhouette from support material + // (it's used with interface and base only). It removes a bit more, + // leaving a thin gap between object and support in the XY plane. + void clip_with_object(map &support, vector support_z, PrintObject &object); + private: + coordf_t get_max_layer_height(PrintObject *object); + + void append_polygons(Polygons &dst, Polygons &src); + + Polygons p(SurfacesPtr &surfaces); + + vector get_keys_sorted(map _map); + + Polygon create_circle(coordf_t radius); + // Used during generate_toolpaths function. PrintObject *object; map overhang;