All checks were successful
Build and Test / build (pull_request) Successful in 28m56s
Remove critically stale docs: - docs/REPOSITORY_STATE.md — snapshot from 2026-01-31, all data outdated - docs/MULTI_USER_CLIENT.md — duplicate of DAG_CLIENT_INTEGRATION.md - docs/src/guide/ztools.md — describes removed addon - docs/KNOWN_ISSUES.md — replaced by Gitea issue tracker Update docs for ztools removal (#344), gears addition, and KCSDK progress: - OVERVIEW.md: fix version (v0.1.5), FreeCAD base (1.2.0), submodule table - ARCHITECTURE.md: replace ztools with gears in bootstrap flow and source layout - COMPONENTS.md: remove ztools section, add gears, remove stale missing-icons note - INTEGRATION_PLAN.md: mark Phase 7 #353-#356 as DONE, update Layer 5 diagram - README.md: update project structure, load order, feature descriptions - CI_CD.md: add context for disabled macOS/Windows builds (#164) - SUMMARY.md: remove ztools guide from mdBook navigation
136 lines
7.4 KiB
Markdown
136 lines
7.4 KiB
Markdown
# Architecture
|
|
|
|
## Bootstrap flow
|
|
|
|
```
|
|
FreeCAD startup
|
|
└─ src/Mod/Create/Init.py
|
|
└─ addon_loader.load_addons(gui=False)
|
|
├─ scan_addons("mods/") — find package.xml manifests
|
|
├─ parse_manifest() — extract <kindred> extensions
|
|
├─ validate_manifest() — check min/max_create_version
|
|
├─ resolve_load_order() — topological sort by <dependency>
|
|
└─ for each addon in order:
|
|
├─ add addon dir to sys.path
|
|
├─ exec(Init.py)
|
|
└─ register in AddonRegistry (FreeCAD.KindredAddons)
|
|
|
|
└─ src/Mod/Create/InitGui.py
|
|
├─ addon_loader.load_addons(gui=True)
|
|
│ └─ for each addon in order:
|
|
│ └─ exec(InitGui.py)
|
|
│ ├─ sdk (priority 0): logs "SDK loaded"
|
|
│ ├─ gears (priority 40): registers GearsWorkbench
|
|
│ └─ silo (priority 60): registers SiloWorkbench
|
|
│ └─ schedules deferred Silo overlay registration (2500ms)
|
|
├─ EditingContextResolver singleton created (MainWindow constructor)
|
|
│ ├─ registers built-in contexts (PartDesign, Sketcher, Assembly, Spreadsheet)
|
|
│ ├─ connects to signalInEdit/signalResetEdit/signalActiveDocument/signalActivateView
|
|
│ └─ BreadcrumbToolBar connected to contextChanged signal
|
|
└─ Deferred setup (QTimer):
|
|
├─ 500ms: _register_kc_format() → .kc file format
|
|
├─ 1500ms: _register_silo_origin() → registers Silo FileOrigin
|
|
├─ 2000ms: _setup_silo_auth_panel() → "Database Auth" dock
|
|
├─ 2500ms: Silo overlay registration → "Silo Origin" toolbar overlay
|
|
├─ 3000ms: _check_silo_first_start() → settings prompt
|
|
├─ 4000ms: _setup_silo_activity_panel() → "Database Activity" dock
|
|
└─ 10000ms: _check_for_updates() → update checker (Gitea API)
|
|
```
|
|
|
|
### Addon lifecycle
|
|
|
|
Each addon in `mods/` provides a `package.xml` manifest with a `<kindred>` extension block:
|
|
|
|
```xml
|
|
<kindred>
|
|
<min_create_version>0.1.0</min_create_version>
|
|
<load_priority>50</load_priority>
|
|
<pure_python>true</pure_python>
|
|
<dependencies>
|
|
<dependency>sdk</dependency>
|
|
</dependencies>
|
|
</kindred>
|
|
```
|
|
|
|
The loader (`addon_loader.py`) processes addons in this order:
|
|
|
|
1. **Scan** — find all `mods/*/package.xml` files
|
|
2. **Parse** — extract `<kindred>` metadata (version bounds, priority, dependencies)
|
|
3. **Validate** — reject addons incompatible with the current Create version
|
|
4. **Resolve** — topological sort by `<dependency>` declarations, breaking ties by `<load_priority>`
|
|
5. **Load** — execute `Init.py` (console) then `InitGui.py` (GUI) for each addon
|
|
6. **Register** — populate `FreeCAD.KindredAddons` registry with addon state
|
|
|
|
Current load order: **sdk** (0) → **gears** (40) → **silo** (60)
|
|
|
|
## Key source layout
|
|
|
|
```
|
|
src/Mod/Create/ Kindred Create module
|
|
├── Init.py Console bootstrap — loads addons via manifest-driven loader
|
|
├── InitGui.py GUI bootstrap — loads addons, Silo integration, update checker
|
|
├── addon_loader.py Manifest-driven addon loader with dependency resolution
|
|
├── kc_format.py .kc file format round-trip preservation
|
|
├── version.py.in CMake template → version.py (build-time)
|
|
├── update_checker.py Checks Gitea releases API for updates
|
|
├── CreateGlobal.h C++ export macros (CreateExport, CreateGuiExport)
|
|
├── App/ C++ App library (CreateApp.so)
|
|
│ ├── AppCreate.cpp Module entry point — PyMOD_INIT_FUNC(CreateApp)
|
|
│ └── AppCreatePy.cpp Python module object (Py::ExtensionModule)
|
|
└── Gui/ C++ Gui library (CreateGui.so)
|
|
├── AppCreateGui.cpp Module entry point — PyMOD_INIT_FUNC(CreateGui)
|
|
└── AppCreateGuiPy.cpp Python module object (Py::ExtensionModule)
|
|
|
|
mods/sdk/ [dir] Kindred addon SDK — stable API contract
|
|
├── package.xml Manifest (priority 0, no dependencies)
|
|
├── kindred_sdk/
|
|
│ ├── __init__.py Public API re-exports
|
|
│ ├── context.py Editing context wrappers (register_context, register_overlay, ...)
|
|
│ ├── theme.py YAML-driven palette system (get_theme_tokens, load_palette, Palette)
|
|
│ ├── origin.py FileOrigin registration (register_origin, unregister_origin)
|
|
│ ├── dock.py Deferred dock panel helper (register_dock_panel)
|
|
│ ├── compat.py Version detection (create_version, freecad_version)
|
|
│ └── palettes/
|
|
│ └── catppuccin-mocha.yaml 26 colors + 14 semantic roles
|
|
└── Init.py / InitGui.py Minimal log messages
|
|
|
|
mods/gears/ [submodule → gears.git] Gears workbench
|
|
├── package.xml Manifest (priority 40, depends on sdk)
|
|
└── ... Parametric gear generation
|
|
|
|
mods/solver/ [submodule → solver.git] Solver addon
|
|
└── ... Solver plugin support
|
|
|
|
mods/silo/ [submodule → silo-mod.git] FreeCAD workbench
|
|
├── freecad/package.xml Manifest (priority 60, depends on sdk)
|
|
├── silo-client/ [submodule → silo-client.git] shared API client
|
|
│ └── silo_client/ SiloClient, SiloSettings, CATEGORY_NAMES
|
|
└── freecad/ FreeCAD workbench (Python)
|
|
├── InitGui.py SiloWorkbench + overlay registration (via SDK)
|
|
├── silo_commands.py Commands + FreeCADSiloSettings adapter
|
|
└── silo_origin.py FileOrigin backend for Silo (via SDK)
|
|
|
|
src/Gui/SDK/ KCSDK C++ shared library (libKCSDK.so)
|
|
├── KCSDKGlobal.h DLL export macros
|
|
├── Types.h Plain C++ types (ContextDef, DockArea, PanelPersistence)
|
|
├── IPanelProvider.h Abstract dock panel interface
|
|
├── WidgetBridge.h/.cpp PySide QWidget <-> C++ QWidget* (via Gui::PythonWrapper)
|
|
├── SDKRegistry.h/.cpp Singleton registry — contexts, panels, providers
|
|
└── bindings/ pybind11 module (kcsdk.so)
|
|
├── kcsdk_py.cpp Module definition — enums, functions, classes
|
|
├── PyIPanelProvider.h Trampoline for Python subclassing
|
|
└── PyProviderHolder.h GIL-safe forwarding wrapper
|
|
|
|
src/Gui/EditingContext.h/.cpp EditingContextResolver singleton + context registry
|
|
src/Gui/BreadcrumbToolBar.h/.cpp Color-coded breadcrumb toolbar (Catppuccin Mocha)
|
|
src/Gui/FileOrigin.h/.cpp FileOrigin base class + LocalFileOrigin
|
|
src/Gui/CommandOrigin.cpp Origin_Commit/Pull/Push/Info/BOM commands
|
|
src/Gui/OriginManager.h/.cpp Origin lifecycle management
|
|
src/Gui/OriginSelectorWidget.h/.cpp UI for origin selection
|
|
|
|
src/Gui/Stylesheets/ QSS themes and SVG assets
|
|
src/Gui/PreferencePacks/ KindredCreate preference pack (cfg + build-time QSS)
|
|
```
|
|
|
|
See [INTEGRATION_PLAN.md](INTEGRATION_PLAN.md) for architecture layers and phase status.
|