主题: 窗户向导

摘要: 本示例将演示如何通过向导创建窗户家族。

项目文件:

Command.cs

该文件包含一个实现 IExternalCommand 接口的 Command 类。该类的作用是创建 WindowWizard 的实例并调用 Run 方法执行。

 WindowWizard.cs

该文件包含一个 WindowWizard 类,它存储 ExternalCommandData,创建 DoubleHungWinCreation 实例,并且还有一个创建 WizardForm 实例的方法。

 WindowParameter.cs

该文件包含三个类: 一个是 WizardParameter,存储向导参数,另一个是 WindowParameter,存储常用窗户参数,还有一个是 DoubleHungWinPara,它是 WindowParameter 的子类,用于存储双挂窗的参数。

 ValidateWindowParameter.cs

该文件包含一个 ValidateWindowParameter 类,用于验证窗户参数。

 WindowCreation.cs

该文件包含一个抽象类 WindowCreation,它有一个抽象方法,用于逐步创建窗户家族。

 DoubleHungWinCreation.cs

该文件包含一个 DoubleHungWinCreation 类,它实现了 WindowCreation,逐步创建双挂窗户家族。

 CreateExtrusion.cs

该文件包含一个 CreateExtrusion 类,它有创建 CurveArray 和实体挤压的方法。

 CreateDimension.cs

该文件包含一个 CreateDimension 类,它有添加参照平面、面或面和参照平面之间的尺寸的方法。

 CreateReferencePlane.cs

该文件包含一个 CreateRefPlane 类,它可以根据主机参照平面和双重偏移量创建参照平面。

 CreateAlignment.cs

该文件包含一个 CreateAlignment 类,它可以在两个面之间添加对齐尺寸。

 Utility.cs

该文件包含一个 Utility 类,它具有允许获取常见元素的静态方法。

 GeoHelper.cs

该文件包含一个 GeoHelper 类,它有助于使用几何数据定位。

 WizardUI.cs

该文件包含一个窗体,允许用户进行用户界面输入和选择。

描述:

该示例实现了 IExternalCommand 接口,允许用户通过向导创建窗户家族。 用户应该使用窗户家族模板创建家族,并且可以输入窗户参数的尺寸,指定材料,将家族文件保存到本地。

- 要创建 Extrusion,请使用 FamilyItemFactory NewExtrusion 方法。

- 要创建 Alignment,请使用 FamilyItemFactory NewAlignment 方法。

- 要创建 Dimension,请使用 FamilyItemFactory NewDimension 方法。

- 要创建 ReferencePlane,请使用 FamilyItemFactory NewReferencePlane 方法。

- 要创建家族类型,请使用 FamilyItemFactory NewType 方法。

- 要获取材料,请使用 Settings.Materials 属性。

- 要获取类别,请使用 Settings.Categories 属性。

说明:

1. 更新 Revit.ini,添加以下代码:

[ExternalCommands]

ECCount      = 1

ECName1=WindowWizard

ECClassName1=Revit.SDK.Samples.WindowWizard.CS

ECAssembly1  = <your path>\WindowWizard.dll

2. 启动 Revit

3. 为使用向导,用户需要手动创建一个带有窗户模板的家族文档(如 Window.rft)。如果模板不正确,命令将失败。

4. 通过外部命令菜单启动 WindowWizard

5. 输入窗户尺寸,包括类型名称、高度、宽度、内嵌和窗槛高度。您可以单击新建或复制按钮创建新的家族类型并输入其尺寸; 用户还可以选择家族类型并修改相应的尺寸。单击“下一步”按钮。

6. 为玻璃窗格和窗扇选择材料。单击“返回”按钮修改尺寸或单击“下一步”按钮进入下一步。

7. 查看已创建的所有窗户类型,您可以返回并对这些类型进行进一步修改。单击“文件”按钮,然后选择一个路径来存储家族文件。单击“完成”按钮,Revit将自动为您创建一个窗户家族。

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

WindowParameter.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;
using System.Collections.Generic;
namespace Revit.SDK.Samples.WindowWizard.CS
{
    /// <summary>
    /// This class will deal with all parameters related to window creation
    /// </summary>
    public class WindowParameter
    {
        /// <summary>
        ///store the family type name
        /// </summary>
        String m_type = String.Empty;
        
