diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index a2e037397..1e1efe877 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -165,17 +165,6 @@ static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_lev } } - // BBS - if (!object->tree_support_layers().empty()) { - for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) { - Polygons contour_offset = offset(ex_poly.contour, brim_object_gap, ClipperLib::jtSquare); - for (Polygon& poly : contour_offset) - poly.douglas_peucker(scaled_resolution); - - polygons_append(islands_object, std::move(contour_offset)); - } - } - for (const PrintInstance &instance : object->instances()) append_and_translate(islands, islands_object, instance); } @@ -248,19 +237,6 @@ static ExPolygons top_level_outer_brim_area(const Print &print } } - // BBS - if (!object->tree_support_layers().empty()) { - for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) { - if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) && is_top_outer_brim) - append(brim_area_object, diff_ex(offset(ex_poly.contour, brim_width + brim_object_gap, jtRound, scaled_resolution), offset(ex_poly.contour, brim_object_gap))); - - if (brim_type != BrimType::btNoBrim) - append(no_brim_area_object, offset_ex(ExPolygon(ex_poly.contour), brim_object_gap)); - - no_brim_area_object.emplace_back(ex_poly.contour); - } - } - for (const PrintInstance &instance : object->instances()) { append_and_translate(brim_area, brim_area_object, instance); append_and_translate(no_brim_area, no_brim_area_object, instance); @@ -360,21 +336,6 @@ static ExPolygons top_level_outer_brim_area(const Print& print, const ConstPrint } } - // BBS - if (!object->tree_support_layers().empty()) { - for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) { - if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) && is_top_outer_brim) - append(brim_area_support, diff_ex(offset(ex_poly.contour, brim_width, jtRound, SCALED_RESOLUTION), offset(ex_poly.contour, 0))); - - if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim) - append(no_brim_area_support, offset_ex(ex_poly.holes, -no_brim_offset)); - - if (brim_type != BrimType::btNoBrim) - append(no_brim_area_support, offset_ex(ex_poly.contour, 0)); - - no_brim_area_support.emplace_back(ex_poly.contour); - } - } brimToWrite.at(object->id()).sup = false; for (const PrintInstance& instance : object->instances()) { if (!brim_area_support.empty()) @@ -543,26 +504,6 @@ static ExPolygons inner_brim_area(const Print& print, const ConstPrintObjectPtrs no_brim_area_support.emplace_back(support_contour); } } - - // BBS - if (!object->tree_support_layers().empty()) { - for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) { - if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) { - if (!top_outer_brim) - append(brim_area_support, diff_ex(offset_ex(ex_poly.contour, brim_width + brim_offset, jtRound, SCALED_RESOLUTION), offset_ex(ex_poly.contour, brim_offset))); - } - if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btOuterAndInner) - append(brim_area_support, diff_ex(offset_ex(ex_poly.holes, -brim_offset), offset_ex(ex_poly.holes, -brim_width - brim_offset))); - if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim) - append(no_brim_area_support, diff_ex(offset(ex_poly.contour, no_brim_offset), ex_poly.holes)); - if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim) - append(no_brim_area_support, offset_ex(ex_poly.holes, -no_brim_offset)); - append(holes_support, ex_poly.holes); - if (brim_type != BrimType::btNoBrim) - append(no_brim_area_support, offset_ex(ex_poly.contour, 0)); - no_brim_area_support.emplace_back(ex_poly.contour); - } - } } brimToWrite.at(object->id()).sup = false; for (const PrintInstance& instance : object->instances()) { @@ -988,7 +929,7 @@ static ExPolygons outer_inner_brim_area(const Print& print, support_material_extruder = printExtruders.front() + 1; } if (support_material_extruder == extruderNo && brimToWrite.at(object->id()).sup) { - if (!object->support_layers().empty()) { + if (!object->support_layers().empty() && object->support_layers().front()->support_type==stInnerNormal) { for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) { // Brim will not be generated for supports /* @@ -1002,8 +943,8 @@ static ExPolygons outer_inner_brim_area(const Print& print, } } // BBS - if (!object->tree_support_layers().empty()) { - for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) { + if (!object->support_layers().empty() && object->support_layers().front()->support_type == stInnerTree) { + for (const ExPolygon &ex_poly : object->support_layers().front()->lslices) { // BBS: additional brim width will be added if adhension area is too small without brim float brim_width_mod = ex_poly.area() / ex_poly.contour.length() < scaled_half_min_adh_length && brim_width < scaled_flow_width ? brim_width + scaled_additional_brim_width : brim_width; @@ -1222,13 +1163,6 @@ static void make_inner_island_brim(const Print& print, const ConstPrintObjectPtr } } - if (!object->tree_support_layers().empty()) { - for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) { - Polygon counter = ex_poly.contour; - save_polygon_if_is_inner_island(holes_area, counter, hole_island_pair); - } - } - //BBS: 3 generate loops, only save part of loop which inside hole const float brim_offset = scale_(object->config().brim_object_gap.value); const float brim_width = scale_(object->config().brim_width.value); @@ -1371,13 +1305,6 @@ static void make_inner_island_brim(const Print& print, const ConstPrintObjectPtr } } - if (!object->tree_support_layers().empty()) { - for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) { - Polygon counter = ex_poly.contour; - save_polygon_if_is_inner_island(holes_area, counter, hole_island_pair_supports); - } - } - //BBS: 3 generate loops, only save part of loop which inside hole const float brim_offset = scale_(object->config().brim_object_gap.value); const float brim_width = floor(scale_(object->config().brim_width.value) / 2 / flow.scaled_spacing()) * 2 * flow.scaled_spacing(); @@ -1665,13 +1592,6 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_ ex_poly_translated.translate(instance.shift.x(), instance.shift.y()); bbx.merge(get_extents(ex_poly_translated)); } - if (!object->tree_support_layers().empty()) - for (const Polygon& ex_poly : object->tree_support_layers().front()->support_fills.polygons_covered_by_spacing()) - for (const PrintInstance& instance : object->instances()) { - auto ex_poly_translated = ex_poly; - ex_poly_translated.translate(instance.shift.x(), instance.shift.y()); - bbx.merge(get_extents(ex_poly_translated)); - } if (supportBrimAreaMap.find(printObjID) != supportBrimAreaMap.end()) { for (const ExPolygon& ex_poly : supportBrimAreaMap.at(printObjID)) bbx.merge(get_extents(ex_poly.contour)); diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index b90198dfd..47462c0a9 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -608,7 +608,7 @@ bool GCode::gcode_label_objects = false; std::vector GCode::collect_layers_to_print(const PrintObject& object) { std::vector layers_to_print; - layers_to_print.reserve(object.layers().size() + object.support_layers().size() + object.tree_support_layers().size()); + layers_to_print.reserve(object.layers().size() + object.support_layers().size()); /* // Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um. @@ -631,9 +631,8 @@ std::vector GCode::collect_layers_to_print(const PrintObjec // Pair the object layers with the support layers by z. size_t idx_object_layer = 0; size_t idx_support_layer = 0; - size_t idx_tree_support_layer = 0; const LayerToPrint* last_extrusion_layer = nullptr; - while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size() || idx_tree_support_layer < object.tree_support_layers().size()) { + while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) { LayerToPrint layer_to_print; double print_z_min = std::numeric_limits::max(); if (idx_object_layer < object.layers().size()) { @@ -646,11 +645,6 @@ std::vector GCode::collect_layers_to_print(const PrintObjec print_z_min = std::min(print_z_min, layer_to_print.support_layer->print_z); } - if (idx_tree_support_layer < object.tree_support_layers().size()) { - layer_to_print.tree_support_layer = object.tree_support_layers()[idx_tree_support_layer++]; - print_z_min = std::min(print_z_min, layer_to_print.tree_support_layer->print_z); - } - if (layer_to_print.object_layer && layer_to_print.object_layer->print_z > print_z_min + EPSILON) { layer_to_print.object_layer = nullptr; --idx_object_layer; @@ -661,17 +655,11 @@ std::vector GCode::collect_layers_to_print(const PrintObjec --idx_support_layer; } - if (layer_to_print.tree_support_layer && layer_to_print.tree_support_layer->print_z > print_z_min + EPSILON) { - layer_to_print.tree_support_layer = nullptr; - --idx_tree_support_layer; - } - layer_to_print.original_object = &object; layers_to_print.push_back(layer_to_print); bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) - || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions() - || (layer_to_print.tree_support_layer && layer_to_print.tree_support_layer->has_extrusions())); + || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions()); // Check that there are extrusions on the very first layer. The case with empty // first layer may result in skirt/brim in the air and maybe other issues. @@ -683,13 +671,12 @@ std::vector GCode::collect_layers_to_print(const PrintObjec // In case there are extrusions on this layer, check there is a layer to lay it on. if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) // Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions. - || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */) - || (layer_to_print.tree_support_layer)) { + || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) { double top_cd = object.config().support_top_z_distance; //double bottom_cd = object.config().support_bottom_z_distance == 0. ? top_cd : object.config().support_bottom_z_distance; double bottom_cd = top_cd; - double extra_gap = ((layer_to_print.support_layer || layer_to_print.tree_support_layer) ? bottom_cd : top_cd); + double extra_gap = (layer_to_print.support_layer ? bottom_cd : top_cd); double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) + layer_to_print.layer()->height @@ -1316,8 +1303,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato zs.reserve(zs.size() + object->layers().size() + object->support_layers().size()); for (auto layer : object->layers()) zs.push_back(layer->print_z); - for (auto layer : object->support_layers()) - zs.push_back(layer->print_z); + for (auto layer : object->support_layers()) zs.push_back(layer->print_z); } std::sort(zs.begin(), zs.end()); m_layer_count = (unsigned int)(std::unique(zs.begin(), zs.end()) - zs.begin()); @@ -2371,7 +2357,6 @@ GCode::LayerResult GCode::process_layer( // First object, support and raft layer, if available. const Layer *object_layer = nullptr; const SupportLayer *support_layer = nullptr; - const TreeSupportLayer* tree_support_layer = nullptr; const SupportLayer *raft_layer = nullptr; for (const LayerToPrint &l : layers) { if (l.object_layer && ! object_layer) @@ -2382,16 +2367,6 @@ GCode::LayerResult GCode::process_layer( if (! raft_layer && support_layer->id() < support_layer->object()->slicing_parameters().raft_layers()) raft_layer = support_layer; } - - if (l.tree_support_layer) { - if (!tree_support_layer) - tree_support_layer = l.tree_support_layer; - // BBS: to be checked. -#if 0 - if (!raft_layer && tree_support_layer->id() < tree_support_layer->object()->slicing_parameters().raft_layers()) - raft_layer = tree_support_layer; -#endif - } } const Layer* layer_ptr = nullptr; @@ -2399,8 +2374,6 @@ GCode::LayerResult GCode::process_layer( layer_ptr = object_layer; else if (support_layer != nullptr) layer_ptr = support_layer; - else - layer_ptr = tree_support_layer; const Layer& layer = *layer_ptr; GCode::LayerResult result { {}, layer.id(), false, last_layer }; if (layer_tools.extruders.empty()) @@ -2421,7 +2394,7 @@ GCode::LayerResult GCode::process_layer( // Check whether it is possible to apply the spiral vase logic for this layer. // Just a reminder: A spiral vase mode is allowed for a single object, single material print only. m_enable_loop_clipping = true; - if (m_spiral_vase && layers.size() == 1 && support_layer == nullptr && tree_support_layer == nullptr) { + if (m_spiral_vase && layers.size() == 1 && support_layer == nullptr) { bool enable = (layer.id() > 0 || !print.has_brim()) && (layer.id() >= (size_t)print.config().skirt_height.value && ! print.has_infinite_skirt()); if (enable) { for (const LayerRegion *layer_region : layer.regions()) @@ -2628,90 +2601,6 @@ GCode::LayerResult GCode::process_layer( } } - // BBS - if (layer_to_print.tree_support_layer != nullptr) { - const TreeSupportLayer& tree_support_layer = *layer_to_print.tree_support_layer; - const PrintObject& object = *layer_to_print.original_object; - if (!tree_support_layer.support_fills.entities.empty()) { - ExtrusionRole role = tree_support_layer.support_fills.role(); - bool has_support = role == erMixed || role == erSupportMaterial || role == erSupportTransition; - bool has_interface = role == erMixed || role == erSupportMaterialInterface; - // Extruder ID of the support base. -1 if "don't care". - unsigned int support_extruder = object.config().support_filament.value - 1; - // Shall the support be printed with the active extruder, preferably with non-soluble, to avoid tool changes? - bool support_dontcare = object.config().support_filament.value == 0; - // Extruder ID of the support interface. -1 if "don't care". - unsigned int interface_extruder = object.config().support_interface_filament.value - 1; - // Shall the support interface be printed with the active extruder, preferably with non-soluble, to avoid tool changes? - bool interface_dontcare = object.config().support_interface_filament.value == 0; - - // BBS: apply wiping overridden extruders - WipingExtrusions& wiping_extrusions = const_cast(layer_tools).wiping_extrusions(); - if (support_dontcare) { - int extruder_override = wiping_extrusions.get_support_extruder_overrides(&object); - if (extruder_override >= 0) { - support_extruder = extruder_override; - support_dontcare = false; - } - } - - if (interface_dontcare) { - int extruder_override = wiping_extrusions.get_support_interface_extruder_overrides(&object); - if (extruder_override >= 0) { - interface_extruder = extruder_override; - interface_dontcare = false; - } - } - - // BBS: try to print support base with a filament other than interface filament - if (support_dontcare && !interface_dontcare) { - unsigned int dontcare_extruder = first_extruder_id; - for (unsigned int extruder_id : layer_tools.extruders) { - if (print.config().filament_soluble.get_at(extruder_id)) continue; - - if (extruder_id == interface_extruder) continue; - - dontcare_extruder = extruder_id; - break; - } - - if (support_dontcare) support_extruder = dontcare_extruder; - } - else if (support_dontcare || interface_dontcare) { - // Some support will be printed with "don't care" material, preferably non-soluble. - // Is the current extruder assigned a soluble filament? - unsigned int dontcare_extruder = first_extruder_id; - if (print.config().filament_soluble.get_at(dontcare_extruder)) { - // The last extruder printed on the previous layer extrudes soluble filament. - // Try to find a non-soluble extruder on the same layer. - for (unsigned int extruder_id : layer_tools.extruders) - if (!print.config().filament_soluble.get_at(extruder_id)) { - dontcare_extruder = extruder_id; - break; - } - } - - if (support_dontcare) - support_extruder = dontcare_extruder; - if (interface_dontcare) - interface_extruder = dontcare_extruder; - } - // Both the support and the support interface are printed with the same extruder, therefore - // the interface may be interleaved with the support base. - bool single_extruder = !has_support || support_extruder == interface_extruder; - - // Assign an extruder to the base. - ObjectByExtruder& obj = object_by_extruder(by_extruder, has_support ? support_extruder : interface_extruder, &layer_to_print - layers.data(), layers.size()); - obj.support = &tree_support_layer.support_fills; - obj.support_extrusion_role = single_extruder ? erMixed : erSupportMaterial; - if (!single_extruder && has_interface) { - ObjectByExtruder& obj_interface = object_by_extruder(by_extruder, interface_extruder, &layer_to_print - layers.data(), layers.size()); - obj_interface.support = &tree_support_layer.support_fills; - obj_interface.support_extrusion_role = erSupportMaterialInterface; - } - } - } - if (layer_to_print.object_layer != nullptr) { const Layer &layer = *layer_to_print.object_layer; // We now define a strategy for building perimeters and fills. The separation @@ -2930,12 +2819,7 @@ GCode::LayerResult GCode::process_layer( m_last_obj_copy = this_object_copy; this->set_origin(unscale(offset)); if (instance_to_print.object_by_extruder.support != nullptr) { - if (layers[instance_to_print.layer_id].support_layer) { - m_layer = layers[instance_to_print.layer_id].support_layer; - } - else { - m_layer = layers[instance_to_print.layer_id].tree_support_layer; - } + m_layer = layers[instance_to_print.layer_id].support_layer; m_object_layer_over_raft = false; //BBS: print supports' brims first @@ -3854,10 +3738,9 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role) return false; //reduce the retractions in lightning infills for tree support - const TreeSupportLayer* ts_layer = dynamic_cast(m_layer); - if (ts_layer != NULL) - for (auto& area : ts_layer->base_areas) - if(area.contains(travel)) + if (support_layer != NULL && support_layer->support_type==stInnerTree) + for (auto &area : support_layer->base_areas) + if (area.contains(travel)) return false; } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index ccf254c57..5289a6656 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -201,10 +201,9 @@ public: // public, so that it could be accessed by free helper functions from GCode.cpp struct LayerToPrint { - LayerToPrint() : object_layer(nullptr), support_layer(nullptr), tree_support_layer(nullptr), original_object(nullptr) {} + LayerToPrint() : object_layer(nullptr), support_layer(nullptr), original_object(nullptr) {} const Layer* object_layer; const SupportLayer* support_layer; - const TreeSupportLayer* tree_support_layer; const PrintObject* original_object; //BBS: used for shared object logic const Layer* layer() const { @@ -214,9 +213,6 @@ public: if (support_layer != nullptr) return support_layer; - if (tree_support_layer != nullptr) - return tree_support_layer; - return nullptr; } @@ -238,10 +234,6 @@ public: count++; } - if (tree_support_layer != nullptr) { - sum_z += tree_support_layer->print_z; - count++; - } return sum_z / count; } }; diff --git a/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp b/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp index ebba1dda2..aca9fdf6e 100644 --- a/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp +++ b/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp @@ -1135,8 +1135,7 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point & const ExPolygons &lslices = gcodegen.layer()->lslices; const std::vector &lslices_bboxes = gcodegen.layer()->lslices_bboxes; - bool is_support_layer = (dynamic_cast(gcodegen.layer()) != nullptr) || - (dynamic_cast(gcodegen.layer()) != nullptr); + bool is_support_layer = (dynamic_cast(gcodegen.layer()) != nullptr); if (!use_external && (is_support_layer || (!lslices.empty() && !any_expolygon_contains(lslices, lslices_bboxes, m_grid_lslice, travel)))) { // Initialize m_internal only when it is necessary. if (m_internal.boundaries.empty()) diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index f600e172e..63bc74326 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -175,10 +175,6 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool for (auto layer : object->support_layers()) zs.emplace_back(layer->print_z); - // BBS - for (auto layer : object->tree_support_layers()) - zs.emplace_back(layer->print_z); - // Find first object layer that is not empty and save its print_z for (const Layer* layer : object->layers()) if (layer->has_extrusions()) { @@ -348,24 +344,6 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto } } - // BBS - for (auto tree_support_layer : object.tree_support_layers()) { - LayerTools &layer_tools = this->tools_for_layer(tree_support_layer->print_z); - ExtrusionRole role = tree_support_layer->support_fills.role(); - bool has_support = role == erMixed || role == erSupportMaterial || role == erSupportTransition;; - bool has_interface = role == erMixed || role == erSupportMaterialInterface; - unsigned int extruder_support = object.config().support_filament.value; - unsigned int extruder_interface = object.config().support_interface_filament.value; - if (has_support) - layer_tools.extruders.push_back(extruder_support); - if (has_interface) - layer_tools.extruders.push_back(extruder_interface); - if (has_support || has_interface) { - layer_tools.has_support = true; - layer_tools.wiping_extrusions().is_support_overriddable_and_mark(role, object); - } - } - // Extruder overrides are ordered by print_z. std::vector>::const_iterator it_per_layer_extruder_override; it_per_layer_extruder_override = per_layer_extruder_switches.begin(); @@ -1042,10 +1020,9 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int if (object->config().flush_into_support) { auto& object_config = object->config(); const SupportLayer* this_support_layer = object->get_support_layer_at_printz(lt.print_z, EPSILON); - const TreeSupportLayer* this_tree_support_layer = object->get_tree_support_layer_at_printz(lt.print_z, EPSILON); do { - if (this_support_layer == nullptr && this_tree_support_layer == nullptr) + if (this_support_layer == nullptr) break; bool support_overriddable = object_config.support_filament == 0; @@ -1053,7 +1030,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int if (!support_overriddable && !support_intf_overriddable) break; - auto& entities = this_support_layer != nullptr ? this_support_layer->support_fills.entities : this_tree_support_layer->support_fills.entities; + auto &entities = this_support_layer->support_fills.entities; if (support_overriddable && !is_support_overridden(object)) { set_support_extruder_override(object, copy, new_extruder, num_of_copies); for (const ExtrusionEntity* ee : entities) { diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 69b8fb99f..814c10ea9 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -211,6 +211,11 @@ private: LayerRegionPtrs m_regions; }; +enum SupportInnerType { + stInnerNormal, + stInnerTree +}; + class SupportLayer : public Layer { public: @@ -219,6 +224,10 @@ public: ExPolygonCollection support_islands; // Extrusion paths for the support base and for the support interface and contacts. ExtrusionEntityCollection support_fills; + SupportInnerType support_type = stInnerNormal; + + // for tree supports + ExPolygons base_areas; // Is there any valid extrusion assigned to this LayerRegion? @@ -231,33 +240,23 @@ public: protected: friend class PrintObject; + friend class TreeSupport; // The constructor has been made public to be able to insert additional support layers for the skirt or a wipe tower // between the raft and the object first layer. SupportLayer(size_t id, size_t interface_id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) : - Layer(id, object, height, print_z, slice_z), m_interface_id(interface_id) {} + Layer(id, object, height, print_z, slice_z), m_interface_id(interface_id), support_type(stInnerNormal) {} virtual ~SupportLayer() = default; size_t m_interface_id; -}; -class TreeSupportLayer : public Layer -{ -public: - ExtrusionEntityCollection support_fills; - ExPolygons overhang_areas; - ExPolygons roof_areas; - ExPolygons roof_1st_layer; // the layer just below roof. When working with PolySupport, this layer should be printed with regular material - ExPolygons floor_areas; - ExPolygons base_areas; - ExPolygons roof_gap_areas; // the areas in the gap between support roof and overhang - - enum AreaType { - BaseType=0, - RoofType=1, - FloorType=2, - Roof1stLayer=3 - }; + // for tree support + ExPolygons overhang_areas; + ExPolygons roof_areas; + ExPolygons roof_1st_layer; // the layer just below roof. When working with PolySupport, this layer should be printed with regular material + ExPolygons floor_areas; + ExPolygons roof_gap_areas; // the areas in the gap between support roof and overhang + enum AreaType { BaseType = 0, RoofType = 1, FloorType = 2, Roof1stLayer = 3 }; struct AreaGroup { ExPolygon *area; @@ -265,23 +264,9 @@ public: coordf_t dist_to_top; // mm dist to top AreaGroup(ExPolygon *a, int t, coordf_t d) : area(a), type(t), dist_to_top(d) {} }; - std::vector area_groups; - - enum OverhangType { - Detected=0, - Enforced - }; + enum OverhangType { Detected = 0, Enforced }; + std::vector area_groups; std::map overhang_types; - - virtual bool has_extrusions() const { return !support_fills.empty(); } - - void simplify_support_extrusion_path() { this->simplify_support_entity_collection(&support_fills);} - -protected: - friend class PrintObject; - TreeSupportLayer(size_t id, PrintObject* object, coordf_t height, coordf_t print_z, coordf_t slice_z) : - Layer(id, object, height, print_z, slice_z) {} - virtual ~TreeSupportLayer() = default; }; template diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index ec2368668..8a2b0ea6b 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1283,7 +1283,6 @@ void PrintObject::clear_shared_object() BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, clear previous shared object data %2%")%this %m_shared_object; m_layers.clear(); m_support_layers.clear(); - m_tree_support_layers.clear(); m_shared_object = nullptr; @@ -1296,7 +1295,6 @@ void PrintObject::copy_layers_from_shared_object() if (m_shared_object) { m_layers.clear(); m_support_layers.clear(); - m_tree_support_layers.clear(); firstLayerObjSliceByVolume.clear(); firstLayerObjSliceByGroups.clear(); @@ -1304,7 +1302,6 @@ void PrintObject::copy_layers_from_shared_object() BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, copied layers from object %2%")%this%m_shared_object; m_layers = m_shared_object->layers(); m_support_layers = m_shared_object->support_layers(); - m_tree_support_layers = m_shared_object->tree_support_layers(); firstLayerObjSliceByVolume = m_shared_object->firstLayerObjSlice(); firstLayerObjSliceByGroups = m_shared_object->firstLayerObjGroups(); @@ -1706,13 +1703,6 @@ void Print::_make_skirt() break; layer->support_fills.collect_points(object_points); } - // BBS - for (const TreeSupportLayer* layer : object->m_tree_support_layers) { - if (layer->print_z > skirt_height_z) - break; - - layer->support_fills.collect_points(object_points); - } object_convex_hulls.insert({ object, Slic3r::Geometry::convex_hull(object_points) }); @@ -1859,12 +1849,12 @@ Polygons Print::first_layer_islands() const Polygons object_islands; for (ExPolygon &expoly : object->m_layers.front()->lslices) object_islands.push_back(expoly.contour); - if (! object->support_layers().empty()) - object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON)); - if (! object->tree_support_layers().empty()) { - ExPolygons& expolys_first_layer = object->m_tree_support_layers.front()->lslices; - for (ExPolygon &expoly : expolys_first_layer) { - object_islands.push_back(expoly.contour); + if (!object->support_layers().empty()) { + if (object->support_layers().front()->support_type==stInnerNormal) + object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON)); + else if(object->support_layers().front()->support_type==stInnerTree) { + ExPolygons &expolys_first_layer = object->m_support_layers.front()->lslices; + for (ExPolygon &expoly : expolys_first_layer) { object_islands.push_back(expoly.contour); } } } islands.reserve(islands.size() + object_islands.size() * object->instances().size()); @@ -2215,7 +2205,7 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co #define JSON_SUPPORT_LAYER_ISLANDS "support_islands" #define JSON_SUPPORT_LAYER_FILLS "support_fills" #define JSON_SUPPORT_LAYER_INTERFACE_ID "interface_id" - +#define JSON_SUPPORT_LAYER_TYPE "support_type" #define JSON_LAYER_REGION_CONFIG_HASH "config_hash" #define JSON_LAYER_REGION_SLICES "slices" @@ -2846,6 +2836,7 @@ void extract_layer(const json& layer_json, Layer& layer) { void extract_support_layer(const json& support_layer_json, SupportLayer& support_layer) { extract_layer(support_layer_json, support_layer); + support_layer.support_type = support_layer_json[JSON_SUPPORT_LAYER_TYPE]; //support_islands int islands_count = support_layer_json[JSON_SUPPORT_LAYER_ISLANDS].size(); for (int islands_index = 0; islands_index < islands_count; islands_index++) @@ -2874,27 +2865,6 @@ void extract_support_layer(const json& support_layer_json, SupportLayer& support return; } -void extract_tree_support_layer(const json& tree_support_layer_json, TreeSupportLayer& tree_support_layer) { - extract_layer(tree_support_layer_json, tree_support_layer); - - //support_fills - tree_support_layer.support_fills.no_sort = tree_support_layer_json[JSON_SUPPORT_LAYER_FILLS][JSON_EXTRUSION_NO_SORT]; - int treesupport_fills_entities_count = tree_support_layer_json[JSON_SUPPORT_LAYER_FILLS][JSON_EXTRUSION_ENTITIES].size(); - for (int treesupport_fills_entities_index = 0; treesupport_fills_entities_index < treesupport_fills_entities_count; treesupport_fills_entities_index++) - { - const json& extrusion_entity_json = tree_support_layer_json[JSON_SUPPORT_LAYER_FILLS][JSON_EXTRUSION_ENTITIES][treesupport_fills_entities_index]; - bool ret = convert_extrusion_from_json(extrusion_entity_json, tree_support_layer.support_fills); - if (!ret) { - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": error parsing fills found at tree_support_layer %1%, print_z %2%")%tree_support_layer.id() %tree_support_layer.print_z; - char error_buf[1024]; - ::sprintf(error_buf, "Error while parsing fills at tree_support_layer %d, print_z %f", tree_support_layer.id(), tree_support_layer.print_z); - throw Slic3r::FileIOError(error_buf); - } - } - - return; -} - int Print::export_cached_data(const std::string& directory, bool with_space) { int ret = 0; @@ -2960,7 +2930,7 @@ int Print::export_cached_data(const std::string& directory, bool with_space) std::string file_name = directory +"/obj_"+std::to_string(arrange_order)+".json"; try { - json root_json, layers_json = json::array(), support_layers_json = json::array(), tree_support_layers_json = json::array(); + json root_json, layers_json = json::array(), support_layers_json = json::array(); root_json[JSON_OBJECT_NAME] = model_obj->name; root_json[JSON_ARRANGE_ORDER] = arrange_order; @@ -3005,6 +2975,7 @@ int Print::export_cached_data(const std::string& directory, bool with_space) convert_layer_to_json(support_layer_json, support_layer); support_layer_json[JSON_SUPPORT_LAYER_INTERFACE_ID] = support_layer->interface_id(); + support_layer_json[JSON_SUPPORT_LAYER_TYPE] = support_layer->support_type; //support_islands for (const ExPolygon& support_island : support_layer->support_islands.expolygons) { @@ -3068,136 +3039,6 @@ int Print::export_cached_data(const std::string& directory, bool with_space) } // for each layer*/ root_json[JSON_SUPPORT_LAYERS] = std::move(support_layers_json); - //export the tree support layers - std::vector tree_support_layers_json_vector(obj->tree_support_layer_count()); - tbb::parallel_for( - tbb::blocked_range(0, obj->tree_support_layer_count()), - [&tree_support_layers_json_vector, obj, convert_layer_to_json](const tbb::blocked_range& tree_support_layer_range) { - for (size_t ts_layer_index = tree_support_layer_range.begin(); ts_layer_index < tree_support_layer_range.end(); ++ ts_layer_index) { - const TreeSupportLayer *tree_support_layer = obj->get_tree_support_layer(ts_layer_index); - json treesupport_layer_json, treesupport_fills_json, treesupportfills_entities_json = json::array(); - //json overhang_areas_json = json::array(), roof_areas_json = json::array(), roof_1st_layer_json = json::array(), floor_areas_json = json::array(), base_areas_json = json::array(); - - convert_layer_to_json(treesupport_layer_json, tree_support_layer); - - //tree_support_fills - treesupport_fills_json[JSON_EXTRUSION_NO_SORT] = tree_support_layer->support_fills.no_sort; - treesupport_fills_json[JSON_EXTRUSION_ENTITY_TYPE] = JSON_EXTRUSION_TYPE_COLLECTION; - for (const ExtrusionEntity* extrusion_entity : tree_support_layer->support_fills.entities) { - json treesupportfill_entity_json, treesupportfill_entity_paths_json = json::array(); - bool ret = convert_extrusion_to_json(treesupportfill_entity_json, treesupportfill_entity_paths_json, extrusion_entity); - if (!ret) - continue; - - treesupportfills_entities_json.push_back(std::move(treesupportfill_entity_json)); - } - treesupport_fills_json[JSON_EXTRUSION_ENTITIES] = std::move(treesupportfills_entities_json); - treesupport_layer_json[JSON_SUPPORT_LAYER_FILLS] = std::move(treesupport_fills_json); - - //following data are not needed in the later stage - //overhang_areas - /*for (const ExPolygon& overhang_area : tree_support_layer->overhang_areas) { - json overhang_area_json = overhang_area; - overhang_areas_json.push_back(std::move(overhang_area_json)); - } - treesupport_layer_json["overhang_areas"] = std::move(overhang_areas_json); - - //roof_areas - for (const ExPolygon& roof_area : tree_support_layer->roof_areas) { - json roof_area_json = roof_area; - roof_areas_json.push_back(std::move(roof_area_json)); - } - treesupport_layer_json["roof_areas"] = std::move(roof_areas_json); - - //roof_1st_layer - for (const ExPolygon& layer_poly : tree_support_layer->roof_1st_layer) { - json layer_poly_json = layer_poly; - roof_1st_layer_json.push_back(std::move(layer_poly_json)); - } - treesupport_layer_json["roof_1st_layer"] = std::move(roof_1st_layer_json); - - //floor_areas - for (const ExPolygon& floor_area : tree_support_layer->floor_areas) { - json floor_area_json = floor_area; - floor_areas_json.push_back(std::move(floor_area_json)); - } - treesupport_layer_json["floor_areas"] = std::move(floor_areas_json); - - //base_areas - for (const ExPolygon& base_area : tree_support_layer->base_areas) { - json base_area_json = base_area; - base_areas_json.push_back(std::move(base_area_json)); - } - treesupport_layer_json["base_areas"] = std::move(base_areas_json);*/ - - tree_support_layers_json_vector[ts_layer_index] = std::move(treesupport_layer_json); - } - } - ); - for (int ts_index = 0; ts_index < tree_support_layers_json_vector.size(); ts_index++) { - tree_support_layers_json.push_back(std::move(tree_support_layers_json_vector[ts_index])); - } - tree_support_layers_json_vector.clear(); -#if 0 - for (const TreeSupportLayer *tree_support_layer : obj->tree_support_layers()) { - json treesupport_layer_json, treesupport_fills_json, treesupportfills_entities_json = json::array(); - json overhang_areas_json = json::array(), roof_areas_json = json::array(), roof_1st_layer_json = json::array(), floor_areas_json = json::array(), base_areas_json = json::array(); - - convert_layer_to_json(treesupport_layer_json, tree_support_layer); - - //tree_support_fills - treesupport_fills_json[JSON_EXTRUSION_NO_SORT] = tree_support_layer->support_fills.no_sort; - treesupport_fills_json[JSON_EXTRUSION_ENTITY_TYPE] = JSON_EXTRUSION_TYPE_COLLECTION; - for (const ExtrusionEntity* extrusion_entity : tree_support_layer->support_fills.entities) { - json treesupportfill_entity_json, treesupportfill_entity_paths_json = json::array(); - bool ret = convert_extrusion_to_json(treesupportfill_entity_json, treesupportfill_entity_paths_json, extrusion_entity); - if (!ret) - continue; - - treesupportfills_entities_json.push_back(std::move(treesupportfill_entity_json)); - } - treesupport_fills_json[JSON_EXTRUSION_ENTITIES] = std::move(treesupportfills_entities_json); - treesupport_layer_json[JSON_SUPPORT_LAYER_FILLS] = std::move(treesupport_fills_json); - - //overhang_areas - /*for (const ExPolygon& overhang_area : tree_support_layer->overhang_areas) { - json overhang_area_json = overhang_area; - overhang_areas_json.push_back(std::move(overhang_area_json)); - } - treesupport_layer_json["overhang_areas"] = std::move(overhang_areas_json); - - //roof_areas - for (const ExPolygon& roof_area : tree_support_layer->roof_areas) { - json roof_area_json = roof_area; - roof_areas_json.push_back(std::move(roof_area_json)); - } - treesupport_layer_json["roof_areas"] = std::move(roof_areas_json); - - //roof_1st_layer - for (const ExPolygon& layer_poly : tree_support_layer->roof_1st_layer) { - json layer_poly_json = layer_poly; - roof_1st_layer_json.push_back(std::move(layer_poly_json)); - } - treesupport_layer_json["roof_1st_layer"] = std::move(roof_1st_layer_json); - - //floor_areas - for (const ExPolygon& floor_area : tree_support_layer->floor_areas) { - json floor_area_json = floor_area; - floor_areas_json.push_back(std::move(floor_area_json)); - } - treesupport_layer_json["floor_areas"] = std::move(floor_areas_json); - - //base_areas - for (const ExPolygon& base_area : tree_support_layer->base_areas) { - json base_area_json = base_area; - base_areas_json.push_back(std::move(base_area_json)); - } - treesupport_layer_json["base_areas"] = std::move(base_areas_json);*/ - - tree_support_layers_json.push_back(std::move(treesupport_layer_json)); - } // for each layer -#endif - root_json[JSON_TREE_SUPPORT_LAYERS] = std::move(tree_support_layers_json); filename_vector.push_back(file_name); json_vector.push_back(std::move(root_json)); @@ -3276,7 +3117,6 @@ int Print::load_cached_data(const std::string& directory) obj->clear_layers(); obj->clear_support_layers(); - obj->clear_tree_support_layers(); int arrange_order = model_instance->arrange_order; if (arrange_order <= 0) { @@ -3328,13 +3168,12 @@ int Print::load_cached_data(const std::string& directory) std::string name = root_json.at(JSON_OBJECT_NAME); int order = root_json.at(JSON_ARRANGE_ORDER); - int layer_count = 0, support_layer_count = 0, treesupport_layer_count = 0; + int layer_count = 0, support_layer_count = 0; layer_count = root_json[JSON_LAYERS].size(); support_layer_count = root_json[JSON_SUPPORT_LAYERS].size(); - treesupport_layer_count = root_json[JSON_TREE_SUPPORT_LAYERS].size(); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__<add_tree_support_layer(layer_json[JSON_LAYER_ID], layer_json[JSON_LAYER_HEIGHT], layer_json[JSON_LAYER_PRINT_Z], layer_json[JSON_LAYER_SLICE_Z]); - if (!new_tree_support_layer) { - BOOST_LOG_TRIVIAL(error) <<__FUNCTION__<< boost::format(":add_support_layer failed, out of memory"); - return CLI_OUT_OF_MEMORY; - } - if (previous_tree_support_layer) { - previous_tree_support_layer->upper_layer = new_tree_support_layer; - new_tree_support_layer->lower_layer = previous_tree_support_layer; - } - previous_tree_support_layer = new_tree_support_layer; - } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": finished load support_layers, start to load treesupport_layers."); - tbb::parallel_for( - tbb::blocked_range(0, obj->tree_support_layer_count()), - [&root_json, &obj](const tbb::blocked_range& tree_support_layer_range) { - for (size_t layer_index = tree_support_layer_range.begin(); layer_index < tree_support_layer_range.end(); ++ layer_index) { - const json& layer_json = root_json[JSON_TREE_SUPPORT_LAYERS][layer_index]; - TreeSupportLayer* tree_support_layer = obj->get_tree_support_layer(layer_index); - extract_tree_support_layer(layer_json, *tree_support_layer); - } - } - ); - count ++; BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": load object %1% from %2% successfully.")%count%object_filenames[obj_index].first; } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 3a6b431de..c5f9aa280 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -31,7 +31,6 @@ class Print; class PrintObject; class SupportLayer; // BBS -class TreeSupportLayer; class TreeSupportData; class TreeSupport; @@ -175,13 +174,6 @@ class ConstSupportLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor(data) {} }; -// BBS -typedef std::vector TreeSupportLayerPtrs; -class ConstTreeSupportLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor { - friend PrintObject; - ConstTreeSupportLayerPtrsAdaptor(const TreeSupportLayerPtrs* data) : ConstVectorOfPtrsAdaptor(data) {} -}; - class BoundingBoxf3; // TODO: for temporary constructor parameter // Single instance of a PrintObject. @@ -296,14 +288,10 @@ public: Transform3d trafo_centered() const { Transform3d t = this->trafo(); t.pretranslate(Vec3d(- unscale(m_center_offset.x()), - unscale(m_center_offset.y()), 0)); return t; } const PrintInstances& instances() const { return m_instances; } - // BBS - ConstTreeSupportLayerPtrsAdaptor tree_support_layers() const { return ConstTreeSupportLayerPtrsAdaptor(&m_tree_support_layers); } // Whoever will get a non-const pointer to PrintObject will be able to modify its layers. LayerPtrs& layers() { return m_layers; } SupportLayerPtrs& support_layers() { return m_support_layers; } - // BBS - TreeSupportLayerPtrs& tree_support_layers() { return m_tree_support_layers; } template static void remove_bridges_from_contacts( @@ -364,12 +352,7 @@ public: Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); // BBS - TreeSupportLayer* get_tree_support_layer(int idx) { return m_tree_support_layers[idx]; } - const TreeSupportLayer* get_tree_support_layer_at_printz(coordf_t print_z, coordf_t epsilon) const; - TreeSupportLayer* get_tree_support_layer_at_printz(coordf_t print_z, coordf_t epsilon); - TreeSupportLayer* add_tree_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); - void clear_tree_support_layers(); - size_t tree_support_layer_count() const { return m_tree_support_layers.size(); } + SupportLayer* add_tree_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); std::shared_ptr alloc_tree_support_preview_cache(); void clear_tree_support_preview_cache() { m_tree_support_preview_cache.reset(); } @@ -380,7 +363,6 @@ public: SupportLayer* get_support_layer_at_printz(coordf_t print_z, coordf_t epsilon); SupportLayer* add_support_layer(int id, int interface_id, coordf_t height, coordf_t print_z); SupportLayerPtrs::iterator insert_support_layer(SupportLayerPtrs::iterator pos, size_t id, size_t interface_id, coordf_t height, coordf_t print_z, coordf_t slice_z); - void delete_support_layer(int idx); // Initialize the layer_height_profile from the model_object's layer_height_profile, from model_object's layer height table, or from slicing parameters. // Returns true, if the layer_height_profile was changed. @@ -497,7 +479,6 @@ private: LayerPtrs m_layers; SupportLayerPtrs m_support_layers; // BBS - TreeSupportLayerPtrs m_tree_support_layers; std::shared_ptr m_tree_support_preview_cache; // this is set to true when LayerRegion->slices is split in top/internal/bottom diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 4cc8b2fc2..ff76f68b1 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -91,7 +91,6 @@ PrintObject::~PrintObject() if (m_shared_regions && -- m_shared_regions->m_ref_cnt == 0) delete m_shared_regions; clear_layers(); clear_support_layers(); - clear_tree_support_layers(); } PrintBase::ApplyStatus PrintObject::set_instances(PrintInstances &&instances) @@ -414,7 +413,6 @@ void PrintObject::generate_support_material() { if (this->set_started(posSupportMaterial)) { this->clear_support_layers(); - this->clear_tree_support_layers(); if ((this->has_support() && m_layers.size() > 1) || (this->has_raft() && ! m_layers.empty())) { m_print->set_status(50, L("Generating support")); @@ -483,16 +481,6 @@ void PrintObject::simplify_extrusion_path() } ); m_print->throw_if_canceled(); - tbb::parallel_for( - tbb::blocked_range(0, m_tree_support_layers.size()), - [this](const tbb::blocked_range& range) { - for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { - m_print->throw_if_canceled(); - m_tree_support_layers[layer_idx]->simplify_support_extrusion_path(); - } - } - ); - m_print->throw_if_canceled(); BOOST_LOG_TRIVIAL(debug) << "Simplify extrusion path of support in parallel - end"; this->set_done(posSimplifySupportPath); } @@ -564,19 +552,6 @@ Layer* PrintObject::add_layer(int id, coordf_t height, coordf_t print_z, coordf_ return m_layers.back(); } -// BBS -const TreeSupportLayer* PrintObject::get_tree_support_layer_at_printz(coordf_t print_z, coordf_t epsilon) const -{ - coordf_t limit = print_z - epsilon; - auto it = Slic3r::lower_bound_by_predicate(m_tree_support_layers.begin(), m_tree_support_layers.end(), [limit](const TreeSupportLayer* layer) { return layer->print_z < limit; }); - return (it == m_tree_support_layers.end() || (*it)->print_z > print_z + epsilon) ? nullptr : *it; -} - -TreeSupportLayer* PrintObject::get_tree_support_layer_at_printz(coordf_t print_z, coordf_t epsilon) -{ - return const_cast(std::as_const(*this).get_tree_support_layer_at_printz(print_z, epsilon)); -} - const SupportLayer* PrintObject::get_support_layer_at_printz(coordf_t print_z, coordf_t epsilon) const { coordf_t limit = print_z - epsilon; @@ -589,12 +564,17 @@ SupportLayer* PrintObject::get_support_layer_at_printz(coordf_t print_z, coordf_ return const_cast(std::as_const(*this).get_support_layer_at_printz(print_z, epsilon)); } -void PrintObject::clear_tree_support_layers() +void PrintObject::clear_support_layers() { if (!m_shared_object) { - for (TreeSupportLayer* l : m_tree_support_layers) + for (SupportLayer* l : m_support_layers) delete l; - m_tree_support_layers.clear(); + m_support_layers.clear(); + for (auto l : m_layers) { + l->sharp_tails.clear(); + l->sharp_tails_height.clear(); + l->cantilevers.clear(); + } } } @@ -614,19 +594,11 @@ std::shared_ptr PrintObject::alloc_tree_support_preview_cache() return m_tree_support_preview_cache; } -TreeSupportLayer* PrintObject::add_tree_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z) +SupportLayer* PrintObject::add_tree_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z) { - m_tree_support_layers.emplace_back(new TreeSupportLayer(id, this, height, print_z, slice_z)); - return m_tree_support_layers.back(); -} - -void PrintObject::clear_support_layers() -{ - if (!m_shared_object) { - for (Layer *l : m_support_layers) - delete l; - m_support_layers.clear(); - } + m_support_layers.emplace_back(new SupportLayer(id, 0, this, height, print_z, slice_z)); + m_support_layers.back()->support_type = stInnerTree; + return m_support_layers.back(); } SupportLayer* PrintObject::add_support_layer(int id, int interface_id, coordf_t height, coordf_t print_z) diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index 617f8f4bf..e33076b88 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -28,7 +28,7 @@ #define TAU (2.0 * M_PI) #define NO_INDEX (std::numeric_limits::max()) -//#define SUPPORT_TREE_DEBUG_TO_SVG +// #define SUPPORT_TREE_DEBUG_TO_SVG namespace Slic3r { @@ -286,7 +286,7 @@ static void draw_layer_mst svg.draw(spanning_tree.vertices(), "black", coord_t(scale_(0.1))); } -static void draw_two_overhangs_to_svg(TreeSupportLayer* ts_layer, const ExPolygons& overhangs1, const ExPolygons& overhangs2) +static void draw_two_overhangs_to_svg(SupportLayer* ts_layer, const ExPolygons& overhangs1, const ExPolygons& overhangs2) { if (overhangs1.empty() && overhangs2.empty()) return; @@ -301,7 +301,7 @@ static void draw_two_overhangs_to_svg(TreeSupportLayer* ts_layer, const ExPolygo svg.draw(union_ex(overhangs2), "red"); } -static void draw_polylines(TreeSupportLayer* ts_layer, Polylines& polylines) +static void draw_polylines(SupportLayer* ts_layer, Polylines& polylines) { if (polylines.empty()) return; @@ -711,11 +711,11 @@ TreeSupport::TreeSupport(PrintObject& object, const SlicingParameters &slicing_p void TreeSupport::detect_object_overhangs() { // overhangs are already detected - if (m_object->tree_support_layer_count() >= m_object->layer_count()) + if (m_object->support_layer_count() >= m_object->layer_count()) return; // Clear and create Tree Support Layers - m_object->clear_tree_support_layers(); + m_object->clear_support_layers(); m_object->clear_tree_support_preview_cache(); create_tree_support_layers(); @@ -997,7 +997,7 @@ void TreeSupport::detect_object_overhangs() m_object->remove_bridges_from_contacts(lower_layer, layer, extrusion_width_scaled, &overhang_areas, max_bridge_length, true); } - TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); + SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); for (ExPolygon& poly : overhang_areas) { if (!offset_ex(poly, -0.1 * extrusion_width_scaled).empty()) ts_layer->overhang_areas.emplace_back(poly); @@ -1147,7 +1147,7 @@ void TreeSupport::detect_object_overhangs() if (m_object->print()->canceled()) break; - TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); + SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); if (support_critical_regions_only) { auto layer = m_object->get_layer(layer_nr); auto lower_layer = layer->lower_layer; @@ -1165,7 +1165,7 @@ void TreeSupport::detect_object_overhangs() } for (auto &area : ts_layer->overhang_areas) { - ts_layer->overhang_types.emplace(&area, TreeSupportLayer::Detected); + ts_layer->overhang_types.emplace(&area, SupportLayer::Detected); } // enforcers if (layer_nr < enforcers.size()) { @@ -1176,7 +1176,7 @@ void TreeSupport::detect_object_overhangs() enforcer = offset(enforcer, 0.1 * extrusion_width_scaled); for (const Polygon& poly : enforcer) { ts_layer->overhang_areas.emplace_back(poly); - ts_layer->overhang_types.emplace(&ts_layer->overhang_areas.back(), TreeSupportLayer::Enforced); + ts_layer->overhang_types.emplace(&ts_layer->overhang_areas.back(), SupportLayer::Enforced); } } @@ -1184,7 +1184,7 @@ void TreeSupport::detect_object_overhangs() } #ifdef SUPPORT_TREE_DEBUG_TO_SVG - for (const TreeSupportLayer* layer : m_object->tree_support_layers()) { + for (const SupportLayer* layer : m_object->support_layers()) { if (layer->overhang_areas.empty()) continue; @@ -1221,9 +1221,9 @@ void TreeSupport::create_tree_support_layers() } for (Layer *layer : m_object->layers()) { - TreeSupportLayer* ts_layer = m_object->add_tree_support_layer(layer->id(), layer->height, layer->print_z, layer->slice_z); + SupportLayer* ts_layer = m_object->add_tree_support_layer(layer->id(), layer->height, layer->print_z, layer->slice_z); if (ts_layer->id() > m_raft_layers) { - TreeSupportLayer* lower_layer = m_object->get_tree_support_layer(ts_layer->id() - 1); + SupportLayer* lower_layer = m_object->get_support_layer(ts_layer->id() - 1); lower_layer->upper_layer = ts_layer; ts_layer->lower_layer = lower_layer; } @@ -1435,7 +1435,7 @@ void TreeSupport::generate_toolpaths() const coordf_t branch_radius = object_config.tree_support_branch_diameter.value / 2; const coordf_t branch_radius_scaled = scale_(branch_radius); - if (m_object->tree_support_layers().empty()) + if (m_object->support_layers().empty()) return; // calculate fill areas for raft layers @@ -1447,8 +1447,8 @@ void TreeSupport::generate_toolpaths() } } - if (m_object->tree_support_layer_count() > m_raft_layers) { - const TreeSupportLayer *ts_layer = m_object->get_tree_support_layer(m_raft_layers); + if (m_object->support_layer_count() > m_raft_layers) { + const SupportLayer *ts_layer = m_object->get_support_layer(m_raft_layers); for (const ExPolygon expoly : ts_layer->floor_areas) raft_areas.push_back(expoly); for (const ExPolygon expoly : ts_layer->roof_areas) @@ -1463,7 +1463,7 @@ void TreeSupport::generate_toolpaths() if (m_raft_layers > 0) { ExtrusionRole raft_contour_er = m_slicing_params.base_raft_layers > 0 ? erSupportMaterial : erSupportMaterialInterface; - TreeSupportLayer *ts_layer = m_object->tree_support_layers().front(); + SupportLayer *ts_layer = m_object->support_layers().front(); Flow flow = m_object->print()->brim_flow(); Polygons loops; @@ -1477,7 +1477,7 @@ void TreeSupport::generate_toolpaths() } for (size_t layer_nr = 0; layer_nr < m_slicing_params.base_raft_layers; layer_nr++) { - TreeSupportLayer *ts_layer = m_object->get_tree_support_layer(layer_nr); + SupportLayer *ts_layer = m_object->get_support_layer(layer_nr); coordf_t expand_offset = (layer_nr == 0 ? 0. : -1.); Flow support_flow = layer_nr == 0 ? m_object->print()->brim_flow() : Flow(support_extrusion_width, ts_layer->height, nozzle_diameter); @@ -1497,7 +1497,7 @@ void TreeSupport::generate_toolpaths() layer_nr < m_slicing_params.base_raft_layers + m_slicing_params.interface_raft_layers; layer_nr++) { - TreeSupportLayer *ts_layer = m_object->get_tree_support_layer(layer_nr); + SupportLayer *ts_layer = m_object->get_support_layer(layer_nr); coordf_t expand_offset = (layer_nr == 0 ? 0. : -1.); Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter); @@ -1529,7 +1529,7 @@ void TreeSupport::generate_toolpaths() // generate tree support tool paths tbb::parallel_for( - tbb::blocked_range(m_raft_layers, m_object->tree_support_layer_count()), + tbb::blocked_range(m_raft_layers, m_object->support_layer_count()), [&](const tbb::blocked_range& range) { for (size_t layer_id = range.begin(); layer_id < range.end(); layer_id++) { @@ -1538,7 +1538,7 @@ void TreeSupport::generate_toolpaths() m_object->print()->set_status(70, (boost::format(_L("Support: generate toolpath at layer %d")) % layer_id).str()); - TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_id); + SupportLayer* ts_layer = m_object->get_support_layer(layer_id); Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter); coordf_t support_spacing = object_config.support_base_pattern_spacing.value + support_flow.spacing(); coordf_t support_density = std::min(1., support_flow.spacing() / support_spacing); @@ -1549,14 +1549,14 @@ void TreeSupport::generate_toolpaths() ExPolygon& poly = *area_group.area; ExPolygons polys; FillParams fill_params; - if (area_group.type != TreeSupportLayer::BaseType) { + if (area_group.type != SupportLayer::BaseType) { // interface if (layer_id == 0) { Flow flow = m_raft_layers == 0 ? m_object->print()->brim_flow() : support_flow; make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, wall_count, flow, - area_group.type == TreeSupportLayer::RoofType ? erSupportMaterialInterface : erSupportMaterial); + area_group.type == SupportLayer::RoofType ? erSupportMaterialInterface : erSupportMaterial); polys = std::move(offset_ex(poly, -flow.scaled_spacing())); - } else if (area_group.type == TreeSupportLayer::Roof1stLayer) { + } else if (area_group.type == SupportLayer::Roof1stLayer) { polys = std::move(offset_ex(poly, 0.5*support_flow.scaled_width())); } else { @@ -1565,7 +1565,7 @@ void TreeSupport::generate_toolpaths() fill_params.density = interface_density; fill_params.dont_adjust = true; } - if (area_group.type == TreeSupportLayer::Roof1stLayer) { + if (area_group.type == SupportLayer::Roof1stLayer) { // roof_1st_layer fill_params.density = interface_density; // Note: spacing means the separation between two lines as if they are tightly extruded @@ -1579,13 +1579,13 @@ void TreeSupport::generate_toolpaths() ts_layer->support_fills.entities.push_back(temp_support_fills); else delete temp_support_fills; - } else if (area_group.type == TreeSupportLayer::FloorType) { + } else if (area_group.type == SupportLayer::FloorType) { // floor_areas fill_params.density = bottom_interface_density; filler_interface->spacing = m_support_material_interface_flow.spacing(); fill_expolygons_generate_paths(ts_layer->support_fills.entities, std::move(polys), filler_interface.get(), fill_params, erSupportMaterialInterface, m_support_material_interface_flow); - } else if (area_group.type == TreeSupportLayer::RoofType) { + } else if (area_group.type == SupportLayer::RoofType) { // roof_areas fill_params.density = interface_density; filler_interface->spacing = m_support_material_interface_flow.spacing(); @@ -2072,7 +2072,7 @@ void TreeSupport::draw_circles(const std::vector>& contact_no break; const std::vector& curr_layer_nodes = contact_nodes[layer_nr]; - TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); + SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); assert(ts_layer != nullptr); // skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355) @@ -2248,10 +2248,10 @@ void TreeSupport::draw_circles(const std::vector>& contact_no } } auto &area_groups = ts_layer->area_groups; - for (auto &area : ts_layer->base_areas) area_groups.emplace_back(&area, TreeSupportLayer::BaseType, max_layers_above_base); - for (auto &area : ts_layer->roof_areas) area_groups.emplace_back(&area, TreeSupportLayer::RoofType, max_layers_above_roof); - for (auto &area : ts_layer->floor_areas) area_groups.emplace_back(&area, TreeSupportLayer::FloorType, 10000); - for (auto &area : ts_layer->roof_1st_layer) area_groups.emplace_back(&area, TreeSupportLayer::Roof1stLayer, max_layers_above_roof1); + for (auto &area : ts_layer->base_areas) area_groups.emplace_back(&area, SupportLayer::BaseType, max_layers_above_base); + for (auto &area : ts_layer->roof_areas) area_groups.emplace_back(&area, SupportLayer::RoofType, max_layers_above_roof); + for (auto &area : ts_layer->floor_areas) area_groups.emplace_back(&area, SupportLayer::FloorType, 10000); + for (auto &area : ts_layer->roof_1st_layer) area_groups.emplace_back(&area, SupportLayer::Roof1stLayer, max_layers_above_roof1); for (auto &area_group : area_groups) { auto& expoly = area_group.area; @@ -2276,7 +2276,7 @@ void TreeSupport::draw_circles(const std::vector>& contact_no for (int layer_nr = 1; layer_nr < m_object->layer_count(); layer_nr++) { if (print->canceled()) break; const std::vector& curr_layer_nodes = contact_nodes[layer_nr]; - TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); + SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); assert(ts_layer != nullptr); // skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355) @@ -2288,10 +2288,10 @@ void TreeSupport::draw_circles(const std::vector>& contact_no int layer_nr_lower = layer_nr - 1; for (layer_nr_lower; layer_nr_lower >= 0; layer_nr_lower--) { - if (!m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers)->area_groups.empty()) break; + if (!m_object->get_support_layer(layer_nr_lower + m_raft_layers)->area_groups.empty()) break; } - TreeSupportLayer* lower_layer = m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers); - ExPolygons& base_areas_lower = m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers)->base_areas; + SupportLayer* lower_layer = m_object->get_support_layer(layer_nr_lower + m_raft_layers); + ExPolygons& base_areas_lower = m_object->get_support_layer(layer_nr_lower + m_raft_layers)->base_areas; ExPolygons overhang; @@ -2325,7 +2325,7 @@ void TreeSupport::draw_circles(const std::vector>& contact_no printZ_to_lightninglayer[lower_layer->print_z] = overhangs.size() - 1; #ifdef SUPPORT_TREE_DEBUG_TO_SVG - draw_two_overhangs_to_svg(m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers), base_areas_lower, to_expolygons(overhangs.back())); + draw_two_overhangs_to_svg(m_object->get_support_layer(layer_nr_lower + m_raft_layers), base_areas_lower, to_expolygons(overhangs.back())); #endif } @@ -2365,7 +2365,7 @@ void TreeSupport::draw_circles(const std::vector>& contact_no m_object->print()->set_status(66, (boost::format(_L("Support: fix holes at layer %d")) % layer_nr).str()); const std::vector& curr_layer_nodes = contact_nodes[layer_nr]; - TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); + SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); assert(ts_layer != nullptr); // skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355) @@ -2375,18 +2375,18 @@ void TreeSupport::draw_circles(const std::vector>& contact_no int layer_nr_lower = layer_nr - 1; for (layer_nr_lower; layer_nr_lower >= 0; layer_nr_lower--) { - if (!m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers)->area_groups.empty()) break; + if (!m_object->get_support_layer(layer_nr_lower + m_raft_layers)->area_groups.empty()) break; } if (layer_nr_lower < 0) continue; - auto& area_groups_lower = m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers)->area_groups; + auto& area_groups_lower = m_object->get_support_layer(layer_nr_lower + m_raft_layers)->area_groups; for (const auto& area_group : ts_layer->area_groups) { - if (area_group.type != TreeSupportLayer::BaseType) continue; + if (area_group.type != SupportLayer::BaseType) continue; const auto& area = area_group.area; for (const auto& hole : area->holes) { // auto hole_bbox = get_extents(hole).polygon(); for (auto& area_group_lower : area_groups_lower) { - if (area_group.type != TreeSupportLayer::BaseType) continue; + if (area_group.type != SupportLayer::BaseType) continue; auto& base_area_lower = *area_group_lower.area; Point pt_on_poly, pt_on_expoly, pt_far_on_poly; // if a hole doesn't intersect with lower layer's contours, add a hole to lower layer and move it slightly to the contour @@ -2451,8 +2451,8 @@ void TreeSupport::draw_circles(const std::vector>& contact_no #endif #ifdef SUPPORT_TREE_DEBUG_TO_SVG - for (int layer_nr = m_object->layer_count() - 1; layer_nr > 0; layer_nr--) { - TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); + for (int layer_nr = m_object->layer_count() - 1; layer_nr >= 0; layer_nr--) { + SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); ExPolygons& base_areas = ts_layer->base_areas; ExPolygons& roof_areas = ts_layer->roof_areas; ExPolygons& roof_1st_layer = ts_layer->roof_1st_layer; @@ -2467,7 +2467,7 @@ void TreeSupport::draw_circles(const std::vector>& contact_no draw_circles_layer_out.open("./SVG/layer_heights_draw_circles.txt"); if (draw_circles_layer_out.is_open()) { for (int layer_nr = m_object->layer_count() - 1; layer_nr > 0; layer_nr--) { - TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); + SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); ExPolygons& base_areas = ts_layer->base_areas; ExPolygons& roof_areas = ts_layer->roof_areas; ExPolygons& roof_1st_layer = ts_layer->roof_1st_layer; @@ -2478,8 +2478,8 @@ void TreeSupport::draw_circles(const std::vector>& contact_no } #endif // SUPPORT_TREE_DEBUG_TO_SVG - TreeSupportLayerPtrs& ts_layers = m_object->tree_support_layers(); - auto iter = std::remove_if(ts_layers.begin(), ts_layers.end(), [](TreeSupportLayer* ts_layer) { return ts_layer->height < EPSILON; }); + SupportLayerPtrs& ts_layers = m_object->support_layers(); + auto iter = std::remove_if(ts_layers.begin(), ts_layers.end(), [](SupportLayer* ts_layer) { return ts_layer->height < EPSILON; }); ts_layers.erase(iter, ts_layers.end()); for (int layer_nr = 0; layer_nr < ts_layers.size(); layer_nr++) { ts_layers[layer_nr]->upper_layer = layer_nr != ts_layers.size() - 1 ? ts_layers[layer_nr + 1] : nullptr; @@ -2585,7 +2585,7 @@ void TreeSupport::drop_nodes(std::vector>& contact_nodes) coordf_t height_next = layer_heights[layer_nr_next].second; std::deque> unsupported_branch_leaves; // All nodes that are leaves on this layer that would result in unsupported ('mid-air') branches. - const Layer* ts_layer = m_object->get_tree_support_layer(layer_nr); + const Layer* ts_layer = m_object->get_support_layer(layer_nr); m_object->print()->set_status(60, (boost::format(_L("Support: propagate branches at layer %d")) % layer_nr).str()); @@ -3347,7 +3347,7 @@ void TreeSupport::generate_contact_points(std::vectorprint()->canceled()) break; - auto ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); + auto ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); const ExPolygons &overhang = ts_layer->overhang_areas; auto & curr_nodes = contact_nodes[layer_nr]; if (overhang.empty()) @@ -3406,7 +3406,7 @@ void TreeSupport::generate_contact_points(std::vectoroverhang_types[&overhang_part] == TreeSupportLayer::Detected) + if (ts_layer->overhang_types[&overhang_part] == SupportLayer::Detected) candidates = {bbox.min, bounding_box_middle(bbox), bbox.max}; else candidates = {bounding_box_middle(bbox)}; @@ -3421,7 +3421,7 @@ void TreeSupport::generate_contact_points(std::vectoroverhang_types[&overhang_part] == TreeSupportLayer::Detected) { + if (ts_layer->overhang_types[&overhang_part] == SupportLayer::Detected) { // add points at corners auto &points = overhang_part.contour.points; int nSize = points.size(); @@ -3438,7 +3438,7 @@ void TreeSupport::generate_contact_points(std::vectoroverhang_types[&overhang_part] == TreeSupportLayer::Enforced || is_slim){ + if(ts_layer->overhang_types[&overhang_part] == SupportLayer::Enforced || is_slim){ // remove close points in Enforcers // auto above_nodes = contact_nodes[layer_nr - 1]; if (!curr_nodes.empty() /*&& !above_nodes.empty()*/) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 1f2a15979..1aaf877b3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -865,42 +865,22 @@ void GLGizmoFdmSupports::run_thread() goto _finished; } - if (m_is_tree_support) + if (!m_print_instance.print_object->support_layers().size()) { - if (!m_print_instance.print_object->tree_support_layers().size()) - { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no tree support layer found, update status to 100%\n"; - print->set_status(100, L("Support Generated")); - goto _finished; - } - for (const TreeSupportLayer *support_layer : m_print_instance.print_object->tree_support_layers()) - { - for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities) - { - _3DScene::extrusionentity_to_verts(extrusion_entity, float(support_layer->print_z), m_print_instance.shift, *m_support_volume); - } - } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%"; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no support layer found, update status to 100%\n"; print->set_status(100, L("Support Generated")); + goto _finished; } - else + for (const SupportLayer *support_layer : m_print_instance.print_object->support_layers()) { - if (!m_print_instance.print_object->support_layers().size()) + for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities) { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no support layer found, update status to 100%\n"; - print->set_status(100, L("Support Generated")); - goto _finished; + _3DScene::extrusionentity_to_verts(extrusion_entity, float(support_layer->print_z), m_print_instance.shift, *m_support_volume); } - for (const SupportLayer *support_layer : m_print_instance.print_object->support_layers()) - { - for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities) - { - _3DScene::extrusionentity_to_verts(extrusion_entity, float(support_layer->print_z), m_print_instance.shift, *m_support_volume); - } - } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%"; - print->set_status(100, L("Support Generated")); } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%"; + print->set_status(100, L("Support Generated")); + record_timestamp(); } catch (...) {