应用程序:NewRoof

Revit平台:所有

Revit版本:2011.0

首次发布版本:2009.0

编程语言:C #

技能水平:高级

类别:元素

类型:ExternalCommand

主题:创建楼盖平面和挤压屋顶。

摘要:

本示例演示了四个主要功能:

1. 如何创建新的楼盖平面。

2. 如何创建挤压屋顶。

3. 如何编辑已存在的楼盖平面。

4. 如何编辑已存在的挤压屋顶。

类:

Autodesk.Revit.UI.IExternalCommand

Autodesk.Revit.DB.FootPrintRoof

Autodesk.Revit.DB.ExtrusionRoof

Autodesk.Revit.DB.Level

Autodesk.Revit.DB.RoofType

Autodesk.Revit.DB.Wall

Autodesk.Revit.DB.Curve

Autodesk.Revit.Creation.Document

项目文件:

Command.cs

该文件包含“命令”类,它继承自“IExternalCommand”接口并实现“Execute”方法。

 

RoofsManager.cs

它包含一个名为RoofsManager”的类,用于管理RevitAdd-In UI之间的操作。它具有创建楼盖平面、创建挤压屋顶、选择楼盖平面以创建楼盖平面和选择概要轮廓以创建挤压屋顶的功能。

 

FootPrintRoofManager.cs

它包含一个名为FootPrintRoofManager”的类,用于管理楼盖平面的创建。

 

ExtrusionRoofManager.cs

它包含一个名为ExtrusionRoofManager”的类,用于管理挤压屋顶的创建。

 

RoofForm.cs

它包含一个名为RoofForm”的类,是Add-In应用程序的主要UI

 

RoofEditorForm.cs

它包含一个名为RoofEditorForm”的类,用于编辑RoofForm中选择的屋顶的UI。它包含一个PropertyGrid,允许用户修改所选屋顶的属性或参数。

 

GraphicsControl.cs

它包含一个名为GraphicsControl”的类,用于在用户编辑楼盖平面时在picture box控件中显示楼盖平面线。在控件中,修改楼盖平面线将被突出显示。

 

CustomTypeConverter.cs

它包含一个LevelConverter类和一个FootPrintRoofLineConverter类。它们用于自定义PropertyGrid控件中一些属性的显示。

 

FootPrintRoofWrapper.cs

它包含一个FootPrintRoofWrapper类和一个FootPrintRoofLine类。FootPrintRoofWrapper类用于包装楼盖平面,以在PropertyGrid控件中编辑屋顶。FootPrintRoofLine用于在PropertyGrid中编辑楼盖平面线,该线可以在GDI中绘制。

 

ExtrusionRoofWrapper.cs

它包含一个名为ExtrusionRoofWrapper”的类,用于包装挤出屋顶以在PropertyGrid控件中编辑屋顶。

描述:

功能:

- 获取活动文档中所有楼盖平面和挤压屋顶,并按创建方式分组列出它们。

- 通过指定曲线环、墙环或墙和曲线组合的环、标高和屋顶类型来创建具有默认属性的楼盖平面。

- 通过提供一系列相连的未封闭线或弧线、屋顶类型、参考平面、挤出起始值和挤出结束值来创建挤出屋顶。注意,参考平面应为垂直平面。

- 在列表中选择楼盖平面,然后用户可以定义楼盖平面线是坡度定义的,并更改所选屋顶的坡度角度。还可以相应地更改屋顶线的其他属性,例如悬挑、底部偏移、延伸进墙。只需选择不同的类型即可更改屋顶的类型。

- 选择列表中的挤出屋顶,然后用户可以更改挤出开始值、挤压结束值以及挤压屋顶的类型和参考标高。

 

实现:

- 使用元素过滤器来获取所有种类的屋顶。

- 使用FootPrintRoof NewFootPrintRoof(CurveArray footPrint, Level level,RoofType roofType, ElementIdSet footPrintToModelCurvesMapping)方法创建楼盖平面。足迹可以通过Selection类的WindowsSelect()方法指定。屋顶类型可以通过Autodesk.Revit.DB.Document.RoofTypes属性获得。

- 使用ExtrusionRoof NewExtrusionRoof(CurveArray profile, ReferencePlane refPlane, Level level, RoofType roofType, double extrusionStart, double extrusionEnd)方法创建挤压屋顶。可以使用WindowsSelect方法指定轮廓,并且参考平面应为垂直平面,并且可以使用元素过滤功能获取。

- 通过访问所选屋顶的属性或参数来编辑楼盖平面或挤压屋顶。

说明:

1. 打开Revit Architecture 2009文件。样本项目文件NewRoof.rvt位于样本文件夹中。

2. 绘制曲线环或墙体环或墙体和曲线的组合,以在Revit中创建基础屋顶。

3. 运行此命令。

4. 一个对话框将显示以显示所有现有的屋顶。基础屋顶将在“基础屋顶”选项卡页中列出,挤压屋顶将在“挤压”选项卡页中列出。

5. 在“基础屋顶”选项卡页中,单击“在Revit中选择基础屋顶”按钮以选择您刚刚创建的基础屋顶。选择一个基本层和屋顶类型,然后单击“创建”按钮,一个基础屋顶将被创建在Revit中,并将被列在“基础屋顶”选项卡页中。单击“确定”按钮接受创建或单击“取消”按钮放弃。

6. Revit中绘制一系列相连的直线或弧线,不闭合成环,以创建一个剖面。在Revit中绘制一个参考平面,用于拉伸剖面以创建挤出屋顶。请确保参考平面是垂直的,否则挤出屋顶将无法成功创建。如果Revit中有许多参考平面,则最好为每个平面创建一个良好的名称以区分它们。

7. 在“挤压”选项卡页中,单击“在Revit中选择剖面”按钮以选择您所创建的剖面。选择一个参考平面、参考层、屋顶类型并指定挤出起点和挤出终点值,然后单击“创建”按钮;一个挤压屋顶将被创建在Revit中,并将被列在“挤压”选项卡页中。有关挤压起点和挤压终点的更多信息,最好参考Revit提供的帮助文件的挤压屋顶部分。单击“确定”按钮接受创建或单击“取消”按钮放弃。

8. 编辑基础屋顶。您可以选择一个基础屋顶并单击“编辑”按钮,或者您可以在“基础屋顶”选项卡页中双击屋顶;一个屋顶编辑器表单将被显示。您可以在PropertyGrid中编辑屋顶的属性。基础屋顶线也将被显示;当前在PropertyGird中选择的屋顶线将被用红色突出显示。您可以在屋顶类型组合框中修改屋顶类型。完成修改后,您可以单击“确定”按钮接受更改或单击“取消”按钮放弃。

9. 编辑挤出屋顶。您可以选择一个挤出屋顶并单击“编辑”按钮,或者您可以在“挤出”选项卡页中双击屋顶;一个屋顶编辑器表单将被显示。您可以在PropertyGird中编辑挤出屋顶的参数。完成修改后,您可以单击“确定”按钮接受更改或单击“取消”按钮放弃。

源代码

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

RoofsManager.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 System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Forms;
using System.Text;
using System.Linq;

using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

using Revit.SDK.Samples.NewRoof.RoofForms.CS;

namespace Revit.SDK.Samples.NewRoof.RoofsManager.CS
{
    /// <summary>
    /// The kinds of roof than can be created.
    /// </summary>
    public enum CreateRoofKind
    {
        FootPrintRoof,
        ExtrusionRoof
    };

    /// <summary>
    /// The RoofsManager is used to manage the operations between Revit and UI.
    /// </summary>
    public class RoofsManager
    {
        // To store a reference to the commandData.
        ExternalCommandData m_commandData;
        // To store the levels info in the Revit.
        List<Level> m_levels;
        // To store the roof types info in the Revit.
        List<RoofType> m_roofTypes;
        // To store a reference to the FootPrintRoofManager to create footprint roof.
        FootPrintRoofManager m_footPrintRoofManager;
        // To store a reference to the ExtrusionRoofManager to create extrusion roof.
        ExtrusionRoofManager m_extrusionRoofManager;

