Esempio n. 1
0
 def __set_endpoints(self):
     opt = SpatialElementBoundaryOptions()
     segments = self.entity.GetBoundarySegments(opt)
     if len(segments):
         self.lines = [segment.GetCurve() for segment in segments[0]]
         self.all_points = []
         for line in self.lines:
             self.all_points.append(line.GetEndPoint(0))
             self.all_points.append(line.GetEndPoint(1))
         self.set_endpoints(self.all_points)
Esempio n. 2
0
    def __init__(self, room, line_style):
        self.line_style = line_style
        self.room = room
        self.area = room.get_Parameter(BuiltInParameter.ROOM_AREA).AsDouble()
        self.room_boundaries = self.room.GetBoundarySegments(SpatialElementBoundaryOptions())
        if not self.area:
            return

        #>>>>>>>>>> CREATE REGION
        dl_curve_array = self.create_outlines()
Esempio n. 3
0
def get_full_square_wall_from_room(room, param_name):
    report = 1
    room_height = room.get_Parameter(BuiltInParameter.ROOM_HEIGHT).AsDouble()
    room_segments = room.GetBoundarySegments(SpatialElementBoundaryOptions())
    perimenter = get_segments_length(room_segments)[1]
    full_wall_square = room_height * perimenter

    elements_in_room = get_segments_length(room_segments)[0]
    inserts = get_inserts_in_room(elements_in_room, room)
    inserts_square = 0
    for ins in inserts:
        inserts_square += get_square(ins)
        if get_square(ins) == 0:
            report = 0
    total_square = full_wall_square - inserts_square
    value = total_square * report
    set_value_by_param_name(room, param_name, value)  # noqa
    return value
Esempio n. 4
0
    def __init__(self, room, floor_type, active_view_level):
        """Class for creating a floor from given room.
        :param room:                Revit Room object.
        :param floor_type:          selected FloorType.
        :param active_view_level:   Level of a currently open view."""

        self.floor_type = floor_type
        self.active_view_level = active_view_level

        self.room = room
        self.area = room.get_Parameter(BuiltInParameter.ROOM_AREA).AsDouble()

        if self.area:
            self.name = room.get_Parameter(
                BuiltInParameter.ROOM_NAME).AsString()
            self.room_boundaries = self.room.GetBoundarySegments(
                SpatialElementBoundaryOptions())

            #>>>>>>>>>> CREATE Floor
            new_floor = self.create_Floors()
    normal = XYZ.BasisZ
    doc.Create.NewFloor( floor_curves, floorType, level, False, normal )



elements = get_selected_elements()
floor_types = get_floor_types()

chosen_type_name = 'Floor 1'
# If can't find matchign floor type name will use the first one found.
type_id = floor_types.get(chosen_type_name, floor_types.values()[0])

#  This is not needed but helps package needed elements to make floor
NewFloor = namedtuple('NewFloor', ['type_id', 'boundary', 'level_id'])
new_floors = []
room_boundary_options = SpatialElementBoundaryOptions()

for element in elements:
    if isinstance(element, Room):
        room = element
        room_level_id = room.Level.Id
        # List of Boundary Segment comes in an array by itself.
        room_boundary = room.GetBoundarySegments(room_boundary_options)[0]
        new_floor = NewFloor(type_id=type_id, boundary=room_boundary,
                             level_id=room_level_id)
        new_floors.append(new_floor)

if not new_floors:
    TaskDialog.Show('MakeFloors', 'You need to select at least one room.')
    __window__.Close()
    sys.exit(0)