        /// <summary>
        /// store the height of opening
        /// </summary>
        double m_height = 0.0;
        /// <summary>
        /// store the width of opening
        /// </summary>
        double m_width = 0.0;       
        #region Properties
        /// <summary>
        /// get/set the Type property
        /// </summary>
        public String Type
        {
            set
            {
                m_type = value;
            }
            get
            {
                return m_type;
            }
        }
        /// <summary>
        /// get/set the Height property
        /// </summary>
        public double Height
        {
            set
            {
                m_height = value;
            }
            get
            {
                return m_height;
            }
        }
        /// <summary>
        /// get/set the Width property
        /// </summary>
        public double Width
        {
            set
            {
                m_width = value;
            }
            get
            {
                return m_width;
            }
        }
        #endregion 
        /// <summary>
        /// constructor of WindowParameter
        /// </summary>
        /// <param name="isMetric">indicate whether the template is metric or imperial</param>
        public WindowParameter(bool isMetric)
        {
            if (isMetric)
            {
                m_type = "NewType";
                m_height = 1000;
                m_width = 500;
            }
            else
            {
                m_type = "NewType";
                m_height = 4.0;
                m_width = 2.0;
            }
        }
        /// <summary>
        /// construcion of WindowParameter
        /// </summary>
        /// <param name="para">the WindowParameter</param>
        public WindowParameter(WindowParameter para)
        {
            if (String.IsNullOrEmpty(para.m_type))
            {
                m_type = "NewType";
            }
            m_type = para.Type + "1";
            m_height = para.Height;
            m_width = para.Width;
        }
    }
    /// <summary>
    /// This class is used to deal with wizard parameters
    /// </summary>
    public class WizardParameter 
    {
        // ToDo add properties for them
        
        /// <summary>
        /// store the template name
        /// </summary>
        public String m_template = String.Empty;
        /// <summary>
        /// store the current WindowParameter
        /// </summary>
        private WindowParameter m_curPara = new WindowParameter(true);        
        
        /// <summary>
        /// store the windowparameter hashtable
        /// </summary>
        Hashtable m_winParas = new Hashtable();
        
        /// <summary>
        /// store the frame material list
        /// </summary>
        private List<String> m_frameMats = new List<string>();
        
        /// <summary>
        /// store the glass material list
        /// </summary>
        private List<String> m_GlassMats = new List<string>();
        
        /// <summary>
        /// store the glass material
        /// </summary>
        String m_glassMat = String.Empty;
        /// <summary>
        /// store the sash material
        /// </summary>
        String m_sashMat = String.Empty;
        /// <summary>
        /// store the ValidateWindowParameter
        /// </summary>
        private ValidateWindowParameter m_validator = new ValidateWindowParameter(10, 10);
        
        /// <summary>
        /// store the temp path
        /// </summary>
        private String m_pathName = System.IO.Path.GetTempPath();
      
        #region
        /// <summary>
        /// get/set Validator property
        /// </summary>
        public ValidateWindowParameter Validator
        {
            get
            {
                return m_validator;
            }
            set
            {
                m_validator = value;
            }
        }
        /// <summary>
        /// get/set FrameMaterials property
        /// </summary>
        public List<String> FrameMaterials
        {
            set
            {
                m_frameMats = value;
            }
            get
            {
                return m_frameMats;
            }
        }
        /// <summary>
        /// get/set GlassMaterials property
        /// </summary>
        public List<String> GlassMaterials
        {
            set
            {
                m_GlassMats = value;
            }
            get
            {
                return m_GlassMats;
            }
        }
        /// <summary>
        /// get/set GlassMat property
        /// </summary>
        public String GlassMat
        {
            set
            {
                m_glassMat = value;
            }
            get
            {
                return m_glassMat;
            }
        }
        /// <summary>
        /// get/set SashMat property
        /// </summary>
        public String SashMat
        {
            set
            {
                m_sashMat = value;
            }
            get
            {
                return m_sashMat;
            }
        }
        /// <summary>
        /// get/set WinParaTab property
        /// </summary>
        public Hashtable WinParaTab
        {
            get
            {
                return m_winParas;
            }
            set
            {
                m_winParas = value;
            }
        }
        /// <summary>
        /// get/set CurrentPara property
        /// </summary>
        public WindowParameter CurrentPara
        {
            get
            {
                return m_curPara;
            }
            set
            {
                m_curPara = value;
            }
        }
        /// <summary>
        /// get/set PathName property
        /// </summary>
        public String PathName
        {
            get
            {
                return m_pathName;
            }
            set
            {
                m_pathName = value;
            }
        }       
        #endregion    
    }
    /// <summary>
    /// This class inherits from WindowParameter
    /// </summary>
    public class DoubleHungWinPara : WindowParameter
    {
        /// <summary>
        /// store the m_inset
        /// </summary>
        double m_inset = 0.0;
        /// <summary>
        /// store the m_sillHeight
        /// </summary>
        double m_sillHeight = 0.0; 
        #region
        /// <summary>
        /// set/get Inset property
        /// </summary>
        public double Inset
        {
            set
            {
                m_inset = value;
            }
            get
            {
                return m_inset;
            }
        }
        /// <summary>
        /// set/get SillHeight property
        /// </summary>
        public double SillHeight
        {
            set
            {
                m_sillHeight = value;
            }
            get
            {
                return m_sillHeight;
            }
        }
        #endregion
        /// <summary>
        /// constructor of DoubleHungWinPara
        /// </summary>
        /// <param name="isMetric">indicate whether the template is metric of imperial</param>
        public DoubleHungWinPara(bool isMetric)
            : base(isMetric)
        {
            if (isMetric)
            {
                m_inset = 20;
                m_sillHeight = 800;
            }
            else
            {
                m_inset = 0.05;
                m_sillHeight = 3;
            }            
        }
        /// <summary>
        /// constructor of DoubleHungWinPara
        /// </summary>
        /// <param name="dbhungPara">DoubleHungWinPara</param>
        public DoubleHungWinPara(DoubleHungWinPara dbhungPara)
            : base(dbhungPara)
        {
            m_inset = dbhungPara.Inset;
            m_sillHeight = dbhungPara.SillHeight;
        }
    }
}