        // To store the selected elements in the Revit
        Selection m_selection;

        // roofs list
        ElementSet m_footPrintRoofs;
        ElementSet m_extrusionRoofs;

        // To store the footprint roof lines.
        Autodesk.Revit.DB.CurveArray m_footPrint;

        // To store the profile lines.
        Autodesk.Revit.DB.CurveArray m_profile;

        // Reference Plane for creating extrusion roof
        List<ReferencePlane> m_referencePlanes;

        // Transaction for manual mode
        Transaction m_transaction;

        // Current creating roof kind.
        public CreateRoofKind RoofKind;

        /// <summary>
        /// The constructor of RoofsManager class.
        /// </summary>
        /// <param name="commandData">The ExternalCommandData</param>
        public RoofsManager(ExternalCommandData commandData)
        {
            m_commandData = commandData;
            m_levels = new List<Level>();
            m_roofTypes = new List<RoofType>();
            m_referencePlanes = new List<ReferencePlane>();

            m_footPrint = new CurveArray();
            m_profile = new CurveArray();

            m_footPrintRoofManager = new FootPrintRoofManager(commandData);
            m_extrusionRoofManager = new ExtrusionRoofManager(commandData);
            m_selection = commandData.Application.ActiveUIDocument.Selection;

            m_transaction = new Transaction(commandData.Application.ActiveUIDocument.Document, "Document");

            RoofKind = CreateRoofKind.FootPrintRoof;
            Initialize();
        }

        /// <summary>
        /// Initialize the data member
        /// </summary>
        private void Initialize()
        {
            Document doc = m_commandData.Application.ActiveUIDocument.Document;
            FilteredElementIterator iter = (new FilteredElementCollector(doc)).OfClass(typeof(Level)).GetElementIterator();
            iter.Reset();
            while (iter.MoveNext())
            {
                m_levels.Add(iter.Current as Level);
            }

            FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
            filteredElementCollector.OfClass(typeof(RoofType));
            m_roofTypes = filteredElementCollector.Cast<RoofType>().ToList<RoofType>();

            // FootPrint Roofs
            m_footPrintRoofs = new ElementSet();
            iter = (new FilteredElementCollector(doc)).OfClass(typeof(FootPrintRoof)).GetElementIterator();
            iter.Reset();
            while (iter.MoveNext())
            {
                m_footPrintRoofs.Insert(iter.Current as FootPrintRoof);
            }

            // Extrusion Roofs
            m_extrusionRoofs = new ElementSet();
            iter = (new FilteredElementCollector(doc)).OfClass(typeof(ExtrusionRoof)).GetElementIterator();
            iter.Reset();
            while (iter.MoveNext())
            {
                m_extrusionRoofs.Insert(iter.Current as ExtrusionRoof);
            }

            // Reference Planes
            iter = (new FilteredElementCollector(doc)).OfClass(typeof(ReferencePlane)).GetElementIterator();
            iter.Reset();
            while (iter.MoveNext())
            {
                ReferencePlane plane = iter.Current as ReferencePlane;
                // just use the vertical plane
                if (Math.Abs(plane.Normal.DotProduct(Autodesk.Revit.DB.XYZ.BasisZ)) < 1.0e-09)
                {
                    if (plane.Name == "Reference Plane")
                    {
                        plane.Name = "Reference Plane" + "(" + plane.Id.IntegerValue.ToString() + ")";
                    }
                    m_referencePlanes.Add(plane);
                }

            }
        }

        /// <summary>
        /// Get the Level elements.
        /// </summary>
        public ReadOnlyCollection<Level> Levels
        {
            get
            {
                return new ReadOnlyCollection<Level>(m_levels);
            }
        }

        /// <summary>
        /// Get the RoofTypes.
        /// </summary>
        public ReadOnlyCollection<RoofType> RoofTypes
        {
            get
            {
                return new ReadOnlyCollection<RoofType>(m_roofTypes);
            }
        }

        /// <summary>
        /// Get the RoofTypes.
        /// </summary>
        public ReadOnlyCollection<ReferencePlane> ReferencePlanes
        {
            get
            {
                return new ReadOnlyCollection<ReferencePlane>(m_referencePlanes);
            }
        }

        /// <summary>
        /// Get all the footprint roofs in Revit.
        /// </summary>
        public ElementSet FootPrintRoofs
        {
            get
            {
                return m_footPrintRoofs;
            }
        }

        /// <summary>
        /// Get all the extrusion roofs in Revit.
        /// </summary>
        public ElementSet ExtrusionRoofs
        {
            get
            {
                return m_extrusionRoofs;
            }
        }

        /// <summary>
        /// Get the footprint roof lines.
        /// </summary>
        public CurveArray FootPrint
        {
            get
            {
                return m_footPrint;
            }
        }

        /// <summary>
        /// Get the extrusion profile lines.
        /// </summary>
        public CurveArray Profile
        {
            get
            {
                return m_profile;
            }
        }

        /// <summary>
        /// Select elements in Revit to obtain the footprint roof lines or extrusion profile lines.
        /// </summary>
        /// <returns>A curve array to hold the footprint roof lines or extrusion profile lines.</returns>
        public CurveArray WindowSelect()
        {
            if (RoofKind == CreateRoofKind.FootPrintRoof)
            {
                return SelectFootPrint();
            }
            else
            {
                return SelectProfile();
            }
        }

        /// <summary>
        /// Select elements in Revit to obtain the footprint roof lines. 
        /// </summary>
        /// <returns>A curve array to hold the footprint roof lines.</returns>
        public CurveArray SelectFootPrint()
        {
            m_footPrint.Clear();
            while (true)
            {
               ElementSet es = new ElementSet();
               foreach (ElementId elementId in m_selection.GetElementIds())
               {
                  es.Insert(m_commandData.Application.ActiveUIDocument.Document.GetElement(elementId));
               }
                es.Clear();
                IList<Element> selectResult;
                try
                {
                    selectResult = m_selection.PickElementsByRectangle();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    break;
                }

                if (selectResult.Count != 0)
                {
                    foreach (Autodesk.Revit.DB.Element element in selectResult)
                    {
                        Wall wall = element as Wall;
                        if (wall != null)
                        {
                            LocationCurve wallCurve = wall.Location as LocationCurve;
                            m_footPrint.Append(wallCurve.Curve);
                            continue;
                        }

                        ModelCurve modelCurve = element as ModelCurve;
                        if (modelCurve != null)
                        {
                            m_footPrint.Append(modelCurve.GeometryCurve);
                        }
                    }
                    break;
                }
                else
                {
                    TaskDialogResult result = TaskDialog.Show("Warning", "You should select a curve loop, or a wall loop, or loops combination \r\nof walls and curves to create a footprint roof.", TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel);
                    if (result == TaskDialogResult.Cancel)
                    {
                        break;
                    }
                }


            }

            return m_footPrint;
        }

        /// <summary>
        /// Create a footprint roof. 
        /// </summary>
        /// <param name="level">The base level of the roof to be created.</param>
        /// <param name="roofType">The type of the newly created roof.</param>
        /// <returns>Return a new created footprint roof.</returns>
        public FootPrintRoof CreateFootPrintRoof(Level level, RoofType roofType)
        {
            FootPrintRoof roof = null;
            roof = m_footPrintRoofManager.CreateFootPrintRoof(m_footPrint, level, roofType);
            if (roof != null)
            {
                this.m_footPrintRoofs.Insert(roof);
            }
            return roof;
        }

