Table of Contents

SGT (Super Girt Tool)

Overview

The Super Girt Tool (SGT) is a Revit add-in for placing and managing structural steel girts and opening framing members (jambs, headers, sills) on foundation walls. It supports both host document walls and walls in linked Revit models.

See also: Specification (Internal)

Source: src/Tools/Structural/SGT/manifest.yml:7-8

Location: src/Tools/Structural/SGT/

Tool ID: DBTools.SGT

Ribbon Location: Structural group, order 40

Features

Core Functionality

Feature Description
Wall Selection Select linked walls or host foundation walls for girt placement
Girt Placement Auto-seed girts at configurable elevations with smart spacing
Opening Framing Automatic detection and framing of openings (jambs, headers, sills)
Live Preview Real-time 2D elevation and 3D preview of proposed framing
Extent Control Configure girt extents by wall length, grids, openings, or manual distances
Edit Mode Modify previously placed SGT systems with host-change reconciliation

Source: src/Tools/Structural/SGT/Features/Commands/SgtNewCommand.cs:36-39

Contextual Edit Launch

The contextual Edit SGT Wall flow pre-creates its ExternalEvent during API-safe injector lifecycle work (InitializeAsync / RefreshAsync) and only calls Raise() from the ribbon click handler. This avoids Revit invalid-context failures when ribbon callbacks run outside standard API execution.

Source: src/Tools/Structural/SGT/Shell/Commands/ContextualRibbonInjector.cs:59
Source: src/Tools/Structural/SGT/Shell/Commands/ContextualRibbonInjector.cs:106
Source: src/Tools/Structural/SGT/Shell/Commands/ContextualRibbonInjector.cs:424

Execution Logging Density (2026-02-09)

SGT debug logging was reduced to emphasize actionable summaries over high-frequency event/probe noise:

  • Hook executor start/completion logs are suppressed for background contextual/view hook refresh paths.
  • Analyze Step 1/2/3 now emits compact preflight summaries ([SGT.PreflightSummary]) and opening summaries.
  • Orientation analysis keeps one Debug summary per solved/failed role ([SGT.Orientation.Summary]), while detailed probe diagnostics are Trace.
  • Temp transaction lifecycle logs ([SGT.TempTx.*]) and per-member placement diagnostics are now Trace, with warnings/errors preserved.

Source: src/DBTools.Core/Tools/DbtHookHost.cs:153
Source: src/DBTools.Core/Revit/UI/ContextualRibbonInjectorBase.cs:293
Source: src/Tools/Structural/SGT/Features/Placement/Steps/PlanBuilder.Step1Calibrate.cs:151
Source: src/Tools/Structural/SGT/Features/Placement/PlanBuilder.Helpers.cs:565
Source: src/Tools/Structural/SGT/Features/Placement/Steps/PlanBuilder.Step2Analyze.cs:310
Source: src/Tools/Structural/SGT/Features/Placement/Steps/PlanBuilder.Step3Warm.cs:481
Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:828
Source: src/Tools/Structural/SGT/Features/Placement/TempTransaction.cs:74
Source: src/Tools/Structural/SGT/Features/Placement/Writers/DomainWriter.MemberPlacement.cs:431

Supported Wall Types

  • Linked Walls: Walls from Revit link instances (any function)
  • Host Foundation Walls: Foundation walls in the host document (WallFunction.Foundation)

Source: src/Tools/Structural/SGT/Features/Commands/SgtNewCommand.cs:96-99

Supported Framing Types

The tool supports structural framing families filtered by shape:

Shape Category Girts Opening Members Notes
C Shapes Yes Yes Default: C10X15.3
MC Shapes Yes Yes Miscellaneous channels
Z Shapes Yes No Intentionally excluded for openings
Angle Shapes Yes No Girt-only; short leg seats elevation and long leg seats exterior plane
HSS (Tube) Yes Yes Square + rectangular role-aware seating/orientation mapping

Source: src/Tools/Structural/SGT/Features/WallAnalysis/FamilySymbolClassifier.cs:158

Architecture

SGT follows a domain-driven MVVM architecture with clear separation between UI, domain logic, and Revit API interactions.

src/Tools/Structural/SGT/
+-- Features/            # Feature-specific code
|   +-- AnalyzeWall/     # Wall analysis services
|   +-- Commands/        # Revit external commands
|   +-- Girts/           # Girt management services
|   +-- Openings/        # Opening detection
|   +-- Orientation/     # Family orientation analysis
|   +-- Place/           # Placement orchestration
|   +-- Preview/         # 2D/3D preview rendering
|   +-- Reconcile/       # Host-change reconciliation
+-- Shell/               # UI layer
|   +-- Composition/     # DI registration
|   +-- DesignTime/      # Design-time ViewModels
|   +-- UI/              # Views and ViewModels
+-- Shared/              # Cross-feature services
    +-- Contracts/       # Interfaces and DTOs
    +-- Extents/         # Extent resolution
    +-- Hydration/       # Domain hydration
    +-- Kernel/          # Core domain
    |   +-- Domain/      # Domain entities (SgtPlan, SgtWall, etc.)
    |   +-- Geometry/    # Geometry utilities
    |   +-- State/       # State management
    |   +-- Units/       # Unit conversion service
    +-- PreviewModels/   # Preview data models
    +-- Revit/           # Revit adapters
    +-- UiModels/        # UI-bound row items (SgtGirtRowItem, etc.)

Key Design Patterns

Single Source of Truth (SSOT)