DoubleHungWinCreation.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.IO;
using System.Collections.Generic;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;

namespace Revit.SDK.Samples.WindowWizard.CS
{
/// <summary>
/// Inherited from WindowCreation class
/// </summary>
class DoubleHungWinCreation : WindowCreation
{
#region Class Memeber Variables
/// <summary>
/// store the Application
/// </summary>
private UIApplication m_application;

/// <summary>
/// store the document
/// </summary>
private Document m_document;

/// <summary>
/// store the FamilyManager
/// </summary>
private FamilyManager m_familyManager;

/// <summary>
/// store the CreateDimension instance
/// </summary>
CreateDimension m_dimensionCreator;

/// <summary>
/// store the CreateExtrusion instance
/// </summary>
CreateExtrusion m_extrusionCreator;

/// <summary>
/// store the sash referenceplane
/// </summary>
ReferencePlane m_sashPlane;

/// <summary>
/// store the center referenceplane
/// </summary>
ReferencePlane m_centerPlane;

/// <summary>
/// store the exterior referenceplane
/// </summary>
ReferencePlane m_exteriorPlane;

/// <summary>
/// store the top referenceplane
/// </summary>
ReferencePlane m_topPlane;

/// <summary>
/// store the sill referenceplane
/// </summary>
ReferencePlane m_sillPlane;

/// <summary>
/// store the right view of the document
/// </summary>
Autodesk.Revit.DB.View m_rightView;

/// <summary>
/// store the frame category
/// </summary>
Category m_frameCat;

/// <summary>
/// store the glass category
/// </summary>
Category m_glassCat;

/// <summary>
/// store the thickness parameter of wall
/// </summary>
double m_wallThickness;

/// <summary>
/// store the height parameter of wall
/// </summary>
double m_height;

/// <summary>
/// store the width parameter of wall
/// </summary>
double m_width;

/// <summary>
/// store the sillheight parameter of wall
/// </summary>
double m_sillHeight;

/// <summary>
/// store the windowInset parameter of wall
/// </summary>
double m_windowInset;

/// <summary>
/// Store the height value of wall
/// </summary>
double m_wallHeight;

/// <summary>
/// Store the width value of wall
/// </summary>
double m_wallWidth;

/// <summary>
/// store the glass material ID
/// </summary>
int m_glassMatID;

/// <summary>
/// store the sash material ID
/// </summary>
int m_sashMatID;
#endregion

/// <summary>
/// constructor of DoubleHungWinCreation
/// </summary>
/// <param name="para">WizardParameter</param>
/// <param name="commandData">ExternalCommandData</param>
public DoubleHungWinCreation(WizardParameter para, ExternalCommandData commandData)
: base(para)
{
m_application = commandData.Application;
m_document = commandData.Application.ActiveUIDocument.Document;
m_familyManager = m_document.FamilyManager;

using (Transaction tran = new Transaction(m_document, "InitializeWindowWizard"))
{
tran.Start();

CollectTemplateInfo();
para.Validator = new ValidateWindowParameter(m_wallHeight, m_wallWidth);
switch (m_document.DisplayUnitSystem)
{
case Autodesk.Revit.DB.DisplayUnit.METRIC:
para.Validator.IsMetric = true;
break;
case Autodesk.Revit.DB.DisplayUnit.IMPERIAL:
para.Validator.IsMetric = false;
break;
}
para.PathName = Path.GetDirectoryName(para.PathName) + "Double Hung.rfa";

CreateCommon();

tran.Commit();
}

}

#region Class Implementation
/// <summary>
/// The implementation of CreateFrame()
/// </summary>
public override void CreateFrame()
{
SubTransaction subTransaction = new SubTransaction(m_document);
subTransaction.Start();

//create sash referenceplane and exterior referenceplane
CreateRefPlane refPlaneCreator = new CreateRefPlane();
if (m_sashPlane == null)
m_sashPlane = refPlaneCreator.Create(m_document, m_centerPlane, m_rightView, new Autodesk.Revit.DB.XYZ(0, m_wallThickness / 2 - m_windowInset, 0), new Autodesk.Revit.DB.XYZ(0, 0, 1), "Sash");
if (m_exteriorPlane == null)
m_exteriorPlane = refPlaneCreator.Create(m_document, m_centerPlane, m_rightView, new Autodesk.Revit.DB.XYZ(0, m_wallThickness / 2, 0), new Autodesk.Revit.DB.XYZ(0, 0, 1), "MyExterior");
m_document.Regenerate();

//get the wall in the document and retrieve the exterior face
List<Wall> walls = Utility.GetElements<Wall>(m_application, m_document);
Face exteriorWallFace = GeoHelper.GetWallFace(walls[0], m_rightView, true);
if (exteriorWallFace == null)
return;

//add dimension between sash reference plane and wall face,and add parameter "Window Inset",label the dimension with window-inset parameter
Dimension windowInsetDimension = m_dimensionCreator.AddDimension(m_rightView, m_sashPlane, exteriorWallFace);
FamilyParameter windowInsetPara = m_familyManager.AddParameter("Window Inset", BuiltInParameterGroup.INVALID, ParameterType.Length, false);
m_familyManager.Set(windowInsetPara, m_windowInset);
windowInsetDimension.FamilyLabel = windowInsetPara;

//create the exterior frame
double frameCurveOffset1 = 0.075;
CurveArray curveArr1 = m_extrusionCreator.CreateRectangle(m_width / 2, -m_width / 2, m_sillHeight + m_height, m_sillHeight, 0);
CurveArray curveArr2 = m_extrusionCreator.CreateCurveArrayByOffset(curveArr1, frameCurveOffset1);
CurveArrArray curveArrArray1 = new CurveArrArray();
curveArrArray1.Append(curveArr1);
curveArrArray1.Append(curveArr2);
Extrusion extFrame = m_extrusionCreator.NewExtrusion(curveArrArray1, m_sashPlane, m_wallThickness / 2 + m_wallThickness / 12, -m_windowInset);
extFrame.SetVisibility(CreateVisibility());
m_document.Regenerate();

//add alignment between wall face and exterior frame face
exteriorWallFace = GeoHelper.GetWallFace(walls[0], m_rightView, true); // Get the face again as the document is regenerated.
Face exteriorExtrusionFace1 = GeoHelper.GetExtrusionFace(extFrame, m_rightView, true);
Face interiorExtrusionFace1 = GeoHelper.GetExtrusionFace(extFrame, m_rightView, false);
CreateAlignment alignmentCreator = new CreateAlignment(m_document);
alignmentCreator.AddAlignment(m_rightView, exteriorWallFace, exteriorExtrusionFace1);

//add dimension between sash referenceplane and exterior frame face and lock the dimension
Dimension extFrameWithSashPlane = m_dimensionCreator.AddDimension(m_rightView, m_sashPlane, interiorExtrusionFace1);
extFrameWithSashPlane.IsLocked = true;
m_document.Regenerate();

//create the interior frame
double frameCurveOffset2 = 0.125;
CurveArray curveArr3 = m_extrusionCreator.CreateRectangle(m_width / 2, -m_width / 2, m_sillHeight + m_height, m_sillHeight, 0);
CurveArray curveArr4 = m_extrusionCreator.CreateCurveArrayByOffset(curveArr3, frameCurveOffset2);
m_document.Regenerate();

CurveArrArray curveArrArray2 = new CurveArrArray();
curveArrArray2.Append(curveArr3);
curveArrArray2.Append(curveArr4);
Extrusion intFrame = m_extrusionCreator.NewExtrusion(curveArrArray2, m_sashPlane, m_wallThickness - m_windowInset, m_wallThickness / 2 + m_wallThickness / 12);
intFrame.SetVisibility(CreateVisibility());
m_document.Regenerate();

//add alignment between interior face of wall and interior frame face
Face interiorWallFace = GeoHelper.GetWallFace(walls[0], m_rightView, false);
Face interiorExtrusionFace2 = GeoHelper.GetExtrusionFace(intFrame, m_rightView, false);
Face exteriorExtrusionFace2 = GeoHelper.GetExtrusionFace(intFrame, m_rightView, true);
alignmentCreator.AddAlignment(m_rightView, interiorWallFace, interiorExtrusionFace2);

//add dimension between sash referenceplane and interior frame face and lock the dimension
Dimension intFrameWithSashPlane = m_dimensionCreator.AddDimension(m_rightView, m_sashPlane, exteriorExtrusionFace2);
intFrameWithSashPlane.IsLocked = true;

//create the sill frame
CurveArray sillCurs = m_extrusionCreator.CreateRectangle(m_width / 2, -m_width / 2, m_sillHeight + frameCurveOffset1, m_sillHeight, 0);
CurveArrArray sillCurveArray = new CurveArrArray();
sillCurveArray.Append(sillCurs);
Extrusion sillFrame = m_extrusionCreator.NewExtrusion(sillCurveArray, m_sashPlane, -m_windowInset, -m_windowInset - 0.1);
m_document.Regenerate();

//add alignment between wall face and sill frame face
exteriorWallFace = GeoHelper.GetWallFace(walls[0], m_rightView, true); // Get the face again as the document is regenerated.
Face sillExtFace = GeoHelper.GetExtrusionFace(sillFrame, m_rightView, false);
alignmentCreator.AddAlignment(m_rightView, sillExtFace, exteriorWallFace);
m_document.Regenerate();

//set subcategories of the frames
if (m_frameCat != null)
{
extFrame.Subcategory = m_frameCat;
intFrame.Subcategory = m_frameCat;
sillFrame.Subcategory = m_frameCat;
}
subTransaction.Commit();
}

/// <summary>
/// The implementation of CreateSash(),and creating the Window Sash Solid Geometry
/// </summary>
public override void CreateSash()
{
double frameCurveOffset1 = 0.075;
double frameDepth = 7 * m_wallThickness / 12 + m_windowInset;
double sashCurveOffset = 0.075;
double sashDepth = (frameDepth - m_windowInset) / 2;

//get the exterior view and sash referenceplane which are used in this process
Autodesk.Revit.DB.View exteriorView = Utility.GetViewByName("Exterior", m_application, m_document);
SubTransaction subTransaction = new SubTransaction(m_document);
subTransaction.Start();

//add a middle reference plane between the top referenceplane and sill referenceplane
CreateRefPlane refPlaneCreator = new CreateRefPlane();
ReferencePlane middlePlane = refPlaneCreator.Create(m_document, m_topPlane, exteriorView, new Autodesk.Revit.DB.XYZ(0, 0, -m_height / 2), new Autodesk.Revit.DB.XYZ(0, -1, 0), "tempmiddle");
m_document.Regenerate();

//add dimension between top, sill, and middle reference plane, make the dimension segment equal
Dimension dim = m_dimensionCreator.AddDimension(exteriorView, m_topPlane, m_sillPlane, middlePlane);
dim.AreSegmentsEqual = true;

//create first sash
CurveArray curveArr5 = m_extrusionCreator.CreateRectangle(m_width / 2 - frameCurveOffset1, -m_width / 2 + frameCurveOffset1, m_sillHeight + m_height / 2 + sashCurveOffset / 2, m_sillHeight + frameCurveOffset1, 0);
CurveArray curveArr6 = m_extrusionCreator.CreateCurveArrayByOffset(curveArr5, sashCurveOffset);
m_document.Regenerate();

CurveArrArray curveArrArray3 = new CurveArrArray();
curveArrArray3.Append(curveArr5);
curveArrArray3.Append(curveArr6);
Extrusion sash1 = m_extrusionCreator.NewExtrusion(curveArrArray3, m_sashPlane, 2 * sashDepth, sashDepth);
m_document.Regenerate();

Face esashFace1 = GeoHelper.GetExtrusionFace(sash1, m_rightView, true);
Face isashFace1 = GeoHelper.GetExtrusionFace(sash1, m_rightView, false);
Dimension sashDim1 = m_dimensionCreator.AddDimension(m_rightView, esashFace1, isashFace1);
sashDim1.IsLocked = true;
Dimension sashWithPlane1 = m_dimensionCreator.AddDimension(m_rightView, m_sashPlane, isashFace1);
sashWithPlane1.IsLocked = true;
sash1.SetVisibility(CreateVisibility());

//create second sash
CurveArray curveArr7 = m_extrusionCreator.CreateRectangle(m_width / 2 - frameCurveOffset1, -m_width / 2 + frameCurveOffset1, m_sillHeight + m_height - frameCurveOffset1, m_sillHeight + m_height / 2 - sashCurveOffset / 2, 0);
CurveArray curveArr8 = m_extrusionCreator.CreateCurveArrayByOffset(curveArr7, sashCurveOffset);
m_document.Regenerate();

CurveArrArray curveArrArray4 = new CurveArrArray();
curveArrArray4.Append(curveArr7);
curveArrArray4.Append(curveArr8);
Extrusion sash2 = m_extrusionCreator.NewExtrusion(curveArrArray4, m_sashPlane, sashDepth, 0);
sash2.SetVisibility(CreateVisibility());
m_document.Regenerate();

Face esashFace2 = GeoHelper.GetExtrusionFace(sash2, m_rightView, true);
Face isashFace2 = GeoHelper.GetExtrusionFace(sash2, m_rightView, false);
Dimension sashDim2 = m_dimensionCreator.AddDimension(m_rightView, esashFace2, isashFace2);
sashDim2.IsLocked = true;
Dimension sashWithPlane2 = m_dimensionCreator.AddDimension(m_rightView, m_sashPlane, isashFace2);
m_document.Regenerate();
sashWithPlane2.IsLocked = true;

//set category of the sash extrusions
if (m_frameCat != null)
{
sash1.Subcategory = m_frameCat;
sash2.Subcategory = m_frameCat;
}
Autodesk.Revit.DB.ElementId id = new ElementId(m_sashMatID);
sash1.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM).Set(id);
sash2.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM).Set(id);
subTransaction.Commit();
}

