mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 23:46:24 -06:00
Initial port of organic tree support from PrusaSlicer (#1938)
* Initial port of organic tree support from PrusaSlicer * Port missing Organic support parameters from PrusaSlicer * Update parameter naming * Reorganize the `raft_first_layer_expansion` and `raft_first_layer_density` parameters as they are not only used by rafts * Reset support style only in simple mode * Sync latest update from PrusaSlicer & copyrights * Fix organic tree support crash with invalid parameters --------- Co-authored-by: Vojtech Bubnik <bubnikv@gmail.com>
This commit is contained in:
parent
b50dfb69a2
commit
a1464735ce
33 changed files with 13299 additions and 38 deletions
161
src/libslic3r/Support/SupportCommon.hpp
Normal file
161
src/libslic3r/Support/SupportCommon.hpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
///|/ Copyright (c) Prusa Research 2023 Vojtěch Bubník @bubnikv
|
||||
///|/
|
||||
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef slic3r_SupportCommon_hpp_
|
||||
#define slic3r_SupportCommon_hpp_
|
||||
|
||||
#include "../Layer.hpp"
|
||||
#include "../Polygon.hpp"
|
||||
#include "../Print.hpp"
|
||||
#include "SupportLayer.hpp"
|
||||
#include "SupportParameters.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintObject;
|
||||
class SupportLayer;
|
||||
|
||||
namespace FFFSupport {
|
||||
|
||||
// Remove bridges from support contact areas.
|
||||
// To be called if PrintObjectConfig::dont_support_bridges.
|
||||
void remove_bridges_from_contacts(
|
||||
const PrintConfig &print_config,
|
||||
const Layer &lower_layer,
|
||||
const LayerRegion &layerm,
|
||||
float fw,
|
||||
Polygons &contact_polygons);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
} // namespace FFFSupport
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif /* slic3r_SupportCommon_hpp_ */
|
Loading…
Add table
Add a link
Reference in a new issue