应用程序:RebarContainerAnyShapeType

Revit平台:Structure

Revit版本:2016.0

首次发布时间:2016.0

编程语言:C#

技能水平:高级

分类:结构

类型:ExternalCommand

主题:创建Rebar Container对象。

摘要:

展示如何在当前未承载钢筋的混凝土构件(梁或柱)中创建Rebar Container

相关类:

Autodesk.Revit.UI.IExternalCommand

Autodesk.Revit.Creation.Document

Autodesk.Revit.DB.Structure.Rebar

Autodesk.Revit.DB.Structure.StructuralType

项目文件:

Command.cs

定义了从IExternalCommand接口继承并实现Execute方法的Command类。Execute的功能是显示模型对话框以为所选元素创建Rebar Container

 

FramReinMaker.cs

定义了由BeamFramReinMakerColumnFramReinMaker派生的FramReinMaker类。这些类的功能是为所选宿主元素创建一个Rebar Container。如果所选元素是梁,则makerBeamFramReinMaker。如果所选元素是列,则makerColumnFramReinMaker

 

BeamFramReinMaker.cs

定义了从FramReinMaker继承的BeamFramReinMaker类。它用于为梁创建Rebar Container

 

ColumnFramReinMaker.cs

定义了从FramReinMaker继承的ColumnFramReinMaker类。它用于为柱创建Rebar Container

 

BeamFramReinMakerForm.cs

定义了从Form继承的BeamFramReinMakerForm类。这个类的功能是为梁的创建准备参数。

 

ColumnFramReinMakerForm.cs

定义了从Form继承的ColumnFramReinMakerForm类。这个类的功能是为柱的创建准备参数。

 

GeomData.cs

定义了BeamRebarDataColumnRebarData类。它们存储梁支撑和柱增强创建的信息。

 

GeometrySupport.cs

作为基类,它支持BeamGeometrySupportColumnGeometrySupport类,并可以存储常见几何信息。这个类也提供了一些辅助函数。

 

BeamGeometrySupport.cs

作为钢筋创建的几何支持类,它为顶部和底部钢筋条以及横向钢筋条的创建准备几何信息。

 

ColumnGeometrySupport.cs

作为柱增强创建的几何支持类,它为横向和竖向钢筋条的创建准备几何信息。

 

GeomUtil.cs

定义了提供基本几何操作的GeomUtil类。它是一个静态类。

 

ParameterUtil.cs

定义了ParameterUtil类,其中包含查找或设置某些参数的实用方法。它是一个静态类。

描述:

此示例使用RebarContainer.Create方法创建所选宿主的Rebar ContainerRebarContainer.Create方法需要RebarContainerType参数,该参数由RebarContainerType.CreateDefaultContainerType调用。

说明:

1.打开现有项目或创建一个新的Revit项目,其中包含当前未承载钢筋的混凝土梁或柱。示例工程文件RebarContainerAnyShapeType.rvt可在样本文件夹中找到。

2.选择混凝土梁或柱,运行命令。

3.设置弹出对话框中的钢筋参数。

4.单击“确定”,将为所选元素(梁或柱)创建Rebar Container

源代码:

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

BeamFramReinMaker.cs

//
// (C) Copyright 2015 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.Windows.Forms;

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

