Using 3D Section Box to set Plan View’s View Range

I was asked if it was possible to set the view range of a floor plan to match the top and bottom extents of a 3d section box. Yes, it is, and here is a little video showing it in action.

  • The view on the left is the 3D view with Section Box
  • The view on the right is the plan view
  • Change the top or bottom of the section box
  • Switch to the plan view
  • Run the macro and the view range is updated
public void SetViewRange()
{
    Document doc = this.ActiveUIDocument.Document;

    // Get the active view and cast it to a ViewPlan (the API's class for Plan View)
    ViewPlan viewPlan = doc.ActiveView as ViewPlan;

    // Error handling in case the active view is not a plan view
    if (viewPlan == null)
    {
        TaskDialog.Show("Error", "Active view must be a plan view.");
        // return ends the execution of the macro
        return;
    }

    // Get the level that generates the plan view
    Level level = viewPlan.GenLevel;

    View3D view3d = null;
    try
    {
        // if there is no 3D view whose name equals viewPlan.Name, then First() will throw an exception
        view3d = (from v in new FilteredElementCollector(doc).OfClass(typeof(View3D)).Cast<View3D>() where v.Name == viewPlan.Name select v).First();
    }
    catch
    {
        TaskDialog.Show("Error", "There is no 3D view named '" + viewPlan.Name + "'");
        return;
    }

    // Get the BoundingBoxXYZ (a 3D rectangular box) that describes the shape of the Section Box
    BoundingBoxXYZ bbox = view3d.SectionBox;

    // The coordinates of the bounding box are defined relative to a coordinate system specific to the bounding box
    // When setting the view range offsets, the values will need to be relative to the model 

    // This transform translates from coordinate system of the bounding box to the model coordinate system
    Transform transform = bbox.Transform;
    // Transform.Origin defines the origin of the bounding box's coordinate system in the model coordinate system
    // The Z value indicates the vertical offset of the bounding box's coordinate system
    double bboxOriginZ = transform.Origin.Z;

    // BoundingBoxXYZ.Min.Z and BoundingBoxXYZ.Max.Z give the Z values for the bottom and top of the section box
    // Adding the Transform.Origin.Z converts the value to the model coordinate system
    double minZ = bbox.Min.Z + bboxOriginZ;
    double maxZ = bbox.Max.Z + bboxOriginZ;

    // Get the PlanViewRange object from the plan view
    PlanViewRange viewRange = viewPlan.GetViewRange();

    // Set all planes of the view range to use the plan view's level
    viewRange.SetLevelId(PlanViewPlane.TopClipPlane, level.Id);
    viewRange.SetLevelId(PlanViewPlane.CutPlane, level.Id);
    viewRange.SetLevelId(PlanViewPlane.BottomClipPlane, level.Id);
    viewRange.SetLevelId(PlanViewPlane.ViewDepthPlane, level.Id);

    // Set the view depth offset to the difference between the bottom of the section box and
    // the elevation of the level
    viewRange.SetOffset(PlanViewPlane.ViewDepthPlane, minZ - level.Elevation);

    // Set all other offsets to to the difference between the top of the section box and
    // the elevation of the level
    viewRange.SetOffset(PlanViewPlane.TopClipPlane, maxZ - level.Elevation);
    viewRange.SetOffset(PlanViewPlane.CutPlane, maxZ - level.Elevation);
    viewRange.SetOffset(PlanViewPlane.BottomClipPlane, maxZ - level.Elevation);

    using (Transaction t = new Transaction(doc, "Set View Range"))
    {
        t.Start();
        // Set the view range
        viewPlan.SetViewRange(viewRange);
        t.Commit();
    }
}
Advertisements

15 thoughts on “Using 3D Section Box to set Plan View’s View Range

  1. Thanks so much for this! Amazing! I wanted to ask, how can it be taken a step further to include Cut Plane? The macro works great for Piping but when I try the same for Receptacles, they disappear and then I have to go in and manually adjust the cut plane. Don’t get me wrong I think this tool is superb!

    • Hi Armando,

      Glad you like it! The cut plane is set with this line.

      viewRange.SetOffset(PlanViewPlane.CutPlane, maxZ – level.Elevation);

      In this implementation the top, bottom, and cut planes all have the same value. What different value would you like the cut plane to have?

      Regards
      Harry

  2. Thank you for the tool.
    I keep getting the message “‘SetViewRange.ThisDocument’ does not contain a definition for ‘ActiveUIDocument’ and no extension method ‘ActiveUIDocument’ accepting a first argument of type ‘SetViewRange.ThisDocument’ could be found (are you missing a using directive or an assembly reference?) (CS1061)
    I pasted all “using” statements from your previous posts and nothing helps.

  3. I keep getting 3 errors cs1518 and cs1033 in Revit 2015 any advice.
    I’m just doing copy paste because i know nothing about Macros.
    please help me make this work

    Thanks

    • In 2014, Autodesk obsoleted the View3D.SectionBox Property with the comment “Use View3D.GetSectionBox() or View3D.SetSectionBox() instead.” In 2015, View3D.SectionBox has been removed, so this line must be changed:
      BoundingBoxXYZ bbox = view3d.SectionBox;
      to
      BoundingBoxXYZ bbox = view3d.GetSectionBox();

      But it seems that there might also be a mismatch in your { and } characters. https://boostyourbim.wordpress.com/2013/05/01/create-a-simple-macro-in-revit-2014/ might help, or if you are interested in building a strong foundation of API skills, please take a look at my course at bitly.com/revitapi

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s