The SgtPlan object serves as the single source of truth for all SGT operations. It contains:

  • Wall geometry and context (host/linked)
  • Girt row configurations
  • Opening row configurations
  • Eligible framing types
  • Pre-computed orientation data
  • Grid positions

Source: src/Tools/Structural/SGT/Shared/Kernel/Domain/SgtPlan.cs:10-14

Plan Store Pattern

The ISgtPlanStore interface provides centralized plan state management with change notifications:

public interface ISgtPlanStore
{
    SgtPlan? Plan { get; }
    event EventHandler<PlanChangedEventArgs>? PlanChanged;
    void SetPlan(SgtPlan plan);
    void Clear();
}

Source: src/Tools/Structural/SGT/Shared/Contracts/ISgtPlanStore.cs

Orchestrator Pattern

The SgtOrchestrator coordinates validation, domain object creation, and placement/update operations:

  1. Validate - Check plan integrity and extent resolution
  2. Build Domain - Create SgtWall with SgtMember and SgtOpening aggregates
  3. Hydrate - Resolve segments and connectivity
  4. Persist - Write to Revit document via ISgtDomainWriter

Source: src/Tools/Structural/SGT/Features/Place/Logic/SgtOrchestrator.cs:17-40

UI Components

Main Window

Class: ShellWindow (WPF Window)
ViewModel: ShellWindowViewModel

Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:1

The main window is a 1600x950 modal dialog with three main regions:

  1. Left Panel: Configuration

    • Scope controls (wall offset, layer selection)
    • Girts expander with DataGrid + Segment Flyout (per-segment editing)
    • Openings expander with DataGrid + Segment Flyout (role + per-segment editing)
    • Bulk edit flyout (in-window overlay)
  2. Center Splitter: Resizable divider

  3. Right Panel: Preview

    • 2D elevation view
    • 3D view (using HelixToolkit)
    • Overlay preview mode/zoom controls

Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:392

Girt Grid Columns

Column Property Description
Elevation ElevationText Vertical position (feet-inches format)
Girt Type GirtTypeId Family type selection
Rotation Rotation Cross-section rotation (0/90/180/270)
Y Justification YJustification Lateral positioning
Z Justification ZJustification Vertical positioning
Flip FlipFacing Mirror orientation (Facing flip)

Segmented girt groups use the Segment Flyout. The chevron appears only on the group leader (ShowSegmentGroupExpander) and opens an in-window flyout overlay containing per-segment edit rows (Type/Rotation/Y/Z/Flip + delete). The flyout opens anchored to the chevron (clamped inside the window) and resets to a consistent default size/position on each open; when resized, extra width should go to the Type column while the rest of the row controls keep their relative alignment/gaps.

Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:470
Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:1910
Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:1996
Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml.cs:790
Source: src/Tools/Structural/SGT/Shell/ViewModels/GirtRowViewModel.cs:67

Opening Grid Columns

Each opening row supports four framing roles with independent configuration:

  • Left Jamb: Vertical member at opening left edge
  • Right Jamb: Vertical member at opening right edge
  • Header: Horizontal member at opening top
  • Sill: Horizontal member at opening bottom (optional)

Source: src/Tools/Structural/SGT/Shared/Kernel/Domain/OpeningRoleRules.cs

Opening member segments are edited via the Segment Flyout (opened from the chevron in the first column). The flyout shows role-level fields and, when segmented, per-segment child nodes for that role. It uses the same anchored-open and resize semantics as the girt segment flyout.

Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:760
Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:1910
Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:2048
Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml.cs:790
Source: src/Tools/Structural/SGT/Shell/ViewModels/Panes/SegmentFlyoutViewModel.cs:14

Preview Modes

Mode Description
Elevation 2D front elevation view with girts and openings
Section 2D section view of member profiles
3D Interactive 3D view with wall layers and framing

Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewMode.cs:4-9
Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:1051

Services

Dependency Injection

All SGT services are registered via SgtServiceCollectionExtensions.AddSgt():

Source: src/Tools/Structural/SGT/Shell/Composition/SgtServiceCollectionExtensions.cs:29-83

Core Services

Service Lifetime Purpose
ISgtPlanStore Singleton Plan state management
IUnitService Singleton Unit conversion
SgtValidationService Singleton Plan validation
ISgtSystemRepository Scoped Extensible storage access
SgtPersistenceService Scoped Plan persistence

Feature Services

Service Lifetime Purpose
RevitOpeningQuery Scoped Opening detection from walls
FamilyCalibrationService Scoped Family profile extraction
WallGeometryService Scoped Wall geometry analysis
SgtOrientationAdapter Scoped Family orientation computation
IExtentResolver Singleton Extent position resolution
SegmentResolutionService Singleton Girt segment computation
SgtAutoSeedingService Singleton Initial girt elevation seeding

Placement Services

Service Lifetime Purpose
ISgtPlanBuilder Transient Build plan from wall context
ISgtDomainWriter Transient Write domain objects to Revit
SgtOrchestrator Transient Coordinate placement flow

Smart Defaults Service

The SgtSmartDefaultsService applies automatic orientation defaults based on family analysis:

// For girts
SgtSmartDefaultsService.ApplySmartDefaultsForGirt(row, plan);

// For opening roles
SgtSmartDefaultsService.TryApplySmartDefaultsForOpeningRole(row, role, plan);

Source: src/Tools/Structural/SGT/Features/Girts/Services/SgtSmartDefaultsService.cs:43-70

Host Change Reconciliation

