docs(plugin): make comments self-contained; drop design-doc and dead-code references

Review the slicing-pipeline plugin comments for context a reader of the source
alone cannot follow, and rewrite them to stand on their own:

- drop pointers to uncommitted design/plan material ("§3.6 (Twistify design)",
  "the brief's note", "Fix 4(a)/4(b)")
- fix dangling references to code this branch removed: the retired set_slices()
  and view mutators, the former G-code post-processing capability/trampoline,
  the "Post-processing" capability family, the pre-refactor array helper
- drop "v1"/"in v1" phase labels, keeping the behavior they described
- correct stale cross-references: Twistify.py -> the real sample path;
  test_plugin_host_api.cpp:32-40 -> import_orca_module in python_test_support.hpp;
  "the binding"/"graphs above" -> the named source

Comment/string-only; no code behavior change.
This commit is contained in:
SoftFever
2026-07-11 03:30:05 +08:00
parent 19352215da
commit a04ce5f81e
9 changed files with 40 additions and 42 deletions

View File

@@ -103,7 +103,7 @@ enum class SlicingPipelineStepPlugin {
posSlice, posPerimeters, posEstimateCurledExtrusions, posPrepareInfill, posInfill, posIroning, posContouring,
posSupportMaterial, posDetectOverhangsForLift, posSimplifyPath, psWipeTower, psSkirtBrim,
// Fires from the GUI G-code export/post-process seam (PostProcessor.cpp), NOT from Print::process().
// At this step the plugin edits the exported G-code file in place; see the binding for the full contract.
// At this step the plugin edits the exported G-code file in place; see SlicingPipelinePluginCapability for the full contract.
psGCodePostProcess
};

View File