        /// <summary>
        /// Select elements in Revit to obtain the extrusion profile lines.
        /// </summary>
        /// <returns>A curve array to hold the extrusion profile lines.</returns>
        public CurveArray SelectProfile()
        {
            m_profile.Clear();
            while (true)
            {
                m_selection.GetElementIds().Clear();
                IList<Element> selectResult;
                try
                {
                    selectResult = m_selection.PickElementsByRectangle();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    break;
                }
                if (selectResult.Count != 0)
                {
                    foreach (Autodesk.Revit.DB.Element element in selectResult)
                    {
                        ModelCurve modelCurve = element as ModelCurve;
                        if (modelCurve != null)
                        {
                            m_profile.Append(modelCurve.GeometryCurve);
                            continue;
                        }
                    }
                    break;
                }
                else
                {
                    TaskDialogResult result = TaskDialog.Show("Warning", "You should select a  connected lines or arcs, \r\nnot closed in a loop to create extrusion roof.", TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel);
                    if (result == TaskDialogResult.Cancel)
                    {
                        break;
                    }
                }
            }
            return m_profile;
        }

        /// <summary>
        /// Create a extrusion roof.
        /// </summary>
        /// <param name="refPlane">The reference plane for the extrusion roof.</param>
        /// <param name="level">The reference level of the roof to be created.</param>
        /// <param name="roofType">The type of the newly created roof.</param>
        /// <param name="extrusionStart">The extrusion start point.</param>
        /// <param name="extrusionEnd">The extrusion end point.</param>
        /// <returns>Return a new created extrusion roof.</returns>
        public ExtrusionRoof CreateExtrusionRoof(ReferencePlane refPlane,
            Level level, RoofType roofType, double extrusionStart, double extrusionEnd)
        {
            ExtrusionRoof roof = null;
            roof = m_extrusionRoofManager.CreateExtrusionRoof(m_profile, refPlane, level, roofType, extrusionStart, extrusionEnd);
            if (roof != null)
            {
                m_extrusionRoofs.Insert(roof);
            }
            return roof;
        }

        /// <summary>
        /// Begin a transaction.
        /// </summary>
        /// <returns></returns>
        public TransactionStatus BeginTransaction()
        {
            if (m_transaction.GetStatus() == TransactionStatus.Started)
            {
                TaskDialog.Show("Revit", "Transaction started already");
            }
            return m_transaction.Start();
        }

        /// <summary>
        /// Finish a transaction.
        /// </summary>
        /// <returns></returns>
        public TransactionStatus EndTransaction()
        {
            return m_transaction.Commit();
        }

        /// <summary>
        /// Abort a transaction.
        /// </summary>
        public TransactionStatus AbortTransaction()
        {
            return m_transaction.RollBack();
        }
    }
}

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

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

namespace Revit.SDK.Samples.NewRoof.RoofsManager.CS
{
    /// <summary>
    /// The FootPrintRoofManager class is to manage the creation of the footprint roof.
    /// </summary>
    class FootPrintRoofManager
    {
        // To store a reference to the commandData
        ExternalCommandData m_commandData;
        // To store a reference to the creation document
        Autodesk.Revit.Creation.Document m_creationDoc;
        // To store a reference to the creation application
        Autodesk.Revit.Creation.Application m_creationApp;

        /// <summary>
        /// The construct of ExtrusionRoofManager class.
        /// </summary>
        /// <param name="commandData">A reference to the commandData.</param>
        public FootPrintRoofManager(ExternalCommandData commandData)
        {
            m_commandData = commandData;
            m_creationDoc = m_commandData.Application.ActiveUIDocument.Document.Create;
            m_creationApp = m_commandData.Application.Application.Create;        
        }

        /// <summary>
        /// Create a footprint roof.
        /// </summary>
        /// <param name="footPrint">The footprint is a curve loop, or a wall loop, or loops combined of walls and curves</param>
        /// <param name="level">The base level of the roof to be created.</param>
        /// <param name="roofType">The type of the newly created roof.</param>
        /// <returns>Return a new created footprint roof.</returns>
        public FootPrintRoof CreateFootPrintRoof(CurveArray footPrint, Level level, RoofType roofType)
        {
            FootPrintRoof footprintRoof = null;
            Transaction createRoofTransaction = new Transaction(m_commandData.Application.ActiveUIDocument.Document, "FootPrintRoof");
            createRoofTransaction.Start();
            try
            {
                ModelCurveArray footPrintToModelCurveMapping = new ModelCurveArray();
                footprintRoof = m_creationDoc.NewFootPrintRoof(footPrint, level, roofType, out footPrintToModelCurveMapping);
                createRoofTransaction.Commit();
            }
            catch (System.Exception e)
            {
                createRoofTransaction.RollBack();
                throw e;
            }
            
            return footprintRoof;
        }

    }
}

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

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

namespace Revit.SDK.Samples.NewRoof.RoofsManager.CS
{
    /// <summary>
    /// The ExtrusionRoofManager class is to manage the creation of the Extrusion roof.
    /// </summary>
    class ExtrusionRoofManager
    {
        // To store a reference to the commandData
        ExternalCommandData m_commandData;
        // To store a reference to the creation document
        Autodesk.Revit.Creation.Document m_creationDoc;
        // To store a reference to the creation application
        Autodesk.Revit.Creation.Application m_creationApp;

        /// <summary>
        /// The construct of ExtrusionRoofManager class.
        /// </summary>
        /// <param name="commandData">A reference to the commandData.</param>
        public ExtrusionRoofManager(ExternalCommandData commandData)
        {
            m_commandData = commandData;
            m_creationDoc = m_commandData.Application.ActiveUIDocument.Document.Create;
            m_creationApp = m_commandData.Application.Application.Create;        
        }

        /// <summary>
        /// Create a extrusion roof.
        /// </summary>
        /// <param name="profile">The profile combined of straight lines and arcs.</param>
        /// <param name="refPlane">The reference plane for the extrusion roof.</param>
        /// <param name="level">The reference level of the roof to be created.</param>
        /// <param name="roofType">The type of the newly created roof.</param>
        /// <param name="extrusionStart">The extrusion start point.</param>
        /// <param name="extrusionEnd">The extrusion end point.</param>
        /// <returns>Return a new created extrusion roof.</returns>
        public ExtrusionRoof CreateExtrusionRoof(CurveArray profile, ReferencePlane refPlane, Level level, RoofType roofType,
            double extrusionStart, double extrusionEnd)
        {
            ExtrusionRoof extrusionRoof = null;
            Transaction createRoofTransaction = new Transaction(m_commandData.Application.ActiveUIDocument.Document, "ExtrusionRoof");
            createRoofTransaction.Start();
            try
            {
                extrusionRoof = m_creationDoc.NewExtrusionRoof(profile, refPlane, level, roofType, extrusionStart, extrusionEnd);
                createRoofTransaction.Commit();
            }
            catch (System.Exception e)
            {
                createRoofTransaction.RollBack();
                throw e;
            }
            
            return extrusionRoof;
        }
    }
}

