应用程序: FrameBuilder

Revit平台: 所有

Revit版本: 2011.0

首次发布: 9.1

编程语言: C#

技能水平: 中级

类别: 结构

类型: 外部命令

主题: 创建由柱、梁和支撑组成的框架。

摘要:

本示例演示如何创建由柱、梁和支撑组成的框架。用户可以输入参数来创建由柱、梁和支撑组成的框架。它具有一个用户可见的选项来使用悬挂更新功能来提高模型创建的速度。并且用户可以复制柱、梁和支撑的类型。

相关类:

Autodesk.Revit.UI.IExternalCommand

Autodesk.Revit.DB.FamilyInstance

Autodesk.Revit.DB.Document

Autodesk.Revit.DB.Level

Autodesk.Revit.DB.FamilySymbol

项目文件:

Command.cs

包含实现接口IExternalCommand的主DLL源文件。初始化创建框架所需的数据,并为用户输入显示UI

 

CreateFrameForm.cs

该文件包含一个主要框架创建的主窗体。

 

DuplicateTypeForm.cs

该文件包含一个用于复制FamilySymbol和编辑其名称和参数的表单类。

 

ErrorMessageException.cs

该文件包含一个类,它通过IExternalCommandExecute方法将错误消息传递给UI或返回给内部错误消息框。

 

FrameBuilder.cs

该文件包含一个类,用于创建柱、梁和支撑以创建框架。

 

FrameData.cs

该文件包含一个数据类,包括创建框架的信息。

 

FrameTypeParameters.cs

该文件包含一个类,用于控制PropertyGrid显示和修改柱、梁或支撑的参数。

 

FrameTypesMgr.cs

该文件包含一个数据管理器,负责当前文档中的FamilySymbol对象。

-在对话框中按“Duplicate”按钮;

描述:

本示例提供以下功能:

- 显示对话框向用户请求以下信息:

- 柱之间的距离

- X方向上的柱数

- Y方向上的柱数

- 柱的类型

- 梁的类型

- 支撑的类型

- 楼层数量

- 自动生成层的增量高度

- 框架左下角的坐标

- 顺时针旋转框架的角度

- 楼层数量少于层数,因为柱将从以下层插入到上面的层。例如,如果请求了3个楼层,则必须有4个层,并且柱将从第1层到第2层,第2层到第3层,第3层到第4层。如果少于2个级别,请告诉用户需要添加2个级别,并以失败退出命令。如果需要更多的级别,则根据楼层数自动生成级别。相邻生成级别之间的高度等于项目中存在的最高2个级别之间的高度。

- 从最低级别开始,按照规定的距离以数组格式将指定类型的柱子以XY方向上指定的柱数插入到项目中。对于指定的每个楼层都要这样做。

- XY方向上将指定类型的梁插入相邻柱之间的顶部,以形成一个方形的梁网格。对于对角柱之间不需要梁。

- 在每个柱的中点和相邻梁的中点之间插入指定类型的支撑。

- 该框架根据左下角的坐标移动。然后按顺时针方向旋转它,根据输入角度。

- 用户可以通过复制指定类型来创建新的混凝土元素类型。工作流程如下:

- 在对话框中按“Duplicate”按钮;

- 更改柱子类型的名称并按OK;

- 在另一个对话框中更改部分的bh的值,然后按OK;

- 可以采取类似的步骤为混凝土和木质梁和支撑。

说明:

1. 打开Revit结构。

2. 运行命令。

3. 输入创建梁、支撑和柱的信息,输入要旋转的角度(可选)。

4. 在示例的主UI中单击“确定”按钮。

5. 应用程序将创建一个由柱、梁和支撑组成的框架。

源代码:

完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码

CreateFrameForm.cs