namespace Revit.SDK.Samples.RebarContainerAnyShapeType.CS
{

/// <summary>
/// The class derived from FramReinMaker shows how to create the reinforcement for a beam
/// </summary>
public class BeamFramReinMaker : FramReinMaker
{
#region Private Members

BeamGeometrySupport m_geometry; // The geometry support for beam reinforcement creation

// The reinforcement type, hook type and spacing information
RebarBarType m_topEndType = null; //type of the end reinforcement in the top of beam
RebarBarType m_topCenterType = null; //type of the center reinforcement in the center of beam
RebarBarType m_bottomType = null; //type of the reinforcement on bottom of the beam
RebarBarType m_transverseType = null; //type of the transverse reinforcement

RebarHookType m_topHookType = null; //type of the hook in the top end reinforcement
RebarHookType m_transverseHookType = null; // type of the hook in the transverse reinforcement

double m_transverseEndSpacing = 0; //the spacing value of end transverse reinforcement
double m_transverseCenterSpacing = 0; //the spacing value of center transverse reinforcement

#endregion

#region Properties
/// <summary>
/// get and set the type of the end reinforcement in the top of beam
/// </summary>
public RebarBarType TopEndRebarType
{
get
{
return m_topEndType;
}
set
{
m_topEndType = value;
}
}

/// <summary>
/// get and set the type of the center reinforcement in the top of beam
/// </summary>
public RebarBarType TopCenterRebarType
{
get
{
return m_topCenterType;
}
set
{
m_topCenterType = value;
}
}

/// <summary>
/// get and set the type of the reinforcement in the bottom of beam
/// </summary>
public RebarBarType BottomRebarType
{
get
{
return m_bottomType;
}
set
{
m_bottomType = value;
}
}

/// <summary>
/// get and set the type of the transverse reinforcement
/// </summary>
public RebarBarType TransverseRebarType
{
get
{
return m_transverseType;
}
set
{
m_transverseType = value;
}
}

/// <summary>
/// get and set the spacing value of end transverse reinforcement
/// </summary>
public double TransverseEndSpacing
{
get
{
return m_transverseEndSpacing;
}
set
{
if (0 > value)
{
throw new Exception("Transverse end spacing should be above zero");
}
m_transverseEndSpacing = value;
}
}

/// <summary>
/// get and set the spacing value of center transverse reinforcement
/// </summary>
public double TransverseCenterSpacing
{
get
{
return m_transverseCenterSpacing;
}
set
{
if (0 > value)
{
throw new Exception("Transverse center spacing should be above zero");
}
m_transverseCenterSpacing = value;
}
}

/// <summary>
/// get and set the hook type of top end reinforcement
/// </summary>
public RebarHookType TopHookType
{
get
{
return m_topHookType;
}
set
{
m_topHookType = value;
}
}

/// <summary>
/// get and set the hook type of transverse reinforcement
/// </summary>
public RebarHookType TransverseHookType
{
get
{
return m_transverseHookType;
}
set
{
m_transverseHookType = value;
}
}

#endregion

#region Constructor
/// <summary>
/// Constructor of the BeamFramReinMaker
/// </summary>
/// <param name="commandData">the ExternalCommandData reference</param>
/// <param name="hostObject">the host beam</param>
public BeamFramReinMaker(ExternalCommandData commandData, FamilyInstance hostObject)
: base(commandData, hostObject)
{
//create new options for current project
Options geoOptions = commandData.Application.Application.Create.NewGeometryOptions();
geoOptions.ComputeReferences = true;

//create a BeamGeometrySupport instance.
m_geometry = new BeamGeometrySupport(hostObject, geoOptions);
}
#endregion

#region Override Methods
/// <summary>
/// Override method to do some further checks
/// </summary>
/// <returns>true if the the data is right and enough, otherwise false.</returns>
protected override bool AssertData()
{
return base.AssertData();
}

/// <summary>
/// Display a form to collect the information for beam reinforcement creation
/// </summary>
/// <returns>true if the information collection is successful, otherwise false</returns>
protected override bool DisplayForm()
{
// Display BeamFramReinMakerForm for the user to input information
using (BeamFramReinMakerForm displayForm = new BeamFramReinMakerForm(this))
{
if (DialogResult.OK != displayForm.ShowDialog())
{
return false;
}
}
return base.DisplayForm();
}

/// <summary>
/// Override method to create rebar on the selected beam
/// </summary>
/// <returns>true if the creation is successful, otherwise false</returns>
protected override bool FillWithBars()
{
//create Rebar Container
ElementId conTypeId = RebarContainerType.CreateDefaultRebarContainerType(m_revitDoc);
RebarContainer cont = RebarContainer.Create(m_revitDoc, m_hostObject, conTypeId);

// create the top items
bool flag = FillTopItems(cont);

// create the bottom items
flag = flag && FillBottomItems(cont);

// create the transverse items
flag = flag && FillTransverseItems(cont);

return base.FillWithBars();
}

#endregion

/// <summary>
/// Create the reinforcement at the bottom of beam
/// </summary>
/// <returns>true if the creation is successful, otherwise false</returns>
public bool FillBottomItems(RebarContainer cont)
{
// get the geometry information of the bottom reinforcement
RebarGeometry geomInfo = m_geometry.GetBottomRebar();

// create the container item
RebarContainerItem item = PlaceContainerItem(cont, m_bottomType, null, null, geomInfo, RebarHookOrientation.Left, RebarHookOrientation.Left);
return (null != item);
}

/// <summary>
/// Create the transverse reinforcement
/// </summary>
/// <returns>true if the creation is successful, otherwise false</returns>
public bool FillTransverseItems(RebarContainer cont)
{
// create all kinds of transverse reinforcement according to the TransverseRebarLocation
foreach (TransverseRebarLocation location in Enum.GetValues(
typeof(TransverseRebarLocation)))
{
RebarContainerItem item = FillTransverseItem(cont, location);
//judge whether the transverse reinforcement creation is successful
if (null == item)
{
return false;
}
}

return true;
}

/// <summary>
/// Create the transverse reinforcement, according to the location of transverse bars
/// </summary>
/// <param name="location">location of rebar which need to be created</param>
/// <returns>the created container item, return null if the creation is unsuccessful</returns>
public RebarContainerItem FillTransverseItem(RebarContainer cont, TransverseRebarLocation location)
{
// Get the geometry information which support reinforcement creation
RebarGeometry geomInfo = new RebarGeometry();
switch (location)
{
case TransverseRebarLocation.Start: // start transverse reinforcement
case TransverseRebarLocation.End: // end transverse reinforcement
geomInfo = m_geometry.GetTransverseRebar(location, m_transverseEndSpacing);
break;
case TransverseRebarLocation.Center:// center transverse reinforcement
geomInfo = m_geometry.GetTransverseRebar(location, m_transverseCenterSpacing);
break;
}

RebarHookOrientation startHook = RebarHookOrientation.Left;
RebarHookOrientation endHook = RebarHookOrientation.Left;
if (!GeomUtil.IsInRightDir(geomInfo.Normal))
{
startHook = RebarHookOrientation.Right;
endHook = RebarHookOrientation.Right;
}

// create the container item
return PlaceContainerItem(cont, m_transverseType, m_transverseHookType, m_transverseHookType, geomInfo, startHook, endHook);
}

/// <summary>
/// Get the hook orient of the top reinforcement
/// </summary>
/// <param name="geomInfo">the rebar geometry support information</param>
/// <param name="location">the location of top rebar</param>
/// <returns>the hook orient of the top hook</returns>
private RebarHookOrientation GetTopHookOrient(RebarGeometry geomInfo, TopRebarLocation location)
{
// Top center rebar doesn't need hook.
if (TopRebarLocation.Center == location)
{
throw new Exception("Center top reinforcement doesn't have any hook.");
}

// Get the hook direction, reinforcement normal and reinforcement line
Autodesk.Revit.DB.XYZ hookVec = m_geometry.GetDownDirection();
Autodesk.Revit.DB.XYZ normal = geomInfo.Normal;
Line rebarLine = geomInfo.Curves[0] as Line;

// get the top start hook orient
if (TopRebarLocation.Start == location)
{
Autodesk.Revit.DB.XYZ curveVec = GeomUtil.SubXYZ(rebarLine.GetEndPoint(0), rebarLine.GetEndPoint(1));
return GeomUtil.GetHookOrient(curveVec, normal, hookVec);
}
else // get the top end hook orient
{
Autodesk.Revit.DB.XYZ curveVec = GeomUtil.SubXYZ(rebarLine.GetEndPoint(0), rebarLine.GetEndPoint(1));
return GeomUtil.GetHookOrient(curveVec, normal, hookVec);
}
}

/// <summary>
/// Create the reinforcement at the top of beam
/// </summary>
/// <returns>true if the creation is successful, otherwise false</returns>
private bool FillTopItems(RebarContainer cont)
{
// create all kinds of top reinforcement according to the TopRebarLocation
foreach (TopRebarLocation location in Enum.GetValues(typeof(TopRebarLocation)))
{
RebarContainerItem item = FillTopItem(cont, location);
//judge whether the top reinforcement creation is successful
if (null == item)
{
return false;
}
}

return true;
}

/// <summary>
/// Create the reinforcement at the top of beam, according to the top reinforcement location
/// </summary>
/// <param name="location">location of rebar which need to be created</param>
/// <returns>the created reinforcement, return null if the creation is unsuccessful</returns>
private RebarContainerItem FillTopItem(RebarContainer cont, TopRebarLocation location)
{
//get the geometry information of the reinforcement
RebarGeometry geomInfo = m_geometry.GetTopRebar(location);

RebarHookType startHookType = null; //the start hook type of the reinforcement
RebarHookType endHookType = null; // the end hook type of the reinforcement
RebarBarType rebarType = null; // the reinforcement type
RebarHookOrientation startOrient = RebarHookOrientation.Right;// the start hook orient
RebarHookOrientation endOrient = RebarHookOrientation.Left; // the end hook orient

// decide the reinforcement type, hook type and hook orient according to location
switch (location)
{
case TopRebarLocation.Start:
startHookType = m_topHookType; // start hook type
rebarType = m_topEndType; // reinforcement type
startOrient = GetTopHookOrient(geomInfo, location); // start hook orient
break;
case TopRebarLocation.Center:
rebarType = m_topCenterType; // reinforcement type
break;
case TopRebarLocation.End:
endHookType = m_topHookType; // end hook type
rebarType = m_topEndType; // reinforcement type
endOrient = GetTopHookOrient(geomInfo, location); // end hook orient
break;
}

// create the container item
return PlaceContainerItem(cont, rebarType, startHookType, endHookType, geomInfo, startOrient, endOrient);
}

}
}

