Source code for mastoron.create

import mastoron
import revitron
import Autodesk.Revit.Creation as Creation
from revitron import _
from mastoron.variables import *
from System.Collections.Generic import List


[docs]class Creator(object): """ Base class for creating Revit elements. """
[docs] def __init__(self, docLevels, element, elementType): """ Inits a new Creator instance. Args: docLevels (object): A list of Revit levels element (object): A Revit element elementType (object): A Revit element type """ self.docLevels = docLevels self.element = element self.elementType = elementType
[docs]class FloorCreator(Creator): """ Inits a new FloorCreator instance. """ def __init__(self, docLevels, element, floorType, loopOffset=0.0, offsetHoles=True): super(FloorCreator, self).__init__(docLevels, element, floorType) self.loopOffset = loopOffset self.offsetHoles = offsetHoles
[docs] def fromBottomFaces(self): """ Creates Revit floor objects from all downward facing faces of given element. Returns: object: A list of Revit floors """ faces = mastoron.FaceExtractor(self.element).getBottomFaces() self.level = mastoron.Level.getLevel( self.element, self.docLevels, min=True ) levelElevation = self.level.Elevation uv = revitron.DB.UV(0.5, 0.5) floors = [] for face in faces: faceZ = face.Evaluate(uv).Z self.offset = faceZ - levelElevation self.curveLoops = mastoron.BorderExtractor(face).getBorder() floor = self._create() if floor: floors.append(floor) return floors
[docs] def fromFamilyModelLines(self, subcategory): """ Create a Revit floor object from model lines of a subcategory for given element. Args: subcategory (string): The name of a subcategory Returns: object: A Revit floor """ self.curveLoop = mastoron.LineExtractor(self.element).bySubcategory(subcategory) self.level = mastoron.Level.getLevel( self.element, self.docLevels, min=True ) levelElevation = self.level.Elevation if not self.curveLoop: return None if self.curveLoop.HasPlane: loopZ = self.curveLoop.GetPlane().Origin.Z else: print('Cannot create floor from non-planar lines.') self.offset = loopZ - levelElevation floor = self._create() if floor: return floor
[docs] def fromTopFaces(self): """ Create a Revit floor object from all upward facing faces of given element. Args: offset (float, optional): The offset distance. Defaults to 0.0. Returns: object: A list of Revit floor objects """ faces = mastoron.FaceExtractor(self.element).getTopFaces() self.level = mastoron.Level.getLevel( self.element, self.docLevels, min=False ) levelElevation = self.level.Elevation uv = revitron.DB.UV(0.5, 0.5) floors = [] for face in faces: faceZ = face.Evaluate(uv).Z self.offset = faceZ - levelElevation self.curveLoops = mastoron.BorderExtractor(face).getBorder() floor = self._create() if floor: floors.append(floor) return floors
def _create(self): """ Internal function for creating a Revit floor. Returns: object: A Revit floor """ self.curveLoops = self._sanitizeLoops() if not self.loopOffset == 0.0: self.curveLoops = self._offsetLoops() try: floor = revitron.DB.Floor.Create( revitron.DOC, self.curveLoops, self.elementType, self.level.Id ) except: print('Cannot create floor: Offset distance probably resulted in overlapping loops.') return None _(floor).set(FLOOR_OFFSET, self.offset) return floor def _offsetLoops(self): offsetLoops = [] for index, curveLoop in enumerate(self.curveLoops): if index >= 1 and self.offsetHoles == False: offsetLoops.append(curveLoop) continue try: offsetLoop = revitron.DB.CurveLoop.CreateViaOffset( curveLoop, self.loopOffset, revitron.DB.XYZ(0, 0, 1)) offsetLoops.append(offsetLoop) except: print('Cannot create floor: Offset distance too large. Revit cannot handle self intersections') return offsetLoops def _sanitizeLoops(self): sanitizedLoops = [] outerLoop = self.curveLoops[0] if not outerLoop.IsCounterclockwise(revitron.DB.XYZ(0,0,1)): outerLoop.Flip() sanitizedLoops.append(outerLoop) for curveLoop in self.curveLoops[1:]: if curveLoop.IsCounterclockwise(revitron.DB.XYZ(0,0,1)): curveLoop.Flip() sanitizedLoops.append(curveLoop) return sanitizedLoops
[docs]class RoofCreator(Creator): """ Inits a new RoofCreator instance. """ def __init__(self, docLevels, element, roofType): super(RoofCreator, self).__init__(docLevels, element, roofType)
[docs] def fromTopFaces(self): """ Creates Revit roof objects from all upward facing faces of given element. Returns: object: A list of Revit roofs """ faces = mastoron.FaceExtractor(self.element).getTopFaces() self.level = mastoron.Level.getLevel( self.element, self.docLevels, min=False ) levelElevation = self.level.Elevation uv = revitron.DB.UV(0.5, 0.5) roofs = [] for face in faces: faceZ = face.Evaluate(uv).Z self.offset = faceZ - levelElevation self.curveLoops = mastoron.BorderExtractor(face).getBorder() roof = self._create() roofs.append(roof) return roofs
def _create(self): """ Internal function for creating a Revit roof. Returns: object: A Revit roof """ import clr self.curveArray = revitron.DB.CurveArray() self.curveLoops = self._sanitizeLoops() for curve in self.curveLoops[0]: self.curveArray.Append(curve) self.elementType = revitron.DOC.GetElement(self.elementType) ModelCurveArray = revitron.DB.ModelCurveArray self.modelCurveArray = clr.StrongBox[ModelCurveArray](ModelCurveArray()) roof = revitron.DOC.Create.NewFootPrintRoof( self.curveArray, self.level, self.elementType, self.modelCurveArray ) _(roof).set(ROOF_OFFSET, self.offset) return roof def _offsetLoops(self): offsetLoops = [] for index, curveLoop in enumerate(self.curveLoops): if index >= 1 and self.offsetHoles == False: offsetLoops.append(curveLoop) continue try: offsetLoop = revitron.DB.CurveLoop.CreateViaOffset( curveLoop, self.loopOffset, revitron.DB.XYZ(0, 0, 1)) offsetLoops.append(offsetLoop) except: print('Cannot create floor: Offset distance too large. Revit cannot handle self intersections') return offsetLoops def _sanitizeLoops(self): sanitizedLoops = [] outerLoop = self.curveLoops[0] if not outerLoop.IsCounterclockwise(revitron.DB.XYZ(0,0,1)): outerLoop.Flip() sanitizedLoops.append(outerLoop) for curveLoop in self.curveLoops[1:]: if curveLoop.IsCounterclockwise(revitron.DB.XYZ(0,0,1)): curveLoop.Flip() sanitizedLoops.append(curveLoop) return sanitizedLoops
[docs]class WallCreator(Creator): """ Inits a new WallCreator instance. """ def __init__(self, docLevels, element, wallType): super(WallCreator, self).__init__(docLevels, element, wallType)
[docs] def fromVerticalFaces(self): """ Creates Revit wall objects from all vertical faces of given element. Returns: object: A list of Revit walls """ faces = mastoron.FaceExtractor(self.element).getVeticalFaces() self.level = mastoron.Level.getLevel( self.element, self.docLevels, min=True ) levelElevation = self.level.Elevation walls = [] for face in faces: self.baseCurve = mastoron.BorderExtractor(face).getLowestEdge() self.topCurve = mastoron.BorderExtractor(face).getHighestEdge() faceMin = self.baseCurve.GetEndPoint(0)[2] if not round(faceMin, 5) == round(self.baseCurve.GetEndPoint(1)[2], 5): continue faceMax = self.topCurve.GetEndPoint(0)[2] offset = faceMin - levelElevation height = faceMax - faceMin wall = revitron.DB.Wall.Create( revitron.DOC, self.baseCurve, self.elementType, self.level.Id, height, offset, True, False ) walls.append(wall) return walls
[docs]class RailingCreator(Creator): """ Inits a new RailingCreator instance. """ def __init__(self, docLevels, element, railingType): super(RailingCreator, self).__init__(docLevels, element, railingType)
[docs] def fromTopFaces(self, includeInnerLoops): """ Creates a Revit railing objects from the boundaries of all upward facing faces of given element. Returns: object: A list of Revit railings """ faces = mastoron.FaceExtractor(self.element).getTopFaces() self.level = mastoron.Level.getLevel( self.element, self.docLevels, min=False ) levelElevation = self.level.Elevation uv = revitron.DB.UV(0.5, 0.5) railings = [] for face in faces: faceZ = face.Evaluate(uv).Z self.offset = faceZ - levelElevation curveLoops = mastoron.BorderExtractor(face).getBorder() innerLoops = [] for curveLoop in curveLoops: if curveLoop.IsCounterclockwise(revitron.DB.XYZ(0,0,1)): outerLoop = curveLoop else: innerLoops.append(curveLoop) railing = revitron.DB.Architecture.Railing.Create( document=revitron.DOC, curveLoop=outerLoop, railingTypeId=self.elementType, baseLevelId=self.level.Id ) if railing: _(railing).set(BASE_OFFSET, self.offset) railings.append(railing) if includeInnerLoops: for loop in innerLoops: railing = revitron.DB.Architecture.Railing.Create( document=revitron.DOC, curveLoop=loop, railingTypeId=self.elementType, baseLevelId=self.level.Id ) if railing: _(railing).set(BASE_OFFSET, self.offset) railings.append(railing) return railings