When editing an existing SGT system, the tool detects changes to the host wall:

  1. Diff Detection: Compare stored vs current wall geometry
  2. Missing Wall Handling: Options for re-link or delete
  3. Opening Actions: Sync/Move decisions now read current detected openings (manual M: openings still read editable plan rows)
  4. Manual-to-Real Mapping: Force-sync maps manual openings to DetectedOpenings, not stored opening snapshots
  5. Update Move Policy: Update runs move-first; move failures can be surfaced to UI and retried as delete/recreate

Source: src/Tools/Structural/SGT/Shell/Services/HostChangeReconciliationService.cs:398
Source: src/Tools/Structural/SGT/Domain/WriteContext.cs:1
Source: src/Tools/Structural/SGT/Features/Placement/DomainWriter.Updates.cs:369
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.CommandsAndBulk.cs:440

Elevation Drag Undo/Redo Coverage (2026-02-07)

Elevation preview drag/snap edits now record real do/undo command actions (not no-op redo stubs), and all snap edit paths share command-stack behavior:

  1. Girt extents (left/right) now execute as command-driven do/undo mutations so redo re-applies snapped extents.
  2. Opening member extents (jamb/header/sill endpoint snaps) now push undo/redo commands by cloning/restoring role config state.
  3. Opening geometry is non-interactive in preview: opening edges/rectangles are not draggable; preview handle edits apply only to girt and opening-member elements.

Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:130
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:681
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Handles.cs:395
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Handles.cs:977

Tab Cycling for Overlapping Handles (2026-02-15)

When multiple handles overlap in the elevation preview, Tab/Shift+Tab cycles nearby candidates, Enter confirms the highlighted handle, and Esc cancels the cycle. Candidates reset when the cursor moves beyond the cycle radius.

Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.CanvasInput.cs:980
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Core.cs:354
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Handles.cs:138

Snap Association Lock Rule (2026-02-07)

Elevation preview drag interactions are now documented and enforced as association-locked operations:

  1. No arbitrary drag targets are produced by snapping (FreeAlong quantized fallback is not used in drag/snap flow).
  2. Nearest valid association is always resolved (grid, wall edge, opening edge, or enabled vertical target like girt/wall top/wall bottom).
  3. Drag commit requires an accepted snapped target (Snapped=true + handle-specific target compatibility). Unsnapped nearest associations are preview-only and do not commit.
  4. Snap feedback is explicit during drag: all valid targets render as guide bands and the active guide/connection line is cyan when accepted and red when not accepted.
  5. Manual Along extents remain explicit form input behavior, not drag/snap output.

Source: src/Tools/Structural/SGT/Features/Preview/Snapping/ElevationSnapService.cs:46
Source: src/Tools/Structural/SGT/Features/Preview/Snapping/ElevationSnapIndex.cs:216
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Snapping.cs:359
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:89

Segment Endpoint Routing + Span Guard (2026-02-16)

Segment endpoint drag routing was hardened for bisected members:

  1. Only true outer boundaries update girt extents: first-segment left endpoint updates start extent, last-segment right endpoint updates end extent.
  2. Other segment endpoints remain opening-edge gap edits using opening-side metadata, avoiding opposite-end extent movement for bisected girts.
  3. Extent snaps now reject no-span outcomes before commit when opening subtraction would leave no valid segment.
  4. Opening-edge snap targets are global in elevation preview (not filtered to the selected opening row), so all eligible opening edges remain reachable during drag.

Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:1189
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:130
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Snapping.cs:18

Opening Segment Context Menu + Delete Lifecycle (2026-02-16)

Opening-segment interaction routing and deletion lifecycle were hardened:

  1. Selected-opening right-click routing now prefers segment geometry with wider member-band/radius hit testing so segmented jamb/header/sill regions resolve reliably.
  2. Segment hits now open segment-only context menus (Delete <Role> Segment N) and do not include row-level Delete Selected, preventing accidental opening-row deletes from segment clicks.
  3. Deleting the last segment now removes only that opening role first; the opening row is removed only when no roles remain on that opening.

Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.CanvasInput.cs:1472
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.CanvasInput.cs:1961
Source: src/Tools/Structural/SGT/Shell/ViewModels/Panes/OpeningsPaneViewModel.cs:394
Source: src/Tools/Structural/SGT/Shell/ViewModels/Panes/OpeningsPaneViewModel.cs:634

Opening Bypass + Auto-Join Contract (2026-02-12)

Drag/snap behavior for bisected girts now includes an explicit opening-bypass contract:

  1. Endpoint reassociation normalizes gap state: changing a girt endpoint association forces the touched endpoint gap override to 0.0, removes stale opening-edge map keys from the prior association, and seeds 0.0 for the new opening-edge map key when applicable.
  2. Interior opposite-edge snap auto-joins across opening: when an interior segment endpoint snaps to the opposite edge of the same opening, SGT auto-joins by adding the opening key to the row bypass set and removing opening-edge gap overrides for that opening.
  3. Bypass state drives preview + placement segmentation: bypassed openings are excluded from preview bisection and placement-time opening subtraction, yielding a single continuous member across that opening until the row is snapped back to that opening edge.

Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:204
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:1795
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:1843
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:1861
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.CoreAndEditing.cs:1565
Source: src/Tools/Structural/SGT/Features/Extents/SegmentResolutionService.cs:39
Source: src/Tools/Structural/SGT/Features/Placement/Orchestrator.cs:155

Preview Horizontal Transform/Projection + Segment Endpoint Ownership (2026-02-07)

