Esempio n. 1
0
def FindRegionEdges(filledRegion):
    view = filledRegion.Document.GetElement(filledRegion.OwnerViewId)
    options = Options()
    options.View = view
    options.ComputeReferences = True
    edges = []
    for o in filledRegion.get_Geometry(options):
        edges.append(o.Edges)
    return edges
Esempio n. 2
0
def get_geometry_instances(elem):
    geo_instance = []
    geo = elem.get_Geometry(Options())
    for g in geo:
        if g.GetType().Name == 'GeometryInstance':
            geo_instance.append(g)
    return geo_instance
Esempio n. 3
0
 def get_faces_from_solid(cls, elem):
     """Возвращает все поверхсти элемента."""
     option = Options()
     faces = []
     geometry = elem.get_Geometry(option)
     for geometry_intance in geometry:
         if isinstance(geometry_intance, Solid):
             faces += list(geometry_intance.Faces)
     return faces
Esempio n. 4
0
def RemovePaintFromElement(el):
    solids = UnwrapElement(el).get_Geometry(Options())  # noqa
    if solids:
        for solid in solids:
            if hasattr(solid, "Faces"):
                for face in solid.Faces:
                    elID = ElementId(el.Id)
                    doc.RemovePaint(elID, face)
                    if face.HasRegions:
                        regions = face.GetRegions()
                        for regFace in regions:
                            doc.RemovePaint(elID, regFace)
Esempio n. 5
0
def get_square_from_solid(element):
    square = 0
    volume = 0
    solids = element.get_Geometry(Options())
    if solids:
        for solid in solids:
            volume += solid.Volume
            if hasattr(solid, 'Faces'):
                for face in solid.Faces:
                    mat_id = face.MaterialElementId
                    if mat_id.IntegerValue == -1:
                        square += face.Area
        return square, volume
Esempio n. 6
0
def set_value_at_point(collector, param_name):
    rooms = []
    for r in collector:
        solids = r.get_Geometry(Options())
        for solid in solids:
            point = solid.ComputeCentroid()
            room = doc.GetRoomAtPoint(point)
            if room:
                rooms.append(room)
                room_number = room.get_Parameter(
                    BuiltInParameter.ROOM_NUMBER).AsString()
                set_value_to_parameter(r, param_name, room_number)
    return rooms
Esempio n. 7
0
def RemovePaintFromElement(el):
    solids = UnwrapElement(el).get_Geometry(Options())  # noqa
    if solids:
        painted_face = []
        for solid in solids:
            if hasattr(solid, "Faces"):
                for face in solid.Faces:
                    elID = ElementId(el.Id)
                    if doc.IsPainted(elID, face):
                        painted_face.append(face)
                    if face.HasRegions:
                        for regFace in face.GetRegions():
                            if doc.IsPainted(elID, regFace):
                                painted_face.append(regFace)
        return painted_face
Esempio n. 8
0
def get_square_from_part(part_list, document):
    if part_list:
        square = 0
        for item_id in part_list:
            stair_run = document.GetElement(item_id)
            geometry = stair_run.get_Geometry(Options())
            if geometry:
                for geo in geometry:
                    if geo.GetType().Name == 'Solid':
                        for face in geo.Faces:
                            square += get_square_from_face(face)
                    if geo.GetType(
                    ).Name == 'GeometryInstance' and square == 0:
                        instance_geo = geo.GetInstanceGeometry()
                        for solid in instance_geo:
                            for face in solid.Faces:
                                square += get_square_from_face(face)
            return square
Esempio n. 9
0
class RB_Space:
    all_space = []
    view_option = Options()
    all_spaces_numbers = None
    all_spaces_numbers_set = None

    def __init__(self, space):
        self._geometry = None
        self.all_space.append(self)
        self.space = space
        self.radiators = self.all_spaces_numbers.count(self.space.Number)
        self.all_spaces_numbers_set.discard(self.space.Number)

    @property
    def geometry(self):
        if self._geometry is None:
            self._geometry = list(
                self.space.Geometry[self.view_option].GetEnumerator())
        return self._geometry
Esempio n. 10
0
    # print("ft cache: ", coord_tuple)
    return str(coord_tuple)


stopwatch = Stopwatch()
stopwatch.Start()

ignored_durchbruch_ids = [
    # "A001G01",
]

# general revitapi options and constants
ft_mm = 304.8
up = XYZ(0, 0, 1)
non_struct = Structure.StructuralType.NonStructural
geo_opt = Options()
rvt_link_opt = RevitLinkOptions(False)

selection = [doc.GetElement(elId) for elId in uidoc.Selection.GetElementIds()]

# create level overviews
lvl_elevations, next_lvl_elevations = get_lvl_dicts()
raw_lvl_elevations, raw_next_lvl_elevations = get_lvl_dicts(building_story=0)

# retrieve model elements
local_gen = Fec(doc).OfCategory(
    Bic.OST_GenericModel).WhereElementIsNotElementType().ToElements()
local_walls = Fec(doc).OfCategory(
    Bic.OST_Walls).WhereElementIsNotElementType().ToElements()
fam_symbols = Fec(doc).OfClass(FamilySymbol).ToElements()
 def getCoordinates(pbp, document):
     option = Options()
     option.ComputeReferences = True
     #PBP location as per revit center
     return pbp.get_BoundingBox(document.ActiveView).Min
Esempio n. 12
0
import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import FilteredElementCollector, ElementIntersectsSolidFilter, Options, FamilyInstance, \
    ElementIntersectsElementFilter, Ceiling
from Autodesk.Revit.DB.Mechanical import Duct

el = UnwrapElement(IN[0])

doc = el.Document
opt = Options()
solid = el.get_Geometry(opt)

el_filter = ElementIntersectsElementFilter(el)
# solid_filter = ElementIntersectsSolidFilter(solid)

cats = []
cats.append(Duct)
cats.append(FamilyInstance)
cats.append(Ceiling)

col = []
for c in cats:
    intersectingInstances = FilteredElementCollector(doc).OfClass(c). \
        WherePasses(el_filter)
    el_list = list(intersectingInstances)
    if el_list:
        col.append(el_list)