//
// (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
{
    partial class CreateFrameForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.unitLabel = new System.Windows.Forms.Label();
            this.cancelButton = new System.Windows.Forms.Button();
            this.floornumberLabel = new System.Windows.Forms.Label();
            this.XLabel = new System.Windows.Forms.Label();
            this.YLabel = new System.Windows.Forms.Label();
            this.DistanceLabel = new System.Windows.Forms.Label();
            this.floorNumberTextBox = new System.Windows.Forms.TextBox();
            this.distanceTextBox = new System.Windows.Forms.TextBox();
            this.yNumberTextBox = new System.Windows.Forms.TextBox();
            this.xNumberTextBox = new System.Windows.Forms.TextBox();
            this.braceLabel = new System.Windows.Forms.Label();
            this.beamLabel = new System.Windows.Forms.Label();
            this.columnLabel = new System.Windows.Forms.Label();
            this.braceTypeComboBox = new System.Windows.Forms.ComboBox();
            this.beamTypeComboBox = new System.Windows.Forms.ComboBox();
            this.columnTypeComboBox = new System.Windows.Forms.ComboBox();
            this.OKButton = new System.Windows.Forms.Button();
            this.columnDuplicateButton = new System.Windows.Forms.Button();
            this.beamDuplicateButton = new System.Windows.Forms.Button();
            this.braceDuplicateButton = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.levelHeightTextBox = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.originXtextBox = new System.Windows.Forms.TextBox();
            this.originYtextBox = new System.Windows.Forms.TextBox();
            this.label4 = new System.Windows.Forms.Label();
            this.originAngletextBox = new System.Windows.Forms.TextBox();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.label3 = new System.Windows.Forms.Label();
            this.label7 = new System.Windows.Forms.Label();
            this.label6 = new System.Windows.Forms.Label();
            this.label5 = new System.Windows.Forms.Label();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            // 
            // unitLabel
            // 
            this.unitLabel.Location = new System.Drawing.Point(133, 36);
            this.unitLabel.Name = "unitLabel";
            this.unitLabel.Size = new System.Drawing.Size(32, 18);
            this.unitLabel.TabIndex = 35;
            this.unitLabel.Text = "feet";
            // 
            // cancelButton
            // 
            this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.cancelButton.Location = new System.Drawing.Point(516, 324);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.Size = new System.Drawing.Size(75, 23);
            this.cancelButton.TabIndex = 27;
            this.cancelButton.Text = "&Cancel";
            this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
            // 
            // floornumberLabel
            // 
            this.floornumberLabel.Location = new System.Drawing.Point(12, 177);
            this.floornumberLabel.Name = "floornumberLabel";
            this.floornumberLabel.Size = new System.Drawing.Size(144, 21);
            this.floornumberLabel.TabIndex = 34;
            this.floornumberLabel.Text = "Number of Floors:";
            // 
            // XLabel
            // 
            this.XLabel.Location = new System.Drawing.Point(12, 65);
            this.XLabel.Name = "XLabel";
            this.XLabel.Size = new System.Drawing.Size(200, 21);
            this.XLabel.TabIndex = 33;
            this.XLabel.Text = "Number of Columns in the X Direction:";
            // 
            // YLabel
            // 
            this.YLabel.Location = new System.Drawing.Point(12, 121);
            this.YLabel.Name = "YLabel";
            this.YLabel.Size = new System.Drawing.Size(200, 21);
            this.YLabel.TabIndex = 32;
            this.YLabel.Text = "Number of Columns in the Y Direction:";
            // 
            // DistanceLabel
            // 
            this.DistanceLabel.Location = new System.Drawing.Point(12, 9);
            this.DistanceLabel.Name = "DistanceLabel";
            this.DistanceLabel.Size = new System.Drawing.Size(152, 21);
            this.DistanceLabel.TabIndex = 31;
            this.DistanceLabel.Text = "Distance between Columns:";
            // 
            // floorNumberTextBox
            // 
            this.floorNumberTextBox.Location = new System.Drawing.Point(15, 200);
            this.floorNumberTextBox.Name = "floorNumberTextBox";
            this.floorNumberTextBox.Size = new System.Drawing.Size(112, 20);
            this.floorNumberTextBox.TabIndex = 22;
            this.floorNumberTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.floorNumberTextBox_Validating);
            // 
            // distanceTextBox
            // 
            this.distanceTextBox.Location = new System.Drawing.Point(15, 33);
            this.distanceTextBox.Name = "distanceTextBox";
            this.distanceTextBox.Size = new System.Drawing.Size(112, 20);
            this.distanceTextBox.TabIndex = 19;
            this.distanceTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.distanceTextBox_Validating);
            // 
            // yNumberTextBox
            // 
            this.yNumberTextBox.Location = new System.Drawing.Point(15, 145);
            this.yNumberTextBox.Name = "yNumberTextBox";
            this.yNumberTextBox.Size = new System.Drawing.Size(112, 20);
            this.yNumberTextBox.TabIndex = 21;
            this.yNumberTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.yNumberTextBox_Validating);
            // 
            // xNumberTextBox
            // 
            this.xNumberTextBox.Location = new System.Drawing.Point(15, 89);
            this.xNumberTextBox.Name = "xNumberTextBox";
            this.xNumberTextBox.Size = new System.Drawing.Size(112, 20);
            this.xNumberTextBox.TabIndex = 20;
            this.xNumberTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.xNumberTextBox_Validating);
            // 
            // braceLabel
            // 
            this.braceLabel.Location = new System.Drawing.Point(214, 121);
            this.braceLabel.Name = "braceLabel";
            this.braceLabel.Size = new System.Drawing.Size(120, 20);
            this.braceLabel.TabIndex = 30;
            this.braceLabel.Text = "Type of Braces:";
            // 
            // beamLabel
            // 
            this.beamLabel.Location = new System.Drawing.Point(214, 64);
            this.beamLabel.Name = "beamLabel";
            this.beamLabel.Size = new System.Drawing.Size(120, 21);
            this.beamLabel.TabIndex = 29;
            this.beamLabel.Text = "Type of Beams:";
            // 
            // columnLabel
            // 
            this.columnLabel.Location = new System.Drawing.Point(214, 9);
            this.columnLabel.Name = "columnLabel";
            this.columnLabel.Size = new System.Drawing.Size(120, 20);
            this.columnLabel.TabIndex = 28;
            this.columnLabel.Text = "Type of Columns:";
            // 
            // braceTypeComboBox
            // 
            this.braceTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.braceTypeComboBox.Location = new System.Drawing.Point(214, 144);
            this.braceTypeComboBox.MaxDropDownItems = 10;
            this.braceTypeComboBox.Name = "braceTypeComboBox";
            this.braceTypeComboBox.Size = new System.Drawing.Size(281, 21);
            this.braceTypeComboBox.TabIndex = 25;
            this.braceTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.braceTypeComboBox_SelectedIndexChanged);
            // 
            // beamTypeComboBox
            // 
            this.beamTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.beamTypeComboBox.Location = new System.Drawing.Point(214, 88);
            this.beamTypeComboBox.MaxDropDownItems = 10;
            this.beamTypeComboBox.Name = "beamTypeComboBox";
            this.beamTypeComboBox.Size = new System.Drawing.Size(281, 21);
            this.beamTypeComboBox.TabIndex = 24;
            this.beamTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.beamTypeComboBox_SelectedIndexChanged);
            // 
            // columnTypeComboBox
            // 
            this.columnTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.columnTypeComboBox.Location = new System.Drawing.Point(214, 32);
            this.columnTypeComboBox.MaxDropDownItems = 10;
            this.columnTypeComboBox.Name = "columnTypeComboBox";
            this.columnTypeComboBox.Size = new System.Drawing.Size(281, 21);
            this.columnTypeComboBox.TabIndex = 23;
            this.columnTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.columnTypeComboBox_SelectedIndexChanged);
            // 
            // OKButton
            // 
            this.OKButton.Location = new System.Drawing.Point(435, 324);
            this.OKButton.Name = "OKButton";
            this.OKButton.Size = new System.Drawing.Size(75, 23);
            this.OKButton.TabIndex = 26;
            this.OKButton.Text = "&OK";
            this.OKButton.Click += new System.EventHandler(this.OKButton_Click);
            // 
            // columnDuplicateButton
            // 
            this.columnDuplicateButton.Location = new System.Drawing.Point(501, 30);
            this.columnDuplicateButton.Name = "columnDuplicateButton";
            this.columnDuplicateButton.Size = new System.Drawing.Size(102, 24);
            this.columnDuplicateButton.TabIndex = 36;
            this.columnDuplicateButton.Text = "&ColumnDuplicate";
            this.columnDuplicateButton.UseVisualStyleBackColor = true;
            this.columnDuplicateButton.Click += new System.EventHandler(this.columnDuplicateButton_Click);
            // 
            // beamDuplicateButton
            // 
            this.beamDuplicateButton.Location = new System.Drawing.Point(501, 85);
            this.beamDuplicateButton.Name = "beamDuplicateButton";
            this.beamDuplicateButton.Size = new System.Drawing.Size(102, 24);
            this.beamDuplicateButton.TabIndex = 37;
            this.beamDuplicateButton.Text = "&BeamDuplicate";
            this.beamDuplicateButton.UseVisualStyleBackColor = true;
            this.beamDuplicateButton.Click += new System.EventHandler(this.beamDuplicateButton_Click);
            // 
            // braceDuplicateButton
            // 
            this.braceDuplicateButton.Location = new System.Drawing.Point(501, 142);
            this.braceDuplicateButton.Name = "braceDuplicateButton";
            this.braceDuplicateButton.Size = new System.Drawing.Size(102, 23);
            this.braceDuplicateButton.TabIndex = 38;
            this.braceDuplicateButton.Text = "B&raceDuplicate";
            this.braceDuplicateButton.UseVisualStyleBackColor = true;
            this.braceDuplicateButton.Click += new System.EventHandler(this.braceDuplicateButton_Click);
            // 
            // label1
            // 
            this.label1.Location = new System.Drawing.Point(12, 233);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(175, 21);
            this.label1.TabIndex = 40;
            this.label1.Text = "Height of Auto Generated Levels:";
            // 
            // levelHeightTextBox
            // 
            this.levelHeightTextBox.Enabled = false;
            this.levelHeightTextBox.Location = new System.Drawing.Point(15, 255);
            this.levelHeightTextBox.Name = "levelHeightTextBox";
            this.levelHeightTextBox.Size = new System.Drawing.Size(112, 20);
            this.levelHeightTextBox.TabIndex = 39;
            this.levelHeightTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.levelHeightTextBox_Validating);
            // 
            // label2
            // 
            this.label2.Location = new System.Drawing.Point(132, 258);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(32, 18);
            this.label2.TabIndex = 41;
            this.label2.Text = "feet";
            // 
            // originXtextBox
            // 
            this.originXtextBox.Location = new System.Drawing.Point(12, 45);
            this.originXtextBox.Name = "originXtextBox";
            this.originXtextBox.Size = new System.Drawing.Size(100, 20);
            this.originXtextBox.TabIndex = 42;
            this.originXtextBox.Validating += new System.ComponentModel.CancelEventHandler(this.originXtextBox_Validating);
            // 
            // originYtextBox
            // 
            this.originYtextBox.Location = new System.Drawing.Point(156, 45);
            this.originYtextBox.Name = "originYtextBox";
            this.originYtextBox.Size = new System.Drawing.Size(100, 20);
            this.originYtextBox.TabIndex = 43;
            this.originYtextBox.Validating += new System.ComponentModel.CancelEventHandler(this.originYtextBox_Validating);
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(9, 21);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(50, 13);
            this.label4.TabIndex = 45;
            this.label4.Text = "Origin (X)";
            // 
            // originAngletextBox
            // 
            this.originAngletextBox.Location = new System.Drawing.Point(12, 100);
            this.originAngletextBox.Name = "originAngletextBox";
            this.originAngletextBox.Size = new System.Drawing.Size(100, 20);
            this.originAngletextBox.TabIndex = 46;
            this.originAngletextBox.Validating += new System.ComponentModel.CancelEventHandler(this.originAngletextBox_Validating);
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.label3);
            this.groupBox1.Controls.Add(this.label7);
            this.groupBox1.Controls.Add(this.label6);
            this.groupBox1.Controls.Add(this.label5);
            this.groupBox1.Controls.Add(this.originYtextBox);
            this.groupBox1.Controls.Add(this.originAngletextBox);
            this.groupBox1.Controls.Add(this.originXtextBox);
            this.groupBox1.Controls.Add(this.label4);
            this.groupBox1.Location = new System.Drawing.Point(214, 179);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(377, 139);
            this.groupBox1.TabIndex = 47;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Location";
            // 
            // label3
            // 
            this.label3.Location = new System.Drawing.Point(262, 48);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(32, 18);
            this.label3.TabIndex = 50;
            this.label3.Text = "feet";
            // 
            // label7
            // 
            this.label7.Location = new System.Drawing.Point(118, 48);
            this.label7.Name = "label7";
            this.label7.Size = new System.Drawing.Size(32, 18);
            this.label7.TabIndex = 49;
            this.label7.Text = "feet,";
            // 
            // label6
            // 
            this.label6.AutoSize = true;
            this.label6.Location = new System.Drawing.Point(161, 21);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(20, 13);
            this.label6.TabIndex = 48;
            this.label6.Text = "(Y)";
            // 
            // label5
            // 
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(12, 76);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(69, 13);
            this.label5.TabIndex = 47;
            this.label5.Text = "Rotate Angle";
            // 
            // CreateFrameForm
            // 
            this.AcceptButton = this.OKButton;
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.CancelButton = this.cancelButton;
            this.ClientSize = new System.Drawing.Size(607, 353);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.levelHeightTextBox);
            this.Controls.Add(this.braceDuplicateButton);
            this.Controls.Add(this.beamDuplicateButton);
            this.Controls.Add(this.columnDuplicateButton);
            this.Controls.Add(this.unitLabel);
            this.Controls.Add(this.cancelButton);
            this.Controls.Add(this.floornumberLabel);
            this.Controls.Add(this.XLabel);
            this.Controls.Add(this.YLabel);
            this.Controls.Add(this.DistanceLabel);
            this.Controls.Add(this.floorNumberTextBox);
            this.Controls.Add(this.distanceTextBox);
            this.Controls.Add(this.yNumberTextBox);
            this.Controls.Add(this.xNumberTextBox);
            this.Controls.Add(this.braceLabel);
            this.Controls.Add(this.beamLabel);
            this.Controls.Add(this.columnLabel);
            this.Controls.Add(this.braceTypeComboBox);
            this.Controls.Add(this.beamTypeComboBox);
            this.Controls.Add(this.columnTypeComboBox);
            this.Controls.Add(this.OKButton);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "CreateFrameForm";
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Frame Builder";
            this.Load += new System.EventHandler(this.CreateFramingForm_Load);
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label unitLabel;
        private System.Windows.Forms.Button cancelButton;
        private System.Windows.Forms.Label floornumberLabel;
        private System.Windows.Forms.Label XLabel;
        private System.Windows.Forms.Label YLabel;
        private System.Windows.Forms.Label DistanceLabel;
        private System.Windows.Forms.TextBox floorNumberTextBox;
        private System.Windows.Forms.TextBox distanceTextBox;
        private System.Windows.Forms.TextBox yNumberTextBox;
        private System.Windows.Forms.TextBox xNumberTextBox;
        private System.Windows.Forms.Label braceLabel;
        private System.Windows.Forms.Label beamLabel;
        private System.Windows.Forms.Label columnLabel;
        private System.Windows.Forms.ComboBox braceTypeComboBox;
        private System.Windows.Forms.ComboBox beamTypeComboBox;
        private System.Windows.Forms.ComboBox columnTypeComboBox;
        private System.Windows.Forms.Button OKButton;
        private System.Windows.Forms.Button columnDuplicateButton;
        private System.Windows.Forms.Button beamDuplicateButton;
        private System.Windows.Forms.Button braceDuplicateButton;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox levelHeightTextBox;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox originXtextBox;
        private System.Windows.Forms.TextBox originYtextBox;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox originAngletextBox;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label7;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.Label label5;
    }
}

