chore: migrate submodules to public repos, rework docs and CI/CD
Some checks failed
Build and Test / build (push) Has been cancelled
Some checks failed
Build and Test / build (push) Has been cancelled
- Update .gitmodules: ztools, silo, and OndselSolver now reference public git.kindred-systems.com URLs instead of internal Gitea - Merge OndselSolver numerical solver with ML solver scaffolding into unified kindred/solver repository - Rewrite README.md for conciseness - Add docs/CI_CD.md with full pipeline documentation - Rework CI/CD workflows for public dockerized runners - Add multi-platform release builds (Linux, macOS, Windows) - Release workflow triggers on v* tags only - Update docs/REPOSITORY_STATE.md and docs/INTEGRATION_PLAN.md
This commit is contained in:
@@ -1,460 +1,159 @@
|
||||
# Kindred Create Integration Plan
|
||||
# Integration Plan
|
||||
|
||||
This document outlines the strategy for integrating ztools and Silo workbenches as built-in addons in Kindred Create while maintaining clear boundaries with FreeCAD core.
|
||||
Strategy for integrating ztools and Silo as built-in addons while maintaining clear boundaries with FreeCAD core.
|
||||
|
||||
## Goals
|
||||
|
||||
1. **Native feel** - ztools and Silo should feel like 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 that supports future Kindred-specific features
|
||||
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
|
||||
|
||||
## Current State
|
||||
|
||||
### Repository Structure
|
||||
```
|
||||
kindred-create/
|
||||
├── src/Mod/ # FreeCAD core modules (PartDesign, Sketcher, Assembly, etc.)
|
||||
├── mods/ # Kindred addons (git submodules)
|
||||
│ ├── ztools/ # Part design extensions, theme
|
||||
│ └── silo/ # Parts database integration
|
||||
└── resources/ # Branding, default preferences
|
||||
```
|
||||
|
||||
### Integration Points Today
|
||||
- **ztools**: Pure Python addon wrapping FreeCAD commands with enhanced UX
|
||||
- **Silo**: Pure Python addon with REST API integration
|
||||
- **Theme**: Preference pack + runtime stylesheet application
|
||||
|
||||
## Architecture Layers
|
||||
## 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 Core Extensions (src/Mod/Kindred/) │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐│
|
||||
│ │ - KindredFeatures: Flip-side pocket, custom geometry ops ││
|
||||
│ │ - KindredGui: Shared UI components, selection helpers ││
|
||||
│ │ - Theme integration hooks ││
|
||||
│ └─────────────────────────────────────────────────────────────┘│
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Layer 2: FreeCAD Python API │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐│
|
||||
│ │ FreeCAD, FreeCADGui, Part, PartDesign, Sketcher, Assembly ││
|
||||
│ └─────────────────────────────────────────────────────────────┘│
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Layer 1: FreeCAD Core (C++) │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐│
|
||||
│ │ App::Document, Part::Feature, PartDesign::Body, etc. ││
|
||||
│ └─────────────────────────────────────────────────────────────┘│
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 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
|
||||
## Boundary definitions
|
||||
|
||||
### Layer 1: FreeCAD Core (DO NOT MODIFY)
|
||||
**Location**: `src/Mod/PartDesign/App/`, `src/Mod/Part/App/`, etc.
|
||||
### Layer 1: FreeCAD Core -- do not modify
|
||||
|
||||
These are FreeCAD's fundamental data structures and should remain untouched:
|
||||
- `PartDesign::Body` - Feature container
|
||||
- `PartDesign::Pocket`, `PartDesign::Pad` - Additive/subtractive features
|
||||
- `Part::Feature` - Base geometric feature
|
||||
- `App::Document` - Document container
|
||||
- `Sketcher::SketchObject` - 2D constraint system
|
||||
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.
|
||||
|
||||
**Rationale**: Modifying these creates merge conflicts with upstream FreeCAD and risks breaking compatibility with existing FCStd files.
|
||||
### Layer 2: FreeCAD Python API -- use as-is
|
||||
|
||||
### Layer 2: FreeCAD Python API (USE AS-IS)
|
||||
**Access via**: `import FreeCAD`, `import FreeCADGui`, `import Part`, etc.
|
||||
The Python API provides everything needed for feature creation, command registration, and geometry access. ZTools and Silo operate entirely through this layer.
|
||||
|
||||
The Python API provides everything needed for feature creation:
|
||||
- Create objects: `body.newObject("PartDesign::Pocket", "Pocket")`
|
||||
- Set properties: `pocket.Length = 10.0`
|
||||
- Register commands: `FreeCADGui.addCommand("Name", CommandClass())`
|
||||
- Access geometry: `shape.Faces`, `shape.Edges`, `shape.Vertexes`
|
||||
### Layer 3: Kindred Bootstrap -- `src/Mod/Create/`
|
||||
|
||||
### Layer 3: Kindred Core Extensions (NEW - MINIMAL)
|
||||
**Location**: `src/Mod/Kindred/` (to be created)
|
||||
The Create module is a thin Python loader that:
|
||||
- Adds `mods/` addon paths to `sys.path` and executes their `Init.py`/`InitGui.py` files
|
||||
- Installs `SiloMenuManipulator` for global File menu/toolbar injection
|
||||
- Sets up deferred Silo dock panels (auth, activity) via `QTimer`
|
||||
- Handles first-start configuration
|
||||
|
||||
A thin C++ module providing capabilities that cannot be achieved in pure Python:
|
||||
This layer does not contain C++ code. It uses FreeCAD's `WorkbenchManipulator` API for menu/toolbar injection.
|
||||
|
||||
| Component | Purpose | Justification |
|
||||
|-----------|---------|---------------|
|
||||
| `CreateFeatures` | Custom PartDesign-like features | Python feature objects have performance limitations for complex boolean operations |
|
||||
| `CreateGui` | Shared UI utilities | Common selection helpers, task panel base classes |
|
||||
| `ThemeHooks` | Theme application entry points | Ensure theme applies before any workbench loads |
|
||||
### Layer 4: Kindred Workbenches -- `mods/`
|
||||
|
||||
**Namespace**: All Kindred Create features use the `Create::` prefix (e.g., `Create::FlipPocket`).
|
||||
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.
|
||||
|
||||
**Design principle**: Only add C++ code when Python cannot achieve the requirement. Document why each component exists.
|
||||
---
|
||||
|
||||
### Layer 4: Kindred Workbenches (ADDON PATTERN)
|
||||
**Location**: `mods/ztools/`, `mods/silo/`
|
||||
## Phase status
|
||||
|
||||
Pure Python workbenches following FreeCAD's addon pattern:
|
||||
- Self-contained with `InitGui.py`, `Init.py`, `package.xml`
|
||||
- Register commands via `FreeCADGui.addCommand()`
|
||||
- Define toolbars/menus via `Workbench.appendToolbar()`
|
||||
- Can be developed/tested independently
|
||||
### Phase 1: Addon auto-loading -- DONE
|
||||
|
||||
## Detailed Integration Plan
|
||||
**Implementation:** `src/Mod/Create/Init.py` and `InitGui.py` load workbenches from `mods/` at startup using `exec()`. Addons degrade gracefully if submodule is absent.
|
||||
|
||||
### Phase 1: Addon Auto-Loading
|
||||
**Default workbench:** `ZToolsWorkbench` (set in `resources/preferences/KindredCreate/KindredCreate.cfg`).
|
||||
|
||||
**Goal**: ztools and Silo load automatically without user intervention.
|
||||
### Phase 2: Enhanced Pocket as C++ feature -- NOT STARTED
|
||||
|
||||
**Implementation**:
|
||||
**Goal:** Replace the Python boolean-operation workaround in `ZTools_EnhancedPocket` with a proper `Create::FlipPocket` C++ feature inheriting from `PartDesign::ProfileBased`.
|
||||
|
||||
1. **Create addon manifest** (`src/Mod/Kindred/addons.json`):
|
||||
```json
|
||||
{
|
||||
"builtin_addons": [
|
||||
{
|
||||
"name": "ztools",
|
||||
"path": "mods/ztools/ztools",
|
||||
"autoload": true,
|
||||
"workbench": "ZToolsWorkbench"
|
||||
},
|
||||
{
|
||||
"name": "silo",
|
||||
"path": "mods/silo/pkg/freecad",
|
||||
"autoload": true,
|
||||
"workbench": "SiloWorkbench"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
**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.
|
||||
|
||||
2. **Modify addon path discovery** (`src/Mod/Kindred/Init.py`):
|
||||
```python
|
||||
# Add mods/ directory to FreeCAD's module search path
|
||||
import FreeCAD
|
||||
import os
|
||||
**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
|
||||
|
||||
mods_dir = os.path.join(FreeCAD.getHomePath(), "mods")
|
||||
if os.path.isdir(mods_dir):
|
||||
for addon in os.listdir(mods_dir):
|
||||
addon_path = os.path.join(mods_dir, addon)
|
||||
if os.path.isdir(addon_path) and addon_path not in sys.path:
|
||||
sys.path.insert(0, addon_path)
|
||||
```
|
||||
**Decision:** Deferred. The Python approach is functional for current needs. Revisit when performance or feature-tree integration becomes a problem.
|
||||
|
||||
3. **Set default workbench** in preferences:
|
||||
```xml
|
||||
<!-- resources/preferences/KindredCreate/KindredCreate.cfg -->
|
||||
<FCText Name="StartUpModule">ZToolsWorkbench</FCText>
|
||||
```
|
||||
### Phase 3: Datum C++ helpers -- NOT STARTED (SUPERSEDED)
|
||||
|
||||
**Files to create/modify**:
|
||||
- Create: `src/Mod/Kindred/Init.py`
|
||||
- Create: `src/Mod/Kindred/InitGui.py`
|
||||
- Create: `src/Mod/Kindred/CMakeLists.txt`
|
||||
- Modify: `src/Mod/CMakeLists.txt` (add Kindred subdirectory)
|
||||
- Modify: `resources/preferences/KindredCreate/KindredCreate.cfg`
|
||||
**Original goal:** Create C++ geometry helper functions for datum calculations.
|
||||
|
||||
### Phase 2: Enhanced Pocket as Separate Feature
|
||||
**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.
|
||||
|
||||
**Goal**: "Flip Side to Cut" becomes a proper feature, not a command wrapper.
|
||||
**Decision:** Superseded by the AttachExtension approach. Only `tangent_to_cylinder` still uses manual placement (requires a vertex reference not currently collected by the UI).
|
||||
|
||||
**Current state** (in ztools):
|
||||
```python
|
||||
# ztools/commands/pocket_commands.py
|
||||
class ZTools_EnhancedPocket:
|
||||
def Activated(self):
|
||||
# Creates standard Pocket, then applies boolean Common
|
||||
# Workaround using existing features
|
||||
```
|
||||
### Phase 4: Theme system -- PARTIAL
|
||||
|
||||
**Proposed architecture**:
|
||||
**Goal:** Theme applies consistently at startup regardless of active workbench.
|
||||
|
||||
```
|
||||
src/Mod/Create/
|
||||
├── App/
|
||||
│ ├── CreateFeatures.cpp # Feature implementations
|
||||
│ ├── FeatureFlipPocket.cpp # Flip-side pocket feature
|
||||
│ └── FeatureFlipPocket.h
|
||||
├── Gui/
|
||||
│ ├── Command.cpp # Command registrations
|
||||
│ ├── TaskFlipPocket.cpp # Task panel
|
||||
│ └── ViewProviderFlipPocket.cpp
|
||||
└── CMakeLists.txt
|
||||
```
|
||||
**Current state:** The Catppuccin Mocha theme is set as the default via the KindredCreate preference pack. Four copies of the QSS file exist and must be kept in sync manually:
|
||||
1. `resources/preferences/KindredCreate/KindredCreate.qss` (canonical)
|
||||
2. `src/Gui/Stylesheets/KindredCreate.qss`
|
||||
3. `src/Gui/PreferencePacks/KindredCreate/KindredCreate.qss`
|
||||
4. `mods/ztools/CatppuccinMocha/CatppuccinMocha.qss`
|
||||
|
||||
**Feature design** (`Create::FlipPocket`):
|
||||
**Remaining work:** Eliminate QSS duplication via build-time copy or symlinks. Move theme responsibility out of ztools and into the Create module.
|
||||
|
||||
```cpp
|
||||
// Inherits from PartDesign::ProfileBased (same base as Pocket)
|
||||
class FeatureFlipPocket : public PartDesign::ProfileBased {
|
||||
public:
|
||||
// Properties (same as Pocket, plus flip flag)
|
||||
App::PropertyLength Length;
|
||||
App::PropertyEnumeration Type; // Dimension, ThroughAll, ToFirst, UpToFace
|
||||
App::PropertyBool Symmetric;
|
||||
App::PropertyBool FlipSide; // NEW: Cut outside instead of inside
|
||||
|
||||
// Implementation uses Boolean Common instead of Cut when FlipSide=true
|
||||
App::DocumentObjectExecReturn* execute();
|
||||
};
|
||||
```
|
||||
### Phase 5: Silo deep integration -- DONE
|
||||
|
||||
**Separation of concerns**:
|
||||
- **FreeCAD Core** (`PartDesign::Pocket`): Standard inside-cut behavior, unchanged
|
||||
- **Create Extension** (`Create::FlipPocket`): Outside-cut using boolean common
|
||||
- **ztools Workbench**: Provides UI command that creates `Create::FlipPocket`
|
||||
**Goal:** Silo commands available globally, not just in the Silo workbench.
|
||||
|
||||
**Files to create**:
|
||||
- `src/Mod/Create/App/FeatureFlipPocket.cpp`
|
||||
- `src/Mod/Create/App/FeatureFlipPocket.h`
|
||||
- `src/Mod/Create/Gui/TaskFlipPocket.cpp`
|
||||
- `src/Mod/Create/Gui/ViewProviderFlipPocket.cpp`
|
||||
**Implementation:** `SiloMenuManipulator` in `src/Mod/Create/InitGui.py` uses `FreeCADGui.addWorkbenchManipulator()` to inject Silo commands into the File menu and toolbar across all workbenches. `Silo_ToggleMode` provides a one-click swap of Ctrl+O/S/N between standard FreeCAD and Silo file commands.
|
||||
|
||||
**ztools update**:
|
||||
```python
|
||||
# mods/ztools/ztools/commands/pocket_commands.py
|
||||
class ZTools_EnhancedPocket:
|
||||
def Activated(self):
|
||||
# Now creates Create::FlipPocket instead of workaround
|
||||
body = FreeCADGui.ActiveDocument.ActiveView.getActiveObject("pdbody")
|
||||
pocket = body.newObject("Create::FlipPocket", "FlipPocket")
|
||||
pocket.Profile = sketch
|
||||
# Show task panel...
|
||||
```
|
||||
**Dock panels:** Database Auth (1500ms) and Database Activity (4000ms) panels are created via deferred QTimers and docked in the right panel area.
|
||||
|
||||
### Phase 3: Datum System Integration
|
||||
### Phase 6: Build system integration -- PARTIAL
|
||||
|
||||
**Goal**: ztools datum creation uses stable, efficient C++ geometry calculations.
|
||||
**Goal:** CMake install rules for `mods/` submodules so packages include ztools and Silo automatically.
|
||||
|
||||
**Current state**: Pure Python geometry calculations in `ztools/datums/core.py`.
|
||||
**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.
|
||||
|
||||
**Issue**: Python geometry operations can be slow and less precise for complex cases.
|
||||
|
||||
**Proposed solution**: Create C++ helper functions, expose via Python.
|
||||
|
||||
```cpp
|
||||
// src/Mod/Create/App/DatumHelpers.cpp
|
||||
namespace Create {
|
||||
// Calculate midplane between two parallel faces
|
||||
gp_Pln computeMidplane(const TopoDS_Face& face1, const TopoDS_Face& face2);
|
||||
|
||||
// Calculate plane through three points
|
||||
gp_Pln computePlaneFrom3Points(gp_Pnt p1, gp_Pnt p2, gp_Pnt p3);
|
||||
|
||||
// Calculate axis at cylinder center
|
||||
gp_Ax1 computeCylinderAxis(const TopoDS_Face& cylinderFace);
|
||||
|
||||
// ... other datum calculations ...
|
||||
}
|
||||
```
|
||||
|
||||
**Python binding**:
|
||||
```python
|
||||
# In ztools after Create module is available
|
||||
from Create import DatumHelpers
|
||||
|
||||
plane = DatumHelpers.computeMidplane(face1, face2)
|
||||
```
|
||||
|
||||
**Separation of concerns**:
|
||||
- **FreeCAD Core** (`PartDesign::DatumPlane`): Data structure, unchanged
|
||||
- **Create Extension** (`DatumHelpers`): Geometry calculation utilities
|
||||
- **ztools Workbench**: UI, selection handling, property storage
|
||||
|
||||
### Phase 4: Theme System Refinement
|
||||
|
||||
**Goal**: Theme applies consistently at startup, no workbench dependency.
|
||||
|
||||
**Current state**: Theme applied when ztools workbench activates.
|
||||
|
||||
**Issue**: If user opens FreeCAD and doesn't activate ztools, theme isn't applied.
|
||||
|
||||
**Proposed solution**:
|
||||
|
||||
1. **Move theme to Create module** (`src/Mod/Create/InitGui.py`):
|
||||
```python
|
||||
# This runs at GUI startup, before any workbench
|
||||
def applyKindredTheme():
|
||||
from PySide import QtWidgets
|
||||
qss_path = os.path.join(FreeCAD.getResourceDir(),
|
||||
"preferences", "KindredCreate", "KindredCreate.qss")
|
||||
with open(qss_path) as f:
|
||||
QtWidgets.QApplication.instance().setStyleSheet(f.read())
|
||||
|
||||
# Apply spreadsheet colors
|
||||
applySpreadsheetColors()
|
||||
|
||||
# Run at import time
|
||||
applyKindredTheme()
|
||||
```
|
||||
|
||||
2. **Remove theme code from ztools**: ztools focuses on commands, not theming.
|
||||
|
||||
3. **Ensure load order**: Create module loads before other workbenches via `src/Mod/CMakeLists.txt` ordering.
|
||||
|
||||
### Phase 5: Silo Deep Integration
|
||||
|
||||
**Goal**: Silo commands available globally, not just in Silo workbench.
|
||||
|
||||
**Current state**: Must switch to Silo workbench to access commands.
|
||||
|
||||
**Proposed solution**:
|
||||
|
||||
1. **Global menu registration** (`src/Mod/Create/InitGui.py`):
|
||||
```python
|
||||
def setupSiloMenu():
|
||||
# Add Silo menu to menu bar regardless of active workbench
|
||||
import silo_commands
|
||||
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
menuBar = mw.menuBar()
|
||||
|
||||
siloMenu = QtWidgets.QMenu("Silo", mw)
|
||||
menuBar.addMenu(siloMenu)
|
||||
|
||||
for cmd in ["Silo_Open", "Silo_Save", "Silo_Commit", "Silo_Pull", "Silo_Push"]:
|
||||
action = FreeCADGui.Command.get(cmd).getAction()
|
||||
siloMenu.addAction(action[0])
|
||||
```
|
||||
|
||||
2. **Keyboard shortcuts** (global):
|
||||
```python
|
||||
# Ctrl+Shift+O: Silo Open
|
||||
# Ctrl+Shift+S: Silo Save
|
||||
# Ctrl+Shift+C: Silo Commit
|
||||
```
|
||||
|
||||
3. **Status bar integration**: Show current Silo item info in status bar.
|
||||
|
||||
### Phase 6: Build System Integration
|
||||
|
||||
**Goal**: mods/ submodules installed correctly during build.
|
||||
|
||||
**Implementation** (`src/Mod/Create/CMakeLists.txt`):
|
||||
**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 ztools workbench
|
||||
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(FILES ${CMAKE_SOURCE_DIR}/mods/ztools/package.xml
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/ztools)
|
||||
|
||||
# Install Silo workbench
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/mods/silo/pkg/freecad/
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/Mod/Silo)
|
||||
```
|
||||
|
||||
## File Organization Summary
|
||||
---
|
||||
|
||||
### New files to create
|
||||
## Design decisions
|
||||
|
||||
```
|
||||
src/Mod/Create/ # NEW: Kindred Create core extensions
|
||||
├── CMakeLists.txt
|
||||
├── Init.py # Addon path setup
|
||||
├── InitGui.py # Theme application, global menus
|
||||
├── App/
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── CreateModule.cpp # Module registration
|
||||
│ ├── FeatureFlipPocket.cpp/h # Flip-side pocket feature
|
||||
│ └── DatumHelpers.cpp/h # Datum geometry utilities
|
||||
└── Gui/
|
||||
├── CMakeLists.txt
|
||||
├── CreateGuiModule.cpp
|
||||
├── Command.cpp # Create-specific commands
|
||||
├── TaskFlipPocket.cpp/h
|
||||
└── ViewProviderFlipPocket.cpp/h
|
||||
```
|
||||
1. **`Create::` namespace prefix.** All Kindred Create features use this prefix to distinguish them from FreeCAD core.
|
||||
|
||||
### Files to modify
|
||||
2. **No upstream contribution.** Kindred Create is a standalone product. This allows divergent design decisions without upstream coordination.
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `src/Mod/CMakeLists.txt` | Add `add_subdirectory(Create)` |
|
||||
| `resources/preferences/KindredCreate/KindredCreate.cfg` | Set default workbench |
|
||||
| `mods/ztools/ztools/commands/pocket_commands.py` | Use `Create::FlipPocket` |
|
||||
| `mods/ztools/ztools/datums/core.py` | Use `Create.DatumHelpers` when available |
|
||||
3. **Silo server distributed separately.** Users deploy the Silo server independently. Setup instructions live in `mods/silo/README.md`.
|
||||
|
||||
### Files to remove/deprecate from ztools
|
||||
|
||||
| File | Reason |
|
||||
|------|--------|
|
||||
| `ztools/resources/theme.py` | Moved to Create module |
|
||||
| Theme application in `InitGui.py` | Handled globally |
|
||||
|
||||
## Implementation Priority
|
||||
|
||||
| Priority | Phase | Effort | Impact |
|
||||
|----------|-------|--------|--------|
|
||||
| 1 | Phase 1: Addon Auto-Loading | Low | High - Seamless user experience |
|
||||
| 2 | Phase 4: Theme System | Low | High - Consistent appearance |
|
||||
| 3 | Phase 5: Silo Global Menu | Medium | High - Always-available database access |
|
||||
| 4 | Phase 2: Enhanced Pocket | High | Medium - Proper feature architecture |
|
||||
| 5 | Phase 3: Datum Helpers | Medium | Medium - Performance improvement |
|
||||
| 6 | Phase 6: Build System | Low | High - Clean distribution |
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- Create feature creation and execution
|
||||
- Datum helper calculations
|
||||
- Theme application verification
|
||||
|
||||
### Integration Tests
|
||||
- Addon auto-loading on fresh install
|
||||
- Feature creation via ztools commands
|
||||
- Silo operations with mock server
|
||||
- Theme persistence across sessions
|
||||
|
||||
### Compatibility Tests
|
||||
- Open existing FCStd files (no regressions)
|
||||
- Export to STEP/IGES (geometry unchanged)
|
||||
- Upstream FreeCAD file compatibility
|
||||
|
||||
## Migration Notes
|
||||
|
||||
### For existing ztools/silo users
|
||||
- No changes required - workbenches continue to function
|
||||
- Enhanced features available automatically when Create module present
|
||||
- Theme applies globally instead of per-workbench
|
||||
|
||||
### For developers
|
||||
- ztools can check for Create module availability:
|
||||
```python
|
||||
try:
|
||||
import Create
|
||||
HAS_CREATE = True
|
||||
except ImportError:
|
||||
HAS_CREATE = False
|
||||
|
||||
# Use C++ implementation if available, fall back to Python
|
||||
if HAS_CREATE:
|
||||
plane = Create.DatumHelpers.computeMidplane(f1, f2)
|
||||
else:
|
||||
plane = compute_midplane_python(f1, f2)
|
||||
```
|
||||
|
||||
## Design Decisions
|
||||
|
||||
1. **Naming convention**: Kindred Create features use the `Create::` prefix (e.g., `Create::FlipPocket`, `Create::DatumHelpers`) to clearly identify them as Kindred Create extensions separate from FreeCAD core.
|
||||
|
||||
2. **Upstream contribution**: Kindred Create is a standalone product and does not plan to contribute features upstream to FreeCAD. This allows for divergent design decisions optimized for Kindred Create's target use cases.
|
||||
|
||||
3. **Silo server distribution**: Silo server is distributed separately from Kindred Create. Users download and deploy the Silo server independently. Setup instructions are documented in `mods/silo/README.md`.
|
||||
|
||||
4. **Version synchronization**: ztools and Silo versions are determined by pinned git submodule commits. Updates are deliberate and tested before each Kindred Create release. To update:
|
||||
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 to <version>"
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user