revit二次开发之多梁夸跨断(就是拆分梁啦)

2018.7.17.南京。外面36°,宜烧烤,感谢麻老师,k神。喵的Leo周*(本人)好饿。早知道不学C#了。。。

环境:revit2018

首先先介绍几个比较重要的先行条件。如果知道最好,不知道我接下来也会给你讲解。

柱的中线点:通过 Location 类,你可以得到指定柱子的中心点。这个对你以后revit二次开发生涯很有帮助。中线点,就是在柱子的俯视图的2条对角线的交点,且高度为柱子的地面高度。

下面是去中线点的代码示意:

LocationPoint columnPoint = column.Location as LocationPoint;

XYZ point =columnPoint.Point;

柱子有中心点,梁则有中心线。

                                                                                               图1-1

如图1-1所示,箭头所指即为中心线的交点。根据上面柱子的中心点,你是否发现。当梁不发生偏移时,梁的中心线的2个端点与柱子的中线点在二维平面重合。

取得中心线的代码示意:

 LocationCurve BeamLoactionCurve = beam.Location as LocationCurve;
  Curve BeamLoaction = BeamLoactionCurve.Curve;

在revit2018中梁作为FamilyInstance拥有了一新的方法叫Split,它可以根据百分比分段梁,并提供新生的梁的ID(梁被分成2断,一段继承原来梁的id,一段生成新的ID)。本人思路:根据柱子中心点,可以得到各个柱子点到指点柱子点的距离(指定点一般是梁的2端的任意一端),也就得知各个段所占百分比。然后梁根据这个在进行劈~~~~完美!perfect!

namespace SplitBeamEI
{
    [Transaction(TransactionMode.Manual)]
    public class SplitBeamWithLean : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            try
            {
                BeamAndColumnSlectionFileter beamAndColumnSelectionFileter = new BeamAndColumnSlectionFileter();
                IList<Reference> refers = uidoc.Selection.PickObjects(ObjectType.Element, beamAndColumnSelectionFileter);
                List<Element> BeamList = new List<Element>();
                List<Element> ColumnList = new List<Element>();
                if (refers.Count > 0)
                {
                    if (refers.Count < 4)
                    {
                        TaskDialog.Show("Error", "选择数量错误,梁+柱必大于等于4!");
                        return Result.Failed;
                    }
                    foreach (var refer in refers)
                    {
                        Element elem = doc.GetElement(refer.ElementId) as Element;
                        if (elem.Category.Name == "结构框架")
                        {
                            BeamList.Add(elem);
                        }
                        else if (elem.Category.Name == "结构柱")
                        {
                            ColumnList.Add(elem);
                        }
                    }
                    if (BeamList.Count != 1 || ColumnList.Count < 3)
                    {
                        TaskDialog.Show("Error", "选择数量错误,梁仅能一个且柱数量大于3!");
                        return Result.Failed;
                    }
                }
                Element beam = BeamList[0];
                LocationCurve BeamLoactionCurve = beam.Location as LocationCurve;
                Curve BeamLoaction = BeamLoactionCurve.Curve;
                XYZ BeamPoint = BeamLoaction.GetEndPoint(0);//取梁中心线前点

                List<XYZ> ColumnPointList = new List<XYZ>();

                foreach (var column in ColumnList)
                {
                    LocationPoint columnPoint = column.Location as LocationPoint;
                    ColumnPointList.Add(columnPoint.Point);
                }

                List<XYZ> newColumnList = BubbleSort(ColumnPointList, BeamPoint);//排序,按照到到梁前点的距离从小到大排列
                List<double> distanceList = new List<double>(); //存放距离数组

                foreach (var point in newColumnList)
                {
                    XYZ zero = newColumnList[0];
                    double distance = Math.Sqrt(Math.Pow((point.X - zero.X), 2) + Math.Pow((point.Y - zero.Y), 2) + Math.Pow((point.Z - zero.Z), 2));
                    distanceList.Add(distance);
                }

                distanceList.RemoveAt(0);//移除第一个
                distanceList.Reverse();//数列反转
                FamilyInstance beamFamilyInstance = beam as FamilyInstance;

                using (Transaction tran = new Transaction(doc))
                {
                    tran.Start("beam start edit");
                    for (int i = 0; i < distanceList.Count - 1; i++)
                    {
                        double percentage = distanceList[i + 1] / distanceList[i];
                        beamFamilyInstance.Split(percentage);
                    }

                    tran.Commit();
                }
            }

            catch (Exception ex)
            {
                message = ex.ToString();
                return Result.Failed;
            }

            return Result.Succeeded;
        }

        /// <summary>
        /// 仅供选择要分段的梁和与之相连接的柱
        /// </summary>
        public class BeamAndColumnSlectionFileter : ISelectionFilter
        {
            public bool AllowElement(Element elem)
            {
                if (elem.Category.Name == "结构框架" || elem.Category.Name == "结构柱")
                {
                    return true;
                }
                return false;
            }

            public bool AllowReference(Reference reference, XYZ position)
            {
                return false;
            }
        }

        /// <summary>
        /// 冒泡排序,按距离从小到大
        /// </summary>
        /// <param name="column">柱子数组</param>
        /// <param name="beam">唯一的梁</param>
        /// <returns></returns>
        public static List<XYZ> BubbleSort(List<XYZ> column, XYZ beam)
        {
            for (int i = 0; i < column.Count; i++)
            {
                for (int j = 0; j < column.Count - 1 - i; j++)
                {
                    double diatance = Math.Sqrt(Math.Pow((beam.X - column[j].X), 2) + Math.Pow((beam.Y - column[j].Y), 2) + Math.Pow((beam.Z - column[j].Z), 2));
                    double diatance1 = Math.Sqrt(Math.Pow((beam.X - column[j + 1].X), 2) + Math.Pow((beam.Y - column[j + 1].Y), 2) + Math.Pow((beam.Z - column[j + 1].Z), 2));
                    if (diatance > diatance1)
                    {
                        XYZ temp = column[j + 1];
                        column[j + 1] = column[j];
                        column[j] = temp;
                    }
                }
            }
            List<XYZ> newColumn = column;
            return newColumn;
        }


        /// <summary>
        /// 已知2点的一条直线,求第三点到的最短距离的点
        /// </summary>
        /// <param name="BeamList"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        private static XYZ GetPoint(List<XYZ> BeamList, XYZ column)
        {
            XYZ point;

            double x1 = BeamList[0].X;
            double y1 = BeamList[0].Y;
            
            double x2 = column.X;
            double y2 = column.Y;
            
            double tana = (BeamList[0].Y - BeamList[1].Y) / (BeamList[0].X - BeamList[1].X);//梁的斜率

            double x = (y2 + x2 / tana - y1 + tana * x1) / (tana + 1 / tana);

            double y = tana * x + y1 - tana * x1;

            point = new XYZ(x, y, BeamList[0].Z);
            return point;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39412924/article/details/81080922
今日推荐