OUT = col
Esempio n. 13
0
class Captures(object):
    opt_1 = Options()
    opt_1.DetailLevel = ViewDetailLevel.Medium
    opt_1.IncludeNonVisibleObjects = True
    opt_2 = Options()
    opt_2.DetailLevel = ViewDetailLevel.Medium
    rebar_found_host = List[ElementId]()

    def __init__(self, doc, parent=None, transforms=None, uidoc=None):
        """
        Начало параметризации.
        Параметрами передаются 
        doc
        1. Получить арматуру в текущем файле.
        2. Распределить арматуру по типам:
            - Системная
            - IFC
        3. Получить все хосты формообразующие текущего докоумента
        4. Найти родителей арматуры
        . Найти либ документы
        . По разнному обработать арматуру на поиск хоста
        {
            doc: transform
        }
        """

        self.transforms = transforms
        self.parent = parent
        self.doc = doc
        self.uidoc = uidoc
        echo("Начинаем работать с {}".format(self))
        self.rebar_system, self.rebar_ifc = self.find_all_rebar()
        echo("Получили арматурные стержни и разделили на IFC {} штук и системную {} штук".format(len(self.rebar_ifc), len(self.rebar_system)))
        self.hosts = self.get_parts_and_floor()
        echo("Получили формы части и плиты {}".format(len(self.hosts)))
        self.find_rebar_capture_system(self.rebar_system)
        self.find_rebar_capture_ifc(self.rebar_ifc)
        echo("Отработал поиск хостов")
        # self.lib_documents = self.get_instance_document()
        # self.parametrizetion_lib()

    def __repr__(self):
        if self.doc:
            return self.doc.Title
        return str(self.doc)

    def get_instance_document(self):
        """
        Находим все экзмепляры связей.

        Запихиваем в documents с их трансформатцией
        Сколько трансформаций. Столько и либов.
        """
        documents = {}
        els = FilteredElementCollector(self.doc).\
            OfClass(RevitLinkInstance).ToElements()
        for i in els:
            l_doc = i.GetLinkDocument()
            trans = i.GetTotalTransform()
            if l_doc not in documents.keys():
                documents[l_doc] = set()
            documents[l_doc].add(trans)
        return documents

    def parametrizetion_lib(self):
        for key, i in self.lib_documents.items():
            if key:
                self.__class__(key, parent=self, transforms=i)

    def find_all_rebar(self):
        """
        Поиск арматуры.

        Ищем всю арматуру и разделяем ее
        на IFC и
        Системную
        """
        system_rebar = set()
        ifc_rebar = set()
        rebars = FilteredElementCollector(self.doc).\
            OfCategory(BuiltInCategory.OST_Rebar).\
            WhereElementIsNotElementType().ToElements()
        for i in rebars:
            pog_met = i.LookupParameter("Рзм.ПогМетрыВкл") if i.LookupParameter("Рзм.ПогМетрыВкл") else self.doc.GetElement(i.GetTypeId()).LookupParameter("Рзм.ПогМетрыВкл")
            if pog_met and not pog_met.AsInteger():
                if isinstance(i, FamilyInstance):
                    ifc_rebar.add(i)
                else:
                    system_rebar.add(i)
        return system_rebar, ifc_rebar

    def get_parts_and_floor(self):
        """
        Получаем все возможные формообразующие в текущем документе.
        """
        els = FilteredElementCollector(self.doc).\
            WhereElementIsNotElementType().\
            OfCategory(BuiltInCategory.OST_Floors).ToElementIds()
        sel = List[ElementId]()
        res = []
        for i in els:
            parts = PartUtils.GetAssociatedParts(self.doc, i, True, True)
            fl = self.doc.GetElement(i)
            fl_par = fl.LookupParameter("Номер захватки")
            if parts.Count:
                fl_par.Set("Не учитывать")
                fl_gr = fl.LookupParameter("Орг.ГруппаВедомостьРасходаБетона").AsString()
                for j in parts:
                    pt = self.doc.GetElement(j)
                    if pt.LookupParameter("Номер захватки").AsString():
                        sel.Add(j)
                        res.append(pt)
                    pt.LookupParameter("Орг.ГруппаВедомостьРасходаБетона").Set(fl_gr)
            else:
                if fl_par.AsString() == "Не учитывать":
                    fl_par.Set("")
                if fl_par.AsString():
                    res.append(fl)
                    sel.Add(i)
        self.uidoc.Selection.SetElementIds(sel)
        return sorted(res, key=lambda x: x.LookupParameter("Номер захватки").AsString())

    def select(self, elements):
        elements = List[ElementId]([i.Id for i in elements])
        __revit__.ActiveUIDocument.Selection.SetElementIds(elements)

    def find_rebar_capture_system(self, elements):
        """
        Находим захватки системной арматуры.
        """
        # hosts = List[ElementId]([i.Id for i in self.hosts])
        elements = List[ElementId]([i.Id for i in elements])
        for host in self.hosts:
            elements_fec = FilteredElementCollector(self.doc, elements)
            bb = host.Geometry[self.opt_1].GetBoundingBox()
            filtered = BoundingBoxIntersectsFilter(Outline(bb.Min, bb.Max))
            rebars = elements_fec.WherePasses(filtered).ToElements()
            for rebar in rebars:
                host_is_found = False
                for host_solid in self.get_solids(host, opt=self.opt_2):
                    if host_is_found:
                        break
                    if isinstance(host_solid, Solid):
                        cur_line = next(iter(rebar.Geometry[self.opt_1]))
                        if host_solid.\
                                IntersectWithCurve(cur_line, None).\
                                SegmentCount:
                            rebar.LookupParameter("Номер захватки").\
                                Set(host.LookupParameter("Номер захватки").AsString())
                            host_is_found = True

    # def find_rebar_host_system(self, elements, parent=None, transforms=None):
    #     """
    #     Находим хосты системной арматуры.
    #     """

    #     rebar_without_hosts = set()
    #     for el in elements:
    #         host_is_found = False
    #         cur_line = next(iter(el.Geometry[self.opt_1]))
    #         transform_host = {}
    #         for host in self.hosts:
    #             if host_is_found:
    #                 break
    #             for host_solid in self.get_solids(host, opt=self.opt_2):
    #                 if isinstance(host_solid, Solid):
    #                     if transforms is not None:
    #                         for transform in transforms:
    #                             trans_line = cur_line.CreateTransformed(transform)
    #                             if host_solid.IntersectWithCurve(trans_line, None).SegmentCount:
    #                                 # echo("У системной арматуры {} найдена захватка в родителе {}".format(el.Id, host.Id))
    #                                 transform_host[transform] = host.Id
    #                     else:
    #                         # echo("Ищем хост")
    #                         if host_solid.IntersectWithCurve(cur_line, None).SegmentCount:
    #                             # echo("У системной арматуры {} найден захватка {}".format(el.Id, host.Id))
    #                             el.LookupParameter("Номер захватки").Set(host.LookupParameter("Номер захватки").AsString())
    #                             host_is_found = True
    #         if not host_is_found:
    #             rebar_without_hosts.add(el)
    #             echo("Для системной арматуры {} не найдена захватка".format(el.Id))
    #     if self.parent and rebar_without_hosts:
    #         echo("Ищем захватку в родителе")
    #         self.parent.find_rebar_host_system(rebar_without_hosts, transforms=self.transforms)

    def find_rebar_capture_ifc(self, elements):
        elements = List[ElementId]([i.Id for i in elements])
        for host in self.hosts:
            elements_fec = FilteredElementCollector(self.doc, elements)
            bb = host.Geometry[self.opt_1].GetBoundingBox()
            filtered = BoundingBoxIntersectsFilter(Outline(bb.Min, bb.Max))
            rebars = elements_fec.WherePasses(filtered).ToElements()
            for rebar in rebars:
                all_reb_solids = self.get_solids(rebar)
                host_is_found = False
                for rebar_solid in all_reb_solids:
                    if host_is_found:
                        break
                    for host_solid in self.get_solids(host):
                        if host_is_found:
                            break
                        try:
                            union_solid = BooleanOperationsUtils.\
                                ExecuteBooleanOperation(
                                    rebar_solid,
                                    host_solid,
                                    BooleanOperationsType.Union)
                            sum_area = rebar_solid.SurfaceArea +\
                                host_solid.SurfaceArea -\
                                union_solid.SurfaceArea
                        except:
                            sum_area = 1
                        if sum_area > 0.0001:
                            host_is_found = True
                            rebar.LookupParameter("Номер захватки").\
                                Set(host.LookupParameter("Номер захватки").\
                                    AsString())

    def find_rebar_host_ifc(self, elements):

        for el in elements:
            all_reb_solids = self.get_solids(el)
            host_is_found = False
            if all_reb_solids:
                for first_solid in all_reb_solids:
                    if host_is_found:
                        break
                    for host in self.hosts:
                        if host_is_found:
                            break
                        sum_area = 0
                        for host_solid in self.get_solids(host):
                            if host_is_found:
                                break
                            union_solid = BooleanOperationsUtils.ExecuteBooleanOperation(first_solid, host_solid, BooleanOperationsType.Union)
                            sum_area += ((first_solid.SurfaceArea + host_solid.SurfaceArea) - union_solid.SurfaceArea)
                            if sum_area > 0.0001:
                                host_is_found = True
                                el.LookupParameter("Номер захватки").Set(host.LookupParameter("Номер захватки").AsString())
                    if not host_is_found:
                        pass
                        echo("Для IFC арматуры {} не найден host".format(el.Id))
            else:
                # pass
                echo("Не найдено геометрии для IFC {}".format(self))

    def get_solids(self, el, opt=None):
        opt = opt if opt is not None else self.opt_1
        res = []
        for geom in el.Geometry[opt]:
            if isinstance(geom, GeometryInstance):
                res += [i for i in geom.GetInstanceGeometry() if isinstance(i, Solid) and i.Volume > 0]
            elif isinstance(geom, Solid) and geom.Volume > 0:
                res.append(geom)
        return res
