应用程序:边界条件

Revit平台:结构

Revit版本:2011.0

首次发布用于:9.1

编程语言:C#

技能等级:高

类别:结构

类型:外部命令

主题:创建或检索边界条件

摘要:此示例显示如何获取BoundaryConditions的参数或创建BoundaryConditions。

相关类:

Autodesk.Revit.UI.IExternalCommand

Autodesk.Revit.DB.BoundaryConditions

项目文件:

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

BoundaryConditionsData.cs此文件包含类BoundaryConditionsData,该类准备所需的数据(选定的图元类型及其BC信息)并创建Boundary Conditions。

BCProperties.cs此文件包含三个枚举(BCType、BCState和BCTranslationRotation)和两个类(BCTypeAttribute、BCProperties)。他们为包含在BoundaryConditionsForm中的PropertyGrid准备数据。

UnitConversion.cs此文件包含一个结构ConversionValue和一个类ConversionValue。该结构定义了显示值和内部值之间的转换规则。类是一个值转换字典,它存储一些单位及其对应的ConversionValue。

功能:

-只选择一个结构元素。

-如果所选择的元素具有边界条件,则呈现边界条件(BC)的参数。用户还可以使用其他有效值设置这些参数。

-在列表框中列出主机为所选元素的BC的所有Id。

-根据选择的BC Id,将显示相关的BC Type、State和X、Y、Z平移/旋转。

-不允许用户更改BC类型。

-用户可以将BC的“状态”设置为“固定”、“锁定”、“滚动”或“用户”(当选择不同的值时,X、Y或Z平移/旋转应根据Revit主程序UI进行相应的更改)。

-如果选择“用户”作为当前状态,则可以将X、Y或Z平移/旋转设置为“固定”、“释放”或“弹簧”。

-如果为X、Y或Z平移/旋转选择了“弹簧”,则可以输入正值作为“弹簧模量”(为用户显示值的单位)。

-如果所选元素没有BC,则创建一个BC。

-根据所选元素将“BC类型”设置为“点”、“线”或“区域”。(梁/墙/墙基础有BC线;柱/支撑有BC点;板/基础板有BC面积)

-其他初始参数设置为固定。

-用户可以更改除BC类型之外的所有参数值(参考最后一点的详细信息)

-当用户单击“确定”按钮时,将更新现有BC或创建新BC。

-我们应该使用Autodesk.Revit.Creation.Document的NewPointBoundaryConditions、NewLineBoundaryConditions和NewAreaBoundary条件方法来创建BC

实施:

1.打开Revit Structure并绘制一个梁。

2.选择梁并运行样本。

3.在窗体中的PropertyGrid控件中选择属性值。

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

5.返回Revit主程序,您可以看到在选定梁上创建了一条线“边界条件”。

其他:

-我们提供了四个附加文件(边界条件Pinned.rfa、边界条件Fixed.rfa、边界条件Roller.rfa和边界条件User.rfa)。它们是边界条件的族文件。如果无法绘制任何边界条件,请先载入这些族。然后在“设置”菜单->“结构设置”->“边界条件设置”中为“边界条件”设置族符号。

-只有以下结构元素可以具有BC:

柱/支撑/独立基础/梁/墙/墙基/板/基础板

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

BoundaryConditionsData.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;
using System.Text;
using System.Linq;
using System.Windows.Forms;

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

namespace Revit.SDK.Samples.BoundaryConditions.CS
{
    /// <summary>
    /// user select a element. If the selected element has boundary conditions, display 
    /// its parameter values else create one.
    /// this class prepare the needed data(the selected element type and its BC information) 
    /// and operate the Revit API
    /// </summary>
    public class BoundaryConditionsData
    {
        #region "Members"

        // the selected Element
        private Autodesk.Revit.DB.Element m_hostElement;

        // store all the corresponding BCs of the current selected host element 
        // and use the BC Id value as the key
        private Dictionary<int, Autodesk.Revit.DB.Structure.BoundaryConditions> m_bCsDictionary =
                new Dictionary<int, Autodesk.Revit.DB.Structure.BoundaryConditions>();

        // the object for which the grid in UI displays.
        private BCProperties m_bCProperties;

        #endregion

        #region "Properties"

