应用程序:CreateBeamSystem

Revit平台:Structure

Revit版本:2011.0

首次发布用于:9.1

编程语言:C#

技能等级:高

类别:结构

类型:外部命令

主题:创建梁系统

摘要:此示例演示如何使用水平线性梁选项配置文件生成梁系统。

相关类:

Autodesk.Revit.UI.IExternalCommand

Autodesk.Revit.DB.BeamSystem

Autodesk.Revit.DB.BeamSystem.LayoutRule

Autodesk.Revit.DB.FamilySymbol

项目文件:

Command.cs这是主DLL源文件。它包含实现接口IExternalCommand的类Command。

BeamSystemBuilder.cs此文件包含一个类BeamSystemBuilder,用于创建梁系统的新实例。

BeamSystemData.cs此文件包含一个类BeamSystemData,它是一个混合数据类(保存UI中显示的数据和用于创建梁系统的数据)。

功能:

-用户选择一些线性梁,这些梁首先形成水平轮廓,并使用该轮廓创建梁系统。允许用户更改已创建梁系统的布局方法和梁类型。

-该命令将显示一个对话框,左侧为预览窗口,右侧为常规特性栅格。

-通用特性网格允许用户更改布局方法(净间距、固定距离、固定数量和最大间距)和梁类型。

-预览窗口显示梁系统的轮廓及其方向。

-波束系统的方向由CurveArray中的第一条线决定,该线在NewBeamSystem方法中被用作轮廓的参数。

-梁系统的布局方法和梁类型可以通过BeamSystem的BeamType和LayoutRule属性进行检索和修改。

-使用Autodesk.Revit.Creation.Document.NewBeamSystem(CurveArray)方法创建BeamSystem。

实施:

-用户选择一些线性梁,这些梁首先形成水平轮廓,并使用该轮廓创建梁系统。允许用户更改已创建梁系统的布局方法和梁类型。

-该命令将显示一个对话框,左侧为预览窗口,右侧为常规特性栅格。

-通用特性网格允许用户更改布局方法(净间距、固定距离、固定数量和最大间距)和梁类型。

-预览窗口显示梁系统的轮廓及其方向。

-波束系统的方向由CurveArray中的第一条线决定,该线在NewBeamSystem方法中被用作轮廓的参数。

-梁系统的布局方法和梁类型可以通过BeamSystem的BeamType和LayoutRule属性进行检索和修改。

-使用Autodesk.Revit.Creation.Document.NewBeamSystem(CurveArray)方法创建BeamSystem。

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

BeamSystemBuilder.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.CreateBeamSystem.CS
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;

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

    /// <summary>
    /// is used to create new instances of beam system
    /// </summary>
    public class BeamSystemBuilder
    {
        /// <summary>
        /// the data used to create beam system
        /// </summary>
        private BeamSystemData m_data;

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="data">the data used to create beam system</param>
        public BeamSystemBuilder(BeamSystemData data)
        {
            m_data = data;
        }

        /// <summary>
        /// create beam system according to given profile and property
        /// </summary>
        public void CreateBeamSystem()
        {
            Document document = m_data.CommandData.Application.ActiveUIDocument.Document;
            // create curve array and insert Lines in order
            IList<Curve> curves = new List<Curve>();
            foreach (Line line in m_data.Lines)
            {
                curves.Add(line);
            }
            // create beam system takes closed profile consist of lines
            BeamSystem aBeamSystem = BeamSystem.Create(document, curves, document.ActiveView.SketchPlane, 0);
            // set created beam system's layout rule and beam type property
            aBeamSystem.LayoutRule = m_data.Param.Layout;
            aBeamSystem.BeamType = m_data.Param.BeamType;
        }
    }
}