Esempio n. 14
0
class Precast_geometry(object):
    "Примесь для поиска солидов."
    option_coarse = Options()
    option_coarse.DetailLevel = ViewDetailLevel.Coarse
    option_medium = Options()
    option_medium.DetailLevel = ViewDetailLevel.Medium
    option_fine = Options()
    option_fine.DetailLevel = ViewDetailLevel.Fine
    _default_option = option_medium

    def __init__(self):
        self._solids = None
        self._union_solid = None
        super(Precast_geometry, self).__init__()

    def get_solids(self, solids, res, transform=None):
        "Записываем солиды и записываем в res рекурсивно."
        if solids:
            for i in solids:
                if isinstance(i, Solid):
                    res.append(Precast_solid(i, self.doc))
                if isinstance(i, GeometryInstance):
                    self.get_solids(i.GetInstanceGeometry(), res)

    @property
    def solids(self):
        "Все солиды элемента."
        if not hasattr(self, "_solids") or self._solids is None:
            self._solids = []
            solids = self.element.Geometry[self._default_option]
            self.get_solids(solids, self._solids)
        return self._solids

    @property
    def real_solids(self):
        "Все солиды элемента."
        if not hasattr(self, "_real_solids"):
            self._real_solids = []
            solids = self.element.Geometry[self.option_fine]
            self.get_solids(solids, self._real_solids)
        return self._real_solids

    @property
    def union_solid(self):
        "Объединение всех солидов."
        if not hasattr(self, "_union_solid") or self._union_solid is None:
            self._union_solid = None
            if self.solids:
                for i in self.solids:
                    if self._union_solid is None:
                        self._union_solid = i.element
                    else:
                        self._union_solid = BooleanOperationsUtils.ExecuteBooleanOperation(
                            self._union_solid, i.element,
                            BooleanOperationsType.Union)
        return self._union_solid

    def join_elements(self, elements_1, elements_2):
        "Присоединяет геометрию элементов"
        result = set()
        rebar_cat = Category.GetCategory(self.doc,
                                         BuiltInCategory.OST_Rebar).Name
        elements_1 = [
            i for i in elements_1 if i.element.Category.Name != rebar_cat
        ]
        elements_2 = [
            i for i in elements_2 if i.element.Category.Name != rebar_cat
        ]
        for element_1 in elements_1:
            for element_2 in elements_2:
                try:
                    res = BooleanOperationsUtils.ExecuteBooleanOperation(
                        element_2.union_solid, element_1.union_solid,
                        BooleanOperationsType.Difference)
                    if res.Volume < element_2.union_solid.Volume:
                        result.add(element_1)
                        try:
                            if not JoinGeometryUtils.AreElementsJoined(
                                    self.doc, element_2.element,
                                    element_1.element):
                                JoinGeometryUtils.JoinGeometry(
                                    self.doc, element_2.element,
                                    element_1.element)
                            if not JoinGeometryUtils.IsCuttingElementInJoin(
                                    self.doc, element_2.element,
                                    element_1.element):
                                JoinGeometryUtils.SwitchJoinOrder(
                                    self.doc, element_2.element,
                                    element_1.element)
                        except:
                            # echo("Ошибка в объединении {} с {}".format(element_1, element_2))
                            pass
                except InvalidOperationException:
                    result.add(element_1)
        return result

    @property
    def center_point(self):
        if not hasattr(self, "_center_point"):
            bb = self.element.Geometry[self._default_option].GetBoundingBox()
            delta = bb.Max - bb.Min
            delta = delta / 2
            self._center_point = bb.Min + delta
        return self._center_point

    @property
    def height(self):
        if not hasattr(self, "_height"):
            bb = self.element.Geometry[self._default_option].GetBoundingBox()
            delta = bb.Max - bb.Min
            self._height = delta.GetLength()
        return self._height

    @property
    def vect_abscis(self):
        "Ветор X."
        if not hasattr(self, "_vect_abscis"):
            self._vect_abscis = self.element.FacingOrientation
        return self._vect_abscis

    @property
    def vect_ordinat(self):
        "Ветор Y."
        if not hasattr(self, "_vect_ordinat"):
            self._vect_ordinat = self.element.HandOrientation
        return self._vect_ordinat

    @property
    def vect_applicat(self):
        "Ветор Z."
        if not hasattr(self, "_vect_applicat"):
            self._vect_applicat = XYZ(0, 0, 1)
        return self._vect_applicat

    @staticmethod
    def project_on_plane(point, origin=None, normal=None, plane=None):
        "Проекция точки на плоскость."
        if plane is None:
            plane = Plane.CreateByNormalAndOrigin(normal, origin)
        normal = plane.Normal * plane.Project(point)[1]
        return point - normal

    @classmethod
    def project_line_on_plane(cls, line, origin=None, normal=None, plane=None):
        p1 = line.GetEndPoint(0)
        p1 = cls.project_on_plane(p1,
                                  origin=origin,
                                  normal=normal,
                                  plane=plane)
        p2 = line.GetEndPoint(1)
        p2 = cls.project_on_plane(p2,
                                  origin=origin,
                                  normal=normal,
                                  plane=plane)
        # echo(p1.IsAlmostEqualTo(p2))
        if not p1.IsAlmostEqualTo(p2):
            try:
                return Line.CreateBound(p1, p2)
            except:
                pass