        /// <summary>
        /// gets or sets the object for which the grid in UI displays. 
        /// </summary>
        public BCProperties BCProperties
        {
            get
            {
                return m_bCProperties;
            }
            set
            {
                m_bCProperties = value;
            }
        }

        /// <summary>
        /// get current host element
        /// </summary>
        public Autodesk.Revit.DB.Element HostElement
        {
            get
            {
                return m_hostElement;
            }
        }

        /// <summary>
        /// get all the BCs correspond with current host
        /// </summary>
        public Dictionary<int, Autodesk.Revit.DB.Structure.BoundaryConditions> BCs
        {
            get
            {
                return m_bCsDictionary;
            }
        }

        #endregion

        #region "Delegate" 

        //A delegate for create boundary condition with different type
        private delegate Autodesk.Revit.DB.Structure.BoundaryConditions
                CreateBCHandler(Autodesk.Revit.DB.Element HostElement);

        #endregion

        #region "Methods"

        /// <summary>
        /// construct function
        /// </summary>
        /// <param name="element"> host element</param>
        public BoundaryConditionsData(Autodesk.Revit.DB.Element element)
        {
            // store the selected element and its BCs
            SetBCHostMap(element);   
        }

        /// <summary>
        /// According to the selected element create corresponding Boundary Conditions.
        /// Add it into m_bCsDictionary.
        /// </summary>
        public bool CreateBoundaryConditions()
        {
            CreateBCHandler createBCH = null;
            
            // judge the type of the HostElement
            if (m_hostElement is FamilyInstance)
            {  
                FamilyInstance familyInstance = m_hostElement as FamilyInstance;
                StructuralType structuralType = familyInstance.StructuralType;

                if (structuralType == StructuralType.Beam)
                {
                    // create Line BC for beam
                    createBCH = new CreateBCHandler(CreateLineBC);
                }
                else if (structuralType == StructuralType.Brace  ||
                         structuralType == StructuralType.Column ||
                         structuralType == StructuralType.Footing)
                {
                    // create point BC for Column/brace
                    createBCH = new CreateBCHandler(CreatePointBC);
                }
            }
            else if (m_hostElement is Wall)
            {
                // create line BC for wall
                createBCH = new CreateBCHandler(CreateLineBC);
            }
            else if (m_hostElement is Floor)
            {
                // create area BC for Floor
                createBCH = new CreateBCHandler(CreateAreaBC);
            }
            else if (m_hostElement is WallFoundation)
            {
                // create line BC for WallFoundation
                createBCH = new CreateBCHandler(CreateLineBC);
            }

            // begin create
            Autodesk.Revit.DB.Structure.BoundaryConditions NewBC = null;
            try
            {
                NewBC = createBCH(m_hostElement);
                if (null == NewBC)
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }

            // add the created Boundary Conditions into m_bCsDictionary
            m_bCsDictionary.Add(NewBC.Id.IntegerValue, NewBC);
            return true;
        }

        /// <summary>
        /// store the selected element and its corresponding BCs
        /// </summary>
        /// <param name="element"> use selected element in Revit UI(the host element)</param>
        private void SetBCHostMap(Autodesk.Revit.DB.Element element)
        {
            // set the Host element with current selected element
            m_hostElement = element;
            // retrieve the Document in which the Element resides.
            Document doc = element.Document;

            IEnumerable<Autodesk.Revit.DB.Structure.BoundaryConditions> boundaryConditions = from elem in
                                                                                       new FilteredElementCollector(doc).OfClass(typeof(Autodesk.Revit.DB.Structure.BoundaryConditions)).ToElements()
                                                                                   let bC = elem as Autodesk.Revit.DB.Structure.BoundaryConditions
                                                                                   where bC != null && m_hostElement.Id.IntegerValue == bC.HostElement.Id.IntegerValue
                                                                                   select bC;
            foreach (Autodesk.Revit.DB.Structure.BoundaryConditions bC in boundaryConditions)
            {
                m_bCsDictionary.Add(bC.Id.IntegerValue, bC);
            }
        }

