# Integration Plan Strategy for integrating ztools and Silo as built-in addons while maintaining clear boundaries with FreeCAD core. ## Goals 1. **Native feel** -- ztools and Silo behave as first-class citizens, not bolted-on addons 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 4: Kindred Workbenches (mods/) │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ ztools │ │ Silo │ │ │ │ Datum Creator │ │ Open/Save/Commit│ │ │ │ Enhanced Pocket │ │ Part numbering │ │ │ │ Assembly Patterns│ │ Revision control│ │ │ │ Spreadsheet fmt │ │ BOM management │ │ │ └──────────────────┘ └──────────────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ Layer 3: Kindred Bootstrap (src/Mod/Create/) │ │ ┌─────────────────────────────────────────────────────────┐│ │ │ Addon loading, theme application, global menu/toolbar ││ │ │ injection via WorkbenchManipulator API ││ │ └─────────────────────────────────────────────────────────┘│ ├─────────────────────────────────────────────────────────────┤ │ 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. ZTools and Silo operate entirely through this layer. ### Layer 3: Kindred Bootstrap -- `src/Mod/Create/` The Create module is a thin Python loader that: - Adds `mods/` addon paths to `sys.path` and executes their `Init.py`/`InitGui.py` files - Registers the Silo FileOrigin so the origin selector can offer it at startup - Sets up deferred Silo dock panels (auth, activity) via `QTimer` - Handles first-start configuration This layer does not contain C++ code. ### Layer 4: Kindred Workbenches -- `mods/` Pure Python workbenches following FreeCAD's addon pattern. Self-contained with `InitGui.py`, `Init.py`, and `package.xml`. Developed and versioned independently as git submodules. --- ## Phase status ### Phase 1: Addon auto-loading -- DONE **Implementation:** `src/Mod/Create/Init.py` and `InitGui.py` load workbenches from `mods/` at startup using `exec()`. Addons degrade gracefully if submodule is absent. **Default workbench:** `ZToolsWorkbench` (set in `resources/preferences/KindredCreate/KindredCreate.cfg`). ### Phase 2: Enhanced Pocket as C++ feature -- NOT STARTED **Goal:** Replace the Python boolean-operation workaround in `ZTools_EnhancedPocket` with a proper `Create::FlipPocket` C++ feature inheriting from `PartDesign::ProfileBased`. **Rationale:** The current Python implementation creates a standard Pocket then applies 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 - Update `ZTools_EnhancedPocket` to create `Create::FlipPocket` instead of the workaround **Decision:** Deferred. The Python approach is functional for current needs. Revisit when performance or feature-tree integration becomes a problem. ### 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`. The unused `resources/preferences/KindredCreate/` directory has been removed. Recent additions: `QGroupBox::indicator` styling for consistent checkbox appearance, and `QLabel[haslink="true"]` link color (`#b4befe` Catppuccin Lavender). Preference defaults tuned for document, selection, notification, and report view settings via `KindredCreate.cfg`. **Remaining work:** Move theme responsibility out of ztools and into the Create module. ### 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. 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 -- PARTIAL **Goal:** CMake install rules for `mods/` submodules so packages include ztools and Silo automatically. **CI/CD status:** Release workflows (`.gitea/workflows/release.yml`) now 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. Build-time code generation is now in use: `src/Mod/Create/version.py.in` is processed by `configure_file()` to inject `KINDRED_CREATE_VERSION` from the root `CMakeLists.txt`. The update checker (`update_checker.py`) uses this at startup to query the Gitea releases API. **Remaining work:** CMake install rules should be formalized in `src/Mod/Create/CMakeLists.txt` so that `cmake --install` includes mods/ submodules without relying on the packaging scripts to copy them: ```cmake install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/ztools/ztools DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/ztools) install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/ztools/CatppuccinMocha DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/ztools) install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/freecad/ DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/Silo) install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/silo-client/ DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/silo-client) ``` --- ## Design decisions 1. **`Create::` namespace prefix.** All Kindred Create 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. 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.** ztools and Silo versions are pinned git submodule commits. Updates are deliberate: ```bash cd mods/ztools && git pull origin main && cd ../.. git add mods/ztools && git commit -m "Update ztools submodule" ``` 5. **Python-first approach.** C++ extensions are deferred until Python cannot achieve the requirement. The AttachExtension approach for datums validated this strategy. 6. **Graceful degradation.** The Create module loads successfully even if submodules are absent. Each addon load is wrapped in try/except with console logging.