Two WW/WS preview parity defects were hardened:

  1. Preview transform/projection semantics now use one coherent contract for all roles: profile transform is pure math (flip/rotation/justification) in member-local UV, and projection into depth/secondary respects analyzer-resolved yTargetsFlange for every role (no role forcing). This is required for families whose section axes are swapped (e.g., C Shapes resolving yTargetsFlange=false).
  2. Segment interior endpoint snapping commits by opening-edge identity (opening key + edge side) for all accepted snaps, so mirrored/rotated cases do not move the opposite endpoint due to transient segment indexing/topology.
  3. Opening-internal spans are placeable by contract: when a row anchors to opposite edges of the same opening, that opening is preserved for that row during span validation/hydration so placement does not fail with no-segment subtraction errors.
  4. Opening-role secondary-axis orientation is deterministic in both elevation and 3D: preview uses the same transformed profile loops + analyzer-resolved projection mapping directly (no centroid-based post-correction path).

Source: src/Tools/Structural/SGT/Features/Preview/OrientationSemanticsHelper.cs:66
Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:292
Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs:858
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:561 Source: src/Tools/Structural/SGT/Features/Extents/SegmentResolutionService.cs:31

Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:39
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:89
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:195
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:293
Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs:774
Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:284

Elevation Grid Marker Bubble Contrast (2026-02-07)

Grid markers in elevation preview now render as a white-filled circle with black stroke and centered black text to preserve readability on dark themes.

Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs:577

Preview/Placement Coordinate Parity (2026-02-06)