Esempio n. 15
0
    if old_Mat == doc.GetElement(face.MaterialElementId).Name:
        doc.Paint(ElementId(elem.Id), face, GetMaterail(new_Mat).Id)
        return "Готово!"
    else:
        return "Нет - {}".format(old_Mat)


sel = IN[1]  # noqa
old_Mat = IN[2]  # noqa
new_Mat = IN[3]  # noqa
all_mat = list()

TransactionManager.Instance.EnsureInTransaction(doc)
if isinstance(sel, list):
    for s in sel:
        solid_list = UnwrapElement(s).get_Geometry(Options())  # noqa
        for solid in solid_list:
            if hasattr(solid, "Faces"):
                for face in solid.Faces:
                    all_mat.append(doc.GetElement(face.MaterialElementId).Name)
                    AddPaint(old_Mat, new_Mat, face, s)
                    if face.HasRegions:
                        regions = face.GetRegions()
                        for regFace in regions:
                            all_mat.append(
                                doc.GetElement(regFace.MaterialElementId).Name)
                            AddPaint(old_Mat, new_Mat, regFace, s)
TransactionManager.Instance.TransactionTaskDone()

OUT = all_mat
Esempio n. 16
0
# -*- coding: utf-8 -*-
import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import FilteredElementCollector, Options, BuiltInCategory, XYZ, UnitUtils, DisplayUnitType
clr.AddReference("RevitNodes")
from Revit.GeometryConversion import RevitToProtoCurve
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

room_col = FilteredElementCollector(doc).OfCategory(
    BuiltInCategory.OST_Rooms).ToElements()
opt = Options()
opt.View = doc.ActiveView
opt.IncludeNonVisibleObjects = True
lines = []
for r in room_col:
    for g in r.get_Geometry(opt):
        if 'Line' in g.ToString():
            vector = (g.GetEndPoint(1) - g.GetEndPoint(0)).Normalize()
            degrees = UnitUtils.ConvertFromInternalUnits(vector.AngleTo(XYZ.BasisX), \
                DisplayUnitType.DUT_DECIMAL_DEGREES)
            if round(degrees) == 135:
                lines.append(RevitToProtoCurve.ToProtoType(g))

OUT = room_col, lines
Esempio n. 17
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
Esempio n. 18
0
    if param:
        if param.CanAssignFormula:
            val = UnitUtils.ConvertFromInternalUnits(value,
                                                     param.DisplayUnitType)
            f_manager.SetFormula(param, str(val))
            return '{} - {}'.format(param_name, val)
    else:
        return 'Not OK'


sel = UnwrapElement(IN[1])  # noqa
faces = []
square = 0
vol1 = 0

solids = sel.get_Geometry(Options())
if solids:
    for solid in solids:
        a = RevitToProtoSolid.ToProtoType(solid)
        vol1 += solid.Volume
        if hasattr(solid, 'Faces'):
            for face in solid.Faces:
                mat_id = face.MaterialElementId
                if mat_id.IntegerValue == -1:
                    square += face.Area

vol2 = GetVolumeFromBBox(sel)

TransactionManager.Instance.EnsureInTransaction(doc)

sq = SetParameterByName(square, 'ARH_sr')
Esempio n. 19
0
currentChoice = []
for i in get_selected_elements(doc):
    currentChoice.append(Reference(i))