RoofForm.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.NewRoof.RoofForms.CS
{
    partial class RoofForm
    {
        /// <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.footPrintRoofsListView = new System.Windows.Forms.ListView();
            this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader4 = new System.Windows.Forms.ColumnHeader();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.roofsTabControl = new System.Windows.Forms.TabControl();
            this.footprintRoofTabPage = new System.Windows.Forms.TabPage();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.roofTypesComboBox = new System.Windows.Forms.ComboBox();
            this.label3 = new System.Windows.Forms.Label();
            this.levelsComboBox = new System.Windows.Forms.ComboBox();
            this.levelLabel = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
            this.selectFootPrintButton = new System.Windows.Forms.Button();
            this.extrusionRoofTabPage = new System.Windows.Forms.TabPage();
            this.groupBox3 = new System.Windows.Forms.GroupBox();
            this.extrusionEndTextBox = new System.Windows.Forms.TextBox();
            this.label5 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.extrusionStartTextBox = new System.Windows.Forms.TextBox();
            this.refPanesComboBox = new System.Windows.Forms.ComboBox();
            this.label2 = new System.Windows.Forms.Label();
            this.extrusionRoofTypesComboBox = new System.Windows.Forms.ComboBox();
            this.label6 = new System.Windows.Forms.Label();
            this.refLevelComboBox = new System.Windows.Forms.ComboBox();
            this.label7 = new System.Windows.Forms.Label();
            this.label8 = new System.Windows.Forms.Label();
            this.selectProfileButton = new System.Windows.Forms.Button();
            this.extrusionRoofsListView = new System.Windows.Forms.ListView();
            this.columnHeader5 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader6 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader7 = new System.Windows.Forms.ColumnHeader();
            this.columnHeader8 = new System.Windows.Forms.ColumnHeader();
            this.editRoofButton = new System.Windows.Forms.Button();
            this.createRoofButton = new System.Windows.Forms.Button();
            this.okButton = new System.Windows.Forms.Button();
            this.cancelButton = new System.Windows.Forms.Button();
            this.groupBox1.SuspendLayout();
            this.roofsTabControl.SuspendLayout();
            this.footprintRoofTabPage.SuspendLayout();
            this.groupBox2.SuspendLayout();
            this.extrusionRoofTabPage.SuspendLayout();
            this.groupBox3.SuspendLayout();
            this.SuspendLayout();
            // 
            // footPrintRoofsListView
            // 
            this.footPrintRoofsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.columnHeader1,
            this.columnHeader2,
            this.columnHeader3,
            this.columnHeader4});
            this.footPrintRoofsListView.Location = new System.Drawing.Point(3, 6);
            this.footPrintRoofsListView.Name = "footPrintRoofsListView";
            this.footPrintRoofsListView.Size = new System.Drawing.Size(368, 231);
            this.footPrintRoofsListView.TabIndex = 2;
            this.footPrintRoofsListView.UseCompatibleStateImageBehavior = false;
            this.footPrintRoofsListView.View = System.Windows.Forms.View.Details;
            // 
            // columnHeader1
            // 
            this.columnHeader1.Text = "Roof Id";
            // 
            // columnHeader2
            // 
            this.columnHeader2.Text = "Name";
            // 
            // columnHeader3
            // 
            this.columnHeader3.Text = "Base Level";
            // 
            // columnHeader4
            // 
            this.columnHeader4.Text = "Roof Type";
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.roofsTabControl);
            this.groupBox1.Controls.Add(this.editRoofButton);
            this.groupBox1.Controls.Add(this.createRoofButton);
            this.groupBox1.Location = new System.Drawing.Point(2, 2);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(395, 447);
            this.groupBox1.TabIndex = 3;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Roofs";
            // 
            // roofsTabControl
            // 
            this.roofsTabControl.Controls.Add(this.footprintRoofTabPage);
            this.roofsTabControl.Controls.Add(this.extrusionRoofTabPage);
            this.roofsTabControl.Location = new System.Drawing.Point(6, 19);
            this.roofsTabControl.Name = "roofsTabControl";
            this.roofsTabControl.SelectedIndex = 0;
            this.roofsTabControl.Size = new System.Drawing.Size(382, 383);
            this.roofsTabControl.TabIndex = 5;
            // 
            // footprintRoofTabPage
            // 
            this.footprintRoofTabPage.Controls.Add(this.groupBox2);
            this.footprintRoofTabPage.Controls.Add(this.footPrintRoofsListView);
            this.footprintRoofTabPage.Location = new System.Drawing.Point(4, 22);
            this.footprintRoofTabPage.Name = "footprintRoofTabPage";
            this.footprintRoofTabPage.Padding = new System.Windows.Forms.Padding(3);
            this.footprintRoofTabPage.Size = new System.Drawing.Size(374, 357);
            this.footprintRoofTabPage.TabIndex = 0;
            this.footprintRoofTabPage.Text = "Footprint Roofs";
            this.footprintRoofTabPage.UseVisualStyleBackColor = true;
            // 
            // groupBox2
            // 
            this.groupBox2.Controls.Add(this.roofTypesComboBox);
            this.groupBox2.Controls.Add(this.label3);
            this.groupBox2.Controls.Add(this.levelsComboBox);
            this.groupBox2.Controls.Add(this.levelLabel);
            this.groupBox2.Controls.Add(this.label1);
            this.groupBox2.Controls.Add(this.selectFootPrintButton);
            this.groupBox2.Location = new System.Drawing.Point(6, 243);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(365, 108);
            this.groupBox2.TabIndex = 3;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "Create FootPrintRoof";
            // 
            // roofTypesComboBox
            // 
            this.roofTypesComboBox.FormattingEnabled = true;
            this.roofTypesComboBox.Location = new System.Drawing.Point(64, 73);
            this.roofTypesComboBox.Name = "roofTypesComboBox";
            this.roofTypesComboBox.Size = new System.Drawing.Size(295, 21);
            this.roofTypesComboBox.TabIndex = 6;
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(6, 76);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(60, 13);
            this.label3.TabIndex = 5;
            this.label3.Text = "Roof Type:";
            // 
            // levelsComboBox
            // 
            this.levelsComboBox.FormattingEnabled = true;
            this.levelsComboBox.Location = new System.Drawing.Point(64, 46);
            this.levelsComboBox.Name = "levelsComboBox";
            this.levelsComboBox.Size = new System.Drawing.Size(295, 21);
            this.levelsComboBox.TabIndex = 4;
            // 
            // levelLabel
            // 
            this.levelLabel.AutoSize = true;
            this.levelLabel.Location = new System.Drawing.Point(6, 49);
            this.levelLabel.Name = "levelLabel";
            this.levelLabel.Size = new System.Drawing.Size(36, 13);
            this.levelLabel.TabIndex = 3;
            this.levelLabel.Text = "Level:";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(6, 22);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(51, 13);
            this.label1.TabIndex = 2;
            this.label1.Text = "Footprint:";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // selectFootPrintButton
            // 
            this.selectFootPrintButton.DialogResult = System.Windows.Forms.DialogResult.Retry;
            this.selectFootPrintButton.Location = new System.Drawing.Point(64, 17);
            this.selectFootPrintButton.Name = "selectFootPrintButton";
            this.selectFootPrintButton.Size = new System.Drawing.Size(295, 23);
            this.selectFootPrintButton.TabIndex = 1;
            this.selectFootPrintButton.Text = "&Select Footprint in Revit";
            this.selectFootPrintButton.UseVisualStyleBackColor = true;
            // 
            // extrusionRoofTabPage
            // 
            this.extrusionRoofTabPage.Controls.Add(this.groupBox3);
            this.extrusionRoofTabPage.Controls.Add(this.extrusionRoofsListView);
            this.extrusionRoofTabPage.Location = new System.Drawing.Point(4, 22);
            this.extrusionRoofTabPage.Name = "extrusionRoofTabPage";
            this.extrusionRoofTabPage.Padding = new System.Windows.Forms.Padding(3);
            this.extrusionRoofTabPage.Size = new System.Drawing.Size(374, 357);
            this.extrusionRoofTabPage.TabIndex = 1;
            this.extrusionRoofTabPage.Text = "Extrusion Roofs";
            this.extrusionRoofTabPage.UseVisualStyleBackColor = true;
            // 
            // groupBox3
            // 
            this.groupBox3.Controls.Add(this.extrusionEndTextBox);
            this.groupBox3.Controls.Add(this.label5);
            this.groupBox3.Controls.Add(this.label4);
            this.groupBox3.Controls.Add(this.extrusionStartTextBox);
            this.groupBox3.Controls.Add(this.refPanesComboBox);
            this.groupBox3.Controls.Add(this.label2);
            this.groupBox3.Controls.Add(this.extrusionRoofTypesComboBox);
            this.groupBox3.Controls.Add(this.label6);
            this.groupBox3.Controls.Add(this.refLevelComboBox);
            this.groupBox3.Controls.Add(this.label7);
            this.groupBox3.Controls.Add(this.label8);
            this.groupBox3.Controls.Add(this.selectProfileButton);
            this.groupBox3.Location = new System.Drawing.Point(3, 207);
            this.groupBox3.Name = "groupBox3";
            this.groupBox3.Size = new System.Drawing.Size(368, 154);
            this.groupBox3.TabIndex = 4;
            this.groupBox3.TabStop = false;
            this.groupBox3.Text = "Create ExtrusionRoof";
            // 
            // extrusionEndTextBox
            // 
            this.extrusionEndTextBox.Location = new System.Drawing.Point(285, 123);
            this.extrusionEndTextBox.Name = "extrusionEndTextBox";
            this.extrusionEndTextBox.Size = new System.Drawing.Size(77, 20);
            this.extrusionEndTextBox.TabIndex = 12;
            this.extrusionEndTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.extrusionEndTextBox_Validating);
            // 
            // label5
            // 
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(207, 126);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(75, 13);
            this.label5.TabIndex = 11;
            this.label5.Text = "Extrusion End:";
            this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(6, 126);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(78, 13);
            this.label4.TabIndex = 10;
            this.label4.Text = "Extrusion Start:";
            this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // extrusionStartTextBox
            // 
            this.extrusionStartTextBox.Location = new System.Drawing.Point(84, 124);
            this.extrusionStartTextBox.Name = "extrusionStartTextBox";
            this.extrusionStartTextBox.Size = new System.Drawing.Size(74, 20);
            this.extrusionStartTextBox.TabIndex = 9;
            this.extrusionStartTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.extrusionStartTextBox_Validating);
            // 
            // refPanesComboBox
            // 
            this.refPanesComboBox.FormattingEnabled = true;
            this.refPanesComboBox.Location = new System.Drawing.Point(84, 45);
            this.refPanesComboBox.Name = "refPanesComboBox";
            this.refPanesComboBox.Size = new System.Drawing.Size(278, 21);
            this.refPanesComboBox.TabIndex = 8;
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(6, 48);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(57, 13);
            this.label2.TabIndex = 7;
            this.label2.Text = "Ref Plane:";
            // 
            // extrusionRoofTypesComboBox
            // 
            this.extrusionRoofTypesComboBox.FormattingEnabled = true;
            this.extrusionRoofTypesComboBox.Location = new System.Drawing.Point(84, 97);
            this.extrusionRoofTypesComboBox.Name = "extrusionRoofTypesComboBox";
            this.extrusionRoofTypesComboBox.Size = new System.Drawing.Size(278, 21);
            this.extrusionRoofTypesComboBox.TabIndex = 6;
            // 
            // label6
            // 
            this.label6.AutoSize = true;
            this.label6.Location = new System.Drawing.Point(6, 100);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(60, 13);
            this.label6.TabIndex = 5;
            this.label6.Text = "Roof Type:";
            // 
            // refLevelComboBox
            // 
            this.refLevelComboBox.FormattingEnabled = true;
            this.refLevelComboBox.Location = new System.Drawing.Point(84, 71);
            this.refLevelComboBox.Name = "refLevelComboBox";
            this.refLevelComboBox.Size = new System.Drawing.Size(278, 21);
            this.refLevelComboBox.TabIndex = 4;
            // 
            // label7
            // 
            this.label7.AutoSize = true;
            this.label7.Location = new System.Drawing.Point(6, 74);
            this.label7.Name = "label7";
            this.label7.Size = new System.Drawing.Size(56, 13);
            this.label7.TabIndex = 3;
            this.label7.Text = "Ref Level:";
            // 
            // label8
            // 
            this.label8.AutoSize = true;
            this.label8.Location = new System.Drawing.Point(6, 22);
            this.label8.Name = "label8";
            this.label8.Size = new System.Drawing.Size(39, 13);
            this.label8.TabIndex = 2;
            this.label8.Text = "Profile:";
            this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // selectProfileButton
            // 
            this.selectProfileButton.DialogResult = System.Windows.Forms.DialogResult.Retry;
            this.selectProfileButton.Location = new System.Drawing.Point(84, 17);
            this.selectProfileButton.Name = "selectProfileButton";
            this.selectProfileButton.Size = new System.Drawing.Size(263, 23);
            this.selectProfileButton.TabIndex = 1;
            this.selectProfileButton.Text = "&Select Profile in Revit";
            this.selectProfileButton.UseVisualStyleBackColor = true;
            // 
            // extrusionRoofsListView
            // 
            this.extrusionRoofsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.columnHeader5,
            this.columnHeader6,
            this.columnHeader7,
            this.columnHeader8});
            this.extrusionRoofsListView.Location = new System.Drawing.Point(3, 6);
            this.extrusionRoofsListView.Name = "extrusionRoofsListView";
            this.extrusionRoofsListView.Size = new System.Drawing.Size(368, 197);
            this.extrusionRoofsListView.TabIndex = 3;
            this.extrusionRoofsListView.UseCompatibleStateImageBehavior = false;
            this.extrusionRoofsListView.View = System.Windows.Forms.View.Details;
            // 
            // columnHeader5
            // 
            this.columnHeader5.Text = "Roof Id";
            // 
            // columnHeader6
            // 
            this.columnHeader6.Text = "Name";
            // 
            // columnHeader7
            // 
            this.columnHeader7.Text = "Reference Level";
            this.columnHeader7.Width = 102;
            // 
            // columnHeader8
            // 
            this.columnHeader8.Text = "Roof Type";
            // 
            // editRoofButton
            // 
            this.editRoofButton.Location = new System.Drawing.Point(207, 408);
            this.editRoofButton.Name = "editRoofButton";
            this.editRoofButton.Size = new System.Drawing.Size(181, 23);
            this.editRoofButton.TabIndex = 4;
            this.editRoofButton.Text = "Edit";
            this.editRoofButton.UseVisualStyleBackColor = true;
            this.editRoofButton.Click += new System.EventHandler(this.editRoofButton_Click);
            // 
            // createRoofButton
            // 
            this.createRoofButton.Location = new System.Drawing.Point(6, 408);
            this.createRoofButton.Name = "createRoofButton";
            this.createRoofButton.Size = new System.Drawing.Size(181, 23);
            this.createRoofButton.TabIndex = 3;
            this.createRoofButton.Text = "Create";
            this.createRoofButton.UseVisualStyleBackColor = true;
            this.createRoofButton.Click += new System.EventHandler(this.createRoofButton_Click);
            // 
            // okButton
            // 
            this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.okButton.Location = new System.Drawing.Point(240, 455);
            this.okButton.Name = "okButton";
            this.okButton.Size = new System.Drawing.Size(75, 23);
            this.okButton.TabIndex = 4;
            this.okButton.Text = "&OK";
            this.okButton.UseVisualStyleBackColor = true;
            // 
            // cancelButton
            // 
            this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.cancelButton.Location = new System.Drawing.Point(322, 455);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.Size = new System.Drawing.Size(75, 23);
            this.cancelButton.TabIndex = 5;
            this.cancelButton.Text = "&Cancel";
            this.cancelButton.UseVisualStyleBackColor = true;
            // 
            // RoofForm
            // 
            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(401, 487);
            this.Controls.Add(this.cancelButton);
            this.Controls.Add(this.okButton);
            this.Controls.Add(this.groupBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "RoofForm";
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "New Roof";
            this.Load += new System.EventHandler(this.RoofForm_Load);
            this.groupBox1.ResumeLayout(false);
            this.roofsTabControl.ResumeLayout(false);
            this.footprintRoofTabPage.ResumeLayout(false);
            this.groupBox2.ResumeLayout(false);
            this.groupBox2.PerformLayout();
            this.extrusionRoofTabPage.ResumeLayout(false);
            this.groupBox3.ResumeLayout(false);
            this.groupBox3.PerformLayout();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.ListView footPrintRoofsListView;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.Button okButton;
        private System.Windows.Forms.Button cancelButton;
        private System.Windows.Forms.Button editRoofButton;
        private System.Windows.Forms.Button createRoofButton;
        private System.Windows.Forms.TabControl roofsTabControl;
        private System.Windows.Forms.TabPage footprintRoofTabPage;
        private System.Windows.Forms.TabPage extrusionRoofTabPage;
        private System.Windows.Forms.ListView extrusionRoofsListView;
        private System.Windows.Forms.ColumnHeader columnHeader1;
        private System.Windows.Forms.ColumnHeader columnHeader2;
        private System.Windows.Forms.ColumnHeader columnHeader3;
        private System.Windows.Forms.ColumnHeader columnHeader4;
        private System.Windows.Forms.ColumnHeader columnHeader5;
        private System.Windows.Forms.ColumnHeader columnHeader6;
        private System.Windows.Forms.ColumnHeader columnHeader7;
        private System.Windows.Forms.ColumnHeader columnHeader8;
        private System.Windows.Forms.GroupBox groupBox2;
        private System.Windows.Forms.ComboBox roofTypesComboBox;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.ComboBox levelsComboBox;
        private System.Windows.Forms.Label levelLabel;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Button selectFootPrintButton;
        private System.Windows.Forms.GroupBox groupBox3;
        private System.Windows.Forms.TextBox extrusionEndTextBox;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox extrusionStartTextBox;
        private System.Windows.Forms.ComboBox refPanesComboBox;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.ComboBox extrusionRoofTypesComboBox;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.ComboBox refLevelComboBox;
        private System.Windows.Forms.Label label7;
        private System.Windows.Forms.Label label8;
        private System.Windows.Forms.Button selectProfileButton;
    }
}