To remove mismatch between preview and placed members (especially for linked walls and opening jambs), SGT now shares the same direction/orientation semantics across analysis, preview, and placement:

  1. Opening T mapping now respects linked frame inversion
    Step 2 compares host-space wall curve direction against WallGeometry.Direction and flips opening T0/T1 when the frames are reversed.
  2. 3D preview now uses the shared depth-plane helper
    Preview layer offset and wall offset now resolve with the same helper used by placement.
  3. 3D section basis now uses canonical orientation rules
    Jamb/horizontal role transforms are built from exterior normal + axis cross products with consistent sign behavior.
  4. Opening role orientation now honors per-role Flip setting in placement path
  5. Opening-edge cutbacks now use gap-only trimming (no jamb face inset)
    Placement and preview segmentation both apply the same opening-edge gap value, eliminating oversized girt-to-jamb trims. Geometry-aware per-side bisection gaps now compute member extents from the same calibrated profile transforms used by preview/placement parity.
  6. Preview justification axis mapping now uses analyzer metadata
    OrientationResult.YTargetsFlange now propagates into preview rendering so Y/Z justifications target the same flange/web axes as placement behavior.
  7. Elevation/Section/3D now consume one shared preview semantics helper
    Justification deltas and orientation-map lookup are centralized and reused by all preview modes.
  8. Preview profile transform ordering now matches placement math
    Preview applies transforms as FlipFacing (mirror in family-local UV) → rotation → Y/Z justification, matching Revit's Facing reference-plane semantics and reducing jamb rotation/depth drift on linked walls.
  9. Opening orientation is strict: Step 2 must populate every role used ResolveYTargetsFlangeForOpening requires exact role-specific opening orientation data. There is no type-level majority-vote fallback and no girt-orientation fallback. If Step 2 did not populate orientation for a role, the pipeline throws [SpecFail/Preview/OrientationMissing].
  10. 3D/Elevation/Section profile transform + projection now use one shared preview semantics helper with explicit role contracts
    Transform semantics are analyzer-driven for all roles (yTargetsFlange preserved) and projection respects analyzer mapping for all roles: Y->Flange => depth=U,secondary=V, Y->Web => depth=V,secondary=U.
  11. Step 3 now stores exact Y/Z pair deltas per rotation for preview/gap parity Warmup records one 16-slot justification table per rotation/flip state instead of reconstructing mixed Y/Z choices from separable axis deltas. This keeps nested/transformed framing families aligned with Revit's true placement behavior.
  12. 3D opening diagnostics now include projection mapping for all opening roles
    Left/Right jamb, Header, and Sill debug entries now log the resolved projection mapping and anchor geometry for faster root-cause triage.
  13. Orientation analyzer probing is role-aware for rotated links
    Step 2 keeps canonical probes (0/90/180/270) for horizontal roles, and applies wall-azimuth residual compensation only for jamb roles during temporary orientation probing. Stored orientation outputs remain canonical quarter-turn values.
  14. Vertical preview/gap sign resolution now uses per-rotation jamb calibration Horizontal roles still use canonical sign calibration, but jamb preview and geometry-aware gap ordering now read the vertical basis/sign payload for the selected canonical rotation. This fixes perpendicular and off-axis wall cases without introducing preview-only azimuth compensation.
  15. Linked opening T mapping now follows frame-swap direction only
    Opening T mapping now uses the wall frame swap outcome directly (dirDot < 0) and no longer applies an additional mirrored-link XOR branch. This prevents mirrored+rotated linked walls from inverting opening side placement.
  16. Step 2 orientation seating is reflection-aware for mirrored links
    Analyzer Y/Z seating now applies a mirrored-aware flange-side rule when evaluating structural-plane seating: non-mirrored links require positive signed side, mirrored links require negative signed side, and web seating remains side-agnostic. This prevents mirrored-link runs from rejecting all girt types during orientation analysis.
  17. HSS role mapping is now explicit in Step 2
    Square HSS uses symmetric seating candidates (all non-endcap faces, no mirrored-side bias). Rectangular HSS now persists deep/shallow calibrated face-id sets and uses role-aware set assignment: horizontal roles seat deep faces at the exterior plane and shallow faces at the elevation/opening plane, while jamb roles invert that mapping so deep faces stay opening-edge-seated.
  18. ANGLE/Z shape contracts are now hard-enforced during analysis
    ANGLE calibration stores short-leg and long-leg face IDs (short=web-like, long=flange-like) and girt Y/Z solving filters to those faces. Z-shape girt validation now resolves flange pairs from aligned section faces and enforces exterior flange-down + interior flange-up ordering.
  19. Web seating mode is now explicit and deterministic in Step 2
    Analyzer resolves web-seat distance mode through a shape/role policy hook: open-section horizontals (Channel girt/head/sill, Z girt, Angle girt) use edge-contact web seating, while HSS profiles and jamb roles use face-coplanar web seating. This restores girt orientation pass behavior without relaxing closed-section seating gates.
  20. Non-HSS mapping no longer carries inferred HSS kind
    Step 2 now forces hssKind=Unknown for non-HSS shapes before role mapping, preventing non-HSS branch contamination from type-name fallback parsing.
  21. Step 2 rejects non-finite Y/Z metrics before ranking
    Candidate and pair evaluations now drop NaN/Infinity metrics, emit explicit rejection diagnostics, and include candidates, finiteCandidates, and rejectedNonFinite counts in fail-fast reasons for deterministic fatal-step triage.
  22. Opening-role web seating planes now anchor to wall-frame origin
    Head/Sill/Jamb web seating planes are created from wall-frame origin for deterministic opening-role Y/Z seating, eliminating origin-induced role drift across rotated/mirrored linked walls.
  23. Temp probe transactions now emit structured failure metadata and deterministic probe outcomes
    Temp probe transactions (Calibration, Orientation Probe, Warm Member Profile) remain rollback-only with independent work/rollback exception capture, but transaction-mode probes now capture failure-preprocessor metadata (blocking, warnings, lastResult, forbidden) through RunWithMetadata(...). Step 1/2/3 consumers now convert blocking metadata into explicit symbol/type failures (forbidden vs generic temp failure), preventing silent probe success when Revit reports blocking failures only through failure processing.
  24. Post-analyze overlay hides only after the first Elevation frame paints
    After successful plan hydration (_planStore.Initialize + RefreshFromPlan + AnalysisComplete), SGT forces Elevation mode, requests a preview refresh, and keeps the overlay visible until the Elevation preview has painted at least one frame (paint barrier). Failed/canceled analyzes skip this path; a Background safety refresh is still scheduled once the overlay is gone.
  25. Face traversal now resolves one geometry source per pass
    Face traversal prefers instance geometry and falls back to symbol geometry only when instance geometry is unavailable, preventing mixed stale/fresh candidate sets from double traversal.
  26. Square-HSS Y/Z probing now re-fetches candidate faces per iteration
    The Y/Z solver no longer reuses a pre-loop hssFaces snapshot. Symmetric HSS candidates are reloaded after each justification update/regenerate pass.
  27. Y/Z solver diagnostics and face-selection guards are now stronger
    Step 2 now emits per-pair [SGT.Orientation.YZ.PairProbe] diagnostics, deduplicates GetFacesByIds results by persistent face id, and uses Acceptance.SeatingTol (not 1e-6) for signed-side filtering.
  28. Preview jamb side ownership now uses frame-mapped opening T values directly Since Step 2 already maps opening T0/T1 by frame direction, preview no longer applies a second mirrored/frame-swap remap when selecting jamb sides. Elevation rendering, elevation handle/hit-test routing, and 3D endpoint generation bind OpeningRole.LeftJamb = screen-left = max(T0,T1) (higher T) and OpeningRole.RightJamb = screen-right = min(T0,T1) (lower T) directly.
  29. Entering 3D preview (and 3D Reset View) now uses a stable exterior “home” camera for mirrored/rotated links The 3D presenter derives a stable exterior normal from the wall frame, then resets the camera to an exterior 3/4 view with a slight downward pitch (instead of accidentally landing on an interior-facing view due to reflection/rotation transforms).
  30. OpeningRoleMapping is the authoritative physical↔visual role boundary Role.JambLeft (physical, −BasisX) maps to OpeningRole.RightJamb (visual, screen-right). Role.JambRight (physical, +BasisX) maps to OpeningRole.LeftJamb (visual, screen-left). All cross-enum bridges go through OpeningRoleMapping.ToOpeningRole() / ToPhysicalRole(). No ad-hoc inline Role↔OpeningRole mappings are permitted.

Source: src/Tools/Structural/SGT/Domain/OpeningRoleMapping.cs