result = 'Retry'
while result == 'Retry':
    pipFilter = PipeandFittingsSelectionFilter()
    choices = uidoc.Selection
    try:
        pipeRef = choices.PickObjects(ObjectType.Element, pipFilter,
                                      "Pick Pipe", currentChoice)
        currentChoice = pipeRef
        overallLength = 0.00
        for i in pipeRef:
            pipe = doc.GetElement(i.ElementId)
            # Pipe
            try:
                overallLength += pipe.Location.Curve.Length
            except:
                overallLength += pipe.GetOriginalGeometry(
                    Options()).GetBoundingBox().Max.DistanceTo(
                        pipe.GetOriginalGeometry(
                            Options()).GetBoundingBox().Min)
        result = str(
            TaskDialog.Show(
                "Measure",
                "Overall Length " + str(FeettoInch(overallLength)) + " feet",
                TaskDialogCommonButtons.Retry))
        uidoc.RefreshActiveView()
    except:
        result = "Cancel"
		except:
			results = 0
		return results
	def get_geometys(element):
		if element.get_Geometry(geo_options):
			for geometry_inst in element.get_Geometry(geo_options):
				if geometry_inst.GetType() == Autodesk.Revit.DB.GeometryInstance:
					for geometry in geometry_inst.SymbolGeometry:
						if geometry.GetType() == Autodesk.Revit.DB.Solid and Math.Round(geometry.Volume,3) != 0:
							return geometry
				else:
					if geometry_inst.GetType() == Autodesk.Revit.DB.Solid and Math.Round(geometry_inst.Volume,3) != 0:
						return geometry_inst
	#endregion
	#region параметры для объединения
	opt = Options()
	items1 = flatten_List(elements)
	catIdlist = [id_name[0] for id_name in cats_ids_names]
	ids = [i.Id for i in items1]
	i_list_ids = List[ElementId](ids)
	inter = []
	aliter = []
	alliter = []
	geo_options = Options()
	geo_options.ComputeReferences = False
	geo_options.IncludeNonVisibleObjects = False	
	# for i in items1:
	# 	ids.append(i.Id)
	#endregion
	#region main итерации, что-то можно заменить на генераторы списков для 
	TransactionManager.Instance.EnsureInTransaction(doc)
Esempio n. 21
0
class RB_Radiator:
    all_spaces = set()
    view_option = Options()
    all_radiators = []
    csv_data = None
    guids = None
    message = []

    def __init__(self, radiator):
        self.all_radiators.append(self)
        self.radiator = radiator
        self._space = None
        self.info = False
        self._random_line = None
        self._geom = None
        if self.space:
            self.space_number = None
            self.symbol = None
            self.length = None
            self.diameter = None
            self.producer = None
            self.description = None
            self.get_radiator_info()
        else:
            self.__class__.message.append(
                "Для конвектора с id {} не найдено пространство в таблице".
                format(self.radiator.Id))

    def get_radiator_info(self):
        for i in self.csv_data:
            if to_str(i[1]).lower().strip() == to_str(
                    self.space.space.Number).lower().strip():
                self.riser = i[0]
                self.space_number = i[1]
                self.symbol = to_str(i[2])
                try:
                    self.length = float(to_str(i[3]).replace(",",
                                                             ".")) / 0.3048
                    self.diameter = float(to_str(i[4]).replace(
                        ",", ".")) / 0.3048 / 1000
                except ValueError:
                    self.__class__.message.append(
                        "Для конвектора с id {} в пространстве {} не заданы длина или диаметр \n"
                        .format(self.radiator.Id, self.space_number))
                    self.length = float()
                    self.diameter = float()
                self.producer = to_str(i[5])
                self.description = to_str(i[6])
                try:
                    # echo(i[7])
                    self.clap = float(to_str(i[7]).replace(",", "."))
                except ValueError:
                    self.__class__.message.append(
                        "Для конвектора с id {} в пространстве {} не найдены настройки клапана \n"
                        .format(self.radiator.Id, self.space_number))
                    self.clap = float(0)
                self.info = True
                break
        # else:
        # self.__class__.message += "Для конвектора с id {} не найдены настройки в таблице \n".format(self.radiator.Id)
        if self.info:
            self.csv_data.remove(i)

    @property
    def space(self):
        if self._space is None:
            for space in self.all_spaces:
                if self._space:
                    break
                for space_geometry in space.geometry:
                    # echo("Ищем радиатор через линию")
                    if self._space:
                        break
                    l_c = 0
                    for i in self.random_line:
                        l_c += 1
                        res = space_geometry.IntersectWithCurve(i, None)
                        if res.SegmentCount:
                            self._space = space
                            # self.__class__.message.append("Найдено через линии {} \n".format(l_c))
                            break
                    # else:
                    #     echo("Все плохо")
                    # for cur_geometry in self.geometry:
                    #     sum_area = 0
                    #     if self._space:
                    #         break
                    #     union_solid = BooleanOperationsUtils.ExecuteBooleanOperation(cur_geometry, space_geometry, BooleanOperationsType.Union)
                    #     sum_area += ((cur_geometry.SurfaceArea + space_geometry.SurfaceArea) - union_solid.SurfaceArea)
                    #     if sum_area > 0.0001:
                    #         self._space = space
                    #         echo("Найдено через объем")
                    #         break
            # else:
            #     echo("Не найдено")
            if self._space:
                self._space.radiators -= 1
        return self._space

    @property
    def geometry(self):
        if self._geom is None:
            geom = list(
                list(self.radiator.Geometry[self.view_option].GetEnumerator())
                [0].GetInstanceGeometry().GetEnumerator())
            self._geom = filter(
                lambda el: isinstance(el, Solid) and el.Volume > 0, geom)
        return self._geom

    @property
    def random_line(self):
        if self._random_line is None:
            self._random_line = set()
            tt = 0
            for g in self.geometry:
                if tt > 10:
                    break
                for i_c in range(g.Edges.Size):
                    if tt > 10:
                        break
                    tt += 1
                    i = g.Edges.Item[i_c].AsCurve()
                    self._random_line.add(i)
        return self._random_line

    def set_parameter(self, parameter, value):
        p = self.radiator.get_Parameter(self.guids[parameter])
        if p:
            if not p.IsReadOnly:
                p.Set(value)
            else:
                self.__class__.message.append(
                    "Параметр {} заблокирован у элемента с id {}".format(
                        parameter, self.radiator.Id))
        else:
            self.__class__.message.append(
                "Параметр {} не найден у элемента с id {}".format(
                    parameter, self.radiator.Id))

    def set_parameters(self):
        if self.info:
            self.set_parameter("BS_Изготовитель", self.producer)
            self.set_parameter("BS_Наименование", self.description)
            self.set_parameter("MEP_Габаритная длина", self.length)
            self.set_parameter("BS_Маркировка", self.symbol)
            self.set_parameter("MEP_Стояк_номер", self.riser)
            self.set_parameter("OV_Номер пространства", self.space_number)
            self.set_parameter("MEP_Диаметр 1", self.diameter)
            self.set_parameter("OV_Настройка клапана", self.clap)