        /// <summary>
        /// Create a new Point BoundaryConditions Element. 
        /// All the parameter default as Fixed.
        /// </summary>
        /// <param name="hostElement"> 
        /// structural element which provide the analytical line end reference
        /// </param>
        /// <returns> the created Point BoundaryConditions Element</returns>
        private Autodesk.Revit.DB.Structure.BoundaryConditions CreatePointBC(Autodesk.Revit.DB.Element hostElement)
        {
            if (!(hostElement is FamilyInstance))
            {
                return null;
            }

            FamilyInstance familyInstance   = hostElement as FamilyInstance;
            AnalyticalModel analyticalModel = familyInstance.GetAnalyticalModel();
            Reference endReference          = null;

            Curve refCurve = analyticalModel.GetCurve();
            if (null != refCurve)
            {

                endReference = analyticalModel.GetReference(new AnalyticalModelSelector(refCurve,AnalyticalCurveSelector.EndPoint));
            }
            else
            {
                return null;
            }

            Autodesk.Revit.Creation.Document createDoc = hostElement.Document.Create;

            // invoke Document.NewPointBoundaryConditions Method 
            Autodesk.Revit.DB.Structure.BoundaryConditions createdBC = 
                    createDoc.NewPointBoundaryConditions(endReference, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
            return createdBC;
        }

        /// <summary>
        /// Create a new Line BoundaryConditions Element. 
        /// All the parameter default as Fixed.
        /// </summary>
        /// <param name="hostElement">structural element which provide the hostElementId</param>
        /// <returns>the created Point BoundaryConditions Element</returns>
        private Autodesk.Revit.DB.Structure.BoundaryConditions CreateLineBC(Autodesk.Revit.DB.Element hostElement)
        {
            Autodesk.Revit.Creation.Document createDoc = hostElement.Document.Create;

            // invoke Document.NewLineBoundaryConditions Method
            Autodesk.Revit.DB.Structure.BoundaryConditions createdBC = 
                    createDoc.NewLineBoundaryConditions(hostElement.GetAnalyticalModel(), 0, 0, 0, 0, 0, 0, 0, 0);

            return createdBC;
        }

        /// <summary>
        /// Create a new Area BoundaryConditions Element. 
        /// All the parameter default as Fixed.
        /// </summary>
        /// <param name="hostElement">structural element which provide the hostElementId</param>
        /// <returns>the created Point BoundaryConditions Element</returns>
        private Autodesk.Revit.DB.Structure.BoundaryConditions CreateAreaBC(Autodesk.Revit.DB.Element hostElement)
        {
            Autodesk.Revit.Creation.Document createDoc = hostElement.Document.Create;

            // invoke Document.NewAreaBoundaryConditions Method
            Autodesk.Revit.DB.Structure.BoundaryConditions createdBC =
                    createDoc.NewAreaBoundaryConditions(hostElement.GetAnalyticalModel(), 0, 0, 0, 0, 0, 0);

            return createdBC;
        } 

        #endregion
    }
}

BCProperties.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.Windows.Forms;

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

namespace Revit.SDK.Samples.BoundaryConditions.CS
{
    /// <summary>
    /// BoundaryConditions Type Enumeration
    /// </summary>
    public enum BCType
    {
        /// <summary>
        /// Point BC
        /// </summary>
        Point = 0,

        /// <summary>
        /// Line BC
        /// </summary>
        Line,

        /// <summary>
        /// Area BC
        /// </summary>
        Area
    };

    /// <summary>
    /// BoundaryConditions State Enumeration
    /// </summary>
    public enum BCState
    {
        /// <summary>
        /// the state of current BC is fixed
        /// </summary>
        Fixed = 0,

        /// <summary>
        /// the state of current BC is Pinned
        /// </summary>
        Pinned,

        /// <summary>
        /// the state of current BC is Roller
        /// </summary>
        Roller,

        /// <summary>
        /// the state of current BC is decided by user
        /// </summary>
        User
    };

    /// <summary>
    /// BoundaryConditions Translation/Rotation Enumeration
    /// </summary>
    public enum BCTranslationRotation
    {
        /// <summary>
        /// the BC is fixed, can used when any  BCState
        /// </summary>
        Fixed = 0,

        /// <summary>
        /// the BC's Translation/Rotation can released
        /// </summary>
        Released,

        /// <summary>
        /// user can set the BC's Translation/Rotation spring  modulus. 
        /// Only can be used when the BCState is User
        /// </summary>
        Spring,
    };
 
