def filter_nonetypes(doc, ids): result = [] for e_id in ids: if doc.GetElement(e_id) != None: result.append(e_id) print(doc.GetElement(e_id).GetType()) return result
def name(self): vtName = "<No Template>" genLevel = "<No Level>" if doc.GetElement(self.item.ViewTemplateId): vtName = doc.GetElement(self.item.ViewTemplateId).Name if self.item.GenLevel: genLevel = self.item.GenLevel.Name return '{} ({}) ----- [{}] --- [{}]'.format(self.item.ViewName, self.item.ViewType, str(vtName), genLevel)
def get_familysymbol_instances(doc, fi): cl = FilteredElementCollector(doc) fifilter = FamilyInstanceFilter(doc, fi.Id) instances = set( cl.WhereElementIsNotElementType().WherePasses(fifilter).ToElements()) # for catching cases where LegendComponent for the family is placed cl2 = FilteredElementCollector(doc) legends = cl2.WhereElementIsNotElementType().OfCategory( BuiltInCategory.OST_LegendComponents).ToElements() for e in legends: p = e.get_Parameter(BuiltInParameter.LEGEND_COMPONENT) fs_id = p.AsElementId() if fs_id.IntegerValue > 0: fs = doc.GetElement(fs_id) try: ff = fs.Family # check is legend component Type Family is the same as fi.Id if ff.Id == fi.Family.Id: instances.add(e) except: pass # print(fs.Id.IntegerValue) return instances
def get_view_filters(doc, v): result = [] ftrs = v.GetFilters() for fId in ftrs: f = doc.GetElement(fId) result.append(f) return result
def GetBWICInfo(doc): # Get the BWIC family to place - this should be selectable by the user and/or based on what type of penetration it will be BWICFamilySymbol = doc.GetElement(ElementId(1290415)) familySymbolName = BWICFamilySymbol.Family.Name all_family_instances = FilteredElementCollector(doc).OfClass( FamilyInstance).OfCategory(BuiltInCategory.OST_GenericModel) bw_penetrations = [ f for f in all_family_instances if f.Name == BWICFamilySymbol.Family.Name ] phase = list(doc.Phases)[-1] # get last phase of project for b in bw_penetrations: if b.Space[phase]: # # BuiltinParameters # # SPACE_ASSOC_ROOM_NUMBER "Room Number" # # SPACE_ASSOC_ROOM_NAME "Room Name" print b.Space[phase].get_Parameter( BuiltInParameter.SPACE_ASSOC_ROOM_NAME).AsString() return "BW Penetrations found: " + str(len(bw_penetrations))
def GetBoundaryGeneratingElement(boundarySegment): linkInstance = doc.GetElement(boundarySegment.ElementId) try: linkDoc = linkInstance.GetLinkDocument() linkedElementId = boundarySegment.LinkElementId generatingElement = linkDoc.GetElement(linkedElementId) return generatingElement except Exception as e: return str(e)
def starting_view(): startingViewSettingsCollector = FilteredElementCollector(doc) startingViewSettingsCollector.OfClass(StartingViewSettings).ToElements() startingView = None for settings in startingViewSettingsCollector: startingView = doc.GetElement(settings.ViewId) logger.debug("Starting view", startingView) return startingView
def process(datafile, saved_list=[], reverse=False): if not reverse: cl = FilteredElementCollector( doc).WhereElementIsNotElementType().OfCategory( BuiltInCategory.OST_Constraints) constraints = cl.ToElements() constraints_to_change = filter(lambda c: c.NumberOfSegments == 0, constraints) constraints_to_change = list( filter(lambda c: c.IsLocked, constraints_to_change)) td_text = "%d enabled Constraints found. Disable them?" % len( constraints_to_change) else: td_text = "Reverse mode.\n%d saved Constraints found. Recover them?" % len( saved_list) constraints_to_change = [] for id_int in saved_list: try: element = doc.GetElement(ElementId(id_int)) constraints_to_change.append(element) except: pass tdres = TaskDialog.Show( "Constraints", td_text, TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No) if tdres == TaskDialogResult.No: return t = Transaction(doc, __title__) t.Start() is_error = False try: for constraint in constraints_to_change: constraint.IsLocked = True if reverse else False if not reverse: saved_list.append(constraint.Id.IntegerValue) except Exception as exc: is_error = True t.RollBack() TaskDialog.Show(__title__, "Error. Changes cancelled.") else: t.Commit() result_text = "Finished." if not reverse: result_text += "\nChanged elements saved. To recover then run the same script with SHIFT button" TaskDialog.Show(__title__, result_text) if not is_error: save(datafile, saved_list) selection.set_to(map(lambda e: e.Id, constraints_to_change))
def get_view_templates(doc, view_type=None, sel_set=sel_set): cl_view_templates = FilteredElementCollector(doc).WhereElementIsNotElementType() allview_templates = cl_view_templates.OfCategory(BuiltInCategory.OST_Views).ToElementIds() vt_list = [] for vtId in allview_templates: vt = doc.GetElement(vtId) if vt.IsTemplate: if view_type is None or vt.ViewType == view_type: vt_list.append(vt) return vt_list
def assign_spaces_to_bw_holes(): # ids = uidoc.Selection.GetElementIds() for id in ids: #el = doc.GetElement(ElementId(int(id))) el = doc.GetElement(id) if el.LookupParameter("MF_BWIC - From Space - Id").AsInteger() == 0: BWIC_assign_spaces(el)
def get_families(doc): cl = FilteredElementCollector(doc) families_types = set(cl.WhereElementIsElementType().ToElements()) families = {} for f in families_types: if type(f) == FamilySymbol or type(f) == AnnotationSymbolType: ff = f.Family f_id = int(ff.Id.IntegerValue) if f_id not in families.keys(): families[f_id] = 0 families[f_id] += len(get_familysymbol_instances(doc, f)) used = list(filter(lambda x: families[x] != 0, families.keys())) not_used = list(filter(lambda x: families[x] == 0, families.keys())) used = list(map(lambda x: doc.GetElement(ElementId(x)), used)) not_used = list(map(lambda x: doc.GetElement(ElementId(x)), not_used)) return used, not_used
def check_dependent_views(l): to_close = [] for uiview in uidoc.GetOpenUIViews(): v = doc.GetElement(uiview.ViewId) if not v.GenLevel: continue if v.GenLevel.Id == l.Id: to_close.append(uiview) return to_close
def get_active_view(): if type(doc.ActiveView) != View: active_view = doc.ActiveView else: if len(selected_ids) == 0: logger.error('Select a view with applied template, to copy filters from it') return active_view = doc.GetElement(selected_ids[0]) if type(active_view) not in allowed_types: logger.error('Selected view is not allowed. Please select or open view from which ' 'you want to copy template settings VG Overrides - Filters') return return active_view
def get_views(): selection = uidoc.Selection.GetElementIds() views_selected = filter( lambda e: doc.GetElement(e).GetType().IsSubclassOf(View), selection) if len(views_selected) == 0: error_text = "No views selected.\nTextnotes from all project views will be exported." q = TaskDialog.Show( __title__, error_text, TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel) if str(q) == "Cancel": return else: return None else: return views_selected
def level_dependent(): """By level""" levels_all = all_levels() if len(levels_all) < 2: print( "At least 2 levels should be created in a project to check dependent. Create one more level and run again" ) return selected_levels = select_levels_dialog(levels_all) if not selected_levels: print("Nothing selected") return results = {} for e in selected_levels: views_to_close = check_dependent_views(e) if len(views_to_close) > 0: q = TaskDialog.Show( __title__, "These views will be closed:\n%s" % ", ".join( map(lambda x: doc.GetElement(x.ViewId).Name, views_to_close)), TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel) if str(q) == "Cancel": break if len(uidoc.GetOpenUIViews()) == len(views_to_close): uidoc.ActiveView = starting_view() for v in views_to_close: v.Close() t = Transaction(doc, "Check level " + e.Name) t.Start() elements = doc.Delete(e.Id) t.RollBack() results[e.Name] = group_by_type(elements) return results
def format_results(textnotes_dict): cl_sheets = FilteredElementCollector(doc) sheetsnotsorted = cl_sheets.OfCategory( BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements( ) sheetsnotsorted = list(sheetsnotsorted) # Last empty element to check not placed views sheetsnotsorted.append(None) result = [] # List of views which wasnt checked views_left = textnotes_dict.keys() for s in sheetsnotsorted: if s: sheet_views = [s.Id] sheet_id = s.Id sheet_name = s.Name sheet_views += s.GetAllPlacedViews() else: sheet_name = "" sheet_id = "" sheet_views = views_left # todo: search for use of .Parameter[] indexer. for v_id in sheet_views: if v_id in textnotes_dict: views_left.remove(v_id) v = doc.GetElement(v_id) tt = textnotes_dict[v_id] for t in tt: result.append( [sheet_name, sheet_id, v.Name, v_id, t[1], t[0]]) return result
def select_duplicate_tags(tags_by_view, selected_switch, all_views): duplicates_id = [] for view, tags in tags_by_view.items(): view_name = doc.GetElement(view).Name duplicates_id_view = find_duplicates_on_view(tags, view_name) duplicates_id += duplicates_id_view dup_count = len(duplicates_id_view) if all_views and dup_count > 0: print("View \"%s\": %d of %d tags duplicated" % (view_name, dup_count, len(tags))) if pyRevitNewer44: selection.set_to(duplicates_id) else: collection = List[ElementId](duplicates_id) selection.SetElementIds(collection) if len(duplicates_id) > 0: print("%d duplicated %s selected" % (len(duplicates_id), selected_switch)) else: print("No duplicated %s found" % (len(duplicates_id), selected_switch))
def group_by_type(elements_ids): ignore_types = config_exceptions() result_dict = {} for e_id in elements_ids: e = doc.GetElement(e_id) if not e: continue try: el_type = e.Category.Name except: el_type = "Other" if el_type in ignore_types: continue el_type_full = el_type + " - " + e.GetType().Name.ToString() if el_type_full not in result_dict: result_dict[el_type_full] = [] result_dict[el_type_full].append(e_id) return result_dict
def BWIC_assign_spaces(el): ############ # get from room and to room global wall_keys global spaces_grouped_by_wall # get location try: location = el.Location.Point level = doc.GetElement( el.LevelId ) ## hopefully all the items shoudl have the same level property if they have been grouped! facingOrientation = el.FacingOrientation BWIC_wall_id = el.LookupParameter( "MF_BWIC Building Element Id").AsInteger() space_matches = spaces_grouped_by_wall[wall_keys.index(BWIC_wall_id)] space_names = [x[3] for x in space_matches] space_ids = [x[2] for x in space_matches] print "Space Matches:" print space_names options = SpatialElementBoundaryOptions() options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.CoreCenter #space_boundaries = [doc.GetElement(ElementId(s)).GetBoundarySegments(options) for s in space_ids] spaces_as_polygons = [] for s in space_matches: space = doc.GetElement(ElementId(s[2])) space_name = s[3] space_boundary_segments = list(space.GetBoundarySegments(options)) #print "space_boundary_segments" #print list(space_boundary_segments) space_curves = [[s.GetCurve() for s in segment] for segment in space_boundary_segments] space_polygon = [(sc.Evaluate(0, True).X, sc.Evaluate(0, True).Y) for sc in space_curves[0]] #print "space_polygon" #print space_polygon spaces_as_polygons.append([space.Id, space_name, space_polygon]) #print "spaces_as_polygons " #print spaces_as_polygons ## get polygons in X,Y to do point_in_polygon test.. dir = 1 tolerance = 100 / 304.8 translation = Transform.CreateTranslation(dir * tolerance * facingOrientation) p1 = translation.OfPoint(location) translation = Transform.CreateTranslation(-1 * dir * tolerance * facingOrientation) p2 = translation.OfPoint(location) bwic_rooms = [] for s in spaces_as_polygons: space_polygon = s[2] if point_inside_polygon(p1.X, p1.Y, space_polygon): bwic_rooms.append(s[1]) bwic_to_room_id = int(s[0].IntegerValue) bwic_to_room_name = s[1] if point_inside_polygon(p2.X, p2.Y, space_polygon): bwic_rooms.append(s[1]) bwic_from_room_id = int(s[0].IntegerValue) bwic_from_room_name = s[1] print "bwic_rooms" print bwic_rooms print "bwic_from_room" print bwic_from_room_name print "bwic_to_room" print bwic_to_room_name el.LookupParameter("MF_BWIC - From Space - Id").Set(bwic_from_room_id) el.LookupParameter("MF_BWIC - From Space - Name").Set( bwic_from_room_name) el.LookupParameter("MF_BWIC - To Space - Id").Set(bwic_to_room_id) el.LookupParameter("MF_BWIC - To Space - Name").Set(bwic_to_room_name) except Exception as e: print str(e)
def MF_CheckIntersections(MEP_ElementsToCheck, building_Element, doc): ## convert this into a function for every MEP curve type? (pipes, duct, cabletray) # MEP_Elements include pipe, duct, cabletray #dt = Transaction(doc, "Duct Intersections") #dt.Start() # Levels ####################################################################### ## ask user to select levels levels = FilteredElementCollector(doc).OfClass(Level).ToElements() class LevelOption(BaseCheckBoxItem): def __init__(self, level_element): super(LevelOption, self).__init__(level_element) @property def name(self): return '{} '.format(self.item.Name) options = [] seleted = [] return_options = forms.SelectFromCheckBoxes.show( [LevelOption(x) for x in levels], title="Select Levels", button_name="Choose Levels", width=800) if return_options: selected = [x.unwrap() for x in return_options if x.state] levels = list(selected) selected_level = selected[0] #building element filter filter = ElementCategoryFilter(BuiltInCategory.OST_Levels) #levels = FilteredElementCollector(doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() #levelIndex = 0 #levelFilter = ElementLevelFilter(levels[levelIndex].Id) levelFilter = ElementLevelFilter(selected_level.Id) levelIndex = list(levels).index(selected_level) filter = ElementCategoryFilter(BuiltInCategory.OST_PipeCurves) # set up level filter for Reference Level pipes = FilteredElementCollector( doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() filter = ElementCategoryFilter(BuiltInCategory.OST_DuctCurves) ducts = FilteredElementCollector( doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() filter = ElementCategoryFilter(BuiltInCategory.OST_CableTray) cable_trays = FilteredElementCollector( doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() pipes = [p for p in pipes] ducts = [d for d in ducts] cable_trays = [c for c in cable_trays] print levels[levelIndex].Name print levels[levelIndex].ProjectElevation # looking in linked document for wall elements... links = FilteredElementCollector(doc).OfCategory( BuiltInCategory.OST_RvtLinks).WhereElementIsNotElementType( ).ToElements() linkDoc = links[0].GetLinkDocument( ) # assumes that the architects document is the first linked document! risky! filter = ElementCategoryFilter(BuiltInCategory.OST_Levels) linkedLevels = FilteredElementCollector( linkDoc).WhereElementIsNotElementType().WherePasses( filter).ToElements() #levelFilter = ElementLevelFilter(linkedLevels[levelIndex].Id) #print linkedLevels[levelIndex].Name #print linkedLevels[levelIndex].ProjectElevation ## need to match levels by name! for l in linkedLevels: if levels[levelIndex].Name == l.Name: levelFilter = ElementLevelFilter(l.Id) print l.Name #sys.exit() filter = ElementCategoryFilter(BuiltInCategory.OST_Walls) curveDriven = ElementIsCurveDrivenFilter() ## levels in liked file have different ids.... compare indexs instead walls = FilteredElementCollector(linkDoc).WhereElementIsNotElementType( ).WherePasses(filter).WherePasses(levelFilter).WherePasses( ElementIsCurveDrivenFilter()).ToElements() # if str(MEP_Element) is "ducts": # MEP_Elements = ducts # if str(MEP_Element) is "pipes": # MEP_Elements = pipes if MEP_ElementsToCheck == "ducts": MEP_Elements = ducts if MEP_ElementsToCheck == "pipes": MEP_Elements = pipes if MEP_ElementsToCheck == "cabletrays": MEP_Elements = cable_trays curves = [] linePoints = [] intersections = [] slopingMEP_Elements = [] all_MEP_Elements = [] verticalMEP_ElementRuns = [] headings = [ "level.Name", "levelZ", "MEP_Element.Id", "MEP_ElementSystem", "MEP_ElementSystemName", "length", "startPointXY", "startPoint.X", "startPoint.Y", "startPoint.Z", "endPoint.X", "endPoint.Y", "endPoint.Z", "deltaX", "deltaY", "deltaZ", "orientation" ] wallHeadings = [ "wall.Name", "MEP_Element.Id", "MEP_ElementSystem", "MEP_ElementSystemName", "length", "startPointXY", "startPoint.X", "startPoint.Y", "startPoint.Z", "endPoint.X", "endPoint.Y", "endPoint.Z", "deltaX", "deltaY", "deltaZ", "orientation" ] intersections.append(headings) slopingMEP_Elements.append(headings) verticalMEP_Elements = [] horizontalMEP_Elements = [] all_MEP_Elements.append(headings) # Get the BWIC family to place - this should be selectable by the user and/or based on what type of penetration it will be BWICFamilySymbol = doc.GetElement(ElementId(1290415)) wallIntersections = [] wallIntersections.append(wallHeadings) print "Walls found: " + str(len(walls)) print "Ducts found:" + str(len(ducts)) print "Pipes found:" + str(len(pipes)) print "Cable Trays found:" + str(len(cable_trays)) #sys.exit() # for wall in walls: # if wall.Location: # #print str(wall.Location.Curve) # #A = startPoint # MEP Curve # #B = endPoint # MEP Curve # C = wall.Location.Curve.Evaluate(0,True) # D = wall.Location.Curve.Evaluate(1,True) # print "( "+ str( C) + ", "+ str( D ) + ")" #sys.exit() # build list of BWIC penetrations bwic_list = [] penetration_list = [] headings = [ "b.Id", "wall.Id", "wall.Name", "MEPElement.Id", "MEP_ElementSystemName", "location", "location.X", "location.Y", "location.Z", "BWIC_width", "BWIC_height", "wall.Orientation" ] bwic_list.append(headings) penetration_list.append(headings) for MEP_Element in MEP_Elements: line = MEP_Element.Location.Curve curves.append(line) startPoint = line.GetEndPoint(0) endPoint = line.GetEndPoint(1) startPointXY = ('%.2f' % startPoint.X, '%.2f' % startPoint.Y) linePoints.append([startPoint, endPoint]) p = 0.1 MEP_ElementTop = max(startPoint.Z, endPoint.Z) MEP_ElementBottom = min(startPoint.Z, endPoint.Z) if MEP_ElementsToCheck == "pipes": MEP_ElementSystem = MEP_Element.get_Parameter( BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM).AsValueString() MEP_ElementSystemName = MEP_Element.get_Parameter( BuiltInParameter.RBS_SYSTEM_NAME_PARAM).AsString() if MEP_ElementsToCheck == "ducts": MEP_ElementSystem = MEP_Element.get_Parameter( BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM).AsValueString() MEP_ElementSystemName = MEP_Element.get_Parameter( BuiltInParameter.RBS_SYSTEM_NAME_PARAM).AsString() if MEP_ElementsToCheck == "cabletrays": MEP_ElementSystem = "Cable Tray" MEP_ElementSystemName = MEP_Element.get_Parameter( BuiltInParameter.RBS_CTC_SERVICE_TYPE).AsString() #MEP_ElementSystem = MEP_Element.get_Parameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM).AsValueString() deltaX = round(endPoint.X - startPoint.X, 2) deltaY = round(endPoint.Y - startPoint.Y, 2) deltaZ = round(endPoint.Z - startPoint.Z, 2) tolerance = 0.01 orientation = ' - ' if (abs(deltaX) > tolerance or abs(deltaY) > tolerance) and abs(deltaZ) > tolerance: orientation = "Sloped" if (abs(deltaX) < tolerance and abs(deltaY) < tolerance) and abs(deltaZ) > tolerance: orientation = "Vertical" verticalMEP_Elements.append(MEP_Element) if (abs(deltaX) > tolerance or abs(deltaY) > tolerance) and abs(deltaZ) < tolerance: orientation = "Horizontal" horizontalMEP_Elements.append(MEP_Element) MEP_ElementData = [ MEP_Element.ReferenceLevel.Name, MEP_Element.ReferenceLevel.ProjectElevation, MEP_Element.Id, MEP_ElementSystem, MEP_ElementSystemName, line.Length, str(startPointXY), startPoint.X, startPoint.Y, startPoint.Z, endPoint.X, endPoint.Y, endPoint.Z, deltaX, deltaY, deltaZ, orientation ] all_MEP_Elements.append(MEP_ElementData) #walls = list(walls)[:20] #tg = TransactionGroup(doc, "Place Wall BWICs") #tg.Start() for wall in walls: if wall.Location: wallMinZ = wall.get_BoundingBox(None).Min.Z wallMaxZ = wall.get_BoundingBox(None).Max.Z #wallLevel = linkDoc.GetElement(ElementId( wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT) )) #if orientation is not "Vertical" and wallMinZ < startPoint.Z < wallMaxZ: if wallMinZ < startPoint.Z < wallMaxZ: # try: #print str(wall.Location.Curve) # A = startPoint # MEP Curve # B = endPoint # MEP Curve # C = wall.Location.Curve.Evaluate(0,True) # D = wall.Location.Curve.Evaluate(1,True) ## flatten to 2D for intersection check.. A = XYZ(startPoint.X, startPoint.Y, 0) # MEP Curve B = XYZ(endPoint.X, endPoint.Y, 0) # MEP Curve C = XYZ( wall.Location.Curve.Evaluate(0, True).X, wall.Location.Curve.Evaluate(0, True).Y, 0) D = XYZ( wall.Location.Curve.Evaluate(1, True).X, wall.Location.Curve.Evaluate(1, True).Y, 0) # print str( C , D ) if intersect(A, B, C, D): print wall.Name + " intersection found with " + MEP_ElementSystemName + " at Z = " + str( startPoint.Z) + " - Wall min : " + str( wallMinZ) + "max: " + str(wallMaxZ) intersection = [ wall.Name, MEP_Element.Id, MEP_ElementSystem, MEP_ElementSystemName, line.Length, str(startPointXY), startPoint.X, startPoint.Y, startPoint.Z, endPoint.X, endPoint.Y, endPoint.Z, deltaX, deltaY, deltaZ, orientation ] wallIntersections.append(intersection) intersection = line_intersection((A, B), (C, D)) location = XYZ(intersection[0], intersection[1], startPoint.Z) ## try this ##b = MF_PlaceBWIC(location, BWICFamilySymbol,level) # st = SubTransaction(doc) # st.Start() #get some info about the wall wall_fire_rating = ' - ' wall_thickness = 100 / 304.8 ## default 300mm converted to feet # try: # wall_thickness = wall.LookupParameter("Width").AsValueString() # wall_fire_rating = wall.LookupParameter("Fire Rating").AsValueString() # except Exception as e: # print str(e) # pass # RBS_PIPE_OUTER_DIAMETER try: MEP_ElementWidth = MEP_Element.Diameter # need to get outer diameter! MEP_ElementHeight = MEP_Element.Diameter except: MEP_ElementWidth = MEP_Element.Width MEP_ElementHeight = MEP_Element.Height # # incorporate a factor to adjust hole size according to MEP Element size sizeFactor = 1.5 BWIC_width = sizeFactor * MEP_ElementWidth BWIC_depth = sizeFactor * wall_thickness # length = wall thickness for walls BWIC_height = sizeFactor * MEP_ElementHeight # special treatment for cable tray! if MEP_ElementsToCheck == "cabletrays": insulation_thickness = 0 # mm margin = 100 # mm try: min_hole_width = MEP_Element.Width + 2 * ( insulation_thickness / 304.8) + ( margin / 304.8) # ft min_hole_height = MEP_Element.Height + 2 * ( insulation_thickness / 304.8) + ( margin / 304.8) # ft except: min_hole_width = MEP_Element.Diameter + 2 * ( insulation_thickness / 304.8) + ( margin / 304.8) # ft min_hole_height = MEP_Element.Diameter + 2 * ( insulation_thickness / 304.8) + ( margin / 304.8) # ft rounded_hole_width = roundup( (min_hole_width) * 304.8, 50) / 304.8 # round up to nearest 50mm rounded_hole_height = roundup( (min_hole_height) * 304.8, 50) / 304.8 # round up to nearest 50mm BWIC_width = rounded_hole_width BWIC_height = rounded_hole_height # special treatment for ducts! if MEP_ElementsToCheck == "ducts": insulation_thickness = MEP_Element.get_Parameter( BuiltInParameter. RBS_REFERENCE_INSULATION_THICKNESS).AsDouble( ) # mm # allow 100mm additional margin after accouting for insulation for pipework holes (50mm either side) margin = 100 # mm try: min_hole_width = MEP_Element.Width + 2 * ( insulation_thickness / 304.8) + ( margin / 304.8) # ft min_hole_height = MEP_Element.Height + 2 * ( insulation_thickness / 304.8) + ( margin / 304.8) # ft except: min_hole_width = MEP_Element.Diameter + 2 * ( insulation_thickness / 304.8) + ( margin / 304.8) # ft min_hole_height = MEP_Element.Diameter + 2 * ( insulation_thickness / 304.8) + ( margin / 304.8) # ft rounded_hole_width = roundup( (min_hole_width) * 304.8, 50) / 304.8 # round up to nearest 50mm rounded_hole_height = roundup( (min_hole_height) * 304.8, 50) / 304.8 # round up to nearest 50mm BWIC_width = rounded_hole_width BWIC_height = rounded_hole_height # special treatment for pipes! elif MEP_ElementsToCheck == "pipes": insulation_thickness = MEP_Element.get_Parameter( BuiltInParameter. RBS_REFERENCE_INSULATION_THICKNESS).AsDouble( ) # ft #insulation_thickness = 25 # mm # allow 50mm additional margin after accouting for insulation for pipework holes (25mm either side) margin = 50 outside_diameter = MEP_Element.get_Parameter( BuiltInParameter.RBS_PIPE_OUTER_DIAMETER ).AsDouble() #ft MEP_ElementWidth = outside_diameter MEP_ElementHeight = outside_diameter min_hole_size = outside_diameter + 2 * insulation_thickness + ( margin / 304.8) # ft rounded_hole = roundup( (min_hole_size) * 304.8, 50) / 304.8 # round up to nearest 50mm BWIC_width = rounded_hole BWIC_height = rounded_hole #place marker for MEP Element - matched to nominal dimensions BWICMarkerFamilySymbol = doc.GetElement( ElementId(4337768)) MEP_Marker = doc.Create.NewFamilyInstance( location, BWICMarkerFamilySymbol, level, Structure.StructuralType.NonStructural) mep = MEP_Marker space_data = BWIC_assign_spaces(mep, wall.Id, location) mep.LookupParameter("MF_Width").Set(MEP_ElementWidth) mep.LookupParameter("MF_Length").Set(BWIC_depth) mep.LookupParameter("MF_Depth").Set(MEP_ElementHeight) # MEP marker mep.LookupParameter("MF_BWIC Building Element Id").Set( wall.Id.IntegerValue) mep.LookupParameter("MF_BWIC MEP Element Id").Set( MEP_Element.Id.IntegerValue) ref_level = MEP_Element.ReferenceLevel ## trying this ref_level = levels[levelIndex] # MEP marker mep_level_param = mep.get_Parameter( BuiltInParameter.FAMILY_LEVEL_PARAM) mep_level_param.Set(ref_level.Id) offset = MEP_Element.get_Parameter( BuiltInParameter.RBS_OFFSET_PARAM).AsDouble( ) ## this does something wierd.. # MEP marker mep.get_Parameter( BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM ).Set(offset) mep.LookupParameter("MF_Package").Set( MEP_ElementSystemName) # MEP marker description = MEP_ElementSystemName + " vs. " + wall.Name + " MARKER" # + "Fire Rating: " + wall_fire_rating mep.LookupParameter("MF_Description").Set(description) #ang = GetAngleFromMEPCurve(MEP_Element) #create rotation axis zDirection = XYZ(0, 0, 1) translation = Transform.CreateTranslation(1 * zDirection) newPoint = translation.OfPoint(location) rotation_axis = Line.CreateBound( location, newPoint ) # for walls we are rotating about the z axis #get angle of wall f pp = XYZ(0, 1, 0) # ,north' - or facing up.. y = 1 qq = wall.Orientation angle = pp.AngleTo(qq) # cant rotate element into this position - probably because it is reference plane - ? ElementTransformUtils.RotateElement( doc, mep.Id, rotation_axis, angle) ## if mep element size is larger than minimum threshold penetration_list.append([ str(mep.Id), str(wall.Id), wall.Name, str(MEP_Element.Id), MEP_ElementSystemName, str(location), location.X, location.Y, location.Z, BWIC_width * 304.8, BWIC_height * 304.8, str(wall.Orientation) ]) minimum_mep_element_size_threshold = 50 / 304.8 # 50 mm #b ############################################################################## if (MEP_ElementWidth + (2 * insulation_thickness) ) > minimum_mep_element_size_threshold: #place BWIC hole including margins etc BWICInstance = doc.Create.NewFamilyInstance( location, BWICFamilySymbol, level, Structure.StructuralType.NonStructural) b = BWICInstance # BWIC_assign_spaces(b, wall.Id, location) b_level_param = b.get_Parameter( BuiltInParameter.FAMILY_LEVEL_PARAM) b_level_param.Set(ref_level.Id) b.get_Parameter( BuiltInParameter. INSTANCE_FREE_HOST_OFFSET_PARAM).Set(offset) b.LookupParameter("MF_Package").Set( MEP_ElementSystemName) ElementTransformUtils.RotateElement( doc, b.Id, rotation_axis, angle ) # rotates BWIC family to match orientation of wall b.LookupParameter("MF_Width").Set(BWIC_width) b.LookupParameter("MF_Length").Set( BWIC_depth) ## match wall thickness # for walls - set the MF_Depth parameter to match the "height " b.LookupParameter("MF_Depth").Set( BWIC_height ) ## TODO: set this based on the thickness of the wall / floor? WALL_ATTR_WIDTH_PARAM b.LookupParameter( "MF_BWIC Building Element Id").Set( wall.Id.IntegerValue) b.LookupParameter("MF_BWIC MEP Element Id").Set( MEP_Element.Id.IntegerValue) description = MEP_ElementSystemName + " vs. " + wall.Name # + "Fire Rating: " + wall_fire_rating b.LookupParameter("MF_Description").Set( description) b.LookupParameter("MF_BWIC - From Space - Id").Set( space_data[0]) b.LookupParameter( "MF_BWIC - From Space - Name").Set( space_data[1]) b.LookupParameter("MF_BWIC - To Space - Id").Set( space_data[2]) b.LookupParameter("MF_BWIC - To Space - Name").Set( space_data[3]) bwic_list.append([ str(b.Id), str(wall.Id), wall.Name, str(MEP_Element.Id), MEP_ElementSystemName, str(location), location.X, location.Y, location.Z, BWIC_width * 304.8, BWIC_height * 304.8, str(wall.Orientation) ]) ##tb.Commit() # print "Total Wall Intersections: " + str(len(wallIntersections)) # except Exception as e: # print str(e) # pass # Find intersections with Levels # floor intersections ######################################## #tg.Assimilate() for level in levels: levelZ = level.ProjectElevation if MEP_ElementTop > levelZ and MEP_ElementBottom < levelZ: intersection = [ level.Name, levelZ, MEP_Element.Id, MEP_ElementSystem, MEP_ElementSystemName, line.Length, str(startPointXY), startPoint.X, startPoint.Y, startPoint.Z, endPoint.X, endPoint.Y, endPoint.Z, deltaX, deltaY, deltaZ, orientation ] intersections.append(intersection) location = XYZ(startPoint.X, startPoint.Y, levelZ) # # BWICInstance = doc.Create.NewFamilyInstance( # # location, # # BWICFamilySymbol, # # level, # # Structure.StructuralType.NonStructural # # ) # b = BWICInstance # ang = GetAngleFromMEPCurve(MEP_Element) # ElementTransformUtils.RotateElement(doc, b.Id, line, ang) # rotates BWIC family to match rotation of duct passing through it # # BuiltinParameters # # SPACE_ASSOC_ROOM_NUMBER "Room Number" # # SPACE_ASSOC_ROOM_NAME "Room Name" # phase = list(doc.Phases)[-1] # get last phase of project # space = b.Space[phase] ## print space.Id # ERROR - always gets same space Id # # fix this for various system types / rectangular / round duct etc # try: # MEP_ElementWidth = MEP_Element.Diameter # MEP_ElementHeight = MEP_Element.Diameter # except: # MEP_ElementWidth = MEP_Element.Width # MEP_ElementHeight = MEP_Element.Height # # # incorporate a factor to adjust hole size according to MEP Element size # b.LookupParameter("MF_Width").Set(1.5* MEP_ElementWidth) # b.LookupParameter("MF_Length").Set(1.5* MEP_ElementHeight) # b.LookupParameter("MF_Depth").Set(50/304.8) ## TODO: set this based on the thickness of the wall / floor? # b.LookupParameter("Offset").Set(0) # b.LookupParameter("MF_Package").Set(MEP_ElementSystemName) if abs(deltaX) > 0 and abs(deltaY) > 0 and abs(deltaZ > 0): MEP_ElementData = [ MEP_Element.ReferenceLevel.Name, MEP_Element.ReferenceLevel.ProjectElevation, MEP_Element.Id, MEP_ElementSystem, MEP_ElementSystemName, line.Length, str(startPointXY), startPoint.X, startPoint.Y, startPoint.Z, endPoint.X, endPoint.Y, endPoint.Z, deltaX, deltaY, deltaZ, orientation ] slopingMEP_Elements.append(MEP_ElementData) #dt.Commit() #print bwic_list #sort bwic_list sorted_bwic_list = sorted(bwic_list[1:], key=lambda x: int(x[1])) groups = [] uniquekeys = [] from itertools import groupby for k, g in groupby(sorted_bwic_list, lambda x: x[1]): groups.append(list(g)) uniquekeys.append(k) print "--- Groups ---------------------------------------" print str(groups) # bwic_list.append([ # str(b.Id), # str(wall.Id), # wall.Name, # str(MEP_Element.Id), # MEP_ElementSystemName, # str(location), # str(location.X), # str(location.Y), # str(location.Z), # BWIC_width*304.8, # BWIC_height*304.8, # str(wall.Orientation)]) group_x_dims = [] items_with_nearby_neighbours = [] for group in groups: x_mins = [g[6] - ((0.5 * g[9]) / 304.8) for g in group] x_maxs = [g[6] + ((0.5 * g[9]) / 304.8) for g in group] x_centres = [g[6] for g in group] x_centres.sort() x_separations = [(x - x_centres[i - 1]) * 304.8 for i, x in enumerate(x_centres)][1:] #group_sorted_by_x_coord = sorted( group, lambda x: x[6] ) #sort group by x coordinate # for item , n in enumerate( group_sorted_by_x_coord ): # if item[n+1][6] - item[n][6] < 100: # items_with_nearby_neighbours.append(item) group_total_x = (max(x_maxs) - min(x_mins)) * 304.8 # converting to mm # sort by x coordinate, then get separation from next one? group_x_dims.append((group, [group_total_x], x_separations)) print "BWIC Group Information ----------------" print group_x_dims MF_WriteToExcel("MEP_Element Data.xlsx", MEP_ElementsToCheck + " vs. Wall ", wallIntersections) MF_WriteToExcel("MEP_Element Data.xlsx", MEP_ElementsToCheck + " vs. Floor ", intersections) MF_WriteToExcel("MEP_Element Data.xlsx", "Sloping " + MEP_ElementsToCheck, slopingMEP_Elements) MF_WriteToExcel("MEP_Element Data.xlsx", "All " + MEP_ElementsToCheck, all_MEP_Elements) MF_WriteToExcel("MEP_Element Data.xlsx", "BWIC - " + MEP_ElementsToCheck, bwic_list) MF_WriteToExcel("MEP_Element Data.xlsx", "All Penetrations - " + MEP_ElementsToCheck, penetration_list) return groups # mep elements grouped by wall return TransactionStatus.Committed
bbA.Min.Z, bbA.Max.Z, bbB.Min.Z, bbB.Max.Z) output = [] for a in listA: bbA = a.get_BoundingBox(None) if not bbA is None: for b in listB: bbB = b.get_BoundingBox(None) if not bbB is None: if bbIntersect(bbA, bbB): output.append([a, b]) c = 0 if len(selected_ids) > 0: t = Transaction(doc) t.Start(__title__) for x in selected_ids: for y in selected_ids: try: JoinGeometryUtils.JoinGeometry(doc, doc.GetElement(x), doc.GetElement(y)) c += 1 except: pass t.Commit() TaskDialog.Show(__title__, "%d pairs of elements unjoined" % c)
def link_method_cad(): files_filter = "DWG files (*.dwg)|*.dwg|DXF files (*.dxf)|*.dxf|DGN files (*.dgn)|*.dgn" files = pick_files(files_filter) # preset origin = doc.ActiveProjectLocation.GetTotalTransform().Origin activeview = uidoc.ActiveView # or uidoc.ActiveView q = forms.alert("Link CAD to current view only?", yes=True, no=True) if q: this_view_only = True target_view = activeview else: this_view_only = False target_view = None logger.debug("Files") logger.debug(files) for f in files: logger.info("Process file %s ..." % f) link_func = doc.Link.Overloads[str, DWGImportOptions, View, System.Type.MakeByRefType(ElementId)] ext = f[-4:] if ext == ".dwg": o = DWGImportOptions() o.AutoCorrectAlmostVHLines = False o.Unit = ImportUnit.Meter o.OrientToView = False o.ReferencePoint = origin o.ThisViewOnly = this_view_only link_func = doc.Link.Overloads[ str, DWGImportOptions, View, System.Type.MakeByRefType(ElementId)] elif ext == ".dgn": o = DGNImportOptions() o.AutoCorrectAlmostVHLines = False o.Unit = ImportUnit.Meter o.OrientToView = False o.ReferencePoint = origin o.ThisViewOnly = this_view_only link_func = doc.Link.Overloads[ str, DWGImportOptions, View, System.Type.MakeByRefType(ElementId)] t = Transaction(doc) t.Start(__title__) try: status, e_id = link_func( f, o, target_view, ) except Exception as e: logger.error("Unable to import CAD") logger.error(e) status = False e_id = None # # # override rotation option # if __shiftclick__: # q = TaskDialog.Show(__title__, "Is it okay?\nIf not CAD will be rotated", # TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No | TaskDialogCommonButtons.Cancel) # if str(q) == "No": # rotate = True # elif str(q) == "Yes": # rotate = False # else: # return if status: l = doc.GetElement(e_id) # if rotate: # if l.Pinned: # l.Pinned = False # axis = Line.CreateBound(origin, # XYZ(origin.X, origin.Y, origin.Z + 1)) # # ElementTransformUtils.RotateElement(doc, l.Id, axis, -project_angle) l.Pinned = True t.Commit() else: t.RollBack()
def main(): location = doc.ActiveProjectLocation activeview = uidoc.ActiveView project_position = location.get_ProjectPosition(XYZ.Zero) project_angle = project_position.Angle origin = location.GetTotalTransform().Origin # Search for any 3D view or a Plan view cl = FilteredElementCollector(doc) views = cl.OfCategory( BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements() q = TaskDialog.Show( __title__, "Link CAD to current view only?", TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No | TaskDialogCommonButtons.Cancel) if str(q) == "No": this_view_only = False target_view = None elif str(q) == "Yes": this_view_only = True target_view = activeview else: return rotate = False if not target_view: target_view_project = None target_view_3d = None for v in views: if v.IsTemplate: continue if type(v) == ViewPlan: orientation = v.get_Parameter(BuiltInParameter.PLAN_VIEW_NORTH) if orientation.AsInteger() == 1: target_view = v break else: if not target_view_project: target_view_project = v if type(v) == View3D and not target_view_3d: target_view_3d = v if not target_view: rotate = True if target_view_project: target_view = target_view_project elif target_view_3d: target_view = target_view_3d if not target_view: logger.error( "Please create 3D view or a PlanView in a project to place CAD correctly" ) return path = pick_file( files_filter= "DWG files (*.dwg)|*.dwg|DXF files (*.dxf)|*.dxf|DGN files (*.dgn)|*.dgn|All files (*.*)|*.*" ) if not path: return o = DWGImportOptions() o.AutoCorrectAlmostVHLines = False o.Unit = ImportUnit.Meter o.OrientToView = False o.ReferencePoint = origin o.ThisViewOnly = this_view_only link_func = doc.Link.Overloads[str, DWGImportOptions, View, System.Type.MakeByRefType(ElementId)] t = Transaction(doc) t.Start(__title__) try: status, e_id = link_func( path, o, target_view, ) except Exception as e: logger.error("Unable to import CAD") logger.error(e) status = False # override rotation option if __shiftclick__: q = TaskDialog.Show( __title__, "Is it okay?\nIf not CAD will be rotated", TaskDialogCommonButtons.Yes | TaskDialogCommonButtons.No | TaskDialogCommonButtons.Cancel) if str(q) == "No": rotate = True elif str(q) == "Yes": rotate = False else: return if status: l = doc.GetElement(e_id) if rotate: if l.Pinned: l.Pinned = False axis = Line.CreateBound(origin, XYZ(origin.X, origin.Y, origin.Z + 1)) ElementTransformUtils.RotateElement(doc, l.Id, axis, -project_angle) l.Pinned = True t.Commit() else: t.RollBack()
width=800) if return_options: selected = [x.unwrap() for x in return_options if x.state] viewList = list(selected) log = [] t = Transaction(doc) t.Start(__title__) for i in viewList: if i.GenLevel: floorPlanView = i floorPlanViews.append(i) vt = doc.GetElement(i.ViewTemplateId) try: newName = vt.Name + " - " + i.GenLevel.Name newNames.append(newName) i.Name = newName log.append("Success: " + newName) except Exception as e: log.append("Error: : " + str(e)) pass if i.ViewType == ViewType.ThreeD: vt = doc.GetElement(i.ViewTemplateId) try:
def MF_CheckIntersectionAccessory(MEP_ElementsToCheck, building_Element, doc): ## convert this into a function for every MEP curve type? (pipes, duct, cabletray) # MEP_Elements include pipe, duct, cabletray #dt = Transaction(doc, "Duct Intersections") #dt.Start() # Levels ####################################################################### ## ask user to select levels levels = FilteredElementCollector(doc).OfClass(Level).ToElements() class LevelOption(BaseCheckBoxItem): def __init__(self, level_element): super(LevelOption, self).__init__(level_element) @property def name(self): return '{} '.format(self.item.Name) options = [] seleted = [] return_options = forms.SelectFromCheckBoxes.show( [LevelOption(x) for x in levels], title="Select Levels", button_name="Choose Levels", width=800) if return_options: selected = [x.unwrap() for x in return_options if x.state] levels = list(selected) selected_level = selected[0] level = selected_level #building element filter filter = ElementCategoryFilter(BuiltInCategory.OST_Levels) #levels = FilteredElementCollector(doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() #levelIndex = 0 #levelFilter = ElementLevelFilter(levels[levelIndex].Id) levelFilter = ElementLevelFilter(selected_level.Id) levelIndex = list(levels).index(selected_level) filter = ElementCategoryFilter(BuiltInCategory.OST_PipeCurves) # set up level filter for Reference Level pipes = FilteredElementCollector( doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() filter = ElementCategoryFilter(BuiltInCategory.OST_DuctCurves) ducts = FilteredElementCollector( doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() filter = ElementCategoryFilter(BuiltInCategory.OST_CableTray) cable_trays = FilteredElementCollector( doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() filter = ElementCategoryFilter(BuiltInCategory.OST_DuctAccessory) duct_accessories = FilteredElementCollector( doc).WhereElementIsNotElementType().WherePasses(filter).ToElements() duct_accessory_collector = FilteredElementCollector( doc).WhereElementIsNotElementType().WherePasses(filter) pipes = [p for p in pipes] ducts = [d for d in ducts] cable_trays = [c for c in cable_trays] print levels[levelIndex].Name print levels[levelIndex].ProjectElevation # looking in linked document for wall elements... links = FilteredElementCollector(doc).OfCategory( BuiltInCategory.OST_RvtLinks).WhereElementIsNotElementType( ).ToElements() linkDoc = links[0].GetLinkDocument( ) # assumes that the architects document is the first linked document! risky! filter = ElementCategoryFilter(BuiltInCategory.OST_Levels) linkedLevels = FilteredElementCollector( linkDoc).WhereElementIsNotElementType().WherePasses( filter).ToElements() #levelFilter = ElementLevelFilter(linkedLevels[levelIndex].Id) #print linkedLevels[levelIndex].Name #print linkedLevels[levelIndex].ProjectElevation ## need to match levels by name! for l in linkedLevels: if levels[levelIndex].Name == l.Name: levelFilter = ElementLevelFilter(l.Id) print l.Name #sys.exit() filter = ElementCategoryFilter(BuiltInCategory.OST_Walls) curveDriven = ElementIsCurveDrivenFilter() ## levels in liked file have different ids.... compare indexs instead walls = FilteredElementCollector(linkDoc).WhereElementIsNotElementType( ).WherePasses(filter).WherePasses(levelFilter).WherePasses( ElementIsCurveDrivenFilter()).ToElements() wallIntersections = [] #intersection filter.. for d in list(duct_accessories): print d.Symbol.Family.Name print(d.Location.Point) MEP_Element = d MEP_ElementSystemName = MEP_Element.get_Parameter( BuiltInParameter.RBS_SYSTEM_NAME_PARAM).AsString() MEP_ElementSystem = MEP_Element.get_Parameter( BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM).AsValueString() # create imaginary normal lines from location centre of object normal = d.HandOrientation orientation = normal centre = d.Location.Point tolerance = 300 / 304.8 translation = Transform.CreateTranslation(-1 * tolerance * normal) startPoint = translation.OfPoint(centre) translation = Transform.CreateTranslation(1 * tolerance * normal) endPoint = translation.OfPoint(centre) line = Line.CreateBound(startPoint, endPoint) for wall in walls: if wall.Location: wallMinZ = wall.get_BoundingBox(None).Min.Z wallMaxZ = wall.get_BoundingBox(None).Max.Z #wallLevel = linkDoc.GetElement(ElementId( wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT) )) #if orientation is not "Vertical" and wallMinZ < startPoint.Z < wallMaxZ: if wallMinZ < startPoint.Z < wallMaxZ: # try: #print str(wall.Location.Curve) # A = startPoint # MEP Curve # B = endPoint # MEP Curve # C = wall.Location.Curve.Evaluate(0,True) # D = wall.Location.Curve.Evaluate(1,True) ## flatten to 2D for intersection check.. A = XYZ(startPoint.X, startPoint.Y, 0) # MEP Curve B = XYZ(endPoint.X, endPoint.Y, 0) # MEP Curve C = XYZ( wall.Location.Curve.Evaluate(0, True).X, wall.Location.Curve.Evaluate(0, True).Y, 0) D = XYZ( wall.Location.Curve.Evaluate(1, True).X, wall.Location.Curve.Evaluate(1, True).Y, 0) # print str( C , D ) if intersect(A, B, C, D): print wall.Name + " intersection found with " + MEP_ElementSystemName + " at Z = " + str( startPoint.Z) + " - Wall min : " + str( wallMinZ) + "max: " + str(wallMaxZ) intersection = [ wall.Name, MEP_Element.Id, MEP_ElementSystem, MEP_ElementSystemName, line.Length, # str(startPointXY), startPoint.X, startPoint.Y, startPoint.Z, endPoint.X, endPoint.Y, endPoint.Z, # deltaX, # deltaY, # deltaZ, orientation ] wallIntersections.append(intersection) intersection = line_intersection((A, B), (C, D)) location = XYZ(intersection[0], intersection[1], startPoint.Z) BWICMarkerFamilySymbol = doc.GetElement( ElementId(4337768)) MEP_Marker = doc.Create.NewFamilyInstance( location, BWICMarkerFamilySymbol, level, Structure.StructuralType.NonStructural) mep = MEP_Marker space_data = BWIC_assign_spaces(mep, wall.Id, location) wall_thickness = 150 / 304.8 try: width = d.LookupParameter( "Damper Width").AsDouble() height = d.LookupParameter( "Damper Height").AsDouble() mep.LookupParameter("MF_Length").Set( wall_thickness) margin = 1 mep.LookupParameter("MF_Width").Set(margin * width) mep.LookupParameter("MF_Depth").Set(margin * height) except: pass #ref_level = d.get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM) ## trying this #ref_level = levels[levelIndex] # MEP marker mep_level_param = mep.get_Parameter( BuiltInParameter.FAMILY_LEVEL_PARAM) mep_level_param.Set(level.Id) offset = MEP_Element.get_Parameter( BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM ).AsDouble() ## this does something wierd.. # MEP marker mep.get_Parameter( BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM ).Set(offset) mep.LookupParameter("MF_Package").Set( MEP_ElementSystemName) mep.LookupParameter("MF_BWIC Building Element Id").Set( wall.Id.IntegerValue) mep.LookupParameter("MF_BWIC MEP Element Id").Set( MEP_Element.Id.IntegerValue) # MEP marker description = d.Symbol.Family.Name + " : " + MEP_ElementSystemName + " vs. " + wall.Name + " MARKER" # + "Fire Rating: " + wall_fire_rating mep.LookupParameter("MF_Description").Set(description)
bEName = bE.Name except Exception as e: bEName = str(e) #inserts = [] ## handle Columns ############################################################# column = False belongsToRoom = False if "Wall" not in bEName: ## terrible hack column = True inserts = ["Column: " + str(column)] else: try: linkInstance = doc.GetElement(bE.Id) linkDoc = links[0].GetLinkDocument() inserts = [] for i in bE.FindInserts(False, False, False, False): insert = linkDoc.GetElement(i) ## does insert belong to this room? insertType = linkDoc.GetElement( insert.GetTypeId()) width = " -width- " try:
def MF_GetFilterRules(f): types = [] pfRuleList = [] categories = '' for c in f.GetCategories(): categories += Category.GetCategory(doc, c).Name + " , " for rule in f.GetRules(): try: comparator = "" ruleValue = "" ruleInfo = "" if rule.GetType() == FilterDoubleRule: ruleValue = "filterdoublerule" fdr = rule if (fdr.GetEvaluator().GetType() == FilterNumericLess): comparator = "<" elif (fdr.GetEvaluator().GetType() == FilterNumericGreater): comparator = ">" ruleValue = fdr.RuleValue.ToString() ruleName = ruleValue if rule.GetType() == FilterStringRule: ruleValue = "filterstringrule" fsr = rule if (fsr.GetEvaluator().GetType() == FilterStringBeginsWith): comparator = "starts with" elif (fsr.GetEvaluator().GetType() == FilterStringEndsWith): comparator = "ends with" elif (fsr.GetEvaluator().GetType() == FilterStringEquals): comparator = "equals" elif (fsr.GetEvaluator().GetType() == FilterStringContains): comparator = "contains" ruleValue = fsr.RuleString ruleName = ruleValue if rule.GetType() == FilterInverseRule: # handle 'string does not contain ' fInvr = rule.GetInnerRule() if (fsr.GetEvaluator().GetType() == FilterStringBeginsWith): comparator = "does not start with" elif (fsr.GetEvaluator().GetType() == FilterStringEndsWith): comparator = "does not end with" elif (fsr.GetEvaluator().GetType() == FilterStringEquals): comparator = "does not equal" elif (fsr.GetEvaluator().GetType() == FilterStringContains): comparator = "does not contain" ruleValue = fInvr.RuleString ruleName = ruleValue if rule.GetType() == FilterIntegerRule: #comparator = "equals" ruleValue = "filterintegerrule" fir = rule if (fir.GetEvaluator().GetType() == FilterNumericEquals): comparator = "=" elif (fir.GetEvaluator().GetType() == FilterNumericGreater): comparator = ">" elif (fir.GetEvaluator().GetType() == FilterNumericLess): comparator = "<" ruleValue = fir.RuleValue if rule.GetType() == FilterElementIdRule: comparator = "equals" feidr = rule ruleValue = doc.GetElement(feidr.RuleValue) ruleName = ruleValue.Abbreviation t = ruleValue.GetType() #ruleName = doc.GetElement(ruleValue.Id).Name types.append(t) paramName = "" bipName = " - " if (ParameterFilterElement.GetRuleParameter(rule).IntegerValue < 0): bpid = f.GetRuleParameter(rule).IntegerValue #bp = System.Enum.Parse(clr.GetClrType(ParameterType), str(bpid) ) #paramName = LabelUtils.GetLabelFor.Overloads[BuiltInParameter](bpid) #paramName = doc.get_Parameter(ElementId(bpid)).ToString() paramName = Enum.Parse(clr.GetClrType(BuiltInParameter), str(bpid)) param = Enum.Parse(clr.GetClrType(BuiltInParameter), str(bpid)) bipName = param.ToString() #YESSS paramName = LabelUtils.GetLabelFor.Overloads[BuiltInParameter]( param) else: paramName = doc.GetElement( ParameterFilterElement.GetRuleParameter(rule)).Name #paramName = doc.GetElement(ParameterFilterElement.GetRuleParameter(rule)).Name #ruleData += "'" + paramName + "' " + comparator + " " + "'" + ruleValue.ToString() + "'" + Environment.NewLine; #ruleInfo += "'" + str(paramName) + "' " + comparator + " " + "'" + ruleValue.ToString() + "---" try: ruleInfo += "" + str( paramName ) + " - " + bipName + " - " + comparator + " - " + ruleValue.ToString( ) + " - " + ruleName + " - " + rule.GetType().ToString( ) + " --- " pfRuleList += [(str(paramName)), (bipName), (comparator), (ruleValue.ToString()), (ruleName), (rule.GetType().ToString()), (" --- ")] except: ruleInfo += "" + str( paramName ) + " - " + bipName + " - " + comparator + " - " + ruleValue.ToString( ) + " - " + ruleName.ToString() + " - " + rule.GetType( ).ToString() + " --- " pfRuleList += [(str(paramName)), (bipName), (comparator), (ruleValue.ToString()), (ruleName.ToString()), (rule.GetType().ToString()), (" --- ")] #ruleList.append([str(paramName), comparator, ruleName]) #ruleInfo = ( (str(paramName) , comparator , ruleValue.ToString() ) ) #filterRuleList.append(pfRuleList) #ruleValues.append(ruleValue) except Exception as e: print str(e) #sublist.extend(pfRuleList) return [categories, pfRuleList]
def merge_bw_holes(group): # #takes a selected set of bwic holes and replaces them with one object #get min and max coords of group # delta x is the new width # delta y ia the new height # centre point is new location # # Prompt user to select elements and to merge # from Autodesk.Revit.UI.Selection import ObjectType # try: # with forms.WarningBar(title="Select Elements to Merge"): # references = uidoc.Selection.PickObjects(ObjectType.Element, "Select Elements to Merge") # except Exception as e: # print str(e) # print references ids = [g[0].Id for g in group] ######### pre-existing selection # ids = uidoc.Selection.GetElementIds() wall_keys = get_rooms_from_walls()[0] spaces_grouped_by_wall = get_rooms_from_walls()[1] bwic_dim_list = [] bwic_location_list = [] package_list = "Combined Services: AUTO MERGED : " for id in ids: #el = doc.GetElement(ElementId(int(id))) el = doc.GetElement(id) # get location location = el.Location.Point bbox = el.get_BoundingBox(None) print str(bbox.Max) print str(bbox.Min) dimX = float(el.LookupParameter("MF_Width").AsDouble( )) # AsValueString readse the value displayed in the GUI (in mm) dimY = float(el.LookupParameter("MF_Depth").AsDouble( )) ## these will need to change when proper parameters are defined dimZ = float(el.LookupParameter("MF_Length").AsDouble()) penetration_depth = float(el.LookupParameter( "MF_Length").AsDouble()) ## ie. thickness of wall package = el.LookupParameter("MF_Package").AsString() package_list += el.LookupParameter("MF_Package").AsString() + ", " el.LookupParameter("MF_Package").Set(package + " (merged)") level = doc.GetElement( el.LevelId ) ## hopefully all the items shoudl have the same level property if they have been grouped! # if delta x == 0 facingOrientation = el.FacingOrientation #if abs(facingOrientation[1]) > 0.001 : x1 = location.X - dimX / 2 x2 = location.X + dimX / 2 x1 = bbox.Min.X x2 = bbox.Max.X y1 = location.Y - dimY / 2 y2 = location.Y + dimY / 2 y1 = bbox.Min.Y y2 = bbox.Max.Y z1 = location.Z - dimZ / 2 z2 = location.Z + dimZ / 2 z1 = bbox.Min.Z z2 = bbox.Max.Z # if abs(facingOrientation[0]) > 0.001 : # x1 = location.X - dimY/2 # x2 = location.X + dimY/2 # y1 = location.Y - dimX/2 # y2 = location.Y + dimX/2 # z1 = location.Z - dimX/2 # z2 = location.Z + dimZ/2 bwic_dim_list.append([x1, y1, z1, x2, y2, z2]) # this describes the 3d box of each element bwic_location_list.append([location.X, location.Y, location.Z]) # dont need to do this here - spaces already assigned elements being merged... # get the wall the e elements are hosted in though... BWIC_wall_id = el.LookupParameter( "MF_BWIC Building Element Id").AsInteger() # wallId = ElementId(BWIC_wall_id) # space_data = BWIC_assign_spaces(el, wallId, location) min_loc_x = min(x[0] for x in bwic_location_list) min_loc_y = min(x[1] for x in bwic_location_list) max_loc_x = max(x[0] for x in bwic_location_list) max_loc_y = max(x[1] for x in bwic_location_list) min_x = min(x[0] for x in bwic_dim_list) max_x = max(x[3] for x in bwic_dim_list) min_y = min(x[1] for x in bwic_dim_list) max_y = max(x[4] for x in bwic_dim_list) min_z = min(x[2] for x in bwic_dim_list) max_z = max(x[5] for x in bwic_dim_list) new_dimX = (max_x - min_x) new_dimY = (max_y - min_y) new_dimZ = (max_z - min_z) new_width = new_dimX new_height = new_dimZ bbMax = XYZ(max_x, max_y, max_z) bbMin = XYZ(min_x, min_y, min_z) bbLine = Line.CreateBound(bbMin, bbMax) #new_location = XYZ( ( min_x + max_x )/2, ( min_y + max_y )/2, ( min_z + max_z )/2 ) #new_location = bbLine.Evaluate(0.5, True) new_location = XYZ((min_x + max_x) / 2, location.Y, (min_z + max_z) / 2) if ( max_loc_x - min_loc_x < 0.01 ): # if all x coords are the same implies the holes are in a y axis wall new_width = new_dimY new_height = new_dimZ new_location = XYZ(location.X, (min_y + max_y) / 2, (min_z + max_z) / 2) # [[124.82351554450474, 38.149876866312894, 26.164698162729657, 124.96131082009529, 38.287672141903442, 26.656824146981627], [125.29267564949158, 38.149876866312887, 26.164698162729657, 125.43047092508213, 38.287672141903435, 26.656824146981627]] print "bwic_dim_list" print bwic_dim_list print "str([(min_x, min_y, min_z), (max_x, max_y, max_z) ])" print str([(min_x, min_y, min_z), (max_x, max_y, max_z)]) print "str([(min_loc_x, min_loc_y), (max_loc_x, max_loc_y)])" print str([(min_loc_x, min_loc_y), (max_loc_x, max_loc_y)]) print "str( [ new_dimX*304.8, new_dimY*308.8, new_dimZ*304.8, new_location] )" print str( [new_dimX * 304.8, new_dimY * 308.8, new_dimZ * 304.8, new_location]) # Get the BWIC family to place - this should be selectable by the user and/or based on what type of penetration it will be BWICFamilySymbol = doc.GetElement(ElementId(1290415)) #st = Subtransaction(doc, "Merge BWICs") #st.Start() BWICInstance = doc.Create.NewFamilyInstance( new_location, BWICFamilySymbol, level, Structure.StructuralType.NonStructural) b = BWICInstance space_data = BWIC_assign_spaces(b, ElementId(BWIC_wall_id), new_location) margin = 100 / 304.8 # 200mm converted to ft #margin = 0 # if wall orientation is facing in the x - swap dim Y and dim X? rounded_width = roundup((new_width + margin) * 304.8, 50) / 304.8 # print "rounded_width" # print rounded_width b.LookupParameter("MF_Width").Set(rounded_width) #b.LookupParameter("MF_Length").Set(new_dimZ ) ## match wall thickness # for walls - set the MF_Depth parameter to match the "height " # this is project Z dimension rounded_height = roundup((new_height + margin) * 304.8, 50) / 304.8 # print "rounded_height" # print rounded_height b.LookupParameter("MF_Depth").Set( rounded_height) # this the project Z direction... b.LookupParameter("MF_Length").Set( penetration_depth ) # in plan for wall penetrations this is ALWAYS the wall thickness b.LookupParameter("MF_Package").Set(package_list) b.LookupParameter("MF_BWIC Building Element Id").Set(BWIC_wall_id) offset = new_location.Z - level.ProjectElevation ## this does something wierd.. b.get_Parameter( BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).Set(offset) ############################ zDirection = XYZ(0, 0, 1) translation = Transform.CreateTranslation(1 * zDirection) newPoint = translation.OfPoint(new_location) rotation_axis = Line.CreateBound( new_location, newPoint) # for walls we are rotating about the z axis #get angle of wall f pp = XYZ(0, 1, 0) # ,north' - or facing up.. y = 1 qq = facingOrientation angle = pp.AngleTo(qq) ElementTransformUtils.RotateElement(doc, b.Id, rotation_axis, angle) #uidoc.ActiveView.IsolateElementsTemporary(select_ids) #st.Commit() #min_x = return True
def find_mergeable_holes(groups): #print str(groups) # first group by wall id # then group by spaces # then group by proximity # bwic_list.append([ # str(b.Id), # str(wall.Id), # wall.Name, # str(MEP_Element.Id), # MEP_ElementSystemName, # str(location), # str(location.X), # str(location.Y), # str(location.Z), # BWIC_width*304.8, # BWIC_height*304.8, # str(wall.Orientation)]) group_x_dims = [] items_with_nearby_neighbours = [] from itertools import groupby all_x_overlaps = [] all_y_overlaps = [] all_x_overlap_holes = [] all_y_overlap_holes = [] separation_threshold = 500 for group in groups: x_mins = [float(g[6]) - ((0.5 * g[9]) / 304.8) for g in group] x_maxs = [float(g[6]) + ((0.5 * g[9]) / 304.8) for g in group] x_centres = [g[6] for g in group] x_overlaps = [] y_overlaps = [] x_overlap_holes = [] y_overlap_holes = [] sorted_group_by_x = sorted(group, key=lambda x: x[6]) sorted_group_by_y = sorted(group, key=lambda x: x[7]) print "###################################################################" print "New Group of BWIC Objects---------------------------------------" i = 0 group_string = '' merge_string = '' print "Items in group: " + str(len(sorted_group_by_x)) print "sorted_group_by_x --------------------" print sorted_group_by_x print "sorted_group_by_y ----------------------" print sorted_group_by_y for i, sg in enumerate(sorted_group_by_x): print "sg contains----------------------------" #sg contains---------------------------- #dot product # ['4250562', '2785448', 'A-25-M3-FBA-Wall-WallType2-SingleLeaf140mmBlockTileBothSides', '2170037', 'RETURN 6', '(127.851730768, 38.218774504, 27.444225722)', 127.85173076760174, 38.218774504108154, 27.444225721784782, 187.5, 187.5, '(0.000000000, 1.000000000, 0.000000000)'] # sg contains---------------------------- # ['4250563', '2785448', 'A-25-M3-FBA-Wall-WallType2-SingleLeaf140mmBlockTileBothSides', '2170046', 'RETURN 6', '(132.772990610, 38.218774504, 27.444225722)', 132.77299061012144, 38.21877450410814, 27.444225721784782, 187.5, 187.5, '(0.000000000, 1.000000000, 0.000000000)'] # sg contains---------------------------- # ['4250564', '2785448', 'A-25-M3-FBA-Wall-WallType2-SingleLeaf140mmBlockTileBothSides', '2170097', 'RETURN 6', '(136.053830505, 38.218774504, 27.444225722)', 136.05383050513552, 38.218774504108126, 27.444225721784775, 450.00000000000006, 187.5, '(0.000000000, 1.000000000, 0.000000000)'] hole = sg # unpacking 2nd item of sublist print hole x_overlap_pair = [] y_overlap_pair = [] x_overlap_hole_pair = [] y_overlap_hole_pair = [] x_overlaps_string = '' x_centre = float(hole[6]) * 304.8 x_min = float(hole[6]) * 304.8 - (float(hole[9]) / 2) x_max = float(hole[6]) * 304.8 + (float(hole[9]) / 2) first_hole_id = hole[0] first_hole = hole if i < (len(sorted_group_by_x) - 1): next_hole = sorted_group_by_x[i + 1] hole = next_hole this_hole_id = hole[0] this_hole = hole x_centre_next = float(hole[6]) * 304.8 x_min_next = float(hole[6]) * 304.8 - (float(hole[9]) / 2) x_max_next = float(hole[6]) * 304.8 + (float(hole[9]) / 2) if ((x_centre_next - x_centre) > 0.001) and ( (x_min_next - x_max) < separation_threshold): x_overlap_pair.append([first_hole_id, this_hole_id]) x_overlap_hole_pair.append([first_hole, this_hole]) x_overlaps.extend(x_overlap_pair) all_x_overlaps.extend(x_overlap_pair) x_overlap_holes.extend(x_overlap_hole_pair) all_x_overlap_holes.extend(x_overlap_hole_pair) i = i + 1 print "Items in group: " + str(len(sorted_group_by_y)) for j, sgy in enumerate(sorted_group_by_y): print "sg contains----------------------------" hole = sgy # unpacking 2nd item of sublist print hole y_overlap_pair = [] x_centre = float(hole[6]) * 304.8 x_min = float(hole[6]) * 304.8 - (float(hole[9]) / 2) x_max = float(hole[6]) * 304.8 + (float(hole[9]) / 2) y_centre = float(hole[7]) * 304.8 y_min = float(hole[7]) * 304.8 - ( float(hole[9]) / 2 ) # work this out basis of orientation axis... y_max = float(hole[7]) * 304.8 + (float(hole[9]) / 2) first_hole_id = hole[0] first_hole = hole if j < (len(sorted_group_by_y) - 1): next_hole = sorted_group_by_y[j + 1] hole = next_hole this_hole_id = hole[0] this_hole = hole y_centre_next = float(hole[7]) * 304.8 y_min_next = float(hole[7]) * 304.8 - ( float(hole[9]) / 2 ) # work this out basis of orientation axis... y_max_next = float(hole[7]) * 304.8 + (float(hole[9]) / 2) if ((y_centre_next - y_centre) > 0.001) and ( (y_min_next - y_max) < separation_threshold): y_overlap_pair.append([first_hole_id, this_hole_id]) y_overlap_hole_pair.append([first_hole, this_hole]) y_overlaps.extend(y_overlap_pair) all_y_overlaps.extend(y_overlap_pair) y_overlap_holes.extend(y_overlap_hole_pair) all_y_overlap_holes.extend(y_overlap_hole_pair) j = j + 1 print "######################################################" print "######################################################" # print "Group of Element Ids:" # print group_string # print "Mergable Element Ids" # print merge_string print "######################################################" print "######################################################" print "x_overlaps:" # remove any duplicates from x_overlaps array #x_overlaps = set(x_overlaps) x_overlaps_string = ';' for pair in x_overlaps: #print pair if len(pair) > 1: x_overlaps_string += str(pair[0]) + ";" + str(pair[1]) + "; " print x_overlaps_string print "######################################################" x_centres.sort() x_separations = [(float(x) - float(x_centres[i - 1])) * 304.8 for i, x in enumerate(x_centres)][1:] group_total_x = (max(x_maxs) - min(x_mins)) * 304.8 # converting to mm # sort by x coordinate, then get separation from next one? group_x_dims.append((group, [group_total_x], x_separations)) #print "BWIC Group Information ----------------" #print group_x_dims #print GetBWICInfo(doc) print "all_x_overlaps:" # remove any duplicates from x_overlaps array #x_overlaps = set(x_overlaps) x_overlaps_string = ';' y_overlaps_string = ';' select_ids = [] for pair in all_x_overlaps: #print pair id = ElementId(int(pair[0])) select_ids.append(id) if len(pair) > 1: x_overlaps_string += str(pair[0]) + ";" + str(pair[1]) + "; " id = ElementId(int(pair[1])) select_ids.append(id) print x_overlaps_string print "all_y_overlaps:" for pair in all_y_overlaps: #print pair id = ElementId(int(pair[0])) select_ids.append(id) if len(pair) > 1: y_overlaps_string += str(pair[0]) + ";" + str(pair[1]) + "; " id = ElementId(int(pair[1])) select_ids.append(id) print y_overlaps_string select_ids = List[ElementId](select_ids) # uidoc.Selection.SetElementIds(select_ids) # t = Transaction(doc, "Isolate BWICs") # t.Start() # uidoc.ActiveView.IsolateElementsTemporary(select_ids) # t.Commit() close_bwics = [doc.GetElement(id) for id in select_ids] merge_bws = [] for bw in close_bwics: space_pair = str( bw.LookupParameter( "MF_BWIC - From Space - Id").AsInteger()) + " - " + str( bw.LookupParameter("MF_BWIC - To Space - Id").AsInteger()) wall_id = bw.LookupParameter("MF_BWIC Building Element Id").AsInteger() merge_bws.append([ bw, wall_id, space_pair, bw.Id, bw.Location.Point.X, bw.Location.Point.Y, bw.Location.Point.Z ]) #### group these by nearby coordinates... # group merge_bws by space_pair sorted_merge_bws = sorted(merge_bws, key=lambda x: (x[1], x[2])) bws_grouped_by_space_pair = [] uniquekeys = [] for k, g in groupby(sorted_merge_bws, lambda x: (x[1], x[2])): bws_grouped_by_space_pair.append(list(g)) uniquekeys.append(k) #print bws_grouped_by_space_pair for group in bws_grouped_by_space_pair: print group # need to group by wall first, then group by space pair? # merge similar types (ducts / pipes / cable tray) - successful!! # similar z elevations , max delta_x and delta_z to avoid really big holes return bws_grouped_by_space_pair
checked_pairs = [] joined_pairs = [] c = 0 for x in rng: for y in rng: if x == y: continue _p = sorted([x,y]) _t = (_p[0],_p[1]) if _t in checked_pairs: continue checked_pairs.append(_t) eid1 = selected_ids[_p[0]] eid2 = selected_ids[_p[1]] e1,e2 = doc.GetElement(eid1),doc.GetElement(eid2) joined = JoinGeometryUtils.AreElementsJoined(doc,e1,e2) if joined: joined_pairs.append((e1,e2)) if len(joined_pairs) > 0: t = Transaction(doc) t.Start(__title__) for p in joined_pairs: JoinGeometryUtils.UnjoinGeometry(doc,p[0],p[1]) c+=1 t.Commit() TaskDialog.Show(__title__,"%d pairs of elements unjoined" % c)