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
Post a Comment