I wish to send out a ray from a specific point and try to hit the Element.Geometry of different objects and get the distance between these points.
It is my goal to get the shortest distance in Z-Direction to the next Element from a specific point.
Currently I draw Lines, split them with the Element.Geometry and take the first one, which takes quite a while, because the line gets split by many objects, which isn´t necessary for the result I need. (Shortest distance to next object in Z-Direction)
could you please share with us some .dyn and .rvt files to better understand what you are trying to accomplish?
The source point is always fixed and known to you as I understood?
The target is an arbitrary object or set of objects? what are these objects? slabs or what? are they always horizontal or they can be in any direction?
There are several nodes that deal with the distance between geometries in Dynamo, built-in, and custom.
There is also Geometry.Intersect node which gives you a point when your line hits the solid. Then you can measure the distance between these two points.
import clr
#Import the Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
#Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
#Reference the active Document and application
doc = DocumentManager.Instance.CurrentDBDocument
#---###Start scripting here:###---#
elem = UnwrapElement(IN[0])
loc = [i.Location.Point for i in elem]
ray = XYZ(0,0,-1)
filter = ElementCategoryFilter(BuiltInCategory.OST_Floors)
dist = []
for i in loc:
refI = ReferenceIntersector(filter, FindReferenceTarget.Face, doc.ActiveView)
refC = refI.FindNearest(i, ray)
reference = refC.GetReference()
intersect = reference.GlobalPoint
dist.append(UnitUtils.ConvertFromInternalUnits(i.DistanceTo(intersect), DisplayUnitType.DUT_MILLIMETERS))
OUT = dist
The code above will need to be tweaked though to get a structured output when you have multiple floors, or you could wrap it in a costum node
Ps: Read more about the ReferenceIntersector class here.
Hi @MartinSpence,
thanks for the answer In theory, it is the perfect solution to my problem, but unfortunately, I need something special. I need to test the ray with “virtual” solids, which were extruded from curves.
Do you know if this is possible somehow? Currently, I have to create DirectShapes from ObjectGeometry to get Elements with ID to feed the ICollection with ElementIds (instead of an ElementFilter).
This way it works, but does not save any performance.
I have to go the way with the solids, because some ceilings have cutouts and a vector goes just through these cutouts. For this reason the distance would not be correct.
Could you perhaps elaborate on what your overall goal is?
And perhaps share a small sample file? A sample file is often the best and fastet way to get a propper solution, since it’s so easy to forget small details which maybe important. What you described in your answer to my post, is rather different from your original post
This isn´t the cleanest way possible, but it does work. Unfortunately it does not work with the “ReferenceIntersector” which seems to work pretty smooth. For this reason I create a Directshape.ByGeometry now, to get an iCollection of Elements, which can be tested with the ray. The problem is, that the process of creating DirectShapes just for collision testing takes ages and does not seem reasonable at all.