// // (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. // namespace Revit.SDK.Samples.FrameBuilder.CS { using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.ApplicationServices; using ModelElement = Autodesk.Revit.DB.Element; /// /// create columns, beams and braces to create framing /// public class FrameBuilder { FrameData m_data; // necessary data to create frame Autodesk.Revit.Creation.Document m_docCreator; // buffer of API object Autodesk.Revit.Creation.Application m_appCreator; // buffer of API object /// /// constructor /// /// data necessary to initialize object public FrameBuilder(FrameData data) { // initialize members if (null == data) { throw new ArgumentNullException("data", "constructor FrameBuilder(FrameData data)'s parameter shouldn't be null "); } m_data = data; m_appCreator = data.CommandData.Application.Application.Create; m_docCreator = data.CommandData.Application.ActiveUIDocument.Document.Create; } /// /// create framing according to FramingData /// /// columns, beams and braces public void CreateFraming() { Transaction t = new Transaction(m_data.CommandData.Application.ActiveUIDocument.Document, Guid.NewGuid().GetHashCode().ToString()); t.Start(); m_data.UpdateLevels(); List frameElems = new List(); Autodesk.Revit.DB.UV[,] matrixUV = CreateMatrix(m_data.XNumber, m_data.YNumber, m_data.Distance); // iterate levels from lower one to higher one by one according to FloorNumber for (int ii = 0; ii < m_data.FloorNumber; ii++) { Level baseLevel = m_data.Levels.Values[ii]; Level topLevel = m_data.Levels.Values[ii + 1]; int matrixXSize = matrixUV.GetLength(0); //length of matrix's x range int matrixYSize = matrixUV.GetLength(1); //length of matrix's y range // insert columns in an array format according to the calculated matrix foreach (Autodesk.Revit.DB.UV point2D in matrixUV) { frameElems.Add(NewColumn(point2D, baseLevel, topLevel)); } // insert beams between the tops of each adjacent column in the X and Y direction for (int j = 0; j < matrixYSize; j++) { for (int i = 0; i < matrixXSize; i++) { //create beams in x direction if (i != (matrixXSize - 1)) { frameElems.Add(NewBeam(matrixUV[i, j], matrixUV[i + 1, j], topLevel)); } //create beams in y direction if (j != (matrixYSize - 1)) { frameElems.Add(NewBeam(matrixUV[i, j], matrixUV[i, j + 1], topLevel)); } } } // insert braces between the mid point of each column // and the mid point of each adjoining beam for (int j = 0; j < matrixYSize; j++) { for (int i = 0; i < matrixXSize; i++) { //create braces in x direction if (i != (matrixXSize - 1)) { frameElems.AddRange( NewBraces(matrixUV[i, j], matrixUV[i + 1, j], baseLevel, topLevel)); } //create braces in y direction if (j != (matrixYSize - 1)) { frameElems.AddRange( NewBraces(matrixUV[i, j], matrixUV[i, j + 1], baseLevel, topLevel)); } } } } MoveRotateFrame(frameElems); t.Commit(); } /// /// constructor without parameter is forbidden /// private FrameBuilder() { } /// /// create a 2D matrix of coordinates to form an array format /// /// number of Columns in the X direction /// number of Columns in the Y direction /// distance between columns private static Autodesk.Revit.DB.UV[,] CreateMatrix(int xNumber, int yNumber, double distance) { Autodesk.Revit.DB.UV[,] result = new Autodesk.Revit.DB.UV[xNumber, yNumber]; for (int i = 0; i < xNumber; i++) { for (int j = 0; j < yNumber; j++) { result[i, j] = new Autodesk.Revit.DB.UV(i * distance, j * distance); } } return result; } /// /// create column of certain type in given position /// /// 2D coordinate of the column /// specified type of the column /// base level of the column /// top level of the colunm private FamilyInstance NewColumn(Autodesk.Revit.DB.UV point2D, Level baseLevel, Level topLevel) { //create column of specified type with certain level and start point Autodesk.Revit.DB.XYZ point = new Autodesk.Revit.DB.XYZ(point2D.U, point2D.V, 0); if (!m_data.ColumnSymbol.IsActive) m_data.ColumnSymbol.Activate(); FamilyInstance column = m_docCreator.NewFamilyInstance(point, m_data.ColumnSymbol, baseLevel, StructuralType.Column); //set baselevel & toplevel of the column SetParameter(column, BuiltInParameter.FAMILY_TOP_LEVEL_PARAM, topLevel.Id); SetParameter(column, BuiltInParameter.FAMILY_BASE_LEVEL_PARAM, baseLevel.Id); SetParameter(column, BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM, 0.0); SetParameter(column, BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM, 0.0); return column; } /// /// create beam of certain type in given position /// /// first point of the location line in 2D /// second point of the location line in 2D /// base level of the beam /// top level of the beam /// nothing private FamilyInstance NewBeam(Autodesk.Revit.DB.UV point2D1, Autodesk.Revit.DB.UV point2D2, Level topLevel) { // calculate the start point and end point of Beam's location line in 3D double height = topLevel.Elevation; Autodesk.Revit.DB.XYZ startPoint = new Autodesk.Revit.DB.XYZ(point2D1.U, point2D1.V, height); Autodesk.Revit.DB.XYZ endPoint = new Autodesk.Revit.DB.XYZ(point2D2.U, point2D2.V, height); // create Beam and set its location Line baseLine = Line.CreateBound(startPoint, endPoint); if (!m_data.BeamSymbol.IsActive) m_data.BeamSymbol.Activate(); FamilyInstance beam = m_docCreator.NewFamilyInstance(baseLine, m_data.BeamSymbol, topLevel, StructuralType.Beam); return beam; } /// /// create 2 braces between the mid point of 2 column and the mid point of adjoining beam /// /// first point of the location line in 2D /// second point of the location line in 2D /// the base level of the brace /// the top level of the brace private List NewBraces(Autodesk.Revit.DB.UV point2D1, Autodesk.Revit.DB.UV point2D2, Level baseLevel, Level topLevel) { // calculate the start point and end point of the location lines of two braces double topHeight = topLevel.Elevation; double baseHeight = baseLevel.Elevation; double middleElevation = (topHeight + baseHeight) / 2; Autodesk.Revit.DB.XYZ startPoint = new Autodesk.Revit.DB.XYZ(point2D1.U, point2D1.V, middleElevation); Autodesk.Revit.DB.XYZ endPoint = new Autodesk.Revit.DB.XYZ(point2D2.U, point2D2.V, middleElevation); Autodesk.Revit.DB.XYZ middlePoint = new Autodesk.Revit.DB.XYZ((point2D1.U + point2D2.U) / 2, (point2D1.V + point2D2.V) / 2, topHeight); Autodesk.Revit.DB.ElementId levelId = topLevel.Id; // create two brace; then set their location line and reference level Line firstBaseLine = Line.CreateBound(startPoint, middlePoint); if (!m_data.BraceSymbol.IsActive) m_data.BraceSymbol.Activate(); FamilyInstance firstBrace = m_docCreator.NewFamilyInstance(firstBaseLine, m_data.BraceSymbol, topLevel, StructuralType.Brace); Line secondBaseLine = Line.CreateBound(endPoint, middlePoint); FamilyInstance secondBrace = m_docCreator.NewFamilyInstance(secondBaseLine, m_data.BraceSymbol, topLevel, StructuralType.Brace); List result = new List(); result.Add(firstBrace); result.Add(secondBrace); return result; } /// /// set parameter whose storage type is Autodesk.Revit.DB.ElementId /// /// Element has parameter /// BuiltInParameter to find parameter /// value to set /// is successful private bool SetParameter(ModelElement elem, BuiltInParameter builtInPara, Autodesk.Revit.DB.ElementId value) { Parameter para = elem.get_Parameter(builtInPara); if (null != para && para.StorageType == StorageType.ElementId && !para.IsReadOnly) { var result = para.Set(value); return result; } return false; } /// /// set parameter whose storage type is double /// /// Element has parameter /// BuiltInParameter to find parameter /// value to set /// is successful private bool SetParameter(ModelElement elem, BuiltInParameter builtInPara, double value) { Parameter para = elem.get_Parameter(builtInPara); if (null != para && para.StorageType == StorageType.Double && !para.IsReadOnly) { var result = para.Set(value); return result; } return false; } /// /// move and rotate the Frame /// /// columns, beams and braces included in frame private void MoveRotateFrame(List frameElems) { Application app = m_data.CommandData.Application.Application; Document doc = m_data.CommandData.Application.ActiveUIDocument.Document; foreach (FamilyInstance elem in frameElems) { MoveElement(doc, elem, m_data.FrameOrigin); RotateElement(m_data.CommandData.Application, elem, m_data.FrameOrigin, m_data.FrameOriginAngle); } } /// /// move an element in horizontal plane /// /// element to be moved /// the 2D vector by which the element is to be moved /// is successful private void MoveElement(Document doc, Autodesk.Revit.DB.Element elem, Autodesk.Revit.DB.UV translation2D) { Autodesk.Revit.DB.XYZ translation3D = new Autodesk.Revit.DB.XYZ(translation2D.U, translation2D.V, 0.0); ElementTransformUtils.MoveElement(doc, elem.Id, translation3D); } /// /// rotate an element a specified number of degrees /// around a given center in horizontal plane /// /// element to be rotated /// the center of rotation /// the number of degrees, in radians, /// by which the element is to be rotated around the specified axis /// is successful private void RotateElement(UIApplication app, Autodesk.Revit.DB.Element elem, Autodesk.Revit.DB.UV center, double angle) { Autodesk.Revit.DB.XYZ axisPnt1 = new Autodesk.Revit.DB.XYZ(center.U, center.V, 0.0); Autodesk.Revit.DB.XYZ axisPnt2 = new Autodesk.Revit.DB.XYZ(center.U, center.V, 1.0); Line axis = Line.CreateBound(axisPnt1, axisPnt2); //axis. ElementTransformUtils.RotateElement(elem.Document, elem.Id, axis, angle); } } }