Esempio n. 22
0
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

import Revit

clr.ImportExtensions(Revit.GeometryConversion)

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

element = UnwrapElement(IN[1])  # noqa

opt = Options()
opt.ComputeReferences = True
opt.IncludeNonVisibleObjects = True
opt.View = doc.ActiveView

element_type = doc.GetElement(element.GetTypeId())
geo = element_type.get_Geometry(opt)
geometry_instance = [
    g for g in geo if g.GetType().Name == 'Solid' and g.Volume > 0
][0]

new_list = []
edges = geometry_instance.Edges

for e in edges:
    curve = e.AsCurve()
Esempio n. 23
0
class Line_by_room(IExternalEventHandler):
    """Линии в комнате по примыкающим стенам
    
    """
    __all_walls = {}
    __wall_levels = {}
    view_option = Options()
    intersect_option_inside = SolidCurveIntersectionOptions()
    intersect_option_outside = SolidCurveIntersectionOptions()
    intersect_option_outside.ResultType = SolidCurveIntersectionMode.CurveSegmentsOutside
    __graphic_syles = {}
    offset_length = to_feet(100)
    tollerance = to_feet(25)

    @property
    def graphic_syles(self):
        """Графические стили проекта
        
        """
        if not self.__graphic_syles:
            els = FilteredElementCollector(doc).OfClass(
                GraphicsStyle).ToElements()
            els = {el.Name: el for el in els}
            self.__graphic_syles = els
        return self.__graphic_syles

    @property
    def walls(self):
        """Получаем стены
        
        Сейчас берем все стены в проекте. Нужно бы придумать
        как брать стены которые рядышком.
      """
        if not self.__all_walls:
            walls = {}
            for i in FilteredElementCollector(
                    doc, curview.Id).OfClass(Wall).ToElements():
                walls.setdefault(i.Name, set())
                walls[i.Name].add(i)
            self.__all_walls = walls
        return self.__all_walls

    @property
    def wall_levels(self):
        """Уровни стен
        
        Считаем уровень стен через поиск центра тела
        После этого берем оттуда координату Z.
        
      """
        if not self.__wall_levels:
            for i in self.walls.keys():
                self.__wall_levels.setdefault(i, 0)
                e = next(iter(self.walls[i]))
                e = next(e.Geometry[
                    self.view_option].GetEnumerator()).ComputeCentroid().Z
                self.__wall_levels[i] = e
        return self.__wall_levels

    def __init__(self, rooms):
        """Начинаем работу
        
      """
        self.room_lines = []
        for room in rooms:
            if isinstance(room, Room):
                self.room_faces = self.get_element_faces(room)
                intersect_walls = self.get_intersect_wall(room)
                intersect_walls = {
                    i: k
                    for i, k in intersect_walls.items() if k
                }
                offset = 0
                for type_name, lines in intersect_walls.items():
                    offset += 1
                    lines = self.line_trimming(lines)
                    lines = self.create_rings(lines)
                    lines = self.add_offset(lines, offset)
                self.room_lines.append(intersect_walls)
        wall_names = set()
        for room in self.room_lines:
            for i in room.keys():
                wall_names.add(i)
        FORM.Start(len(wall_names) + 2)
        pp = 1
        self.form_val = {}
        for k in wall_names:
            cur = FORM.GetLines(pp).add_textbox(k, '')
            cur.Height = 24
            FORM.GetLines(pp).add_label("Смещение для {}".format(k))
            self.form_val.setdefault(k, cur)
            pp += 1

        but_create = FORM.GetLines(pp).add_button('Выполнить')
        but_cancel = FORM.GetLines(pp + 1).add_button('Отмена')

        exEvent = ExternalEvent.Create(self)

        but_cancel.AddFunction(FORM.Close)
        but_create.AddFunction(self.start)

        FORM.calculate_size()
        FORM.Create(exEvent)

    def start(self):
        FORM.exEvent.Raise()

    def Execute(self, app):
        try:
            self.form_val = {
                i: to_feet(int(self.form_val[i].GetValue()))
                for i in self.form_val.keys()
                if self.form_val[i].GetValue().isdigit()
            }
            with Transaction(doc, 'Рисуем линии') as t:
                t.Start()
                for room in self.room_lines:
                    # echo(room)
                    for type_name, lines in room.items():
                        if type_name in self.form_val.keys():
                            lines = self.add_offset(lines,
                                                    self.form_val[type_name])
                            # echo(self.get_graphic_styles(type_name))
                            self.print_line_by_face(
                                lines, self.get_graphic_styles(type_name),
                                type_name)
                        else:
                            message(
                                'Не задан отступ для типоразмера {} линия создана не будте'
                                .format(type_name))
                t.Commit()
        except:
            echo(sys.exc_info()[1])
        FORM.Close()

    def GetName(self):
        return 'Рисуем линии отделки'

    def line_trimming(self, lines):
        """Обрезка линий, которые выступают друг за друга
        
         формируем линии путем попытки пересечения их.
         Если линии пересекается с другими два раза
         два пересечения и есть точки этой линии
         
         если линия пересекается один раз. То ближняя точка заменяется 
         той, которая пересеклась
         
         если линия не пересекается - оставляем без изменений
        
        """
        new_lines = []
        for line_1 in lines:
            new_points = list()
            p1 = line_1.GetEndPoint(0)
            p2 = line_1.GetEndPoint(1)
            for line_2 in lines:
                intersect_result = StrongBox[IntersectionResultArray]()
                intersect_result_text = line_1.Intersect(
                    line_2, intersect_result)
                intersect_result = intersect_result.Value
                if intersect_result_text == SetComparisonResult.Overlap and intersect_result:
                    for i in intersect_result:
                        new_points.append(i.XYZPoint)
            if len(new_points) == 2:
                new_lines.append(Line.CreateBound(new_points[0],
                                                  new_points[1]))
            elif len(new_points) == 1:
                if p1.DistanceTo(new_points[0]) > p2.DistanceTo(new_points[0]):
                    new_lines.append(Line.CreateBound(p1, new_points[0]))
                else:
                    new_lines.append(Line.CreateBound(p2, new_points[0]))
            else:
                new_lines.append(line_1)
        return new_lines

    def add_offset(self, lines, offset):
        """Добавляем отступ линии
        
        """
        new_lines = []
        for line in lines:
            points = [line.GetEndPoint(0), line.GetEndPoint(1)]
            for point_pos in range(0, 2):
                point = points[point_pos]
                faces = set()
                for face in self.room_faces:
                    plane = face.GetSurface()
                    project_point = plane.Project(point)
                    # echo(project_point)
                    if project_point:
                        if project_point[1] < self.tollerance:
                            faces.add(face)
                normal_sum = XYZ(0, 0, 0)
                for face in faces:
                    normal_sum += face.ComputeNormal(UV())
                if abs(normal_sum.X) > 0.0001: dev_x = abs(normal_sum.X)
                else: dev_x = 1
                if abs(normal_sum.Y) > 0.0001: dev_y = abs(normal_sum.Y)
                else: dev_y = 1

                normal_sum = XYZ(normal_sum.X / dev_x, normal_sum.Y / dev_y, 0)
                point -= normal_sum * offset
                points[point_pos] = point
            new_lines.append(Line.CreateBound(points[0], points[1]))
        return new_lines

    def have_pair(self, point, lines):
        count = 0
        for line in lines:
            p1 = line.GetEndPoint(0)
            p1 = line.GetEndPoint(1)

    def get_element_faces(self, elem):
        geom = elem.Geometry[self.view_option]
        faces = []
        for i in geom:
            faces += list(i.Faces)
        return faces

    def get_graphic_styles(self, type_name):
        """Получаем графический стиль
        
        исходя из имени типоразмера стены
        
        """
        for i in self.graphic_syles.keys():
            if i in type_name and i != '0':
                return self.graphic_syles[i]

    def get_intersect_wall(self, room):
        """Получаем конаты и находим все стены которые с ними пересекаются
        
            потом получаем общие грани. get_common_edges возвращает линии
            
            если общие линии найдены - объединяем их рекурсивно.
            необходимо создавать изначально массив good_lines т.к. concate_lines
            ничего не возвращает.
            
            в good_lines запишутся все линии, которые нам необходимы
            
            добавляем в словарь walls все линии с ключем = типоразмеру стены.
            
        """
        walls = {}
        for wall_name, cur_walls in self.walls.items():
            wall_solids, room_solid = self.get_wall_intersect(room, cur_walls)
            lines = self.get_common_edges(room_solid, wall_solids)
            if lines:
                good_lines = []
                self.concate_lines(lines, good_lines=good_lines)
                lines = good_lines
            walls.setdefault(wall_name, lines)
        return walls

    def concate_lines(self, lines, good_lines=None, depth=0):
        """Объеденяет линии рекрсивно. 
        
        в good_line Необходимо передавать массив.
        В него как раз будет записываться уже объедененные линии
        Как вариант найти как вернуть good_lines. Пока что не заморачивался
        
        """
        if lines:
            line = lines.pop()

            new_line = None

            p1 = line.GetEndPoint(0)
            p2 = line.GetEndPoint(1)

            unbound_line = line.Clone()
            unbound_line.MakeUnbound()

            chean = []

            for cur_line in lines:
                intersection_result_type = unbound_line.Intersect(cur_line)
                if intersection_result_type == SetComparisonResult.Superset and self.common_end_points(
                        cur_line, line):
                    chean.append(cur_line)
            if chean:
                for i in chean:
                    lines.remove(i)
                    new_line = self.create_longest_lines(chean + [line])
                lines.append(new_line)
            else:
                good_lines.append(line)
            self.concate_lines(lines, good_lines=good_lines, depth=depth)

    def common_end_points(self, line_1, line_2):
        """Проверяем совпадает ли какой-нибудь конец у двух линий.
        
        """
        cp1 = line_1.GetEndPoint(0)
        cp2 = line_1.GetEndPoint(1)
        p1 = line_2.GetEndPoint(0)
        p2 = line_2.GetEndPoint(1)
        if cp1.DistanceTo(p1) < self.tollerance or cp1.DistanceTo(
                p2) < self.tollerance or cp2.DistanceTo(
                    p1) < self.tollerance or cp2.DistanceTo(
                        p2) < self.tollerance:
            return True
        else:
            cp1_to_line_2 = line_1.Project(p1)
            cp2_to_line_2 = line_1.Project(p2)
            p1_to_line_1 = line_2.Project(p1)
            p2_to_line_1 = line_2.Project(p2)
            if (
                (cp1_to_line_2 and cp1_to_line_2.Distance < self.tollerance)
                    and
                (cp2_to_line_2 and cp2_to_line_2.Distance < self.tollerance)
            ) or ((p1_to_line_1 and p1_to_line_1.Distance < self.tollerance)
                  and
                  (p2_to_line_1 and p2_to_line_1.Distance < self.tollerance)):
                return True

    def get_new_line(self, line_1, line_2):

        cp1 = line_1.GetEndPoint(0)
        cp2 = line_1.GetEndPoint(1)
        p1 = line_2.GetEndPoint(0)
        p2 = line_2.GetEndPoint(1)

        line_1_unbound = line_1.Clone()
        line_1_unbound.MakeUnbound()
        line_2_unbound = line_2.Clone()
        line_2_unbound.MakeUnbound()

        inter_res = StrongBox[IntersectionResultArray]()
        inter_res_text = line_1_unbound.Intersect(line_2_unbound, inter_res)
        if inter_res_text == SetComparisonResult.Overlap:
            inter_point = next(iter(inter_res)).XYZPoint
            if cp1.DistanceTo(
                    inter_point) < self.tollerance and cp2.DistanceTo(
                        inter_point) > self.tollerance:
                return Line.CreateBound(cp2, inter_point)
            elif cp2.DistanceTo(
                    inter_point) < self.tollerance and cp1.DistanceTo(
                        inter_point) > self.tollerance:
                return Line.CreateBound(cp1, inter_point)

    def create_longest_lines(self, lines):
        """Делаем из поданных линий максимально длинную.
        
        """
        all_points = self.all_lines_points(lines)
        p1, p2 = self.max_distance(all_points)
        return Line.CreateBound(p1, p2)

    def max_distance(self, points):
        """Из массива точек возвращаем две точки, которые находятся  на максимальном расстоянии."""
        max_distance = (0, 0, 0)
        args = []
        for i in points:
            for b in points:
                distance = i.DistanceTo(b)
                if distance > max_distance[2]:
                    max_distance = (i, b, distance)
        return (max_distance[0], max_distance[1])

    def print_line_by_face(self, lines, graphic_syles, name):
        """Рисует линии для которых есть типоразмер
        
        На вход подаем:
        lines - массив линий
        graphic_syles - элемент графического стиля
        name - имя типоразмера стены
        
        """
        if lines:
            line_set = set()
            test = CurveArray()
            if not graphic_syles:
                message("Не найден стиль для типоразмера {}".format(name))
                return
            for i in lines:
                # if i.ApproximateLength > self.tollerance:
                test.Append(i)
            res = doc.Create.NewDetailCurveArray(curview, test)
            for i in res:
                i.LineStyle = graphic_syles

    def get_common_edges(self, room_solid, solids):
        """Получает общие грани у солидов.
        
        Логика получения:
            находим геометрический центр каждого солида из solids
            проходим по всем поверхностям данного солида
            проецируем на Face этот центр масс
            проверяем лежит ли данная точка на какой-либо из поверхностей
                room_solid. Если лижит - добавляем поверхность в faces
            проходим по всем выбранным поверхностям, по ее граням
                если линия не вертикальна - добавляем ее в lines - set()
                
            приводим все линии к горизонтальной Z - которых соответствует origin
                текущего вида
            убираем все null из массива
            возвращаем массив линий.
        
        """
        lines = set()
        faces = set()
        for solid in solids:
            wall_cenroid = solid.ComputeCentroid()
            for face in solid.Faces:
                if isinstance(face, PlanarFace):
                    for general_face in room_solid.Faces:
                        centroid_project = face.Project(wall_cenroid)
                        if centroid_project:
                            center = centroid_project.XYZPoint
                            result = general_face.Project(center)
                            if result and result.Distance < 0.00001:
                                # echo(face)
                                faces.add(face)
        for face in faces:
            for edge_loop in face.EdgeLoops:
                for line in edge_loop:
                    line = line.AsCurve()
                    if self.is_not_vertical(line):
                        intersection_result_inside = room_solid.IntersectWithCurve(
                            line, self.intersect_option_inside)
                        intersection_result_outside = room_solid.IntersectWithCurve(
                            line, self.intersect_option_outside)
                        if intersection_result_inside.SegmentCount > 0:
                            max_distance_outside = 0
                            if intersection_result_outside.SegmentCount:
                                max_distance_outside = intersection_result_outside.GetCurveSegment(
                                    0).ApproximateLength
                                # if max_distance_outside > 1:
                                # self.print_line(intersection_result_inside.GetCurveSegment(0))
                            for i in range(
                                    0,
                                    intersection_result_inside.SegmentCount):
                                inter_line = intersection_result_inside.GetCurveSegment(
                                    i)
                                if inter_line.ApproximateLength > max_distance_outside + 0.0001:
                                    lines.add(inter_line)
        lines = [self.line_z_to_curview(line) for line in lines]
        lines = [i for i in lines if i is not None]
        return lines

    def print_line(self, line):
        """Рисуем линию."""
        doc.Create.NewDetailCurve(curview, self.line_z_to_curview(line))

    def line_z_to_curview(self, line):
        """Обнуляет координату Z у линии."""
        z = curview.Origin.Z
        p1 = line.GetEndPoint(0)
        p2 = line.GetEndPoint(1)
        p1 = XYZ(p1.X, p1.Y, z)
        p2 = XYZ(p2.X, p2.Y, z)
        return Line.CreateBound(p1, p2)

    def is_not_vertical(self, line):
        """Проверяет не является ли линия вертикальной."""
        vec = (line.GetEndPoint(0) - line.GetEndPoint(1)).Normalize()
        if not (vec.IsAlmostEqualTo(XYZ(0, 0, 1))
                or vec.IsAlmostEqualTo(XYZ(0, 0, -1))):
            return True

    def get_wall_intersect(self, room, walls):
        """Находим стены которые пересекаются с текущим помещением"""
        room_geometries = room.Geometry[self.view_option].GetEnumerator()
        walls_intersect = []
        for room_geometry in room_geometries:
            for i in walls:
                wall_geometries = i.Geometry[self.view_option].GetEnumerator()
                for wall_geometry in wall_geometries:
                    union_solid = BooleanOperationsUtils.ExecuteBooleanOperation(
                        room_geometry, wall_geometry,
                        BooleanOperationsType.Union)
                    sum_area = ((room_geometry.SurfaceArea +
                                 wall_geometry.SurfaceArea) -
                                union_solid.SurfaceArea)
                    if sum_area > 0.0001:
                        walls_intersect.append(wall_geometry)
        return (walls_intersect, room_geometry)

    def all_lines_points(self, lines):
        """Все точки линий
        
        """
        all_points = []
        for i in lines:
            all_points.append(i.GetEndPoint(0))
            all_points.append(i.GetEndPoint(1))
        return all_points

    def create_rings(self, lines):
        """Создание колец
        
        """
        # echo('является ли {} кольцом?'.format(line_name))
        # echo(self.is_ring(lines))
        new_lines = []
        for line_1 in lines:
            for line_2 in lines:
                inter_res = self.get_new_line(line_1, line_2)
                if inter_res:
                    line_1 = inter_res
            new_lines.append(line_1)
        return new_lines

    def is_ring(self, lines):
        """Являются ли заданные линии кольцом
      
        У каждого кольца должно быть парное количество одинаковых точек.
        иначе это не кольцо
        """
        points = self.all_lines_points(lines)

        for point_1 in points:
            count = 0
            for point_2 in points:
                echo(count)
                if point_1.IsAlmostEqualTo(point_2):
                    count += 1
            # if count < 2:
            # return
        return True
Esempio n. 24
0
from Autodesk.Revit.DB import DatumExtentType, FilteredElementCollector, BuiltInCategory, Line, Reference, ReferenceArray, Options, XYZ

import rpw
from rpw import revit

doc = revit.doc
uidoc = revit.uidoc

selection = FilteredElementCollector(doc).OfCategory(
    BuiltInCategory.OST_Levels).WhereElementIsNotElementType()

# All reference in reference will be dimensioned
reference_array = ReferenceArray()

options = Options(ComputeReferences=True, IncludeNonVisibleObjects=True)

for element in selection:
    reference_array.Append(Reference(element))

crvs = []

ends = []

for element in selection:
    crvs.extend(
        element.GetCurvesInView(DatumExtentType.ViewSpecific, doc.ActiveView))

for crv in crvs:
    ends.append(crv.GetEndPoint(0))
Esempio n. 25
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