diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 7c673231e0..6db340051a 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -309,16 +309,16 @@ set(lisbslic3r_sources Support/SupportLayer.hpp Support/SupportMaterial.cpp Support/SupportMaterial.hpp - Support/SupportParameters.hpp Support/SupportSpotsGenerator.cpp Support/SupportSpotsGenerator.hpp Support/TreeSupport.hpp Support/TreeSupport.cpp - Support/TreeSupport3D.cpp Support/TreeSupport3D.hpp - Support/TreeSupportCommon.hpp - Support/TreeModelVolumes.cpp + Support/TreeSupport3D.cpp Support/TreeModelVolumes.hpp + Support/TreeModelVolumes.cpp + Support/TreeSupportCommon.hpp + Support/SupportParameters.hpp PrincipalComponents2D.cpp PrincipalComponents2D.hpp MinimumSpanningTree.hpp diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index d5ce03d3b4..d64ab81689 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -56,7 +56,7 @@ Fill* Fill::new_from_type(const InfillPattern type) case ipOctagramSpiral: return new FillOctagramSpiral(); case ipAdaptiveCubic: return new FillAdaptive::Filler(); case ipSupportCubic: return new FillAdaptive::Filler(); - case ipSupportBase: return new FillSupportBase(); + case ipSupportBase: return new FillSupportBase(); // simply line fill case ipLightning: return new FillLightning::Filler(); // BBS: for internal solid infill only case ipConcentricInternal: return new FillConcentricInternal(); diff --git a/src/libslic3r/Support/SupportMaterial.cpp b/src/libslic3r/Support/SupportMaterial.cpp index 57567b90d8..47c476564b 100644 --- a/src/libslic3r/Support/SupportMaterial.cpp +++ b/src/libslic3r/Support/SupportMaterial.cpp @@ -329,22 +329,6 @@ static Polygons contours_simplified(const Vec2i32 &grid_size, const double pixel } #endif // SUPPORT_USE_AGG_RASTERIZER -static std::string get_svg_filename(std::string layer_nr_or_z, std::string tag = "bbl_ts") -{ - static bool rand_init = false; - - if (!rand_init) { - srand(time(NULL)); - rand_init = true; - } - - int rand_num = rand() % 1000000; - //makedir("./SVG"); - std::string prefix = "./SVG/"; - std::string suffix = ".svg"; - return prefix + tag + "_" + layer_nr_or_z /*+ "_" + std::to_string(rand_num)*/ + suffix; -} - PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object, const SlicingParameters &slicing_params) : m_print_config (&object->print()->config()), m_object_config (&object->config()), @@ -567,18 +551,6 @@ void PrintObjectSupportMaterial::generate(PrintObject &object) } #endif /* SLIC3R_DEBUG */ -#if 0 // #ifdef SLIC3R_DEBUG - // check bounds - std::ofstream out; - out.open("./SVG/ns_support_layers.txt"); - if (out.is_open()) { - out << "### Support Layers ###" << std::endl; - for (auto& i : object.support_layers()) { - out << i->print_z << std::endl; - } - } -#endif /* SLIC3R_DEBUG */ - // Generate the actual toolpaths and save them into each layer. generate_support_toolpaths(object.support_layers(), *m_object_config, m_support_params, m_slicing_params, raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers); @@ -2245,10 +2217,6 @@ SupportGeneratorLayersPtr PrintObjectSupportMaterial::top_contact_layers( layer->sharp_tails.push_back(expoly); layer->sharp_tails_height.push_back( accum_height ); append(overhangs_per_layers[layer_nr], overhang); -#ifdef SUPPORT_TREE_DEBUG_TO_SVG - SVG svg(get_svg_filename(std::to_string(layer->print_z), "sharp_tail"), object.bounding_box()); - if (svg.is_opened()) svg.draw(overhang, "yellow"); -#endif } } @@ -2959,36 +2927,6 @@ SupportGeneratorLayersPtr PrintObjectSupportMaterial::raft_and_intermediate_supp for (size_t i = 0; i < top_contacts.size(); ++i) assert(top_contacts[i]->height > 0.); #endif /* _DEBUG */ - -#if 0 // #ifdef SLIC3R_DEBUG - // check bounds - std::ofstream out; - out.open("./SVG/ns_bounds.txt"); - if (out.is_open()) { - if (!top_contacts.empty()) { - out << "### Top Contacts ###" << std::endl; - for (auto& t : top_contacts) { - out << t->print_z << std::endl; - } - } - if (!bottom_contacts.empty()) { - out << "### Bottome Contacts ###" << std::endl; - for (auto& b : bottom_contacts) { - out << b->print_z << std::endl; - } - } - if (!intermediate_layers.empty()) { - out << "### Intermediate Layers ###" << std::endl; - for (auto& i : intermediate_layers) { - out << i->print_z << std::endl; - } - } - out << "### Slice Layers ###" << std::endl; - for (size_t j = 0; j < object.layers().size(); ++j) { - out << object.layers()[j]->print_z << std::endl; - } - } -#endif /* SLIC3R_DEBUG */ return intermediate_layers; } diff --git a/src/libslic3r/Support/SupportParameters.hpp b/src/libslic3r/Support/SupportParameters.hpp index e4c0dcd00e..1b1c11d953 100644 --- a/src/libslic3r/Support/SupportParameters.hpp +++ b/src/libslic3r/Support/SupportParameters.hpp @@ -5,11 +5,8 @@ #include "../Flow.hpp" namespace Slic3r { - -class PrintObject; -enum InfillPattern : int; - struct SupportParameters { + SupportParameters() = default; SupportParameters(const PrintObject &object) { const PrintConfig &print_config = object.print()->config(); @@ -86,20 +83,24 @@ struct SupportParameters { // Object is printed with the same extruder as the support. this->can_merge_support_regions = true; } - - double interface_spacing = object_config.support_interface_spacing.value + this->support_material_interface_flow.spacing(); - this->interface_density = std::min(1., this->support_material_interface_flow.spacing() / interface_spacing); + + + this->base_angle = Geometry::deg2rad(float(object_config.support_angle.value)); + this->interface_angle = Geometry::deg2rad(float(object_config.support_angle.value + 90.)); + this->interface_spacing = object_config.support_interface_spacing.value + this->support_material_interface_flow.spacing(); + this->interface_density = std::min(1., this->support_material_interface_flow.spacing() / this->interface_spacing); double raft_interface_spacing = object_config.support_interface_spacing.value + this->raft_interface_flow.spacing(); this->raft_interface_density = std::min(1., this->raft_interface_flow.spacing() / raft_interface_spacing); - double support_spacing = object_config.support_base_pattern_spacing.value + this->support_material_flow.spacing(); - this->support_density = std::min(1., this->support_material_flow.spacing() / support_spacing); + this->support_spacing = object_config.support_base_pattern_spacing.value + this->support_material_flow.spacing(); + this->support_density = std::min(1., this->support_material_flow.spacing() / this->support_spacing); if (object_config.support_interface_top_layers.value == 0) { // No interface layers allowed, print everything with the base support pattern. + this->interface_spacing = this->support_spacing; this->interface_density = this->support_density; } SupportMaterialPattern support_pattern = object_config.support_base_pattern; - this->with_sheath = /*is_tree(object_config.support_type) &&*/ object_config.tree_support_wall_count > 0; + this->with_sheath = object_config.tree_support_wall_count > 0; this->base_fill_pattern = support_pattern == smpHoneycomb ? ipHoneycomb : this->support_density > 0.95 || this->with_sheath ? ipRectilinear : ipSupportBase; @@ -115,9 +116,7 @@ struct SupportParameters { object_config.support_interface_pattern == smipConcentric ? ipConcentric : (this->interface_density > 0.95 ? ipRectilinear : ipSupportBase); - - this->base_angle = Geometry::deg2rad(float(object_config.support_angle.value)); - this->interface_angle = Geometry::deg2rad(float(object_config.support_angle.value + 90.)); + this->raft_angle_1st_layer = 0.f; this->raft_angle_base = 0.f; this->raft_angle_interface = 0.f; @@ -215,11 +214,13 @@ struct SupportParameters { float base_angle; float interface_angle; - + coordf_t interface_spacing; + coordf_t support_expansion=0; // Density of the top / bottom interface and contact layers. coordf_t interface_density; // Density of the raft interface and contact layers. coordf_t raft_interface_density; + coordf_t support_spacing; // Density of the base support layers. coordf_t support_density; SupportMaterialStyle support_style = smsDefault; @@ -235,7 +236,7 @@ struct SupportParameters { // Shall the sparse (base) layers be printed with a single perimeter line (sheath) for robustness? bool with_sheath; // Branches of organic supports with area larger than this threshold will be extruded with double lines. - double tree_branch_diameter_double_wall_area_scaled; + double tree_branch_diameter_double_wall_area_scaled = 0.25 * sqr(scaled(3.0)) * M_PI;; float raft_angle_1st_layer; float raft_angle_base; diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index 2a410e443f..37613bcb8c 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -1,23 +1,27 @@ #include -#include "MinimumSpanningTree.hpp" -#include "TreeSupport.hpp" -#include "Print.hpp" -#include "Layer.hpp" + +#include "ClipperUtils.hpp" +#include "Fill/FillBase.hpp" #include "Fill/FillBase.hpp" #include "Fill/FillConcentric.hpp" -#include "CurveAnalyzer.hpp" -#include "SVG.hpp" -#include "ShortestPath.hpp" #include "I18N.hpp" +#include "Layer.hpp" +#include "MinimumSpanningTree.hpp" +#include "Print.hpp" +#include "ShortestPath.hpp" +#include "SupportCommon.hpp" +#include "SVG.hpp" +#include "TreeSupportCommon.hpp" +#include "TreeSupport.hpp" +#include "TreeSupport3D.hpp" #include #include -#include "TreeSupport3D.hpp" -#include -#include -#include + #include +#include +#include #include #include @@ -1646,28 +1650,25 @@ void TreeSupport::generate() m_ts_data = m_object->alloc_tree_support_preview_cache(); m_ts_data->is_slim = is_slim; - // Generate contact points of tree support - std::vector> contact_nodes(m_object->layers().size()); - std::vector move_bounds(m_highest_overhang_layer + 1); profiler.stage_start(STAGE_GENERATE_CONTACT_NODES); m_object->print()->set_status(56, _u8L("Support: generate contact points")); - generate_contact_points(contact_nodes); + generate_contact_points(); profiler.stage_finish(STAGE_GENERATE_CONTACT_NODES); //Drop nodes to lower layers. profiler.stage_start(STAGE_DROP_DOWN_NODES); m_object->print()->set_status(60, _u8L("Generating support")); - drop_nodes(contact_nodes); + drop_nodes(); profiler.stage_finish(STAGE_DROP_DOWN_NODES); - smooth_nodes(contact_nodes); // , tree_support_3d_config); + smooth_nodes();// , tree_support_3d_config); //Generate support areas. profiler.stage_start(STAGE_DRAW_CIRCLES); m_object->print()->set_status(65, _u8L("Generating support")); - draw_circles(contact_nodes); + draw_circles(); profiler.stage_finish(STAGE_DRAW_CIRCLES); @@ -1714,7 +1715,6 @@ coordf_t TreeSupport::calc_branch_radius(coordf_t base_radius, coordf_t mm_to_to { radius = mm_to_top;// this is a 45 degree tip } - radius = std::max(radius, MIN_BRANCH_RADIUS); radius = std::min(radius, MAX_BRANCH_RADIUS); // if have interface layers, radius should be larger @@ -1876,7 +1876,7 @@ Polygons TreeSupport::get_trim_support_regions( return polygons_trimming; } -void TreeSupport::draw_circles(const std::vector>& contact_nodes) +void TreeSupport::draw_circles() { const PrintObjectConfig &config = m_object->config(); const Print* print = m_object->print(); @@ -1980,11 +1980,11 @@ void TreeSupport::draw_circles(const std::vector>& con } }; - BOOST_LOG_TRIVIAL(debug) << "circles at layer " << layer_nr << " contact nodes size=" << contact_nodes[layer_nr].size(); + BOOST_LOG_TRIVIAL(debug) << "circles at layer " << layer_nr << " contact nodes size=" << curr_layer_nodes.size(); //Draw the support areas and add the roofs appropriately to the support roof instead of normal areas. - ts_layer->lslices.reserve(contact_nodes[layer_nr].size()); + ts_layer->lslices.reserve(curr_layer_nodes.size()); ExPolygons area_poly; // the polygon node area which will be printed as normal support - for (const SupportNode* p_node : contact_nodes[layer_nr]) + for (const SupportNode* p_node : curr_layer_nodes) { if (print->canceled()) break; @@ -2366,7 +2366,7 @@ void TreeSupport::draw_circles(const std::vector>& con double SupportNode::diameter_angle_scale_factor; -void TreeSupport::drop_nodes(std::vector>& contact_nodes) +void TreeSupport::drop_nodes() { const PrintObjectConfig &config = m_object->config(); // Use Minimum Spanning Tree to connect the points on each layer and move them while dropping them down. @@ -2405,7 +2405,7 @@ void TreeSupport::drop_nodes(std::vector>& contact_nod return move_dist; }; - m_ts_data->layer_heights = plan_layer_heights(contact_nodes); + m_ts_data->layer_heights = plan_layer_heights(); std::vector &layer_heights = m_ts_data->layer_heights; if (layer_heights.empty()) return; @@ -2468,7 +2468,6 @@ void TreeSupport::drop_nodes(std::vector>& contact_nod coordf_t height_next = layer_heights[layer_nr_next].height; 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_support_layer(layer_nr); m_object->print()->set_status(60 + int(10 * (1 - float(layer_nr) / contact_nodes.size())), _u8L("Generating support"));// (boost::format(_u8L("Support: propagate branches at layer %d")) % layer_nr).str()); @@ -2731,7 +2730,7 @@ void TreeSupport::drop_nodes(std::vector>& contact_nod // 1. do not merge neighbors under 5mm // 2. Only merge node with single neighbor in distance between [max_move_distance, 10mm/layer_height] float dist2_to_first_neighbor = neighbours.empty() ? 0 : vsize2_with_unscale(neighbours[0] - node.position); - if (ts_layer->print_z > DO_NOT_MOVER_UNDER_MM && + if (node.print_z > DO_NOT_MOVER_UNDER_MM && (neighbours.size() > 1 || (neighbours.size() == 1 && dist2_to_first_neighbor >= max_move_distance2))) // Only nodes that aren't about to collapse. { // Move towards the average position of all neighbours. @@ -2747,7 +2746,7 @@ void TreeSupport::drop_nodes(std::vector>& contact_nod coordf_t branch_bottom_radius = calc_branch_radius(branch_radius, node.dist_mm_to_top + node.print_z, diameter_angle_scale_factor); coordf_t neighbour_bottom_radius = calc_branch_radius(branch_radius, neighbour_node->dist_mm_to_top + neighbour_node->print_z, diameter_angle_scale_factor); - double max_converge_distance = tan_angle * (ts_layer->print_z - DO_NOT_MOVER_UNDER_MM) + std::max(branch_bottom_radius, neighbour_bottom_radius); + double max_converge_distance = tan_angle * (p_node->print_z - DO_NOT_MOVER_UNDER_MM) + std::max(branch_bottom_radius, neighbour_bottom_radius); if (dist2_to_neighbor > max_converge_distance * max_converge_distance) continue; if (is_line_cut_by_contour(node.position, neighbour)) continue; @@ -2892,7 +2891,7 @@ void TreeSupport::drop_nodes(std::vector>& contact_nod BOOST_LOG_TRIVIAL(debug) << "after m_avoidance_cache.size()=" << m_ts_data->m_avoidance_cache.size(); } -void TreeSupport::smooth_nodes(std::vector> &contact_nodes) +void TreeSupport::smooth_nodes() { for (int layer_nr = 0; layer_nr < contact_nodes.size(); layer_nr++) { std::vector &curr_layer_nodes = contact_nodes[layer_nr]; @@ -2963,7 +2962,7 @@ void TreeSupport::smooth_nodes(std::vector> &contact_ } } -std::vector TreeSupport::plan_layer_heights(std::vector> &contact_nodes) +std::vector TreeSupport::plan_layer_heights() { std::vector layer_heights(contact_nodes.size()); std::map> bounds; // layer_nr:(print_z, height) @@ -3061,7 +3060,7 @@ std::vector TreeSupport::plan_layer_heights(std::vector>& contact_nodes) +void TreeSupport::generate_contact_points() { const PrintObjectConfig &config = m_object->config(); const coordf_t point_spread = scale_(config.tree_support_branch_distance.value); @@ -3119,8 +3118,11 @@ void TreeSupport::generate_contact_points(std::vector> // fix bug of generating support for very thin objects if (m_object->layers().size() <= z_distance_top_layers + 1) return; - //if (m_object->support_layer_count() <= m_raft_layers) - // return; + + contact_nodes.clear(); + contact_nodes.resize(m_object->layers().size()); + + tbb::spin_mutex mtx; int nonempty_layers = 0; tbb::concurrent_vector all_nodes; diff --git a/src/libslic3r/Support/TreeSupport.hpp b/src/libslic3r/Support/TreeSupport.hpp index b8d4bdbbba..f94fd57020 100644 --- a/src/libslic3r/Support/TreeSupport.hpp +++ b/src/libslic3r/Support/TreeSupport.hpp @@ -379,7 +379,7 @@ public: int avg_node_per_layer = 0; - float nodes_angle = 0; + float nodes_angle = 0; bool has_sharp_tails = false; bool has_cantilever = false; double max_cantilever_dist = 0; @@ -405,11 +405,11 @@ private: * Lazily computes volumes as needed. * \warning This class is NOT currently thread-safe and should not be accessed in OpenMP blocks */ + std::vector> contact_nodes; std::shared_ptr m_ts_data; - std::unique_ptr m_model_volumes; PrintObject *m_object; - const PrintObjectConfig *m_object_config; + const PrintObjectConfig* m_object_config; SlicingParameters m_slicing_params; // Various precomputed support parameters to be shared with external functions. SupportParameters m_support_params; @@ -441,7 +441,7 @@ private: * save the resulting support polygons to. * \param contact_nodes The nodes to draw as support. */ - void draw_circles(const std::vector>& contact_nodes); + void draw_circles(); /*! * \brief Drops down the nodes of the tree support towards the build plate. @@ -455,16 +455,16 @@ private: * dropped down. The nodes are dropped to lower layers inside the same * vector of layers. */ - void drop_nodes(std::vector>& contact_nodes); + void drop_nodes(); - void smooth_nodes(std::vector>& contact_nodes); + void smooth_nodes(); /*! BBS: MusangKing: maximum layer height * \brief Optimize the generation of tree support by pre-planning the layer_heights * */ - std::vector plan_layer_heights(std::vector>& contact_nodes); + std::vector plan_layer_heights(); /*! * \brief Creates points where support contacts the model. * @@ -478,7 +478,7 @@ private: * \return For each layer, a list of points where the tree should connect * with the model. */ - void generate_contact_points(std::vector>& contact_nodes); + void generate_contact_points(); /*! * \brief Add a node to the next layer. diff --git a/src/libslic3r/Support/TreeSupport3D.cpp b/src/libslic3r/Support/TreeSupport3D.cpp index 8773cae565..22505d4f92 100644 --- a/src/libslic3r/Support/TreeSupport3D.cpp +++ b/src/libslic3r/Support/TreeSupport3D.cpp @@ -7,22 +7,22 @@ // CuraEngine is released under the terms of the AGPLv3 or higher. #include "TreeSupport3D.hpp" - -#include "../AABBTreeIndirect.hpp" -#include "../BuildVolume.hpp" -#include "../ClipperUtils.hpp" -#include "../EdgeGrid.hpp" -#include "../Fill/Fill.hpp" -#include "../Layer.hpp" -#include "../Print.hpp" -#include "../MultiPoint.hpp" -#include "../Polygon.hpp" -#include "../Polyline.hpp" -#include "../MutablePolygon.hpp" -#include "TreeSupportCommon.hpp" +#include "AABBTreeIndirect.hpp" +#include "AABBTreeLines.hpp" +#include "BuildVolume.hpp" +#include "ClipperUtils.hpp" +#include "EdgeGrid.hpp" +#include "Fill/Fill.hpp" +#include "Layer.hpp" +#include "Print.hpp" +#include "MultiPoint.hpp" +#include "Polygon.hpp" +#include "Polyline.hpp" +#include "MutablePolygon.hpp" #include "SupportCommon.hpp" +#include "TriangleMeshSlicer.hpp" #include "TreeSupport.hpp" -#include "libslic3r.h" +#include "I18N.hpp" #include #include @@ -49,7 +49,11 @@ #include #endif // TREE_SUPPORT_ORGANIC_NUDGE_NEW -// #define TREESUPPORT_DEBUG_SVG +#ifndef _L +#define _L(s) Slic3r::I18N::translate(s) +#endif + + //#define TREESUPPORT_DEBUG_SVG namespace Slic3r { @@ -57,16 +61,6 @@ namespace Slic3r namespace TreeSupport3D { -enum class LineStatus -{ - INVALID, - TO_MODEL, - TO_MODEL_GRACIOUS, - TO_MODEL_GRACIOUS_SAFE, - TO_BP, - TO_BP_SAFE -}; - using LineInformation = std::vector>; using LineInformations = std::vector; using namespace std::literals; @@ -363,6 +357,28 @@ static std::vector>> group_me return max_layer; } +// picked from convert_lines_to_internal() +[[nodiscard]] LineStatus get_avoidance_status(const Point& p, coord_t radius, LayerIndex layer_idx, + const TreeModelVolumes& volumes, const TreeSupportSettings& config) +{ + const bool min_xy_dist = config.xy_distance > config.xy_min_distance; + + LineStatus type = LineStatus::INVALID; + + if (!contains(volumes.getAvoidance(radius, layer_idx, TreeModelVolumes::AvoidanceType::FastSafe, false, min_xy_dist), p)) + type = LineStatus::TO_BP_SAFE; + else if (!contains(volumes.getAvoidance(radius, layer_idx, TreeModelVolumes::AvoidanceType::Fast, false, min_xy_dist), p)) + type = LineStatus::TO_BP; + else if (config.support_rests_on_model && !contains(volumes.getAvoidance(radius, layer_idx, TreeModelVolumes::AvoidanceType::FastSafe, true, min_xy_dist), p)) + type = LineStatus::TO_MODEL_GRACIOUS_SAFE; + else if (config.support_rests_on_model && !contains(volumes.getAvoidance(radius, layer_idx, TreeModelVolumes::AvoidanceType::Fast, true, min_xy_dist), p)) + type = LineStatus::TO_MODEL_GRACIOUS; + else if (config.support_rests_on_model && !contains(volumes.getCollision(radius, layer_idx, min_xy_dist), p)) + type = LineStatus::TO_MODEL; + + return type; +} + /*! * \brief Converts a Polygons object representing a line into the internal format. * @@ -1942,7 +1958,7 @@ static void increase_areas_one_layer( inc_wo_collision.clear(); if (!settings.no_error) { // ERROR CASE - // if the area becomes for whatever reason something that clipper sees as a line, offset would stop working, so ensure that even if if wrongly would be a line, it still actually has an area that can be increased + // if the area becomes for whatever reason something that clipper sees as a line, offset would stop working, so ensure that even if it would be a line wrongly, it still actually has an area that can be increased Polygons lines_offset = offset(to_polylines(parent.influence_area), scaled(0.005), jtMiter, 1.2); Polygons base_error_area = union_(parent.influence_area, lines_offset); result = increase_single_area(volumes, config, settings, layer_idx, parent, @@ -3321,7 +3337,7 @@ static void organic_smooth_branches_avoid_collisions( * \param storage The data storage where the mesh data is gotten from and * where the resulting support areas are stored. */ -static void generate_support_areas(Print &print, const BuildVolume &build_volume, const std::vector &print_object_ids, std::function throw_on_cancel) +static void generate_support_areas(Print &print, TreeSupport* tree_support, const BuildVolume &build_volume, const std::vector &print_object_ids, std::function throw_on_cancel) { // Settings with the indexes of meshes that use these settings. std::vector>> grouped_meshes = group_meshes(print, print_object_ids); @@ -3985,7 +4001,7 @@ void generate_tree_support_3D(PrintObject &print_object, TreeSupport* tree_suppo std::transform(bedpts.begin(), bedpts.end(), std::back_inserter(bedptsf), [](const Point &p) { return unscale(p); }); BuildVolume build_volume{ bedptsf, tree_support->m_print_config->printable_height }; - TreeSupport3D::generate_support_areas(*print_object.print(), build_volume, { idx }, throw_on_cancel); + TreeSupport3D::generate_support_areas(*print_object.print(), tree_support, build_volume, { idx }, throw_on_cancel); } } // namespace Slic3r diff --git a/src/libslic3r/Support/TreeSupport3D.hpp b/src/libslic3r/Support/TreeSupport3D.hpp index ba543fbc81..1e58743c25 100644 --- a/src/libslic3r/Support/TreeSupport3D.hpp +++ b/src/libslic3r/Support/TreeSupport3D.hpp @@ -47,8 +47,6 @@ struct SlicingParameters; namespace TreeSupport3D { -// The number of vertices in each circle. -static constexpr const size_t SUPPORT_TREE_CIRCLE_RESOLUTION = 25; struct AreaIncreaseSettings { diff --git a/src/libslic3r/Support/TreeSupportCommon.hpp b/src/libslic3r/Support/TreeSupportCommon.hpp index b382f6526c..3122a43d2d 100644 --- a/src/libslic3r/Support/TreeSupportCommon.hpp +++ b/src/libslic3r/Support/TreeSupportCommon.hpp @@ -17,10 +17,10 @@ namespace Slic3r { - + // The number of vertices in each circle. + static constexpr const size_t SUPPORT_TREE_CIRCLE_RESOLUTION = 25; namespace TreeSupport3D { - using LayerIndex = int; enum class InterfacePreference @@ -40,18 +40,18 @@ struct TreeSupportMeshGroupSettings { const PrintObjectConfig &config = print_object.config(); const SlicingParameters &slicing_params = print_object.slicing_parameters(); // const std::vector printing_extruders = print_object.object_extruders(); - + // Support must be enabled and set to Tree style. - assert(config.enable_support || config.enforce_support_layers > 0); - assert(is_tree(config.support_type)); - + //assert(config.support_material); + //assert(config.support_material_style == smsTree || config.support_material_style == smsOrganic); + // Calculate maximum external perimeter width over all printing regions, taking into account the default layer height. coordf_t external_perimeter_width = 0.; for (size_t region_id = 0; region_id < print_object.num_printing_regions(); ++ region_id) { const PrintRegion ®ion = print_object.printing_region(region_id); external_perimeter_width = std::max(external_perimeter_width, region.flow(print_object, frExternalPerimeter, config.layer_height).width()); } - + this->layer_height = scaled(config.layer_height.value); this->resolution = scaled(print_config.resolution.value); // Arache feature @@ -74,24 +74,15 @@ struct TreeSupportMeshGroupSettings { this->support_xy_distance_overhang = std::min(this->support_xy_distance, scaled(0.5 * external_perimeter_width)); this->support_top_distance = scaled(slicing_params.gap_support_object); this->support_bottom_distance = scaled(slicing_params.gap_object_support); - // this->support_interface_skip_height = - // this->support_infill_angles = this->support_roof_enable = config.support_interface_top_layers.value > 0; - this->support_roof_layers = this->support_roof_enable ? config.support_interface_top_layers.value : 0; - this->support_floor_enable = config.support_interface_top_layers.value > 0 && config.support_interface_bottom_layers.value > 0; - this->support_floor_layers = this->support_floor_enable ? config.support_interface_bottom_layers.value : 0; - // this->minimum_roof_area = - // this->support_roof_angles = + this->support_roof_layers = config.support_interface_top_layers.value; + this->support_floor_enable = config.support_interface_bottom_layers.value > 0; + this->support_floor_layers = config.support_interface_bottom_layers.value; this->support_roof_pattern = config.support_interface_pattern; this->support_pattern = config.support_base_pattern; this->support_line_spacing = scaled(config.support_base_pattern_spacing.value); - // this->support_bottom_offset = - // this->support_wall_count = config.support_material_with_sheath ? 1 : 0; - this->support_wall_count = 1; + this->support_wall_count = std::max(1, config.tree_support_wall_count.value); // at least 1 wall for organic tree support this->support_roof_line_distance = scaled(config.support_interface_spacing.value) + this->support_roof_line_width; - // this->minimum_support_area = - // this->minimum_bottom_area = - // this->support_offset = this->support_tree_branch_distance = scaled(config.tree_support_branch_distance_organic.value); this->support_tree_angle = std::clamp(config.tree_support_branch_angle_organic * M_PI / 180., 0., 0.5 * M_PI - EPSILON); this->support_tree_angle_slow = std::clamp(config.tree_support_angle_slow * M_PI / 180., 0., this->support_tree_angle - EPSILON); @@ -100,26 +91,6 @@ struct TreeSupportMeshGroupSettings { this->support_tree_top_rate = config.tree_support_top_rate.value; // percent // this->support_tree_tip_diameter = this->support_line_width; this->support_tree_tip_diameter = std::clamp(scaled(config.tree_support_tip_diameter.value), (coord_t)0, this->support_tree_branch_diameter); - - std::cout << "\n---------------\n" - << "layer_height: " << layer_height << "\nresolution: " << resolution << "\nmin_feature_size: " << min_feature_size - << "\nsupport_angle: " << support_angle << "\nconfig.support_threshold_angle: " << config.support_threshold_angle << "\nsupport_line_width: " << support_line_width - << "\nsupport_roof_line_width: " << support_roof_line_width << "\nsupport_bottom_enable: " << support_bottom_enable - << "\nsupport_bottom_height: " << support_bottom_height - << "\nsupport_material_buildplate_only: " << support_material_buildplate_only - << "\nsupport_xy_distance: " << support_xy_distance << "\nsupport_xy_distance_overhang: " << support_xy_distance_overhang - << "\nsupport_top_distance: " << support_top_distance << "\nsupport_bottom_distance: " << support_bottom_distance - << "\nsupport_roof_enable: " << support_roof_enable << "\nsupport_roof_layers: " << support_roof_layers - << "\nsupport_floor_enable: " << support_floor_enable << "\nsupport_floor_layers: " << support_floor_layers - << "\nsupport_roof_pattern: " << support_roof_pattern << "\nsupport_pattern: " << support_pattern - << "\nsupport_line_spacing: " << support_line_spacing << "\nsupport_wall_count: " << support_wall_count - << "\nsupport_roof_line_distance: " << support_roof_line_distance - << "\nsupport_tree_branch_distance: " << support_tree_branch_distance - << "\nsupport_tree_angle_slow: " << support_tree_angle_slow - << "\nsupport_tree_branch_diameter: " << support_tree_branch_diameter - << "\nsupport_tree_branch_diameter_angle: " << support_tree_branch_diameter_angle - << "\nsupport_tree_top_rate: " << support_tree_top_rate << "\nsupport_tree_tip_diameter: " << support_tree_tip_diameter - << "\n---------------\n"; } /*********************************************************************/ @@ -768,6 +739,17 @@ private: std::mutex m_mutex_layer_storage; }; +enum class LineStatus +{ + INVALID, + TO_MODEL, + TO_MODEL_GRACIOUS, + TO_MODEL_GRACIOUS_SAFE, + TO_BP, + TO_BP_SAFE +}; + + } // namespace TreeSupport3D } // namespace Slic3r diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 05822fdfdb..4ae655c2cf 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1496,43 +1496,6 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) m_config_manipulation.apply(m_config, &new_conf); } - // BBS popup a message to ask the user to set optimum parameters for tree support - if (opt_key == "support_type" || opt_key == "support_style") { - if (is_tree_slim(m_config->opt_enum("support_type"), m_config->opt_enum("support_style")) && - !(m_config->opt_float("support_top_z_distance") == 0 && m_config->opt_int("support_interface_top_layers") == 0 && m_config->opt_int("tree_support_wall_count") == 2)) { - wxString msg_text = _L("We have added an experimental style \"Tree Slim\" that features smaller support volume but weaker strength.\n" - "We recommend using it with: 0 interface layers, 0 top distance, 2 walls."); - msg_text += "\n\n" + _L("Change these settings automatically? \n" - "Yes - Change these settings automatically\n" - "No - Do not change these settings for me"); - MessageDialog dialog(wxGetApp().plater(), msg_text, "Suggestion", wxICON_WARNING | wxYES | wxNO); - DynamicPrintConfig new_conf = *m_config; - if (dialog.ShowModal() == wxID_YES) { - new_conf.set_key_value("support_top_z_distance", new ConfigOptionFloat(0)); - new_conf.set_key_value("support_interface_top_layers", new ConfigOptionInt(0)); - new_conf.set_key_value("tree_support_wall_count", new ConfigOptionInt(2)); - m_config_manipulation.apply(m_config, &new_conf); - } - wxGetApp().plater()->update(); - } else if ((m_config->opt_enum("support_type")==stTreeAuto && (m_config->opt_enum("support_style")==smsTreeStrong || m_config->opt_enum("support_style") == smsTreeHybrid)) && - !((m_config->opt_float("support_top_z_distance") >=0.1 || is_support_filament(m_config->opt_int("support_interface_filament") - 1)) - && m_config->opt_int("support_interface_top_layers") >1) ) { - wxString msg_text = _L("For \"Tree Strong\" and \"Tree Hybrid\" styles, we recommend the following settings: at least 2 interface layers, at least 0.1mm top z distance or using support materials on interface."); - msg_text += "\n\n" + _L("Change these settings automatically? \n" - "Yes - Change these settings automatically\n" - "No - Do not change these settings for me"); - MessageDialog dialog(wxGetApp().plater(), msg_text, "Suggestion", wxICON_WARNING | wxYES | wxNO); - DynamicPrintConfig new_conf = *m_config; - if (dialog.ShowModal() == wxID_YES) { - if (!is_support_filament(m_config->opt_int("support_interface_filament") - 1) && m_config->opt_float("support_top_z_distance") < 0.1) - new_conf.set_key_value("support_top_z_distance", new ConfigOptionFloat(0.2)); - new_conf.set_key_value("support_interface_top_layers", new ConfigOptionInt(2)); - m_config_manipulation.apply(m_config, &new_conf); - } - wxGetApp().plater()->update(); - } - } - // BBS popup a message to ask the user to set optimum parameters for support interface if support materials are used if (opt_key == "support_interface_filament") { int interface_filament_id = m_config->opt_int("support_interface_filament") - 1; // the displayed id is based from 1, while internal id is based from 0