docs: Datum Creator system reference #212
@@ -50,6 +50,7 @@
|
||||
# Reference
|
||||
|
||||
- [Configuration](./reference/configuration.md)
|
||||
- [Datum Creator](./reference/datum-creator.md)
|
||||
- [Glossary](./reference/glossary.md)
|
||||
|
||||
# C++ API Reference
|
||||
|
||||
177
docs/src/reference/datum-creator.md
Normal file
177
docs/src/reference/datum-creator.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# Datum Creator System
|
||||
|
||||
The ZTools Datum Creator (`ZTools_DatumCreator`) creates parametric datum planes, axes, and points. It auto-detects the datum type from selected geometry and provides a unified task panel with 16 creation modes.
|
||||
|
||||
**Source files:**
|
||||
|
||||
- `mods/ztools/ztools/ztools/commands/datum_commands.py` -- UI, selection handling, mode detection
|
||||
- `mods/ztools/ztools/ztools/datums/core.py` -- geometry computation and FreeCAD object creation
|
||||
|
||||
## Geometry Classification
|
||||
|
||||
The `SelectionItem` class wraps a selected geometry element and classifies it into one of seven types:
|
||||
|
||||
| Type | Detection | Icon |
|
||||
|------|-----------|------|
|
||||
| face | Planar `Part.Face` or object with "Plane" in TypeId | ▢ |
|
||||
| plane | Datum plane objects or planar faces | ▣ |
|
||||
| cylinder | `Part.Face` with `Surface.Cylinder` | ◎ |
|
||||
| edge | `Part.Edge` with `Part.Line` curve | ― |
|
||||
| circle | `Part.Edge` with `Part.Circle` or `Part.ArcOfCircle` | ○ |
|
||||
| vertex | `Part.Vertex` | • |
|
||||
| unknown | Unclassified geometry | ? |
|
||||
|
||||
Classification flow:
|
||||
|
||||
1. Extract shape from object using the sub-element name (Face#, Edge#, Vertex#)
|
||||
2. Check shape type (Face, Edge, Vertex)
|
||||
3. For faces: check `surface.isPlanar()` or `isinstance(surface, Part.Cylinder)`
|
||||
4. For edges: check curve type (Line, Circle, ArcOfCircle)
|
||||
5. Fall back to `unknown`
|
||||
|
||||
## Creation Modes
|
||||
|
||||
### Planes (7 modes)
|
||||
|
||||
| Mode | Required Selection | Parameters | Description |
|
||||
|------|--------------------|------------|-------------|
|
||||
| `offset_face` | 1 face | distance (mm) | Plane parallel to face at offset |
|
||||
| `offset_plane` | 1 plane | distance (mm) | Plane parallel to datum plane at offset |
|
||||
| `midplane` | 2 faces | -- | Plane halfway between two parallel faces |
|
||||
| `3_points` | 3 vertices | -- | Plane through three non-collinear points |
|
||||
| `normal_edge` | 1 edge | position (0--1) | Plane perpendicular to edge at parameter |
|
||||
| `angled` | 1 face + 1 edge | angle (deg) | Plane at angle to face, rotating about edge |
|
||||
| `tangent_cyl` | 1 cylinder | angle (deg) | Plane tangent to cylinder at angular position |
|
||||
|
||||
### Axes (4 modes)
|
||||
|
||||
| Mode | Required Selection | Parameters | Description |
|
||||
|------|--------------------|------------|-------------|
|
||||
| `axis_2pt` | 2 vertices | -- | Axis through two points |
|
||||
| `axis_edge` | 1 edge | -- | Axis along linear edge |
|
||||
| `axis_cyl` | 1 cylinder | -- | Axis along cylinder centerline |
|
||||
| `axis_intersect` | 2 planes | -- | Axis at intersection of two planes |
|
||||
|
||||
### Points (5 modes)
|
||||
|
||||
| Mode | Required Selection | Parameters | Description |
|
||||
|------|--------------------|------------|-------------|
|
||||
| `point_vertex` | 1 vertex | -- | Point at vertex location |
|
||||
| `point_xyz` | (none) | x, y, z (mm) | Point at explicit coordinates |
|
||||
| `point_edge` | 1 edge | position (0--1) | Point at parameter location on edge |
|
||||
| `point_face` | 1 face | -- | Point at center of mass of face |
|
||||
| `point_circle` | 1 circle | -- | Point at center of circular edge |
|
||||
|
||||
## Auto-Detection Algorithm
|
||||
|
||||
The `_match_score()` method scores how well the current selection matches each mode's required types.
|
||||
|
||||
**Scoring:**
|
||||
|
||||
1. If the selection has fewer items than required, score is **0** (no match).
|
||||
2. For each required type, find a matching selected type using fuzzy matching:
|
||||
- `face` requirement matches `face` or `cylinder`
|
||||
- `edge` requirement matches `edge` or `circle`
|
||||
- All other types require exact match
|
||||
3. Score calculation:
|
||||
- **Exact cardinality** (selection count == required count): score = `100 + matched_count`
|
||||
- **Over-selected** (more items than required): score = `matched_count`
|
||||
- **No match**: score = `0`
|
||||
|
||||
The mode with the highest score wins. On each selection change, `update_mode_from_selection()` re-evaluates all 16 modes and activates the best match.
|
||||
|
||||
The detected mode is displayed with a category color:
|
||||
|
||||
- Planes: Mauve (#cba6f7)
|
||||
- Axes: Teal (#94e2d5)
|
||||
- Points: Yellow (#f9e2af)
|
||||
|
||||
## Task Panel UI
|
||||
|
||||
```
|
||||
+-------------------------------------+
|
||||
| ZTools Datum Creator |
|
||||
+-------------------------------------+
|
||||
| Selection |
|
||||
| [icon] Element Name [Remove] |
|
||||
| [Add Selected] [Remove] [Clear] |
|
||||
+-------------------------------------+
|
||||
| Datum Type |
|
||||
| DETECTED MODE (colored) |
|
||||
| Override: [dropdown] |
|
||||
+-------------------------------------+
|
||||
| Parameters (dynamic per mode) |
|
||||
| Offset: [spinner] mm |
|
||||
| Angle: [spinner] deg |
|
||||
| Position: [spinner] 0-1 |
|
||||
| X/Y/Z: [spinner] mm |
|
||||
+-------------------------------------+
|
||||
| Options |
|
||||
| [ ] Link to Spreadsheet |
|
||||
| [x] Add to Active Body |
|
||||
| [ ] Custom Name: [text] |
|
||||
+-------------------------------------+
|
||||
| [OK] [Cancel] |
|
||||
+-------------------------------------+
|
||||
```
|
||||
|
||||
### Selection table
|
||||
|
||||
Three columns: type icon (28px), element name (stretch), remove button (28px). Duplicates are rejected. A FreeCAD `SelectionObserver` keeps the "Add Selected" button state synchronized with the active 3D selection.
|
||||
|
||||
### Mode override
|
||||
|
||||
The dropdown lists all 16 modes prefixed by category (`[P]` plane, `[A]` axis, `[Pt]` point). Selecting a mode disables auto-detection until "(Auto-detect)" is re-selected.
|
||||
|
||||
### Parameters section
|
||||
|
||||
Rebuilt dynamically when the mode changes. Only the parameter widgets relevant to the active mode are shown. Modes with no parameters hide the section entirely.
|
||||
|
||||
### Options
|
||||
|
||||
- **Link to Spreadsheet**: creates a spreadsheet alias and expression-links the datum parameter (offset, angle, coordinates) for parametric control.
|
||||
- **Add to Active Body**: when checked, creates a `PartDesign::Plane/Line/Point` inside the active body. When unchecked, creates a document-level `Part::Plane/Line/Vertex`.
|
||||
- **Custom Name**: overrides the auto-generated name (format: `ZPlane_Offset_001`).
|
||||
|
||||
## Dispatch to core.py
|
||||
|
||||
`DatumCreatorTaskPanel.accept()` calls `create_datum()`, which:
|
||||
|
||||
1. Reads the current mode, body, name, and parameters from the UI
|
||||
2. Extracts `SelectionItem` objects by type
|
||||
3. Dispatches to the corresponding `core.*` function:
|
||||
|
||||
| Mode | Core function |
|
||||
|------|---------------|
|
||||
| `offset_face` | `core.plane_offset_from_face(face, distance, ...)` |
|
||||
| `offset_plane` | `core.plane_offset_from_plane(plane, distance, ...)` |
|
||||
| `midplane` | `core.plane_midplane(face1, face2, ...)` |
|
||||
| `3_points` | `core.plane_from_3_points(p1, p2, p3, ...)` |
|
||||
| `normal_edge` | `core.plane_normal_to_edge(edge, parameter, ...)` |
|
||||
| `angled` | `core.plane_angled(face, edge, angle, ...)` |
|
||||
| `tangent_cyl` | `core.plane_tangent_to_cylinder(face, angle, ...)` |
|
||||
| `axis_2pt` | `core.axis_from_2_points(p1, p2, ...)` |
|
||||
| `axis_edge` | `core.axis_from_edge(edge, ...)` |
|
||||
| `axis_cyl` | `core.axis_cylinder_center(face, ...)` |
|
||||
| `axis_intersect` | `core.axis_intersection_planes(plane1, plane2, ...)` |
|
||||
| `point_vertex` | `core.point_at_vertex(vertex, ...)` |
|
||||
| `point_xyz` | `core.point_at_coordinates(x, y, z, ...)` |
|
||||
| `point_edge` | `core.point_on_edge(edge, parameter, ...)` |
|
||||
| `point_face` | `core.point_center_of_face(face, ...)` |
|
||||
| `point_circle` | `core.point_center_of_circle(edge, ...)` |
|
||||
|
||||
## Core Implementation
|
||||
|
||||
Each `core.*` function:
|
||||
|
||||
1. Creates the FreeCAD object (`PartDesign::Plane` in a body, `Part::Plane` at document level)
|
||||
2. Computes the placement from the source geometry
|
||||
3. Configures attachment (MapMode, AttachmentSupport, offset) for parametric updates
|
||||
4. Stores ZTools metadata in custom properties:
|
||||
- `ZTools_Type` -- creation method identifier (e.g. `"offset_from_face"`)
|
||||
- `ZTools_Params` -- parameters as JSON (e.g. `{"distance": 10}`)
|
||||
- `ZTools_SourceRefs` -- source geometry references as JSON
|
||||
5. Applies Catppuccin Mocha styling (mauve at 70% transparency for planes)
|
||||
6. Optionally links parameters to a spreadsheet alias
|
||||
|
||||
Auto-naming uses the format `ZPlane_Offset_001`, incrementing the index for each new datum of the same type.
|
||||
Reference in New Issue
Block a user