I have started this script to ideally allow be to select HVAC Zones but it is not letting me. Any ideas?
from Autodesk.Revit.DB import (
FilteredElementCollector,
BuiltInCategory,
ViewPlan,
SpatialElementBoundaryOptions,
GraphicsStyle,
Transaction,
ElementId,
SpatialElement
)
from Autodesk.Revit.UI.Selection import ObjectType, ISelectionFilter
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_HVAC_Zones):
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
selected_zone_refs = uidoc.Selection.PickObjects(ObjectType.Element, HVACZoneSelectionFilter(), "Select HVAC Zones")
from Autodesk.Revit.DB import (
FilteredElementCollector,
BuiltInCategory,
ViewPlan,
SpatialElementBoundaryOptions,
GraphicsStyle,
Transaction,
ElementId,
SpatialElement
)
from Autodesk.Revit.UI.Selection import ObjectType, ISelectionFilter
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
selected_zone_refs = uidoc.Selection.PickObjects(ObjectType.Element, HVACZoneSelectionFilter(), "Select HVAC Zones")
# 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 line styles available in the document
line_styles = FilteredElementCollector(doc).OfClass(GraphicsStyle).ToElements()
# 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()
I am attempting to get the zone boundaries to then be able to place detail lines over them.
as of now, it it placing detail lines over any space boundary due to BuiltInCategory.OST_MEPSpaces which i don’t want
class HVACZoneSelectionFilter(ISelectionFilter):
def AllowElement(self, element):
# Check if the element is an HVAC zone
if element.Category is not None and element.Category.Id.IntegerValue == int(BuiltInCategory.OST_HVAC_Zones):
return True
return False
def AllowReference(self, reference, position):
return False
# Get current document and active view
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
# 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")
selected_zones = [doc.GetElement(ref) for ref in selected_zone_refs]
forms.alert("Selected {} HVAC Zones.".format(len(selected_zones)))
except Exception as e:
forms.alert("Selection cancelled or error occurred: {}".format(str(e)))
@andreasd811 hmm, i guess HVAC Zones are not spatial elements.
so after implementing this into the main script, it works.
I have a little debugging to do but i would like some input on my error i am getting
from Autodesk.Revit.DB import (
FilteredElementCollector,
BuiltInCategory,
ViewPlan,
SpatialElementBoundaryOptions,
GraphicsStyle,
Transaction,
ElementId,
SpatialElement
)
from Autodesk.Revit.UI.Selection import ObjectType, ISelectionFilter
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 element.Category is not None and element.Category.Id.IntegerValue == int(BuiltInCategory.OST_HVAC_Zones):
return True
return False
def AllowReference(self, reference, position):
return False
# Get current document and active view
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
# 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")
selected_zones = [doc.GetElement(ref) for ref in selected_zone_refs]
forms.alert("Selected {} HVAC Zones.".format(len(selected_zones)))
except Exception as e:
forms.alert("Selection cancelled or error occurred: {}".format(str(e)))
# 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 line styles available in the document
line_styles = FilteredElementCollector(doc).OfClass(GraphicsStyle).ToElements()
# 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()
As part of the script, i also have it prompt a selection for detail lines but the prompt shows me a lot more that aren’t line styles for detail lines
i think you have select model and detailline before… line style is indemented, because you can convert always lines… which line do you need i thought you only grab Zones.
lines = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Lines).WhereElementIsNotElementType().ToElements()
detail_lines = [ i for i in lines if i.Name.Contains("Detail")]
model_lines = [ i for i in lines if i.Name.Contains("Model")]
print("you have {} detail lines".format(len(detail_lines)))
print("you have {} model lines".format(len(model_lines)))
it works well, next step find the right place in your script
so that did help a lot. it was showing me 5000+ detail lines
but it helped resolve it by using this:
# Filter the collected styles to include only those that:
# - Belong to a subcategory under the 'Lines' category (i.e., detail line styles)
# - Are of the 'Projection' type, which is the typical type for detail lines in Revit
detail_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