2188{
2189#ifdef SLIC3R_DEBUG
2190 static int iRun = 0;
2191 ++ iRun;
2192 #define SLIC3R_IRUN , iRun
2193#endif
2194
2195
2196
2199 }
2200
2201
2203
2204
2206
2207 BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::top_contact_layers() in parallel - start";
2208
2209
2210
2211
2212
2213 size_t num_layers = this->
has_support() ?
object.layer_count() : 1;
2214
2215
2216 contact_out.assign(num_layers * 2, nullptr);
2217
2218 std::vector<ExPolygons> overhangs_per_layers(num_layers);
2219 size_t layer_id_start = this->
has_raft() ? 0 : 1;
2220
2221 tbb::parallel_for(tbb::blocked_range<size_t>(layer_id_start, num_layers),
2222 [&](
const tbb::blocked_range<size_t>&
range) {
2223 for (
size_t layer_id =
range.begin(); layer_id <
range.end(); layer_id++) {
2224 const Layer& layer = *object.layers()[layer_id];
2226
2228#ifdef SLIC3R_DEBUG
2229 , iRun
2230#endif
2231 );
2232
2233 if (object.print()->canceled())
2234 break;
2235 }
2236 }
2237 );
2238
2239 if (object.print()->canceled())
2241
2242
2243 bool detect_first_sharp_tail_only = false;
2247 for (size_t layer_nr = layer_id_start; layer_nr < num_layers; layer_nr++) {
2248 if (object.print()->canceled())
2249 break;
2250
2251 const Layer* layer = object.get_layer(layer_nr);
2252 const Layer* lower_layer = layer->lower_layer;
2253 if (!lower_layer)
2254 continue;
2255
2256
2257 const ExPolygons& lower_layer_sharptails = lower_layer->sharp_tails;
2258 const auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height;
2259 for (const ExPolygon& expoly : layer->lslices) {
2260 bool is_sharp_tail = false;
2261 float accum_height = layer->height;
2262 do {
2263
2264
2265
2266
2268 if (supported_by_lower.empty()) {
2269 is_sharp_tail = false;
2270 break;
2271 }
2272
2273
2274#if 0
2275
2276 float supported_area =
area(supported_by_lower);
2278 is_sharp_tail = false;
2279 break;
2280 }
2281#endif
2282 BoundingBox bbox =
get_extents(supported_by_lower);
2284 is_sharp_tail = false;
2285 break;
2286 }
2287
2288
2289 for (size_t i = 0; i < lower_layer_sharptails_height.size();i++) {
2290 if (lower_layer_sharptails[i].
overlaps(expoly)) {
2291 accum_height += lower_layer_sharptails_height[i];
2292 break;
2293 }
2294 }
2296 is_sharp_tail = false;
2297 break;
2298 }
2299
2300
2301
2305 is_sharp_tail = false;
2306 break;
2307 }
2308
2309
2310 is_sharp_tail = true;
2311 } while (0);
2312
2313 if (is_sharp_tail) {
2315 layer->sharp_tails.push_back(expoly);
2316 layer->sharp_tails_height.push_back( accum_height );
2317
2318
2319 if (!annotations.blockers_layers.empty() && !annotations.blockers_layers[layer_nr].empty()) {
2320 const auto& blocker = annotations.blockers_layers[layer_nr];
2321 overhang =
diff_ex(overhang, blocker);
2322 }
2323
2324 append(overhangs_per_layers[layer_nr], overhang);
2325 }
2326
2327 }
2328 }
2329 }
2330
2331 if (object.print()->canceled())
2333
2334
2335 const bool config_remove_small_overhangs =
m_object_config->support_remove_small_overhang.value;
2336 if (config_remove_small_overhangs) {
2337 std::vector<OverhangCluster> clusters;
2338 double fw_scaled =
scale_(extrusion_width);
2339 std::set<ExPolygon*> removed_overhang;
2340
2341 for (size_t layer_id = layer_id_start; layer_id < num_layers; layer_id++) {
2342 const Layer* layer = object.get_layer(layer_id);
2343 for (auto& overhang : overhangs_per_layers[layer_id]) {
2345 if (
overlaps({ overhang }, layer->cantilevers))
2346 cluster->is_cantilever =
true;
2347 }
2348 }
2349
2350 for (OverhangCluster& cluster : clusters) {
2351
2352 cluster.is_sharp_tail =
false;
2353 for (
size_t layer_id =
cluster.min_layer; layer_id <=
cluster.max_layer; layer_id++) {
2354 const Layer* layer = object.get_layer(layer_id);
2357 break;
2358 }
2359 }
2360
2362
2363 cluster.is_small_overhang =
false;
2364 auto erode1 =
offset_ex(
cluster.merged_overhangs_dilated, -1.0 * fw_scaled);
2366 if (bbox_sz.x() < 2 * fw_scaled || bbox_sz.y() < 2 * fw_scaled) {
2367 cluster.is_small_overhang =
true;
2368 }
2369 }
2370
2371#ifdef SUPPORT_TREE_DEBUG_TO_SVG
2372 const Layer* layer1 =
object.get_layer(
cluster.min_layer);
2375 SVG svg(
format(
"SVG/overhangCluster_%s_%s_tail=%s_cantilever=%s_small=%s.svg",
cluster.min_layer, layer1->print_z,
cluster.is_sharp_tail,
cluster.is_cantilever,
cluster.is_small_overhang), bbox);
2376 if (svg.is_opened()) {
2377 svg.draw(layer1->lslices, "red");
2378 svg.draw(
cluster.merged_overhangs_dilated,
"blue");
2379 }
2380#endif
2381
2382
2383 if (
cluster.is_small_overhang) {
2384 for (
auto overhangs :
cluster.layer_overhangs) {
2385 for (auto* poly : overhangs.second)
2386 removed_overhang.insert(poly);
2387 }
2388 }
2389 }
2390
2391 for (size_t layer_id = layer_id_start; layer_id < num_layers; layer_id++) {
2392 auto& layer_overhangs = overhangs_per_layers[layer_id];
2393 if (layer_overhangs.empty())
2394 continue;
2395
2396 for (int poly_idx = 0; poly_idx < layer_overhangs.size(); poly_idx++) {
2397 auto* overhang = &layer_overhangs[poly_idx];
2398 if (removed_overhang.find(overhang) != removed_overhang.end()) {
2399 overhang->clear();
2400 }
2401 }
2402 }
2403 }
2404
2405 if (object.print()->canceled())
2407
2408 for (size_t layer_id = layer_id_start; layer_id < num_layers; layer_id++) {
2409 const Layer& layer = *object.layers()[layer_id];
2412 SlicesMarginCache slices_margin;
2413
2414 auto [contact_polygons, enforcer_polygons, no_interface_offset] =
2416#ifdef SLIC3R_DEBUG
2417 , iRun
2418#endif
2419 );
2420
2421
2422 if (!contact_polygons.empty() || !overhang_polygons.empty()) {
2423
2425 if (new_layer) {
2426
2428 *
m_object_config, slices_margin, overhang_polygons, contact_polygons, enforcer_polygons, lower_layer_polygons,
2430#ifdef SLIC3R_DEBUG
2431 , iRun, layer
2432#endif
2433 );
2434
2435
2436
2437 contact_out[layer_id * 2] = new_layer;
2438 if (bridging_layer != nullptr) {
2439 bridging_layer->polygons = new_layer->polygons;
2440 bridging_layer->contact_polygons = std::make_unique<Polygons>(*new_layer->contact_polygons);
2441 bridging_layer->overhang_polygons = std::make_unique<Polygons>(*new_layer->overhang_polygons);
2442 if (new_layer->enforcer_polygons)
2443 bridging_layer->enforcer_polygons = std::make_unique<Polygons>(*new_layer->enforcer_polygons);
2444 contact_out[layer_id * 2 + 1] = bridging_layer;
2445 }
2446 }
2447 }
2448 }
2449
2450
2452
2453
2454
2456
2457 BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::top_contact_layers() in parallel - end";
2458
2459 return contact_out;
2460}
PointType size() const
Definition BoundingBox.cpp:178
bool has_raft() const
Definition SupportMaterial.hpp:28
static constexpr bool g_config_support_sharp_tails
Definition libslic3r.h:116
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
ClusteredPoints cluster(Index3D &sindex, unsigned max_points, std::function< std::vector< PointIndexEl >(const Index3D &, const PointIndexEl &)> qfn)
Definition Clustering.cpp:27
static const double area_thresh_well_supported
Definition SupportMaterial.cpp:1441
static ExPolygons detect_overhangs(const Layer &layer, const size_t layer_id, Polygons &lower_layer_polygons, const PrintConfig &print_config, const PrintObjectConfig &object_config, SupportAnnotations &annotations, const double gap_xy)
Definition SupportMaterial.cpp:1448
Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:831
std::vector< ExPolygon > ExPolygons
Definition ExPolygon.hpp:20
static const double length_thresh_well_supported
Definition SupportMaterial.cpp:1440
BoundingBox get_extents(const ExPolygonsWithIds &e)
Definition Emboss.cpp:1374
double area(const ExPolygon &poly)
Definition ExPolygon.hpp:511
bool is_auto(SupportType stype)
Definition PrintConfig.hpp:389
static void merge_contact_layers(const SlicingParameters &slicing_params, double support_layer_height_min, SupportGeneratorLayersPtr &layers)
Definition SupportMaterial.cpp:2071
double nozzle_diameter_for_filament(const PrintConfig &config, int filament_id, bool is_bbl_printer)
Definition PrintConfig.cpp:148
static void fill_contact_layer(SupportGeneratorLayer &new_layer, size_t layer_id, const SlicingParameters &slicing_params, const PrintObjectConfig &object_config, const SlicesMarginCache &slices_margin, const Polygons &overhang_polygons, const Polygons &contact_polygons, const Polygons &enforcer_polygons, const Polygons &lower_layer_polygons, const Flow &support_material_flow, float no_interface_offset)
Definition SupportMaterial.cpp:1918
Polygons to_polygons(const ExPolygon &src)
Definition ExPolygon.hpp:307
static const double sharp_tail_max_support_height
Definition SupportMaterial.cpp:1444
Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:605
Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:878
@ stNormalAuto
Definition PrintConfig.hpp:379
@ stNormal
Definition PrintConfig.hpp:379
void remove_nulls(std::vector< T * > &vec)
Definition libslic3r.h:223
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:45
static OverhangCluster * add_overhang(std::vector< OverhangCluster > &clusters, ExPolygon *overhang, int layer_nr, coordf_t offset_scaled)
Definition SupportMaterial.cpp:2166
bool overlaps(const ExPolygons &expolys1, const ExPolygons &expolys2)
Definition ExPolygon.cpp:192
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:157
static std::pair< SupportGeneratorLayer *, SupportGeneratorLayer * > new_contact_layer(const PrintConfig &print_config, const PrintObjectConfig &object_config, const SlicingParameters &slicing_params, const coordf_t support_layer_height_min, const Layer &layer, SupportGeneratorLayerStorage &layer_storage)
Definition SupportMaterial.cpp:1814
static std::tuple< Polygons, Polygons, double > detect_contacts(const Layer &layer, const size_t layer_id, Polygons &overhang_polygons, Polygons &lower_layer_polygons, const PrintConfig &print_config, const PrintObjectConfig &object_config, SupportAnnotations &annotations, SlicesMarginCache &slices_margin, const double gap_xy)
Definition SupportMaterial.cpp:1642