/// <summary>
/// The implementation of CreateGlass(), creating the Window Glass Solid Geometry
/// </summary>
public override void CreateGlass()
{
double frameCurveOffset1 = 0.075;
double frameDepth = m_wallThickness - 0.15;
double sashCurveOffset = 0.075;
double sashDepth = (frameDepth - m_windowInset) / 2;
double glassDepth = 0.05;
double glassOffsetSash = 0.05; //from the exterior of the sash

//create first glass
SubTransaction subTransaction = new SubTransaction(m_document);
subTransaction.Start();
CurveArray curveArr9 = m_extrusionCreator.CreateRectangle(m_width / 2 - frameCurveOffset1 - sashCurveOffset, -m_width / 2 + frameCurveOffset1 + sashCurveOffset, m_sillHeight + m_height / 2 - sashCurveOffset / 2, m_sillHeight + frameCurveOffset1 + sashCurveOffset, 0);
m_document.Regenerate();

CurveArrArray curveArrArray5 = new CurveArrArray();
curveArrArray5.Append(curveArr9);
Extrusion glass1 = m_extrusionCreator.NewExtrusion(curveArrArray5, m_sashPlane, sashDepth + glassOffsetSash + glassDepth, sashDepth + glassOffsetSash);
m_document.Regenerate();
glass1.SetVisibility(CreateVisibility());
m_document.Regenerate();
Face eglassFace1 = GeoHelper.GetExtrusionFace(glass1, m_rightView, true);
Face iglassFace1 = GeoHelper.GetExtrusionFace(glass1, m_rightView, false);
Dimension glassDim1 = m_dimensionCreator.AddDimension(m_rightView, eglassFace1, iglassFace1);
glassDim1.IsLocked = true;
Dimension glass1WithSashPlane = m_dimensionCreator.AddDimension(m_rightView, m_sashPlane, eglassFace1);
glass1WithSashPlane.IsLocked = true;

//create the second glass
CurveArray curveArr10 = m_extrusionCreator.CreateRectangle(m_width / 2 - frameCurveOffset1 - sashCurveOffset, -m_width / 2 + frameCurveOffset1 + sashCurveOffset, m_sillHeight + m_height - frameCurveOffset1 - sashCurveOffset, m_sillHeight + m_height / 2 + sashCurveOffset / 2, 0);
CurveArrArray curveArrArray6 = new CurveArrArray();
curveArrArray6.Append(curveArr10);
Extrusion glass2 = m_extrusionCreator.NewExtrusion(curveArrArray6, m_sashPlane, glassOffsetSash + glassDepth, glassOffsetSash);
m_document.Regenerate();
glass2.SetVisibility(CreateVisibility());
m_document.Regenerate();
Face eglassFace2 = GeoHelper.GetExtrusionFace(glass2, m_rightView, true);
Face iglassFace2 = GeoHelper.GetExtrusionFace(glass2, m_rightView, false);
Dimension glassDim2 = m_dimensionCreator.AddDimension(m_rightView, eglassFace2, iglassFace2);
glassDim2.IsLocked = true;
Dimension glass2WithSashPlane = m_dimensionCreator.AddDimension(m_rightView, m_sashPlane, eglassFace2);
glass2WithSashPlane.IsLocked = true;

//set category
if (null != m_glassCat)
{
glass1.Subcategory = m_glassCat;
glass2.Subcategory = m_glassCat;
}
Autodesk.Revit.DB.ElementId id = new ElementId(m_glassMatID);

glass1.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM).Set(id);
glass2.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM).Set(id);
subTransaction.Commit();
}

