The “Edited By” property provided by Revit is a great feature for internal modeling coordination, so good that it makes people wonder if it could be even better. Most of Revit end user must have experienced this: you come to work in the morning, open the model, go to a view to start your well-planned working day, only to find out that some doors are missing, some walls have moved, which kind of ruined your previous day’s masterpiece design. The worst part is, you don’t know who was the irresponsible culprit to yell at, so you send out an email yelling at all your teammates to remind them to be responsible and communicative. Some of your teammates are nice enough to provide vocal support, others remain silent, hopefully also thinking about whether he/she did the editing. You feel the same thing shouldn’t happen again after this email, and it didn’t, until three days later. This time you definitely need to find the person, but how? Who to start with? Indeed, you wouldn’t spend too much of your brain power on this kind of political decision if you are in a healthy enough team, but the reality is most often not as good as your perfect world.
The person who did the change is most often newbies to collaborated working environment in Revit, but sometimes even experienced users could do that, just because of the complexity and inter-connectivity of a Revit model.
Could there be a “Last Edited By” property for every element, so we can directly find the right person without any guessing or group-email-over-killing. Or could it be even better, to have a complete history of who edited this element and when was the change saved? The most intuitive and reasonable way to achieve this, if Revit API allows, is to tell the central model to take a note whenever an element is checked out by the user. To my knowledge, Revit API does not allow direct/separate control of the central model. Also, Revit API does not provide “checking out” event for plugin to response to. In terms of performance impact, my solution is not as perfect as this imaginary route, but it is still good enough to achieve the end result without sacrificing much local performance.
WHAT HAPPENS BEHIND THE SCENE
The user of this plugin probably cares about what exactly happens behind the scene, and I am providing the technical detail now. Whenever there is a “transaction” – user action that results in change in the model – happening, Revit API allows access to three lists of element ids, which are elements that have been created, modified or deleted during this transaction. End User Assistant plugin (not this plugin) will temporarily record these lists of ids in RAM, for every transaction a user initiated. Whenever the user does a SAVE or SYNC , the plugin will first eliminate duplicated ids, then save them permanently into Revit file by creating a Data Storage element and then write history data into it. A Data Storage element a special element type that is only visible to Revit API, and its intention is to store external data for plugins. Every user will have his/her own Data Storage element so there will be no checking out conflict. Till now, all the job have been done by End User Assistant plugin. The reason of using a separate plugin is to ensure minimum performance impact.
What this plugin does is simply reading data from all users Data Storage elements, rearrange by time, and show the history in a table. It provides several filters to manage the displaying history data, and we can decide the way to combine these filters. To make tracking down history of individual element as easy as possible, the plugin will automatically update displaying data according to current Revit selection. In other words, if you just want to see the history of one specific element, simply select that element while the plugin is running, and the plugin will show only the history of that element.
The most notable and unsolvable issue of this plugin is the history of deleted elements. Revit API only provide Element Id information of a deleted element, and the End User Plugin can only record what Revit provides. There are ways, of course, to work around this limitation and get other information such as name and category, but will be at the expense of performance. Therefore, End User Plugin will only record Element Id, and leave everything else blank. This plugin will be able to show the Id, the time frame during which the element was deleted, and show everything else as “N/A”.
Another issue is the impact to the performance. The actual impact can be easily checked using End User Assistant. Every time it does anything, it records the time needed for it to do whatever it needs to do in the background. All the time records during an open Revit session are showed in a table, so the end user can decide whether needs to turn off one or more functions. The real-time recording of created/modified/deleted elements’ ids is probably the easiest thing a computer can do, so it is almost instant (should be showing 0.000 seconds). The permanent recording into Revit file is slightly less easy, but it only involves modification of only one element that is not connected to anything else in the model, so the time needed should also be close to nothing.
File Size Increase
Although one history item is pretty simple and only stores very minimum amount of data, the inter-connectivity of a Revit model means an editing to one element initiated by the user will often result in changes of many other related elements. Even though the plugin will eliminate all the duplicates before writing into the file, the amount of data will quickly accumulate, especially when the project is complex and there are a large team working on it. The good news is that the amount of stored data will not impact the performance, nor the time for loading the file since the data storage is always invisible. It will only impact the time for the plugin to filter through all the data and display those we want to see. This is another thing that a computer is best at, and I noticed minimum impact when I tested the plugin with a million randomly-generated history items.
Although it does not impact performance, most of time we don’t need to have a million history items reside in the model, while what we really need is just the most recent history items. This plugin lets you delete all items at once. You can use this function right after archiving your file, so the history data stays in the archived model.
As always, suggestions for future releases are most welcomed. Feel free to contact me if you want specific function in the plugin, or if your firm has special demands that could be best met by a more customized tool.
Special thanks to Ryan Borszich, for his ideas and suggestions on the development of this plugin.