Esempio n. 6
0
def convertRoomsToHBZones(rooms, boundaryLocation=1):
    """Convert rooms to honeybee zones.

    This script will only work from inside Dynamo nodes. for a similar script
    forRrevit check this link for more details:
    https://github.com/jeremytammik/SpatialElementGeometryCalculator/
        blob/master/SpatialElementGeometryCalculator/Command.cs
    """
    rooms = tuple(_getInternalElements(rooms))
    if not rooms:
        return []

    # create a spatial element calculator to calculate room data
    doc = rooms[0].Document
    options = SpatialElementBoundaryOptions()
    options.SpatialElementBoundaryLocation = getBoundaryLocation(
        boundaryLocation)
    calculator = SpatialElementGeometryCalculator(doc, options)

    opt = Options()
    _ids = []
    _zones = range(len(rooms))
    _surfaces = {}  # collect hbSurfaces so I can set adjucent surfaces
    for zoneCount, room in enumerate(rooms):
        # initiate zone based on room id
        _zone = HBZone(room.Id)

        # assert False, room.Id
        elementsData = calculator.CalculateSpatialElementGeometry(room)

        _roomGeo = elementsData.GetGeometry()
        # This can be the same as finish wall or in the center of the wall
        roomDSFaces = tuple(face.ToProtoType()[0] for face in _roomGeo.Faces)

        assert _roomGeo.Faces.Size == len(roomDSFaces), \
            "Number of rooms elements ({}) doesn't match number of faces ({}).\n" \
            "Make sure the Room is bounded.".format(_roomGeo.Faces.Size,
                                                    len(roomDSFaces))

        for count, face in enumerate(_roomGeo.Faces):
            # base face is useful to project the openings to room boundary
            _baseFace = roomDSFaces[count]

            # Revit is strange! if two roofs have a shared wall then it will be
            # duplicated! By checking the values inside the _collector
            _collector = []

            _boundaryFaces = elementsData.GetBoundaryFaceInfo(face)

            if len(_boundaryFaces) == 0:
                # initiate honeybee surface
                _ver = tuple(v.PointGeometry for v in _baseFace.Vertices)

                _hbSurface = HBSurface("%s:%s" % (_zone.name, createUUID()),
                                       _ver)

                _zone.addSurface(_hbSurface)
                continue

            for boundaryFace in _boundaryFaces:
                # boundaryFace is from type SpatialElementBoundarySubface
                # get the element (Wall, Roof, etc)
                boundaryElement = doc.GetElement(
                    boundaryFace.SpatialBoundaryElement.HostElementId)

                # initiate honeybee surface
                _ver = tuple(v.PointGeometry for v in _baseFace.Vertices)

                if _ver in _collector:
                    continue

                _hbSurface = HBSurface(
                    "%s:%s" % (_zone.name, boundaryElement.Id), _ver)

                _collector.append(_ver)

                if boundaryElement.Id not in _surfaces:
                    _surfaces[boundaryElement.Id] = _hbSurface
                else:
                    # TODO: set adjacent surface
                    pass

                # Take care of curtain wall systems
                # I'm not sure how this will work with custom Curtain Wall
                if getParameter(boundaryElement, 'Family') == 'Curtain Wall':
                    _elementIds, _coordinates = \
                        extractPanelsVertices(boundaryElement, _baseFace, opt)

                    for count, coordinate in enumerate(_coordinates):
                        if not coordinate:
                            print "{} has an opening with less than " \
                                "two coordinates. It has been removed!" \
                                .format(childElements[count].Id)
                            continue

                        # create honeybee surface - use element id as the name
                        _hbfenSurface = HBFenSurface(_elementIds[count],
                                                     coordinate)

                        # add fenestration surface to base honeybee surface
                        _hbSurface.addFenestrationSurface(_hbfenSurface)
                else:
                    # check if there is any child elements
                    childElements = getChildElemenets(boundaryElement)

                    if childElements:

                        _coordinates = exctractGlazingVertices(
                            boundaryElement, _baseFace, opt)

                        for count, coordinate in enumerate(_coordinates):

                            if not coordinate:
                                print "{} has an opening with less than " \
                                    "two coordinates. It has been removed!" \
                                    .format(childElements[count].Id)
                                continue

                            # create honeybee surface - use element id as the name
                            _hbfenSurface = HBFenSurface(
                                childElements[count].Id, coordinate)
                            # add fenestration surface to base honeybee surface
                            _hbSurface.addFenestrationSurface(_hbfenSurface)

                # add hbsurface to honeybee zone
                _zone.addSurface(_hbSurface)
                boundaryElement.Dispose()

        _zones[zoneCount] = _zone

        # clean up!
        elementsData.Dispose()

    calculator.Dispose()
    return _zones
    # append room number to list
    roomNumbers.append(n)