BeamGeometrySupport.cs

//
// (C) Copyright 2015 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.DB.Structure;

namespace Revit.SDK.Samples.RebarContainerAnyShapeType.CS
{
/// <summary>
/// The geometry support for reinforcement creation on beam.
/// It can prepare the geometry information for top reinforcement, bottom and transverse reinforcement creation
/// </summary>
public class BeamGeometrySupport : GeometrySupport
{
// Private members
double m_beamLength; //the length of the beam
double m_beamWidth; //the width of the beam
double m_beamHeight; //the height of the beam

/// <summary>
/// constructor
/// </summary>
/// <param name="element">the beam which the rebars are placed on</param>
/// <param name="geoOptions">the geometry option</param>
public BeamGeometrySupport(FamilyInstance element, Options geoOptions)
: base(element, geoOptions)
{
// assert the host element is a beam
if (!element.StructuralType.Equals(StructuralType.Beam))
{
throw new Exception("BeamGeometrySupport can only work for beam instance.");
}

// Get the length, width and height of the beam.
m_beamLength = GetDrivingLineLength();
m_beamWidth = GetBeamWidth();
m_beamHeight = GetBeamHeight();
}

/// <summary>
/// Get the geometry information for top rebar
/// </summary>
/// <param name="location">indicate where top rebar is placed</param>
/// <returns>the gotten geometry information</returns>
public RebarGeometry GetTopRebar(TopRebarLocation location)
{
// sort the points of the swept profile
XYZHeightComparer comparer = new XYZHeightComparer();
m_points.Sort(comparer);

// Get the normal parameter for reinforcement creation
List<Autodesk.Revit.DB.XYZ > directions = GetRelatedVectors(m_points[3]);
directions.Sort(comparer);
Autodesk.Revit.DB.XYZ normal = directions[1];

double offset = 0; //the offset from the beam surface to the reinforcement
double startPointOffset = 0; // the offset of start point from swept profile
double rebarLength = m_beamLength / 3; //the length of the reinforcement
int rebarNumber = BeamRebarData.TopRebarNumber; //the number of the reinforcement

// set offset and startPointOffset according to the location of reinforcement
switch (location)
{
case TopRebarLocation.Start: // top start reinforcement
offset = BeamRebarData.TopEndOffset;
break;
case TopRebarLocation.Center: // top center reinforcement
offset = BeamRebarData.TopCenterOffset;
startPointOffset = m_beamLength / 3 - 0.5;
rebarLength = m_beamLength / 3 + 1;
break;
case TopRebarLocation.End: // top end reinforcement
offset = BeamRebarData.TopEndOffset;
startPointOffset = m_beamLength * 2 / 3;
break;
default:
throw new Exception("The program should never go here.");
}

// Get the curve which define the shape of the top reinforcement curve
List<Autodesk.Revit.DB.XYZ > movedPoints = OffsetPoints(offset);
Autodesk.Revit.DB.XYZ startPoint = movedPoints[movedPoints.Count - 1];

// offset the start point according startPointOffset
startPoint = GeomUtil.OffsetPoint(startPoint, m_drivingVector, startPointOffset);
// get the coordinate of endpoint
Autodesk.Revit.DB.XYZ endPoint = GeomUtil.OffsetPoint(startPoint, m_drivingVector, rebarLength);
IList<Curve> curves = new List<Curve>(); //the profile of the top reinforcement
curves.Add(Line.CreateBound(startPoint, endPoint));

// the spacing of the reinforcement
double spacing = spacing = (m_beamWidth - 2 * offset) / (rebarNumber - 1);

// return the reinforcement geometry information
return new RebarGeometry(normal, curves, rebarNumber, spacing);
}

/// <summary>
/// Get the geometry information of bottom reinforcement
/// </summary>
/// <returns>the gotten geometry information</returns>
public RebarGeometry GetBottomRebar()
{
// sort the points of the swept profile
XYZHeightComparer comparer = new XYZHeightComparer();
m_points.Sort(comparer);

// Get the normal parameter for bottom reinforcement creation
List<Autodesk.Revit.DB.XYZ > directions = GetRelatedVectors(m_points[0]);
directions.Sort(comparer);
Autodesk.Revit.DB.XYZ normal = directions[0];

double offset = BeamRebarData.BottomOffset; //offset value of the reinforcement
int rebarNumber = BeamRebarData.BottomRebarNumber; //the number of the reinforcement
// the spacing of the reinforcement
double spacing = (m_beamWidth - 2 * offset) / (rebarNumber - 1);

// Get the curve which define the shape of the bottom reinforcement curve
List<Autodesk.Revit.DB.XYZ > movedPoints = OffsetPoints(offset);
Autodesk.Revit.DB.XYZ startPoint = movedPoints[0]; //get the coordinate of startpoint
//get the coordinate of endpoint
Autodesk.Revit.DB.XYZ endPoint = GeomUtil.OffsetPoint(startPoint, m_drivingVector, m_beamLength);

IList<Curve> curves = new List<Curve>(); //the profile of the bottom reinforcement
curves.Add(Line.CreateBound(startPoint, endPoint));

// return the reinforcement geometry information
return new RebarGeometry(normal, curves, rebarNumber, spacing);
}

/// <summary>
/// Get the geometry information of transverse reinforcement
/// </summary>
/// <param name="location">indicate which part of transverse rebar</param>
/// <param name="spacing">the spacing of the rebar</param>
/// <returns>the gotten geometry information</returns>
public RebarGeometry GetTransverseRebar(TransverseRebarLocation location, double spacing)
{
// sort the points of the swept profile
XYZHeightComparer comparer = new XYZHeightComparer();
m_points.Sort(comparer);

// the offset from the beam surface to the reinforcement
double offset = BeamRebarData.TransverseOffset;
// the offset from the beam end to the transverse end
double endOffset = BeamRebarData.TransverseEndOffset;
// the offset between two transverses
double betweenOffset = BeamRebarData.TransverseSpaceBetween;
// the length of the transverse reinforcement
double rebarLength = (m_beamLength - 2 * endOffset - 2 * betweenOffset) / 3;
// the number of the transverse reinforcement
int rebarNumber = (int)(rebarLength / spacing) + 1;

// get the origin and normal parameter for reinforcement creation
Autodesk.Revit.DB.XYZ normal = m_drivingVector;
double curveOffset = 0;

//judge the coordinate of transverse reinforcement according to the location
switch (location)
{
case TransverseRebarLocation.Start: // start transverse reinforcement
curveOffset = endOffset;
break;
case TransverseRebarLocation.Center: // center transverse reinforcement
curveOffset = endOffset + rebarLength + betweenOffset;
curveOffset = curveOffset + (rebarLength % spacing) / 2;
break;
case TransverseRebarLocation.End: // end transverse reinforcement
curveOffset = m_beamLength - endOffset - rebarLength + (rebarLength % spacing);
break;
default:
throw new Exception("The program should never go here.");
}

// get the profile of the transverse reinforcement
List<Autodesk.Revit.DB.XYZ > movedPoints = OffsetPoints(offset);

// Translate curves points
List<Autodesk.Revit.DB.XYZ > translatedPoints = new List<Autodesk.Revit.DB.XYZ >();
foreach (Autodesk.Revit.DB.XYZ point in movedPoints)
{
translatedPoints.Add(GeomUtil.OffsetPoint(point, m_drivingVector, curveOffset));
}

IList<Curve> curves = new List<Curve>();
Autodesk.Revit.DB.XYZ first = translatedPoints[0];
Autodesk.Revit.DB.XYZ second = translatedPoints[1];
Autodesk.Revit.DB.XYZ third = translatedPoints[2];
Autodesk.Revit.DB.XYZ fourth = translatedPoints[3];

curves.Add(Line.CreateBound(first, second));
curves.Add(Line.CreateBound(second, fourth));
curves.Add(Line.CreateBound(fourth, third));
curves.Add(Line.CreateBound(third, first));

// return the reinforcement geometry information
return new RebarGeometry(normal, curves, rebarNumber, spacing);
}

/// <summary>
/// Get the down direction, which stand for the top hook direction
/// </summary>
/// <returns>the down direction</returns>
public Autodesk.Revit.DB.XYZ GetDownDirection()
{
XYZHeightComparer comparer = new XYZHeightComparer();
m_points.Sort(comparer);

Autodesk.Revit.DB.XYZ refPoint = m_points[3];
List<Autodesk.Revit.DB.XYZ > directions = GetRelatedVectors(refPoint);
directions.Sort(comparer);

return directions[0];
}

/// <summary>
/// Get the width of the beam
/// </summary>
/// <returns>the width data</returns>
private double GetBeamWidth()
{
XYZHeightComparer comparer = new XYZHeightComparer();
m_points.Sort(comparer);

Autodesk.Revit.DB.XYZ refPoint = m_points[0];
List<Autodesk.Revit.DB.XYZ > directions = GetRelatedVectors(refPoint);
directions.Sort(comparer);

return GeomUtil.GetLength(directions[0]);
}

/// <summary>
/// Get the height of the beam
/// </summary>
/// <returns>the height data</returns>
private double GetBeamHeight()
{
XYZHeightComparer comparer = new XYZHeightComparer();
m_points.Sort(comparer);

Autodesk.Revit.DB.XYZ refPoint = m_points[0];
List<Autodesk.Revit.DB.XYZ > directions = GetRelatedVectors(refPoint);
directions.Sort(comparer);

return GeomUtil.GetLength(directions[1]);
}
}
}

