Files
create/docs/INTEGRATION_PLAN.md
forbes 7f02fd182e
All checks were successful
Build and Test / build (pull_request) Successful in 24m46s
docs: comprehensive documentation refresh — remove stale references, add missing content
Root documentation:
- README.md: add Datums description, update addon load order and SDK references,
  fix project structure tree, update issue reporting guidance
- CONTRIBUTING.md: update submodule table (remove ztools, add gears/datums/solver),
  fix QSS guidance (single canonical source, not three copies)
- docs/ARCHITECTURE.md: update bootstrap flow (5 addons, split deferred timers
  between Create core and Silo addon), update load order and source layout
- docs/COMPONENTS.md: add Datums and Solver sections, update Gears description,
  fix Silo origin registration reference
- docs/KNOWN_ISSUES.md: create missing file referenced by CLAUDE.md and CONTRIBUTING.md
- docs/INTEGRATION_PLAN.md: update layer 5 diagram, fix load order references,
  update Phase 6 install rules, fix Layer 2/3/5 descriptions
- docs/OVERVIEW.md: add datums submodule entry
- docs/UPSTREAM.md: update Phase 1 directory table and Phase 4 submodule list

mdBook documentation (docs/src/):
- SUMMARY.md: replace dead architecture/ links with existing reference pages,
  remove deleted silo-server files, add new silo-server pages
- introduction.md: rewrite — replace ztools with current addons (Silo, Gears,
  Datums, KCSDK), update version to v0.1.5/FreeCAD 1.2.0
- guide/getting-started.md: update first-run addon list
- guide/installation.md: update verification console output
- guide/workbenches.md: rewrite — replace ztools with Gears, Datums, Solver
- guide/building.md: update submodule table, fix error message guidance
- development/contributing.md: fix scope example and issue reporting
- development/repo-structure.md: rewrite — add SDK, datums, gears, solver,
  reference/ folder; update submodule and key files tables
- development/writing-an-addon.md: fix priority range table
- reference/create-module-bootstrap.md: rewrite — reflect addon_loader system,
  split deferred timers between Create core and Silo addon
- reference/datum-creator.md: update from ZTools to datums addon paths and naming
- reference/glossary.md: add KCSDK entry, update FreeCAD version, remove ztools
  entry, update repository URLs table
2026-03-03 13:52:53 -06:00

17 KiB

Integration Plan

Strategy for integrating Kindred addons as built-in components while maintaining clear boundaries with FreeCAD core.

Goals

  1. Native feel -- Addons behave as first-class citizens, not bolted-on extras
  2. Clean boundaries -- Clear separation between FreeCAD core, Kindred extensions, and addon code
  3. Minimal core modifications -- Preserve FreeCAD's container models (Part, Body, Assembly)
  4. Maintainability -- Easy to pull upstream FreeCAD changes without merge conflicts
  5. Extensibility -- Architecture supports future Kindred-specific features

Architecture layers

┌─────────────────────────────────────────────────────────────┐
│                   Kindred Create Application                 │
├─────────────────────────────────────────────────────────────┤
│  Layer 5: Kindred Addons (mods/)                            │
│  ┌──────────────────┐  ┌──────────────────┐                 │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│  │   Silo   │ │  Gears   │ │  Datums  │ │  Solver  │       │
│  │ PLM/VCS  │ │ Gear gen │ │ Datum    │ │ Assembly │       │
│  │ BOM mgmt │ │          │ │ creator  │ │ research │       │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘       │
├─────────────────────────────────────────────────────────────┤
│  Layer 4: Kindred Addon SDK (mods/sdk/)                     │
│  ┌─────────────────────────────────────────────────────────┐│
│  │  Stable API contract: context, theme, origin, dock      ││
│  │  Isolates addons from FreeCADGui.* platform internals   ││
│  └─────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────┤
│  Layer 3: Kindred Create Module (src/Mod/Create/)           │
│  ┌─────────────────────────────────────────────────────────┐│
│  │  Python: manifest-driven addon loader, Silo integration ││
│  │  C++: CreateApp / CreateGui libraries (feature scaffold)││
│  └─────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────┤
│  Layer 2: FreeCAD Python API                                │
│  ┌─────────────────────────────────────────────────────────┐│
│  │  FreeCAD, FreeCADGui, Part, PartDesign, Sketcher,       ││
│  │  Assembly, WorkbenchManipulator                         ││
│  └─────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────┤
│  Layer 1: FreeCAD Core (C++)                                │
│  ┌─────────────────────────────────────────────────────────┐│
│  │  App::Document, Part::Feature, PartDesign::Body, etc.   ││
│  └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘

Boundary definitions

Layer 1: FreeCAD Core -- do not modify

FreeCAD's fundamental data structures: PartDesign::Body, PartDesign::Pocket, Part::Feature, App::Document, Sketcher::SketchObject. Modifying these creates merge conflicts with upstream and risks breaking FCStd file compatibility.

Layer 2: FreeCAD Python API -- use as-is

The Python API provides everything needed for feature creation, command registration, and geometry access. Addons operate through this layer. Stable FreeCAD APIs (Gui.addCommand(), Gui.addWorkbench(), Gui.addWorkbenchManipulator()) are called directly -- they do not need SDK wrappers.

Layer 3: Kindred Create Module -- src/Mod/Create/

The Create module serves two roles:

Python bootstrap (Init.py, InitGui.py, addon_loader.py):

  • Scans mods/ for package.xml manifests with <kindred> extensions
  • Validates version compatibility, resolves dependencies via topological sort
  • Loads addons in priority order (sdk → solver → gears → datums → silo)
  • Populates FreeCAD.KindredAddons registry for runtime introspection
  • Sets up deferred .kc format registration and update checker

C++ module scaffold (App/, Gui/, CreateGlobal.h):

  • CreateApp.so and CreateGui.so shared libraries
  • Currently scaffold-only (no features). Will host Create::FlipPocket and other C++ features that need to compile with the application rather than live in mods/.
  • Follows the Assembly module pattern (PyMOD_INIT_FUNC, Py::ExtensionModule)

Layer 4: Kindred Addon SDK -- mods/sdk/

The SDK is a pure-Python package that provides stable wrappers around Kindred-specific platform APIs. Addons import from kindred_sdk instead of calling FreeCADGui.* platform internals directly. This creates a single adaptation point during upstream rebases.

SDK modules:

  • context — editing context registration (register_context, register_overlay, inject_commands, etc.)
  • theme — YAML-driven palette system (get_theme_tokens, load_palette, Palette)
  • origin — FileOrigin registration (register_origin, unregister_origin)
  • dock — deferred dock panel helper (register_dock_panel)
  • compat — version detection (create_version, freecad_version)

The SDK is loaded first (priority 0) and has no dependencies.

Layer 5: Kindred Addons -- mods/

Pure Python addons with package.xml manifests. Self-contained with Init.py, InitGui.py, and <kindred> metadata. Developed and versioned independently as git submodules. Must declare <dependency>sdk</dependency> to use SDK APIs. Current addons: solver (assembly research), gears (parametric gear generation), datums (unified datum creator), silo (PLM).


Phase status

Phase 1: Addon auto-loading -- DONE

Implementation: src/Mod/Create/addon_loader.py implements manifest-driven loading with dependency resolution. Replaces the original exec()-based approach. Each addon provides a package.xml with <kindred> extensions specifying version bounds, load priority, and dependencies.

Default workbench: PartDesignWorkbench (set in PreferencePacks/KindredCreate/KindredCreate.cfg).

Registry: FreeCAD.KindredAddons provides runtime introspection — .loaded() returns addon names and states, .get(name) returns manifest data, .contexts() lists registered editing contexts.

Phase 1.5: Addon SDK -- DONE

Goal: Provide a stable API contract between the Create platform and addons, isolating addons from FreeCADGui.* platform internals that may change during upstream rebases.

Implementation: mods/sdk/kindred_sdk/ package with wrappers for editing contexts, theme tokens, FileOrigin registration, and dock panel creation. YAML-driven palette system (palettes/catppuccin-mocha.yaml) replaces hardcoded color dicts that were duplicated across 5+ locations.