# room numbers will be used as id when creating svg polygon

# -----------------------
# get room boundaries, scale for pixels & chop into groups
# -----------------------

# adapted with kudos to forum post by jean
# https://forum.dynamobim.com/t/bounding-box-issue/16159/9

# create an empty list to store room boundaries
roomBounds = []
# set alias for default options
opts = SpatialElementBoundaryOptions()
# string to be evaluated in loop for boundary location
bLocation = 'SpatialElementBoundaryLocation.' + boundaryLocation
# for each room in selected level
for room in allRoomsOnLevel:
    # set boundary location
    opts.SpatialElementBoundaryLocation = eval(bLocation)
    # create an empty list to store curves of room boundary
    crvs = []
    # room outer boundary is always at index [0]
    for seg in room.GetBoundarySegments(opts)[0]:
        # get the curve of the segment
        # seg.GetCurve() works for revit 2017+ for previous versions use
        # crv = seg.Curve
        # refer to piersons forum post
        # https://forum.dynamobim.com/t/lunchbox-2016-11-10-lunchbox-room-element-collector-issue/7374/4
Esempio n. 8
0
        value = param1 * param2
        return value


doc = DocumentManager.Instance.CurrentDBDocument

door_cat = ElementCategoryFilter(BuiltInCategory.OST_Doors)
win_cat = ElementCategoryFilter(BuiltInCategory.OST_Windows)

room_col = FilteredElementCollector(doc).OfCategory(
    BuiltInCategory.OST_Rooms).ToElements()

elements = []
square_value = []

opt = SpatialElementBoundaryOptions()
TransactionManager.Instance.EnsureInTransaction(doc)

for room in room_col:
    room_height_param = room.get_Parameter(BuiltInParameter.ROOM_HEIGHT)
    segments_list = room.GetBoundarySegments(opt)
    all_length = 0
    elem_in_room = []
    for segments in segments_list:
        for segment in segments:
            element_segement = doc.GetElement(segment.ElementId)
            hasCurtainGrid = hasattr(element_segement, 'CurtainGrid')
            if hasCurtainGrid:
                if element_segement.CurtainGrid is None:
                    all_length += segment.GetCurve().Length
                else:
Esempio n. 9
0
import System.Threading
import System.Threading.Tasks
from Autodesk.Revit.DB import Document,FilteredElementCollector, PerformanceAdviser, FamilySymbol,Transaction,\
    FailureHandlingOptions, CurveElement, BuiltInCategory, ElementCategoryFilter, ReferenceIntersector, \
    FindReferenceTarget, SpatialElementBoundaryOptions
from Autodesk.Revit.UI import TaskDialog
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
from pyrevit.framework import List
from pyrevit import revit, DB
import os
from collections import defaultdict
from pyrevit import script
from pyrevit import forms

__doc__ = 'Select room bounding elements of selected room'

selection = Selection.get_selected_elements(doc)

elements = []
# convenience variable for first element in selection
for i in selection:
    loops = i.GetBoundarySegments(SpatialElementBoundaryOptions())

    for l in loops:
        for s in l:
            element = s.ElementId
            print(element)
            elements.append(doc.GetElement(element))
