Extreme Roof Framing Tool (ERFT)
ERFT is a Testing-category tool that adjusts structural columns and beams to match the slope of a selected floor/roof target. It supports selecting targets from the host model or a linked model, computes vertical deltas via closest-point projection, and applies parameter offsets with user-configurable rounding.
See also: Technical Specification (Internal)
Source Location
- Tool code:
src/Tools/Testing/ERFT/ - Manifest:
src/Tools/Testing/ERFT/manifest.yml
Key Concepts
- Target surface mesh extraction (floor/roof)
- Framing hierarchy (beam-to-column / beam-to-beam dependencies)
- Adjustment calculation + rounding tolerance
- Apply workflow (write offsets + persist plan snapshot)
- Source filtering: concrete members are excluded when their Structural Material name matches
\bconcrete\b(case-insensitive). The filter checks both instance-level and type-level material assignments.
Source:
src/Tools/Testing/ERFT/Features/Selection/ErftSelectionOrchestrator.cs:22
Contextual Ribbon Hook
ERFT includes a contextual ribbon injector that:
- Subscribes to Revit selection changes at initialize time
- Refreshes contextual UI state through the queued Revit call gate
- Evaluates selected structural framing/column elements for ERFT ExtensibleStorage metadata
- Injects and toggles
Edit ERFTon contextual Modify tabs (columns, framing, and multi-select variants) - Raises edit execution through
ExternalEvent+ISafeExecutorwith an active notifier - Blocks invalid edit clicks (no ERFT systems selected, or
ExternalEvent.Raise()not accepted) with explicit banner feedback - Creates a per-click
AppRuntimerun scope (InlineUi) before resolvingErftRunner, then clears/disposes the scoped Revit run context infinally
Source:
src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:66Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:119Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:139Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:207Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:272Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:320Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:444Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:484Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:535
Logging Density Controls (2026-02-09)
ERFT debug output is now consolidated for long sessions:
- Selection-hook executor noise is suppressed (
LogStart=false,LogCompletion=false,WorkPerformed=false) so the log is not flooded per selection change. - Contextual selection evaluation logs only when state actually changes, and the "schema missing" message is emitted once until schema becomes available.
- Profile warmup logs emit one summary info line (total/warmed/failed) while per-type progress moves to Trace.
Source:
src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:151Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:212Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:237Source:src/Tools/Testing/ERFT/Features/Preview/Revit/ErftMemberProfileWarmupService.cs:154
Selection Guidance Banners
Before ERFT opens its window, the picker flow now shows yellow guidance banners for each selection phase:
- Linked target phase: instructs picking a linked floor/roof and using ESC to switch to host selection.
- Host target phase (after ESC from linked phase): instructs picking a host floor/roof and using ESC to cancel launch.
- Source phase: instructs selecting source structural columns/beams and finishing the multi-pick.
These banners are shown with BannerManager.ShowTopWarning(...) and always cleaned up with BannerManager.Hide() in finally blocks around picker calls.
Source:
src/Tools/Testing/ERFT/Features/Selection/ErftSelectionOrchestrator.cs:21Source:src/Tools/Testing/ERFT/Features/Selection/ErftSelectionOrchestrator.cs:231Source:src/Tools/Testing/ERFT/Features/Selection/ErftSelectionOrchestrator.cs:313
Audit Remediation (2026-02-11)
- Source validation enforces the spec rule: at least one selected column, or at least one selected beam that frames to a column via ERFT hierarchy logic; invalid beams-only selections are blocked with
[SpecFail/Selection/NoColumnConnection]. - Contextual edit launch hard-fails when stored reconstruction payload is missing/corrupt (
[SpecFail/Edit/StoredPlanMissing]) and edit mode does not fall back to new-flow selection. - Stored edit tolerance is strict; non-positive values fail reconstruction (
[SpecFail/Edit/InvalidStoredTolerance]) instead of defaulting silently. - Target preview now prefers analyzed bottom-surface mesh (
TargetSurface) and only falls back to full element mesh (TargetElement) if the primary mesh is unavailable. - Link transform payload is documented and produced as a 16-value homogeneous matrix contract.
- Catch paths in target extraction, column top calculation, and target-edge overlay now emit contextual logs instead of silent suppression.
Source:
src/Tools/Testing/ERFT/Features/Selection/ErftSelectionOrchestrator.cs:98Source:src/Tools/Testing/ERFT/Features/Selection/ErftSelectionValidationRules.cs:24Source:src/Tools/Testing/ERFT/Features/Commands/ErftContextualRibbonInjector.cs:566Source:src/Tools/Testing/ERFT/Features/Commands/ErftRunner.cs:95Source:src/Tools/Testing/ERFT/Features/Preview/Logic/ErftPreviewSceneBuilder.cs:76Source:src/Tools/Testing/ERFT/Common/Domain/TargetSurfaceGeometry.cs:23Source:src/Tools/Testing/ERFT/Features/Analysis/ErftTargetGeometryService.cs:123Source:src/Tools/Testing/ERFT/Features/Analysis/ErftColumnQueryService.cs:136Source:src/Tools/Testing/ERFT/Features/Preview/UI/ErftPreview3DRenderer.cs:82
3D Preview Rendering and Navigation (Maintainer Notes)
- Renderer entrypoint:
ErftPreview3DRenderer.Render(...)is the only runtime render entrypoint; it clears/rebuilds meshes and edge overlays each frame. - Scene builder entrypoint:
ErftPreviewSceneBuilder.Build(...)is the authoritative 3D scene contract (TargetSurface/TargetElement+ member meshes). - Navigation invariants: viewport navigation is canceled via a single
CancelViewportNavigation(...)path onLostMouseCapture, windowDeactivated, or missing-button move paths. - Shared constraints policy: wheel zoom/orbit/pan all use shared
HelixRevitNavigationfor pivoting, zoom envelopes, and post-interaction constraint clamping. - Dark-theme readability policy: target fill stays low opacity (
0.12), edges are high-contrast cyan-gray, and the light rig is deterministic (3 directional + ambient).
Source:
src/Tools/Testing/ERFT/Features/Preview/UI/ErftPreview3DRenderer.cs:17Source:src/Tools/Testing/ERFT/Features/Preview/UI/ErftPreview3DRenderer.cs:196Source:src/Tools/Testing/ERFT/Features/Preview/Logic/ErftPreviewSceneBuilder.cs:21Source:src/Tools/Testing/ERFT/Shell/UI/Views/ErftWindow.Preview3D.cs:312Source:src/Tools/Testing/ERFT/Shell/UI/Views/ErftWindow.Preview3D.cs:516Source:src/Tools/Common/UI/Navigation/HelixRevitNavigation.cs:47
UI Grid Status Column Layout
Both ERFT comparison grids (columns and beams) use a stretch-last Status column with an explicit minimum width so the status field remains readable while consuming trailing space instead of showing an unused blank area.
Source:
src/Tools/Testing/ERFT/Shell/UI/Views/ErftWindow.xaml:427Source:src/Tools/Testing/ERFT/Shell/UI/Views/ErftWindow.xaml:546