Source: src/Tools/Structural/SGT/Features/Placement/Steps/PlanBuilder.Step2Analyze.cs:200
Source: src/Tools/Structural/SGT/Features/Placement/Steps/PlanBuilder.Step2Analyze.cs:446
Source: src/Tools/Structural/SGT/Features/WallAnalysis/WallGeometryContext.cs
Source: src/Tools/Structural/SGT/Features/WallAnalysis/WallGeometryService.cs
Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAdapter.cs:423
Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:170
Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:539
Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:42
Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:516
Source: src/Tools/Structural/SGT/Features/Placement/Orchestrator.cs:296
Source: src/Tools/Structural/SGT/Features/Placement/Writers/DomainWriter.MemberPlacement.cs:398
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.CoreAndEditing.cs:1801
Source: src/Tools/Structural/SGT/Domain/ValueObjects/OrientationResult.cs:17
Source: src/Tools/Structural/SGT/Features/Preview/OrientationSemanticsHelper.cs:36
Source: src/Tools/Structural/SGT/Features/Preview/OrientationSemanticsHelper.cs:101
Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs:743
Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs:1358
Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs:804
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Handles.cs:421
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.CanvasInput.cs:874
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.CanvasInput.cs:1600
Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:389
Source: src/Tools/Structural/SGT/Features/WallAnalysis/SymbolCalibrationService.cs:446
Source: src/Tools/Structural/SGT/Features/WallAnalysis/FamilyCalibrationData.cs:68
Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:583
Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:1035
Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:1406 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:885 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:292 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:309 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:415 Source: src/Tools/Structural/SGT/Features/Placement/TempTransaction.cs Source: src/Tools/Structural/SGT/Features/Placement/TempTransaction.cs:38 Source: src/Tools/Structural/SGT/Features/Placement/TempTransaction.cs:123 Source: src/Tools/Structural/SGT/Features/Placement/TempTransaction.cs:279 Source: src/Tools/Structural/SGT/Features/WallAnalysis/SymbolCalibrationService.cs:243 Source: src/Tools/Structural/SGT/Features/Placement/Steps/PlanBuilder.Step3Warm.cs:443 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:408 Source: src/Tools/Structural/SGT/Features/WallAnalysis/FaceSelectors.cs:20 Source: src/Tools/Structural/SGT/Features/WallAnalysis/FaceSelectors.cs:88 Source: src/Tools/Structural/SGT/Features/WallAnalysis/SymbolCalibrationService.cs:356 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:832 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:902 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:1369 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:1384 Source: src/Tools/Structural/SGT/Features/Orientation/OrientationAnalyzer.cs:1426 Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.AnalysisAndHydration.cs:210 Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.AnalysisAndHydration.cs:228 Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Viewport3D.cs:36 Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:64

3D Preview End-Cap Tessellation (2026-02-21)

SGT 3D preview now tessellates member end caps from the transformed section loops using EvenOdd fill across all contours (supports concave profiles and hollow sections). Caps use dedicated vertices (not shared with the side-wall extrusion) so lighting doesn’t smooth across the cap seam.

Source: src/Tools/Structural/SGT/Features/Preview/Geometry/SectionCapTriangulator.cs:18 Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:670

3D Preview Rendering + Navigation Refresh (2026-03-04)

Lighting: Deterministic four-light rig (front key, skylight, uplight, stronger ambient) keeps channel/Z concavities readable in dark theme without flattening the scene.

Materials: Steel diffuse colors are boosted toward white for readability, with tighter/brighter highlights (Specular=0.8, Shininess=64) and zero emissive noise; wall materials remain unboosted with zero specular.

Edge lines: Crease overlays stay fixed-size and non-hit-testable; wall edges use blueprint cyan-gray and steel edges use luminous white with thicker steel lines (1.5).

Wall visibility: Layered and fallback wall fills are now wireframe-first context (0.02 unselected, 0.10 selected) so the wall no longer fogs steel geometry.

Navigation reliability: 3D interactions now cancel cleanly on LostMouseCapture / window deactivation / missing-button move paths, and click-to-inspect resolves on mouse-up (click-only, not pan-drag).

Zoom/constraint feel: Shared HelixRevitNavigation now uses a loose constraint profile and a relaxed wheel clamp envelope for close inspection without abrupt hard stops.