ColumnFramReinMaker.cs

//
// (C) Copyright 2015 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.Windows.Forms;

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

namespace Revit.SDK.Samples.RebarContainerAnyShapeType.CS
{
/// <summary>
/// The class derived form FramReinMaker shows how to create the reinforcement for a column
/// </summary>
public class ColumnFramReinMaker : FramReinMaker
{
#region Private Members

ColumnGeometrySupport m_geometry; // The geometry support for column reinforcement creation

RebarBarType m_transverseEndType = null; //type of the end transverse reinforcement
RebarBarType m_transverseCenterType = null; //type of the center transverse reinforcement
RebarBarType m_verticalType = null; //type of the vertical reinforcement
RebarHookType m_transverseHookType = null; //type of the hook

double m_transverseEndSpacing = 0; //the space value of end transverse reinforcement
double m_transverseCenterSpacing = 0; //the space value of center transverse reinforcement
int m_verticalRebarNumber = 0; //the number of the vertical reinforcement

#endregion

#region Properties

/// <summary>
/// get and set the type of the end transverse reinforcement
/// </summary>
public RebarBarType TransverseEndType
{
get
{
return m_transverseEndType;
}
set
{
m_transverseEndType = value;
}
}

/// <summary>
/// get and set the type of the center transverse reinforcement
/// </summary>
public RebarBarType TransverseCenterType
{
get
{
return m_transverseCenterType;
}
set
{
m_transverseCenterType = value;
}
}

/// <summary>
/// get and set the type of the vertical reinforcement
/// </summary>
public RebarBarType VerticalRebarType
{
get
{
return m_verticalType;
}
set
{
m_verticalType = value;
}
}

/// <summary>
/// get and set the space value of end transverse reinforcement
/// </summary>
public double TransverseEndSpacing
{
get
{
return m_transverseEndSpacing;
}
set
{
if (0 > value) // spacing data must be above 0
{
throw new Exception("Transverse end spacing should be above zero");
}
m_transverseEndSpacing = value;
}
}

/// <summary>
/// get and set the space value of center transverse reinforcement
/// </summary>
public double TransverseCenterSpacing
{
get
{
return m_transverseCenterSpacing;
}
set
{
if (0 > value) // spacing data must be above 0
{
throw new Exception("Transverse center spacing should be above zero");
}
m_transverseCenterSpacing = value;
}
}

/// <summary>
/// get and set the number of vertical reinforcement
/// </summary>
public int VerticalRebarNumber
{
get
{
return m_verticalRebarNumber;
}
set
{
if (4 > value) // vertical reinforcement number must be above 3
{
throw new Exception("The minimum of vertical reinforcement number should be 4.");
}
m_verticalRebarNumber = value;
}
}

/// <summary>
/// get and set the hook type of transverse reinforcement
/// </summary>
public RebarHookType TransverseHookType
{
get
{
return m_transverseHookType;
}
set
{
m_transverseHookType = value;
}
}

#endregion

#region Constructor
/// <summary>
/// Constructor of the ColumnFramReinMaker
/// </summary>
/// <param name="commandData">the ExternalCommandData reference</param>
/// <param name="hostObject">the host column</param>
public ColumnFramReinMaker(ExternalCommandData commandData, FamilyInstance hostObject)
: base(commandData, hostObject)
{
//create a new options for current project
Options geoOptions = commandData.Application.Application.Create.NewGeometryOptions();
geoOptions.ComputeReferences = true;

//create a ColumnGeometrySupport instance
m_geometry = new ColumnGeometrySupport(hostObject, geoOptions);
}
#endregion

#region Override Methods

/// <summary>
/// Override method to do some further checks
/// </summary>
/// <returns>true if the the data is right and enough, otherwise false.</returns>
protected override bool AssertData()
{
return base.AssertData();
}

/// <summary>
/// Display a form to collect the information for column reinforcement creation
/// </summary>
/// <returns>true if the information collection is successful, otherwise false</returns>
protected override bool DisplayForm()
{
// Display ColumnFramReinMakerForm for the user input information
using (ColumnFramReinMakerForm displayForm = new ColumnFramReinMakerForm(this))
{
if (DialogResult.OK != displayForm.ShowDialog())
{
return false;
}
}
return base.DisplayForm();
}

/// <summary>
/// Override method to create reinforcement on the selected column
/// </summary>
/// <returns>true if the creation is successful, otherwise false.</returns>
protected override bool FillWithBars()
{
//create Rebar Container
ElementId conTypeId = RebarContainerType.CreateDefaultRebarContainerType(m_revitDoc);
ElementId hostId = m_hostObject.Id;
Element host = m_revitDoc.GetElement(hostId);
if (null != host)
{
RebarContainer cont = RebarContainer.Create(m_revitDoc, host, conTypeId);
bool flag = FillTransverseItems(cont);
flag = flag && FillVerticalItems(cont);
}

return base.FillWithBars();
}

#endregion

/// <summary>
/// create the transverse reinforcement for the column
/// </summary>
/// <returns>true if the creation is successful, otherwise false</returns>
public bool FillTransverseItems(RebarContainer cont)
{
// create all kinds of transverse reinforcement according to the TransverseRebarLocation
foreach (TransverseRebarLocation location in Enum.GetValues(typeof(TransverseRebarLocation)))
{
RebarContainerItem item = FillTransverseItem(cont, location);
//judge whether the transverse reinforcement creation is successful
if (null == item)
{
return false;
}
}

return true;
}

/// <summary>
/// Create the transverse reinforcement, according to the transverse reinforcement location
/// </summary>
/// <param name="location">location of rebar which need to be created</param>
/// <returns>the created reinforcement, return null if the creation is unsuccessful</returns>
public RebarContainerItem FillTransverseItem(RebarContainer cont, TransverseRebarLocation location)
{
// Get the geometry information which support reinforcement creation
RebarGeometry geomInfo = new RebarGeometry();
RebarBarType barType = null;
switch (location)
{
case TransverseRebarLocation.Start: // start transverse reinforcement
case TransverseRebarLocation.End: // end transverse reinforcement
geomInfo = m_geometry.GetTransverseRebar(location, m_transverseEndSpacing);
barType = m_transverseEndType;
break;
case TransverseRebarLocation.Center:// center transverse reinforcement
geomInfo = m_geometry.GetTransverseRebar(location, m_transverseCenterSpacing);
barType = m_transverseCenterType;
break;
default:
break;
}

// create the container item
return PlaceContainerItem(cont, barType, m_transverseHookType, m_transverseHookType, geomInfo, RebarHookOrientation.Left, RebarHookOrientation.Left);
}

/// <summary>
/// Create the vertical reinforcement according the location
/// </summary>
/// <param name="location">location of rebar which need to be created</param>
/// <returns>the created reinforcement, return null if the creation is unsuccessful</returns>
public RebarContainerItem FillVerticalItem(RebarContainer cont, VerticalRebarLocation location)
{
//calculate the reinforcement number in different location
int rebarNubmer = m_verticalRebarNumber / 4;
switch (location)
{
case VerticalRebarLocation.East: // the east vertical reinforcement
if (0 < m_verticalRebarNumber % 4)
{
rebarNubmer++;
}
break;
case VerticalRebarLocation.North: // the north vertical reinforcement
if (2 < m_verticalRebarNumber % 4)
{
rebarNubmer++;
}
break;
case VerticalRebarLocation.West: // the west vertical reinforcement
if (1 < m_verticalRebarNumber % 4)
{
rebarNubmer++;
}
break;
case VerticalRebarLocation.South: // the south vertical reinforcement
break;
}

// get the geometry information for reinforcement creation
RebarGeometry geomInfo = m_geometry.GetVerticalRebar(location, rebarNubmer);

// create the container item
return PlaceContainerItem(cont, m_verticalType, null, null, geomInfo, RebarHookOrientation.Right, RebarHookOrientation.Right);
}

/// <summary>
/// create the all the vertical reinforcement
/// </summary>
/// <returns>true if the creation is successful, otherwise false</returns>
private bool FillVerticalItems(RebarContainer cont)
{
// create all kinds of vertical reinforcement according to the VerticalRebarLocation
foreach (VerticalRebarLocation location in Enum.GetValues(typeof(VerticalRebarLocation)))
{
RebarContainerItem item = FillVerticalItem(cont, location);
//judge whether the vertical reinforcement creation is successful
if (null == item)
{
return false;
}
}

return true;
}

}

}