revit.get_selection().set_to(elements)
Esempio n. 10
0
            level2 = None
            for level in levels:
                elev2 = round(level.Elevation)
                if elev == elev2:
                    level2 = level

            if level2 is not None:
                if round(level2.Elevation) == round(
                        doc.ActiveView.GenLevel.Elevation):
                    name = room.get_Parameter(
                        BuiltInParameter.ROOM_NAME).AsString()
                    number = room.get_Parameter(
                        BuiltInParameter.ROOM_NUMBER).AsString()
                    height = room.get_Parameter(
                        BuiltInParameter.ROOM_UPPER_OFFSET).AsDouble()
                    sOptions = SpatialElementBoundaryOptions()
                    sOptions.StoreFreeBoundaryFaces = True
                    line = room.GetBoundarySegments(sOptions)
                    for llist in line:
                        for l in llist:
                            ll = l.GetCurve()
                            cArray.Append(ll)
                try:
                    # doc.Create.NewSpaceBoundaryLines(doc.ActiveView.SketchPlane, cArray, doc.ActiveView)
                    space = doc.Create.NewSpace(level2, uv)
                    space.get_Parameter(BuiltInParameter.ROOM_NAME).Set(name)
                    space.get_Parameter(
                        BuiltInParameter.ROOM_NUMBER).Set(number)
                    space.get_Parameter(
                        BuiltInParameter.ROOM_UPPER_OFFSET).Set(height)
