Create PolyLoop from room.BoundarySegment

Create PolyLoop from room.BoundarySegment

Anonymous
Not applicable
2,070 Views
8 Replies
Message 1 of 9

Create PolyLoop from room.BoundarySegment

Anonymous
Not applicable

This might be a stupid question, so correct me if I'm completely off. 

 

I'm trying to leverage the .centroid property of the PolyLoop class, so I can find the center of my L-shaped rooms, but I can't figure out how to get my BoundarySegments to polyloops. 

 

I'm currently getting the roomBoundarySegment of the room and converting them into polylines in a foreach loop. 

 

public XYZ GetRoomCentroid(Room room)
        {
            IList<IList<BoundarySegment>> roomBoundarySegment = room.GetBoundarySegments(new SpatialElementBoundaryOptions());
            IList<PolyLine> roomPolyLines = null; 
            IList<XYZ> listCoord = null;

            string message = "BoundarySegment:";



            foreach (IList<BoundarySegment> segmentList in roomBoundarySegment)
            {
                foreach (BoundarySegment segment in segmentList)
                {
                    

                    //Get startpoint of curve
                    //message += "\n Curve startpoint (" + segment.GetCurve().GetEndPoint(0).X + "," + segment.GetCurve().GetEndPoint(0).Y + "," + segment.GetCurve().GetEndPoint(0).Z + ")";

                    //Get endpoint of curve 
                    //message += "\n Curve end´point (" + segment.GetCurve().GetEndPoint(1).X + "," + segment.GetCurve().GetEndPoint(1).Y + "," + segment.GetCurve().GetEndPoint(1).Z + ")";


                    
                    XYZ coordinatesStart = new XYZ(segment.GetCurve().GetEndPoint(0).X, segment.GetCurve().GetEndPoint(0).Y, segment.GetCurve().GetEndPoint(0).Z);
                    XYZ coordinatesEnd = new XYZ(segment.GetCurve().GetEndPoint(1).X, segment.GetCurve().GetEndPoint(1).Y, segment.GetCurve().GetEndPoint(1).Z);

                    listCoord.Add(coordinatesStart);
                    listCoord.Add(coordinatesEnd);


                    PolyLine line = PolyLine.Create(listCoord);
                    
                    roomPolyLines.Add(line);
                    
                }
            }

 

I just can't figure out how to convert polylines, curves or anything into a Polyloop where I can call the .Centroid property.

When I look at the RevitAPI documentation it states the a Polyloop is composed of straight lines segments where each endpoint is the same is the previous startpoint - thats what I get when I'm using the BoundarySegment class as far as I understand.

 

Can anyone share some insight on what I'm doing wrong? 

 

0 Likes
Accepted solutions (1)
2,071 Views
8 Replies
Replies (8)
Message 2 of 9

RPTHOMAS108
Mentor
Mentor
Accepted solution

That object appears to be associated with EnergyAnalysisSpace class. Not sure it can be created directly.

 

To find centroid you can use your curveloops to create a solid i.e. 

GeometryCreationUtilities.CreateExtrusionGeometry(IList(Of CurveLoop), XYZ.Basis.Z, 1)

 

Then your solid can be queried for it's centroid.

0 Likes
Message 3 of 9

Anonymous
Not applicable

@RPTHOMAS108 Thank you - that works perfectly. 

 

Marking your answer as solved. 

 

Do you happen to know a good way to seperate the curves if I have squares in side another square? right now it gives me an error of unconnected lines, which is true but not my intent. 

 

If a try to create it for the room outside the blue boundary, it gets me 8 curves, which is correct. But how do I make it create that as 1 Curveloop and 1 solid which I can find the centroid from? (the shape in in between the black lines)

 

mikkelnymand_1-1618514787347.png

 

 

Thank you for the thelp though! 🙂 

 
0 Likes
Message 4 of 9

RPTHOMAS108
Mentor
Mentor

If you need to identify the outer loops you will have to do something similar to below:

 

The Building Coder: Disjunct Planar Face Outer Loops (typepad.com)

 

Are you saying the extrusion function does not allow inner loops to represent voids?

 

In the end the circle has the same centroid as a donut.

0 Likes
Message 5 of 9

Anonymous
Not applicable

@RPTHOMAS108 Okay - I will check out the link. 

 

No the extrusion function most likely allows it, but the Curveloop does not - it wont accept line that dont connect. 

I'm getting the below error when trying to move the roomtag of the outer room (room 11). 

mikkelnymand_0-1618527339703.png

 

I've gotten it to work on almost all other shapes I try - some L-, and U-shaped rooms doesn't work, but I'm handling the exceptions for now and skipping the room and outputting it in a Dialog when all other rooms are moved. 

Below is what I've tested on so far, only one of them fails. 

mikkelnymand_0-1618527154382.png

 

0 Likes
Message 6 of 9

RPTHOMAS108
Mentor
Mentor

Your issue is your centroid is outside the body of the room (as would usually be the case for O, U and L etc). So centroid can't be used to place the room tag?

0 Likes
Message 7 of 9

Anonymous
Not applicable

Yea, I actually got that, but I’m handling the exceptions with IsInsideRoom - but with the O I’m getting and error in my foreach loop when I create the curveloop.

I was wondering how to catch that.

 

I can place the tags, sure. But they need to be inside the room - we would rather have to manually move L and O shaped if centroid can’t place them inside. 

is there a mathematical way to determine a better center for those rooms? 

The only way I see is to use a centroid of one of the straight shapes in the L, by dividing it to into to straight shapes - I just have no idea how to determine this programmatically while also handling normal rooms. 

0 Likes
Message 8 of 9

RPTHOMAS108
Mentor
Mentor

Yes for a CurveLoop the lines must be joined.

 

If you take a horizontal unbound line with origin at your centroid you can test for intersections with this horizontal ray against the curves from your curve loops that you know are associated with that room.

 

1) If you find an odd number of intersection left of your centroid then I believe your centroid is within solid

2) If you find even number of intersections left of your centroid then I believe your centroid is outside solid

 

For (2) average the first and second intersections to the left of centroid for a point inside the room just to the left of centroid.

 

i.e. travelling through all points left of centroid we know that you will ultimately end up outside your room (regardless of if you start inside or out). You either started inside your room in which case you must pass through an odd number of boundaries to get outside. Otherwise you started outside your room needed to pass through one wall the get inside and then an odd number to get back outside (even number).

 

This is how I believe they check these things.

 

With a horizontal line there is a case where you pass through nothing on the left (reverse C). For 0 intersection you are outside. Would have to consider intersections by taking rays through other directions to find an appropriate inside location for such things e.g. vector between centroid and mid point of curve from one of the curve loops.

 

0 Likes
Message 9 of 9

Anonymous
Not applicable

@RPTHOMAS108 Okay - Thank you for the help. 

 

I got to work more on this, but for now I'll filter out the once that doesn't work as intended and they can be done manually. 

 

I'm collection all the failed rooms in a list, and posting it as i dialog afterwards, so people know what rooms didn't get centered. 

 

I appreciate the assistance. 

0 Likes