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

Powerpoint countdown and current time in slides VBA

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