Migration: Silo has been migrated to use the SDK (#250) — it declares <dependency>sdk</dependency> and uses kindred_sdk for overlay registration and theme tokens. Gears also depends on the SDK. The former ztools addon was removed from the build (#344) and archived to reference/ztools/ (#345) as part of the UI/UX rework (#346); its commands will be reimplemented through the KCSDK system.

Phase 1.75: C++ module scaffold -- DONE

Goal: Establish src/Mod/Create/App/ and src/Mod/Create/Gui/ so Kindred-specific C++ features have a proper build target.

Implementation: CreateApp.so and CreateGui.so shared libraries following the Assembly module pattern. Currently scaffold-only — no features registered. The existing Python bootstrap continues working alongside the C++ module.

Phase 2: Enhanced Pocket as C++ feature -- NOT STARTED

Goal: Implement a proper Create::FlipPocket C++ feature inheriting from PartDesign::ProfileBased.

Rationale: The former ztools Python implementation created a standard Pocket then applied a boolean Common. A native feature would integrate properly with the feature tree, support undo/redo correctly, and perform better on complex geometry.

Scope:

  • src/Mod/Create/App/FeatureFlipPocket.cpp -- Feature implementation
  • src/Mod/Create/Gui/TaskFlipPocket.cpp -- Task panel
  • src/Mod/Create/Gui/ViewProviderFlipPocket.cpp -- View provider

Decision: Deferred. The former Python approach was functional. Revisit as part of the KCSDK-driven command reimplementation (#346).

Phase 3: Datum C++ helpers -- NOT STARTED (SUPERSEDED)

Original goal: Create C++ geometry helper functions for datum calculations.

Current state: The Python implementation now uses FreeCAD's built-in Part::AttachExtension for automatic parametric updates. Each datum type maps to a native MapMode (FlatFace, ThreePointsPlane, NormalToEdge, etc.) with appropriate AttachmentSupport and AttachmentOffset. This eliminates the need for custom geometry calculations.

Decision: Superseded by the AttachExtension approach. Only tangent_to_cylinder still uses manual placement (requires a vertex reference not currently collected by the UI).

Phase 4: Theme system -- DONE

Goal: Theme applies consistently at startup regardless of active workbench.

Current state: The Catppuccin Mocha theme is set as the default via the KindredCreate preference pack. The canonical QSS lives in src/Gui/Stylesheets/KindredCreate.qss. The PreferencePacks copy is generated at build time via configure_file() in src/Gui/PreferencePacks/CMakeLists.txt.

Theme colors are now centralized in the SDK's YAML palette (mods/sdk/kindred_sdk/palettes/catppuccin-mocha.yaml). Addons use kindred_sdk.theme.get_theme_tokens() instead of hardcoding color dicts. The SDK provides a Palette class for programmatic access to colors and semantic roles.

Phase 5: Silo deep integration -- DONE

Goal: Silo commands available globally, not just in the Silo workbench.

Implementation: The unified origin system (FileOrigin, OriginManager, OriginSelectorWidget) in src/Gui/ delegates all file operations (New/Open/Save) to the selected origin. Standard commands (Std_New, Std_Open, Std_Save) and origin commands (Origin_Commit, Origin_Pull, Origin_Push, Origin_Info, Origin_BOM) are built into the File toolbar and menu. The Silo workbench no longer has its own toolbar — it only provides a menu with admin/management commands.

Dock panels: Database Auth (2000ms), Database Activity (4000ms), and Start Panel panels are created via deferred QTimers using kindred_sdk.register_dock_panel(). The Activity panel displays real-time server events via SSE with automatic reconnection. The Start Panel provides an in-viewport landing page with recent files and Silo integration.

Phase 6: Build system integration -- DONE

Goal: CMake install rules for mods/ submodules so packages include all addons automatically.

Implementation: src/Mod/Create/CMakeLists.txt includes install rules for all addons (mods/sdk, mods/solver, mods/gears, mods/datums, mods/silo) and the C++ module scaffold (App/, Gui/). Build-time code generation: version.py.inversion.py via configure_file().

CI/CD status: Release workflows (.gitea/workflows/release.yml) build for Linux (AppImage + .deb), macOS (DMG for Intel + Apple Silicon), and Windows (.exe NSIS installer + .7z archive). Builds run on public runners in dockerized mode. Releases are triggered by v* tags. See docs/CI_CD.md for details.


Phase 7: KCSDK — C++-backed SDK module -- IN PROGRESS

Goal: Replace the pure-Python SDK wrappers with a C++ shared library (libKCSDK.so) and pybind11 bindings (kcsdk.so). This gives addons a stable, typed API with proper GIL safety and enables future C++ addon development without Python.

Architecture:

Python Addons (silo, future addons, ...)
       |
kindred_sdk  (mods/sdk/)              <- convenience layer (try kcsdk, fallback FreeCADGui)
       |
kcsdk.so     (pybind11 module)        <- C++ API bindings
       |
KCSDK        (C++ shared library)     <- SDKRegistry + provider interfaces
       |
FreeCADGui   (EditingContextResolver, DockWindowManager, OriginManager, ...)

Sub-phases:

# Issue Status Description
1 #350 DONE Scaffold KCSDK library + kcsdk pybind11 module
2 #351 DONE Migrate editing context API to kcsdk
3 #352 DONE Panel provider system (IPanelProvider)
4 #353 DONE C++ theme engine
5 #354 DONE Toolbar provider system (IToolbarProvider)
6 #355 DONE Menu and action system
7 #356 DONE Status bar provider + origin migration
8 #357 Deprecation cleanup + SDK v1.0.0

Key files:

  • src/Gui/SDK/ — C++ library (KCSDKGlobal.h, Types.h, SDKRegistry, IPanelProvider, WidgetBridge)
  • src/Gui/SDK/bindings/ — pybind11 module (kcsdk_py.cpp, PyIPanelProvider, PyProviderHolder)
  • mods/sdk/kindred_sdk/ — Python wrappers with kcsdk/legacy fallback

Design decisions:

  • No Qt in public C++ APITypes.h uses std::string, std::vector, std::function. Qt conversion happens internally in SDKRegistry.cpp.
  • GIL-safe Python callables — Python callbacks stored via std::make_shared<py::object> with py::gil_scoped_acquire before every invocation.
  • PySide widget bridgingWidgetBridge::toQWidget() converts PySide QWidget objects to C++ QWidget* via Gui::PythonWrapper (Shiboken).
  • Provider pattern — Interfaces like IPanelProvider enable addons to register factories. The registry calls create_widget() once and manages the lifecycle through DockWindowManager.

Design decisions

  1. Create:: namespace prefix. All Kindred Create C++ features use this prefix to distinguish them from FreeCAD core.

  2. No upstream contribution. Kindred Create is a standalone product. This allows divergent design decisions without upstream coordination. Category 3 bug fixes (see UPSTREAM.md) may be upstreamed to reduce patch burden.

  3. Silo server distributed separately. Users deploy the Silo server independently. Setup instructions live in mods/silo/README.md.

  4. Version synchronization via submodule pins. Addon versions are pinned git submodule commits. Updates are deliberate:

    cd mods/silo && git pull origin main && cd ../..
    git add mods/silo && git commit -m "Update silo submodule"
    
  5. Python-first approach. C++ extensions are deferred until Python cannot achieve the requirement.

  6. Graceful degradation. The addon loader skips addons that fail validation or loading. Each addon load is wrapped in try/except with console logging. Any addon can be absent without breaking the bootstrap.

  7. SDK as adaptation layer. Addons call kindred_sdk.* instead of FreeCADGui.* platform internals. This creates a single point of adaptation during upstream rebases — update the SDK wrappers, not every addon.

  8. Manifest-driven loading. Addons declare version bounds, dependencies, and load priority in package.xml <kindred> extensions. This replaces hardcoded load lists and enables third-party addons in the future.