Saturday, May 28, 2011

An oddity with Drafting View mirroring

So I was asked if it was possible to mirror a drafting view using the API (apparently the built-in project mirroring doesn't cover drafting views).

It seemed straightforward enough... so I wrote a quick test... and it didn't work...
- it worked fine in a floor plan view
- it didn't work in a drafting view
- the code completed just fine - it just didn't really seem to show any difference.

My initial code is below...
- Get all the elements in the current view
- Use the new ElementTransformUtil class to figure out which could be mirrored, and mirror them.

FilteredElementCollector coll =
new FilteredElementCollector(uiDoc.Document, uiDoc.ActiveView.Id);

IList elems = coll.ToElements();

// make sure that stuff can be mirrored
List toMirror = new List();

foreach (Element elem in elems)
if (ElementTransformUtils.CanMirrorElement(uiDoc.Document, elem.Id) == false) continue;

So why did this complete successfully, but not show any difference?
The answer is one of those great undocumented elements in the wilds of the Revit database. When I looked in the debugger at what I was actually attempting to mirror, I saw this:

What I see here is a mystery element called "ExtentElem" which is being copied. I have a sneaking suspicion that it might be telling the view the actual extent of what is in it... So how can we exclude it? well - it has no actual category (which is probably a sign that in general we don't want to mirror an element like that!).

So - we add a line like:

if (elem.Category == null) continue;

and voila! we have our drafting view being mirrored.

I wish that I could say that all Revit database mysteries are "easily" solvable like this - there's plenty of times where you just run into a wall, and can't get to what you want... but today's story has a happy ending!


Jason G said...

Matt, where did you add the "if (elem.Category == null) continue;" to your script.

Matt Mason said...

Sorry I should have been more specific. Inside the for loop, right above the "if" test for whether Revit thinks it can mirror it. So it looks like:

foreach (Element elem in elems)
if (elem.Category == null) continue;
if (ElementTransformUtils.CanMirrorElement(uiDoc.Document, elem.Id) == false) continue;

Jason G said...

Next question could the code be written to mirror multile views at once.

Matt Mason said...

Sure. Standard Revit API.

Jason G said...

Is there a way to iterate thru the drafting views in a project, and mirror each one of them. I really dont want to open each drafting views one at a time and then run the addin.

Matt Mason said...

Sure - pretty easy Revit API stuff to do a collector and iterate thru.