feat(plugin): add the slicing-pipeline plugin capability

Introduces a plugin capability that runs Python at the seams of Print::process(),
letting a plugin read and rewrite slicing state as it is computed.

- New slicing_pipeline_plugin config option; selected plugin refs are serialized
  into the print manifest.
- Print gains an injectable hook fired at each pipeline step (posSlice,
  posPerimeters, posInfill, ...). It is a no-op when unset, fires only on genuine
  (re)computation, and never on the use-cache path.
- orca.slicing submodule: SlicingPipelineCapabilityBase plus a trampoline and a
  Step enum. Capabilities read the live graph through zero-copy int64 numpy views
  (contour/holes geometry with unscaled coordinates, flattened toolpath data) and
  edit it through 2D-geometry mutators with cache-invariant refresh.
- GUI dispatcher runs capabilities during slicing under the GIL, turns plugin
  errors into slicing errors, honors cancellation, and adds the plugin picker.
- Ships the InsetEverySlice sample plugin and binding/hook tests.
This commit is contained in:
SoftFever
2026-07-04 04:33:20 +08:00
parent 43bc76d9a9
commit b0bacdd00b
23 changed files with 1622 additions and 38 deletions

View File

@@ -882,6 +882,11 @@ enum FilamentCompatibilityType {
InvalidTemperatureRange
};
enum class SlicingPipelineStep {
Slice, Perimeters, EstimateCurledExtrusions, Infill, Ironing, Contouring,
SupportMaterial, DetectOverhangsForLift, SimplifyPath, WipeTower, SkirtBrim
};
// The complete print tray with possibly multiple objects.
class Print : public PrintBaseWithState<PrintStep, psCount>
{
@@ -891,6 +896,11 @@ private: // Prevents erroneous use by other classes.
typedef std::pair<PrintObject *, bool> PrintObjectInfo;
public:
using SlicingPipelineHookFn = std::function<void(Print&, const PrintObject*, SlicingPipelineStep)>;
// 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); }
Print() = default;
virtual ~Print() { this->clear(); }
@@ -1147,6 +1157,13 @@ private:
// Islands of objects and their supports extruded at the 1st layer.
Polygons first_layer_islands() const;
static SlicingPipelineHookFn s_slicing_pipeline_hook_fn;
bool m_pipeline_plugin_active { false };
void run_pipeline_hook(SlicingPipelineStep step, const PrintObject* object) {
if (m_pipeline_plugin_active && s_slicing_pipeline_hook_fn)
s_slicing_pipeline_hook_fn(*this, object, step);
}
PrintConfig m_config;
PrintObjectConfig m_default_object_config;
PrintRegionConfig m_default_region_config;