Create Generic Annotations in list in Drafting View.FamilyViewType

Create generic annotaitons in  a drafting view of type AE-GENN-ANNO v2.20

import sys ##Standard system input import clr ##https://gist.github.com/gtalarico/e6be055472dfcb6f597e3dcd20d11f37 from Autodesk.Revit.DB import FilteredElementCollector import RevitServices from RevitServices.Persistence import DocumentManager from RevitServices.Transactions import TransactionManager # Drafting Views from Autodesk.Revit.DB import BuiltInCategory, BuiltInParameter from Autodesk.Revit.DB import ViewFamilyType, ViewDrafting, Element from Autodesk.Revit.DB import ViewFamily from Autodesk.Revit.DB import Transaction ###Creates a Drafting View### from Autodesk.Revit.DB import Transaction, Element, ElementTransformUtils ##https://forum.dynamobim.com/t/collecting-all-elements-of-family-types-in-active-view/19838/2 from Autodesk.Revit.DB import BuiltInCategory, BuiltInParameter # ViewFamilyTypes and Drafting views creation from Autodesk.Revit.DB import ViewFamilyType, ViewDrafting, Element from Autodesk.Revit.DB import ViewFamily import System ##filterAnnot = System.Predicate <<Work on removing from System.Collections.Generic import List ##Not same as type() = List <<Work on removing import math ##For truncate to integer-RA import re ##Regular expressions for 'natural' sort from itertools import groupby #from Autodesk.Revit.DB import * from Autodesk.Revit.DB import FamilySymbol, FamilyInstance, XYZ, AnnotationSymbol doc = DocumentManager.Instance.CurrentDBDocument uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument ##Likely View Families for View Types REFERENCE ViewTypeArray=["AreaPlan","CeilingPlan","CostReport","Detail","Drafting","Elevation","FloorPlan", "GraphicalColumnSchedule", "Legend", "LoadsReport", "PanelSchedule", "PressureLossReport", "Schedule", "Section", "Sheet", "StructuralPlan", "SystemsAnalysisReport", "ThreeDimensional","Walkthrough" ]; ##uidoc = __revit__.ActiveUIDocument ##doc = __revit__.ActiveUIDocument.Document ##################################################################################### ##Create a Drafting View# def get_drafting_type_id(): ##Selects First available ViewType that Matches Drafting Type.## viewfamily_types = FilteredElementCollector(doc).OfClass(ViewFamilyType) for i in viewfamily_types: if i.ViewFamily == ViewFamily.Drafting: ##*.ViewFamily Backwards 'parent' ref I've been looking for!##<<<<<<<<<<<<<<<<<<<<<<<<<<HERE return i.Id def GetDraftingViews(): ##https://forums.autodesk.com/t5/revit-api-forum/view3d-collector/td-p/5277451 DraftingViewsList = FilteredElementCollector(doc).OfClass(ViewDrafting).ToElements() ##DraftingViewTemplates = [v.Id for v in DraftingViewsList if v.IsTemplate == True] DraftingViewsList = [v for v in DraftingViewsList if v.IsTemplate == False] return [DraftingViewsList] def GetDraftingViewTemplates(): ##https://forums.autodesk.com/t5/revit-api-forum/view3d-collector/td-p/5277451 DraftingViewsList = FilteredElementCollector(doc).OfClass(ViewDrafting).ToElements() DraftingViewTemplates = [v for v in DraftingViewsList if v.IsTemplate == True] ##DraftingViewsList = [v.Id for v in DraftingViewsList if v.IsTemplate == False] return [DraftingViewTemplates] def GetDraftingViewByName(objViewFamilyType, strName=""): ##Check if drafting view existds = if not, create it and assign view name DraftingView = None ##Set to null to start if not strName == "": ##If string name is set look for the drafting view DraftingView = FilteredElementCollector(doc).OfClass(ViewDrafting).ToElements() ##Get all drafting views DraftingView = [v for v in DraftingView if v.Name == strName] ##Return Drafting view for each Drafting view eq. Name if DraftingView: DraftingView = DraftingView[0] ##Return single item not list<<<<<<<<<<<<<<< if not DraftingView: ##If no drafting view found DraftingView = ViewDrafting.Create(doc, objViewFamilyType.Id) ##Create View ##After creating view- if not strName=="" : ##IF string is not null set the name of the new view DraftingView.Name = strName return DraftingView ##Return single value def GetGenericAnnotationTypes(): ##BAsed in part ##https://forum.dynamobim.com/t/how-can-i-collect-all-family-types-that-are-considered-annotation-symbols-in-revit/37480/10 ##https://forum.dynamobim.com/t/get-all-generic-annotations-in-a-view/80514/2 filterAnnot = System.Predicate[System.Object](lambda x : x.Family.FamilyCategory.Name == "Generic Annotations") symbAnnot = List[Element](FilteredElementCollector(doc).OfClass(FamilySymbol).ToElements()).FindAll(filterAnnot) return symbAnnot def Lambda_Natural_sort(l): ##Slow 50x but effective ##ORiginal function doesn't work with Objects. ConvertText = lambda ConvertText: int(ConvertText) if ConvertText.isdigit() else ConvertText.lower() alphanum_key = lambda key: [ ConvertText(c) for c in re.split('([0-9]+)', key) ] return sorted(l, key = alphanum_key) def Lambda_GenAnno_Sort_w_fam_name(lstObj): ConvertText = lambda ConvertText: int(ConvertText) if ConvertText.isdigit() else ConvertText.lower() alphanum_key = lambda i: [ ConvertText(c) for c in re.split('(\d+)', i) ] ##GenAnnoTypeName##https://forum.dynamobim.com/t/python-script-to-get-type-name-from-an-element/63306/2 GAstrName = lambda j: [ alphanum_key(c) for c in (j.Family.Name + GetNameByElem(j))] return sorted(lstObj, key = GAstrName) def GetNameByElem(elem): ##GenericAnnotationFamilyType".Name" return doc.GetElement(elem.Id).get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME).AsString() def GroupGenAnnos(lstElems): ##test to Group By Key https://forum.dynamobim.com/t/group-by-key-in-python/39145/2 grp=[] ukey=[] ##Presorted by genannolistfort_w_family_name for k, g in groupby(lstElems, lambda x:x.Family.Name): grp.append(list(g)) ukey.append(k) #Assign your output to the OUT variable. return grp def GetAnnosInView(viewView): ##https://forum.dynamobim.com/t/get-all-generic-annotations-in-a-view/80514/2 symbAnnot = [x for x in FilteredElementCollector(doc,viewDraft.Id).OfCategory(BuiltInCategory.OST_GenericAnnotation).WhereElementIsNotElementType()] def ListConv(x): ## Returns list if single item if type(x) is list : return x ##Leave as list if laready list else: try: z=iter(x) ##if element is iterable- e.g. Generic.List - it can be converted to regular list return [x for x in x] ##Convert to list if single item except: return[x] ##Convert single element to list def ListOfList1InList2(list1,list2): list1Out=[] for x in list1: ##For each element in 1st list (Check against elements in 2nd list) found = False ##Reset to not found for next element for y in list2: if x==y: ##If found, found =True ##Set founc to TRUE break ##Can stop looking in second list this round list1Out.append(found) ##Append result return list1Out def List1InList2(list1,list2): ##If any of list 1 in list 2 return TRUE else False for x in list1: ##For each element in 1st list (Check against elements in 2nd list) for y in list2: if x==y: ##If found, return True ##Return True return False ##Return false def GenAnnosInView(viewView): ##GET ANNOTATIONSIN VIEW ##https://forum.dynamobim.com/t/get-all-generic-annotations-in-a-view/80514/2 FEC=FilteredElementCollector(doc,viewView).OfCategory(BuiltInCategory.OST_GenericAnnotation).WhereElementIsNotElementType() return FEC def GetViewFamilyTypeByName(clsViewFamily, ViewTypeName=""): ##Returns existing or newly created View Type ##Trans_GDVBTN = Transaction (doc, 'Drafting View Type') ##MUST Be in traqnsaction to Create/Name! ViewTypes = [ x for x in FilteredElementCollector(doc).OfClass(ViewFamilyType) if x.ViewFamily == clsViewFamily ] found=False ##Found as false if not ViewTypeName == "": ##If view name is not null for ViewType in ViewTypes: ##Looking for Viewtype name amongst ViewFamily'ies if GetNameByElem(ViewType) == ViewTypeName: ##Get name by ID as FamilyViewType.Name BROKEN - 2022-09-15 check furture versions! found=True break if not found: ViewTypes = ViewTypes[0] ##Set to base type ViewType = ViewTypes.Duplicate(ViewTypeName) ##(strName) as ViewFamilyType ##Trans_GDVBTN.Commit() ##Commit transaction return ViewType ##Return Viewtype def PlaceGenAnnoArray(GAFamTypes, viewView): ###Single family of generic annotaiton types to place yLimit = 10.5/12.0 ##Limit of Y column height 10" (8-1/2"x17" Guide to format into sheet size references) columnCT = 0 ##columnCT location AnnoEXST=[] ##Existing annotaitons in view AnnoNEWW=[] ##New annotaitons creted ##get AllGenAnnosInView - if any... AnnosInView =[] ##AnnosInView = FilteredElementCollector(doc,viewView.Id).OfCategory(BuiltInCategory.OST_GenericAnnotation).WhereElementIsNotElementType().ToElements ##https://forum.dynamobim.com/t/get-all-generic-annotations-in-a-view/80514/13 SeanP filterAnnot = System.Predicate[System.Object](lambda x : doc.GetElement(x.GetTypeId()).Family.FamilyCategory.Name == "Generic Annotations") AnnosInView = List[Element](FilteredElementCollector(doc, viewView.Id).OfClass(FamilyInstance).ToElements()).FindAll(filterAnnot) AnnosInView = UnwrapElement(AnnosInView) ##Unwrap to get to get to Revit Type Elements yPos=0.0 ##Initialoze Y position for GAFamType in GAFamTypes : ##from 0,0 run (-)DOWN then (+)RIGHT for simplicity. These typically will NOT end up on printed sheets ##But are head to use to schedule. Any object in any view will schedule regardless of on/off sheet palcement. ySpace=0.0 ##Initialize as double if GAFamType.LookupParameter("Row.Height"): ##User "Row.Height" to store height of each row for offsets ySpace=GAFamType.LookupParameter("Row.Height").AsDouble() ##Set value as double for offset if ySpace <= 0.0: ##If ySpace unset or zero- set default ySpace = 3.0/16.0/12.0 ##Vertical spacing 3/16" tall (Text is 3/32" high) xSpace=0.0 if GAFamType.LookupParameter("Column.Width"): ##User "Row.Height" to store height of each row for offsets xSpace=GAFamType.LookupParameter("Column.Width").AsDouble() ##Set value as double for offset if xSpace <= 0: ##If ySpace unset or zero- set default xSpace = 10.5/12.0 ##Horizontal spacing 3/16" tall (Text is 3/32" high) if abs(yPos) > yLimit: yPos=0.00 ##Reset Y to start of /next/ column columnCT +=1 ##Increase columnCT xPos = columnCT * (xSpace + 1.0/8.0/12.0) ##Get x location + xspacing + 1/8" ##xPos=0.0 objPoint = XYZ(xPos, yPos, 0) ##GET POINT to place anno yPos -= ySpace ##Set next Y space value for next sopt DOWN GAiv = None
if AnnosInView : ##If ther are annos in the view for GAivx in AnnosInView: ##For each Gen Anno in view Found = False ##Reset Found for y in GAFamTypes: if GetNameByElem(GAFamType)==GAivx.Name: ##If found, Found = True ##Return True GAiv=GAivx break ##Break with Found set if Found: ##If found (after for y) break ##Exit out of outer loop with GAiv (Gen Anno In View) set else: GAiv=None if GAiv: AnnoEXST.append(GAFamType) ##Add it to the existing list for GAinVIew in AnnosInView: ##Cycle through to set it if GAinVIew.Name==GetNameByElem(GAFamType): ##GenericAnnotaitonFamilyTypeCompare GAiv.Location.Point = objPoint ##Sets Fixed Position for element in list. break else: ##Not List1InList2 GAinVIew = doc.Create.NewFamilyInstance(objPoint, GAFamType, viewView) ##Create NEW annotaiton in its location AnnoNEWW.append(GAinVIew) ##Append it to the new list as a double check return AnnoNEWW,AnnoEXST ##Return the New and Existing. Re-running should only return existing. ####################################################################################### def Main(): ###Entry point to procedures t = Transaction (doc, 'Drafting Views From Generic Annos') t.Start() EXST=[] NEWW=[] GenAnnoTypes = [] GenAnnoTypes = GetGenericAnnotationTypes() ##LIST of FAMILY TYPE of GenAnnoTypes GenAnnoTypes = Lambda_GenAnno_Sort_w_fam_name(GenAnnoTypes) ##Sort in natural order- numbers as numbers text as text GenAnnoTypes = GroupGenAnnos(GenAnnoTypes) ##Create nested list by Family and Types for GAFamType in GenAnnoTypes: ##2D list [1.GenAnnoFamilies] DraftViewName = "" DraftViewName = GAFamType[0].Family.Name ##FAmily name used for drafting view name objViewFamilyType=GetViewFamilyTypeByName(ViewFamily.Drafting,"AE-ANNO-GENN") viewDraft = GetDraftingViewByName(objViewFamilyType, DraftViewName) ##Get or create drafting view by name Annos=PlaceGenAnnoArray (GAFamType, viewDraft) ##Place or update gfams per view if Annos[0]: NEWW.append([viewDraft.Name,Annos[0]]) if Annos[1]: EXST.append([viewDraft.Name,Annos[1]]) t.Commit() return ([NEWW,EXST]) ############################################################################################ ############################################################################################ ## #OUT=GetViewFamilyTypeByName(ViewFamily.FloorPlan,"AE-FP-DT") ## GetDraftingView_AllTypes() OUT=Main () #OUT=GetViewFamilyTypeByName(ViewFamily.Drafting,"AE-ANNO-GENN") #OUT=Main () ##Entry point to run all scripts ############################################################################################ ############################################################################################

Comments

Popular posts from this blog

Revit area plans adding new types and references (Gross and rentable)

Powerpoint countdown and current time in slides VBA

Revit 2019 and up tab colorizer