using System; using System.Collections.Generic; using System.Collections; using System.Text; using System.Windows.Forms; using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.Collections; namespace RevitLookup.Test.SDKSamples.CreateSheet { public class Views { private ViewSet m_allViews = new ViewSet(); private ViewSet m_selectedViews = new ViewSet(); private FamilySymbol m_titleBlock = null; private FamilySymbolSet m_allTitleBlocks = new FamilySymbolSet(); private ArrayList m_titleBlockNames = new ArrayList(); private string m_sheetName = null; private double m_rows = 0; private double TITLEBAR = 0.2; private double GOLDENSECTION = 0.618; /// /// Constructor of views object. /// /// the active document public Views(Document doc) { m_allViews = Utils.View.GetAllViews(doc); GetTitleBlocks(doc); } /// /// Tree node store all views' names. /// public ViewSet AllViews { get { return m_allViews; } } /// /// List of all title blocks' names. /// public ArrayList TitleBlockNames { get { return m_titleBlockNames; } } /// /// The selected sheet's name. /// public string SheetName { get { return m_sheetName; } set { m_sheetName = value; } } /// /// Set the views to generate from a list of ViewNames. /// public void SetSelectViewsFromNames(ArrayList viewNames) { foreach (Autodesk.Revit.DB.View v in m_allViews) { foreach (string s in viewNames) { if (s.Equals(v.Name)) { m_selectedViews.Insert(v); break; } } } } /// /// Generate sheet in active document. /// /// the currently active document public void GenerateSheet(Document doc) { if (0 == m_selectedViews.Size) { MessageBox.Show("No view was selected, sheet generation cancelled."); return; } ViewSheet sheet = doc.Create.NewViewSheet(m_titleBlock); sheet.Name = m_sheetName; PlaceViews(m_selectedViews, sheet); } /// /// Retrieve the title block to be generate by its name. /// /// The title block's name public void SetTitleBlock(string name) { foreach (FamilySymbol f in m_allTitleBlocks) { if (name.Equals(f.Name)) { m_titleBlock = f; return; } } } /// /// Retrieve all available title blocks in the currently active document. /// /// the currently active document private void GetTitleBlocks(Document doc) { m_allTitleBlocks = doc.TitleBlocks; if (0 == m_allTitleBlocks.Size) { throw new Exception("There is no title block to generate sheet."); } foreach (FamilySymbol f in m_allTitleBlocks) { m_titleBlockNames.Add(f.Name); if (null == m_titleBlock) { m_titleBlock = f; } } } /// /// Place all selected views on this sheet's appropriate location. /// /// all selected views /// all views located sheet private void PlaceViews(ViewSet views, ViewSheet sheet) { double xDistance = 0; double yDistance = 0; CalculateDistance(sheet.Outline, views.Size, ref xDistance, ref yDistance); UV origin = GetOffset(sheet.Outline, xDistance, yDistance); UV temp = new UV(origin.U, origin.V); int n = 1; foreach (Autodesk.Revit.DB.View v in views) { UV location = new UV(temp.U, temp.V); Autodesk.Revit.DB.View view = v; Rescale(view, xDistance, yDistance); sheet.AddView(view, location); if (0 != n++ % m_rows) { temp = new UV( temp.U + xDistance * (1 - TITLEBAR), temp.V ); } else { temp = new UV( origin.U,temp.V + yDistance); } } } /// /// Retrieve the appropriate origin. /// /// The 2D outline of the sheet /// The appropriate origin private UV GetOffset(BoundingBoxUV bBox, double x, double y) { return new UV(bBox.Min.U + x * GOLDENSECTION, bBox.Min.V + y * GOLDENSECTION); } /// /// Calculate the apropriate distance between the views lay on the sheet. /// /// The outline of sheet. /// Amount of views. /// Distance in x axis between each view /// Distance in y axis between each view private void CalculateDistance(BoundingBoxUV bBox, int amount, ref double x, ref double y) { double xLength = (bBox.Max.U - bBox.Min.U) * (1 - TITLEBAR); double yLength = (bBox.Max.V - bBox.Min.V); //calculate appropriate rows numbers. double result = Math.Sqrt(amount); while (0 < (result - (int)result)) { amount = amount + 1; result = Math.Sqrt(amount); } m_rows = result; double area = xLength * yLength / amount; //calculate appropriate distance between the views. if (bBox.Max.U > bBox.Max.V) { x = Math.Sqrt(area / GOLDENSECTION); y = GOLDENSECTION * x; } else { y = Math.Sqrt(area / GOLDENSECTION); x = GOLDENSECTION * y; } } /// /// Rescale the view's Scale value for suitable. /// /// The view to be located on sheet. /// Distance in x axis between each view /// Distance in y axis between each view private void Rescale(Autodesk.Revit.DB.View view, double x, double y) { double Rescale = 2; UV outline = new UV(view.Outline.Max.U - view.Outline.Min.U, view.Outline.Max.V - view.Outline.Min.V); if (outline.U > outline.V) { Rescale = outline.U / x * Rescale; } else { Rescale = outline.V / y * Rescale; } if (1 != view.Scale) { view.Scale = (int)(view.Scale * Rescale); } } } }