Merge branch 'main' into perf/slicing-optimizations

This commit is contained in:
raistlin7447 committed 2026-10-19 11:33:03 -05:00
commit 17c3bbb7b6
874 files changed
+200107 -30859

No files matched your search

+35 -34
View File
@@ -17,6 +17,7 @@
#include "I18N.hpp"
#include "Layer.hpp"
#include "MutablePolygon.hpp"
#include "PerimeterGenerator.hpp"
#include "PrintBase.hpp"
#include "PrintConfig.hpp"
#include "SLA/IndexedMesh.hpp"
@@ -32,7 +33,7 @@
#include "Fill/FillAdaptive.hpp"
#include "Fill/Fill.hpp"
#include "Fill/FillLightning.hpp"
#include "Fill/FillTpmsAdaptive.hpp"
#include "Fill/AdaptiveInfillField.hpp"
#include "format.hpp"
#include "AABBTreeIndirect.hpp"
#include "AABBTreeLines.hpp"
@@ -860,11 +861,10 @@ void PrintObject::contour_z()
BOOST_LOG_TRIVIAL(debug) << "Contouring in parallel - start";
TriangleMesh mesh = this->m_model_object->raw_mesh();
if (m_model_object->instances.size() != 1) {
throw RuntimeError("ContourZ: unexpected number of instances");
}
ModelInstance *inst = m_model_object->instances.front();
// A PrintObject groups the instances that share their whole transformation but the XY shift: an
// instance rotated, scaled or mirrored differently is a PrintObject of its own. So the first
// instance stands for all of them.
const ModelInstance *inst = m_instances.front().model_instance;
Point center_offset = this->center_offset();
Geometry::Transformation trans = inst->get_transformation();
@@ -887,7 +887,8 @@ void PrintObject::contour_z()
std::scoped_lock lock(mtx);
completed++;
std::string msg = (boost::format("Z contoured layer %d/%d (%d%%)") % (completed) % m_layers.size() % int(double(completed) / m_layers.size() * 100)).str();
// TRN Slicing status: layers done, total layers, percentage done.
std::string msg = (boost::format(L("Z contoured layer %d/%d (%d%%)")) % (completed) % m_layers.size() % int(double(completed) / m_layers.size() * 100)).str();
m_print->set_status(40, msg);
}
}
@@ -960,12 +961,11 @@ void PrintObject::generate_support_material(bool with_belt_brim)
BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(0) << "is_support_necessary takes " << duration << " secs.";
if (sntype != NoNeedSupp) {
std::map<SupportNecessaryType, std::string> reasons = {
{SharpTail,L("floating regions")},
{Cantilever,L("floating cantilever")},
{LargeOverhang,L("large overhangs")} };
std::string warning_message = Slic3r::format(L("It seems object %s has %s. Please re-orient the object or enable support generation."),
this->model_object()->name, reasons[sntype]);
std::map<SupportNecessaryType, std::string> messages = {
{SharpTail,L("It seems object %1% has floating regions. Please re-orient the object or enable support generation.")},
{Cantilever,L("It seems object %1% has a floating cantilever. Please re-orient the object or enable support generation.")},
{LargeOverhang,L("It seems object %1% has large overhangs. Please re-orient the object or enable support generation.")} };
std::string warning_message = Slic3r::format(messages[sntype], this->model_object()->name);
this->active_step_add_warning(PrintStateBase::WarningLevel::NON_CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn);
}
@@ -984,6 +984,9 @@ void PrintObject::generate_support_material(bool with_belt_brim)
this->_generate_support_material();
m_print->throw_if_canceled();
}
// Orca: the tree support collision/avoidance caches and support nodes are only used while this step runs
// (detect_overhangs() rebuilds them from scratch), so don't keep them resident until the next slice.
this->clear_tree_support_preview_cache();
// Belt brim rides here rather than in the brim step because its apron
// prologue introduces print_z values below the object's first layer, and
// those must exist before ToolOrdering is built at psWipeTower - one step
@@ -1251,19 +1254,19 @@ FillLightning::GeneratorPtr PrintObject::prepare_lightning_infill_data()
return has_lightning_infill ? FillLightning::build_generator(std::as_const(*this), [this]() -> void { this->throw_if_canceled(); }) : FillLightning::GeneratorPtr();
}
TpmsRadialFields PrintObject::prepare_tpms_radial_fields() const
AdaptiveInfillFields PrintObject::prepare_adaptive_infill_fields() const
{
TpmsRadialFields fields;
std::array<bool, size_t(TpmsAdaptiveMode::Count)> modes{};
AdaptiveInfillFields fields;
std::array<bool, size_t(AdaptiveInfillMode::Count)> modes{};
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++region_id)
if (const PrintRegionConfig &config = this->printing_region(region_id).config();
config.sparse_infill_density > 0 && config.sparse_infill_density < 100 && is_tpms_adaptive_pattern(config.sparse_infill_pattern))
modes[size_t(config.tpms_adaptive.value)] = true;
modes[size_t(TpmsAdaptiveMode::Disabled)] = false;
config.sparse_infill_density > 0 && config.sparse_infill_density < 100 && is_adaptive_infill_pattern(config.sparse_infill_pattern))
modes[size_t(config.adaptive_infill_mode.value)] = true;
modes[size_t(AdaptiveInfillMode::Disabled)] = false;
if (std::find(modes.begin(), modes.end(), true) == modes.end() || m_layers.empty())
return fields;
std::vector<TpmsRadialField::Slice> slices;
std::vector<AdaptiveInfillField::Slice> slices;
slices.reserve(m_layers.size());
BoundingBox bbox;
for (const Layer *layer : m_layers) {
@@ -1276,7 +1279,7 @@ TpmsRadialFields PrintObject::prepare_tpms_radial_fields() const
if (!modes[mode])
continue;
// Without a field, the infill falls back to the regular pattern.
auto field = std::make_unique<TpmsRadialField>(slices, bbox, TpmsAdaptiveMode(mode), [this]() { m_print->throw_if_canceled(); });
auto field = std::make_unique<AdaptiveInfillField>(slices, bbox, AdaptiveInfillMode(mode), [this]() { m_print->throw_if_canceled(); });
if (!field->empty())
fields[mode] = std::move(field);
}
@@ -1464,15 +1467,13 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "top_surface_speed") {
// Brim is printed below supports, support invalidates brim and skirt.
steps.emplace_back(posSupportMaterial);
if (opt_key == "brim_type") {
const auto* old_brim_type = old_config.option<ConfigOptionEnum<BrimType>>(opt_key);
const auto* new_brim_type = new_config.option<ConfigOptionEnum<BrimType>>(opt_key);
//BBS: When switch to manual brim, the object must have brim, then re-generate perimeter
//to make the wall order of first layer to be outer-first
// btLeadingEdgeOnly is printed as an outer brim (Brim.cpp, BeltBrim.cpp), so it
// takes part in the same first-layer wall order rule.
if (old_brim_type->value == btOuterOnly || new_brim_type->value == btOuterOnly ||
old_brim_type->value == btLeadingEdgeOnly || new_brim_type->value == btLeadingEdgeOnly)
if (opt_key == "brim_type" || opt_key == "brim_width") {
// Regenerate the walls when the brim starts or stops putting the first layer's outer walls first.
auto outer_walls_first = [](const ConfigOptionResolver &config) {
return brim_puts_outer_walls_first(config.option<ConfigOptionEnum<BrimType>>("brim_type")->value,
config.option<ConfigOptionFloat>("brim_width")->value);
};
if (outer_walls_first(old_config) != outer_walls_first(new_config))
steps.emplace_back(posPerimeters);
}
} else if (
@@ -1686,9 +1687,9 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "infill_overhang_angle") {
steps.emplace_back(posInfill);
} else if (opt_key == "sparse_infill_pattern"
|| opt_key == "tpms_adaptive"
|| opt_key == "tpms_interior_density"
|| opt_key == "tpms_adaptive_gradient"
|| opt_key == "adaptive_infill_mode"
|| opt_key == "adaptive_infill_interior_density"
|| opt_key == "adaptive_infill_gradient"
// Orca: Body centering now also determines bridge anchors during preparation.
// Invalidating preparation also invalidates infill, including top/bottom surfaces.
|| opt_key == "center_of_surface_pattern"
@@ -3307,7 +3308,7 @@ void PrintObject::bridge_over_infill()
}
this->m_adaptive_fill_octrees = this->prepare_adaptive_infill_data(surfaces_w_layer);
this->m_tpms_radial_fields = this->prepare_tpms_radial_fields();
this->m_adaptive_infill_fields = this->prepare_adaptive_infill_fields();
std::vector<size_t> layers_to_generate_infill;
for (const auto &pair : surfaces_by_layer) {