Hi,
We want to calculate the column finish area of columns of room if column is present half inside the room and half outside, we have to ignore the outside finish area and only want the area which comes inside the room bounding's. in Revit API.
Attaching the screenshot as well to see column case visually.
Thank you.
Regards,
Pravin
1) Get column base curve.
2) Get the room bounding segments and their curves.
3) Get the intersections between column curves and the room curves.
4) Calculate circumference of the column curve lying in the room boundary.
5) Using room height calculate the area.
Might be slightly more straightforward in that the BoundarySegment class has an ElementID property that identifies the Element that generated the boundary segment.
If you review these in RevitLookup you get the segment length measured to the centre of the wall. This length however likely depends on how the GetBoundarySegments is called i.e.
Use 'SpatialElementBoundaryOptions.SpatialElementBoundaryLocation = Finish' instead of center, then you may get the curve length for each face which you can multiply with room height.
I've not really experimented though all I can tell is the curve lengths go to the centre of the wall in the lookup tool (which is probably using default options).
We are following same way to get the columns but from the edges we are not able to get the exact overlapping edges with room for the column inside the room.
@RPTHOMAS108 solution looks much cleaner and simplier, you should give it a try. If you get the lines only to the centre of the wall, you can get the wall thickness and subtract one half of it from the line length.
Hi..
In our case we don't know exactly how much portion of the column is inside and how much portion is outside. also room is present in active document and column is present in linked document. kindly suggest how can we het the edges of column which comes inside the room.
thank you.
Regards,
Pravin
Slightly more challenging but same principles as noted previously apply:
Summary of below:
Private Function TObj75(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
If commandData.Application.ActiveUIDocument Is Nothing Then Return Result.Cancelled Else
Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
Dim Doc As Document = UIDoc.Document
Dim R As Reference = Nothing
Try
R = UIDoc.Selection.PickObject(Selection.ObjectType.Element, "Pick a room any room.")
Catch ex As Exception
End Try
If R Is Nothing Then Return Result.Cancelled Else
Dim Room As Room = TryCast(Doc.GetElement(R), Room)
If Room Is Nothing Then Return Result.Cancelled Else
Dim GeomEl As GeometryElement = Room.ClosedShell
Dim S As Solid = GeomEl(0) 'Assume single solid for brevity
Dim FEClnk As New FilteredElementCollector(Doc)
Dim ECFlnk As New ElementClassFilter(GetType(RevitLinkInstance))
Dim Lnk As List(Of RevitLinkInstance) = FEClnk.WherePasses(ECFlnk).ToElements.Cast(Of RevitLinkInstance).ToList
Dim LinkDoc As Document = Lnk(0).GetLinkDocument() 'Assume single link containing columns for brevity
Dim SolTransformed As Solid = SolidUtils.CreateTransformed(S, Lnk(0).GetTransform.Inverse)
'The solid in the coord system of the link
Dim ElintS As New ElementIntersectsSolidFilter(SolTransformed)
Dim ECF As New ElementCategoryFilter(BuiltInCategory.OST_StructuralColumns)
Dim LandF As New LogicalAndFilter(ElintS, ECF)
Dim FEC As New FilteredElementCollector(LinkDoc)
Dim Els As List(Of ElementId) = FEC.WherePasses(LandF).ToElementIds
Using tx As New Transaction(Doc, "Copy")
If tx.Start = TransactionStatus.Started Then
Dim NewIDs As List(Of ElementId) = ElementTransformUtils.CopyElements(LinkDoc, Els, Doc, Lnk(0).GetTransform, Nothing)
Dim Ops As New SpatialElementBoundaryOptions() With {.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish}
Dim BoundSegs As IList(Of IList(Of BoundarySegment)) = Room.GetBoundarySegments(Ops)
For i = 0 To BoundSegs.Count - 1
Dim SegLst As IList(Of BoundarySegment) = BoundSegs(i)
Debug.WriteLine("List: " & CStr(i + 1)) 'List 0' just doesn't sound right
For ix = 0 To SegLst.Count - 1
Dim Seg As BoundarySegment = SegLst(ix)
If NewIDs.Contains(Seg.ElementId) = False Then Continue For Else
Debug.WriteLine(CStr(Seg.ElementId.IntegerValue) & ", " & (Seg.GetCurve.Length * 304.8).ToString("F1"))
'Tried below to see what .LinkedElementId represented (not apparent)
'Debug.WriteLine(CStr(Seg.LinkElementId.IntegerValue) & "," & Seg.GetCurve.Length & "FromLink")
Next
Next
tx.RollBack()
End If
End Using
End Function
Proof of concept:
List: 1
427532, 400.0
427532, 750.0
427532, 400.0
427536, 275.0
427536, 200.0
427534, 200.0
427534, 750.0
427534, 200.0
Dear Pravin,
Thank you for your query, and much greater thanks to Richard RPTHOMAS108 Thomas for this beautiful and robust solution.
Happily, it simultaneously answers a number of other recent issues discussed here in the forum which also involve intersections and room boundaries in linked documents, including your previous thread on how to find the rooms geometry adjacent to walls, where an analogous approach can be applied:
I wish I could award ever so many more than just one like to you, Richard!
Best regards,
Jeremy
Jeremy thanks I appreciate your kind comments.
As users of Revit we had long applied this technique in the UI i.e. tab into a linked element, copy it to the clipboard and paste it to the same place within the host document. The ElementTransformUtils is definitely a powerful feature of the API which sometimes gets overlooked in terms of how it can be applied to solve problems.
Dear Pravin and Richard,
I am so thrilled by this solution that I edited and shared it for posterity in The Building Coder:
Pravin, would you like to let us know how this suggestion worked out for you?
Would you like to express any appreciation to Richard for this brilliant suggestion and all the in-depth experience that he shared, both developing this solution manually in the end user interface and then translating that tricky approach into such a succinct API solution?
I am not aware of anyone else who would have been capable and willing to document and share such an effective solution.
Best regards,
Jeremy