/// <summary>
/// The implementation of CreateMaterial()
/// </summary>
public override void CreateMaterial()
{
SubTransaction subTransaction = new SubTransaction(m_document);
subTransaction.Start();

FilteredElementCollector elementCollector = new FilteredElementCollector(m_document);
elementCollector.WherePasses(new ElementClassFilter(typeof(Material)));
IList<Element> materials = elementCollector.ToElements();

foreach (Element materialElement in materials)
{
Material material = materialElement as Material;
if (0 == material.Name.CompareTo(m_para.SashMat))
{
m_sashMatID = material.Id.IntegerValue;
}

if (0 == material.Name.CompareTo(m_para.GlassMat))
{
m_glassMatID = material.Id.IntegerValue;
}
}
subTransaction.Commit();
}

/// <summary>
/// The implementation of CombineAndBuild() ,defining New Window Types
/// </summary>
public override void CombineAndBuild()
{
SubTransaction subTransaction = new SubTransaction(m_document);
subTransaction.Start();
foreach (String type in m_para.WinParaTab.Keys)
{
WindowParameter para = m_para.WinParaTab[type] as WindowParameter;

newFamilyType(para);
}

subTransaction.Commit();

}

/// <summary>
/// The implementation of Creation(), defining the way to do the whole creation.
/// </summary>
public override bool Creation()
{
using (Autodesk.Revit.DB.Transaction trans = new Transaction(m_document, "FinishWindowWizard"))
{
try
{
trans.Start();
this.CreateMaterial();
this.CreateFrame();
this.CreateSash();
this.CreateGlass();
this.CombineAndBuild();
trans.Commit();
}
catch (Exception ee)
{
System.Diagnostics.Debug.WriteLine(ee.Message);
System.Diagnostics.Debug.WriteLine(ee.StackTrace);
return false;
}
finally
{
if (trans.HasStarted())
trans.RollBack();
}
}

try
{
if (File.Exists(m_para.PathName))
File.Delete(m_para.PathName);
m_document.SaveAs(m_para.PathName);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Write to " + m_para.PathName + " Failed");
System.Diagnostics.Debug.WriteLine(e.Message);
}
return true;
}

