Source code for revitron.room

""" 
This submodule contains a wrapper classes for **Revit** room elements.
"""
from revitron.element import Element


[docs]class Room(Element): """ A wrapper class for room elements. """
[docs] def getBboxCenter(self, inRoomOnly=False): """ Get the center point of a room's bounding box. Args: inRoomOnly (boolean): Optionally only return a point in case the bounding box center is actually in the room Returns: object: A Revit point object """ room = self.element bbox = self.getBbox() point = bbox.getCenterPoint() if room.IsPointInRoom(point) or not inRoomOnly: return point
[docs] def getBoundary(self): """ Get the boundary of a given room. Returns: list: A list of boundary segment curves """ import revitron room = self.element options = revitron.DB.SpatialElementBoundaryOptions() boundaryLocation = revitron.DB.AreaVolumeSettings.GetAreaVolumeSettings( revitron.DOC ).GetSpatialElementBoundaryLocation(revitron.DB.SpatialElementType.Room) options.SpatialElementBoundaryLocation = boundaryLocation curveList = [] for boundaryList in room.GetBoundarySegments(options): for boundary in boundaryList: curveList.append(boundary.GetCurve()) return curveList
[docs] def getBoundaryPoints(self): """ Get all points along a room boundary. Returns: list: A list of points """ curveList = self.getBoundary() points = [] for curve in curveList: # If the curve is an arc, first tessellate the curve # and extend the points array with the polyline points. if 'Arc' in str(curve.GetType()): points.extend(curve.Tessellate()) else: points.append(curve.GetEndPoint(0)) return points
[docs] def getBoundaryInsetPoints(self, inset=0.1): """ Get all points along an inset of the room boundary. The inset is useful in cases where a point has to be used as a location for a tag and therefore should be located direktly on the boundary but a little bit more inside instead to avoid issues and warnings. Args: inset (float, optional): The inset. Defaults to 0.1. Returns: list: The list of points """ import revitron room = self.element options = revitron.DB.SpatialElementBoundaryOptions() boundaryLocation = revitron.DB.AreaVolumeSettings.GetAreaVolumeSettings( revitron.DOC ).GetSpatialElementBoundaryLocation(revitron.DB.SpatialElementType.Room) options.SpatialElementBoundaryLocation = boundaryLocation curves = dict() points = [] try: for boundaryList in room.GetBoundarySegments(options): cl = revitron.DB.CurveLoop() for x in boundaryList: cl.Append(x.GetCurve()) curves[cl.GetExactLength()] = cl curveLengths = curves.keys() longest = curves[max(curveLengths)] tempInset = revitron.DB.CurveLoop.CreateViaOffset( longest, inset, revitron.DB.XYZ(0, 0, 1) ) if tempInset.GetExactLength() > max(curveLengths): tempInset = revitron.DB.CurveLoop.CreateViaOffset( longest, inset, revitron.DB.XYZ(0, 0, -1) ) for c in tempInset: points.append(c.GetEndPoint(0)) except: # If CurveLoop throws exception, get points from boundary. points = self.getPoints() pass return points
[docs] def getPointClosest(self, point, inset=0.1): """ Get the point on a room boundary that is the closest to a given point. Args: point (object): A Revit XYZ object inset (float, optional): An optional room boundary inset. Defaults to 0.1. Returns: object: A Revit XYZ object """ closestDistance = False for p in self.getBoundaryInsetPoints(inset): d = p.DistanceTo(point) if not closestDistance: closestDistance = d closestPoint = p else: if d < closestDistance: closestDistance = d closestPoint = p return closestPoint
[docs] def getPointTopLeft(self, inset=0.1): """ Get the most top left point of a room boundary. Args: inset (float, optional): An optional room boundary inset. Defaults to 0.1. Returns: object: A Revit XYZ object """ import revitron bbox = self.getBbox() bboxTopLeft = revitron.DB.XYZ(bbox.Min.X, bbox.Max.Y, bbox.Min.Z) return self.getPointClosest(bboxTopLeft, inset)
[docs] def getPointTopRight(self, inset=0.1): """ Get the most top right point of a room boundary. Args: inset (float, optional): An optional room boundary inset. Defaults to 0.1. Returns: object: A Revit XYZ object """ import revitron bbox = self.getBbox() bboxTopLeft = revitron.DB.XYZ(bbox.Max.X, bbox.Max.Y, bbox.Min.Z) return self.getPointClosest(bboxTopLeft, inset)
[docs] def getPointBottomLeft(self, inset=0.1): """ Get the most bottom left point of a room boundary. Args: inset (float, optional): An optional room boundary inset. Defaults to 0.1. Returns: object: A Revit XYZ object """ import revitron bbox = self.getBbox() bboxTopLeft = revitron.DB.XYZ(bbox.Min.X, bbox.Min.Y, bbox.Min.Z) return self.getPointClosest(bboxTopLeft, inset)
[docs] def getPointBottomRight(self, inset=0.1): """ Get the most bottom right point of a room boundary. Args: inset (float, optional): An optional room boundary inset. Defaults to 0.1. Returns: object: A Revit XYZ object """ import revitron bbox = self.getBbox() bboxTopLeft = revitron.DB.XYZ(bbox.Max.X, bbox.Min.Y, bbox.Min.Z) return self.getPointClosest(bboxTopLeft, inset)
[docs] def getPointGrid(self, size=5, inset=0.05): """ Generates a point grid based on a given size within the room boundary. Args: size (float, optional): The maximum grid field size. Defaults to 5.00. inset (float, optional): The inset of the room boundary. Defaults to 0.05. Returns: list: A list of Revit XYZ objects """ import revitron import math points = [] bbox = self.getBbox() if isinstance(bbox, revitron.BoundingBox): tlp = revitron.DB.XYZ(bbox.Min.X, bbox.Max.Y, bbox.Min.Z) brp = revitron.DB.XYZ(bbox.Max.X, bbox.Min.Y, bbox.Min.Z) lengthX = bbox.Max.X - bbox.Min.X lengthY = bbox.Max.Y - bbox.Min.Y fieldSizeX = ((lengthX - (2 * inset)) / math.ceil(lengthX / size)) fieldSizeY = ((lengthY - (2 * inset)) / math.ceil(lengthY / size)) _x = tlp.X + inset while (_x < brp.X): _y = brp.Y + inset while (_y < tlp.Y): p = revitron.DB.XYZ(_x, _y, tlp.Z) if self.element.IsPointInRoom(p): points.append(p) _y = _y + fieldSizeY _x = _x + fieldSizeX return points
[docs] def traceHeight(self, view3D, elementFilter=None, gridSize=5, inset=0.05): """ Traces the room heights and returns an object containing the min/max bottom and min/max top points. Args: view3D (object): A Revit 3D view. elementFilter (mixed, optional): Either a list of Revit element IDs or a Revit ElementClassFilter. Defaults to None. gridSize (float, optional): The maximum grid field size for the raytracing. Defaults to 5.00. inset (float, optional): The inset of the room boundary. Defaults to 0.05. Returns: object: An object containing a top and bottom property. Both properties are nested objects containing an Min and a Max value. """ import revitron points = [] if self.element.Location: gridPoints = self.getPointGrid(gridSize, inset) boundaryPoints = self.getBoundaryInsetPoints(inset) if gridPoints: points = gridPoints if boundaryPoints: points = points + boundaryPoints # Set z to the room center. z = self.getBboxCenter().Z intersectionsTop = [] intersectionsBottom = [] for point in points: point = revitron.DB.XYZ(point.X, point.Y, z) raytracer = revitron.Raytracer(point, view3D) try: intersectionsTop.append( raytracer.findIntersection(revitron.DB.XYZ(0, 0, 1), elementFilter).Z ) except: pass try: intersectionsBottom.append( raytracer.findIntersection(revitron.DB.XYZ(0, 0, -1), elementFilter).Z ) except: pass try: top = revitron.AttrDict({ 'min': min(intersectionsTop), 'max': max(intersectionsTop) }) except: top = None try: bottom = revitron.AttrDict({ 'min': min(intersectionsBottom), 'max': max(intersectionsBottom) }) except: bottom = None return revitron.AttrDict({'top': top, 'bottom': bottom})