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();
}
}
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
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.
Hi Vadim,
Did you make a Document macro or Application macro? The code I am posting on this blog is for Application macros. I wrote a bit about document and application macros at
https://boostyourbim.wordpress.com/2012/12/05/macros-vs-add-ins-whats-the-difference/
Regards
Harry
Yes, that was the problem. I made it a Document instead of Application. It works great now. Thank you very much.
[…] some of them out and using the method explained above, add them to your Revit application editor. Using 3D Section Box to set Plan View’s View Range, Divide Parts at Levels, Creating a Void to Cut […]
hi, i am trying this but get x2 } expected (CS1513) errors
Hi James,
It might help to make sure that you can compile a simple macro with no errors first. This would make it easier to check that the open and closed curly brackets are properly balanced. Then try pasting this code into the macro source.
Harry
thanks, will give it ago, only just started on macros so a lot to learn, i have tried a few examples on here…all with the same error so i am doing something wrong!
Hopefully this post might help – https://boostyourbim.wordpress.com/2013/05/01/create-a-simple-macro-in-revit-2014/ Or if you are interested in building a strong foundation of API skills, please take a look at my course at https://www.udemy.com/revitapi/?couponCode=%2425off-4158ef98
🙂 i just made that macro! although at present im using 2013 till our company installs 2014 and clients require it. I will look at the course to, as im really interested in exploring this part of Revit (i have been a Revit user for over 6 years and now want to get into the nitty gritty of it)
If you are using 2013, keep in mind that 2014 adds a default set of “using” statements that you will have to manually add in 2013. https://boostyourbim.wordpress.com/2012/12/23/using-statements/
thank you, got it working by adding some using statements at the beginning and got the bug now
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