DuplicateTypeForm.cs

//
// (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
{
    partial class DuplicateTypeForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
         this.familyTextBox = new System.Windows.Forms.TextBox();
         this.label1 = new System.Windows.Forms.Label();
         this.label2 = new System.Windows.Forms.Label();
         this.typeNameTextBox = new System.Windows.Forms.TextBox();
         this.typeParameterPropertyGrid = new System.Windows.Forms.PropertyGrid();
         this.typeParametersGroupBox = new System.Windows.Forms.GroupBox();
         this.OKButton = new System.Windows.Forms.Button();
         this.cancelButton = new System.Windows.Forms.Button();
         this.typeParametersGroupBox.SuspendLayout();
         this.SuspendLayout();
         // 
         // familyTextBox
         // 
         this.familyTextBox.Location = new System.Drawing.Point(86, 12);
         this.familyTextBox.Name = "familyTextBox";
         this.familyTextBox.ReadOnly = true;
         this.familyTextBox.Size = new System.Drawing.Size(280, 20);
         this.familyTextBox.TabIndex = 0;
         // 
         // label1
         // 
         this.label1.AutoSize = true;
         this.label1.Location = new System.Drawing.Point(12, 15);
         this.label1.Name = "label1";
         this.label1.Size = new System.Drawing.Size(39, 13);
         this.label1.TabIndex = 1;
         this.label1.Text = "Family:";
         // 
         // label2
         // 
         this.label2.AutoSize = true;
         this.label2.Location = new System.Drawing.Point(12, 47);
         this.label2.Name = "label2";
         this.label2.Size = new System.Drawing.Size(34, 13);
         this.label2.TabIndex = 2;
         this.label2.Text = "Type:";
         // 
         // typeNameTextBox
         // 
         this.typeNameTextBox.Location = new System.Drawing.Point(86, 44);
         this.typeNameTextBox.Name = "typeNameTextBox";
         this.typeNameTextBox.ReadOnly = true;
         this.typeNameTextBox.Size = new System.Drawing.Size(280, 20);
         this.typeNameTextBox.TabIndex = 3;
         // 
         // typeParameterPropertyGrid
         // 
         this.typeParameterPropertyGrid.Location = new System.Drawing.Point(6, 19);
         this.typeParameterPropertyGrid.Name = "typeParameterPropertyGrid";
         this.typeParameterPropertyGrid.Size = new System.Drawing.Size(348, 271);
         this.typeParameterPropertyGrid.TabIndex = 4;
         // 
         // typeParametersGroupBox
         // 
         this.typeParametersGroupBox.Controls.Add(this.typeParameterPropertyGrid);
         this.typeParametersGroupBox.Location = new System.Drawing.Point(12, 75);
         this.typeParametersGroupBox.Name = "typeParametersGroupBox";
         this.typeParametersGroupBox.Size = new System.Drawing.Size(360, 296);
         this.typeParametersGroupBox.TabIndex = 5;
         this.typeParametersGroupBox.TabStop = false;
         this.typeParametersGroupBox.Text = "Type Parameters:";
         // 
         // OKButton
         // 
         this.OKButton.Location = new System.Drawing.Point(207, 379);
         this.OKButton.Name = "OKButton";
         this.OKButton.Size = new System.Drawing.Size(75, 23);
         this.OKButton.TabIndex = 6;
         this.OKButton.Text = "&OK";
         this.OKButton.UseVisualStyleBackColor = true;
         this.OKButton.Click += new System.EventHandler(this.OKButton_Click);
         // 
         // cancelButton
         // 
         this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
         this.cancelButton.Location = new System.Drawing.Point(291, 379);
         this.cancelButton.Name = "cancelButton";
         this.cancelButton.Size = new System.Drawing.Size(75, 23);
         this.cancelButton.TabIndex = 7;
         this.cancelButton.Text = "&Cancel";
         this.cancelButton.UseVisualStyleBackColor = true;
         this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
         // 
         // DuplicateTypeForm
         // 
         this.AcceptButton = this.OKButton;
         this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
         this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
         this.CancelButton = this.cancelButton;
         this.ClientSize = new System.Drawing.Size(383, 414);
         this.Controls.Add(this.cancelButton);
         this.Controls.Add(this.OKButton);
         this.Controls.Add(this.typeParametersGroupBox);
         this.Controls.Add(this.typeNameTextBox);
         this.Controls.Add(this.label2);
         this.Controls.Add(this.label1);
         this.Controls.Add(this.familyTextBox);
         this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
         this.MaximizeBox = false;
         this.MinimizeBox = false;
         this.Name = "DuplicateTypeForm";
         this.ShowInTaskbar = false;
         this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
         this.Text = "Type Properties";
         this.Load += new System.EventHandler(this.DuplicateTypeForm_Load);
         this.typeParametersGroupBox.ResumeLayout(false);
         this.ResumeLayout(false);
         this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox familyTextBox;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox typeNameTextBox;
        private System.Windows.Forms.PropertyGrid typeParameterPropertyGrid;
        private System.Windows.Forms.GroupBox typeParametersGroupBox;
        private System.Windows.Forms.Button OKButton;
        private System.Windows.Forms.Button cancelButton;
    }
}

ErrorMessageException.cs

//
// (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;

    /// <summary>
    /// pass error message to UI or back to internal error messagebox by Execute method in IExternalCommand
    /// </summary>
    class ErrorMessageException : ApplicationException
    {
        /// <summary>
        /// constructor entirely using baseclass'
        /// </summary>
        public ErrorMessageException()
            : base()
        {
        }

        /// <summary>
        /// constructor entirely using baseclass'
        /// </summary>
        /// <param name="message">error message</param>
        public ErrorMessageException(String message)
            : base(message)
        {
        }
    }
}

FrameBuilder.cs

//
// (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;

   /// <summary>
   /// create columns, beams and braces to create framing
   /// </summary>
   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

      /// <summary>
      /// constructor
      /// </summary>
      /// <param name="data">data necessary to initialize object</param>
      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;
      }

      /// <summary>
      /// create framing according to FramingData
      /// </summary>
      /// <returns>columns, beams and braces</returns>
      public void CreateFraming()
      {
         Transaction t = new Transaction(m_data.CommandData.Application.ActiveUIDocument.Document, Guid.NewGuid().GetHashCode().ToString());
         t.Start();
         m_data.UpdateLevels();
         List<FamilyInstance> frameElems = new List<FamilyInstance>();
         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();
      }

      /// <summary>
      /// constructor without parameter is forbidden
      /// </summary>
      private FrameBuilder()
      {
      }

      /// <summary>
      /// create a 2D matrix of coordinates to form an array format
      /// </summary>
      /// <param name="xNumber">number of Columns in the X direction</param>
      /// <param name="yNumber">number of Columns in the Y direction</param>
      /// <param name="distance">distance between columns</param>
      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;
      }

      /// <summary>
      /// create column of certain type in given position
      /// </summary>
      /// <param name="point2D">2D coordinate of the column</param>
      /// <param name="columnType">specified type of the column</param>
      /// <param name="baseLevel">base level of the column</param>
      /// <param name="topLevel">top level of the colunm</param>
      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;
      }

      /// <summary>
      /// create beam of certain type in given position
      /// </summary>
      /// <param name="point2D1">first point of the location line in 2D</param>
      /// <param name="point2D2">second point of the location line in 2D</param>
      /// <param name="baseLevel">base level of the beam</param>
      /// <param name="topLevel">top level of the beam</param>
      /// <returns>nothing</returns>
      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;
      }

      /// <summary>
      /// create 2 braces between the mid point of 2 column and the mid point of adjoining beam
      /// </summary>
      /// <param name="point2D1">first point of the location line in 2D</param>
      /// <param name="point2D2">second point of the location line in 2D</param>
      /// <param name="baseLevel">the base level of the brace</param>
      /// <param name="topLevel">the top level of the brace</param>
      private List<FamilyInstance> 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<FamilyInstance> result = new List<FamilyInstance>();
         result.Add(firstBrace);
         result.Add(secondBrace);
         return result;
      }

      /// <summary>
      /// set parameter whose storage type is Autodesk.Revit.DB.ElementId 
      /// </summary>
      /// <param name="elem">Element has parameter</param>
      /// <param name="builtInPara">BuiltInParameter to find parameter</param>
      /// <param name="value">value to set</param>
      /// <returns>is successful</returns>
      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;
      }

      /// <summary>
      /// set parameter whose storage type is double
      /// </summary>
      /// <param name="elem">Element has parameter</param>
      /// <param name="builtInPara">BuiltInParameter to find parameter</param>
      /// <param name="value">value to set</param>
      /// <returns>is successful</returns>
      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;
      }


      /// <summary>
      /// move and rotate the Frame
      /// </summary>
      /// <param name="frameElems">columns, beams and braces included in frame</param>
      private void MoveRotateFrame(List<FamilyInstance> 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);
         }
      }

      /// <summary>
      /// move an element in horizontal plane
      /// </summary>
      /// <param name="elem">element to be moved</param>
      /// <param name="translation2D">the 2D vector by which the element is to be moved</param>
      /// <returns>is successful</returns>
      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);
      }

      /// <summary>
      /// rotate an element a specified number of degrees 
      /// around a given center in horizontal plane
      /// </summary>
      /// <param name="elem">element to be rotated</param>
      /// <param name="center">the center of rotation</param>
      /// <param name="angle">the number of degrees, in radians, 
      /// by which the element is to be rotated around the specified axis</param>
      /// <returns>is successful</returns>
      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);
      }
   }
}

FrameData.cs

//
// (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.Text;
    using System.Collections.Generic;

    using Autodesk.Revit;
    using Autodesk.Revit.ApplicationServices;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI;
    using UV = Autodesk.Revit.DB.UV;

    /// <summary>
    /// data class contains information to create framing
    /// </summary>
    public class FrameData
    {
        const int XNumberMaxValue = 50;			// maximum number of Columns in the X Direction
        const int XNumberMinValue = 2;			// minimum number of Columns in the X Direction
        const int XNumberDefault = 3;			// default number of Columns in the X Direction
        const int YNumberMaxValue = 50;			// maximum number of Columns in the Y Direction
        const int YNumberMinValue = 2;			// minimum number of Columns in the Y Direction
        const int YNumberDefault = 3;			// default number of Columns in the Y Direction
        const int TotalMaxValue = 200;			// maximum total number of Columns to create
        const int FloorNumberMinValue = 1;		// minimum number of floors
        const int FloorNumberMaxValue = 200;	// maximum number of floors
        const double DistanceMaxValue = 3000;	// maxinum distance between 2 adjoining columns
        const double DistanceMinValue = 1;		// mininum distance between 2 adjoining columns
        const double DistanceDefault = 5;		// default distance between 2 adjoining columns
        const double LevelHeightMaxValue = 100;	// maximum height between 2 new levels
        const double LevelHeightMinValue = 1;	// minimum height between 2 new levels
        const int DigitPrecision = 4;			// the number of significant digits(precision)

        int m_xNumber = XNumberDefault;			// number of Columns in the X Direction
        int m_yNumber = XNumberDefault;			// number of Columns in the Y Direction
        double m_distance = DistanceDefault;	// distance between 2 adjoining columns
        int m_floorNumber;						// number of floors
        double m_levelHeight;					// increaced height of autogenerated levels
        Autodesk.Revit.DB.UV m_frameOrigin = new Autodesk.Revit.DB.UV(0.0, 0.0);	// bottom left point of the frame
        double m_frameOriginAngle = 0.0;		// the angle to rotate around bottom left point
        int m_originalLevelSize;				// the number of levels before invoke external command

        FamilySymbol m_columnSymbol;			// column's type
        FamilySymbol m_beamSymbol;				// beam's type
        FamilySymbol m_braceSymbol;				// brace's type

        ExternalCommandData m_commandData;
        FrameTypesMgr m_columnSymbolsMgr;		// object manage all column types
        FrameTypesMgr m_beambracesSymbolsMgr;	// object manage all beam types
        SortedList<double, Level> m_levels;		// list of all levels in the order of Elevation

        /// <summary>
        /// command data pass from entry point
        /// </summary>
        public ExternalCommandData CommandData
        {
            get
            {
                return m_commandData;
            }
        }

        /// <summary>
        /// object manage all column types
        /// </summary>
        public FrameTypesMgr ColumnSymbolsMgr
        {
            get
            {
                return m_columnSymbolsMgr;
            }
        }

        /// <summary>
        /// object manage all beam types
        /// </summary>
        public FrameTypesMgr BeamSymbolsMgr
        {
            get
            {
                return m_beambracesSymbolsMgr;
            }
        }

        /// <summary>
        /// object manage all brace types
        /// </summary>
        public FrameTypesMgr BraceSymbolsMgr
        {
            get
            {
                return m_beambracesSymbolsMgr;
            }
        }

        /// <summary>
        /// number of Columns in the Y Direction
        /// </summary>
        public int YNumber
        {
            get
            {
                return m_yNumber;
            }
            set
            {
                if (value < YNumberMinValue || value > YNumberMaxValue)
                {
                    string message = "Number of Columns in the Y Direction should no less than "
                        + YNumberMinValue.ToString() + " and no more than "
                        + YNumberMaxValue.ToString();
                    throw new ErrorMessageException(message);
                }
                CheckTotalNumber(value * XNumber * (m_floorNumber - 1));
                m_yNumber = value;
            }
        }

        /// <summary>
        /// number of Columns in the X Direction
        /// </summary>
        public int XNumber
        {
            get
            {
                return m_xNumber;
            }
            set
            {
                if (value < XNumberMinValue || value > XNumberMaxValue)
                {
                    string message = "Number of Columns in the X Direction should no less than "
                        + XNumberMinValue.ToString() + " and no more than "
                        + XNumberMaxValue.ToString();
                    throw new ErrorMessageException(message);
                }
                CheckTotalNumber(value * YNumber * (m_floorNumber - 1));
                m_xNumber = value;
            }
        }

        /// <summary>
        /// distance between 2 adjoining columns
        /// </summary>
        public double Distance
        {
            get
            {
                return m_distance;
            }
            set
            {
                if (value < DistanceMinValue || value > DistanceMaxValue)
                {
                    string message = "The distance between columns shoule no less than "
                        + DistanceMinValue.ToString() + "and no more than "
                        + DistanceMaxValue.ToString();
                    throw new ErrorMessageException(message);
                }
                m_distance = value;
            }
        }

        /// <summary>
        /// number of floors
        /// </summary>
        public int FloorNumber
        {
            get
            {
                return m_floorNumber;
            }
            set
            {
                if (value < FloorNumberMinValue || value > FloorNumberMaxValue)
                {
                    string message = "Number of floors should no less than "
                        + FloorNumberMinValue.ToString() + " and no more than "
                        + FloorNumberMaxValue.ToString();
                    throw new ErrorMessageException(message);
                }
                CheckTotalNumber(XNumber * YNumber * (value - 1));
                m_floorNumber = value;
            }
        }

        /// <summary>
        /// increased height of autogenerated levels
        /// </summary>
        public double LevelHeight
        {
            get
            {
                return Math.Round(m_levelHeight, DigitPrecision);
            }
            set
            {
                if (value < LevelHeightMinValue || value > LevelHeightMaxValue)
                {
                    string message = "The distance between columns shoule no less than "
                        + LevelHeightMinValue.ToString() + "and no more than "
                        + LevelHeightMaxValue.ToString();
                    throw new ErrorMessageException(message);
                }
                m_distance = value;
            }
        }

        /// <summary>
        /// bottom left point of the frame
        /// </summary>
        public Autodesk.Revit.DB.UV FrameOrigin
        {
            get
            {
                return m_frameOrigin;
            }
            set
            {
                m_frameOrigin = value;
            }
        }

        /// <summary>
        /// the angle to rotate around bottom left point
        /// </summary>
        public double FrameOriginAngle
        {
            get
            {
                return m_frameOriginAngle;
            }
            set
            {
                m_frameOriginAngle = value;
            }
        }

        /// <summary>
        /// column's type
        /// </summary>
        public FamilySymbol ColumnSymbol
        {
            get
            {
                return m_columnSymbol;
            }
        }

        /// <summary>
        /// beam's type
        /// </summary>
        public FamilySymbol BeamSymbol
        {
            get
            {
                return m_beamSymbol;
            }
        }

        /// <summary>
        /// brace's type
        /// </summary>
        public FamilySymbol BraceSymbol
        {
            get
            {
                return m_braceSymbol;
            }
        }

        /// <summary>
        /// list of all levels in the ordr of Elevation
        /// </summary>
        public SortedList<double, Level> Levels
        {
            get
            {
                return m_levels;
            }
        }

        /// <summary>
        /// the number of levels before invoke external command
        /// </summary>
        public int OriginalLevelSize
        {
            get
            {
                return m_originalLevelSize;
            }
        }

        /// <summary>
        /// create FramingData object. applicationException will throw out,
        /// if current Revit document doesn't satisfy the condition to create framing
        /// </summary>
        /// <param name="commandData"></param>
        /// <returns></returns>
        public static FrameData CreateInstance(ExternalCommandData commandData)
        {
            FrameData data = new FrameData(commandData);
            data.Initialize();
            data.Validate();

            // initialize members after checking precondition
            data.m_floorNumber = (data.m_levels.Count - 1) > 0 ? (data.m_levels.Count - 1) : 1;
            data.m_columnSymbol = data.m_columnSymbolsMgr.FramingSymbols[0];
            data.m_beamSymbol = data.m_beambracesSymbolsMgr.FramingSymbols[0];
            data.m_braceSymbol = data.m_beambracesSymbolsMgr.FramingSymbols[0];
            data.m_levelHeight = data.m_levels.Values[data.m_levels.Count - 1].Elevation
                - data.m_levels.Values[data.m_levels.Count - 2].Elevation;

            return data;
        }

        /// <summary>
        /// cast object to FamilySymbol and set as column's type
        /// </summary>
        /// <param name="obj">FamilySymbol object</param>
        /// <returns>failed to cast and set</returns>
        public bool SetColumnSymbol(object obj)
        {
            FamilySymbol symbol = obj as FamilySymbol;
            if (null == symbol)
            {
                return false;
            }
            m_columnSymbol = symbol;
            return true;
        }

        /// <summary>
        /// cast object to FamilySymbol and set as beam's type
        /// </summary>
        /// <param name="obj">FamilySymbol object</param>
        /// <returns>failed to cast and set</returns>
        public bool SetBeamSymbol(object obj)
        {
            FamilySymbol symbol = obj as FamilySymbol;
            if (null == symbol)
            {
                return false;
            }
            m_beamSymbol = symbol;
            return true;
        }

        /// <summary>
        /// cast object to FamilySymbol and set as brace's type
        /// </summary>
        /// <param name="obj">FamilySymbol object</param>
        /// <returns>failed to cast and set</returns>
        public bool SetBraceSymbol(object obj)
        {
            FamilySymbol symbol = obj as FamilySymbol;
            if (null == symbol)
            {
                return false;
            }
            m_braceSymbol = symbol;
            return true;
        }

        /// <summary>
        /// add more levels so that level number can meet floor number
        /// </summary>
        public void UpdateLevels()
        {
            double baseElevation = m_levels.Values[m_levels.Count - 1].Elevation;
            Autodesk.Revit.Creation.Document createDoc = m_commandData.Application.ActiveUIDocument.Document.Create;
            Autodesk.Revit.DB.Document m_Doc = m_commandData.Application.ActiveUIDocument.Document;

            FilteredElementCollector collector = new FilteredElementCollector(m_Doc);
            IList<Element> viewFamilyTypes = collector.OfClass(typeof(ViewFamilyType)).ToElements();
            ElementId floorPlanId = new ElementId(-1);
            foreach (Element e in viewFamilyTypes)
            {
                ViewFamilyType v = e as ViewFamilyType;

                if (v != null && v.ViewFamily == ViewFamily.FloorPlan)
                {
                    floorPlanId = e.Id;
                    break;
                }
            }

            int newLevelSize = (m_floorNumber + 1) - m_levels.Count;
            if (newLevelSize == 0)
            {
                return;
            }

            for (int ii = 0; ii < newLevelSize; ii++)
            {
                double elevation = baseElevation + m_levelHeight * (ii + 1);
                Level newLevel = Level.Create(m_commandData.Application.ActiveUIDocument.Document, elevation);
                //createDoc.NewViewPlan(newLevel.Name, newLevel, Autodesk.Revit.DB.ViewPlanType.FloorPlan);
                ViewPlan viewPlan = ViewPlan.Create(m_Doc, floorPlanId, newLevel.Id);
                viewPlan.Name = newLevel.Name;
                m_levels.Add(elevation, newLevel);
            }
            m_originalLevelSize = m_levels.Count;
        }

        /// <summary>
        /// it is only used for object factory method
        /// </summary>
        /// <param name="commandData"></param>
        private FrameData(ExternalCommandData commandData)
        {
            // initialize members
            m_commandData = commandData;
            m_columnSymbolsMgr = new FrameTypesMgr(commandData);
            m_beambracesSymbolsMgr = new FrameTypesMgr(commandData);
            m_levels = new SortedList<double, Level>();
            m_originalLevelSize = m_levels.Count;
            m_yNumber = YNumberDefault;
            m_xNumber = XNumberDefault;
            m_distance = DistanceDefault;
        }

        /// <summary>
        /// check the total number of columns to create less than certain value
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        private static void CheckTotalNumber(int number)
        {
            if (number > TotalMaxValue)
            {
                string message = "The total number of columns should less than "
                    + TotalMaxValue.ToString();
                throw new ErrorMessageException(message);
            }
        }

        /// <summary>
        /// initialize list of column, beam and brace's type;
        /// initialize list of level
        /// </summary>
        private void Initialize()
        {
            Application app = m_commandData.Application.Application;
            Document doc = m_commandData.Application.ActiveUIDocument.Document;

            FilteredElementCollector collector1 = new FilteredElementCollector(doc);
            IList<Autodesk.Revit.DB.Element> a1 = collector1.OfClass(typeof(Level)).ToElements();

            foreach (Level lev in a1)
            {
                m_levels.Add(lev.Elevation, lev);
            }

            a1.Clear();

            Categories categories = doc.Settings.Categories;
            BuiltInCategory bipColumn = BuiltInCategory.OST_StructuralColumns;
            BuiltInCategory bipFraming = BuiltInCategory.OST_StructuralFraming;
            Autodesk.Revit.DB.ElementId idColumn = categories.get_Item(bipColumn).Id;
            Autodesk.Revit.DB.ElementId idFraming = categories.get_Item(bipFraming).Id;

            ElementCategoryFilter filterColumn = new ElementCategoryFilter(bipColumn);
            ElementCategoryFilter filterFraming = new ElementCategoryFilter(bipFraming);
            LogicalOrFilter orFilter = new LogicalOrFilter(filterColumn, filterFraming);

            ElementClassFilter filterSymbol = new ElementClassFilter(typeof(FamilySymbol));
            LogicalAndFilter andFilter = new LogicalAndFilter(orFilter, filterSymbol);
            //
            // without filtering for the structural categories,
            // our sample project was returning over 500 family symbols;
            // adding the category filters reduced this number to 40:
            //
            FilteredElementCollector collector2 = new FilteredElementCollector(doc);
            IList<Element> a2 = collector2.WherePasses(andFilter).ToElements();

            foreach (FamilySymbol symbol in a2)
            {
                Autodesk.Revit.DB.ElementId categoryId = symbol.Category.Id;

                if (idFraming.Equals(categoryId))
                {
                    m_beambracesSymbolsMgr.AddSymbol(symbol);
                }
                else if (idColumn.Equals(categoryId))
                {
                    m_columnSymbolsMgr.AddSymbol(symbol);
                }
            }
        }

        /// <summary>
        /// validate the precondition to create framing
        /// </summary>
        private void Validate()
        {
            // level shouldn't less than 2
            if (m_levels.Count < 2)
            {
                throw new ErrorMessageException("The level's number in active document is less than 2.");
            }
            // no Structural Column family is loaded in current document
            if (m_columnSymbolsMgr.Size == 0)
            {
                throw new ErrorMessageException("No Structural Column family is loaded in current project.");
            }
            // no Structural Beam family is loaded in current document
            if (m_beambracesSymbolsMgr.Size == 0)
            {
                throw new ErrorMessageException("No Structural Beam family is loaded in current project.");
            }
        }
    }
}

FrameTypeParameters.cs

//
// (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.Windows.Forms;
    using System.ComponentModel;

    using Autodesk.Revit;
    using Autodesk.Revit.DB;

    /// <summary>
    /// for control PropertyGrid to show and modify parameters of column, beam or brace
    /// </summary>
    public class FrameTypeParameters
    {
        Parameter m_hDimension;        // parameter named h
        Parameter m_bDimension;        // parameter named b

        /// <summary>
        /// parameter h in parameter category Dimension
        /// </summary>
        [CategoryAttribute("Dimensions")]
        public double h
        {
            get
            {
                return m_hDimension.AsDouble();
            }
            set
            {
                m_hDimension.Set(value);
            }
        }

        /// <summary>
        /// parameter b in parameter category Dimension
        /// </summary>
        [CategoryAttribute("Dimensions")]
        public double b
        {
            get
            {
                return m_bDimension.AsDouble();
            }
            set
            {
                m_bDimension.Set(value);
            }
        }

        /// <summary>
        /// constructor without parameter is forbidden
        /// </summary>
        private FrameTypeParameters()
        {
        }

        /// <summary>
        /// constructor used only for object factory
        /// </summary>
        /// <param name="symbol">FamilySymbol object has parameters</param>
        private FrameTypeParameters(FamilySymbol symbol)
        {
            // iterate and initialize parameters
            foreach (Parameter para in symbol.Parameters)
            {
                if (para.Definition.Name == "h")
                {
                    m_hDimension = para;
                    continue;
                }
                if (para.Definition.Name == "b")
                {
                    m_bDimension = para;
                    continue;
                }
            }
        }

        /// <summary>
        /// object factory to create FramingTypeParameters; 
        /// will return null if necessary Parameters can't be found
        /// </summary>
        /// <param name="symbol"></param>
        /// <returns></returns>
        public static FrameTypeParameters CreateInstance(FamilySymbol symbol)
        {
            FrameTypeParameters result = new FrameTypeParameters(symbol);
            if (null == result.m_bDimension || null == result.m_hDimension)
            {
                return null;
            }
            return result;
        }
    }
}

FrameTypesMgr.cs

//
// (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 Autodesk.Revit.UI;

namespace Revit.SDK.Samples.FrameBuilder.CS
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections.ObjectModel;

    using Autodesk.Revit;
    using Autodesk.Revit.DB;

    /// <summary>
    /// data manager take charge of FamilySymbol object in current document
    /// </summary>
    public class FrameTypesMgr
    {
        // map list pairs FamilySymbol object and its Name 
        private Dictionary<String, FamilySymbol> m_symbolMaps;    
        // list of FamilySymbol objects
        private List<FamilySymbol> m_symbols;                    
        private ExternalCommandData m_commandData;

        /// <summary>
        /// command data pass from entry point
        /// </summary>
        public ExternalCommandData CommandData
        {
            get
            {
                return m_commandData;
            }
        }

        /// <summary>
        /// size of FamilySymbol objects in current Revit document
        /// </summary>
        public int Size
        {
            get
            {
                return m_symbolMaps.Count;
            }
        }

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="commandData"></param>
        public FrameTypesMgr(ExternalCommandData commandData)
        {
            m_commandData = commandData;
            m_symbolMaps = new Dictionary<String, FamilySymbol>();
            m_symbols = new List<FamilySymbol>();
        }

        /// <summary>
        /// constructor without parameters is forbidden
        /// </summary>
        private FrameTypesMgr()
        {
        }

        /// <summary>
        /// get list of FamilySymbol objects in current Revit document
        /// </summary>
        public ReadOnlyCollection<FamilySymbol> FramingSymbols
        {
            get
            {
                return new ReadOnlyCollection<FamilySymbol>(m_symbols);
            }
        }

        /// <summary>
        /// add one FamilySymbol object to the lists
        /// </summary>
        /// <param name="framingSymbol"></param>
        /// <returns></returns>
        public bool AddSymbol(Autodesk.Revit.DB.FamilySymbol framingSymbol)
        {
            if (ContainsSymbolName(framingSymbol.Name))
            {
                return false;
            }
            m_symbolMaps.Add(framingSymbol.Name, framingSymbol);
            m_symbols.Add(framingSymbol);
            return true;
        }

        /// delete one FamilySymbol both in Revit and lists here
        /// </summary>
        /// <param name="symbol">FamilySymbol to be deleted</param>
        /// <returns>successful to delete</returns>
        public bool DeleteSymbol(FamilySymbol symbol)
        {
            try
            {              
                // remove from the lists
                m_symbolMaps.Remove(symbol.Name);
                m_symbols.Remove(symbol);
                // delete from Revit
                List<ElementId> ids = m_commandData.Application.ActiveUIDocument.Document.Delete(symbol.Id) as List<ElementId>;
                if (ids.Count == 0)
                {
                    return false;
                }               
            }
            catch
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// duplicate one FamilySymbol and add to lists
        /// </summary>
        /// <param name="framingSymbol">FamilySymbol to be copied</param>
        /// <param name="symbolName">duplicate FamilySymbol's Name</param>
        /// <returns>new FamilySymbol</returns>
        public FamilySymbol DuplicateSymbol(ElementType framingSymbol, string symbolName)
        {
            // duplicate a FamilySymbol
            ElementType symbol = framingSymbol.Duplicate(GenerateSymbolName(symbolName));
            FamilySymbol result = symbol as FamilySymbol;
            if (null != result)
            {
                // add to lists
                m_symbolMaps.Add(result.Name, result);
                m_symbols.Add(result);
            }
            return result;
        }

        /// <summary>
        /// inquire whether the FamilySymbol's Name already exists in the list
        /// </summary>
        /// <param name="symbolName"></param>
        /// <returns></returns>
        public bool ContainsSymbolName(string symbolName)
        {
            return m_symbolMaps.ContainsKey(symbolName);
        }

        /// <summary>
        /// generate a new FamilySymbol's Name according to given name
        /// </summary>
        /// <param name="symbolName">original name</param>
        /// <returns>generated name</returns>
        public string GenerateSymbolName(string symbolName)
        {
            int suffix = 2;
            string result = symbolName;
            while (ContainsSymbolName(result))
            {
                result = symbolName + " " + suffix.ToString();
                suffix++;
            }
            return result;
        }
    }
}