// List to store door elements that the path of travel intersects
List<Element> intersectedDoors = new List<Element>();
// Find a 3D view to use for the ReferenceIntersector constructor
FilteredElementCollector collector = new FilteredElementCollector(mydoc);
View3D view3D = collector
.OfClass(typeof(View3D))
.Cast<View>() // First, cast the collected Elements to Views
.Where(v => v is View3D && !((View3D)v).IsTemplate) // Then check if it is a View3D and not a template
.FirstOrDefault() as View3D; // Finally, cast the result to View3D
List<ElementId> DoorElements = new List<ElementId>();
foreach (var curve in PathOfTravel_Curves)
{
Line curve_line = curve as Line;
XYZ curve_direction = curve_line.Direction;
XYZ curve_Point = curve.GetEndPoint(0);
// Create a category filter for Doors
ElementCategoryFilter doorsCategoryfilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
ReferenceIntersector My_refIntersector = new ReferenceIntersector(doorsCategoryfilter, FindReferenceTarget.Element, view3D);
//IList<ReferenceWithContext> referencesWithContext = My_refIntersector.Find(curve_Point, curve_direction);
ReferenceWithContext referencesWithContext = My_refIntersector.FindNearest(curve_Point, curve_direction);
if (referencesWithContext != null)
{
var referenceElem = referencesWithContext.GetReference();
var refElem = referenceElem.ElementId;
if (DoorElements.Contains(refElem)){ continue; }
else
{
DoorElements.Add(refElem);
totalNumberOfIntersectedDoors += 1;
}
}
}
Hi, I wanted to make a list of all the doors that need to be crossed to follow a path of travel line. This is exactly what Jeremmy Tommik has mentioned in his Github page before : https://github.com/jeremytammik/PathOfTravelDoors
I tried to code what he has recommended, but seems that ReferenceIntersector finds even the doors which are not exactly on the path of travel but the introduced ray is reaching them. I don't know how to avoid it, Any idea?
I am including piece of my code which is doing the task.
(BTW his code does nothing for me, I actually don't see anything in it that can do the task when I open it, maybe there is something that I am not familiar with.)
Thank you for asking and pointing out that. I don't know off-hand whether it was ever completed. Before looking elsewhere, one of the first places to examine before addressing a Revit API programming task is the collection of Revit SDK samples. In this case, you ought to take a look at the PathOfTravel sample. When you say that a ray returns a door intersection even though it has not reached it, you may need to limit the distance of the ray length, or restrict the door intersections to lie within a given room, or something like that. I don't quite understand how to reconcile your two statements, "the introduced ray is reaching them" and "his code does nothing for me". That sounds like a contradiction to me. I hope this helps, anyway.
Thanks @Anonymous for the quick response.
By "introduced ray" I meant the one that is created by the ReferenceIntersector in my own code that I have provided in the post. That might solve the contradiction I guess.
I was actually thinking about those things as well, but isn't it the ReferenceIntersector that generates those rays and therefore doesn't give the flexibility to limit them?
I checked the SDK samples for PathofTravel, but didn't find anything relevant, or maybe I overlooked something.
I will still think about your solutions and see how I can apply them.
Maybe you should take a look at the ReferenceIntersector documentation:
The remarks and examples are pretty illuminating.
You could also use the FindNearest method to ensure that you only get a maximum of one single intersected door, and that it is the nearest one:
So, if the path of travel passes through that door and you set up the intersector ray appropriately, you are bound to find it and nothing else.
Thanks @Jeremmy, I have indeed studied the ReferenceIntersector documentation many times before writing this post but really couldn't find an answer for my question, also in my code I am using the FindNearest method (The Find method is commented, was there to show that it was also tested). And the question is how to set up the intersector ray appropriately.
I am including an screen shot from a floor plan view which I have applied the code to find the doors on the pathofTravel line that starts from a door and ends to the staircase. The doors with yellow circles are the one that my code finds, and as you see only three of them are correct.
Hmm. Maybe, this task can be addressed vastly simpler. How about this suggestion to approach it without using the reference intersector at all:
Afaict, that should solve the problem right there. What do you think?
Just cracked it an hour ago! I tackled it by this trick ( so far good, not sure if it can be a universal solution): For each curve in the path of travel line I did once from the start point following the curve's direction, and once from the endpoint with the reversed direction. Then, I accepted the points that appeared in both.
I thought of another approach as you mentioned: generating an imaginary line at each door location and checking whether the path of travel line segments intersected it or not. However, this method required finding the two points of each door, possibly by examining the geometry of a wall for its opening. While it seemed plausible, I decided against pursuing it initially due to its complexity.
Glad to hear you discovered a viable solution. Congratulations!
Unfortunately, the described technique fails to yield the intended results across certain models, resulting in a null output from the ReferenceIntersector. and I have no clue why? Does anyone has any idea why this is happening?
As a workaround for these specific models, an alternative approach was employed. This involved extracting the end point and start points of each line from door geometry instance, constructing an imaginary line corresponding to the door's location. (the bounding box includes door swing, so not proper for my case), Consequently, the intersection of this imaginary line with the curves of the path of travel lines was examined.
Glad to hear that you found an approach that works reliably for all door instances.
I cannot say why for sure the reference intersector fails in some cases. One thing to consider, though, is that a content creator has complete freedom in the family creation. So, some content creators might choose to represent doors in a completely unconventional manner. They might define the door geometry so that no solids or faces exist for the reference intersector to detect, which would lead to such failures. This infinite flexibility provided for Revit family definitions can make it hard to ensure that an approach always covers all cases. This makes unit testing on a large collection of possible BIM variations all the more important.
The approach you describe is very generic: every door opening is described by one single line from start to end point, and that line must be crossed to pass through the door. That sounds pretty fool proof to me.
Can't find what you're looking for? Ask the community or share your knowledge.