BeamSystemData.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.CreateBeamSystem.CS
{
    using System;
    using System.Text;
    using System.Collections.Generic;
    using System.Collections;
    using System.Diagnostics;
    using System.Collections.ObjectModel;

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

    /// <summary>
    /// mixed data class save the data to show in UI
    /// and the data used to create beam system
    /// </summary>
    public class BeamSystemData
    {
        /// <summary>
        /// all beam types loaded in current Revit project
        /// it is declared as static only because of PropertyGrid
        /// </summary>
        private static Dictionary<string, FamilySymbol> m_beamTypes = new Dictionary<string, FamilySymbol>();

        /// <summary>
        /// properties of beam system
        /// </summary>
        private BeamSystemParam m_param;

        /// <summary>
        /// buffer of ExternalCommandData
        /// </summary>
        private ExternalCommandData m_commandData;

        /// <summary>
        /// the lines compose the profile of beam system
        /// </summary>
        private List<Line> m_lines = new List<Line>();

        /// <summary>
        /// a number of beams that intersect end to end
        /// so that form a profile used as beam system's profile
        /// </summary>
        private List<FamilyInstance> m_beams = new List<FamilyInstance>();

        /// <summary>
        /// properties of beam system
        /// </summary>
        public BeamSystemParam Param
        {
            get
            {
                return m_param; 
            }
        }

        /// <summary>
        /// lines form the profile of beam system
        /// </summary>
        public ReadOnlyCollection<Line> Lines
        {
            get
            {
                return new ReadOnlyCollection<Line>(m_lines);
            }
        }

        /// <summary>
        /// buffer of ExternalCommandData
        /// </summary>
        public ExternalCommandData CommandData
        {
            get
            {
                return m_commandData;
            }
        }

        /// <summary>
        /// the data used to show in UI is updated
        /// </summary>
        public event EventHandler ParamsUpdated;

        /// <summary>
        /// constructor
        /// if precondition in current Revit project isn't enough,
        /// ErrorMessageException will be throw out
        /// </summary>
        /// <param name="commandData">data from Revit</param>
        public BeamSystemData(ExternalCommandData commandData)
        {
            // initialize members
            m_commandData = commandData;
            PrepareData();
            InitializeProfile(m_beams);

            m_param                      = BeamSystemParam.CreateInstance(LayoutMethod.ClearSpacing);
            List<FamilySymbol> beamTypes = new List<FamilySymbol>(m_beamTypes.Values);
            m_param.BeamType             = beamTypes[0];
            m_param.LayoutRuleChanged   += new LayoutRuleChangedHandler(LayoutRuleChanged);
        }

        /// <summary>
        /// change the direction to the next line in the profile
        /// </summary>
        public void ChangeProfileDirection()
        {
            Line tmp = m_lines[0];
            m_lines.RemoveAt(0);
            m_lines.Add(tmp);
        }

        /// <summary>
        /// all beam types loaded in current Revit project
        /// it is declared as static only because of PropertyGrid
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, FamilySymbol> GetBeamTypes()
        {
            Dictionary<string, FamilySymbol> beamTypes = new Dictionary<string, FamilySymbol>(m_beamTypes);
            return beamTypes;
        }

        /// <summary>
        /// initialize members using data from current Revit project
        /// </summary>
        private void PrepareData()
        {
            UIDocument doc = m_commandData.Application.ActiveUIDocument;
            m_beamTypes.Clear();

            // iterate all selected beams
            foreach (ElementId elementId in doc.Selection.GetElementIds())
            {
               object obj = doc.Document.GetElement(elementId);
                FamilyInstance beam = obj as FamilyInstance;
                if (null == beam)
                {
                    continue;
                }

                // add beam to lists according to category name
                string categoryName = beam.Category.Name;
                if ("Structural Framing" == categoryName
                    && beam.StructuralType == StructuralType.Beam)
                {
                    m_beams.Add(beam);
                }
            }

            //iterate all beam types
            FilteredElementIterator itor = new FilteredElementCollector(doc.Document).OfClass(typeof(Family)).GetElementIterator();
            itor.Reset();
            while (itor.MoveNext())
            {
                // get Family to get FamilySymbols
                Family aFamily = itor.Current as Family;
                if (null == aFamily)
                {
                    continue;
                }

                foreach (ElementId symbolId in aFamily.GetFamilySymbolIds())
                {
                   FamilySymbol symbol = doc.Document.GetElement(symbolId) as FamilySymbol;
                    if (null == symbol.Category)
                    {
                        continue;
                    }

                    // add symbols to lists according to category name
                    string categoryName = symbol.Category.Name;
                    if ("Structural Framing" == categoryName)
                    {
                        m_beamTypes.Add(symbol.Family.Name + ":" + symbol.Name, symbol);
                    }
                }
            }

            if (m_beams.Count == 0)
            {
                throw new ErrorMessageException("Please select beams.");
            }

            if (m_beamTypes.Count == 0)
            {
                throw new ErrorMessageException("There is no Beam families loaded in current project.");
            }
        }

        /// <summary>
        /// retrieve the profiles using the selected beams
        /// ErrorMessageException will be thrown out if beams can't make a closed profile
        /// </summary>
        /// <param name="beams">beams which may form a closed profile</param>
        private void InitializeProfile(List<FamilyInstance> beams)
        {
            // retrieve collection of lines in beams
            List<Line> lines = new List<Line>();
            foreach (FamilyInstance beam in beams)
            {
                LocationCurve locationLine = beam.Location as LocationCurve;
                Line line = locationLine.Curve as Line;
            if (null == line)
            {
               throw new ErrorMessageException("Please don't select any arc beam.");
            }
                lines.Add(line);
            }

            // lines should in the same horizontal plane
            if (!GeometryUtil.InSameHorizontalPlane(lines))
            {
                throw new ErrorMessageException("The selected beams can't form a horizontal profile.");
            }

            // sorted lines so that all lines are intersect end to end
            m_lines = GeometryUtil.SortLines(lines);
            // lines can't make a closed profile
            if (null == m_lines)
            {
                throw new ErrorMessageException("The selected beams can't form a closed profile.");
            }
        }

        /// <summary>
        /// layout rule of beam system has changed
        /// </summary>
        /// <param name="layoutMethod">changed method</param>
        private void LayoutRuleChanged(ref LayoutMethod layoutMethod)
        {
            // create BeamSystemParams instance according to changed LayoutMethod
            m_param = m_param.CloneInstance(layoutMethod);

            // raise DataUpdated event
            OnParamsUpdated(new EventArgs());

            // rebind delegate
            m_param.LayoutRuleChanged += new LayoutRuleChangedHandler(LayoutRuleChanged);
        }

        /// <summary>
        /// the data used to show in UI is updated
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnParamsUpdated(EventArgs e)
        {
            if (null != ParamsUpdated)
            {
                ParamsUpdated(this, e);
            }
        }
    }
}