ColumnGeometrySupport.cs

//
// (C) Copyright 2015 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 Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
namespace Revit.SDK.Samples.RebarContainerAnyShapeType.CS
{
   /// <summary>
   /// The geometry support for reinforcement creation on column.
   /// It can prepare the geometry information for transverse and vertical reinforcement creation
   /// </summary>
   class ColumnGeometrySupport : GeometrySupport
   {
      // Private members
      double m_columnLength; //the length of the column
      double m_columnWidth;  //the width of the column
      double m_columnHeight; //the height of the column
      /// <summary>
      /// constructor for the ColumnGeometrySupport
      /// </summary>
      /// <param name="element">the column which the rebars are placed on</param>
      /// <param name="geoOptions">the geometry option</param>
      public ColumnGeometrySupport(FamilyInstance element, Options geoOptions)
         : base(element, geoOptions)
      {
         // assert the host element is a column
         if (!element.StructuralType.Equals(StructuralType.Column))
         {
            throw new Exception("ColumnGeometrySupport can only work for column instance.");
         }
         // Get the length, width and height of the column.
         m_columnHeight = GetDrivingLineLength();
         m_columnLength = GetColumnLength();
         m_columnWidth = GetColumnWidth();
      }
      /// <summary>
      /// Get the geometry information of the transverse reinforcement
      /// </summary>
      /// <param name="location">the location of transverse rebar</param>
      /// <param name="spacing">the spacing value of the rebar</param>
      /// <returns>the got geometry information</returns>
      public RebarGeometry GetTransverseRebar(TransverseRebarLocation location, double spacing)
      {
         // sort the points of the swept profile
         XYZHeightComparer comparer = new XYZHeightComparer();
         m_points.Sort(comparer);
         // the offset from the column surface to the reinforcement
         double offset = ColumnRebarData.TransverseOffset;
         //the length of the transverse reinforcement
         double rebarLength = 0;
         // get the origin and normal parameter for reinforcement creation
         Autodesk.Revit.DB.XYZ normal = m_drivingVector;
         double curveOffset = 0;
         //set reinforcement length and origin according to the location of reinforcement
         switch (location)
         {
            case TransverseRebarLocation.Start:     // start transverse reinforcement
               rebarLength = m_columnHeight / 4;
               break;
            case TransverseRebarLocation.Center:    // center transverse reinforcement
               rebarLength = m_columnHeight / 2;
               curveOffset = m_columnHeight / 4 + (rebarLength % spacing) / 2;
               break;
            case TransverseRebarLocation.End:       // end transverse reinforcement
               rebarLength = m_columnHeight / 4;
               curveOffset = m_columnHeight - rebarLength + (rebarLength % spacing);
               break;
            default:
               throw new Exception("The program should never go here.");
         }
         // the number of the transverse reinforcement
         int rebarNumber = (int)(rebarLength / spacing) + 1;
         // get the profile of the transverse reinforcement
         List<Autodesk.Revit.DB.XYZ> movedPoints = OffsetPoints(offset);
         List<Autodesk.Revit.DB.XYZ> translatedPoints = new List<Autodesk.Revit.DB.XYZ>();
         foreach (Autodesk.Revit.DB.XYZ point in movedPoints)
         {
            translatedPoints.Add(GeomUtil.OffsetPoint(point, m_drivingVector, curveOffset));
         }
         IList<Curve> curves = new List<Curve>(); //the profile of the transverse reinforcement
         Autodesk.Revit.DB.XYZ first = translatedPoints[0];
         Autodesk.Revit.DB.XYZ second = translatedPoints[1];
         Autodesk.Revit.DB.XYZ third = translatedPoints[2];
         Autodesk.Revit.DB.XYZ fourth = translatedPoints[3];
         curves.Add(Line.CreateBound(first, second));
         curves.Add(Line.CreateBound(second, fourth));
         curves.Add(Line.CreateBound(fourth, third));
         curves.Add(Line.CreateBound(third, first));
         // return the reinforcement geometry information
         return new RebarGeometry(normal, curves, rebarNumber, spacing);
      }
      /// <summary>
      /// Get the geometry information of vertical reinforcement
      /// </summary>
      /// <param name="location">the location of vertical rebar</param>
      /// <param name="rebarNumber">the spacing value of the rebar</param>
      /// <returns>the got geometry information</returns>
      public RebarGeometry GetVerticalRebar(VerticalRebarLocation location, int rebarNumber)
      {
         // sort the points of the swept profile
         XYZHeightComparer comparer = new XYZHeightComparer();
         m_points.Sort(comparer);
         // Get the offset and reinforcement length
         double offset = ColumnRebarData.VerticalOffset;
         double rebarLength = m_columnHeight + 3; //the length of reinforcement
         // Get the start point of the vertical reinforcement curve
         Autodesk.Revit.DB.XYZ startPoint = m_drivingLine.GetEndPoint(0);
         List<Autodesk.Revit.DB.XYZ> movedPoints = OffsetPoints(offset);
         movedPoints.Sort(comparer);
         Autodesk.Revit.DB.XYZ normal = new Autodesk.Revit.DB.XYZ(); // the normal parameter
         double rebarOffset = 0; // rebar offset, equal to rebarNumber* spacing 
         // get the normal, start point and reinforcement vertical offset
         switch (location)
         {
            case VerticalRebarLocation.East:   //vertical reinforcement in east 
               normal = new Autodesk.Revit.DB.XYZ(0, 1, 0);
               rebarOffset = m_columnWidth - 2 * offset;
               startPoint = movedPoints[1];
               break;
            case VerticalRebarLocation.North: //vertical reinforcement in north
               normal = new Autodesk.Revit.DB.XYZ(-1, 0, 0);
               rebarOffset = m_columnLength - 2 * offset;
               startPoint = movedPoints[3];
               break;
            case VerticalRebarLocation.West: //vertical reinforcement in west
               normal = new Autodesk.Revit.DB.XYZ(0, -1, 0);
               rebarOffset = m_columnWidth - 2 * offset;
               startPoint = movedPoints[2];
               break;
            case VerticalRebarLocation.South: //vertical reinforcement in south
               normal = new Autodesk.Revit.DB.XYZ(1, 0, 0);
               rebarOffset = m_columnLength - 2 * offset;
               startPoint = movedPoints[0];
               break;
            default:
               break;
         }
         double spacing = rebarOffset / rebarNumber; //spacing value of the reinforcement
         Autodesk.Revit.DB.XYZ endPoint = GeomUtil.OffsetPoint(startPoint, m_drivingVector, rebarLength);
         IList<Curve> curves = new List<Curve>();       //profile of the reinforcement
         curves.Add(Line.CreateBound(startPoint, endPoint));
         // return the reinforcement geometry information
         return new RebarGeometry(normal, curves, rebarNumber, spacing);
      }
      /// <summary>
      /// Get the length of the column
      /// </summary>
      /// <returns>the length data</returns>
      private double GetColumnLength()
      {
         XYZHeightComparer comparer = new XYZHeightComparer();
         m_points.Sort(comparer);
         Autodesk.Revit.DB.XYZ refPoint = m_points[0];
         List<Autodesk.Revit.DB.XYZ> directions = GetRelatedVectors(refPoint);
         directions.Sort(comparer);
         return GeomUtil.GetLength(directions[0]);
      }
      /// <summary>
      /// Get the width of the column
      /// </summary>
      /// <returns>the width data</returns>
      private double GetColumnWidth()
      {
         XYZHeightComparer comparer = new XYZHeightComparer();
         m_points.Sort(comparer);
         Autodesk.Revit.DB.XYZ refPoint = m_points[0];
         List<Autodesk.Revit.DB.XYZ> directions = GetRelatedVectors(refPoint);
         directions.Sort(comparer);
         return GeomUtil.GetLength(directions[1]);
      }
   }
}