Room.Boundaries - more curves than walls..?

 

Hi all,

How do I automatically merge several straight subsequent curve segments (“wall segments”) , so the two list in the picture have the same length?

Curve 1 and curve 2 should be merged automatically…

dynamo1

dynamo2

Thomas, the output of the node is simply what the Revit API returns as room boundaries. You are welcome to improve the node’s functionality :wink:

If I had the skill level I would! :slight_smile: But currently I have no idea what i’m doing in Dynamo :wink:

btw a split wall at curve endpoint would do the trick too. The wall type list and curves just need to have the same length

One thing you could try is compare lines that have a common vector. If they also have a common start point or end point you have your culprits.

Andreas, Thomas,

I had a brief look at it, and made some changes that I believe make it a little bit more efficient.

CaptureAlso, SegmentCurve.Element was made obsolete and replaced with SegmentCurve.ElementId in Revit 2016 so it wasnt working in 2016 at all. This code should be exactly what Thomas is asking for as I am not filtering out any duplicate curves.

Also, Thomas, yes it is possible to “join” two boundary segments, but that will return something called PolyCurve so you would end up with a list looking like this: [Line, Line, Line, PolyCurve, Line] . I can add that additional functionality if that’s what you want. Keep in mind that that will make the two lists not be of the same Length. Why? Because normally each wall that encloses a room will be returned but some curves will be joined so naturally the curve list might end up being shorter.

 

@Andres I tried to compare curves with common vectors yesterday, but that only gave more problem with more complex rooms… But thanks for the answer anyway :slight_smile:

 

@Konan, thank for the answer… your code seems to works perfectly! You are naturally right about the list length problem…

 

Is it possible in any way to get a list with the same length as the curves so i’m able to identify each curve as a specific wall construction? (ID/name/…)

Or as secondary, less preferable option, find out which curves are external/internal walls? :slight_smile:

 

 

Thomas,

This must be as close to being called Conan as I will ever get, which of course makes me imagine this:

1127604821560070722Anyways, to answer your question: I thought this was solved. Each segment of the boundary line belongs to a wall that bounds that room. This means that YOU WILL ALWAYS GET EQUAL LENGTH CURVE AND WALL LISTS. What is the problem? With that being said the two lists are also matching in order so first curve in the list is coming from first wall in the list. This means that you can query the wall for its construction/ID or whatever and “assign” that to the curve. Same goes for querying that wall for whether its exterior or interior. It should be relatively easy the way that they are structured now. If you are seeing a different behavior than one described here, please post your Revit file, as I am not able to replicate it.
Now, back to your original inquiry about joining curves. Like I said you can do that, but in that case if two curves become one, you will end up with an extra wall in the respective walls list.

I think I deleted the wrong text before posting my last comment… … hmm … :-S Sry

Your code works perfectly with the room I posted in the first comment, but when I redefine the room shape with a new area it doesn’t - I don’t get equal length curve and wall lists :-/ (see pics)

revit model: test_room :slight_smile:

dynamo1 dynamo2

 

 

 

This is caused by different Room bounding conditions. For example:

Capture

 

 

Capture

 

 

Capture

 

 

 

You are probably noticing a pattern there. Revit has trouble recognizing a wall by its “short” face. Also, in case there was a small break in-between the walls, rooms will automatically fill in the gap to enclose themselves, but in that case - and understandably - there is no wall associated with that particular edge.

Does that make sense?

However, what is possible is what you have originally asked for - that is to join some lines together. This of course comes with a risk of lines not exactly matching to their walls. Let’s say that we assume that every time there is a small modeling mistake (like images above) and Revit automatically fills in the gaps in room boundaries, we can safely say that that short stub of a line can belong to the “next” wall in series. Now, if every time that we encounter a Null in a list of walls, we take a corresponding Curve and join it to the next curve in series, then technically we are just “applying” it to the next wall in series. Then we can just clean the Null reference from the walls list, and we are good to go. Something like this:
Capture

 

 

And here is the code to clean up the Null references in the walls while making some polycurves in curve list:
Capture

Konrad Thank you VERY MUCH!

 

I can’t thank you enough!

 

The script works perfectly! :smiley: :smiley: :smiley:

Hi @Konrad_K_Sobon & @Thomas_Perkov,

I was trying to read Konrad’s Code however, it is too small and I wasn’t able to read it. Could you please share the code?
I have also similar issues that the curves that @Thomas_Perkov had. For some reason the curve I retrieve form the room boundary has divided into multiple pieces. (just like in the image you posted @Thomas_Perkov)

Thank you so much!!

Hi, it’s from Archilab package, RoomBoundaries.CleanNulls

import clr
import sys
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

from System import Array
from System.Collections.Generic import *

walls = IN[0]
curves = IN[1]


for i, (wList, cList) in enumerate(zip(walls, curves)):
	for j, (wall, curve) in enumerate(zip(wList, cList)):
		if wall == None:
			del walls[i][j]
			# take corresponding curve and join it to next one in order
			# if there is no next one, then use previous
			curveList = [curves[i][j], curves[i][j+1]]
			curveArray = List[Curve](curveList)
			newPolyCurve = PolyCurve.ByJoinedCurves(curveArray)
			curves[i][j+1] = newPolyCurve
			del curves[i][j]

OUT = [walls, curves]
1 Like

Thank you so much @Vladimir! very appreciated!

And what’s the point of doing this? You’re loosing wall-curve info. You could build small solid boxes by extruding and thickening shortened “null” curves, and find elements by Element.Intersects Solid (Bimorph package). So, no “nulls” at all.

Long in short, I was trying to add a thin layer of wall as a wall finish by using the room boundaries and its edges. However, when I apply the walls to the edges I get two sometimes three separate walls on the same edge of the room boundary. See screencap below:

That was the reason.

I honestly changed my mind since those thin walls creates more problems for documentation purposes. For instance, you can’t tag your wall types when those walls are merged into room walls and also it is hard to dimension rooms.

Anyway, thank you though!

By the way, I just noticed that Springs package has a great node that simplifies the curve loop segments into single line. In case anyone needed. “Springs.CurveLoop.Simplify”

image

Yeah wall finishes are one of those tricky things in Revit. Currently my preferred method is still walls because you can join them to cut doors/windows from them. If you ever stop them at openings manually then I’ve found railings an interesting approach in the past if surface pattern alignment doesn’t matter. For skirtings using roofing and fascias for finish/skirting actually works quite well.

1 Like