Setting viewport location on sheet

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi everyone,
These last few day I've been struggling with the exact location of a viewport.
At first glance it looked easy enough, just get the boxcenter of the viewport and move it to the inverted XYZ of the boxcenter. (Titleblock center = XYZ(0,0,0)).
This did work in some projects but not in others (I've literally no idea why).
With RevitLookup I checked if the boxcenter equals the viewport.GetBoxCenter(). (Same with BoundingBox and BoxOutlines)
To my suprise it isn't the same.
Hope somebody can set me in the right direction.
This is my script, and attached you will find the .rvt file in Revit 2019.
It works with the Detail Component (00_BIB_Viewport_A3_liggend.rfa) already loaded in Floorplan "begane grond" and Section A. Simply run the script and select the family. It should automatically create a sheet and place the view.
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using BimBuildings.Util;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using View = Autodesk.Revit.DB.View;
namespace BimBuildings
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
class DetailsOnSheets : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
#region//Utils
StringBuilder sb = new StringBuilder();
LengthUnitConverter converter = new LengthUnitConverter();
Collector collector = new Collector();
#endregion
#region//Application context.
var uidoc = commandData.Application.ActiveUIDocument;
var doc = uidoc.Document;
#endregion
#region//Get view
ElementId viewId = doc.ActiveView.Id;
View view = doc.ActiveView;
#endregion
#region//Get element
Reference selectionRef;
try
{
selectionRef = uidoc.Selection.PickObject(ObjectType.Element, "Select one textnote.");
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
return Result.Cancelled;
}
Element element = doc.GetElement(selectionRef);
FamilyInstance familyInstance = element as FamilyInstance;
#endregion
#region//Get detail name from Mark
string detailName = familyInstance.LookupParameter("Mark").AsString();
if(detailName == null)
{
Message.Display("Please fill in a Mark", WindowType.Warning);
return Result.Cancelled;
}
#endregion
#region//Get Light lines in family
Options options = new Options();
options.IncludeNonVisibleObjects = true;
options.ComputeReferences = true;
options.View = doc.ActiveView;
List<LineEndPointData> lineData = new List<LineEndPointData>();
List<Curve> lines = new List<Curve>();
var geoElement = element.get_Geometry(options);
foreach (var item in geoElement)
{
GeometryInstance geoInstance = item as GeometryInstance;
foreach(var o in geoInstance.GetInstanceGeometry())
{
Line line = o as Line;
if (line != null)
{
GraphicsStyle gStyle = doc.GetElement(line.GraphicsStyleId) as GraphicsStyle;
if (gStyle != null)
{
if(gStyle.GraphicsStyleCategory.Name == "Light Lines")
{
lineData.Add(new LineEndPointData() { line = line, endPoint0 = line.GetEndPoint(0), endPoint1 = line.GetEndPoint(1) });
}
}
}
}
}
#endregion
#region//Reorder lines to form enclosed loop
lines.Add(lineData[0].line);
while(lines.Count < lineData.Count)
{
foreach (LineEndPointData data in lineData)
{
if (lines[lines.Count - 1].GetEndPoint(1).ToString() == data.endPoint0.ToString())
{
lines.Add(data.line);
break;
}
}
}
#endregion
#region//Get sheetnumber
int newsheetnumber;
foreach (Match m in Regex.Matches(detailName, @"\d"))
{
sb.Append(m);
}
if(view.ViewType == ViewType.FloorPlan)
{
newsheetnumber = int.Parse(sb.ToString()) + 450;
}
else
{
newsheetnumber = int.Parse(sb.ToString()) + 400;
}
#endregion
#region//Check if sheetnumber already exists
List<Element> sheets = new FilteredElementCollector(doc).OfClass(typeof(ViewSheet)).ToElements().ToList();
List<int> sheetnumbers = new List<int>();
foreach (Element e in sheets)
{
ViewSheet sheet = e as ViewSheet;
sheetnumbers.Add(int.Parse(sheet.LookupParameter("Sheet Number").AsString()));
}
if(sheetnumbers.Contains(newsheetnumber))
{
Message.Display("Sheetnumber is already in use. Please enter a different Mark", WindowType.Error);
return Result.Cancelled;
}
#endregion
#region//Get Titleblock
List<Element> titleBlocks = collector.GetTitleBlocks(doc);
ElementId titleBlock = null;
foreach(Element tb in titleBlocks)
{
if(tb.Name.StartsWith("A3 liggend"))
{
titleBlock = tb.Id;
}
}
if(titleBlock == null)
{
Message.Display("Can't find TitleBlock 'A3 liggend'", WindowType.Warning);
return Result.Cancelled;
}
#endregion
using (Transaction tx = new Transaction(doc))
{
tx.Start("Create Duplicated View");
#region//Setting scale to 1:5
view.Scale = 5;
#endregion
#region//Duplicate view as dependent
ElementId duplicatedViewId = doc.ActiveView.Duplicate(ViewDuplicateOption.AsDependent);
View duplicatedView = doc.GetElement(duplicatedViewId) as View;
duplicatedView.Name = detailName;
#endregion
#region//Hide categories in duplicated view
duplicatedView.SetCategoryHidden(Category.GetCategory(doc, BuiltInCategory.OST_Site).Id, true);
duplicatedView.SetCategoryHidden(Category.GetCategory(doc, BuiltInCategory.OST_Grids).Id, true);
#endregion
#region//Setting CropBox shape
CurveLoop cl = CurveLoop.Create(lines);
ViewCropRegionShapeManager vpcr = duplicatedView.GetCropRegionShapeManager();
bool cropValid = vpcr.IsCropRegionShapeValid(cl);
if(cropValid)
{
vpcr.SetCropShape(cl);
vpcr.BottomAnnotationCropOffset = converter.ConvertToFeet(3);
vpcr.LeftAnnotationCropOffset = converter.ConvertToFeet(3);
vpcr.RightAnnotationCropOffset = converter.ConvertToFeet(3);
vpcr.TopAnnotationCropOffset = converter.ConvertToFeet(3);
}
else
{
Message.Display("The given CropBox shape isn't valid. Please try again", WindowType.Error);
return Result.Cancelled;
}
#endregion
#region//Create sheet
ViewSheet sheet = ViewSheet.Create(doc, titleBlock);
sheet.Name = "Detail " + detailName;
sheet.LookupParameter("Sheet Number").Set(newsheetnumber.ToString());
ElementId sheetId= sheet.Id;
#endregion
#region//Place viewport on sheet
Viewport.Create(doc, sheetId, duplicatedViewId, XYZ.Zero);
Viewport viewport = doc.GetElement(sheet.GetAllViewports().First()) as Viewport;
//viewport.ChangeTypeId(viewPortTypeId);
BoundingBoxXYZ boxXYZ = viewport.get_BoundingBox(sheet);
TaskDialog.Show("INFO", min + "\n" + max);
XYZ boxCenter = viewport.GetBoxCenter();
Outline outline = viewport.GetBoxOutline();
#endregion
tx.Commit();
}
return Result.Succeeded;
}
}
}