Hi,
i made a script wich runs fine a does what it needs to do but i get this error popup-window everytime i run it.
It seems that the issue is related to the XYZ’s at the moment i do UV-calculation and modification and then use them for raytracing.
But i can’t really figure out what exactly.
the script:
# -- coding: UTF-8 --
# imports
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import SpecTypeId
from System.Collections.Generic import List
from pyrevit import revit, script
# doc & appplication
doc = revit.doc
uidoc = revit.uidoc
# collect walls in model
walls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements()
# dictionary containing all wall information: {wall:{faces:[], points:[], dir:[]}}
wall_info = {}
# WALLFACES
for wall in walls:
# get exteriorface
extside = HostObjectUtils.GetSideFaces(wall,ShellLayerType.Exterior)
for e in extside:
extface = wall.GetGeometryObjectFromReference(e)
if extface == None:
continue
else:
wall_info[wall] = {}
wall_info[wall]['wall_faces'] = [extface]
# POINTS & DIRECTIONS
# determin precision of the check
precision = 3
for wall , info in wall_info.items():
# create dictionary sublists for points and directions
wall_info[wall]['points'] = []
wall_info[wall]['directions']= []
# iterate through the face to get points grid and directions
for face in info['wall_faces']:
# create list to store all points of each face in
points = []
point_dir = []
# get min & max UV for each face and determin the interval based on the presicion
bboxUV = face.GetBoundingBox()
u_interval = (bboxUV.Max.U - bboxUV.Min.U) / (precision-1)
v_interval = (bboxUV.Max.V - bboxUV.Min.V) / (precision-1)
# create pointgrid for the face
for i in range(precision):
u = bboxUV.Min.U + i * u_interval
for j in range(precision):
v = bboxUV.Min.V + j * v_interval
uv = UV(u, v)
# check if points are on the face
if face.IsInside(uv):
points.append(face.Evaluate(uv))
point_dir.append(face.ComputeNormal(uv))
else:
# if the UV-point is outside the face, adjust it
for d in range (1, precision):
# Try moving the point towards the center of the face
adjusted_uv = UV(u - d * u_interval / precision, v - d * v_interval / precision)
if face.IsInside(adjusted_uv):
points.append(face.Evaluate(uv))
point_dir.append(face.ComputeNormal(uv))
break
# add points of face to dict entry of the wall
wall_info[wall]['points'].append(points)
wall_info[wall]['directions'].append(point_dir)
# for wall,info in wall_info.items():
# print(wall)
# for i in info:
# print(i)
# for x in info[i]:
# print(x)
# print('------------')
# INTERSECTING
# Get Raytracing view + settings
views = FilteredElementCollector(doc).OfClass(View).WhereElementIsNotElementType().ToElements()
for view in views:
if view.Name == "Systemcheck":
view = view
break
ri = ReferenceIntersector(view)
ri.FindReferencesInRevitLinks = False
# Document UI Units
try:
UIunit = Document.GetUnits(doc).GetFormatOptions(UnitType.UT_Length).DisplayUnits
except:
UIunit = Document.GetUnits(doc).GetFormatOptions(SpecTypeId.Length).GetUnitTypeId()
# Dictionary to store wall thickness
wall_thickness = {}
# set wich all unique systems
systems = set()
# Raytrace for intersections with each point
for wall , info in wall_info.items():
# append wall thickness to list
if wall.Id not in wall_thickness:
wall_thickness[wall.Id] = UnitUtils.ConvertFromInternalUnits(wall.WallType.Width, UIunit)
for points, directions in zip(info['points'],info['directions']):
for point, dir in zip(points,directions):
# set both directions of a point
directions = [dir, -dir]
pointset = set()
pointset.add(wall.Name)
for direction in directions:
# Define the Exclusion Filter and reset it for each direction
filter_list = [wall.Id]
filter = ExclusionFilter(List[ElementId](filter_list))
ri.SetFilter(filter)
# Distance tollarance of intersection: mm to ft (x3.281)
if direction == dir:
distance_check = 150
else:
distance_check = 150 + wall_thickness[wall.Id]
# raytracing loop
while True:
filter = ExclusionFilter(List[ElementId](filter_list))
ri.SetFilter(filter)
ref = ri.FindNearest(point, direction)
# stop condition
if ref is None:
break
# get ref information
refel = ref.GetReference()
refp = ref.GetReference().GlobalPoint
elem = doc.GetElement(refel.ElementId)
dist = UnitUtils.ConvertFromInternalUnits(point.DistanceTo(refp), UIunit) #mm (converted from internal ft)
# check distance
if dist <= distance_check:
pointset.add(elem.Name)
filter_list.Add(refel.ElementId)
# Get the thickness of the intersected wall
if elem.Id not in wall_thickness:
wall_thickness[elem.Id] = UnitUtils.ConvertFromInternalUnits(elem.WallType.Width, UIunit)
# modify check distance
distance_check = distance_check + wall_thickness[elem.Id]
else:
break
pointset_f = frozenset(pointset)
systems.add(pointset_f)
# int = 1
# for set in systems:
# print("set"+ str(int))
# for i in set:
# print(i)
# print('-----')
# int = int +1
output = script.get_output()
data = []
typenr = 1
for set in systems:
dataset = []
dataset.append(typenr)
for i in set:
dataset.append(i)
typenr = typenr+1
data.append(dataset)
headers = ["System Nr"]
longest_set = len(max(systems, key=len))
for i in range(longest_set):
headers.append("Materiaal " + str(i+1))
output.print_table(table_data = data,
title="Wallsystems",
columns= headers,
formats=['', '', '', ''],)
output.log_success('script succesfull')