Files
OrcaSlicer/src/libslic3r/Support/SupportCommon.hpp
T
harrierpigeonandClaude Fable 5.1 9dbd0307f8 Add the includes clang-tidy's include cleaner asks for on the belt files
The clang-tidy job on #14394 fails on 129 misc-include-cleaner findings:
the belt sources and tests use std::, Eigen, Point/PrintConfig and
BeltBrim symbols without including the header that provides them, which
only compiled because the precompiled header supplied it. Every include
the job names is added, in each file's existing include style ("../" in
the GCode/ and Support/ subdirectories, quoted libslic3r/ paths in the
GUI and tests). No code changes.

Verified with scripts/clang_tidy_diff.py -p build-tidy --base eb5b9a77b9
(SLIC3R_PCH=OFF compile database, clang-tidy 22.1.8): no findings left.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6Kg5igmmMU2YLoK6HrsWV
2026-10-05 20:43:18 -05:00

170 lines
7.3 KiB
C++

#ifndef slic3r_SupportCommon_hpp_
#define slic3r_SupportCommon_hpp_
#include "../Polygon.hpp"
#include "../Print.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/ExtrusionEntity.hpp"
#include "SupportLayer.hpp"
#include "SupportParameters.hpp"
#include "../Point.hpp"
#include "../libslic3r.h"
#include <utility>
#include <algorithm>
#include <vector>
namespace Slic3r { class Fill; }
namespace Slic3r { class Flow; }
namespace Slic3r { struct SlicingParameters; }
namespace Slic3r {
class PrintObject;
class SupportLayer;
// Turn some of the base layers into base interface layers.
// For soluble interfaces with non-soluble bases, print maximum two first interface layers with the base
// extruder to improve adhesion of the soluble filament to the base.
// For Organic supports, merge top_interface_layers & top_base_interface_layers with the interfaces
// produced by this function.
std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interface_layers(
const PrintObjectConfig &config,
const SupportParameters &support_params,
const SupportGeneratorLayersPtr &bottom_contacts,
const SupportGeneratorLayersPtr &top_contacts,
// Input / output, will be merged with output
SupportGeneratorLayersPtr &top_interface_layers,
SupportGeneratorLayersPtr &top_base_interface_layers,
// Input, will be trimmed with the newly created interface layers.
SupportGeneratorLayersPtr &intermediate_layers,
SupportGeneratorLayerStorage &layer_storage);
// Generate raft layers, also expand the 1st support layer
// in case there is no raft layer to improve support adhesion.
SupportGeneratorLayersPtr generate_raft_base(
const PrintObject &object,
const SupportParameters &support_params,
const SlicingParameters &slicing_params,
const SupportGeneratorLayersPtr &top_contacts,
const SupportGeneratorLayersPtr &interface_layers,
const SupportGeneratorLayersPtr &base_interface_layers,
const SupportGeneratorLayersPtr &base_layers,
SupportGeneratorLayerStorage &layer_storage);
void tree_supports_generate_paths(ExtrusionEntitiesPtr &dst, const Polygons &polygons, const Flow &flow, const SupportParameters &support_params);
void fill_expolygons_with_sheath_generate_paths(
ExtrusionEntitiesPtr &dst, const Polygons &polygons, Fill *filler, float density, ExtrusionRole role, const Flow &flow, const SupportParameters& support_params, bool with_sheath, bool no_sort);
// returns sorted layers
SupportGeneratorLayersPtr generate_support_layers(
PrintObject &object,
const SupportGeneratorLayersPtr &raft_layers,
const SupportGeneratorLayersPtr &bottom_contacts,
const SupportGeneratorLayersPtr &top_contacts,
const SupportGeneratorLayersPtr &intermediate_layers,
const SupportGeneratorLayersPtr &interface_layers,
const SupportGeneratorLayersPtr &base_interface_layers);
// Produce the support G-code.
// Used by both classic and tree supports.
void generate_support_toolpaths(
SupportLayerPtrs &support_layers,
const PrintObjectConfig &config,
const SupportParameters &support_params,
const SlicingParameters &slicing_params,
const SupportGeneratorLayersPtr &raft_layers,
const SupportGeneratorLayersPtr &bottom_contacts,
const SupportGeneratorLayersPtr &top_contacts,
const SupportGeneratorLayersPtr &intermediate_layers,
const SupportGeneratorLayersPtr &interface_layers,
const SupportGeneratorLayersPtr &base_interface_layers);
// FN_HIGHER_EQUAL: the provided object pointer has a Z value >= of an internal threshold.
// Find the first item with Z value >= of an internal threshold of fn_higher_equal.
// If no vec item with Z value >= of an internal threshold of fn_higher_equal is found, return vec.size()
// If the initial idx is size_t(-1), then use binary search.
// Otherwise search linearly upwards.
template<typename IteratorType, typename IndexType, typename FN_HIGHER_EQUAL>
IndexType idx_higher_or_equal(IteratorType begin, IteratorType end, IndexType idx, FN_HIGHER_EQUAL fn_higher_equal)
{
auto size = int(end - begin);
if (size == 0) {
idx = 0;
} else if (idx == IndexType(-1)) {
// First of the batch of layers per thread pool invocation. Use binary search.
int idx_low = 0;
int idx_high = std::max(0, size - 1);
while (idx_low + 1 < idx_high) {
int idx_mid = (idx_low + idx_high) / 2;
if (fn_higher_equal(begin[idx_mid]))
idx_high = idx_mid;
else
idx_low = idx_mid;
}
idx = fn_higher_equal(begin[idx_low]) ? idx_low :
(fn_higher_equal(begin[idx_high]) ? idx_high : size);
} else {
// For the other layers of this batch of layers, search incrementally, which is cheaper than the binary search.
while (int(idx) < size && ! fn_higher_equal(begin[idx]))
++ idx;
}
return idx;
}
template<typename T, typename IndexType, typename FN_HIGHER_EQUAL>
IndexType idx_higher_or_equal(const std::vector<T>& vec, IndexType idx, FN_HIGHER_EQUAL fn_higher_equal)
{
return idx_higher_or_equal(vec.begin(), vec.end(), idx, fn_higher_equal);
}
// FN_LOWER_EQUAL: the provided object pointer has a Z value <= of an internal threshold.
// Find the first item with Z value <= of an internal threshold of fn_lower_equal.
// If no vec item with Z value <= of an internal threshold of fn_lower_equal is found, return -1.
// If the initial idx is < -1, then use binary search.
// Otherwise search linearly downwards.
template<typename IT, typename FN_LOWER_EQUAL>
int idx_lower_or_equal(IT begin, IT end, int idx, FN_LOWER_EQUAL fn_lower_equal)
{
auto size = int(end - begin);
if (size == 0) {
idx = -1;
} else if (idx < -1) {
// First of the batch of layers per thread pool invocation. Use binary search.
int idx_low = 0;
int idx_high = std::max(0, size - 1);
while (idx_low + 1 < idx_high) {
int idx_mid = (idx_low + idx_high) / 2;
if (fn_lower_equal(begin[idx_mid]))
idx_low = idx_mid;
else
idx_high = idx_mid;
}
idx = fn_lower_equal(begin[idx_high]) ? idx_high :
(fn_lower_equal(begin[idx_low ]) ? idx_low : -1);
} else {
// For the other layers of this batch of layers, search incrementally, which is cheaper than the binary search.
while (idx >= 0 && ! fn_lower_equal(begin[idx]))
-- idx;
}
return idx;
}
template<typename T, typename FN_LOWER_EQUAL>
int idx_lower_or_equal(const std::vector<T*> &vec, int idx, FN_LOWER_EQUAL fn_lower_equal)
{
return idx_lower_or_equal(vec.begin(), vec.end(), idx, fn_lower_equal);
}
// Belt floor: compute the belt-side half-plane polygon at a given print_z.
// Used to clip support polygons against the belt surface.
Polygons belt_floor_surface_polygon(
const SlicingParameters &slicing_params, const PrintConfig &print_config,
const PrintObject &object, coordf_t print_z);
// Build plate tilt: XY drift of gravity per unit of layer height, zero on a level plate.
// The tilt is capped below 90 degrees to keep the drift finite.
Vec2d build_plate_tilt_slope(const PrintConfig &print_config);
} // namespace Slic3r
#endif /* slic3r_SupportCommon_hpp_ */