/// <summary>
/// The method is used to collect template information, specifying the New Window Parameters
/// </summary>
private void CollectTemplateInfo()
{
List<Wall> walls = Utility.GetElements<Wall>(m_application, m_document);
m_wallThickness = walls[0].Width;
ParameterMap paraMap = walls[0].ParametersMap;
Parameter wallheightPara = walls[0].get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM);//paraMap.get_Item("Unconnected Height");
if (wallheightPara != null)
{
m_wallHeight = wallheightPara.AsDouble();
}

LocationCurve location = walls[0].Location as LocationCurve;
m_wallWidth = location.Curve.Length;

m_windowInset = m_wallThickness / 10;
FamilyType type = m_familyManager.CurrentType;
FamilyParameter heightPara = m_familyManager.get_Parameter(BuiltInParameter.WINDOW_HEIGHT);
FamilyParameter widthPara = m_familyManager.get_Parameter(BuiltInParameter.WINDOW_WIDTH);
FamilyParameter sillHeightPara = m_familyManager.get_Parameter("Default Sill Height");
if (type.HasValue(heightPara))
{
switch (heightPara.StorageType)
{
case StorageType.Double:
m_height = type.AsDouble(heightPara).Value;
break;
case StorageType.Integer:
m_height = type.AsInteger(heightPara).Value;
break;
}
}
if (type.HasValue(widthPara))
{
switch (widthPara.StorageType)
{
case StorageType.Double:
m_width = type.AsDouble(widthPara).Value;
break;
case StorageType.Integer:
m_width = type.AsDouble(widthPara).Value;
break;
}
}
if (type.HasValue(sillHeightPara))
{
switch (sillHeightPara.StorageType)
{
case StorageType.Double:
m_sillHeight = type.AsDouble(sillHeightPara).Value;
break;
case StorageType.Integer:
m_sillHeight = type.AsDouble(sillHeightPara).Value;
break;
}
}