RoofEditorForm.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.NewRoof.RoofForms.CS
{
    partial class RoofEditorForm
    {
        /// <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.roofEditorPropertyGrid = new System.Windows.Forms.PropertyGrid();
            this.label1 = new System.Windows.Forms.Label();
            this.roofTypesComboBox = new System.Windows.Forms.ComboBox();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.okButton = new System.Windows.Forms.Button();
            this.cancelButton = new System.Windows.Forms.Button();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            // 
            // roofEditorPropertyGrid
            // 
            this.roofEditorPropertyGrid.Location = new System.Drawing.Point(6, 19);
            this.roofEditorPropertyGrid.Name = "roofEditorPropertyGrid";
            this.roofEditorPropertyGrid.Size = new System.Drawing.Size(365, 385);
            this.roofEditorPropertyGrid.TabIndex = 0;
            this.roofEditorPropertyGrid.ToolbarVisible = false;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(9, 12);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(60, 13);
            this.label1.TabIndex = 1;
            this.label1.Text = "Roof Type:";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // roofTypesComboBox
            // 
            this.roofTypesComboBox.FormattingEnabled = true;
            this.roofTypesComboBox.Location = new System.Drawing.Point(75, 9);
            this.roofTypesComboBox.Name = "roofTypesComboBox";
            this.roofTypesComboBox.Size = new System.Drawing.Size(314, 21);
            this.roofTypesComboBox.TabIndex = 2;
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.roofEditorPropertyGrid);
            this.groupBox1.Location = new System.Drawing.Point(12, 36);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(377, 410);
            this.groupBox1.TabIndex = 3;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Roof Properties";
            // 
            // okButton
            // 
            this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.okButton.Location = new System.Drawing.Point(233, 452);
            this.okButton.Name = "okButton";
            this.okButton.Size = new System.Drawing.Size(75, 23);
            this.okButton.TabIndex = 4;
            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(314, 452);
            this.cancelButton.Name = "cancelButton";
            this.cancelButton.Size = new System.Drawing.Size(75, 23);
            this.cancelButton.TabIndex = 5;
            this.cancelButton.Text = "&Cancel";
            this.cancelButton.UseVisualStyleBackColor = true;
            // 
            // RoofEditorForm
            // 
            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(401, 487);
            this.Controls.Add(this.cancelButton);
            this.Controls.Add(this.okButton);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.roofTypesComboBox);
            this.Controls.Add(this.label1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "RoofEditorForm";
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Roof Editor";
            this.Load += new System.EventHandler(this.RoofEditorForm_Load);
            this.groupBox1.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.PropertyGrid roofEditorPropertyGrid;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.ComboBox roofTypesComboBox;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.Button okButton;
        private System.Windows.Forms.Button cancelButton;
    }
}

