Setting viewport location on sheet

Setting viewport location on sheet

Anonymous
Not applicable
3,219 Views
2 Replies
Message 1 of 3

Setting viewport location on sheet

Anonymous
Not applicable

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;
        }
    }
}

 

0 Likes
3,220 Views
2 Replies
Replies (2)
Message 2 of 3

naveen.kumar.t
Autodesk Support
Autodesk Support

Hi @Anonymous ,

These below links will help you to understand the viewport position

https://thebuildingcoder.typepad.com/blog/2013/08/setting-the-exact-view-location-on-a-sheet.html 

https://thebuildingcoder.typepad.com/blog/2010/09/view-location-on-sheet.html 


Naveen Kumar T
Developer Technical Services
Autodesk Developer Network

0 Likes
Message 3 of 3

KEVIN_W_MAK_WSP
Participant
Participant

I used the following code to move a new viewport to a control location.

// New viewport bounding box.
BoundingBoxXYZ newViewportBoundingBox = newViewport.get_BoundingBox(newSheet);

// I use the top-right corner as viewport control point, not the box center.
XYZ newViewportTopRightCorner = newViewportBoundingBox.Max;

// Move viewport.
ElementTransformUtils.MoveElement(doc, newViewport.Id, new XYZ(
controlTopRightCorner.X - newViewportTopRightCorner.X,
controlTopRightCorner.Y - newViewportTopRightCorner.Y,
0));

0 Likes