//set the height,width and sillheight parameter of the opening
m_familyManager.Set(m_familyManager.get_Parameter(BuiltInParameter.WINDOW_HEIGHT),
m_height);
m_familyManager.Set(m_familyManager.get_Parameter(BuiltInParameter.WINDOW_WIDTH),
m_width);
m_familyManager.Set(m_familyManager.get_Parameter("Default Sill Height"), m_sillHeight);

//get materials

FilteredElementCollector elementCollector = new FilteredElementCollector(m_document);
elementCollector.WherePasses(new ElementClassFilter(typeof(Material)));
IList<Element> materials = elementCollector.ToElements();

foreach (Element materialElement in materials)
{
Material material = materialElement as Material;
m_para.GlassMaterials.Add(material.Name);
m_para.FrameMaterials.Add(material.Name);
}

//get categories
Categories categories = m_document.Settings.Categories;
Category category = categories.get_Item(BuiltInCategory.OST_Windows);
CategoryNameMap cnm = category.SubCategories;

m_frameCat = categories.get_Item(BuiltInCategory.OST_WindowsFrameMullionProjection);
m_glassCat = categories.get_Item(BuiltInCategory.OST_WindowsGlassProjection);

//get referenceplanes
List<ReferencePlane> planes = Utility.GetElements<ReferencePlane>(m_application, m_document);
foreach (ReferencePlane p in planes)
{
if (p.Name.Equals("Sash"))
m_sashPlane = p;
if (p.Name.Equals("Exterior"))
m_exteriorPlane = p;
if (p.Name.Equals("Center (Front/Back)"))
m_centerPlane = p;
if (p.Name.Equals("Top") || p.Name.Equals("Head"))
m_topPlane = p;
if (p.Name.Equals("Sill") || p.Name.Equals("Bottom"))
m_sillPlane = p;
}
}

