Automatiseringsbibliotek
10 scripts til BIM/IFC, data quality og digital afleveringFind elementer uden CCS/CCI-kode
Dynamo / RevitFinder modelobjekter uden klassifikationskode i instance- eller typeparametre som CCSCode, CCI_Code og ClassificationCode.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
PARAMETER_NAMES = ["CCSCode", "CCS_Code", "CCI", "CCI_Code", "ClassificationCode", "Classification"]
def text_value(parameter):
if not parameter or not parameter.HasValue:
return None
value = parameter.AsString() or parameter.AsValueString()
return str(value).strip() if value and str(value).strip() else None
def get_value(element, names):
for name in names:
value = text_value(element.LookupParameter(name))
if value:
return value
type_id = element.GetTypeId()
if type_id and type_id != ElementId.InvalidElementId:
element_type = doc.GetElement(type_id)
if element_type:
for name in names:
value = text_value(element_type.LookupParameter(name))
if value:
return value
return None
def is_model_element(element):
return (
element.Category
and element.Category.CategoryType == CategoryType.Model
and not element.ViewSpecific
)
elements = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
missing = []
for element in elements:
if not is_model_element(element):
continue
if get_value(element, PARAMETER_NAMES):
continue
missing.append([
element.Id.IntegerValue,
element.Category.Name,
getattr(element, "Name", ""),
"CCS/CCI mangler",
])
OUT = [["ElementId", "Kategori", "Navn", "Fejl"]] + missing if missing else ["OK - alle modelobjekter har CCS/CCI-kode"]Find døre uden FireRating
Dynamo / RevitKontrollerer alle Revit-døre for brandklassifikation på instance eller type, fx FireRating, Fire Rating eller Brandklasse.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
PARAMETER_NAMES = ["FireRating", "Fire Rating", "Brandklasse", "Brandmodstand", "Fire Resistance"]
def text_value(parameter):
if not parameter or not parameter.HasValue:
return None
value = parameter.AsString() or parameter.AsValueString()
return str(value).strip() if value and str(value).strip() else None
def get_value(element, names):
for name in names:
value = text_value(element.LookupParameter(name))
if value:
return value
type_id = element.GetTypeId()
if type_id and type_id != ElementId.InvalidElementId:
element_type = doc.GetElement(type_id)
if element_type:
for name in names:
value = text_value(element_type.LookupParameter(name))
if value:
return value
return None
doors = (
FilteredElementCollector(doc)
.OfCategory(BuiltInCategory.OST_Doors)
.WhereElementIsNotElementType()
.ToElements()
)
missing = []
for door in doors:
if get_value(door, PARAMETER_NAMES):
continue
level_name = doc.GetElement(door.LevelId).Name if door.LevelId and door.LevelId != ElementId.InvalidElementId else ""
missing.append([
door.Id.IntegerValue,
getattr(door, "Name", ""),
level_name,
"FireRating mangler",
])
OUT = [["ElementId", "Dørtype", "Level", "Fejl"]] + missing if missing else ["OK - alle døre har FireRating"]Find rum uden rumnummer/navn
Dynamo / RevitFinder placerede og uplacerede rum, hvor rumnummer eller rumnavn mangler, så rumdata kan ryddes op før skemaer og IFC.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
def parameter_text(element, builtin):
parameter = element.get_Parameter(builtin)
if not parameter or not parameter.HasValue:
return ""
value = parameter.AsString() or parameter.AsValueString()
return str(value).strip() if value else ""
rooms = (
FilteredElementCollector(doc)
.OfCategory(BuiltInCategory.OST_Rooms)
.WhereElementIsNotElementType()
.ToElements()
)
missing = []
for room in rooms:
number = parameter_text(room, BuiltInParameter.ROOM_NUMBER)
name = parameter_text(room, BuiltInParameter.ROOM_NAME)
area = room.Area if hasattr(room, "Area") else 0
issues = []
if not number:
issues.append("Rumnummer mangler")
if not name:
issues.append("Rumnavn mangler")
if area <= 0:
issues.append("Rum er ikke placeret eller har 0 m2")
if issues:
level_name = room.Level.Name if room.Level else ""
missing.append([room.Id.IntegerValue, number, name, level_name, "; ".join(issues)])
OUT = [["ElementId", "Nummer", "Navn", "Level", "Fejl"]] + missing if missing else ["OK - alle rum har nummer og navn"]Find MEP-komponenter uden SystemCode
Dynamo / RevitScanner VVS, ventilation, el og plumbing-komponenter for manglende systemkode på instance eller type.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
PARAMETER_NAMES = ["SystemCode", "System Code", "Systemkode", "System_Kode", "System Classification"]
MEP_CATEGORIES = [
BuiltInCategory.OST_DuctTerminal,
BuiltInCategory.OST_DuctAccessory,
BuiltInCategory.OST_DuctFitting,
BuiltInCategory.OST_MechanicalEquipment,
BuiltInCategory.OST_PipeAccessory,
BuiltInCategory.OST_PipeFitting,
BuiltInCategory.OST_PlumbingFixtures,
BuiltInCategory.OST_ElectricalEquipment,
BuiltInCategory.OST_ElectricalFixtures,
BuiltInCategory.OST_LightingFixtures,
BuiltInCategory.OST_CableTray,
BuiltInCategory.OST_Conduit,
]
def text_value(parameter):
if not parameter or not parameter.HasValue:
return None
value = parameter.AsString() or parameter.AsValueString()
return str(value).strip() if value and str(value).strip() else None
def get_value(element, names):
for name in names:
value = text_value(element.LookupParameter(name))
if value:
return value
type_id = element.GetTypeId()
if type_id and type_id != ElementId.InvalidElementId:
element_type = doc.GetElement(type_id)
if element_type:
for name in names:
value = text_value(element_type.LookupParameter(name))
if value:
return value
return None
elements = []
for category in MEP_CATEGORIES:
try:
elements.extend(
FilteredElementCollector(doc)
.OfCategory(category)
.WhereElementIsNotElementType()
.ToElements()
)
except:
pass
missing = []
seen = set()
for element in elements:
if element.Id.IntegerValue in seen:
continue
seen.add(element.Id.IntegerValue)
if get_value(element, PARAMETER_NAMES):
continue
missing.append([
element.Id.IntegerValue,
element.Category.Name if element.Category else "",
getattr(element, "Name", ""),
"SystemCode mangler",
])
OUT = [["ElementId", "Kategori", "Navn", "Fejl"]] + missing if missing else ["OK - alle MEP-komponenter har SystemCode"]Find objekter uden FM_ID
Dynamo / RevitFinder modelobjekter uden drifts-ID eller asset-ID, så FM-data er klar til digital aflevering.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
PARAMETER_NAMES = ["FM_ID", "FMID", "AssetID", "Asset Identifier", "DriftsID", "FacilityManagementId"]
EXCLUDED_CATEGORIES = set(["Cameras", "Views", "Sheets"])
def text_value(parameter):
if not parameter or not parameter.HasValue:
return None
value = parameter.AsString() or parameter.AsValueString()
return str(value).strip() if value and str(value).strip() else None
def get_value(element, names):
for name in names:
value = text_value(element.LookupParameter(name))
if value:
return value
type_id = element.GetTypeId()
if type_id and type_id != ElementId.InvalidElementId:
element_type = doc.GetElement(type_id)
if element_type:
for name in names:
value = text_value(element_type.LookupParameter(name))
if value:
return value
return None
def include_element(element):
if not element.Category:
return False
if element.Category.Name in EXCLUDED_CATEGORIES:
return False
return element.Category.CategoryType == CategoryType.Model and not element.ViewSpecific
elements = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
missing = []
for element in elements:
if not include_element(element):
continue
if get_value(element, PARAMETER_NAMES):
continue
missing.append([
element.Id.IntegerValue,
element.Category.Name,
getattr(element, "Name", ""),
"FM_ID mangler",
])
OUT = [["ElementId", "Kategori", "Navn", "Fejl"]] + missing if missing else ["OK - alle relevante objekter har FM_ID"]Find views/sheets med forkert navngivning
Dynamo / RevitValiderer navngivning af sheets og views mod projektets regex-mønstre, så output passer til CDE og IKT-krav.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
import re
doc = DocumentManager.Instance.CurrentDBDocument
SHEET_NUMBER_PATTERN = r"^[A-Z]{2,3}-\d{3,4}(-[A-Z0-9]+)?$"
VIEW_NAME_PATTERN = r"^(ARK|KON|EL|VVS|VENT|BRAND|BIM)-[A-Z0-9]+-.+"
sheets = FilteredElementCollector(doc).OfClass(ViewSheet).ToElements()
views = FilteredElementCollector(doc).OfClass(View).ToElements()
issues = []
for sheet in sheets:
if sheet.IsPlaceholder:
continue
if not re.match(SHEET_NUMBER_PATTERN, sheet.SheetNumber or ""):
issues.append(["Sheet", sheet.Id.IntegerValue, sheet.SheetNumber, sheet.Name, "SheetNumber matcher ikke standard"])
for view in views:
if view.IsTemplate:
continue
if view.ViewType in [ViewType.ProjectBrowser, ViewType.SystemBrowser, ViewType.Internal]:
continue
if not re.match(VIEW_NAME_PATTERN, view.Name or ""):
issues.append(["View", view.Id.IntegerValue, "", view.Name, "ViewName matcher ikke standard"])
OUT = [["Type", "ElementId", "SheetNumber", "Navn", "Fejl"]] + issues if issues else ["OK - views og sheets følger navngivningsstandarden"]IFC export readiness check
Dynamo / RevitKører en samlet preflight før IFC-eksport med checks for projektinfo, links, rumdata, klassifikation og modeladvarsler.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
def parameter_text(element, name):
parameter = element.LookupParameter(name) if element else None
if not parameter or not parameter.HasValue:
return ""
value = parameter.AsString() or parameter.AsValueString()
return str(value).strip() if value else ""
def has_any_parameter(element, names):
for name in names:
if parameter_text(element, name):
return True
type_id = element.GetTypeId()
if type_id and type_id != ElementId.InvalidElementId:
element_type = doc.GetElement(type_id)
if element_type:
for name in names:
if parameter_text(element_type, name):
return True
return False
checks = []
project_info = doc.ProjectInformation
required_project_info = ["Project Number", "Project Name"]
for name in required_project_info:
checks.append(["Projektinfo", name, "OK" if parameter_text(project_info, name) else "MANGLER"])
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
bad_rooms = []
for room in rooms:
number = room.get_Parameter(BuiltInParameter.ROOM_NUMBER)
name = room.get_Parameter(BuiltInParameter.ROOM_NAME)
number_value = number.AsString().strip() if number and number.AsString() else ""
name_value = name.AsString().strip() if name and name.AsString() else ""
if not number_value or not name_value or room.Area <= 0:
bad_rooms.append(room.Id.IntegerValue)
checks.append(["Rumdata", "Rum uden nummer/navn/areal", "OK" if not bad_rooms else str(len(bad_rooms))])
elements = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
classification_missing = 0
for element in elements:
if not element.Category or element.Category.CategoryType != CategoryType.Model or element.ViewSpecific:
continue
if not has_any_parameter(element, ["CCSCode", "CCI_Code", "ClassificationCode", "IfcExportAs"]):
classification_missing += 1
checks.append(["Klassifikation", "Objekter uden CCS/CCI/IfcExportAs", "OK" if classification_missing == 0 else str(classification_missing)])
try:
link_status = []
for link_type in FilteredElementCollector(doc).OfClass(RevitLinkType).ToElements():
link_status.append(str(link_type.GetLinkedFileStatus()))
unloaded = [status for status in link_status if "Loaded" not in status]
checks.append(["Links", "Revit links loaded", "OK" if not unloaded else ", ".join(unloaded)])
except:
checks.append(["Links", "Revit links loaded", "Kunne ikke læses"])
warnings_count = len(doc.GetWarnings())
checks.append(["Model health", "Revit warnings", "OK" if warnings_count == 0 else str(warnings_count)])
OUT = [["Område", "Check", "Status"]] + checksLOD/LOI parameter completeness check
Dynamo / RevitKontrollerer om modelobjekter har de aftalte LOD/LOI- og informationsparametre før fagmodel- eller afleveringsmilepæle.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
REQUIRED_PARAMETERS = ["LOD", "LOI", "ModelStatus", "DisciplineCode"]
def parameter_has_value(element, name):
parameter = element.LookupParameter(name)
if parameter and parameter.HasValue:
value = parameter.AsString() or parameter.AsValueString()
if value and str(value).strip():
return True
type_id = element.GetTypeId()
if type_id and type_id != ElementId.InvalidElementId:
element_type = doc.GetElement(type_id)
if element_type:
type_parameter = element_type.LookupParameter(name)
if type_parameter and type_parameter.HasValue:
value = type_parameter.AsString() or type_parameter.AsValueString()
if value and str(value).strip():
return True
return False
def include_element(element):
return (
element.Category
and element.Category.CategoryType == CategoryType.Model
and not element.ViewSpecific
)
elements = FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements()
missing = []
for element in elements:
if not include_element(element):
continue
missing_parameters = [name for name in REQUIRED_PARAMETERS if not parameter_has_value(element, name)]
if missing_parameters:
missing.append([
element.Id.IntegerValue,
element.Category.Name,
getattr(element, "Name", ""),
", ".join(missing_parameters),
])
OUT = [["ElementId", "Kategori", "Navn", "Manglende parametre"]] + missing if missing else ["OK - alle relevante elementer har LOD/LOI-data"]Model health report
Dynamo / RevitGenererer en hurtig sundhedsrapport med Revit warnings, importerede CAD-filer, in-place families, uplacerede rum og linkstatus.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
report = []
warnings = doc.GetWarnings()
report.append(["Warnings", len(warnings), "Bør gennemgås før aflevering"])
imports = FilteredElementCollector(doc).OfClass(ImportInstance).ToElements()
report.append(["Importerede CAD/ImportInstance", len(imports), "Fjern eller link i stedet hvis muligt"])
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
unplaced_rooms = [room for room in rooms if room.Area <= 0]
report.append(["Uplacerede rum", len(unplaced_rooms), "Skal ryddes op før IFC/arealskema"])
views = FilteredElementCollector(doc).OfClass(View).ToElements()
working_views = [view for view in views if not view.IsTemplate and not view.Name.startswith("{")]
report.append(["Views uden templates", len(working_views), "Kontroller browserstruktur og navngivning"])
in_place = []
for family_instance in FilteredElementCollector(doc).OfClass(FamilyInstance).ToElements():
try:
family = family_instance.Symbol.Family
if family and family.IsInPlace:
in_place.append(family_instance)
except:
pass
report.append(["In-place families", len(in_place), "Bør kun bruges hvis aftalt"])
try:
link_rows = []
for link_type in FilteredElementCollector(doc).OfClass(RevitLinkType).ToElements():
link_rows.append([link_type.Name, str(link_type.GetLinkedFileStatus())])
unloaded = [row for row in link_rows if "Loaded" not in row[1]]
report.append(["Unloaded links", len(unloaded), "Alle nødvendige links bør være loaded"])
except:
report.append(["Unloaded links", "Ukendt", "Linkstatus kunne ikke læses"])
OUT = [["Check", "Antal", "Kommentar"]] + reportDigital aflevering check
Dynamo / RevitSamler afleveringskritiske checks for projektinfo, rumdata, klassifikation, FM_ID, views/sheets og Revit warnings.
import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
import re
doc = DocumentManager.Instance.CurrentDBDocument
PROJECT_INFO_PARAMETERS = ["Project Number", "Project Name", "Client Name"]
CLASSIFICATION_PARAMETERS = ["CCSCode", "CCI_Code", "ClassificationCode"]
FM_PARAMETERS = ["FM_ID", "FMID", "AssetID", "Asset Identifier", "DriftsID"]
SHEET_PATTERN = r"^[A-Z]{2,3}-\d{3,4}(-[A-Z0-9]+)?$"
def text_value(parameter):
if not parameter or not parameter.HasValue:
return ""
value = parameter.AsString() or parameter.AsValueString()
return str(value).strip() if value else ""
def has_any_parameter(element, names):
for name in names:
if text_value(element.LookupParameter(name)):
return True
type_id = element.GetTypeId()
if type_id and type_id != ElementId.InvalidElementId:
element_type = doc.GetElement(type_id)
if element_type:
for name in names:
if text_value(element_type.LookupParameter(name)):
return True
return False
def include_model_element(element):
return (
element.Category
and element.Category.CategoryType == CategoryType.Model
and not element.ViewSpecific
)
summary = []
project_missing = [name for name in PROJECT_INFO_PARAMETERS if not text_value(doc.ProjectInformation.LookupParameter(name))]
summary.append(["Projektinfo", "OK" if not project_missing else "MANGLER", ", ".join(project_missing)])
rooms = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType().ToElements()
bad_rooms = 0
for room in rooms:
number = room.get_Parameter(BuiltInParameter.ROOM_NUMBER)
name = room.get_Parameter(BuiltInParameter.ROOM_NAME)
if not text_value(number) or not text_value(name) or room.Area <= 0:
bad_rooms += 1
summary.append(["Rumdata", "OK" if bad_rooms == 0 else "FEJL", str(bad_rooms)])
elements = [element for element in FilteredElementCollector(doc).WhereElementIsNotElementType().ToElements() if include_model_element(element)]
missing_classification = [element.Id.IntegerValue for element in elements if not has_any_parameter(element, CLASSIFICATION_PARAMETERS)]
missing_fm = [element.Id.IntegerValue for element in elements if not has_any_parameter(element, FM_PARAMETERS)]
summary.append(["CCS/CCI", "OK" if not missing_classification else "FEJL", str(len(missing_classification))])
summary.append(["FM_ID", "OK" if not missing_fm else "FEJL", str(len(missing_fm))])
sheets = FilteredElementCollector(doc).OfClass(ViewSheet).ToElements()
bad_sheets = [sheet.SheetNumber for sheet in sheets if not sheet.IsPlaceholder and not re.match(SHEET_PATTERN, sheet.SheetNumber or "")]
summary.append(["Sheet navngivning", "OK" if not bad_sheets else "FEJL", str(len(bad_sheets))])
warnings_count = len(doc.GetWarnings())
summary.append(["Revit warnings", "OK" if warnings_count == 0 else "ADVARSEL", str(warnings_count)])
delivery_ready = all(row[1] == "OK" for row in summary)
OUT = [["Digital aflevering klar", delivery_ready], ["Område", "Status", "Antal/mangler"]] + summary