Files
create/docs/src/reference/datum-creator.md
forbes e443538548
Some checks failed
Build and Test / build (pull_request) Has been cancelled
docs: Datum Creator system reference (#141)
Document the ZTools Datum Creator: SelectionItem geometry classification,
16 creation modes (7 plane, 4 axis, 5 point), auto-detection scoring
algorithm, task panel UI layout, parameter sections, dispatch to
datums/core.py, and core implementation details.
2026-02-14 13:22:43 -06:00

7.8 KiB

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.