We use several line-based Detail Items to show fire and smoke ratings on Walls, based on NFPA standard symbols (filled diamonds, one for each hour of fire-resistance rating, with an "S"appended if the wall is also a smoke barrier; unrated smoke partitions get just the "S"). Placing these in plan views is tedious, at best, and it seemed to me that since the fire/smoke rating information is already attached to the Walls in a parameter, and the endpoints of the Wall and the endpoints of the line-based Detail Item are one and the same, that a Dynamo graph ought to be able place the correct family on each Wall. NOTE: This graph was developed using Dynamo 0.8.2.
For the purposes of my proof-of-concept first pass, I chose to focus just on straight Walls. Several early experiments revealed that simply grabbing all of the Walls in the active view would not work if there were Walls within the current View whose Base Constraint was not at the same level as the level associated with the View, as the node that creates the Detail Items would crash if passed a Wall whose Base Constraint was at a different level. I assume that is because the node was trying to create a Detail Item (annoation) at a level other than the current level. Some of these Walls were Walls at a lower level, not seen because they were hidden by the Floor, but due to the View range Bottom being set below the associated level. We would not want to have the line-based family drawn for these. Others could be multi-story Walls, with a Base Constraint at a lower level, where we would want to show the fire/smoke family. For the first pass, these Walls will still need to be done manually; I do not expect there will be many of these in a project.
So my first task was to be able to get a list of all Walls in the current View whose base constraint matched that of the currently active View. I ended up creating a custom node that takes no input, and has three outputs: in [Walls in the active View whose Base Constraints match the associated level of the active View], out [all other Walls in the active View] and level [for plan views, a text string indicating the name of the associated level; for all other views, a text string indicating "Not a Plan View"]. The in output is the one on which the main graph will operate; the other two are there for diagnostic purposes. If the main graph is not behaving as expected, it can be useful to see whether Walls that you expect to receive a Detail Item are in the out list. If all of the Walls end up in the out list, checking the level output to see if there is an unexpected value or that the graph was mistakenly run in a non-plan view can also be helpful in troubleshooting.
There are a number of nodes inside the custom node. One group extracts the level name of the currently active View, by using the Document.Current, Document.ActiveView and Element.GetParameterValueByName nodes, along with a Code Block to provide the name of the parameter of interest, which is "Associated Level". For plan Views, this will be the name of the level with which the View is associated. Non-plan Views (such as elevations or section) will return an empty text string, as they do not have this parameter.
Another group generates a list of all of the Walls in the active View, starting with the All Elements in Active View node. This list is winnowed down to just the Walls by using a RemoveIfNot node, with the type set to "Wall".
A list of names of the level to which each Wall's Base Constraint is associated is derived using two Element.GetParameterValueByName nodes. The first gets the value of the Base Constraint parameter of each Wall; the second gets the name of each Base Constraint.
The level name with which the active View is associated is then compared to the list of level names of the Base Constraints of the Walls using an == (x equal to y) node. This creates a list of true or false values, indicating whether or not the corresponding Wall's Base Constraint level is the same as the active View's level (true means they are the same, false means they are different). This list is used as the mask by a List.FilterByBoolMask node, which splits the list of Walls in the active View into two lists: the "in" list, for Walls where the Base Constraint level matches the level of the active View, and the "out" list, where the levels do not match.
The outputs of the List.FilterByBoolMask node are the "in" and "out" outputs of the custom node. The "level" output is generated by an If node. The test for the If node is an == node, which compares the name of the active View's Associated Level to an empty string. If the level name is equal to an empty string (active View is not a plan view), then the If node result is the text in the Code Block node, "Not a Plan View" (true input). If the active View's Associated Level is not an empty string, then the name of the active View's Associated Level is the result (false input). The If node result is the "level" output of the custom node.
The entire graph of the custom node, which includes a few Watch nodes that were not shown above and which were useful during development but which could be deleted from the custom node, is shown in the image below.