// // (C) Copyright 2003-2019 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Windows.Forms; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Linq; using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Architecture; namespace Revit.SDK.Samples.RoomSchedule { /// /// Iterates through the rooms in the project and get the information of all the rooms /// public class RoomsData { #region Class Constant Variables /// /// Constant name for RoomID, this column must exist in first row. /// public const String RoomID = "ID"; /// /// Constant name for room area, this column must exist in first row /// public const String RoomArea = "Room Area"; /// /// Constant named for room name, this column must exist in first row /// public const String RoomName = "Room Name"; /// /// Constant name for room number, this column must exist in first row /// public const String RoomNumber = "Room Number"; /// /// Constant name for room number, this column must exist in first row /// public const String RoomComments = "Room Comments"; /// /// Constant name for shared parameter, /// the mapped room id of spread sheet will saved in this parameter. /// public const String SharedParam = "External Room ID"; #endregion #region Class Member Variables /// /// Active document to which this RoomsData instance belongs /// Document m_activeDocument; /// /// a list to store all rooms in the project /// List m_rooms = new List(); /// /// parameters which will be displayed in DataGridView /// List m_parameters = new List(); /// /// a list to store column names of Rooms /// List m_columnNames = new List(); #endregion #region Class Properties /// /// A list of all the rooms in the project /// public ReadOnlyCollection Rooms { get { return new ReadOnlyCollection(m_rooms); } } #endregion #region Class Constructor Method /// /// Constructor /// /// Revit project. public RoomsData(Document activeDocument) { m_activeDocument = activeDocument; // initialize the output parameters InitializeParameters(); // get all the rooms in the project GetAllRooms(activeDocument); } #endregion #region Class Public Methods /// /// Update rooms data after room creation happens in Revit /// public void UpdateRoomsData() { // clear all rooms and re-retrieve data from Revit m_rooms.Clear(); GetAllRooms(m_activeDocument); } /// /// Get all parameters to be displayed in DataGridView. /// /// all parameters specified by user. public void UpdateParameters(ReadOnlyCollection specifiedParams) { // if there is no instance, parameter setting is not allowed if (m_rooms.Count <= 0) { throw new Exception("No element instance to set parameters"); } // clear old parameters data m_parameters.Clear(); m_columnNames.Clear(); // get column names of room by specified parameters Room firstRoom = m_rooms[0]; foreach (BuiltInParameter param in specifiedParams) { // add this parameter m_parameters.Add(param); // store all specified parameter names of room. Parameter toomPara = firstRoom.get_Parameter(param); m_columnNames.Add(toomPara.Definition.Name); } } /// /// Generate all rooms which are located in specified level. /// A DataTable data object will be generated after this method call. /// /// the specified level to retrieve rooms /// DataTable generated from rooms public DataTable GenRoomsDataTable(Level level) { // get all Rooms information and generate a DataTable if (m_rooms.Count == 0) { return null; } // generate columns by all parameters DataTable newTable = new DataTable(); foreach (String col in m_columnNames) { DataColumn column = new DataColumn(); column.ColumnName = col; column.ReadOnly = true; column.DataType = System.Type.GetType("System.String"); newTable.Columns.Add(column); } // add constant column: External Room ID DataColumn constantCol = new DataColumn(); constantCol.ColumnName = SharedParam; constantCol.ReadOnly = true; constantCol.DataType = System.Type.GetType("System.String"); newTable.Columns.Add(constantCol); // filter rooms by level foreach (Room room in m_rooms) { // check whether room is located at specified level if ((null == level) || (m_activeDocument.GetElement(room.LevelId) != null && room.LevelId.IntegerValue == level.Id.IntegerValue)) { DataRow dataRow = newTable.NewRow(); for (int i = 0; i < m_parameters.Count; i++) { dataRow[i] = GetProperty(m_activeDocument, room, m_parameters[i], true); } // add constant column value: External Room ID Parameter param = null; bool bExist = ShareParameterExists(room, SharedParam, ref param); if (bExist && null != param && false == String.IsNullOrEmpty(param.AsString())) { dataRow[m_parameters.Count] = param.AsString(); } else { dataRow[m_parameters.Count] = ""; } // add this row newTable.Rows.Add(dataRow); } } return newTable; } /// /// Get the room property value according the parameter name /// /// Current active document. /// an instance of room class /// the parameter used to get parameter value /// convert parameter to value type or not. /// if true, the value of parameter will be with unit. /// if false, the value of parameter will be without unit. /// the string value of property specified by shared parameter public static String GetProperty(Document activeDoc, Room room, BuiltInParameter paraEnum, bool useValue) { String propertyValue = null; //the value of parameter // Assuming the build in parameter is legal for room. // if the room is not placed, some properties are not available, i.g. Level name, Area ... // trying to retrieve them will throw exception; // however some parameters are available, e.g.: name, number Parameter param; try { param = room.get_Parameter(paraEnum); } catch (Exception) { // throwing exception for this parameter is acceptable if it's a unplaced room if (null == room.Location) { propertyValue = "Not Placed"; return propertyValue; } else { throw new Exception("Illegal built in parameter."); } } // get the parameter via the built in parameter if (null == param) { return ""; } // get the parameter's storage type and convert parameter to string StorageType storageType = param.StorageType; switch (storageType) { case StorageType.Integer: int iVal = param.AsInteger(); propertyValue = iVal.ToString(); break; case StorageType.String: propertyValue = param.AsString(); break; case StorageType.Double: // AsValueString will make the return string with unit, it's appreciated. if (useValue) { propertyValue = param.AsValueString(); } else { propertyValue = param.AsDouble().ToString(); } break; case StorageType.ElementId: Autodesk.Revit.DB.ElementId elemId = param.AsElementId(); Element elem = activeDoc.GetElement(elemId); propertyValue = elem.Name; break; default: propertyValue = param.AsString(); break; } return propertyValue; } /// /// Check to see whether specified parameter exists in room object. /// /// Room object used to get parameter /// parameter name to be checked /// shared parameter returned /// true, the parameter exists; false, the parameter doesn't exist public static bool ShareParameterExists(Room roomObj, String paramName, ref Parameter sharedParam) { // get the parameter try { sharedParam = roomObj.LookupParameter(paramName); } catch { } return (null != sharedParam); } #endregion #region Class Implementation /// /// Get all rooms in current Revit project /// private void GetAllRooms(Document activeDoc) { // get all room elements // try to find all rooms in the project and add to the list RoomFilter filter = new RoomFilter(); FilteredElementCollector collector = new FilteredElementCollector(activeDoc); m_rooms = collector.WherePasses(filter).ToElements().Cast().ToList(); // sort rooms by number m_rooms.Sort(CompRoomByNumber); } /// /// Sort the rooms by number /// /// /// /// private static int CompRoomByNumber(Room room1, Room room2) { if (null == room1 || null == room2) { return -1; } return room1.Number.CompareTo(room2.Number); } /// /// Initialize the parameters displayed in DataGridView control /// private void InitializeParameters() { // Room name m_parameters.Add(BuiltInParameter.ROOM_NAME); m_columnNames.Add("Name"); // Room Number m_parameters.Add(BuiltInParameter.ROOM_NUMBER); m_columnNames.Add("Number"); // Room Area m_parameters.Add(BuiltInParameter.ROOM_AREA); m_columnNames.Add("Area"); // Room Comments m_parameters.Add(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS); m_columnNames.Add("Comments"); // Level m_parameters.Add(BuiltInParameter.LEVEL_NAME); m_columnNames.Add("Level"); // Phase m_parameters.Add(BuiltInParameter.ROOM_PHASE); m_columnNames.Add("Phase"); } #endregion } }