/// <summary>
/// the method is used to create new family type
/// </summary>
/// <param name="para">WindowParameter</param>
/// <returns>indicate whether the NewType is successful</returns>
private bool newFamilyType(WindowParameter para)//string typeName, double height, double width, double sillHeight)
{
DoubleHungWinPara dbhungPara = para as DoubleHungWinPara;
string typeName = dbhungPara.Type;
double height = dbhungPara.Height;
double width = dbhungPara.Width;
double sillHeight = dbhungPara.SillHeight;
double windowInset = dbhungPara.Inset;
switch (m_document.DisplayUnitSystem)
{
case Autodesk.Revit.DB.DisplayUnit.METRIC:
height = Utility.MetricToImperial(height);
width = Utility.MetricToImperial(width);
sillHeight = Utility.MetricToImperial(sillHeight);
windowInset = Utility.MetricToImperial(windowInset);
break;
}
try
{
FamilyType type = m_familyManager.NewType(typeName);
m_familyManager.CurrentType = type;
m_familyManager.Set(m_familyManager.get_Parameter(BuiltInParameter.WINDOW_HEIGHT), height);
m_familyManager.Set(m_familyManager.get_Parameter(BuiltInParameter.WINDOW_WIDTH), width);
m_familyManager.Set(m_familyManager.get_Parameter("Default Sill Height"), sillHeight);
m_familyManager.Set(m_familyManager.get_Parameter("Window Inset"), windowInset);
return true;
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
return false;
}
}

/// <summary>
/// The method is used to create a FamilyElementVisibility instance
/// </summary>
/// <returns>FamilyElementVisibility instance</returns>
private FamilyElementVisibility CreateVisibility()
{
FamilyElementVisibility familyElemVisibility = new FamilyElementVisibility(FamilyElementVisibilityType.Model);
familyElemVisibility.IsShownInCoarse = true;
familyElemVisibility.IsShownInFine = true;
familyElemVisibility.IsShownInMedium = true;
familyElemVisibility.IsShownInFrontBack = true;
familyElemVisibility.IsShownInLeftRight = true;
familyElemVisibility.IsShownInPlanRCPCut = false;
return familyElemVisibility;
}

/// <summary>
/// The method is used to create common class variables in this class
/// </summary>
private void CreateCommon()
{
//create common
m_dimensionCreator = new CreateDimension(m_application.Application, m_document);
m_extrusionCreator = new CreateExtrusion(m_application.Application, m_document);
m_rightView = Utility.GetViewByName("Right", m_application, m_document);
}
#endregion
}
}