I am trying to write a script that will look at the HVAC Zone
Boundary’s curve/geometry/something and will then place a
detail line of my choosing over it. Basically tracing the HVAC
Zone with a detail line.
The current script I have places detail lines on every single
space separator and i cannot figure out how to make it look at the
zone boundary.
I have been stuck on this for a while.
Any and all help will mean so much and be greatly appreciated.
This is the furthest I have able to take this with the help of few other colleagues.
from Autodesk.Revit.DB import (
FilteredElementCollector,
BuiltInCategory,
ViewPlan,
SpatialElementBoundaryOptions,
GraphicsStyle,
GraphicsStyleType,
Transaction,
ElementId,
SpatialElement
)
from Autodesk.Revit.UI.Selection import ObjectType, ISelectionFilter
from Autodesk.Revit.Exceptions import OperationCanceledException
from pyrevit import forms
# Custom selection filter to ensure only HVAC zones are selected
class HVACZoneSelectionFilter(ISelectionFilter):
def AllowElement(self, element):
# Check if the element is an HVAC zone
if isinstance(element, SpatialElement) and element.Category.Id.IntegerValue == int(BuiltInCategory.OST_MEPSpaces):
return True
return False
def AllowReference(self, reference, position):
return False
# Get current document
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument # Correctly get the active UIDocument
# Get current view (assuming it's a floor plan or ceiling plan)
current_view = doc.ActiveView
# Check if the view is valid for detail lines
if not isinstance(current_view, ViewPlan):
forms.alert("Please run this script in a Floor Plan or Ceiling Plan view.", exitscript=True)
# Prompt user to select HVAC zones with the custom filter
try:
selected_zone_refs = uidoc.Selection.PickObjects(ObjectType.Element, HVACZoneSelectionFilter(), "Select HVAC Zones")
except OperationCanceledException:
forms.alert("Selection canceled. Exiting script.", exitscript=True)
selected_zone_refs = None # Ensure that selected_zone_refs is None
# Exit if the user cancels the selection
if not selected_zone_refs:
forms.alert("No HVAC zones selected. Exiting script.", exitscript=True)
# Convert selected references to elements
selected_zones = [doc.GetElement(ref.ElementId) for ref in selected_zone_refs]
# Collect all graphic styles in the document
# Graphics styles include line styles, projection styles, etc.
collector = FilteredElementCollector(doc).OfClass(GraphicsStyle)
# Collect all line styles available in the document
line_styles = [
style for style in collector
if style.GraphicsStyleCategory.Parent is not None and
style.GraphicsStyleCategory.Parent.Id.IntegerValue == int(BuiltInCategory.OST_Lines) and
style.GraphicsStyleType == GraphicsStyleType.Projection
]
# Create a dictionary of line style names and their corresponding ElementIds
line_style_dict = {ls.Name: ls.Id for ls in line_styles}
# Sort the line style names alphabetically
sorted_line_styles = sorted(line_style_dict.keys())
# Prompt user to select a line style from the sorted list
selected_line_style_name = forms.SelectFromList.show(sorted_line_styles, title="Select Line Style", button_name="OK")
# Exit if the user cancels the selection
if not selected_line_style_name:
forms.alert("No line style selected. Exiting script.", exitscript=True)
# Get the selected line style ElementId
selected_line_style_id = line_style_dict[selected_line_style_name]
# Start a transaction
t = Transaction(doc, "Draw HVAC Zone Boundaries")
t.Start()
try:
for zone in selected_zones:
# Get the boundary curves for the zone
boundary_options = SpatialElementBoundaryOptions() # Instantiate the boundary options
boundary_segments = zone.GetBoundarySegments(boundary_options)
for segment in boundary_segments:
for curve in segment:
# Convert curve to a detail line in the current view with the selected line style
detail_line = doc.Create.NewDetailCurve(current_view, curve.GetCurve())
detail_line.LineStyle = doc.GetElement(selected_line_style_id) # Set the line style
finally:
# Commit the transaction
t.Commit()
the way the code works so far is:
prompts the user to select spaces/zones
ask the user the type of detail line to use
then places the detail line chosen