Esempio n. 11
0
def analyze_rooms(rooms, boundary_location=1):
    """Convert revit rooms to dynosaur rooms.

    This script will only work from inside Dynamo nodes. for a similar script
    forRrevit check this link for more details:
    https://github.com/jeremytammik/SpatialElementGeometryCalculator/
        blob/master/SpatialElementGeometryCalculator/Command.cs
    """
    # unwrap room elements
    # this is not the right way of logging in python and probably any other language
    log = []
    rooms = tuple(_get_internalelement_collector(rooms))
    if not rooms:
        return []

    # create a spatial element calculator to calculate room data
    doc = rooms[0].Document
    options = SpatialElementBoundaryOptions()
    options.SpatialElementBoundaryLocation = get_boundary_location(boundary_location)
    calculator = SpatialElementGeometryCalculator(doc, options)

    opt = Options()
    element_collector = []
    room_collector = range(len(rooms))
    # surface_collector = {}  # collect hbSurfaces so I can set adjucent surfaces
    for room_count, revit_room in enumerate(rooms):
        # initiate zone based on room id
        element_collector.append([])
        new_room = room.create_room(revit_room.Id)

        # calculate spatial data for revit room
        revit_room_spatial_data = calculator.CalculateSpatialElementGeometry(revit_room)
        # get the geometry of the room
        revit_room_geometry = revit_room_spatial_data.GetGeometry()
        # Cast revit room faces to dynamo geometry using ToProtoType method
        room_faces_dyn = \
            tuple(face.ToProtoType()[0] for face in revit_room_geometry.Faces)

        assert revit_room_geometry.Faces.Size == len(room_faces_dyn), \
            "Number of rooms elements ({}) doesn't match number of faces ({}).\n" \
            "Make sure the Room is bounded.".format(revit_room_geometry.Faces.Size,
                                                    len(room_faces_dyn))

        for count, face in enumerate(revit_room_geometry.Faces):
            # base face is useful to project the openings to room boundary
            base_face_dyn = room_faces_dyn[count]

            # Revit is strange! if two roofs have a shared wall then it will be
            # duplicated! By checking the values inside the _collector I try to avoid
            # that.
            _collector = []

            boundary_faces = revit_room_spatial_data.GetBoundaryFaceInfo(face)

            if len(boundary_faces) == 0:
                # There is no boundary face! I don't know what does this exactly mean
                # in the Revit world but now that there is no boundary face we can just
                # use the dynamo face and create the surface!
                face_vertices = tuple(v.PointGeometry for v in base_face_dyn.Vertices)

                new_surface = surface.create_surface(
                    "%s_%s" % (new_room['name'], create_uuid()),
                    new_room['name'],
                    face_vertices
                )

                room.add_surface_to_room(new_room, new_surface)
                continue

            for boundary_face in boundary_faces:
                # boundary_face is a SpatialElementBoundarySubface
                # we need ti get the element (Wall, Roof, etc) first
                boundary_element = doc.GetElement(
                    boundary_face.SpatialBoundaryElement.HostElementId
                )

                # initiate honeybee surface
                face_vertices = tuple(v.PointGeometry for v in base_face_dyn.Vertices)

                # TODO(mostapha) This should be done once when all the surfaces are
                # created.
                if face_vertices in _collector:
                    continue

                new_surface = surface.create_surface(
                    "%s_%s" % (new_room['name'], boundary_element.Id),
                    new_room['name'],
                    face_vertices
                )

                # TODO(mostapha) This should be done once when all the surfaces are
                # created.
                _collector.append(face_vertices)

                # collect element id for each face.
                # this can be part of the object itself. I need to think about it before
                # adding it to the object. Trying to keep it as light as possible
                element_collector[room_count].append(doc.GetElement(
                    boundary_face.SpatialBoundaryElement.HostElementId
                ))

                # I'm not sure how this works in Revit but I assume there is an easy
                # way to find the adjacent surface for an element. Let's hope this time
                # revit doesn't let me down!
                # if boundary_element.Id not in surface_collector:
                #     surface_collector[boundary_element.Id] = new_surface
                # else:
                #     # TODO(mostapha): set adjacent surface
                #     pass
                # ----------------------- child surfaces --------------------------- #
                # time to find child surfaces (e.g. windows!)
                # this is the reason dynosaur exists in the first place

                # Take care of curtain wall systems
                # This will most likely fail for custom curtain walls
                if get_parameter(boundary_element, 'Family') == 'Curtain Wall':
                    # get cooredinates and element ids for this curtain wall.
                    _elementIds, _coordinates = extract_panels_vertices(
                        boundary_element, base_face_dyn, opt)

                    for count, coordinate in enumerate(_coordinates):
                        if not coordinate:
                            log.append("{} has an opening with less than "
                                       "two coordinates. It has been removed!"
                                       .format(_elementIds[count]))
                            continue

                        # create honeybee surface - use element id as the name
                        new_fen_surface = surface.create_fen_surface(
                            _elementIds[count],
                            new_surface['name'],
                            coordinate)

                        # get element and add it to the collector
                        elm = boundary_element.Document.GetElement(_elementIds[count])
                        element_collector[room_count].append(elm)

                        # add fenestration surface to base surface
                        surface.add_fenestration_to_surface(new_surface, new_fen_surface)
                else:
                    # collect child elements for non-curtain wall systems
                    childelement_collector = get_child_elemenets(boundary_element)

                    if childelement_collector:

                        _coordinates = exctract_glazing_vertices(
                            boundary_element,
                            base_face_dyn,
                            opt
                        )

                        for count, coordinate in enumerate(_coordinates):

                            if not coordinate:
                                log.append("{} in {} has an opening with less than "
                                           "two coordinates. It has been removed!"
                                           .format(
                                               childelement_collector[count].Id,
                                               new_room['name']
                                           ))

                            # create honeybee surface - use element id as the name
                            new_fen_surface = surface.create_fen_surface(
                                childelement_collector[count].Id,
                                new_room['name'],
                                coordinate
                            )

                            # add fenestration surface to base honeybee surface
                            element_collector[room_count].append(
                                childelement_collector[count]
                            )
                            # add fenestration surface to base surface
                            surface.add_fenestration_to_surface(new_surface,
                                                                new_fen_surface)

                # add surface to dynosaur room
                room.add_surface_to_room(new_room, new_surface)
                # clean up!
                boundary_element.Dispose()

        room_collector[room_count] = new_room

        # clean up!
        revit_room_spatial_data.Dispose()

    calculator.Dispose()
    return room_collector, element_collector, log