GraphicsControl.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.NewRoof.RoofForms.CS
{
    partial class GraphicsControl
    {
        /// <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 Component 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.SuspendLayout();
            // 
            // GraphicsControl
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Name = "GraphicsControl";
            this.Size = new System.Drawing.Size(151, 146);
            this.ResumeLayout(false);

        }

        #endregion
    }
}

CustomTypeConverter.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 System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using Autodesk.Revit.DB;

namespace Revit.SDK.Samples.NewRoof.RoofForms.CS
{
    /// <summary>
    /// The LevelConverter class is inherited from the TypeConverter class which is used to
    /// show the property which returns Level type as like a combo box in the PropertyGrid control.
    /// </summary>
    public class LevelConverter : TypeConverter
    {
        /// <summary>
        /// To store the levels element
        /// </summary>
        static private Dictionary<String, Level> m_levels = new Dictionary<String, Level>();

        /// <summary>
        /// Initialize the levels data.
        /// </summary>
        /// <param name="levels"></param>
        static public  void SetStandardValues(ReadOnlyCollection<Level> levels)
        {
            m_levels.Clear();
            foreach (Level level in levels)
            {
                m_levels.Add(level.Id.IntegerValue.ToString(), level);
            }
        }

        /// <summary>
        /// Get a level by a level id.
        /// </summary>
        /// <param name="id">The id of the level</param>
        /// <returns>Returns a level which id equals the specified id.</returns>
        static public Level GetLevelByID(int id)
        {            
            return m_levels[id.ToString()];
        }

        /// <summary>
        /// Override the CanConvertTo method.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(Level))
                return true;
            return base.CanConvertTo(context, destinationType);
        }

        /// <summary>
        ///  Override the ConvertTo method, convert a level type value to a string type value for displaying in the PropertyGrid.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(String) && value is Level)
            {
                Level level = (Level)value;
                return level.Name + "[" + level.Id.IntegerValue.ToString() + "]";
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }

        /// <summary>
        /// Override the CanConvertFrom method.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(String))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }

        /// <summary>
        /// Override the ConvertFrom method, convert a string type value to a level type value.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is String)
            {
                try
                {
                    String levelString = (String)value;

                    int leftBracket = levelString.IndexOf('[');
                    int rightBracket = levelString.IndexOf(']');

                    String idString = levelString.Substring(leftBracket + 1, rightBracket - leftBracket - 1);

                    return m_levels[idString];
                }
                catch (Exception ex)
                {
                    Autodesk.Revit.UI.TaskDialog.Show("Revit", ex.Message);
                }
            }
            return base.ConvertFrom(context, culture, value);
        }

        /// <summary>
        /// Override the GetStandardValuesSupported method for displaying a level list in the PropertyGrid.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        /// <summary>
        /// Override the StandardValuesCollection method for supplying a level list in the PropertyGrid.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            return new StandardValuesCollection(m_levels.Values);
        }
    }

    /// <summary>
    /// The FootPrintRoofLineConverter class is inherited from the ExpandableObjectConverter class which is used to
    /// expand the property which returns FootPrintRoofLine type as like a tree view in the PropertyGrid control.
    /// </summary>
    public class FootPrintRoofLineConverter : ExpandableObjectConverter
    {
        // To store the FootPrintRoofLines data.
        static private Dictionary<String, FootPrintRoofLine> m_footPrintLines = new Dictionary<String, FootPrintRoofLine>();
        
        /// <summary>
        /// Initialize the FootPrintRoofLines data. 
        /// </summary>
        /// <param name="footPrintRoofLines"></param>
        static public void SetStandardValues(List<FootPrintRoofLine> footPrintRoofLines)
        {
            m_footPrintLines.Clear();
            foreach (FootPrintRoofLine footPrintLine in footPrintRoofLines)
            {
                if (m_footPrintLines.ContainsKey(footPrintLine.Id.ToString()))
                    continue;
                m_footPrintLines.Add(footPrintLine.Id.ToString(), footPrintLine);
            }
        }

        /// <summary>
        /// Override the CanConvertTo method.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(FootPrintRoofLine))
                return true;
            return base.CanConvertTo(context, destinationType);
        }

        /// <summary>
        ///  Override the ConvertTo method, convert a FootPrintRoofLine type value to a string type value for displaying in the PropertyGrid.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(System.String) && value is FootPrintRoofLine)
            {
                FootPrintRoofLine footPrintLine = (FootPrintRoofLine)value;
                return footPrintLine.Name + "[" + footPrintLine.Id.ToString() + "]";
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }

        /// <summary>
        /// Override the CanConvertFrom method.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }

        /// <summary>
        /// Override the ConvertFrom method, convert a string type value to a FootPrintRoofLine type value.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is String)
            {
                try
                {
                    String footPrintLineString = (String)value;

                    int leftBracket = footPrintLineString.IndexOf('[');
                    int rightBracket = footPrintLineString.IndexOf(']');

                    String idString = footPrintLineString.Substring(leftBracket + 1, rightBracket - leftBracket - 1);

                    return m_footPrintLines[idString];
                }
                catch (Exception ex)
                {
                    Autodesk.Revit.UI.TaskDialog.Show("Revit", ex.Message);
                }
            }
            
            return base.ConvertFrom(context, culture, value);
        }

        /// <summary>
        /// Override the GetStandardValuesSupported method for displaying a FootPrintRoofLine list in the PropertyGrid.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool  GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        /// <summary>
        /// Override the StandardValuesCollection method for supplying a FootPrintRoofLine list in the PropertyGrid.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            return new StandardValuesCollection(m_footPrintLines.Values);
        }
    };
}

FootPrintRoofWrapper.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 System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Collections.ObjectModel;

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

namespace Revit.SDK.Samples.NewRoof.RoofForms.CS
{
    /// <summary>
    /// The Util class is used to translate Revit coordination to windows coordination.
    /// </summary>
    public class Util
    {
        /// <summary>
        /// Translate a Revit 3D point to a windows 2D point according the boundingbox.
        /// </summary>
        /// <param name="pointXYZ">A Revit 3D point</param>
        /// <param name="boundingbox">The boundingbox of the roof whose footprint lines will be displayed in GDI.</param>
        /// <returns>A windows 2D point.</returns>
        static public PointF Translate(Autodesk.Revit.DB.XYZ pointXYZ, BoundingBoxXYZ boundingbox)
        {
            double centerX = (boundingbox.Min.X + boundingbox.Max.X) / 2;
            double centerY = (boundingbox.Min.Y + boundingbox.Max.Y) / 2;
            return new PointF((float)(pointXYZ.X - centerX), -(float)(pointXYZ.Y - centerY));
        }
    };

    /// <summary>
    /// The FootPrintRoofLine class is used to edit the foot print data of a footprint roof. 
    /// </summary>
    public class FootPrintRoofLine
    {
        // To store the footprint roof which the foot print data belong to.
        private FootPrintRoof m_roof;
        // To store the model curve data which the foot print data stand for.
        private ModelCurve m_curve;
        // To store the boundingbox of the roof
        private BoundingBoxXYZ m_boundingbox;
        /// <summary>
        /// The construct of the FootPrintRoofLine class.
        /// </summary>
        /// <param name="roof">The footprint roof which the foot print data belong to.</param>
        /// <param name="curve">The model curve data which the foot print data stand for.</param>
        public FootPrintRoofLine(FootPrintRoof roof, ModelCurve curve)
        {
            m_roof = roof;
            m_curve = curve;
            m_boundingbox = m_roof.get_BoundingBox(Revit.SDK.Samples.NewRoof.CS.Command.ActiveView);
        }

        /// <summary>
        /// Draw the footprint line in GDI.
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="pen"></param>
        public void Draw(System.Drawing.Graphics graphics, System.Drawing.Pen pen)
        {
            Curve curve = m_curve.GeometryCurve;
            DrawCurve(graphics, pen, curve);
        }

        /// <summary>
        /// Draw the curve in GDI.
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="pen"></param>
        /// <param name="curve"></param>
        private void DrawCurve(Graphics graphics, System.Drawing.Pen pen, Curve curve)
        {
            List<PointF> poinsts = new List<PointF>();
            foreach (Autodesk.Revit.DB.XYZ point in curve.Tessellate())
            {
                poinsts.Add(Util.Translate(point,m_boundingbox));
            }
            graphics.DrawCurve(pen, poinsts.ToArray());
        }

        /// <summary>
        /// Get the model curve data which the foot print data stand for.
        /// </summary>
        [Browsable(false)]
        public ModelCurve ModelCurve
        {
            get
            {
                return m_curve;
            }
        }

        /// <summary>
        /// Get the id value of the model curve.
        /// </summary>
        [Browsable(false)]
        public int Id
        {
            get
            {
                return m_curve.Id.IntegerValue;
            }
        }

        /// <summary>
        /// Get the name of the model curve.
        /// </summary>
        [Browsable(false)]
        public String Name
        {
            get
            {
                return m_curve.Name;
            }
        }

        /// <summary>
        /// Get/Set the slope definition of a model curve of the roof.
        /// </summary>
        [Description("The slope definition of the FootPrintRoof line.")]
        public bool DefinesSlope
        {
            get
            {
                return m_roof.get_DefinesSlope(m_curve);
            }
            set
            {
                m_roof.set_DefinesSlope(m_curve, value);
            }
        }

        /// <summary>
        /// Get/Set the slope angle of the FootPrintRoof line..
        /// </summary>
        [Description("The slope angle of the FootPrintRoof line.")]
        public double SlopeAngle
        {
            get
            {
                return m_roof.get_SlopeAngle(m_curve);
            }
            set
            {
                m_roof.set_SlopeAngle(m_curve, value);
            }
        }

        /// <summary>
        /// Get/Set the offset of the FootPrintRoof line.
        /// </summary>
        [Description("The offset of the FootPrintRoof line.")]
        public double Offset
        {
            get
            {
                return m_roof.get_Offset(m_curve);
            }
            set
            {
                m_roof.set_Offset(m_curve, value);
            }
        }

        /// <summary>
        /// Get/Set the overhang value of the FootPrintRoof line if the roof is created by picked wall.
        /// </summary>
        [Description("The overhang value of the FootPrintRoof line if the roof is created by picked wall.")]
        public double Overhang
        {
            get
            {
                return m_roof.get_Overhang(m_curve);
            }
            set
            {
                m_roof.set_Overhang(m_curve, value);
            }
        }

        /// <summary>
        /// Get/Set ExtendIntoWall value whether you want the overhang to be measured from the core of the wall or not.
        /// </summary>
        [Description("whether you want the overhang to be measured from the core of the wall or not.")]
        public bool ExtendIntoWall
        {
            get
            {
                return m_roof.get_ExtendIntoWall(m_curve);
            }
            set
            {
                m_roof.set_ExtendIntoWall(m_curve, value);
            }
        }
    };

    /// <summary>
    /// The FootPrintRoofWrapper class is use to edit a footprint roof in a PropertyGrid.
    /// It contains a footprint roof.
    /// </summary>
    public class FootPrintRoofWrapper
    {
        // To store the footprint roof which will be edited in a PropertyGrid.
        private FootPrintRoof m_roof;
        // To store the footprint line data of the roof which will be edited.
        private FootPrintRoofLine m_footPrintLine;
        // To store the footprint lines data of the roof.
        private List<FootPrintRoofLine> m_roofLines;

