在实际工作中,我们给项目的不同阶段标注了不同的信息(大多是尺寸标注),在出图时,就遇到了问题:为了工作和绘图方便,两个阶段公用了一个视图,但是阶段1的图不需要阶段2的标注,反之亦然。所以在出图前夕,我们需要将多余的标注信息隐藏。的由于标注族(Annotation Families)不能用视图过滤器(view Filters)来进行隐藏/显示的操作,所以我做了一个小脚本来快速完成这项工作。

这次我同样用到了来自DATA|SHAPES 的UI界面节点:

使用过程:首先选择要改变可见性的族类别(Category),然后用一个关键词过滤出(Filter)需要被涵盖的族名称(Type Name),同时可选的给出要在哪些视图上进行操作(否则默认所有视图),最后选择要进行的操作(hide or unhide)。工作完成后,Dynamo会生成一个Excel表格作为结果报告。
Dynamo 脚本如下:
操作界面(UI) 和 结果报告(Report)这两部分无需赘言,这个脚本的重点在于Core的部分。下面具体解释一下Python Script:
# Coded by kj-luo # kj-luo.com/ import clr clr.AddReference('RevitAPI') from Autodesk.Revit.DB import * from Autodesk.Revit.DB.Structure import * clr.AddReference('System') from System.Collections.Generic import List clr.AddReference('RevitServices') import RevitServices from RevitServices.Persistence import DocumentManager from RevitServices.Transactions import TransactionManager doc = DocumentManager.Instance.CurrentDBDocument uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument # the IN-part, including the keywords of the names of view and family type, which participate in the game. "Switch" determins wether the Elements should be hidden or shown. # 这里是python node的输入端。这里我们需要族的类别,族和视图的关键词(用于过滤),以及一个开关(Switch)用来判定操作是隐藏或者显示。 categoryId = UnwrapElement(IN[0]).Id filterViewName = IN[1] filterTypeName = IN[2] switch = IN[3] fiViewsName = [] fiElements = [] out = [] ###### DEFINITIONS ############# # two definitions hide and unhide are separately coded # 两个大同小异的definitions用来进行具体的隐藏和显示操作 def hide(doc,element,fiViewsName): report = [] # here oView should be the views on which elements would be hidden. # 这里的oView列表就是最后需要被隐藏物件的列表 oView = [] # vitally important is, we can hide/unhide something from an owner view, but it dosen't affect the same element on dependent views. # So all dependent views must be collected in list oView. # 很重要的是,我在某个主视图隐藏一个图元后,这个主视图的相关视图上同一个图元并不会被影响到。所以所有相关视图都得被列出来。 mView = doc.GetElement(element.OwnerViewId) oView.append(mView) dViews = [doc.GetElement(x) for x in mView.GetDependentViewIds() ] id = element.Id for v in dViews: oView.append(v) # iCollection list: hideId = List[ElementId]([id]) # loop through all views (when they are in the filterd view list) and hide the element with its ID. # 通过循环找到所以需要操作的视图,并将上面的图元隐藏起来。 for view in oView: if view.Name in fiViewsName: try: view.HideElements(hideId) report.append(str(id) +" hidden " + "(" + view.Name + ")") except: report.append(str(id) +" not hidden " + "(" + view.Name + ")") else: report.append(str(id) +" view is filtered " + "(" + view.Name + ")") # a report of the result would be very helpful # 最后生成一个报告 return report # the same for the definition unhide. # 运用同样的道理做一个使图元显示的definition。 def unhide(doc,element,fiViewsName): report = [] oView = [] mView = doc.GetElement(element.OwnerViewId) oView.append(mView) dViews = [doc.GetElement(x) for x in mView.GetDependentViewIds() ] id = element.Id for v in dViews: oView.append(v) hideId = List[ElementId]([id]) for view in oView: if view.Name in fiViewsName: try: view.UnhideElements(hideId) report.append(str(id) +" shown " + "(" + view.Name + ")") except: report.append(str(id) +" still hidden " + "(" + view.Name + ")") else: report.append(str(id) +" view is filtered " + "(" + view.Name + ")") return report ###### COLLECTIONS ############# # collect all view names excluding view templates # 搜集所有除了视图样板外的视图对象 viewsName = [x.Name for x in FilteredElementCollector(doc).WhereElementIsNotElementType().OfClass(View).ToElements() if not x.IsTemplate] # filter the views with keyword # 用关键词过滤视图对象 if filterViewName: for viewName in viewsName: if filterViewName in viewName: fiViewsName.append(viewName) else: fiViewsName = viewsName # collect all elements from the chosen category and type name. And as well filter them with the keyword. # 同样的,根据族类别和族名称搜集最终要被操作的对象图元 elements =[x for x in FilteredElementCollector(doc).OfCategoryId(categoryId).WhereElementIsNotElementType().ToElements() ] for ele in elements: try: typeName = doc.GetElement(ele.GetTypeId()).get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME).AsString() if filterTypeName in typeName: fiElements.append(ele) except: pass ###### TRANSACTION ############# TransactionManager.Instance.EnsureInTransaction(doc) # now we can start the transaction # 现在可以开启transaction for ele in fiElements: viewId = ele.OwnerViewId.IntegerValue # if an element dosen't have an ownerId, it is not an Annotation. # 一个没有视图信息的图元并不是一个标注,所以这里被排除在外。 if viewId == -1: out.append("Category not supported") break else: if switch: out.append(hide(doc,ele,fiViewsName)) else: out.append(unhide(doc,ele,fiViewsName)) TransactionManager.Instance.TransactionTaskDone() OUT = out
最后运行的结果报告(Report)会展示哪些图元在哪些视图(包括所有的主视图和相关视图)上被隐藏/显示了,如此:

如果对这个脚本稍加改动,操作对象就可以不限于标注图元,而是各个类别的族。这里就不作深入的讨论了。
2021年1月4日