Skip to content

Add pyrevit.revit.avf — helpers for displaying values via the Analysis Visualization Framework#3487

Open
Wurschdhaud wants to merge 5 commits into
pyrevitlabs:developfrom
Wurschdhaud:new-lib-avf
Open

Add pyrevit.revit.avf — helpers for displaying values via the Analysis Visualization Framework#3487
Wurschdhaud wants to merge 5 commits into
pyrevitlabs:developfrom
Wurschdhaud:new-lib-avf

Conversation

@Wurschdhaud

Copy link
Copy Markdown
Contributor

Description

Summary

Adds a small helper module for Revit's AVF / SpatialFieldManager API, so
extension authors can paint arbitrary numeric values (KPIs, QC results,
heatmaps, counts, whatever) onto elements in a view without hand-rolling
SFM/schema/primitive bookkeeping every time.

This started as an internal tool for diagnostic/KPI overlays and I'm
proposing a generalized version for the shared lib.

What's included

  • get_face_facing_direction(element, direction) — returns the largest
    face of an element whose normal faces a given direction (typically
    view.ViewDirection). Used to pick a sensible point to anchor a marker.
  • display_avf_values(element_value_dict, view, ...) — paints a dict of
    {element: value} onto a view in one call; creates/reuses the
    SpatialFieldManager and schema, returns primitive handles for later
    updates.
  • update_avf_values(primitive_dict, element_value_dict, view, ...)
    cheap re-update of existing primitives (no geometry re-query).
  • display_avf_values_at_points(point_value_pairs, view, ...) — same idea
    but for arbitrary XYZ points with no host element (e.g. a sampled grid);
    automatically chunks into multiple primitives per Autodesk's documented
    500-points-per-primitive guidance.
  • remove_avf_primitive(view, sfp_id) / clear_avf_results(view)
    cleanup helpers.
  • get_or_create_marker_display_style(doc, style_name) — get-or-create an
    AnalysisDisplayStyle configured to show text markers.
  • get_or_create_colored_surface_display_style(doc, style_name, ...)
    get-or-create the gradient/heatmap style instead, with min/max color,
    legend steps, and rounding exposed.

Known limitations

  • Non-planar faces (cylinders, etc.) are sampled at the UV-bounding-box
    center for marker placement, which is an approximation, not a true
    centroid.
  • use_bbox_center=True is the fallback for elements without usable
    solid faces, but it still requires the element to have geometry
    visible in the target view.
  • display_avf_values_at_points chunks at 500 points/primitive per
    Autodesk's documented recommendation for the no-geometry overload —
    not independently benchmarked here, just carried over from the docs.

Checklist

Before submitting your pull request, ensure the following requirements are met:

  • Code follows the PEP 8 style guide.
  • Code has been formatted with Black using the command:
    pipenv run black {source_file_or_directory}
  • Changes are tested and verified to work as expected.

@devloai devloai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary:

  • Adds pyrevit.revit.avf, a new helper module wrapping Revit's AVF/SpatialFieldManager API to paint arbitrary numeric values onto elements/points in a view.
  • Provides face-selection, value display/update, primitive cleanup, and get-or-create helpers for marker/colored-surface AnalysisDisplayStyles.
  • Wires the new module into pyrevit.revit.__init__, and adds a Developer Examples demo pushbutton + bundle entry.

Review Summary:

Overall a well-documented, self-contained addition with sound transaction handling (leveraging pyRevit's existing sub-transaction support) and reasonable defensive per-element error handling. Cross-checked the AnalysisResultSchema.SetUnits API contract (non-empty/unique unit names) referenced in the module's own docstring and found two functions (update_avf_values, display_avf_values_at_points) default unit="", inconsistent with display_avf_values's "Value" default and the documented API requirement — this can throw ArgumentsInconsistentException if those functions register a schema before display_avf_values has run. Also flagged a minor Black slice-formatting nit per the repo's formatting guideline. No other correctness, security, or naming-convention issues found; IronPython 2.7 conventions (e.g. basestring) are used consistently with the rest of the codebase.

Suggestions

  • Add a unit test/demo exercising update_avf_values and display_avf_values_at_points as first calls (no prior schema) to catch the empty-unit bug. Apply

Comment thread pyrevitlib/pyrevit/revit/avf.py Outdated
Comment thread pyrevitlib/pyrevit/revit/avf.py Outdated
Comment thread pyrevitlib/pyrevit/revit/avf.py Outdated
Wurschdhaud and others added 2 commits July 14, 2026 20:43
Fix the empty-unit trap where update_avf_values and
display_avf_values_at_points defaulted unit to '' — registering an AVF
schema with an empty unit name raises ArgumentsInconsistentException from
AnalysisResultSchema.SetUnits when they are the first call on a view.

- Default unit to 'Value' in both functions (matching display_avf_values)
- Sanitize empty unit names in _get_or_create_schema as a safety net
- Add Revit-hosted regression tests exercising both functions as first
  calls (no prior schema) plus an explicit empty-unit case
- Add DevTools 'AVF Module Tests' pushbutton to run them
@devloai

devloai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Added regression coverage for the empty-unit trap in update_avf_values / display_avf_values_at_points (commit 55852d9).

Since you'd already fixed the defaults to "Value" in 05f7da5, this rebases on top of that and adds the test/demo that would have caught the bug:

  • pyrevitlib/pyrevit/unittests/test_avf.py — Revit-hosted tests (following the test_query_get_name.py pattern) exercising both functions as first calls on a view (no prior schema, unique schema names so the "register a new schema" branch is always hit):
    • test_display_points_default_unit_first_calldisplay_avf_values_at_points registers a schema on a first call without raising ArgumentsInconsistentException.
    • test_update_values_default_unit_first_callupdate_avf_values registers a schema on a first call (even with nothing to update).
    • test_explicit_empty_unit_is_sanitized — an explicit unit="" no longer blows up.
    • Tests skip gracefully if the active view doesn't support AVF, and clean up results in tearDown.
  • _get_or_create_schema — added a small safety net that substitutes an empty unit name with "Value", so callers explicitly passing unit="" don't trip SetUnits either.
  • DevTools "AVF Module Tests" pushbutton (Debug.panel/Unit Tests.pulldown, context: doc-project) to run the suite from Revit.

Verified: py_compile passes and black --check reports both files clean.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new pyrevit.revit.avf helper module that wraps Revit’s Analysis Visualization Framework (SpatialFieldManager) to make it easier for extension authors to display and update numeric overlays (markers/heatmaps) in views. It also adds a small DevTools example button to act as a smoke-test/demo for the new API.

Changes:

  • Added pyrevit.revit.avf with helpers to create/reuse SFM + result schemas and paint/update values on elements or arbitrary XYZ points.
  • Exposed “get-or-create” helpers for AnalysisDisplayStyle (marker/text and colored-surface/gradient styles).
  • Added an “AVF” Developer Examples button demonstrating end-to-end usage.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 5 comments.

File Description
pyrevitlib/pyrevit/revit/avf.py New AVF utility module for creating schemas/styles and displaying/updating AVF values on elements/points.
pyrevitlib/pyrevit/revit/__init__.py Exposes avf from the pyrevit.revit package for easier importing.
extensions/pyRevitDevTools.extension/pyRevitDev.tab/Developer Examples.panel/bundle.yaml Adds the new “AVF” example button to the DevTools panel layout.
extensions/pyRevitDevTools.extension/pyRevitDev.tab/Developer Examples.panel/AVF.pushbutton/script.py New demo script: pick element, enter value, select style, display via AVF helpers.

Comment thread pyrevitlib/pyrevit/revit/avf.py Outdated
Comment thread pyrevitlib/pyrevit/revit/avf.py
Comment thread pyrevitlib/pyrevit/revit/avf.py
Comment thread pyrevitlib/pyrevit/revit/avf.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants