应用程序: FoundationSlab

Revit平台: 所有

Revit版本: 2011.0

首次发布: 9.1

编程语言: C#

技能水平: 中级

类别: 元素

类型: 外部命令

主题: 创建基础板。

摘要:

本示例演示如何创建基础板。

相关类:

Autodesk.Revit.UI.IExternalCommand

Autodesk.Revit.DB.Floor

Autodesk.Revit.DB.FloorType

Autodesk.Revit.DB.Document

项目文件:

Command.cs

该文件包含实现接口IExternalCommandCommand类。它创建了一个基础板表单的SlabData实例并显示该表单。

 

RegularSlab.cs

该文件包含一个常规板的类。按照其边界框创建一个八边形剖面。

 

FoundationSlabForm.cs

该文件包含一个显示基础板属性和剖面的类。

 

SlabData.cs

该文件包含一个SlabData类,它是RevitAPIFoundationSlabForm之间的中介者。它具有一组函数来创建基础板,查找所有常规水平板,获取板的剖面,验证板是否平面等。

 

Sketch.cs

该文件包含一个用于绘制板的剖面的内部类。

描述:

- 要获取板,需要通过文档迭代来查找'Floor'对象。

- floor参数中可以找到Mark属性:BuiltInParameter.ALL_MODEL_MARK

- 可以通过迭代文档来查找类别为“结构基础”的“FloorType”对象来找到基础板类型。

- 可以通过使用给定的水平剖面和指定的基础板样式的'NewFloor'方法创建基础板。

- 结构板的剖面可以在其AnalyticalModel属性中找到。非结构地面的剖面可以通过其Geometry属性形成。

- 八边形剖面是一个由平面线组成的数组,表示八边形基础板的水平剖面。

- 确保板的剖面是一个封闭的轮廓线,否则它不能被Revit创建。

说明:

1. 准备Revit项目。

打开或新建Revit项目,确保文档中有一些地板。示例项目文件FoundationSlab.rvt可在示例文件夹中找到。

2. 运行命令。

3. 在常规板组中,选择要进行更改的地板。

4. 在对话框底部,选择要应用的基础板类型。

5. 您可以在Picture Box中看到转换结果的预览。单击OK按钮以为选定的地板创建八边形板。

源代码:

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

FoundationSlabForm.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 ITS 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.FoundationSlab.CS
{
    partial class FoundationSlabForm
    {
        /// <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()
        {
            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
            this.pictureBox = new System.Windows.Forms.PictureBox();
            this.okButton = new System.Windows.Forms.Button();
            this.diagramGroupBox = new System.Windows.Forms.GroupBox();
            this.gridGroupBox = new System.Windows.Forms.GroupBox();
            this.clearAllButton = new System.Windows.Forms.Button();
            this.selectAllButton = new System.Windows.Forms.Button();
            this.dataGridView = new System.Windows.Forms.DataGridView();
            this.typeComboBox = new System.Windows.Forms.ComboBox();
            this.typeLabel = new System.Windows.Forms.Label();
            this.cancelButton = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
            this.diagramGroupBox.SuspendLayout();
            this.gridGroupBox.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
            this.SuspendLayout();
            // 
            // pictureBox
            // 
            this.pictureBox.BackColor = System.Drawing.SystemColors.ControlText;
            this.pictureBox.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.pictureBox.Location = new System.Drawing.Point(6, 19);
            this.pictureBox.Name = "pictureBox";
            this.pictureBox.Size = new System.Drawing.Size(419, 296);
            this.pictureBox.TabIndex = 0;
            this.pictureBox.TabStop = false;
            this.pictureBox.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox_Paint);
            // 
            // okButton
            // 
            this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.okButton.Location = new System.Drawing.Point(271, 524);
            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);
            // 
            // diagramGroupBox
            // 
            this.diagramGroupBox.Controls.Add(this.pictureBox);
            this.diagramGroupBox.ForeColor = System.Drawing.Color.Black;
            this.diagramGroupBox.Location = new System.Drawing.Point(12, 12);
            this.diagramGroupBox.Name = "diagramGroupBox";
            this.diagramGroupBox.Size = new System.Drawing.Size(431, 321);
            this.diagramGroupBox.TabIndex = 2;
            this.diagramGroupBox.TabStop = false;
            this.diagramGroupBox.Text = "Slabs Diagram (Analytical Model)";
            // 
            // gridGroupBox
            // 
            this.gridGroupBox.Controls.Add(this.clearAllButton);
            this.gridGroupBox.Controls.Add(this.selectAllButton);
            this.gridGroupBox.Controls.Add(this.dataGridView);
            this.gridGroupBox.ForeColor = System.Drawing.Color.Black;
            this.gridGroupBox.Location = new System.Drawing.Point(12, 339);
            this.gridGroupBox.Name = "gridGroupBox";
            this.gridGroupBox.Size = new System.Drawing.Size(431, 160);
            this.gridGroupBox.TabIndex = 3;
            this.gridGroupBox.TabStop = false;
            this.gridGroupBox.Text = "Regular Slabs";
            // 
            // clearAllButton
            // 
            this.clearAllButton.ForeColor = System.Drawing.SystemColors.ControlText;
            this.clearAllButton.Location = new System.Drawing.Point(350, 62);
            this.clearAllButton.Name = "clearAllButton";
            this.clearAllButton.Size = new System.Drawing.Size(75, 23);
            this.clearAllButton.TabIndex = 2;
            this.clearAllButton.Text = "&Clear All";
            this.clearAllButton.UseVisualStyleBackColor = true;
            this.clearAllButton.Click += new System.EventHandler(this.clearAllButton_Click);
            // 
            // selectAllButton
            // 
            this.selectAllButton.ForeColor = System.Drawing.SystemColors.ControlText;
            this.selectAllButton.Location = new System.Drawing.Point(349, 19);
            this.selectAllButton.Name = "selectAllButton";
            this.selectAllButton.Size = new System.Drawing.Size(75, 23);
            this.selectAllButton.TabIndex = 1;
            this.selectAllButton.Text = "&Select All";
            this.selectAllButton.UseVisualStyleBackColor = true;
            this.selectAllButton.Click += new System.EventHandler(this.selectAllButton_Click);
            // 
            // dataGridView
            // 
            this.dataGridView.AllowUserToResizeRows = false;
            this.dataGridView.BackgroundColor = System.Drawing.SystemColors.Window;
            this.dataGridView.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
            dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window;
            dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            dataGridViewCellStyle2.ForeColor = System.Drawing.Color.Black;
            dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
            dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
            dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
            this.dataGridView.DefaultCellStyle = dataGridViewCellStyle2;
            this.dataGridView.Location = new System.Drawing.Point(6, 19);
            this.dataGridView.Name = "dataGridView";
            this.dataGridView.RowHeadersWidth = 30;
            this.dataGridView.Size = new System.Drawing.Size(337, 133);
            this.dataGridView.TabIndex = 0;
            this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);
            this.dataGridView.CurrentCellDirtyStateChanged += new System.EventHandler(this.dataGridView_CurrentCellDirtyStateChanged);
            this.dataGridView.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellValueChanged);
            // 
            // typeComboBox
            // 
            this.typeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.typeComboBox.FormattingEnabled = true;
            this.typeComboBox.Location = new System.Drawing.Point(18, 525);
            this.typeComboBox.Name = "typeComboBox";
            this.typeComboBox.Size = new System.Drawing.Size(181, 21);
            this.typeComboBox.TabIndex = 4;
            this.typeComboBox.SelectedIndexChanged += new System.EventHandler(this.typeComboBox_SelectedIndexChanged);
            // 
            // typeLabel
            // 
            this.typeLabel.AutoSize = true;
            this.typeLabel.ForeColor = System.Drawing.Color.Black;
            this.typeLabel.Location = new System.Drawing.Point(15, 505);
            this.typeLabel.Name = "typeLabel";
            this.typeLabel.Size = new System.Drawing.Size(149, 13);
            this.typeLabel.TabIndex = 5;
            this.typeLabel.Text = "Select Foundation Slab Types";
            // 
            // cancelButton
            // 
            this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.cancelButton.Location = new System.Drawing.Point(362, 524);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.Size = new System.Drawing.Size(75, 23);
            this.cancelButton.TabIndex = 0;
            this.cancelButton.Text = "&Cancel";
            this.cancelButton.UseVisualStyleBackColor = true;
            this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
            // 
            // FoundationSlabForm
            // 
            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(455, 566);
            this.Controls.Add(this.cancelButton);
            this.Controls.Add(this.typeLabel);
            this.Controls.Add(this.typeComboBox);
            this.Controls.Add(this.gridGroupBox);
            this.Controls.Add(this.diagramGroupBox);
            this.Controls.Add(this.okButton);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "FoundationSlabForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Foundation Slab";
            this.Load += new System.EventHandler(this.FoundationSlabForm_Load);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
            this.diagramGroupBox.ResumeLayout(false);
            this.gridGroupBox.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.PictureBox pictureBox;
        private System.Windows.Forms.Button okButton;
        private System.Windows.Forms.GroupBox diagramGroupBox;
        private System.Windows.Forms.GroupBox gridGroupBox;
        private System.Windows.Forms.DataGridView dataGridView;
        private System.Windows.Forms.ComboBox typeComboBox;
        private System.Windows.Forms.Label typeLabel;
        private System.Windows.Forms.Button cancelButton;
        private System.Windows.Forms.Button clearAllButton;
        private System.Windows.Forms.Button selectAllButton;
    }
}

RegularSlab.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 ITS 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.Collections.Generic;
using System.Text;

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

namespace Revit.SDK.Samples.FoundationSlab.CS
{
    /// <summary>
    /// A class of regular slab.
    /// </summary>
    public class RegularSlab
    {
        bool m_selected = true; // Be selected or not.
        string m_mark;   // The mark of the slab.
        Level m_level;   // The level of the slab.
        ElementType m_type; // The type of the slab.

        Autodesk.Revit.DB.ElementId m_id; // The id of the slab.
        CurveArray m_profile;  // The profile of the slab.
        CurveArray m_octagonalProfile; // The octagonal profile of the slab.
        BoundingBoxXYZ m_maxBBox; // The max bounding box of the slab.

        /// <summary>
        /// Selected property.
        /// </summary>
        public bool Selected
        {
            get { return m_selected; }
            set { m_selected = value; }
        }

        /// <summary>
        /// Mark property.
        /// </summary>
        public string Mark
        {
            get { return m_mark; }
        }

        /// <summary>
        /// LevelName property.
        /// </summary>
        public string LevelName
        {
            get { return m_level.Name; }
        }

        /// <summary>
        /// SlabTypeName property.
        /// </summary>
        public string SlabTypeName
        {
            get { return m_type.Name; }
        }

        /// <summary>
        /// Id property.
        /// </summary>
        public Autodesk.Revit.DB.ElementId Id
        {
            get { return m_id; }
        }

        /// <summary>
        /// Profile property.
        /// </summary>
        public CurveArray Profile
        {
            get { return m_profile; }
        }

        /// <summary>
        /// OctagonalProfile property.
        /// </summary>
        public CurveArray OctagonalProfile
        {
            get { return m_octagonalProfile; }
        }

        /// <summary>
        /// BBox property.
        /// </summary>
        public BoundingBoxXYZ BBox
        {
            get { return m_maxBBox; }
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="floor">The floor object.</param>
        /// <param name="floorProfile">The floor's profile.</param>
        /// <param name="bBox">The floor's bounding box.</param>
        public RegularSlab(Floor floor, CurveArray floorProfile, BoundingBoxXYZ bBox)
        {
            // Get floor's properties.
            if (null != floor)
            {
                // Get floor's Mark property.
                Parameter markPara = floor.get_Parameter(BuiltInParameter.ALL_MODEL_MARK);
                if (null != markPara)
                {
                    m_mark = markPara.AsString();
                }

                m_level = floor.Document.GetElement(floor.LevelId) as Level;   // Get floor's level.
                m_type = floor.Document.GetElement(floor.GetTypeId()) as ElementType;// Get floor's type.
                m_id = floor.Id; // Get floor's Id.
                m_profile = floorProfile;  // Get floor's profile.
            }

            // Create an octagonal profile for the floor according to it's bounding box.
            if (null != bBox)
            {
                CreateOctagonProfile(bBox.Min, bBox.Max);
            }
        }

        /// <summary>
        /// Create an octagonal profile.
        /// </summary>
        /// <param name="min">The min point of the floor's bounding box.</param>
        /// <param name="max">The max point of the floor's bounding box.</param>
        /// <returns>The bool value suggests successful or not.</returns>
        private bool CreateOctagonProfile(Autodesk.Revit.DB.XYZ min, Autodesk.Revit.DB.XYZ max)
        {
            // Calculate the x/y offset.
            double xOffset = Math.Abs(max.Y - min.Y) / 8;
            double yOffset = Math.Abs(max.X - min.X) / 8;
            double z = max.Z;

            // Calculate the eight points of the octagon.
            Autodesk.Revit.DB.XYZ[] points = new Autodesk.Revit.DB.XYZ[8];
            points[0] = new Autodesk.Revit.DB.XYZ(min.X, min.Y, z);
            points[1] = new Autodesk.Revit.DB.XYZ((min.X + max.X) / 2, (min.Y - yOffset), z);
            points[2] = new Autodesk.Revit.DB.XYZ(max.X, min.Y, z);
            points[3] = new Autodesk.Revit.DB.XYZ((max.X + xOffset), (min.Y + max.Y) / 2, z);
            points[4] = new Autodesk.Revit.DB.XYZ(max.X, max.Y, z);
            points[5] = new Autodesk.Revit.DB.XYZ((min.X + max.X) / 2, (max.Y + yOffset), z);
            points[6] = new Autodesk.Revit.DB.XYZ(min.X, max.Y, z);
            points[7] = new Autodesk.Revit.DB.XYZ((min.X - xOffset), (min.Y + max.Y) / 2, z);

            // Get the octagonal profile.
            m_octagonalProfile = new CurveArray();
            for (int i = 0; i < 8; i++)
            {
                Line line;
                if (7 == i)
                    line = Line.CreateBound(points[i], points[0]);
                else
                    line = Line.CreateBound(points[i], points[i + 1]);
                m_octagonalProfile.Append(line);
            }

            // Get the octagonal profile's bounding box.
            Autodesk.Revit.DB.XYZ newMin = new Autodesk.Revit.DB.XYZ(min.X - xOffset, min.Y - yOffset, z);
            Autodesk.Revit.DB.XYZ newMax = new Autodesk.Revit.DB.XYZ(max.X + xOffset, max.Y + yOffset, z);
            m_maxBBox = new BoundingBoxXYZ();
            m_maxBBox.Min = newMin;
            m_maxBBox.Max = newMax;

            return true;
        }

    }
}

Sketch.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 ITS 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.Collections.Generic;
using System.Text;

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections.ObjectModel;

using Autodesk.Revit.DB;

namespace Revit.SDK.Samples.FoundationSlab.CS
{
    /// <summary>
    /// An internal class for drawing slabs' profiles.
    /// This class is intended to contain only static methods.
    /// </summary>
    class Sketch
    {
        // A private constructor to prevent the compiler from generating a default constructor.
        private Sketch() { }

        /// <summary>
        /// Draw profiles.
        /// </summary>
        /// <param name="graphic">The object of Graphics to draw profiles.</param>
        /// <param name="rclip">The rectangle area to draw profiles.</param>
        /// <param name="baseSlabList">A set of base floors' datas containing profiles.</param>
        public static void DrawProfile(Graphics graphic, RectangleF rclip, Collection<RegularSlab> baseSlabList)
        {
            RectangleF maxBBox = GetMaxBBox(baseSlabList);    // Get the max bounding box's rectangle area.
            Matrix matrix = GetTransformMatrix(rclip, maxBBox); // Get the transform matrix.
            if (null == matrix)
                return;

            graphic.Clear(System.Drawing.Color.Black); // Clear the object of graphics.
            graphic.Transform = matrix;  // Transform the object of graphics.
            graphic.SmoothingMode = SmoothingMode.HighQuality; // Smooth it.

            // Two pens for drawing profiles.
            Pen yellowPen = new Pen(System.Drawing.Color.Yellow, (float)0.05);  // For floors' profiles.
            Pen greenPen = new Pen(System.Drawing.Color.Green, (float)0.2); // For octagonal profiles.

            // Draw profiles.
            foreach (RegularSlab slab in baseSlabList)
            {
                if (null != slab.Profile)
                {
                    DrawLine(yellowPen, graphic, slab.Profile);   // Draw floor's profiles.
                }
                if (slab.Selected)
                {
                    DrawLine(greenPen,graphic, slab.OctagonalProfile); // Draw octagonal profiles.
                }
            }

            // Dispose pen and matrix.
            yellowPen.Dispose();
            greenPen.Dispose();
            matrix.Dispose();
        }

        /// <summary>
        /// Draw Lines.
        /// </summary>
        /// <param name="pen">The pen to draw lines.</param>
        /// <param name="graphic">The object of graphics to draw lines.</param>
        /// <param name="curveArray">A set contains lines.</param>
        private static void DrawLine(Pen pen, Graphics graphic, CurveArray curveArray)
        {
            foreach (Curve curve in curveArray)
            {
                Line line = curve as Line;  // Draw one line.
                if (null != line)
                {
                    PointF startPoint = new PointF((float)line.GetEndPoint(0).X, (float)line.GetEndPoint(0).Y);
                    PointF endPoint = new PointF((float)line.GetEndPoint(1).X, (float)line.GetEndPoint(1).Y);
                    graphic.DrawLine(pen, startPoint, endPoint);
                    continue;
                }
                List<XYZ> xyzArray = curve.Tessellate() as List<XYZ>;    // Draw lines which form one arc.
                for (int i = 0; i < (xyzArray.Count - 1); i++)
                {
                    PointF startPoint = new PointF((float)xyzArray[i].X, (float)xyzArray[i].Y);
                    PointF endPoint = new PointF((float)xyzArray[i + 1].X, (float)xyzArray[i + 1].Y);
                    graphic.DrawLine(pen, startPoint, endPoint);
                }
            }
        }

        /// <summary>
        /// Get transform matrix.
        /// </summary>
        /// <param name="rclip">The rectangle area to draw profiles.</param>
        /// <param name="rBox">the rectangle area of the all the floors' max bounding box.</param>
        /// <returns>The transform matrix.</returns>
        private static Matrix GetTransformMatrix(RectangleF rclip, RectangleF rBox)
        {
            try
            {
                RectangleF rdraw = rclip;

                // Calculate the draw area according to the size of the sketch:
                // Adjust the shrink to change borders
                float shrink = (float)0.15, shrinked = (float)1.0 - 2 * shrink;
                if (rBox.Width * rclip.Height > rBox.Height * rclip.Width)
                    rdraw.Inflate(-rclip.Width * shrink, (rclip.Width * shrinked * (float)rBox.Height / (float)rBox.Width - rclip.Height) / 2);
                else
                    rdraw.Inflate((rclip.Height * shrinked * (float)rBox.Width / (float)rBox.Height - rclip.Width) / 2, -rclip.Height * shrink);

                // Mapping the point in sketch to point in draw area:
                PointF[] plgpts = new PointF[3];
                plgpts[0].X = rdraw.Left;
                plgpts[0].Y = rdraw.Bottom;
                plgpts[1].X = rdraw.Right;
                plgpts[1].Y = rdraw.Bottom;
                plgpts[2].X = rdraw.Left;
                plgpts[2].Y = rdraw.Top;

                // Get the transform matrix and return.
                return new Matrix(rBox, plgpts);
            }
            catch (ArithmeticException)
            {
                return null;
            }
            catch (OutOfMemoryException)
            {
                return null;
            }
        }

        /// <summary>
        /// Get the max bounding box of all floors.
        /// </summary>
        /// <param name="baseSlabList">A set of base floors' datas containing bounding box.</param>
        /// <returns>The rectangle area of all the base floors' max bounding box.</returns>
        private static RectangleF GetMaxBBox(Collection<RegularSlab> baseSlabList)
        {
            int count = 1;
            RectangleF union = new RectangleF();
            foreach (RegularSlab slab in baseSlabList)
            {
                float x = (float)(slab.BBox.Min.X);
                float y = (float)(slab.BBox.Min.Y);
                float width = (float)(slab.BBox.Max.X - slab.BBox.Min.X);
                float height = (float)(slab.BBox.Max.Y - slab.BBox.Min.Y);
                RectangleF slabBox = new RectangleF(x,y,width,height); // Rectangle area of each floor.
                if(1 == count)
                {
                    union = slabBox;
                }
                else
                {
                    union = RectangleF.Union(union, slabBox);   // The union of all the floors' rectangle areas.
                }
                count++;
            }
            return union;
        }

    }
}

SlabData.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 ITS 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.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;

using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB.Structure;

namespace Revit.SDK.Samples.FoundationSlab.CS
{
   /// <summary>
   /// A class collecting all useful datas from revit API for UI.
   /// </summary>
   public class SlabData
   {
      const double PlanarPrecision = 0.00033;

      // For finding elements and creating foundations slabs.
      public static Autodesk.Revit.UI.UIApplication m_revit;
      public static Autodesk.Revit.Creation.Application CreApp;
      // Foundation slab type for creating foundation slabs.
      FloorType m_foundationSlabType;
      // A set of levels to find out the lowest level of the building.
      SortedList<double, Level> m_levelList = new SortedList<double, Level>();
      // A set of views to find out the regular slab's bounding box.
      List<View> m_viewList = new List<View>();
      // A set of floors to find out all the regular slabs at the base of the building.
      List<Floor> m_floorList = new List<Floor>();

      // A set of regular slabs at the base of the building.
      // This set supplies all the regular slabs' datas for UI.
      List<RegularSlab> m_allBaseSlabList = new List<RegularSlab>();

      // A set of  the types of foundation slab.
      // This set supplies all the types of foundation slab for UI.
      List<FloorType> m_slabTypeList = new List<FloorType>();

      /// <summary>
      /// BaseSlabList property.
      /// This property is for UI. It can be edited by user.
      /// </summary>
      public Collection<RegularSlab> BaseSlabList
      {
         get { return new Collection<RegularSlab>(m_allBaseSlabList); }
      }

      /// <summary>
      /// FoundationSlabTypeList property.
      /// This property is for UI. It can not be edited by user.
      /// </summary>
      public ReadOnlyCollection<FloorType> FoundationSlabTypeList
      {
         get { return new ReadOnlyCollection<FloorType>(m_slabTypeList); }
      }

      /// <summary>
      /// FoundationSlabType property.
      /// This property gets value from UI to create foundation slabs.
      /// </summary>
      public object FoundationSlabType
      {
         set { m_foundationSlabType = value as FloorType; }
      }

      /// <summary>
      /// Constructor.
      /// </summary>
      /// <param name="revit">An application object that contains data related to revit command.</param>
      public SlabData(UIApplication revit)
      {
         m_revit = revit;
         CreApp = m_revit.Application.Create;
         // Find out all useful elements.
         FindElements();
         // Get all base slabs. If no slab be found, throw an exception and return cancel.
         if (!GetAllBaseSlabs())
            throw new NullReferenceException("No planar slabs at the base of the building.");
      }

      /// <summary>
      /// Check whether a regular slab is selected.
      /// </summary>
      /// <returns>The bool value suggest being selected or not.</returns>
      public bool CheckHaveSelected()
      {
         foreach (RegularSlab slab in m_allBaseSlabList)
         {
            if (slab.Selected)
               return true;
         }
         return false;
      }

      /// <summary>
      /// Change the Selected property for all regular slabs.
      /// </summary>
      /// <param name="value">The value for Selected property</param>
      public void ChangeAllSelected(bool value)
      {
         foreach (RegularSlab slab in m_allBaseSlabList)
         {
            slab.Selected = value;
         }
      }

      /// <summary>
      /// Create foundation slabs.
      /// </summary>
      /// <returns>The bool value suggest successful or not.</returns>
      public bool CreateFoundationSlabs()
      {
         // Create a foundation slab for each selected regular slab.
         foreach (RegularSlab slab in m_allBaseSlabList)
         {
            if (!slab.Selected)
            {
               continue;
            }

            // Create a new slab.
            Autodesk.Revit.DB.XYZ normal = new Autodesk.Revit.DB.XYZ(0, 0, 1);
            Transaction t = new Transaction(m_revit.ActiveUIDocument.Document, Guid.NewGuid().GetHashCode().ToString());
            t.Start();
            Floor foundationSlab = m_revit.ActiveUIDocument.Document.Create.NewFoundationSlab(
                slab.OctagonalProfile, m_foundationSlabType, m_levelList.Values[0],
                true, normal);
            t.Commit();
            if (null == foundationSlab)
            {
               return false;
            }

            // Delete the regular slab.
            Transaction t2 = new Transaction(m_revit.ActiveUIDocument.Document, Guid.NewGuid().GetHashCode().ToString());
            t2.Start();
            Autodesk.Revit.DB.ElementId deleteSlabId = slab.Id;
            m_revit.ActiveUIDocument.Document.Delete(deleteSlabId);
            t2.Commit();
         }
         return true;
      }

      /// <summary>
      /// Find out all useful elements.
      /// </summary>
      private void FindElements()
      {
         IList<ElementFilter> filters = new List<ElementFilter>(4);
         filters.Add(new ElementClassFilter(typeof(Level)));
         filters.Add(new ElementClassFilter(typeof(View)));
         filters.Add(new ElementClassFilter(typeof(Floor)));
         filters.Add(new ElementClassFilter(typeof(FloorType)));

         LogicalOrFilter orFilter = new LogicalOrFilter(filters);
         FilteredElementCollector collector = new FilteredElementCollector(m_revit.ActiveUIDocument.Document);
         FilteredElementIterator iterator = collector.WherePasses(orFilter).GetElementIterator();
         while (iterator.MoveNext())
         {
            // Find out all levels.
            Level level = (iterator.Current) as Level;
            if (null != level)
            {
               m_levelList.Add(level.Elevation, level);
               continue;
            }

            // Find out all views.
            View view = (iterator.Current) as View;
            if (null != view && !view.IsTemplate)
            {
               m_viewList.Add(view);
               continue;
            }

            // Find out all floors.
            Floor floor = (iterator.Current) as Floor;
            if (null != floor)
            {
               m_floorList.Add(floor);
               continue;
            }

            // Find out all foundation slab types.
            FloorType floorType = (iterator.Current) as FloorType;
            if (null == floorType)
            {
               continue;
            }
            if ("Structural Foundations" == floorType.Category.Name)
            {
               m_slabTypeList.Add(floorType);
            }
         }
      }

      /// <summary>
      /// Get all base slabs.
      /// </summary>
      /// <returns>A bool value suggests successful or not.</returns>
      private bool GetAllBaseSlabs()
      {
         // No level, no slabs.
         if (0 == m_levelList.Count)
            return false;

         // Find out the lowest level's view for finding the bounding box of slab.
         View baseView = null;
         foreach (View view in m_viewList)
         {
            if (view.Name == m_levelList.Values[0].Name)
            {
               baseView = view;
            }
         }
         if (null == baseView)
            return false;

         // Get all slabs at the base of the building.
         foreach (Floor floor in m_floorList)
         {
            if (floor.LevelId.IntegerValue == m_levelList.Values[0].Id.IntegerValue)
            {
               BoundingBoxXYZ bbXYZ = floor.get_BoundingBox(baseView);   // Get the slab's bounding box.

               // Check the floor. If the floor is planar, deal with it, otherwise, leap it.
               if (!IsPlanarFloor(bbXYZ, floor))
                  continue;

               CurveArray floorProfile = GetFloorProfile(floor);    // Get the slab's profile.
               RegularSlab regularSlab = new RegularSlab(floor, floorProfile, bbXYZ);   // Get a regular slab.
               m_allBaseSlabList.Add(regularSlab);  // Add regular slab to the set.
            }
         }

         // Getting regular slabs.
         if (0 != m_allBaseSlabList.Count)
            return true;
         else return false;
      }

      /// <summary>
      /// Check whether the floor is planar.
      /// </summary>
      /// <param name="bbXYZ">The floor's bounding box.</param>
      /// <param name="floor">The floor object.</param>
      /// <returns>A bool value suggests the floor is planar or not.</returns>
      private static bool IsPlanarFloor(BoundingBoxXYZ bbXYZ, Floor floor)
      {
         // Get floor thickness.
         double floorThickness = 0.0;
         ElementType floorType = m_revit.ActiveUIDocument.Document.GetElement(floor.GetTypeId()) as ElementType;
         Parameter attribute = floorType.get_Parameter(BuiltInParameter.FLOOR_ATTR_DEFAULT_THICKNESS_PARAM);
         if (null != attribute)
         {
            floorThickness = attribute.AsDouble();
         }

         // Get bounding box thickness.
         double boundThickness = Math.Abs(bbXYZ.Max.Z - bbXYZ.Min.Z);

         // Planar or not.
         if (Math.Abs(boundThickness - floorThickness) < PlanarPrecision)
            return true;
         else
            return false;
      }

      /// <summary>
      /// Get a floor's profile.
      /// </summary>
      /// <param name="floor">The floor whose profile you want to get.</param>
      /// <returns>The profile of the floor.</returns>
      private CurveArray GetFloorProfile(Floor floor)
      {
         CurveArray floorProfile = new CurveArray();
         // Structural slab's profile can be found in it's AnalyticalModel.
         if (null != floor.GetAnalyticalModel())
         {
            AnalyticalModel analyticalModel = floor.GetAnalyticalModel();
            IList<Curve> curveList = analyticalModel.GetCurves(AnalyticalCurveType.ActiveCurves);
            for (int i = 0; i < curveList.Count; i++)
            {
               floorProfile.Append(curveList[i]);
            }

            return floorProfile;
         }

         // Nonstructural floor's profile can be formed through it's Geometry.
         Options aOptions = m_revit.Application.Create.NewGeometryOptions();
         Autodesk.Revit.DB.GeometryElement aElementOfGeometry = floor.get_Geometry(aOptions);
         //GeometryObjectArray geometryObjects = aElementOfGeometry.Objects;
         IEnumerator<GeometryObject> Objects = aElementOfGeometry.GetEnumerator();
         //foreach (GeometryObject o in geometryObjects)
         while (Objects.MoveNext())
         {
            GeometryObject o = Objects.Current;

            Solid solid = o as Solid;
            if (null == solid)
               continue;

            // Form the floor's profile through solid's edges.
            EdgeArray edges = solid.Edges;
            for (int i = 0; i < (edges.Size) / 3; i++)
            {
               Edge edge = edges.get_Item(i);
               List<XYZ> xyzArray = edge.Tessellate() as List<XYZ>;  // A set of points.
               for (int j = 0; j < (xyzArray.Count - 1); j++)
               {
                  Autodesk.Revit.DB.XYZ startPoint = xyzArray[j];
                  Autodesk.Revit.DB.XYZ endPoint = xyzArray[j + 1];
                  Line line = Line.CreateBound(startPoint, endPoint);

                  floorProfile.Append(line);
               }
            }
         }
         return floorProfile;
      }

   }
}