        // To store the boundingbox of the roof
        private BoundingBoxXYZ m_boundingbox;

        public event EventHandler OnFootPrintRoofLineChanged;
     
        /// <summary>
        /// The construct of the FootPrintRoofWrapper class.
        /// </summary>
        /// <param name="roof">The footprint roof which will be edited in a PropertyGrid.</param>
        public FootPrintRoofWrapper(FootPrintRoof roof)
        {
            m_roof = roof;
            m_roofLines = new List<FootPrintRoofLine>();
            ModelCurveArrArray curveloops = m_roof.GetProfiles();
            
            foreach(ModelCurveArray curveloop in curveloops)
            {
                foreach(ModelCurve curve in curveloop)
                {
                    m_roofLines.Add(new FootPrintRoofLine(m_roof, curve));
                }
            }

            FootPrintRoofLineConverter.SetStandardValues(m_roofLines);
            m_footPrintLine = m_roofLines[0];

            m_boundingbox = m_roof.get_BoundingBox(Revit.SDK.Samples.NewRoof.CS.Command.ActiveView);
        }


        /// <summary>
        /// Get the bounding box of the roof.
        /// </summary>
        [Browsable(false)]
        public BoundingBoxXYZ Boundingbox
        {
            get
            {
                return m_boundingbox;
            }
        }

        /// <summary>
        /// Get/Set the current footprint roof line which will be edited in the PropertyGrid.
        /// </summary>
        [TypeConverterAttribute(typeof(FootPrintRoofLineConverter)), Category("Footprint Roof Line Information")]
        public FootPrintRoofLine FootPrintLine
        {
            get
            {
                return m_footPrintLine;
            }
            set
            {
                m_footPrintLine = value;
                OnFootPrintRoofLineChanged(this, new EventArgs());
            }
        }

        /// <summary>
        /// The base level of the footprint roof.
        /// </summary>
        [TypeConverterAttribute(typeof(LevelConverter)), Category("Constrains")]
        [DisplayName("Base Level")]
        public Level BaseLevel
        {
            get
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.ROOF_BASE_LEVEL_PARAM);
                return LevelConverter.GetLevelByID(para.AsElementId().IntegerValue);
            }
            set
            {
                // update base level
                Parameter para = m_roof.get_Parameter(BuiltInParameter.ROOF_BASE_LEVEL_PARAM);
                Autodesk.Revit.DB.ElementId id = new Autodesk.Revit.DB.ElementId(value.Id.IntegerValue);
                para.Set(id);
            }
        }

        /// <summary>
        /// The eave cutter type of the footprint roof.
        /// </summary>
        [Category("Construction")]
        [DisplayName("Rafter Cut")]
        [Description("The eave cutter type of the footprint roof.")]
        public EaveCutterType EaveCutterType
        {
            get
            {
                return m_roof.EaveCuts;
            }
            set
            {
                m_roof.EaveCuts = value;
            }
        }

        /// <summary>
        /// Get the footprint roof lines data.
        /// </summary>
        [Browsable(false)]
        public ReadOnlyCollection<FootPrintRoofLine> FootPrintRoofLines
        {
            get
            {
                return new ReadOnlyCollection<FootPrintRoofLine>(m_roofLines);
            }
        }

        /// <summary>
        /// Draw the footprint lines.
        /// </summary>
        /// <param name="graphics">The graphics object.</param>
        /// <param name="displayPen">A display pen.</param>
        /// <param name="highlightPen">A highlight pen.</param>
        public void DrawFootPrint(Graphics graphics, Pen displayPen, Pen highlightPen)
        {
            foreach (FootPrintRoofLine line in m_roofLines)
            {
                if (line.Id == m_footPrintLine.Id)
                {
                    line.Draw(graphics, highlightPen);
                }
                else
                {
                    line.Draw(graphics, displayPen);
                }
            }
        }
    }
}

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

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

namespace Revit.SDK.Samples.NewRoof.RoofForms.CS
{
    
    /// <summary>
    /// The ExtrusionRoofWrapper class is use to edit a extrusion roof in a PropertyGrid.
    /// It contains a extrusion roof.
    /// </summary>
    public class ExtrusionRoofWrapper
    {
        // To store the extrusion roof which will be edited in a PropertyGrid.
        private ExtrusionRoof m_roof;
      
        /// <summary>
        /// The construct of the ExtrusionRoofWrapper class.
        /// </summary>
        /// <param name="roof">The extrusion roof which will be edited in a PropertyGrid.</param>
        public ExtrusionRoofWrapper(ExtrusionRoof roof)
        {
            m_roof = roof;
        }

        #region The properties will be shown in the PropertyGrid
        /// <summary>
        /// The reference plane of the extrusion roof.
        /// </summary>
        [Category("Constrains")]
        [Description("The reference plane of the extrusion roof.")]
        public String WorkPlane
        {
            get
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.SKETCH_PLANE_PARAM);
                return para.AsString();
            }
        }

        /// <summary>
        /// The extrusion start point of the extrusion roof.
        /// </summary>
        [Category("Constrains")]
        [DisplayName("Extrusion Start")]
        [Description("The extrusion of a roof can extend in either direction along the reference plane. If the extrusion extends away from the plane, the start and end points are positive values. If the extrusion extends toward the plane, the start and end points are negative.")]
        public String ExtrusionStart
        {
            get
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.EXTRUSION_START_PARAM);
                return para.AsValueString();
            }
            set
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.EXTRUSION_START_PARAM);
                if (para.SetValueString(value) == false)
                {
                    throw new Exception("Invalid Input");
                }
            }
        }

        /// <summary>
        /// The extrusion end point of the extrusion roof.
        /// </summary>
        [Category("Constrains")]
        [DisplayName("Extrusion End")]
        [Description("The extrusion of a roof can extend in either direction along the reference plane. If the extrusion extends away from the plane, the start and end points are positive values. If the extrusion extends toward the plane, the start and end points are negative.")]
        public String ExtrusionEnd
        {
            get
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.EXTRUSION_END_PARAM);
                return para.AsValueString();
            }
            set
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.EXTRUSION_END_PARAM);
                if (para.SetValueString(value) == false)
                {
                    throw new Exception("Invalid Input");
                }
            }
        }

        /// <summary>
        /// The reference level of the extrusion roof.
        /// </summary>
        [TypeConverterAttribute(typeof(LevelConverter)), Category("Constrains")]
        [DisplayName("Reference Level")]
        [Description("The reference level of the extrusion roof.")]
        public Level ReferenceLevel
        {
            get
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.ROOF_CONSTRAINT_LEVEL_PARAM);
                return LevelConverter.GetLevelByID(para.AsElementId().IntegerValue);
            }
            set
            {
                // update reference level
                Parameter para = m_roof.get_Parameter(BuiltInParameter.ROOF_CONSTRAINT_LEVEL_PARAM);
                Autodesk.Revit.DB.ElementId id = new Autodesk.Revit.DB.ElementId(value.Id.IntegerValue);
                para.Set(id);
            }
        }

        /// <summary>
        /// The offset from the reference level of the extrusion roof.
        /// </summary>
        [Category("Constrains")]
        [DisplayName("Level Offset")]
        [Description("The offset from the reference level.")]
        public String LevelOffset
        {
            get
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.ROOF_CONSTRAINT_OFFSET_PARAM);
                return para.AsValueString();
            }
            set
            {
                Parameter para = m_roof.get_Parameter(BuiltInParameter.ROOF_CONSTRAINT_OFFSET_PARAM);
                if (para.SetValueString(value) == false)
                {
                    throw new Exception("Invalid Input");
                }
            }
        }
        #endregion        
    }
}