    /// <summary>
    /// A custom attribute to allow a target to have a pet.
    /// this attribute is about the BoundaryConditions Type Enumeration
    /// </summary>
    public sealed class BCTypeAttribute : Attribute
    { 
        // Keep a variable internally ...
        private BCType[] m_bCTypes;

        /// <summary>
        /// The constructor is called when the attribute is set.
        /// </summary>
        /// <param name="bcTypes"></param>
        public BCTypeAttribute(BCType[] bcTypes)
        {
            m_bCTypes = bcTypes;
        }

        /// <summary>
        /// property get or set internal variable m_bcTypes
        /// </summary>
        public BCType[] BCType
        {
            get
            {
                return m_bCTypes;
            }
            set
            {
                m_bCTypes = value;
            }
        }

        /// <summary>
        /// override Equals method
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            BCTypeAttribute temp = obj as BCTypeAttribute;
            if (null == temp)
            {
                return false;
            }

            foreach (BCType t1 in temp.BCType)
            {
                foreach (BCType t2 in m_bCTypes)
                {
                    if (t1 == t2)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// override GetHashCode method
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

    /// <summary>
    /// use to create instance as the display object of the PropertyGrid
    /// </summary>
    public class BCProperties
    {
        // the boundary conditions of which the information will displayed in the UI grid
        private Autodesk.Revit.DB.Structure.BoundaryConditions m_bC;

        #region "Properties"

        /// <summary>
        /// BoundaryConditions Type
        /// this item will be displayed no matter the point BC,line BC or area BC 
        /// </summary>
        [Category("Structural Analysis"),ReadOnly(true),
        BCType(new BCType[] { BCType.Point, BCType.Line, BCType.Area })]
        public BCType BoundaryConditionsType
        {
            get
            {
                return (BCType)GetParameterValue("Boundary Conditions Type", 
                        BuiltInParameterGroup.PG_STRUCTURAL_ANALYSIS);
            }
            set
            {
                SetParameterValue("Boundary Conditions Type", 
                        BuiltInParameterGroup.PG_STRUCTURAL_ANALYSIS, value);
            }
        }

        /// <summary>
        /// BoundaryConditions State
        /// </summary>
        [Category("Structural Analysis"),
        BCType(new BCType[] { BCType.Point, BCType.Line, BCType.Area })]
        public BCState State
        {
            get
            {
                return (BCState)GetParameterValue("State", BuiltInParameterGroup.PG_STRUCTURAL_ANALYSIS);
            }
            // Point BC includes Fixed, Pinned, Roller and User four different State; 
            // Line BC includes Fixed, Pinned and User; 
            // while the Area BC includes Pinned and User.
            set
            {
                if (BCType.Area == BoundaryConditionsType)
                {
                    if (BCState.Fixed != value && BCState.Roller != value)
                    {
                        SetParameterValue("State", BuiltInParameterGroup.PG_STRUCTURAL_ANALYSIS, value);
                    }
                }
                else if (BCType.Line == BoundaryConditionsType)
                {
                    if (BCState.Roller != value)
                    {
                        SetParameterValue("State", BuiltInParameterGroup.PG_STRUCTURAL_ANALYSIS, value); ;
                    }
                }
                else if (BCType.Point == BoundaryConditionsType)
                {
                    SetParameterValue("State", BuiltInParameterGroup.PG_STRUCTURAL_ANALYSIS, value); ;
                }

                // other parameters do corresponding change when the State is changed.
                MatchBCValuesRule();
            }
        }
        
        /// <summary>
        /// BoundaryConditions XTranslation
        /// </summary>
        [Description("This value can be edit under User state"),Category("Translation in"),
        BCType(new BCType[]{BCType.Point, BCType.Line, BCType.Area})]
        public BCTranslationRotation XTranslation
        {
            get
            {
                return (BCTranslationRotation)GetParameterValue("X Translation", 
                        BuiltInParameterGroup.PG_TRANSLATION_IN);
            }
            set
            {
                if (BCState.User == State)
                {
                    SetParameterValue("X Translation", BuiltInParameterGroup.PG_TRANSLATION_IN, value);
                }       
            }
        }

        /// <summary>
        /// BoundaryConditions SpringModulus about XTranslation
        /// </summary>
        [Category("Translation in")]
        public double XTranslationSpringModulus
        {
            get
            {
                return (double)GetParameterValue("X Spring Modulus", 
                        BuiltInParameterGroup.PG_TRANSLATION_IN);
            }
            set
            {
                SetParameterValue("X Spring Modulus", BuiltInParameterGroup.PG_TRANSLATION_IN, value);
            }
        }

        /// <summary>
        /// BoundaryCondition YTranslation
        /// </summary>
        [Description("This value can be edit under User state"),Category("Translation in"),
         BCType(new BCType[] { BCType.Point, BCType.Line, BCType.Area })]
        public BCTranslationRotation YTranslation
        {
            get
            {
                return (BCTranslationRotation)GetParameterValue("Y Translation", 
                        BuiltInParameterGroup.PG_TRANSLATION_IN);
            }
            set
            {
                if (BCState.User == State)
                {
                    SetParameterValue("Y Translation", BuiltInParameterGroup.PG_TRANSLATION_IN, value);
                }
            }
        }

        /// <summary>
        /// BoundaryConditions SpringModulus about YTranslation
        /// </summary>
        [Category("Translation in")]
        public double YTranslationSpringModulus
        {
            get
            {
                return (double)GetParameterValue("Y Spring Modulus", 
                        BuiltInParameterGroup.PG_TRANSLATION_IN);
            }
            set
            {
                SetParameterValue("Y Spring Modulus", BuiltInParameterGroup.PG_TRANSLATION_IN, value);
            }
        }

        /// <summary>
        /// BoundaryConditions ZTranslation
        /// </summary>
        [Description("This value can be edit under User state"), Category("Translation in"), 
        BCType(new BCType[] { BCType.Point, BCType.Line, BCType.Area })]
        public BCTranslationRotation ZTranslation
        {
            get
            {
                return (BCTranslationRotation)GetParameterValue("Z Translation",
                        BuiltInParameterGroup.PG_TRANSLATION_IN);
            }
            set
            {
                if (BCState.User == State)
                {
                    SetParameterValue("Z Translation", BuiltInParameterGroup.PG_TRANSLATION_IN, value);
                }
            }
        }

        /// <summary>
        /// BoundaryConditions SpringModulus about ZTranslation
        /// </summary>
        [Category("Translation in")]
        public double ZTranslationSpringModulus
        {
            get
            {
                return (double)GetParameterValue("Z Spring Modulus",
                        BuiltInParameterGroup.PG_TRANSLATION_IN);
            }
            set
            {
                SetParameterValue("Z Spring Modulus", BuiltInParameterGroup.PG_TRANSLATION_IN, value);
            }
        }

        /// <summary>
        /// BoundaryConditions XRotation
        /// only displayed when the BC Type is point or line
        /// </summary>
        [Description("This value can be edit under User state"), Category("Rotation about"), 
        BCType(new BCType[] { BCType.Point, BCType.Line})]
        public BCTranslationRotation XRotation
        {
            get
            {
                return (BCTranslationRotation)GetParameterValue("X Rotation", 
                        BuiltInParameterGroup.PG_ROTATION_ABOUT);
            }
            set
            {
                if (BCState.User == State)
                {
                    SetParameterValue("X Rotation", BuiltInParameterGroup.PG_ROTATION_ABOUT, value);
                }
            }
        }

        /// <summary>
        /// BoundaryConditions SpringModulus about XRotation
        /// </summary>
        [Category("Rotation about")]
        public double XRotationSpringModulus
        {
            get
            {
                return (double)GetParameterValue("X Spring Modulus",
                        BuiltInParameterGroup.PG_ROTATION_ABOUT);
            }
            set
            {
                SetParameterValue("X Spring Modulus", BuiltInParameterGroup.PG_ROTATION_ABOUT, value);
            }
        }

        /// <summary>
        /// BoundaryConditions YRotation
        /// Only be displayed when the BC Type is point
        /// </summary>
        [ Description("This value can be edit under User state"),Category("Rotation about"), 
        BCType(new BCType[] { BCType.Point})]
        public BCTranslationRotation YRotation
        {
            get
            {
                return (BCTranslationRotation)GetParameterValue("Y Rotation",
                        BuiltInParameterGroup.PG_ROTATION_ABOUT);
            }
            set
            {
                if (BCState.User == State)
                {
                    SetParameterValue("Y Rotation", BuiltInParameterGroup.PG_ROTATION_ABOUT, value);
                }
            }
        }

        /// <summary>
        /// BoundaryConditions SpringModulus about YRotation
        /// </summary>
        [Category("Rotation about")]
        public double YRotationSpringModulus
        {
            get
            {
                return (double)GetParameterValue("Y Spring Modulus",
                        BuiltInParameterGroup.PG_ROTATION_ABOUT);
            }
            set
            {
                SetParameterValue("Y Spring Modulus", BuiltInParameterGroup.PG_ROTATION_ABOUT, value);
            }
        }

        /// <summary>
        /// BoundaryConditions ZRotation
        /// </summary>
        [Description("This value can be edit under User state"), 
        Category("Rotation about"),BCType(new BCType[] { BCType.Point })]
        public BCTranslationRotation ZRotation
        {
            get
            {
                return (BCTranslationRotation)GetParameterValue("Z Rotation",
                        BuiltInParameterGroup.PG_ROTATION_ABOUT);
            }
            set
            {
                if (BCState.User == State)
                {
                    SetParameterValue("Z Rotation", BuiltInParameterGroup.PG_ROTATION_ABOUT, value);
                }
            }
        }

        /// <summary>
        /// BoundaryConditions SpringModulus about ZRotation
        /// </summary>
        [Category("Rotation about")]
        public double  ZRotationSpringModulus
        {
            get
            {
                return (double)GetParameterValue("Z Spring Modulus",
                        BuiltInParameterGroup.PG_ROTATION_ABOUT);
            }
            set
            {
                SetParameterValue("Z Spring Modulus", BuiltInParameterGroup.PG_ROTATION_ABOUT, value);
            }
        }

        #endregion

        #region "Methods"

        /// <summary>
        /// constructor  
        /// </summary>
        /// <param name="bC">
        /// the boundary conditions of which the information will displayed in the UI grid
        /// </param>
        public BCProperties(Autodesk.Revit.DB.Structure.BoundaryConditions bC)
        {
            m_bC = bC;
        }

        /// <summary>
        /// When Spring is selected for Translation/Rotation the user enter a positive value 
        /// greater than Zero as the corresponding Spring Modulus. 
        /// And according to its display unit do the conversion between display value and inside value.
        /// </summary>
        /// <param name="gridItemLabel">the name of parameter which value is spring</param>
        public void SetSpringModulus(string gridItemLabel)
        {
            using (SpringModulusForm springModulusForm = new SpringModulusForm())
            {
                // judge current conversion rule between the display value and inside value
                if (BCType.Point == BoundaryConditionsType)
                {
                    if (gridItemLabel.Contains("Translation"))
                    {
                        springModulusForm.Conversion = UnitConversion.UnitDictionary["PTSpringModulusConver"];
                    }
                    else if (gridItemLabel.Contains("Rotation"))
                    {
                        springModulusForm.Conversion = UnitConversion.UnitDictionary["PRSpringModulusConver"];
                    }
                }
                else if (BCType.Line == BoundaryConditionsType)
                {
                    if (gridItemLabel.Contains("Translation"))
                    {
                        springModulusForm.Conversion = UnitConversion.UnitDictionary["LTSpringModulusConver"];
                    }
                    else if (gridItemLabel.Contains("Rotation"))
                    {
                        springModulusForm.Conversion = UnitConversion.UnitDictionary["LRSpringModulusConver"];
                    }
                }
                else if (BCType.Area == BoundaryConditionsType && gridItemLabel.Contains("Translation"))
                {
                    springModulusForm.Conversion = UnitConversion.UnitDictionary["ATSpringModulusConver"];
                }

                // get the old value
                if ("XTranslation" == gridItemLabel)
                {
                    springModulusForm.OldStringModulus = XTranslationSpringModulus;
                }
                else if ("YTranslation" == gridItemLabel)
                {
                    springModulusForm.OldStringModulus = YTranslationSpringModulus;
                }
                else if ("ZTranslation" == gridItemLabel)
                {
                    springModulusForm.OldStringModulus = ZTranslationSpringModulus;
                }
                else if ("XRotation" == gridItemLabel)
                {
                    springModulusForm.OldStringModulus = XRotationSpringModulus;
                }
                else if ("YRotation" == gridItemLabel)
                {
                    springModulusForm.OldStringModulus = YRotationSpringModulus;
                }
                else if ("ZRotation" == gridItemLabel)
                {
                    springModulusForm.OldStringModulus = ZRotationSpringModulus;
                }

                // show the spring modulus dialog to ask a positive number
                DialogResult result = springModulusForm.ShowDialog();

                // set the user input number as the new value
                if (DialogResult.OK == result)
                {
                    if ("XTranslation" == gridItemLabel)
                    {
                        XTranslationSpringModulus = springModulusForm.StringModulus;
                    }
                    else if ("YTranslation" == gridItemLabel)
                    {
                        YTranslationSpringModulus = springModulusForm.StringModulus;
                    }
                    else if ("ZTranslation" == gridItemLabel)
                    {
                        ZTranslationSpringModulus = springModulusForm.StringModulus;
                    }
                    else if ("XRotation" == gridItemLabel)
                    {
                        XRotationSpringModulus = springModulusForm.StringModulus;
                    }
                    else if ("YRotation" == gridItemLabel)
                    {
                        YRotationSpringModulus = springModulusForm.StringModulus;
                    }
                    else if ("ZRotation" == gridItemLabel)
                    {
                        ZRotationSpringModulus = springModulusForm.StringModulus;
                    }
                }
            }
        }

        /// <summary>
        /// get parameter via matching the appointed name and group.
        /// and deal with it according to the type of Parameter's StorageType
        /// </summary>
        protected Object GetParameterValue(string parameterName, BuiltInParameterGroup parameterGroup)
        {
            ParameterSet parameters = m_bC.Parameters;
            foreach (Parameter parameter in parameters)
            {
                // find the parameter of which the name is the same as the param name
                if ((parameterName != parameter.Definition.Name) || 
                    (parameterGroup != parameter.Definition.ParameterGroup))
                {
                    continue;
                }

                // get the parameter value
                switch (parameter.StorageType)
                {
                    case StorageType.Double:
                        return parameter.AsDouble();
                    case StorageType.Integer:
                        return parameter.AsInteger();
                    case StorageType.ElementId:
                        return parameter.AsElementId();
                    case StorageType.String:
                        return parameter.AsString();
                    case StorageType.None:
                        return parameter.AsValueString();
                    default:
                        return null;
                }
            }

            return null;
        }

        /// <summary>
        /// when user changed the parameter value via the UI set this changed parameter value
        /// </summary>
        /// <param name="parameterName">the name of the changed parameter</param>
        /// <param name="parameterGroup">
        /// because some parameters of boundary conditions have the same name
        /// </param>
        /// <param name="value">the new parameter value</param>
        protected void SetParameterValue(string parameterName,
                                         BuiltInParameterGroup parameterGroup, 
                                         Object value)
        {
            ParameterSet parameters = m_bC.Parameters;
            foreach (Parameter parameter in parameters)
            {
                // find the parameter of which the name is the same as the param name
                if ((parameterName != parameter.Definition.Name) ||
                    (parameterGroup != parameter.Definition.ParameterGroup))
                {
                    continue;
                }

                // get the parameter value
                switch (parameter.StorageType)
                {
                    case StorageType.Double:
                        parameter.Set((double)value);
                        break;
                    case StorageType.Integer:
                        parameter.Set((int)value);
                        break;
                    case StorageType.ElementId:
                        Autodesk.Revit.DB.ElementId Id = (Autodesk.Revit.DB.ElementId)value;
                        parameter.Set(Id);
                        break;
                    case StorageType.String:
                        parameter.Set(value as string);
                        break;
                    case StorageType.None:
                        parameter.SetValueString(value as string);
                        break;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// the BC parameter values rules according to the Revit main program.
        /// For example, when the State is Fixed all the Translation/Rotation parameters are Fixed too.
        /// </summary>
        private void MatchBCValuesRule()
        {
            if (BCState.Fixed == State)
            {
                XTranslation = BCTranslationRotation.Fixed;
                YTranslation = BCTranslationRotation.Fixed;
                ZTranslation = BCTranslationRotation.Fixed;
                XRotation    = BCTranslationRotation.Fixed;
                YRotation    = BCTranslationRotation.Fixed;
                ZRotation    = BCTranslationRotation.Fixed;
            }
            else if (BCState.Pinned == State)
            {
                XTranslation = BCTranslationRotation.Fixed;
                YTranslation = BCTranslationRotation.Fixed;
                ZTranslation = BCTranslationRotation.Fixed;
                ZRotation    = BCTranslationRotation.Released;
                YRotation    = BCTranslationRotation.Released;
                ZRotation    = BCTranslationRotation.Released;
            }
            else if (BCState.Roller == State)
            {
                XTranslation = BCTranslationRotation.Released;
                YTranslation = BCTranslationRotation.Released;
                ZTranslation = BCTranslationRotation.Fixed;
                XRotation    = BCTranslationRotation.Released;
                YRotation    = BCTranslationRotation.Released;
                ZRotation    = BCTranslationRotation.Released;
            }
        }

        #endregion
    }
}

UnitConversion.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;

namespace Revit.SDK.Samples.BoundaryConditions.CS
{
    /// <summary>
    /// a structure about the conversion rule between display value and inside value
    /// </summary>
    public struct ConversionValue
    {
        // members
        private int m_precision;   // the precision of the diaplay value
        private string m_unitName; // the unit of the display value
        private double m_ratio;    // the radio of inside value to display value

        /// <summary>
        /// constructor, using to initialize the members
        /// </summary>
        /// <param name="precision">the precision of the diaplay value</param>
        /// <param name="ratio">the unit of the display value</param>
        /// <param name="unitName">the radio of inside value to display valuea</param>
        public ConversionValue(int precision, double ratio, string unitName)
        {

            m_precision = precision;
            m_ratio     = ratio;
            m_unitName  = unitName;
        }

        /// <summary>
        /// get the precision of the diaplay value
        /// </summary>
        public int Precision
        {
            get 
            {
                return m_precision;
            }
        }

        /// <summary>
        /// get the unit of the display value
        /// </summary>
        public string UnitName
        {
            get 
            {
                return m_unitName;
            }
        }

        /// <summary>
        /// get the radio of inside value to display value
        /// </summary>
        public double Ratio
        {
            get 
            {
                return m_ratio;
            }
        }
    };

    /// <summary>
    /// value conversion dictionary, in this class the data we gave only fit for Imperial unit
    /// the relationship about dislay paramete values and inside parameter values
    /// </summary>
    public static class UnitConversion
    {
        // member: dictionary
        private static Dictionary<string, ConversionValue> m_unitDictionary;

        /// <summary>
        /// get the value dictionary
        /// </summary>
        public static Dictionary<string, ConversionValue> UnitDictionary
        {
            get
            {
                return m_unitDictionary;
            }
        }

        /// <summary>
        /// static constructor to initialize the value conversion dictionary which we will used 
        /// according to the difference unit
        /// </summary>
        static UnitConversion()
        {
            m_unitDictionary = new Dictionary<string, ConversionValue>();

            #region "fill my units dictionary"
            char degree = (char)0xb0;
            char square = (char)0xB2;
            char cube = (char)0xB3;

            // about point BC's translation spring modulus
            AddNewUnit(1, 175126.835246476, "kip/in", "PTSpringModulusConver");

            // about point BC's rotation spring modulus
            AddNewUnit(1, 47880.2589803358, "kip-f/" + degree + "F", "PRSpringModulusConver");

            // about Line BC's translation spring modulus
            AddNewUnit(4, 14593.9029372064, "kip/ft" + square, "LTSpringModulusConver");

            // about Line BC's rotation spring modulus
            AddNewUnit(1, 47880.2589803358, "kip-f/" + degree + "F/ft", "LRSpringModulusConver");

            // about Area BC's translation spring modulus
            AddNewUnit(1, 14593.9029372064, "kip/ft" + cube, "ATSpringModulusConver");

            #endregion
        }

        /// <summary>
        /// add a new unit conversion item
        /// </summary>
        /// <param name="precision"> the precision of the display value</param>
        /// <param name="ratio"> the radio of inside value to display value about current unit</param>
        /// <param name="unitName"> the unit of the display value</param>
        /// <param name="key"></param>
        private static void AddNewUnit(int precision, double ratio, string unitName, string key)
        {
            // create a ConversionValue instance
            ConversionValue conversionValue = new ConversionValue(precision, ratio, unitName);

            // add this item to ourself dictionary
            m_unitDictionary.Add(key, conversionValue);
        }
    }
}