创建冠梁配筋

using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BeamReinforcingBars
{
    /// <summary>
    /// 创建冠梁配筋,以1000mm*1000mm为例,主要针对常规构建进行配筋设置
    /// </summary>
    [Transaction(TransactionMode.Manual)]
    public class Class1 : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {

            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            //获得当前视图
            #region 判断是否为3D视图,不是则跳转3D视图
            View3D view3d;
            var Vtype = doc.ActiveView.GetType();

            if (!typeof(View3D).Equals(Vtype))
            {
                using (Transaction ts = new Transaction(doc, "3dview"))
                {
                    ts.Start();
                    ViewFamilyType viewtype = new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType))
                                             .Cast<ViewFamilyType>()
                                             .FirstOrDefault<ViewFamilyType>(
                                              x => ViewFamily.ThreeDimensional
                                               == x.ViewFamily);
                    view3d = View3D.CreateIsometric(doc, viewtype.Id);
                    ts.Commit();
                    uidoc.ActiveView = view3d;
                }
            }
            #endregion
            View3D view3D = doc.ActiveView as View3D;
            //MainWindows mainWindows = new MainWindows();
            //mainWindows.ShowDialog();
            //选择梁
            Reference reference = uidoc.Selection.PickObject(ObjectType.Element, "选择梁");
            //创建梁数据结构
            BeamInfo beamInfo = new BeamInfo();
            beamInfo.ele = doc.GetElement(reference);
            FamilyInstance beam = beamInfo.ele as FamilyInstance;
            //获取梁控制线
            beamInfo.curve = (beam.Location as LocationCurve).Curve;
            //获取梁原始集合包围框
            Options options = new Options();
            GeometryElement geoEle = beam.GetOriginalGeometry(options);
            BoundingBoxXYZ boundingBox = geoEle.GetBoundingBox();
            //获得梁的长、宽、高,由于梁是可载入族,用b、h等参数不可靠
            //建议通过包围框获得梁的宽和高
            beamInfo.length = beamInfo.curve.Length;
            beamInfo.h = boundingBox.Max.Z - boundingBox.Min.Z;
            beamInfo.b = boundingBox.Max.Y - boundingBox.Min.Y;
            //获得梁的坐标系
            beamInfo.tf = beam.GetTransform();
            beamInfo.protect = 40 / 304.8;
            beamInfo.origin = beamInfo.curve.GetEndPoint(0);     //注意控制线位置在梁顶部
            #region 获取相应的钢筋类型
            //获得钢筋的类型。以12HRB400为例
            FilteredElementCollector rbTypeCol_12 = new FilteredElementCollector(doc);
            rbTypeCol_12.OfClass(typeof(RebarBarType));
            IEnumerable<RebarBarType> rTypes_12 = from elem in rbTypeCol_12
                                                  let r = elem as RebarBarType
                                                  where r.Name == "12 HRB400"
                                                  select r;
            RebarBarType type_12 = rTypes_12.First();
            //外箍筋形状
            FilteredElementCollector rShapesColGJ = new FilteredElementCollector(doc);
            rShapesColGJ.OfClass(typeof(RebarShape));
            IEnumerable<RebarShape> rShapesGJ = from ele in rShapesColGJ
                                                let barshape = ele as RebarShape
                                                where barshape.Name == "33"
                                                select barshape;
            RebarShape rShapeGJ = rShapesGJ.First();

            //中部筋类型
            FilteredElementCollector rbTypeZ = new FilteredElementCollector(doc);
            rbTypeZ.OfClass(typeof(RebarBarType));
            IEnumerable<RebarBarType> rtypesZ = from ele in rbTypeZ
                                                let barshape = ele as RebarBarType
                                                where barshape.Name == "20 HRB400"
                                                select barshape;
            RebarBarType rtypeZ = rtypesZ.First();

            //侧边钢筋类型
            FilteredElementCollector rbtyprColJJ = new FilteredElementCollector(doc);
            rbtyprColJJ.OfClass(typeof(RebarBarType));
            IEnumerable<RebarBarType> rbTypesJJ = from ele in rbtyprColJJ
                                                  let barType = ele as RebarBarType
                                                  where barType.Name == "25 HRB400"
                                                  select barType;
            RebarBarType rTypeJJ = rbTypesJJ.First();

            FilteredElementCollector rShapeCol01 = new FilteredElementCollector(doc);
            rShapeCol01.OfClass(typeof(RebarShape));
            IEnumerable<RebarShape> rShapes01 = from ele in rShapeCol01
                                                let barshape = ele as RebarShape
                                                where barshape.Name == "01"
                                                select barshape;
            RebarShape rShape01 = rShapes01.First();


            #endregion
            double space = 400 / 304.8;

            int num = 5;
            int num2 = 9;

            //创建并启动事务
            Transaction transaction = new Transaction(doc, "钢筋");
            transaction.Start();
            CreateGJ(doc, beamInfo, space, view3D, type_12, rShapeGJ);
            CreateZb(doc, beamInfo, num, view3D, rtypeZ, rShape01, type_12);
            CreateCb(doc, beamInfo, num2, view3D, rTypeJJ, rShape01, type_12);

            transaction.Commit();
            return Result.Succeeded;
        }

        public struct BeamInfo
        {
            public Element ele; //冠梁
            public Curve curve;//冠梁控制线
            public Transform tf;//冠梁坐标系
            public double protect;//保护层厚度
            public XYZ origin;//冠梁中心坐标
            public double b;//冠梁b长
            public double h;//冠梁h长
            public double length;//冠梁长度
        }

        /// <summary>
        /// 外箍筋创建
        /// </summary>
        /// <param name="doc">doc</param>
        /// <param name="bInfo">冠梁参数结构体</param>
        /// <param name="view3D">3D视图</param>
        /// <param name="rbtype">钢筋类型</param>
        /// <param name="rShape">钢筋形状</param>
        public void CreateGJ(Document doc, BeamInfo bInfo, double space, View3D view3D, RebarBarType rbtype, RebarShape rShape)
        {

            //外箍筋数量
            int num = (int)Math.Ceiling(bInfo.length / space);
            //箍筋中心离冠梁侧边距离,保护层以40mm为例,注意包含箍筋半径
            double ct = bInfo.protect + rbtype.BarDiameter / 2;
            Element ele = bInfo.ele;
            for (int i = 0; i < num; i++)
            {
                double depth = ct + i * space;//外箍筋位置
                                              //冠梁底部中心点
                XYZ origin = bInfo.tf.Inverse.OfPoint(bInfo.origin);
                //获得箍筋控制点
                XYZ delta1 = new XYZ(depth, -bInfo.b / 2 + ct, -bInfo.h + ct);
                XYZ delta2 = new XYZ(depth, -bInfo.b / 2 + ct, -ct);
                XYZ delta3 = new XYZ(depth, bInfo.b / 2 - ct, -ct);
                XYZ delta4 = new XYZ(depth, bInfo.b / 2 - ct, -bInfo.h + ct);
                XYZ p1 = bInfo.tf.OfPoint(origin + delta1);
                XYZ p2 = bInfo.tf.OfPoint(origin + delta2);
                XYZ p3 = bInfo.tf.OfPoint(origin + delta3);
                XYZ p4 = bInfo.tf.OfPoint(origin + delta4);
                //钢筋形态放置方向,以p1为放置点
                XYZ xVec = (p2 - p1);
                XYZ yVec = (p4 - p1);
                //创建钢筋
                Rebar rb = Rebar.CreateFromRebarShape(doc, rShape, rbtype, ele, p1, xVec, yVec);
                //设置钢筋在范围框内
                rb.GetShapeDrivenAccessor().ScaleToBox(p1, xVec, yVec);
                //作为实体查看,false时钢筋以线的形式表示
                rb.SetSolidInView(view3D, true);
                //清晰的视图设置
                rb.SetUnobscuredInView(view3D, true);
            }
        }

        /// <summary>
        /// 中部创建横向钢筋
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="bInfo"></param>
        /// <param name="view3D"></param>
        /// <param name="rt"></param>
        /// <param name="rs"></param>
        /// <param name="rTG"></param>
        public void CreateZb(Document doc, BeamInfo bInfo, int num, View3D view3D, RebarBarType rt, RebarShape rs, RebarBarType rTG)
        {
            //获得冠梁的b、h、高和transform
            Element ele = bInfo.ele;
            double b = bInfo.b;
            double h = bInfo.h;
            double length = bInfo.length;
            Transform tf = bInfo.tf;
            //冠梁定位点通过ofpoint转成冠梁transform的坐标,否则钢筋不在主体内
            XYZ origin = bInfo.tf.Inverse.OfPoint(bInfo.origin);
            XYZ norm = bInfo.tf.BasisZ;
            //纵筋区域起始位置离冠梁边距离
            double depth = bInfo.protect + rTG.BarDiameter + rt.BarDiameter / 2;
            //获得b纵筋间距,案例以num条中部筋为例
            double spaceB = (bInfo.b - bInfo.protect * 2 - rt.BarDiameter - rTG.BarDiameter * 2) / (num + 1);
            //B侧,案例以3条中部筋为例
            for (int i = 0; i < num; i++)
            {
                //放置点位置
                double set = (i + 1) * spaceB + depth;
                //b上侧
                XYZ p1 = tf.OfPoint(origin + new XYZ(0, -b / 2 + set, -depth));
                XYZ p11 = tf.OfPoint(origin + new XYZ(length, -b / 2 + set, -depth));
                //b下侧
                XYZ p2 = tf.OfPoint(origin + new XYZ(0, -b / 2 + set, -h + depth));
                XYZ p22 = tf.OfPoint(origin + new XYZ(length, -b / 2 + set, -h + depth));
                //保存创建的钢筋用于显示
                List<Rebar> rbs = new List<Rebar>();
                //获得中部筋的控制线
                IList<Curve> c1 = new List<Curve>();
                IList<Curve> c2 = new List<Curve>();
                c1.Add(Line.CreateBound(p1, p11));
                c2.Add(Line.CreateBound(p2, p22));
                //角筋弯钩方向和放置方向,没有弯钩时不影响结果
                RebarHookOrientation rho = RebarHookOrientation.Left;
                //创建角筋
                rbs.Add(Rebar.CreateFromCurvesAndShape(doc, rs, rt, null, null, ele, norm, c1, rho, rho));
                rbs.Add(Rebar.CreateFromCurvesAndShape(doc, rs, rt, null, null, ele, norm, c2, rho, rho));
                foreach (Rebar rb in rbs)
                {
                    //作为实体查看,false时钢筋以线的形式表示
                    rb.SetSolidInView(view3D, true);
                    //清晰的视图设置
                    rb.SetUnobscuredInView(view3D, true);
                }
            }
        }

        /// <summary>
        ///侧边创建横向钢筋
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="bInfo"></param>
        /// <param name="view3D"></param>
        /// <param name="rt"></param>
        /// <param name="rs"></param>
        /// <param name="rTG"></param>
        public void CreateCb(Document doc, BeamInfo bInfo, int num, View3D view3D, RebarBarType rt, RebarShape rs, RebarBarType rTG)
        {
            //获得冠梁的b、h、高和transform
            Element ele = bInfo.ele;
            double b = bInfo.b;
            double h = bInfo.h;
            double length = bInfo.length;
            Transform tf = bInfo.tf;
            //冠梁定位点通过ofpoint转成冠梁transform的坐标,否则钢筋不在主体内
            XYZ origin = bInfo.tf.Inverse.OfPoint(bInfo.origin);
            XYZ norm = bInfo.tf.BasisY;
            //纵筋区域起始位置离冠梁边距离
            double depth = bInfo.protect + rTG.BarDiameter + rt.BarDiameter / 2;
            //获得b纵筋间距,案例以num条中部筋为例
            double spaceB = (bInfo.h - bInfo.protect * 2 - rTG.BarDiameter * 2-rt.BarDiameter) / (num - 1);
            //B侧,案例以3条中部筋为例
            for (int i = 0; i < num; i++)
            {
                //放置点位置
                double set =i * spaceB + depth;
                //b上侧
                XYZ p1 = tf.OfPoint(origin + new XYZ(0, b/2-depth, -h+set));
                XYZ p11 = tf.OfPoint(origin + new XYZ(length,b/2 -depth, -h+set));
                //b下侧
                XYZ p2 = tf.OfPoint(origin + new XYZ(0, -b/2 + depth,-h+set));
                XYZ p22 = tf.OfPoint(origin + new XYZ(length, -b/2 + depth, -h+set));
                //保存创建的钢筋用于显示
                List<Rebar> rbs = new List<Rebar>();
                //获得中部筋的控制线
                IList<Curve> c1 = new List<Curve>();
                IList<Curve> c2 = new List<Curve>();
                c1.Add(Line.CreateBound(p1, p11));
                c2.Add(Line.CreateBound(p2, p22));
                //角筋弯钩方向和放置方向,没有弯钩时不影响结果
                RebarHookOrientation rho = RebarHookOrientation.Left;
                //创建角筋
                rbs.Add(Rebar.CreateFromCurvesAndShape(doc, rs, rt, null, null, ele, norm, c1, rho, rho));
                rbs.Add(Rebar.CreateFromCurvesAndShape(doc, rs, rt, null, null, ele, norm, c2, rho, rho));
                foreach (Rebar rb in rbs)
                {
                    //作为实体查看,false时钢筋以线的形式表示
                    rb.SetSolidInView(view3D, true);
                    //清晰的视图设置
                    rb.SetUnobscuredInView(view3D, true);
                }
            }
        }
    }
}


猜你喜欢

转载自blog.csdn.net/waiting233/article/details/117984968