Technical

Show who modified an element last in Revit

In Revit, don’t you ever wish you could find out who was guilty of screwing over your completely pristine BIM model? In software, we run special tracking software so that we can monitor the history of every single line of code, and blame whoever messed it up (literally, the program is called git blame). Although in the architecture industry we don’t quite have this same fidelity of tracking (well, sort of, more on that later), it’s still possible to find out who touched any Revit element last so we can interrogate them.

Finding out who last modified an element or created an element is actually a native Revit feature, but it is not very exposed on the user interface. First, I’ll show you how to check it via the interface, and then I’ll show you how to create a macro to check it from any view. I’ll then also show you how to check the history of less obvious Revit elements, like who last modified the view template.

To do this, we are assuming there is a central Revit file and people are checking out local copies of it. We are also assuming that everybody has different Revit usernames. You can check your Revit username by going to Menu->Options->General->Username.

Revit username option

Then, turn on a worksharing mode. Any of the four available modes have this feature, so pick any that you’d like.

Revit worksharing display mode options

Once the mode is enabled, just hover over any element in your view, and a Revit tooltip will appear showing various information about who created it, who owns it, and who touched it last. I’ve censored it so you can’t see who’s guilty.

Revit last updated tooltip

This is great and really easy. However to make things even easier I’ve written a macro that will allow you to click on any element without haven’t to first switch display modes, and then it’ll tell you who touched it last.

Go into the Manage tab and click on Macro Manager. Create a new Module in Python, and dump the following code:

def Blame(self):
    select = self.Application.ActiveUIDocument.Selection
    el = self.Application.ActiveUIDocument.Document.GetElement(select.PickObject(ObjectType.Element, 'Get element'))
    info = WorksharingUtils.GetWorksharingTooltipInfo(self.Application.ActiveUIDocument.Document, el.Id)
    TaskDialog.Show('Blame', 'Created by: ' + str(info.Creator) + '\nLast changed by: ' + str(info.LastChangedBy))

Press F8 to compile the macro, then run it in the macro manager. After clicking any element, you’ll see a dialog box pop up. I like to assign a keyboard shortcut to the macro manager to make this very quick to do.

If you feel the need to see the history of another less obvious / clickable element (say, a view template), you will need to first get its element ID. This is an integer that all elements in Revit have (note: it is not the GUID, which is a related but different thing). Using tools that allow you to query or browse the BIM database such as plugins provided by Ideate allow you to find out these element IDs.

Once you have the element ID, you can substitute the element acquisition line in the code above with the below snippet, where XXXXXXXX is your element ID:

el = self.Application.ActiveUIDocument.Document.GetElement(ElementId(XXXXXXXX))

There you have it – it’s all fun and games until you realise that half the screw-ups are your own fault :)

Technical

In order to discuss BDD, as a blogger, I need to talk about Behat

If you’re developing a web application, especially one that uses PHP, you should know about Behat.

Behat introduces itself as “a php framework for testing your business expectations”. And it does exactly that. You write down your business expectations of the application, and it automatically tests whether or not your application achieves them.

You begin every feature description with a three liner following the form:

[sourcecode]
Feature: Foo bar
In order to … (achieve what goal?)
As a … (what target audience?)
I need to … (use what feature?)
[/sourcecode]

This is then split up into individual scenarios of using this feature, all of which are described using natural English following the Gherkin syntax. It then uses Mink which is a browser abstraction layer to run these tests.

I’ve been enjoying Behat for quite some time now, and I’ve noticed certain tests I need to write that come up again and again which aren’t included in the default Mink definitions.

The first is to check whether or not an element is visible. These days, Javascript heavy UIs use a lot of hiding and showing, and often this is vital to the business expectations of how the website should work. These sorts of tests need a non-headless browser emulator, such as Sahi. Simply prefix your test with the line @mink:sahi, and now we can use the following definition:

[php]
/**
* @Then /^"([^"]*)" should be visible$/
*/
public function shouldBeVisible($selector)
{
$element = $this->getSession()->getPage()->find(‘css’, $selector);
if (empty($element))
throw new Exception(‘Element "’.$selector.’" not found’);

    $display = $this->getSession()->evaluateScript(
        'jQuery("'.$selector.'").css("display")'
    );

    if ($display === 'none')
        throw new Exception('Element "'.$selector.'" is not visible');
}

[/php]

… so you can now write …

[sourcecode]
Then "div" should be visible
[/sourcecode]

Worth highlighting is the ->evaluateScript() function that is being called. This means that anything you can check with JQuery can be tested. This is pretty much everything.

Another useful query is dealing with images. Modern web apps have to handle image uploading quite a bit, and often this comes with resizing or cropping (for avatars, keeping to layout widths, thumbnails). Wouldn’t it be great if you could just write…

[sourcecode]
Given I have an image with width "500" and height "400" in "/tmp/foo.png"
Then the "img" element should display "/tmp/foo.png"
And the "img" element should be "500" by "400" pixels
[/sourcecode]

… and of course, now you can. All this code is included in vtemplate under the FeatureContext file.

Happy testing!