Hit Element.Geometry with Ray and get Distance | Vector Collision Element.Geometry

Hi everyone :slight_smile:

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)

Is there a better / faster way to do this?

Kind regards,
Jannis

Hi @Jannis,

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.
image

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.

1 Like

Hi Jannis,

As a supplement to @mohamed.m.matook’s answer, here’s a way to do it using the ReferenceIntersector from the API:

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 :slight_smile:

Ps: Read more about the ReferenceIntersector class here.

2 Likes

Hi @MartinSpence,
thanks for the answer :slight_smile: 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).
image

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.

Hi @Jannis,

Could you perhaps elaborate on what your overall goal is? :slight_smile:

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 :slight_smile:

Hey Martin,
thanks for getting back to me :slight_smile:

It is my goal to get the UKR / UKRD from a specific point of the element. The problem is that the ray goes “through” the opening of a ceiling.

For this reason I have to get the curves of the ceiling and create solids in the area of the openings.

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.

Here is my script and my testfile :slight_smile:
Example.rvt (3.0 MB) reference.dyn (53.9 KB)