refactor(plugin): prefix SlicingPipelineStepPlugin values with pos/ps to mirror Print steps

This commit is contained in:
SoftFever
2026-07-10 17:28:26 +08:00
parent 11dd078f64
commit 21ed68963f
10 changed files with 70 additions and 70 deletions

View File

@@ -2319,7 +2319,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
BOOST_LOG_TRIVIAL(info) << "Starting the slicing process." << log_memory_info();
if (!use_cache) {
// Fire the SlicingPipeline hook for `obj` iff it just (re)computed `pstep` this pass.
auto hook_after = [this](PrintObject* obj, bool was_done, PrintObjectStep pstep, SlicingPipelineStep sstep) {
auto hook_after = [this](PrintObject* obj, bool was_done, PrintObjectStep pstep, SlicingPipelineStepPlugin sstep) {
if (m_pipeline_plugin_active && !was_done && obj->is_step_done(pstep))
run_pipeline_hook(sstep, obj);
};
@@ -2329,7 +2329,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
if (need_slicing_objects.count(obj) != 0) {
const bool was_done = obj->is_step_done(posSlice);
obj->slice();
hook_after(obj, was_done, posSlice, SlicingPipelineStep::Slice);
hook_after(obj, was_done, posSlice, SlicingPipelineStepPlugin::posSlice);
// re-snapshot each layer's raw_slices AFTER the Slice hook ran, so the
// plugin's mutation becomes the untyped baseline. Without this, a later
// perimeter-only re-run (make_perimeters -> restore_untyped_slices) reverts
@@ -2349,7 +2349,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
if (need_slicing_objects.count(obj) != 0) {
const bool was_done = obj->is_step_done(posPerimeters);
obj->make_perimeters(); // slice() inside is a no-op: posSlice already DONE
hook_after(obj, was_done, posPerimeters, SlicingPipelineStep::Perimeters);
hook_after(obj, was_done, posPerimeters, SlicingPipelineStepPlugin::posPerimeters);
} else {
if (obj->set_started(posPerimeters)) obj->set_done(posPerimeters);
}
@@ -2358,7 +2358,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
if (need_slicing_objects.count(obj) != 0) {
const bool was_done = obj->is_step_done(posEstimateCurledExtrusions);
obj->estimate_curled_extrusions();
hook_after(obj, was_done, posEstimateCurledExtrusions, SlicingPipelineStep::EstimateCurledExtrusions);
hook_after(obj, was_done, posEstimateCurledExtrusions, SlicingPipelineStepPlugin::posEstimateCurledExtrusions);
}
else {
if (obj->set_started(posEstimateCurledExtrusions))
@@ -2374,10 +2374,10 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
// is DONE, so this is a mechanical split mirroring the slice/perimeters loop.
const bool prepare_was_done = obj->is_step_done(posPrepareInfill);
obj->prepare_infill();
hook_after(obj, prepare_was_done, posPrepareInfill, SlicingPipelineStep::PrepareInfill);
hook_after(obj, prepare_was_done, posPrepareInfill, SlicingPipelineStepPlugin::posPrepareInfill);
const bool was_done = obj->is_step_done(posInfill);
obj->infill();
hook_after(obj, was_done, posInfill, SlicingPipelineStep::Infill);
hook_after(obj, was_done, posInfill, SlicingPipelineStepPlugin::posInfill);
}
else {
if (obj->set_started(posPrepareInfill))
@@ -2390,7 +2390,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
if (need_slicing_objects.count(obj) != 0) {
const bool was_done = obj->is_step_done(posIroning);
obj->ironing();
hook_after(obj, was_done, posIroning, SlicingPipelineStep::Ironing);
hook_after(obj, was_done, posIroning, SlicingPipelineStepPlugin::posIroning);
}
else {
if (obj->set_started(posIroning))
@@ -2404,7 +2404,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
if (need_contouring) {
const bool was_done = obj->is_step_done(posContouring);
obj->contour_z();
hook_after(obj, was_done, posContouring, SlicingPipelineStep::Contouring);
hook_after(obj, was_done, posContouring, SlicingPipelineStepPlugin::posContouring);
} else {
if (obj->set_started(posContouring))
obj->set_done(posContouring);
@@ -2437,13 +2437,13 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
for (size_t i = 0; i < m_objects.size(); ++i)
if (need_slicing_objects.count(m_objects[i]) != 0 && !sup_was_done[i]
&& m_objects[i]->is_step_done(posSupportMaterial))
run_pipeline_hook(SlicingPipelineStep::SupportMaterial, m_objects[i]);
run_pipeline_hook(SlicingPipelineStepPlugin::posSupportMaterial, m_objects[i]);
for (PrintObject* obj : m_objects) {
if (need_slicing_objects.count(obj) != 0) {
const bool was_done = obj->is_step_done(posDetectOverhangsForLift);
obj->detect_overhangs_for_lift();
hook_after(obj, was_done, posDetectOverhangsForLift, SlicingPipelineStep::DetectOverhangsForLift);
hook_after(obj, was_done, posDetectOverhangsForLift, SlicingPipelineStepPlugin::posDetectOverhangsForLift);
}
else {
if (obj->set_started(posDetectOverhangsForLift))
@@ -2520,7 +2520,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
}
this->set_done(psWipeTower);
if (m_pipeline_plugin_active) run_pipeline_hook(SlicingPipelineStep::WipeTower, nullptr);
if (m_pipeline_plugin_active) run_pipeline_hook(SlicingPipelineStepPlugin::psWipeTower, nullptr);
}
if (this->has_wipe_tower()) {
@@ -2646,7 +2646,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
this->finalize_first_layer_convex_hull();
this->set_done(psSkirtBrim);
if (m_pipeline_plugin_active) run_pipeline_hook(SlicingPipelineStep::SkirtBrim, nullptr);
if (m_pipeline_plugin_active) run_pipeline_hook(SlicingPipelineStepPlugin::psSkirtBrim, nullptr);
if (time_cost_with_cache) {
end_time = (long long)Slic3r::Utils::get_current_time_utc();
@@ -2663,7 +2663,7 @@ void Print::process(long long *time_cost_with_cache, bool use_cache)
// shared with the use_cache path (re_slicing_objects), so `!use_cache` must be checked
// explicitly here to keep hooks from ever firing on cache-loaded (plugin-final) objects.
if (!use_cache && m_pipeline_plugin_active && !was_done && obj->is_step_done(posSimplifyPath))
run_pipeline_hook(SlicingPipelineStep::SimplifyPath, obj);
run_pipeline_hook(SlicingPipelineStepPlugin::posSimplifyPath, obj);
}
else {
if (obj->set_started(posSimplifyPath))

View File

@@ -99,6 +99,11 @@ enum PrintObjectStep {
posCount,
};
enum class SlicingPipelineStepPlugin {
posSlice, posPerimeters, posEstimateCurledExtrusions, posPrepareInfill, posInfill, posIroning, posContouring,
posSupportMaterial, posDetectOverhangsForLift, posSimplifyPath, psWipeTower, psSkirtBrim
};
// A PrintRegion object represents a group of volumes to print
// sharing the same config (including the same assigned extruder(s))
class PrintRegion
@@ -882,11 +887,6 @@ enum FilamentCompatibilityType {
InvalidTemperatureRange
};
enum class SlicingPipelineStep {
Slice, Perimeters, EstimateCurledExtrusions, PrepareInfill, Infill, Ironing, Contouring,
SupportMaterial, DetectOverhangsForLift, SimplifyPath, WipeTower, SkirtBrim
};
// The complete print tray with possibly multiple objects.
class Print : public PrintBaseWithState<PrintStep, psCount>
{
@@ -896,7 +896,7 @@ private: // Prevents erroneous use by other classes.
typedef std::pair<PrintObject *, bool> PrintObjectInfo;
public:
using SlicingPipelineHookFn = std::function<void(Print&, const PrintObject*, SlicingPipelineStep)>;
using SlicingPipelineHookFn = std::function<void(Print&, const PrintObject*, SlicingPipelineStepPlugin)>;
// Cross-layer injection (mirrors ConfigBase::set_resolve_capability_fn): the GUI/plugin
// layer registers a dispatcher; libslic3r stays free of any plugin/Python dependency.
static void set_slicing_pipeline_hook_fn(SlicingPipelineHookFn fn) { s_slicing_pipeline_hook_fn = std::move(fn); }
@@ -1159,7 +1159,7 @@ private:
static SlicingPipelineHookFn s_slicing_pipeline_hook_fn;
bool m_pipeline_plugin_active { false };
void run_pipeline_hook(SlicingPipelineStep step, const PrintObject* object) {
void run_pipeline_hook(SlicingPipelineStepPlugin step, const PrintObject* object) {
if (m_pipeline_plugin_active && s_slicing_pipeline_hook_fn)
s_slicing_pipeline_hook_fn(*this, object, step);
}

View File

@@ -3130,7 +3130,7 @@ bool GUI_App::on_init_inner()
// cancellation, and convert a plugin failure into a (non-critical) SlicingError so it surfaces as a
// slicing-error notification rather than the fatal-crash dialog.
Slic3r::Print::set_slicing_pipeline_hook_fn(
[](Slic3r::Print& print, const Slic3r::PrintObject* object, Slic3r::SlicingPipelineStep step) {
[](Slic3r::Print& print, const Slic3r::PrintObject* object, Slic3r::SlicingPipelineStepPlugin step) {
const auto* caps = print.config().option<ConfigOptionStrings>("slicing_pipeline_plugin");
// `plugins` is a dynamic-only manifest key (not a static PrintConfig member), so it
// must be read from the full/dynamic config -- reading it off print.config() (the
@@ -3180,10 +3180,10 @@ bool GUI_App::on_init_inner()
// out in Release), so it must NOT be called from a pipeline hook.
if (!r.message.empty()) {
static const char* const kStepNames[] = {
"Slice", "Perimeters", "EstimateCurledExtrusions", "PrepareInfill", "Infill",
"Ironing", "Contouring", "SupportMaterial", "DetectOverhangsForLift",
"SimplifyPath", "WipeTower", "SkirtBrim"
}; // order must match Slic3r::SlicingPipelineStep
"posSlice", "posPerimeters", "posEstimateCurledExtrusions", "posPrepareInfill", "posInfill",
"posIroning", "posContouring", "posSupportMaterial", "posDetectOverhangsForLift",
"posSimplifyPath", "psWipeTower", "psSkirtBrim"
}; // order must match Slic3r::SlicingPipelineStepPlugin
const char* step_name = static_cast<size_t>(step) < sizeof(kStepNames) / sizeof(kStepNames[0])
? kStepNames[static_cast<int>(step)] : "Unknown";
BOOST_LOG_TRIVIAL(info) << "Slicing pipeline plugin '" << ref.capability_name

View File

@@ -1794,7 +1794,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
// always carries resolved "name;uuid;capability" references that full_config() and save_to_json()
// then pass downstream as-is -- no separate rebuild anywhere else.
if (const ConfigOptionDef* opt_def = m_config->def()->get(opt_key);
opt_def && opt_def->gui_type == ConfigOptionDef::GUIType::plugin_picker)
opt_def && opt_def->plugin_type != ConfigOptionDef::PluginType::None)
m_config->update_plugin_manifest();
if (opt_key == "gcode_flavor" && m_type == Preset::TYPE_PRINTER) {

View File

@@ -414,7 +414,7 @@ void PluginHostSlicing::RegisterBindings(py::module_& host)
layer_region
.def_readonly("slices", &LayerRegion::slices,
"Sliced, typed surfaces (SurfaceCollection). Edit in place, or replace with "
"slices.set(expolygons, surface_type). At Step.Slice this is the primary mutation "
"slices.set(expolygons, surface_type). At Step.posSlice this is the primary mutation "
"target; the split slice loop runs make_perimeters() afterward so edits cascade downstream.")
.def_readonly("fill_surfaces", &LayerRegion::fill_surfaces,
"Surfaces prepared for infill (SurfaceCollection). Edit in place or via fill_surfaces.set(...).")

View File

@@ -13,19 +13,19 @@ void SlicingPipelinePluginCapability::RegisterBindings(py::module_& module, py::
(void) pluginTypes; // matches gcode/script/printerAgent; Step is a fresh enum below.
auto slicing = module.def_submodule("slicing", "Slicing pipeline API (research/experimental).");
py::enum_<SlicingPipelineStep>(slicing, "Step")
.value("Slice", SlicingPipelineStep::Slice)
.value("Perimeters", SlicingPipelineStep::Perimeters)
.value("EstimateCurledExtrusions", SlicingPipelineStep::EstimateCurledExtrusions)
.value("PrepareInfill", SlicingPipelineStep::PrepareInfill) // after prepare_infill, before make_fills: editing fill_surfaces here CASCADES
.value("Infill", SlicingPipelineStep::Infill) // after make_fills: editing fill_surfaces here does NOT regenerate fills (v1)
.value("Ironing", SlicingPipelineStep::Ironing)
.value("Contouring", SlicingPipelineStep::Contouring)
.value("SupportMaterial", SlicingPipelineStep::SupportMaterial)
.value("DetectOverhangsForLift", SlicingPipelineStep::DetectOverhangsForLift)
.value("SimplifyPath", SlicingPipelineStep::SimplifyPath) // covers all simplify sub-steps
.value("WipeTower", SlicingPipelineStep::WipeTower)
.value("SkirtBrim", SlicingPipelineStep::SkirtBrim)
py::enum_<SlicingPipelineStepPlugin>(slicing, "Step")
.value("posSlice", SlicingPipelineStepPlugin::posSlice)
.value("posPerimeters", SlicingPipelineStepPlugin::posPerimeters)
.value("posEstimateCurledExtrusions", SlicingPipelineStepPlugin::posEstimateCurledExtrusions)
.value("posPrepareInfill", SlicingPipelineStepPlugin::posPrepareInfill) // after prepare_infill, before make_fills: editing fill_surfaces here CASCADES
.value("posInfill", SlicingPipelineStepPlugin::posInfill) // after make_fills: editing fill_surfaces here does NOT regenerate fills (v1)
.value("posIroning", SlicingPipelineStepPlugin::posIroning)
.value("posContouring", SlicingPipelineStepPlugin::posContouring)
.value("posSupportMaterial", SlicingPipelineStepPlugin::posSupportMaterial)
.value("posDetectOverhangsForLift", SlicingPipelineStepPlugin::posDetectOverhangsForLift)
.value("posSimplifyPath", SlicingPipelineStepPlugin::posSimplifyPath) // covers all simplify sub-steps
.value("psWipeTower", SlicingPipelineStepPlugin::psWipeTower)
.value("psSkirtBrim", SlicingPipelineStepPlugin::psSkirtBrim)
.export_values();
// The read-graph data model (Surface / ExPolygon / the extrusion tree / LayerRegion /

View File

@@ -1,6 +1,6 @@
#pragma once
#include "slic3r/plugin/PythonPluginInterface.hpp"
#include "libslic3r/Print.hpp" // SlicingPipelineStep, Print, PrintObject
#include "libslic3r/Print.hpp" // SlicingPipelineStepPlugin, Print, PrintObject
#include <pybind11/pybind11.h>
#include <map>
#include <string>
@@ -15,7 +15,7 @@ namespace Slic3r {
// src/slic3r/plugin/PluginHostSlicing.cpp.
struct SlicingPipelineContext {
std::string orca_version;
SlicingPipelineStep step { SlicingPipelineStep::Slice };
SlicingPipelineStepPlugin step { SlicingPipelineStepPlugin::posSlice };
Print* print { nullptr }; // always present when dispatched
const PrintObject* object { nullptr }; // null for print-wide steps
// read-only per-plugin settings, populated by the dispatcher from the