avf
Analysis Visualization Framework (AVF) helpers.
Utilities for displaying arbitrary numeric values on elements in a view, using Revit's SpatialFieldManager / AVF. Useful for heatmaps, KPI overlays, QA/QC markers, or any "paint a number onto elements" workflow.
Typical usage::
from pyrevit import revit
from pyrevit.revit import avf
values = {wall1: 12.5, wall2: 44.0}
# use get_or_create_colored_surface_display_style(...) instead for a
# gradient/heatmap look rather than text markers
style = avf.get_or_create_marker_display_style(revit.doc, "MyTool_AVF")
with revit.Transaction("Show values"):
revit.active_view.AnalysisDisplayStyleId = style.Id
results = avf.display_avf_values(values, revit.active_view, unit="ea")
Notes / known limitations:
- Face selection uses the largest planar-or-curved face whose normal
opposes the given view direction. Non-planar faces are sampled at
their UV-bounding-box center, which is an approximation for
strongly curved faces (cylinders, etc.).
- SpatialFieldManager results (the actual point/value data) are NOT
saved with the document - they live only for the current session
and are gone on reopen even without calling clear_avf_results.
What IS saved with the model is the AnalysisDisplayStyle itself and
its assignment to a view (View.AnalysisDisplayStyleId), so a
view can "remember" how it should render results without remembering
the results. Call clear_avf_results to remove results within a
session (e.g. before recomputing).
- Two display styles are provided: get_or_create_marker_display_style
(text markers, good for discrete/inspectable values) and
get_or_create_colored_surface_display_style (gradient heatmap,
good for continuous/comparative values).
- Requires an open transaction; all public write functions here open
their own transaction unless already inside one is fine (Revit
allows nested calls as long as some transaction is open - callers
driving multiple lib calls per click should wrap them in a single
outer transaction for performance).
Attributes
get_elementid_value = get_elementid_value_func()
module-attribute
mlogger = get_logger(__name__)
module-attribute
Classes
Functions:
get_face_facing_direction(element, direction, detail_level=DB.ViewDetailLevel.Coarse)
Find the largest face of element that faces the viewer.
"Faces the viewer" means the face's outward normal roughly opposes
direction (dot product < 0), which is the correct test when
direction is a view's look direction (View.ViewDirection points
from the eye into the model, so a front-facing face's normal points
the other way).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element
|
Element
|
Element to inspect. |
required |
direction
|
XYZ
|
Direction the viewer is looking, e.g.
|
required |
detail_level
|
ViewDetailLevel
|
Geometry detail level to extract. Defaults to Coarse. |
Coarse
|
Returns:
| Type | Description |
|---|---|
|
DB.Face: The best-matching face, or None if the element has no solid geometry, or no face is oriented toward the viewer. |
Source code in pyrevitlib/pyrevit/revit/avf.py
clear_avf_results(view)
Clear all AVF results from a view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
view
|
View
|
The view to clear results from. |
required |
Note
AVF result data is not saved with the document at all, so this is only needed to clear results within the current session (e.g. before recomputing). The AnalysisDisplayStyle assigned to the view is unaffected and does persist with the model.
Source code in pyrevitlib/pyrevit/revit/avf.py
display_avf_values(element_value_dict, view, schema_name='pyRevitAVF', schema_desc='AVF values from pyRevit', unit='Value', use_bbox_center=False, visible=True)
Display numeric values on multiple elements in a view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
element_value_dict
|
dict[Element, float]
|
Element -> value. |
required |
view
|
View
|
View to display values in. |
required |
schema_name
|
str
|
AVF schema name. Reused if a schema with this name already exists on the view. Defaults to "pyRevitAVF". |
'pyRevitAVF'
|
schema_desc
|
str
|
AVF schema description. |
'AVF values from pyRevit'
|
unit
|
str or list[tuple[str, float]]
|
Single unit
label, or a list of |
'Value'
|
use_bbox_center
|
bool
|
Use the element's bounding-box center instead of a face point as the insertion point. Useful for elements without usable solid faces. Defaults to False. |
False
|
visible
|
bool
|
Whether the schema is visible/toggle-able in the view. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
|
dict[int, tuple]: element-id-value -> (success, sfp_id). |
Source code in pyrevitlib/pyrevit/revit/avf.py
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | |
update_avf_values(primitive_dict, element_value_dict, view, schema_name='pyRevitAVF', schema_desc='AVF values from pyRevit', unit='Value', visible=True)
Update values on primitives previously created by display_avf_values.
Cheaper than re-running display_avf_values since it reuses the
existing primitive/face instead of re-searching geometry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
primitive_dict
|
dict[int, tuple]
|
Output of |
required |
element_value_dict
|
dict[Element, float]
|
Element -> new value. |
required |
view
|
View
|
View the primitives were created in. |
required |
schema_name
|
str
|
Must match the schema used originally. |
'pyRevitAVF'
|
schema_desc
|
str
|
AVF schema description. |
'AVF values from pyRevit'
|
unit
|
str or list[tuple[str, float]]
|
Must match what was used when the schema was first created. |
'Value'
|
visible
|
bool
|
Whether the schema is visible. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
|
dict[int, bool]: element-id-value -> success. |
Source code in pyrevitlib/pyrevit/revit/avf.py
remove_avf_primitive(view, sfp_id)
Remove a single AVF primitive from a view.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
view
|
View
|
View the primitive belongs to. |
required |
sfp_id
|
int
|
Primitive index, as returned by |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
True if removed, False if no SFM/primitive was found. |
Source code in pyrevitlib/pyrevit/revit/avf.py
get_or_create_marker_display_style(doc, style_name, show_legend=False)
Get an existing marker-style AnalysisDisplayStyle, or create one.
Creates a style that shows values as text markers (no color gradient), which is a good default for discrete/inspectable values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
doc
|
Document
|
Document to search/create in. |
required |
style_name
|
str
|
Name of the display style. |
required |
show_legend
|
bool
|
Show the AVF legend in views using this style. Defaults to False. |
False
|
Returns:
| Type | Description |
|---|---|
|
DB.Analysis.AnalysisDisplayStyle: The existing or newly created style. |
Source code in pyrevitlib/pyrevit/revit/avf.py
get_or_create_colored_surface_display_style(doc, style_name, min_color=(200, 0, 200), max_color=(255, 205, 0), show_legend=True, show_grid_lines=True, number_of_steps=10, rounding=0.05)
Get an existing colored-surface AnalysisDisplayStyle, or create one.
Creates a gradient/heatmap style, generally a better fit than
get_or_create_marker_display_style for continuous or comparative
values (e.g. KPI heatmaps) rather than discrete inspectable ones.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
doc
|
Document
|
Document to search/create in. |
required |
style_name
|
str
|
Name of the display style. |
required |
min_color
|
tuple[int, int, int]
|
RGB for the low end of the gradient. Defaults to purple. |
(200, 0, 200)
|
max_color
|
tuple[int, int, int]
|
RGB for the high end of the gradient. Defaults to orange. |
(255, 205, 0)
|
show_legend
|
bool
|
Show the AVF legend. Defaults to True (usually what you want for a gradient, unlike markers). |
True
|
show_grid_lines
|
bool
|
Show grid lines on the colored surface. Defaults to True. |
True
|
number_of_steps
|
int
|
Number of discrete color steps in the legend/gradient. Defaults to 10. |
10
|
rounding
|
float
|
Legend value rounding. Defaults to 0.05. |
0.05
|
Returns:
| Type | Description |
|---|---|
|
DB.Analysis.AnalysisDisplayStyle: The existing or newly created style. |
Source code in pyrevitlib/pyrevit/revit/avf.py
display_avf_values_at_points(point_value_pairs, view, schema_name='pyRevitAVF', schema_desc='AVF values from pyRevit', unit='Value', visible=True, max_points_per_primitive=500)
Display values at arbitrary XYZ points, not tied to any element.
Useful for point-cloud style overlays (e.g. a sampled grid) where
there's no host element/face to anchor the value to. Per Revit's own
guidance, points are chunked into multiple primitives of at most
max_points_per_primitive points each, rather than one giant
primitive, for performance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
point_value_pairs
|
list[tuple[XYZ, float]]
|
Points and their values. |
required |
view
|
View
|
View to display values in. |
required |
schema_name
|
str
|
AVF schema name. |
'pyRevitAVF'
|
schema_desc
|
str
|
AVF schema description. |
'AVF values from pyRevit'
|
unit
|
str or list[tuple[str, float]]
|
See
|
'Value'
|
visible
|
bool
|
Whether the schema is visible. Defaults to True. |
True
|
max_points_per_primitive
|
int
|
Chunk size. Defaults to 500, per Revit's documented recommendation. |
500
|
Returns:
| Type | Description |
|---|---|
|
list[int]: The primitive ids created (one per chunk). |