Thursday, May 31, 2012

Which way am I looking?

One of the somewhat obscure but interesting features that I had been looking forward to in the Revit 2013 API, I finally got a chance to use recently when updating our Scan To BIM for Revit application.

That is - you can finally look at the ViewRange settings for a particular plan view. Now, there are a thousand posts out there about how View Range works, and I think you can also ask a hundred Revit users and get at least 30 different answers. The truth is, there are a LOT of complications to it.

From the API persective, there are 5 kinds of PlaneViewPlanes:

  • Top Clip Plane
  • Cut Plane
  • Bottom Clip Plane
  • View Depth Plane
  • Underlay Bottom Plane
Finding out the ViewRange is pretty easy:

PlanViewRange range = myPlanView.GetViewRange();
// for a given plane, find the associated level and offset
ElementId cutLevelId = range.GetLevelId( PlanViewPlane.CutPlane );
double cutLevelOffset = range.GetOffset( PlanViewPlane.CutPlane );
Of course, you can set the view range data as well.

The Real Reason For My Post: View Direction

This is all well and good, but now we come to the REAL reason for my post. As happens so often within the Revit API, you think you can see the way to get from point A to point B and accomplish your mission. And then you are blindsided by some strange Revit complexity that you might have heard about, but had not dealt with before.

The fundamental problem I was trying to solve was to identify what parts of a point cloud were visible in the Plan View. Much of this you can determine from the the PlanViewRange, shown above. But it soon became clear that there was a bit more to it than that. As you may know, Plan Views may face upwards or downwards within Revit. That is to say - a FloorPlan is always "looking down" at the floor - but a Reflected Ceiling Plan or Mechanical Plan is always "looking up" at the ceiling. Apparently structural views could not be decided, so you can actually edit the setting on the view type to be up or down for a model.

I had originally guessed that the ViewDirection property would be a different vector to represent the direction that you're looking ... but that's not the case. So - if you have to know the direction, how do you find it?

It hinges upon the ViewFamilyType (this concept existed as an Element in 2012, but has a fully exposed class in 2013 - so you wouldn't have been stuck in 2012). Views all derive from a ViewFamilyType. Inside the ViewFamilyType, there is a hidden BuiltInParameter (it's only a visible parameter on the aforementioned Structural ViewType). 

 // determine the view direction
ElementId vftId = vp.GetTypeId();
Element vft = vp.Document.GetElement(vftId);
if (vft == null) throw new ArgumentException("Unable to find view family type for view: " + vp.Name);
Parameter viewDirParam = vft.get_Parameter(BuiltInParameter.PLAN_VIEW_VIEW_DIR);

So once you have that, you're all set - the parameter tells you, for your view, whether you're looking up or down.

It's obscure, but as always, I hope you stumble upon this when it's useful to you!