Here are some notes on the properties and ordering of area boundary segments from a case handled by my colleagues Katsuaki Takamizawa, Harry Mattison and Tamas Badics:
Question: I am analysing a Revit area element, marked below by the red circle, with another adjacent area beside it:
I would have assumed this area to have 4 segments in its boundary. When I use the RvtMgdDbg snoop functionality to explore it, though, it displays 5 segments:
Is this the expected behaviour? If so, I cannot simply use the vertex and edge count to analyse an area and determine whether it is triangular or rectangular. Instead, I have to check whether adjacent edges are parallel, and if so, treat them as one edge instead of two.
Concerning the ordering of edges, I have drawn the lines using the edge coordinates, starting from segment 0 in red and ending with segment 4 in dark blue:
The boundary segments seem to be stored in counter clockwise order. Is this always true?
Answer: The order of storage is counter clockwise for outer boundaries and clockwise for inner boundaries. For instance, imagine a room with an island at the centre. It will have two boundaries, one outer, and one inner.
As for the number of segments, what you see is expected in this situation.
Questions to You
By the way, before we close, I have two questions to you:
- Is anyone out there using RealDWG inside a Revit add-in, to read DWG files in native format?
- Does anyone know of a profiler that works with Revit 2010 add-ins?
Thank you!
Jeremy,
Great blog! Been a follower for some time now.
I apologize for reviving a nearly one-year-old post. For a few years I've been trying to "automate" many of our daily tasks, adding pieces at a time to help our firm's Revit adoption and growth (basically eliminate as much of the human-error element as possible, without replacing responsibilities of actual people... delicate balance)
Today's venture has led me to revisit building code analysis.
I'm researching ways of:
1. Identifying adjacency relationships between area/rooms/spaces (e.g., Room 1 = Occupancy classification A-2, Room 2 = A-4)
2. Looking to Fire Rating parameter of walls to determine separation
3. Flag rooms with non-compliant separation (maybe even schedule separation required as according to key schedule or a schedule driven by shared params versus separation currently provided in the model)
Any ideas?
Posted by: Aaron | February 24, 2010 at 18:02
Dear Aaron,
I am very glad you like it and find it worthwhile following, that feels good.
There are many ways to identify adjacency relationships and they seem to be constantly growing as well:
All FamilyInstance objects have FromRoom and ToRoom properties, which at least are implemented on door elements:
- FromRoom: The room from which the door or window is opened.
- ToRoom: The room to which the door or window is opened.
They can be used to identify adjacent rooms with a connecting door between them.
You can make use of the GetRoomAtPoint and GetSpaceAtPoint methods.
Another interesting pair of methods in this context are the Room.IsPointInRoom and Space.IsPointInSpace methods, which determines whether a given point lies within the specified volume. Space.IsPointInSpace is used to analyse space adjacencies in
http://thebuildingcoder.typepad.com/blog/2009/07/space-adjacency.html
From a room you can also determine all its bounding elements such as walls etc., and then set up a relationship graph to map all rooms to their bounding elements and vice versa. You can analyse this relationship graphs and use the fact that all rooms sharing the same bounding element will be neighbours.
I hope this helps.
Cheers, Jeremy.
Posted by: Jeremy Tammik | March 01, 2010 at 12:03
Hi Jeremy,
I am able to get the boundaries of a particular room. Now my problem is I am having a point say A(x,y,z) and I want to check whether this point lie on any of the boundary of the room? I am using the below code:
foreach (BoundarySegmentArray bsa in room.Boundary)
{
int flag = 0;
foreach (BoundarySegment bs in bsa)
{
Wall revitWall = bs.Element as Wall;
if (revitWall != null)
{
Curve bsCrv = bs.Curve as Curve;
LocationCurve lcrv = revitWall.Location as LocationCurve;}
}
}
here the location curver give me only two points of the boundary and if i make an arc then I have to go for third point which will be not lie on the boundary and that make it unwanted.
I also use the below code but arc become null in this case:
foreach (BoundarySegmentArray bsa in room.Boundary)
{
int flag = 0;
foreach (BoundarySegment bs in bsa)
{
Wall revitWall = bs.Element as Wall;
if (revitWall != null)
{
Options opt = revitApp.Create.NewGeometryOptions();
opt.ComputeReferences = true;
opt.IncludeNonVisibleObjects = true;
Autodesk.Revit.Geometry.Element geomElem = bs.Element.get_Geometry(opt);
foreach (GeometryObject objj in geomElem.Objects)
{
Arc arc = objj as Arc;
Line line = objj as Line;
Solid solid = objj as Solid;
if (arc != null)
{
}
}
}
}
}
Will you please tell me how I can get that point is lie on the boundary of the room or not?
Thanks in advance
Posted by: Ritish | September 28, 2010 at 03:05
Dear Ritish,
Thank you ever so much, I love geometrical questions!
Yes, I think this is really easy to solve, and provide much more functionality than using the method you suggest above working from just the wall end points. Instead, you can query the wall location curve for its geometrical curve C. Use Curve.Project to project your point P onto C, calling the result of the projection Q, and determine the distance from P to Q. If it is small enough, you can consider P to lie on the room boundary.
Sound good?
It does to me!
Cheers, Jeremy.
Posted by: Jeremy Tammik | October 04, 2010 at 03:40