@@ -39,8 +39,8 @@ pybind11::array make_readonly_rows(pybind11::handle base, const T* data, pybind1
namespace py = pybind11;
if (rows == 0 || data == nullptr) {
py::array_t<T> empty(std::vector<py::ssize_t>{ 0, (py::ssize_t) N });
// Keep behavior-preserving: the pre-refactor helper returned read-only
// arrays on every path, so mark the fresh empty array read-only too.
// Mark the fresh empty array read-only so every return path of this
// helper yields a read-only view.
empty.attr("setflags")(py::arg("write") = false);
return std::move(empty);
}

View File

@@ -109,7 +109,7 @@ void PluginHostSlicing::RegisterBindings(py::module_& host)
// ------------------------------------------------------------------
// Slicing print-graph data model — raw bindings of the classes the C++
// pipeline itself uses, same nodelete/reference style as the Model and
// Preset graphs above.
// Preset graphs in PluginHostApi.cpp.
//
// LIFETIME (C++ semantics, the one rule of this API): every object handed
// out below is a non-owning reference into the live slicing graph owned by
@@ -306,8 +306,7 @@ void PluginHostSlicing::RegisterBindings(py::module_& host)
.def("set_type", [](SurfaceCollection& c, SurfaceType t) { c.set_type(t); }, py::arg("surface_type"))
.def("set", [](SurfaceCollection& c, const std::vector<ExPolygon>& src, SurfaceType t) { c.set(src, t); },
py::arg("expolygons"), py::arg("surface_type"),
"Replace all surfaces from a list of ExPolygon, all tagged `surface_type`. "
"This is the faithful replacement for the retired set_slices().")
"Replace all surfaces from a list of ExPolygon, all tagged `surface_type`.")
.def("set", [](SurfaceCollection& c, const std::vector<Surface>& src) { c.set(src); },
py::arg("surfaces"), "Replace all surfaces from a list of Surface (types preserved per surface).")
.def("append", [](SurfaceCollection& c, const std::vector<ExPolygon>& src, SurfaceType t) { c.append(src, t); },
@@ -315,9 +314,8 @@ void PluginHostSlicing::RegisterBindings(py::module_& host)
.def("filter_by_type", [](py::object self, SurfaceType t) {
SurfaceCollection& c = self.cast<SurfaceCollection&>();
py::list out;
// SurfacesPtr (SurfaceCollection::filter_by_type's return type) is
// std::vector<const Surface*> (see Surface.hpp); the brief's note describing it
// as std::vector<Surface*> does not match the header, so this iterates by const
// SurfaceCollection::filter_by_type returns SurfacesPtr, which is
// std::vector<const Surface*> (see Surface.hpp), so iterate by const
// pointer (py::cast accepts `const itype*` directly, see cast.h cast(const itype*)).
for (const Surface* s : c.filter_by_type(t))
out.append(py::cast(s, py::return_value_policy::reference_internal, self));
@@ -333,7 +331,7 @@ void PluginHostSlicing::RegisterBindings(py::module_& host)
}, "Surfaces as [Surface] references into the live collection. Invalidated by "
"set()/append()/clear() on this collection (C++ vector semantics).");
// --- Extrusion tree (read-only in v1). Registered polymorphically: when a returned
// --- Extrusion tree (read-only). Registered polymorphically: when a returned
// ExtrusionEntity*'s dynamic type IS one of the classes registered below, pybind
// hands the plugin that concrete type, so plugins walk the same tree shape C++ does.
// When the dynamic type is NOT registered (e.g. ExtrusionLoopSloped, produced with
@@ -419,9 +417,9 @@ void PluginHostSlicing::RegisterBindings(py::module_& host)
.def_readonly("fill_surfaces", &LayerRegion::fill_surfaces,
"Surfaces prepared for infill (SurfaceCollection). Edit in place or via fill_surfaces.set(...).")
.def_readonly("perimeters", &LayerRegion::perimeters,
"Perimeter toolpaths (ExtrusionEntityCollection, read-only in v1).")
"Perimeter toolpaths (ExtrusionEntityCollection, read-only).")
.def_readonly("fills", &LayerRegion::fills,
"Infill toolpaths (ExtrusionEntityCollection, read-only in v1).")
"Infill toolpaths (ExtrusionEntityCollection, read-only).")
.def("layer", [](LayerRegion& r) -> py::object {
Layer* l = r.layer();
if (l == nullptr)
@@ -487,7 +485,7 @@ void PluginHostSlicing::RegisterBindings(py::module_& host)
out.append(py::cast(static_cast<Layer*>(sl),
py::return_value_policy::reference_internal, self));
return out;
}, "Support layers as [Layer] (support-specific fields are not exposed in v1).")
}, "Support layers as [Layer] (support-specific fields are not exposed).")
.def("model_object", [](PrintObject& o) -> py::object {
// The Print's model SNAPSHOT (worker-thread stable), reusing the
// orca.host.ModelObject bindings — mesh access for slicing plugins.

View File

@@ -102,7 +102,7 @@ void execute_capabilities_from_refs(const ConfigOptionStrings& capabilities,
{
PluginManager& plugin_mgr = PluginManager::instance();
// Log prefix derived from the capability type so each capability family (Post-processing,
// Log prefix derived from the capability type so each capability family (Printer connection,
// Slicing Pipeline, ...) tags its dispatch diagnostics with its own display name.
const std::string tag = plugin_capability_type_display_name(type);

View File

@@ -10,7 +10,7 @@ namespace Slic3r {
bool SlicingPipelineContext::cancelled() const { return print && print->canceled(); }
void SlicingPipelinePluginCapability::RegisterBindings(py::module_& module, py::enum_<PluginCapabilityType>& pluginTypes) {
(void) pluginTypes; // matches gcode/script/printerAgent; Step is a fresh enum below.
(void) pluginTypes; // unused: this capability defines its own Step enum (below) rather than extending the shared PluginCapabilityType enum.
auto slicing = module.def_submodule("slicing", "Slicing pipeline API (research/experimental).");
py::enum_<SlicingPipelineStepPlugin>(slicing, "Step")
@@ -18,7 +18,7 @@ void SlicingPipelinePluginCapability::RegisterBindings(py::module_& module, py::
.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("posInfill", SlicingPipelineStepPlugin::posInfill) // after make_fills: editing fill_surfaces here does NOT regenerate the fills
.value("posIroning", SlicingPipelineStepPlugin::posIroning)
.value("posContouring", SlicingPipelineStepPlugin::posContouring)
.value("posSupportMaterial", SlicingPipelineStepPlugin::posSupportMaterial)
@@ -70,8 +70,8 @@ void SlicingPipelinePluginCapability::RegisterBindings(py::module_& module, py::
if (ctx.object == nullptr)
return py::none();
// The hook signature hands objects out as const; they are genuinely mutable
// (owned by the Print) — the same const_cast the old view mutators used,
// done once here at the graph entry point.
// (owned by the Print), so the const_cast is safe — done once here at the
// graph entry point so Python steps receive a mutable PrintObject.
return py::cast(const_cast<PrintObject*>(ctx.object), py::return_value_policy::reference);
}, "orca.host.PrintObject for object-scoped steps, or None for print-wide steps. "
"Valid only during the execute(ctx) call.")

View File

@@ -14,10 +14,10 @@ public:
[&]{
// At Step.psGCodePostProcess the plugin edits the exported G-code file, which lives
// outside data_dir() (a temp/output folder), so writing to it would otherwise be
// blocked by the audit sandbox. Grant that folder as a scoped allowed root, mirroring
// the former G-code post-processing trampoline. The setup callback runs AFTER the
// audit context is constructed, so the scoped root is not cleared by its constructor.
// Empty at every other step, so no extra access is granted to the geometry hooks.
// blocked by the audit sandbox. Grant that folder as a scoped allowed root. The setup
// callback runs AFTER the audit context is constructed, so the scoped root is not
// cleared by its constructor. Empty at every other step, so no extra access is
// granted to the geometry hooks.
if (!ctx.gcode_path.empty())
::Slic3r::PluginAuditManager::instance().add_scoped_allowed_root(
std::filesystem::path(ctx.gcode_path).parent_path());