Segment highlight: 3-tier visual hierarchy remains — selected segment (gold #FEC425 emissive), sibling segments (mild 85% dim), everything else (full dim). SegmentSelectionKey pushed from 3D click for precise highlighting.

Source: src/Tools/Structural/SGT/Shell/UI/Rendering/Preview3DRenderer.cs:66 Source: src/Tools/Structural/SGT/Shell/UI/Rendering/Preview3DRenderer.cs:176 Source: src/Tools/Structural/SGT/Shell/UI/Rendering/Preview3DRenderer.cs:208 Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:24 Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Navigation3D.cs:16 Source: src/Tools/Common/UI/Navigation/HelixRevitNavigation.cs:19

Flyout Positioning & Scrim (2026-03-03)

Both segment and bulk-edit flyouts now center vertically in the window (horizontal position unchanged — right of trigger). The flyout modal scrim uses a lighter 40% opacity (#66000000) instead of the global 60% default, keeping the preview visible behind the flyout.

Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml.cs Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml

Configuration

Manifest

id: DBTools.SGT
assembly: DBTools
moduleType: DBTools.SGT.SgtToolModule
order: 0
sandboxWindows:
  - id: DBTools.SGT.Main
    displayName: "Super Girt Tool"
    group: "Structural"
    windowType: "DBTools.SGT.Shell.UI.Views.SgtWindow"
    designTimeViewModelType: "DBTools.SGT.Shell.DesignTime.SgtWindowDesignTimeViewModel"
tool:
  ribbonTools:
    - internalName: DBTools.SGT
      commandType: DBTools.SGT.Features.Commands.SgtNewCommand
      availabilityType: DBTools.App.Tools.Availability.DbtDocumentAvailability
      runProfile: InlineUi
      displayText: "Super Girt Tool"
      iconBaseKey: sgt
      tooltip: "Launch Super Girt Tool"
      controlKind: PushButton
      order: 40

Source: src/Tools/Structural/SGT/manifest.yml:1-21

UI State Persistence

The ISgtUiStateStore persists user preferences:

  • Expander states (Girts, Openings)
  • Preview mode selection
  • Column visibility

Source: src/Tools/Structural/SGT/Shell/UI/Settings/ISgtUiStateStore.cs

Domain Model

Key Domain Entities

SgtPlan

The central data structure containing all configuration:

public sealed class SgtPlan
{
    // Wall context
    public int? HostWallId { get; init; }
    public int? LinkedWallId { get; init; }
    public int? LinkInstanceId { get; init; }
    public WallGeometry? WallGeometry { get; set; }
    
    // Girt configuration
    public List<SgtGirtRow> GirtRows { get; init; }
    public int SelectedGirtTypeId { get; set; }
    
    // Opening configuration
    public List<SgtOpeningRow> OpeningRows { get; set; }
    public IReadOnlyList<OpeningDetectionData> DetectedOpenings { get; set; }
    
    // Options
    public int DepthPlaneLayerIndex { get; set; }
    public double WallOffsetFeet { get; set; }
    public bool FoundationMode { get; set; }
}

Source: src/Tools/Structural/SGT/Shared/Kernel/Domain/SgtPlan.cs:15-811

Extent Types

Girts support multiple extent modes:

Extent Type Description
FullLengthExtent Wall start to wall end
AlongExtent Fixed distances from wall start
GridExtent Between named grid lines with offsets
OpeningEdgeExtent Relative to opening edges
DualOpeningEdgeExtent Between two opening edges
MemberEdgeExtent Terminates at a segmented-member boundary (OpeningKey:Role)

Source: src/Tools/Structural/SGT/Shared/Kernel/Domain/ (multiple files)

Auto-Segmentation (REV2, 2026-02-11)

REV2 Phases 1-5 are now implemented end-to-end for both horizontal girt segmentation and vertical jamb segmentation.

  • Horizontal segmentation remains persisted as first-class GirtRow siblings using SegmentGroupId/SegmentOrder/ParentUiKey, with recursive re-segmentation support when extending an already segmented child.
  • Vertical segmentation is modeled on OpeningRoleConfig via SegmentedConfigs plus JambSegmentGroupId/JambSegmentOrder; opening-role callsites iterate OpeningRow.GetEffectiveConfigs(role) while parent TypeId remains the role enable flag.
  • Vertical auto-bisection now triggers from jamb extent snapping (ApplyOpeningMemberExtentSnap) using resolved girt T-ranges, with minimum-length rejection and user warning banner for invalid splits.
  • Rendering and interaction are segment-aware for opening roles:
    • Elevation and 3D preview iterate per-segment opening-role configs (LeftJamb/RightJamb/Header/Sill).
    • Section preview iterates segmented Header/Sill configs and continues to omit jamb profile bands by design.
    • Elevation draws dashed boundary lines between adjacent jamb segments.
    • Handle generation creates jamb top/bottom pairs and header/sill left/right endpoint pairs per segment; all opening-member handle drags carry SegmentIndex so segmented child configs are edited directly.
  • Openings-pane operations now include explicit jamb segment add/remove commands (left/right) that mutate SegmentedConfigs in-place with segment-order/group maintenance and minimum-length guardrails.
  • Placement remains independent per member (no grouping at writer layer):
    • Orchestrator and writer utilities resolve/place each jamb segment as an independent opening component.
    • DomainWriter maps placed jamb components back to segment configs by role and local-Z ordering.
  • Reconciliation was upgraded from Phase 1 defensive reset to full segment-group cleanup:
    • host diffs track MemberEdgeImpactKeys,
    • opening deletion flow merges/dissolves orphaned segment groups,
    • post-pass renumbers/dissolves inconsistent groups,
    • orphaned jamb segment sets dissolve when referenced bisecting girts disappear.
  • Edge-case hardening includes:
    • MemberEdge handling in grid normalization + extent T-resolution,
    • validation warnings for invalid member-edge labels/orphaned groups,
    • adjacent bisection-point merge within 2 * END_GAP,
    • explicit MemberEdge cutback behavior in placement gap computation.
  • Persistence now uses explicit field mapping for opening-role configs (including nested SegmentedConfigs, JambSegmentGroupId, and JambSegmentOrder) in StorageMapper serialize/deserialize helpers.

Segment Merge + Collapse Hardening (2026-03-03)

Follow-up hardening was implemented to prevent stale references and stale segmented state during editing:

  • MergeGirtSegments rewrites opening extent targets: when two girt segment UiKeys are removed and replaced with a merged row, any TopExtentTarget / BottomExtentTarget references that pointed at either removed key are rewritten to the merged key (and Undo restores opening rows).
  • Re-segmentation collapses segment groups: if re-segmentation recomputation produces fewer than 2 child segments, the segment group is collapsed back to a standalone row, segment metadata is cleared, bypass keys + opening-edge gap overrides are merged, and opening extent targets are rewritten to the collapsed row key.
  • Bisection provenance is preserved: near-duplicate bisections coalesce by position but retain all source intersecting element keys so bypass filtering remains correct when multiple openings contribute to one merged point.

Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:1908
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.CoreAndEditing.cs:1268
Source: src/Tools/Structural/SGT/Features/Extents/MemberIntersectionService.cs:309

Geometry-Aware Gap Fallback Surfacing (2026-03-03)

Gap computation can fall back to flat END_GAP when profile data is missing or a profile transform fails. This is now tagged per-bisection and surfaced to the UI once per session as a summary banner when it affects segmentation actions.

Source: src/Tools/Structural/SGT/Features/Extents/MemberIntersectionService.cs:411
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.CoreAndEditing.cs:1209

Gap Override Validation Hardening (2026-03-03)

  • Gap overrides reject NaN / Infinity inputs and enforce a sane maximum absolute magnitude; negative values remain allowed (extend instead of trim).
  • Persisted override values are validated for finiteness during Plan.Validate() so corrupted state is caught before placement.

Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.CoreAndEditing.cs:2899
Source: src/Tools/Structural/SGT/Domain/Plan.cs:271

Source: src/Tools/Structural/SGT/Domain/ValueObjects/ExtentKind.cs:12
Source: src/Tools/Structural/SGT/Domain/Plan.cs:508
Source: src/Tools/Structural/SGT/Domain/Plan.cs:767
Source: src/Tools/Structural/SGT/Domain/Plan.cs:883
Source: src/Tools/Structural/SGT/Features/Extents/MemberIntersectionService.cs:77
Source: src/Tools/Structural/SGT/Features/Extents/MemberIntersectionService.cs:164
Source: src/Tools/Structural/SGT/Features/Extents/AutoSegmentationService.cs:16
Source: src/Tools/Structural/SGT/Features/Extents/AutoSegmentationService.cs:69
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:225
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:506
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:700
Source: src/Tools/Structural/SGT/Shell/ViewModels/ShellWindowViewModel.DomainIntegration.cs:574
Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs:658
Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs:717
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Core.cs:459
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Handles.cs:634
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Handles.cs:879
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Handles.cs:1087
Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs:292
Source: src/Tools/Structural/SGT/Shell/UI/Behaviors/PreviewPresenterBehavior.Handles.cs:381
Source: src/Tools/Structural/SGT/Shell/ViewModels/Panes/OpeningsPaneViewModel.cs:242
Source: src/Tools/Structural/SGT/Shell/Views/ShellWindow.xaml:1290
Source: src/Tools/Structural/SGT/Features/Placement/Orchestrator.cs:204
Source: src/Tools/Structural/SGT/Features/Placement/Writers/DomainWriter.Utilities.cs:336
Source: src/Tools/Structural/SGT/Features/Placement/Writers/DomainWriter.OpeningPlacement.cs:174
Source: src/Tools/Structural/SGT/Features/Placement/DomainWriter.Updates.cs:467
Source: src/Tools/Structural/SGT/Features/EditWall/HostChangeDiffService.cs:245
Source: src/Tools/Structural/SGT/Shell/Services/HostChangeReconciliationService.cs:158
Source: src/Tools/Structural/SGT/Shell/Services/HostChangeReconciliationService.cs:307
Source: src/Tools/Structural/SGT/Shell/Services/HostChangeReconciliationService.cs:375
Source: src/Tools/Structural/SGT/Shell/Services/GridManagementService.cs:189
Source: src/Tools/Structural/SGT/Shell/Services/GridManagementService.cs:318
Source: src/Tools/Structural/SGT/Domain/Validation/ValidationService.cs:121
Source: src/Tools/Structural/SGT/Features/Placement/Writers/DomainWriter.MemberPlacement.cs:319
Source: src/Tools/Structural/SGT/Features/Persistence/SchemaDefinition.cs:20
Source: src/Tools/Structural/SGT/Features/Persistence/StorageMapper.cs:108
Source: src/Tools/Structural/SGT/Features/Persistence/StorageMapper.cs:170
Source: src/Tools/Structural/SGT/Shell/Startup.cs:59 Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs
Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs

Integration Points

Revit API Integration

SGT interacts with Revit through adapter services:

  • WallGeometryService: Extract wall curves, layers, dimensions
  • RevitOpeningQuery: Detect doors, windows, and openings in walls
  • SgtDomainWriter: Create structural framing instances
  • SgtSystemRepository: Store/retrieve SGT configurations in extensible storage

Testing

SGT includes comprehensive tests:

src/Tools/Structural/SGT/Tests/
+-- SgtAdapterTests.cs
+-- SgtFrameBuilderTests.cs
+-- SgtConfigHydratorTests.cs
+-- SgtValidationServiceTests.cs
+-- SgtOrchestratorExtentTests.cs
+-- SgtHostChangeDiffServiceTests.cs
+-- ... (additional test files)

Source: src/Tools/Structural/SGT/Tests/DBTools.SGT.Tests.csproj

Run tests via the Revit test runner:

bash invoke-revit-tests.sh --smart --tool SGT

Preview Rotation Parity (2026-02-07)

Preview profile transforms use one shared section-space transform helper for Elevation/Section/3D.

  • FlipFacing mirrors in family-local UV.
  • Cross-section rotation is applied in section space.
  • Exact Y/Z justification-pair deltas translate along U/V (instance-local section axes).
  • Projection into depth/secondary always respects analyzer-resolved yTargetsFlange (no role forcing).

Source: src/Tools/Structural/SGT/Features/Preview/OrientationSemanticsHelper.cs

Preview Secondary-Axis Parity (2026-02-07)

Preview no longer uses a separate secondary-axis sign correction path.

  • Projection uses analyzer yTargetsFlange mapping for all roles (Y->Flange => depth=U,secondary=V; Y->Web => depth=V,secondary=U).
  • Horizontal roles use canonical warmup signs; jamb roles use the selected per-rotation vertical calibration entry.
  • Preview parity is obtained by the warmed baseline profile loops, exact Y/Z pair deltas, and the same pure-math transform contract used by all preview modes.

Source: src/Tools/Structural/SGT/Features/Preview/OrientationSemanticsHelper.cs Source: src/Tools/Structural/SGT/Shell/UI/Rendering/PreviewRenderer.cs Source: src/Tools/Structural/SGT/Features/Preview/Models/PreviewScene3DBuilder.cs


Documentation Status: Complete

Last Updated: 2026-02-19

Source Review: Verified against source files in src/Tools/Structural/SGT/