One of my main goals with RevitPythonShell is to provide a handy environment for exploring the Autodesk Revit API. But anyone seriously interested in exploring the Revit API should also be familiar with RevitLookup, formally known as RvtMgdDbg. This tool can be found in the SDK and includes a handy command for "snooping" a selected element called "Snoop Current Selection...". I use this so often, that I created a keyboard shortcut to invoke it. It provides vital information for working with Revit objects - information you probably want access to while inside an interactive RPS shell!
Unfortunately, you can't execute plugins while inside the RPS shell. Well, not through the Revit UI. You can access them via code. This blog is about a simple little module I wrote that let's you do this anywhere inside the shell:
>>>import revitsnoop >>>snooper = revitsnoop.RevitSnoop(__revit__) >>>snooper.snoop(doc.ProjectInformation)
And have a dialog like this popped up:
Notice how you specify the object you want to snoop in code, as opposed to having to select it in the UI. Pretty nifty, eh?
How it works
The Autodesk.Revit.UI.UIApplication object has a property LoadedApplications that returns a list of all loaded external applications. As long as you have RevitLookup installed (quick test: can you find it in the Add-Ins tab?), it will show up in this list. It is pretty easy to find it:
rlapp = [app for app in uiApplication.LoadedApplications if app.GetType().Namespace == 'RevitLookup' and app.GetType().Name == 'App']
I can't test with isinstance, since RPS doesn't know about RevitLookup yet and therefore I can't name the type. That is why I used GetType() and compared the namespace and name of the type.
Once we have the type, though, we can load the assembly and import RevitLookup as a module into IronPython:
import clr clr.AddReference(rlapp.GetType().Assembly) import RevitLookup
The statement import RevitLookup will only work after adding a reference to the assembly, but afterwards, we can start using the classes inside. To figure out what had to be done, I checked the source for RevitLookup, specifically the ExternalCommand that implements the "Snoop Current Selection..." functionality: RevitLookup.CmdSnoopModScope. It would have been possible to create an instance of this class and call its Execute method, but it turned out to be quicker and easier to just implement the body myself:
# See note in CollectorExt.cs in the RevitLookup source: RevitLookup.Snoop.CollectorExts.CollectorExt.m_app = __revit__ # create a list of elements to snoop elementSet = ElementSet() elementSet.Insert(doc.ProjectInformation) # create and show the dialog form = RevitLookup.Snoop.Forms.Objects(elementSet) form.ShowDialog()
This code is wrapped up in a module called revitsnoop for your convenience in the RevitPythonShell download section. To use it, place it inside one of the search paths configured in RPS.
For completeness sake, here is the whole module:
''' revitsnoop.py a simple library to access the RevitLookup snoop functionality while inside the interactive shell... ''' import clr from Autodesk.Revit.DB import ElementSet class RevitSnoop(object): def __init__(self, uiApplication): ''' for RevitSnoop to function properly, it needs to be instantiated with a reverence to the Revit Application object. ''' # find the RevitLookup plugin rlapp = [app for app in uiApplication.LoadedApplications if app.GetType().Namespace == 'RevitLookup' and app.GetType().Name == 'App'] # tell IronPython about the assembly of the RevitLookup plugin clr.AddReference(rlapp.GetType().Assembly) import RevitLookup self.RevitLookup = RevitLookup # See note in CollectorExt.cs in the RevitLookup source: self.RevitLookup.Snoop.CollectorExts.CollectorExt.m_app = uiApplication def snoop(self, element): elementSet = ElementSet() elementSet.Insert(element) form = self.RevitLookup.Snoop.Forms.Objects(elementSet) form.ShowDialog()
I think a logical further improvement would be to add some methods (e.g. snoopDocument and snoopApplication) for accessing the other useful functions of RevitLookup. But by now you should already know how to do it yourself!