Revit二次开发_轴网快速标注

通过Revit二次开发实现对平行轴网的快速标注。交互操作是框选轴网->点选尺寸标注出现的位置->生成两道尺寸标注。

 

 

要达到设想的结果一些地方需要特殊考虑:

  1. 框选操作容易误选轴网,起码要把与所选轴网不平行的轴网过滤出来。选用了第二步操作所选点的最近轴网作为轴网平行的参考基准。遍历所有框选的轴网,如果轴网与基准轴网的向量相同或相反,则判定为平行轴网;
  2. 外侧的尺寸标注需要标识最外侧的两根轴网,取得外侧两根轴网的方法也比较简单,遍历轴网,判断另外的轴网是否都在这根轴网的左边,或者都不在这根轴网的左边,即可获得最外侧的两根轴网;
  3. 在不同的视图比例下,尺寸标注的字体高度是不一样的,所以需要读取字体高度,根据当前视图的比例,计算出内侧尺寸标注的合适位置。

以下代码:

    class QGridDimension : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            //获取轴网类型
            DimensionType dimType = null;
            FilteredElementCollector elems = new FilteredElementCollector(doc);
            foreach (DimensionType dt in elems.OfClass(typeof(DimensionType)))
            {
                if (dt.Name == "轴网尺寸标注")
                {
                    dimType = dt;
                    //dimensionGrid(uidoc, dt);
                    break;
                }
            }
            if (dimType != null)
            {
                Document document = uidoc.Document;
                IList<Element> grids = uidoc.Selection.PickElementsByRectangle(new GridFilter(), "框选轴网");
                if (grids.Count > 1)
                {
                    XYZ selPoint = uidoc.Selection.PickPoint(ObjectSnapTypes.None, "选择尺寸定位位置");
                    View activeView = uidoc.ActiveView;

                    ReferenceArray referenceArray1 = new ReferenceArray();
                    ReferenceArray referenceArray2 = new ReferenceArray();
                    //获得最靠近选择点的轴网为参照基准
                    List<Grid> lineGrid = new List<Grid>();
                    Line referenceLine = null;
                    double dis = double.MaxValue;
                    foreach (Grid g in grids)
                    {
                        double d = g.Curve.Distance(selPoint);
                        Line line = g.Curve as Line;
                        if (line != null)
                        {
                            lineGrid.Add(g);
                            if (d < dis)
                            {
                                referenceLine = line;
                                dis = d;
                            }
                        }
                    }
                    //获得内侧尺寸标注的引用
                    foreach (Grid g in lineGrid)
                    {
                        Line line = g.Curve as Line;
                        if (line.Direction.IsAlmostEqualTo(referenceLine.Direction) || line.Direction.IsAlmostEqualTo(referenceLine.Direction.Multiply(-1)))
                        {
                            referenceArray1.Append(new Reference(g));
                        }
                    }
                    //获取外侧尺寸标注的引用
                    foreach (Reference refGrid in referenceArray1)
                    {
                        Grid g = doc.GetElement(refGrid) as Grid;
                        Line line = g.Curve as Line;
                        XYZ point1 = line.GetEndPoint(0);
                        XYZ point2 = line.GetEndPoint(1);
                        int i = 0;
                        foreach (Reference _refGrid in referenceArray1)
                        {
                            Grid _g = doc.GetElement(_refGrid) as Grid;
                            Line _line = _g.Curve as Line;
                            //XYZ point1 = _line.GetEndPoint(0);
                            //XYZ point2 = _line.GetEndPoint(1);
                            XYZ point = _line.GetEndPoint(0);
                            if (PointOnTheLeft(point1, point2, point))
                            {
                                i += 1;
                            }
                        }
                        if (i == 0 || i == referenceArray1.Size - 1)
                        {
                            referenceArray2.Append(new Reference(g));
                        }
                    }
                    //计算尺寸标注位置
                    XYZ lineDir = referenceLine.Direction.CrossProduct(new XYZ(0, 0, 1));
                    XYZ point_s = referenceLine.GetEndPoint(0);
                    XYZ point_e = referenceLine.GetEndPoint(1);
                    if (point_s.DistanceTo(selPoint) > point_e.DistanceTo(selPoint))
                    {
                        XYZ temPoint = point_s;
                        point_s = point_e;
                        point_e = temPoint;
                    }
                    XYZ offsetDir = point_e - point_s;
                    double lenght = dimType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
                    Line line_o = Line.CreateUnbound(selPoint, lineDir);
                    Line line_i = Line.CreateUnbound(selPoint + offsetDir.Normalize() * lenght * activeView.Scale * 1.9, lineDir);
                    //创建尺寸标注
                    using (Transaction tran = new Transaction(document, "轴网尺寸标注"))
                    {
                        tran.Start();
                        document.Create.NewDimension(activeView, line_o, referenceArray2, dimType);
                        document.Create.NewDimension(activeView, line_i, referenceArray1, dimType);
                        tran.Commit();
                    }
                }
            }
            else
            {
                TaskDialog.Show("err", "未有轴网尺寸标注类型");
            }
            return Result.Succeeded;
        }

        bool PointOnTheLeft(XYZ point1, XYZ point2, XYZ point)
        {
            double r = (point1.X - point2.X) / (point1.Y - point2.Y) * (point.Y - point2.Y) + point2.X;
            if (r > point.X)
            {
                return true;
            }
            return false;
        }
    }
    internal class GridFilter : ISelectionFilter
    {
        public bool AllowElement(Element elem)
        {
            if (elem is Grid)
            {
                return true;
            }
            return false;
        }
        public bool AllowReference(Reference reference, XYZ position)
        {
            return true;
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值